source: trunk/gui/scripts/editor.tcl @ 17

Last change on this file since 17 was 17, checked in by mmc, 19 years ago

Added a capability to MainWin? to syncCutBuffer with the
application. The VNC Java client uses the cutbuffer
instead of the selection for Copy/Paste? to desktop, and
this mechanism keeps the two in sync so Copy/Paste? works
properly. Also, added Cut/Copy/Paste? menus to the right
mouse button of various widgets.

Fixed 3D plotting to work with the vtkCutter so it works
better. Also, added support for 3D meshes in addition
to clouds. Meshes store connectivity, so they are better
at representing holes in data. Fixed the 3D plotter so
that rotate is more intuitive, and added lights so you can
see your data better at any angle.

Fixed the loader so that it can load elements with the ""
value, and so that it doesn't duplicate entries found
more than once by *.xml pattern matching.

File size: 10.3 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: editor - pop-up editor for little bits of text
3#
4#  This widget acts as a pop-up editor for small text fields.  It
5#  pops up on top of any text field, accepts edits, and then attempts
6#  to validate and apply changes back to the underlying widget.
7#
8#  This widget uses a number of callbacks to handle communication
9#  with the underlying widget:
10#
11#  -activatecommand .... Should return a key/value list with the
12#                        following elements:
13#                          x ...... root x coordinate for editor
14#                          y ...... root y coordinate for editor
15#                          w ...... width of text being edited
16#                          h ...... height of text being edited
17#                          text ... initial text for the editor
18#
19#  -validatecommand .... Invoked with the new value as an argument.
20#                        Should return 1 if the value is okay, and
21#                        0 otherwise.
22#
23#  -applycommand ....... Invoked with the new value as an argument.
24#                        Should apply the new value to the underlying
25#                        widget.
26#
27# ======================================================================
28#  AUTHOR:  Michael McLennan, Purdue University
29#  Copyright (c) 2004-2005
30#  Purdue Research Foundation, West Lafayette, IN
31# ======================================================================
32package require Itk
33
34option add *Editor.background white widgetDefault
35option add *Editor.outline black widgetDefault
36option add *Editor.borderwidth 1 widgetDefault
37option add *Editor.relief flat widgetDefault
38option add *Editor.selectBorderWidth 0 widgetDefault
39
40itcl::class Rappture::Editor {
41    inherit itk::Toplevel
42
43    itk_option define -outline outline Outline ""
44    itk_option define -activatecommand activateCommand ActivateCommand ""
45    itk_option define -validatecommand validateCommand ValidateCommand ""
46    itk_option define -applycommand applyCommand ApplyCommand ""
47
48    constructor {args} { # defined below }
49
50    public method activate {}
51    public method deactivate {args}
52    public method value {newval}
53
54    protected method _click {x y}
55    protected method _resize {}
56    protected variable _loc   ;# array of editor location parameters
57}
58                                                                               
59itk::usual Editor {
60    keep -cursor -font
61}
62
63# ----------------------------------------------------------------------
64# CONSTRUCTOR
65# ----------------------------------------------------------------------
66itcl::body Rappture::Editor::constructor {args} {
67    wm overrideredirect $itk_component(hull) yes
68    wm withdraw $itk_component(hull)
69
70    itk_option remove hull.background hull.borderwidth
71    component hull configure -borderwidth 1
72
73    itk_component add editor {
74        entry $itk_interior.editor -highlightthickness 0
75    } {
76        usual
77        keep -relief
78        ignore -highlightthickness
79        ignore -highlightcolor
80        ignore -highlightbackground
81    }
82    pack $itk_component(editor) -expand yes -fill both
83
84    bind $itk_component(editor) <KeyPress> \
85        [itcl::code $this _resize]
86    bind $itk_component(editor) <KeyPress-Return> \
87        [itcl::code $this deactivate]
88    bind $itk_component(editor) <KeyPress-Escape> \
89        [itcl::code $this deactivate -abort]
90    bind $itk_component(editor) <ButtonPress> \
91        [itcl::code $this _click %X %Y]
92
93    itk_component add emenu {
94        menu $itk_component(editor).menu -tearoff 0
95    } {
96        usual
97        ignore -tearoff
98        ignore -background -foreground
99    }
100    $itk_component(emenu) add command -label "Cut" -accelerator "^X" \
101        -command [list event generate $itk_component(editor) <<Cut>>]
102    $itk_component(emenu) add command -label "Copy" -accelerator "^C" \
103        -command [list event generate $itk_component(editor) <<Copy>>]
104    $itk_component(emenu) add command -label "Paste" -accelerator "^V" \
105        -command [list event generate $itk_component(editor) <<Paste>>]
106    bind $itk_component(editor) <<PopupMenu>> {
107        tk_popup %W.menu %X %Y
108    }
109
110    eval itk_initialize $args
111}
112
113# ----------------------------------------------------------------------
114# USAGE: activate
115#
116# Clients use this to start the editing process on the underlying
117# widget.  This pops up the editor with the current text from the
118# underlying widget and allows the user to edit the text.  The editor
119# remains up until it is deactivated.
120# ----------------------------------------------------------------------
121itcl::body Rappture::Editor::activate {} {
122    set e $itk_component(editor)
123    if {[winfo ismapped $e]} {
124        return  ;# already mapped -- nothing to do
125    }
126
127    set info ""
128    if {[string length $itk_option(-activatecommand)] > 0} {
129        set status [catch {uplevel #0 $itk_option(-activatecommand)} info]
130        if {$status != 0} {
131            bgerror $info
132            return
133        }
134    }
135
136    #
137    # Pull out the location information from the values passed back
138    # from the activation command.  We must have at least an x,y
139    # coordinate.  If we get width and height too, then use it.
140    # If not, figure out the width and height based on the size
141    # of the string.
142    #
143    array set vals $info
144    if {![info exists vals(x)] || ![info exists vals(y)]} {
145        return
146    }
147    set _loc(x) $vals(x)
148    set _loc(y) $vals(y)
149    set _loc(w) [expr {([info exists vals(w)]) ? $vals(w) : 0}]
150    set _loc(h) [expr {([info exists vals(h)]) ? $vals(h) : 0}]
151
152    $itk_component(editor) delete 0 end
153    if {[info exists vals(text)]} {
154        $itk_component(editor) insert end $vals(text)
155    }
156    $itk_component(editor) select from 0
157    $itk_component(editor) select to end
158
159    _resize
160    wm deiconify $itk_component(hull)
161    raise $itk_component(hull)
162    focus $itk_component(editor)
163
164    # try to grab the pointer, and keep trying...
165    update
166    while {[catch {grab set -global $itk_component(editor)}]} {
167        after 100
168    }
169}
170
171# ----------------------------------------------------------------------
172# USAGE: deactivate ?-abort?
173#
174# This is invoked automatically whenever the user presses Enter or
175# Escape in the editor.  Clients can also use it explicitly to
176# deactivate the editor.
177#
178# If the -abort flag is specified, then the editor is taken down
179# without any validation or application of the result.  Otherwise,
180# we validate the contents of the editor and apply the change back
181# to the widget.
182# ----------------------------------------------------------------------
183itcl::body Rappture::Editor::deactivate {args} {
184    # take down any error cue that might be up
185    ::Rappture::Tooltip::cue hide
186
187    if {$args == "-abort"} {
188        grab release $itk_component(editor)
189        wm withdraw $itk_component(hull)
190        return
191    }
192
193    set str [$itk_component(editor) get]
194
195    #
196    # If there's a -validatecommand option, then invoke the code
197    # now to check the new value.
198    #
199    if {[string length $itk_option(-validatecommand)] > 0} {
200        set cmd "uplevel #0 [list $itk_option(-validatecommand) [list $str]]"
201        if {[catch $cmd result]} {
202            bgerror $result
203            set result 1
204        }
205        if {$result == 0} {
206            bell
207            $itk_component(editor) select from 0
208            $itk_component(editor) select to end
209            $itk_component(editor) icursor end
210            focus $itk_component(editor)
211            return
212        }
213    }
214
215    grab release $itk_component(editor)
216    wm withdraw $itk_component(hull)
217
218    #
219    # If there's an -applycommand option, then invoke the code
220    # now to apply the new value.
221    #
222    if {[string length $itk_option(-applycommand)] > 0} {
223        set cmd "uplevel #0 [list $itk_option(-applycommand) [list $str]]"
224        if {[catch $cmd result]} {
225            bgerror $result
226            return
227        }
228    }
229}
230
231# ----------------------------------------------------------------------
232# USAGE: value <newval>
233#
234# Clients use this to suggest a new value, particular when they've
235# caught an error in the editing process.  For example, if the user's
236# value is below the minimum allowed value, a client would call this
237# method to suggest the minimum value.
238# ----------------------------------------------------------------------
239itcl::body Rappture::Editor::value {newval} {
240    $itk_component(editor) delete 0 end
241    $itk_component(editor) insert end $newval
242}
243
244# ----------------------------------------------------------------------
245# USAGE: _click <X> <Y>
246#
247# This is invoked automatically whenever the user clicks somewhere
248# inside or outside of the editor.  If the <X>,<Y> coordinate is
249# outside the editor, then we assume the user is done and wants to
250# take the editor down.  Otherwise, we do nothing, and let the entry
251# bindings take over.
252# ----------------------------------------------------------------------
253itcl::body Rappture::Editor::_click {x y} {
254    if {[winfo containing $x $y] != $itk_component(editor)} {
255        deactivate
256    } else {
257        # make sure the editor has keyboard focus!
258        # it loses focus sometimes during cut/copy/paste operations
259        focus -force $itk_component(editor)
260    }
261}
262
263# ----------------------------------------------------------------------
264# USAGE: _resize
265#
266# Invoked automatically as each key is pressed in the editor.
267# Resizes the editor so that it is just big enough to show all
268# of the text within it.
269# ----------------------------------------------------------------------
270itcl::body Rappture::Editor::_resize {} {
271    set e $itk_component(editor)
272    set str [$e get]
273    set fnt [$e cget -font]
274
275    set w [expr {[font measure $fnt $str]+20}]
276    set w [expr {($w < $_loc(w)) ? $_loc(w) : $w}]
277    if {$w+$_loc(x) >= [winfo screenwidth $e]} {
278        set w [expr {[winfo screenwidth $e]-$_loc(x)}]
279    }
280
281    set h [expr {[font metrics $fnt -linespace]+4}]
282    set h [expr {($h < $_loc(h)) ? $_loc(h) : $h}]
283    if {$h+$_loc(y) >= [winfo screenwidth $e]} {
284        set h [expr {[winfo screenwidth $e]-$_loc(y)}]
285    }
286
287    wm geometry $itk_component(hull) "${w}x${h}+$_loc(x)+$_loc(y)"
288}
289
290# ----------------------------------------------------------------------
291# CONFIGURATION OPTION: -outline
292# ----------------------------------------------------------------------
293itcl::configbody Rappture::Editor::outline {
294    component hull configure -background $itk_option(-outline)
295}
Note: See TracBrowser for help on using the repository browser.