source: trunk/gui/scripts/textentry.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: 14.0 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: textentry - general-purpose text entry widget
3#
4#  This widget is a cross between the Tk entry and text widgets.  For
5#  one-line messages, it acts like an entry widget.  For larger
6#  messages, it morphs into a text widget.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005
10#  Purdue Research Foundation, West Lafayette, IN
11# ======================================================================
12package require Itk
13
14option add *TextEntry.size auto widgetDefault
15option add *TextEntry.width 0 widgetDefault
16option add *TextEntry.height 0 widgetDefault
17option add *TextEntry.editable yes widgetDefault
18option add *TextEntry.textBackground white widgetDefault
19
20option add *TextEntry.hintForeground gray50 widgetDefault
21option add *TextEntry.hintFont \
22    -*-helvetica-medium-r-normal-*-*-100-* widgetDefault
23
24itcl::class Rappture::TextEntry {
25    inherit itk::Widget
26
27    itk_option define -editable editable Editable ""
28    itk_option define -width width Width 0
29    itk_option define -height height Height 0
30
31    constructor {xmlobj path args} { # defined below }
32
33    public method value {args}
34
35    public method label {}
36    public method tooltip {}
37    public method size {} { return $_size }
38
39    protected method _layout {}
40
41    private variable _dispatcher "" ;# dispatcher for !events
42    private variable _xmlobj ""   ;# XML containing description
43    private variable _path ""     ;# path in XML to this number
44
45    private variable _mode ""       ;# entry or text mode
46    private variable _size ""       ;# size hint from XML
47}
48                                                                               
49itk::usual TextEntry {
50}
51
52# ----------------------------------------------------------------------
53# CONSTRUCTOR
54# ----------------------------------------------------------------------
55itcl::body Rappture::TextEntry::constructor {xmlobj path args} {
56    if {![Rappture::library isvalid $xmlobj]} {
57        error "bad value \"$xmlobj\": should be Rappture::library"
58    }
59    set _xmlobj $xmlobj
60    set _path $path
61
62    Rappture::dispatcher _dispatcher
63    $_dispatcher register !layout
64    $_dispatcher dispatch $this !layout "[itcl::code $this _layout]; list"
65
66    set _size [$xmlobj get $path.size]
67
68    set hints [$xmlobj get $path.about.hints]
69    if {[string length $hints] > 0} {
70        itk_component add hints {
71            label $itk_interior.hints -anchor w -text $hints
72        } {
73            usual
74            rename -foreground -hintforeground hintForeground Foreground
75            rename -font -hintfont hintFont Font
76        }
77        pack $itk_component(hints) -side bottom -fill x
78    }
79
80    eval itk_initialize $args
81
82    set str [$xmlobj get $path.default]
83    if {"" != $str} { value $str }
84}
85
86# ----------------------------------------------------------------------
87# USAGE: value ?-check? ?<newval>?
88#
89# Clients use this to query/set the value for this widget.  With
90# no args, it returns the current value for the widget.  If the
91# <newval> is specified, it sets the value of the widget and
92# sends a <<Value>> event.  If the -check flag is included, the
93# new value is not actually applied, but just checked for correctness.
94# ----------------------------------------------------------------------
95itcl::body Rappture::TextEntry::value {args} {
96    set onlycheck 0
97    set i [lsearch -exact $args -check]
98    if {$i >= 0} {
99        set onlycheck 1
100        set args [lreplace $args $i $i]
101    }
102
103    if {[llength $args] == 1} {
104        if {$onlycheck} {
105            # someday we may add validation...
106            return
107        }
108        set newval [lindex $args 0]
109        if {$_mode == "entry"} {
110            $itk_component(entry) configure -state normal
111            $itk_component(emenu) entryconfigure "Cut" -state normal
112            $itk_component(emenu) entryconfigure "Copy" -state normal
113            $itk_component(emenu) entryconfigure "Paste" -state normal
114            $itk_component(entry) delete 0 end
115            $itk_component(entry) insert 0 $newval
116            if {!$itk_option(-editable)} {
117                $itk_component(entry) configure -state disabled
118                $itk_component(emenu) entryconfigure "Cut" -state disabled
119                $itk_component(emenu) entryconfigure "Copy" -state disabled
120                $itk_component(emenu) entryconfigure "Paste" -state disabled
121            }
122        } elseif {$_mode == "text"} {
123            $itk_component(text) configure -state normal
124            $itk_component(tmenu) entryconfigure "Cut" -state normal
125            $itk_component(tmenu) entryconfigure "Copy" -state normal
126            $itk_component(tmenu) entryconfigure "Paste" -state normal
127            $itk_component(text) delete 1.0 end
128            $itk_component(text) insert end $newval
129            if {!$itk_option(-editable)} {
130                $itk_component(text) configure -state disabled
131                $itk_component(tmenu) entryconfigure "Cut" -state disabled
132                $itk_component(tmenu) entryconfigure "Copy" -state disabled
133                $itk_component(tmenu) entryconfigure "Paste" -state disabled
134            }
135        }
136        $_dispatcher event -idle !layout
137        event generate $itk_component(hull) <<Value>>
138        return $newval
139
140    } elseif {[llength $args] != 0} {
141        error "wrong # args: should be \"value ?-check? ?newval?\""
142    }
143
144    #
145    # Query the value and return.
146    #
147    if {$_mode == "entry"} {
148        return [$itk_component(entry) get]
149    } elseif {$_mode == "text"} {
150        return [$itk_component(text) get 1.0 end-1char]
151    }
152    return ""
153}
154
155# ----------------------------------------------------------------------
156# USAGE: label
157#
158# Clients use this to query the label associated with this widget.
159# Reaches into the XML and pulls out the appropriate label string.
160# ----------------------------------------------------------------------
161itcl::body Rappture::TextEntry::label {} {
162    set label [$_xmlobj get $_path.about.label]
163    if {"" == $label} {
164        set label "String"
165    }
166    return $label
167}
168
169# ----------------------------------------------------------------------
170# USAGE: tooltip
171#
172# Clients use this to query the tooltip associated with this widget.
173# Reaches into the XML and pulls out the appropriate description
174# string.  Returns the string that should be used with the
175# Rappture::Tooltip facility.
176# ----------------------------------------------------------------------
177itcl::body Rappture::TextEntry::tooltip {} {
178    set str [$_xmlobj get $_path.about.description]
179    return [string trim $str]
180}
181
182# ----------------------------------------------------------------------
183# USAGE: _layout
184#
185# Used internally to change the layout of this widget depending
186# on the .size hint and its contents.  Switches between an entry
187# and a text widget.
188# ----------------------------------------------------------------------
189itcl::body Rappture::TextEntry::_layout {} {
190    set size $_size
191    if {$size == "" || $size == "auto"} {
192        #
193        # If the size is "auto", then look at the current value
194        # and count its lines/characters.
195        #
196        set val ""
197        if {$_mode == "entry"} {
198            set val [$itk_component(entry) get]
199        } elseif {$_mode == "text"} {
200            set val [$itk_component(text) get 1.0 end-1char]
201        }
202
203        set chars 0
204        set lines 0
205        foreach line [split $val \n] {
206            incr lines
207            if {[string length $line] > $chars} {
208                set chars [string length $line]
209            }
210        }
211        incr chars
212
213        if {$lines > 1} {
214            set size "${chars}x${lines}"
215        } else {
216            set size $chars
217        }
218    }
219
220    if {[regexp {^[0-9]+$} $size]} {
221        #
222        # If the size is WW, then flip to entry mode, with
223        # a requested size of WW characters.
224        #
225        if {$_mode != "entry"} {
226            set val ""
227            if {$_mode == "text"} {
228                set val [$itk_component(text) get 1.0 end-1char]
229                destroy $itk_component(text)
230                destroy $itk_component(scrollbars)
231            }
232
233            itk_component add entry {
234                entry $itk_interior.entry
235            } {
236                usual
237                rename -background -textbackground textBackground Background
238                rename -foreground -textforeground textForeground Foreground
239            }
240            pack $itk_component(entry) -expand yes -fill both
241            $itk_component(entry) configure \
242                -background $itk_option(-textbackground) \
243                -foreground $itk_option(-textforeground)
244
245            itk_component add emenu {
246                menu $itk_component(entry).menu -tearoff 0
247            }
248            $itk_component(emenu) add command -label "Cut" -accelerator "^X" \
249                -command [list event generate $itk_component(entry) <<Cut>>]
250            $itk_component(emenu) add command -label "Copy" -accelerator "^C" \
251                -command [list event generate $itk_component(entry) <<Copy>>]
252            $itk_component(emenu) add command -label "Paste" -accelerator "^V" \
253                -command [list event generate $itk_component(entry) <<Paste>>]
254            bind $itk_component(entry) <<PopupMenu>> {
255                tk_popup %W.menu %X %Y
256            }
257
258            $itk_component(entry) insert end $val
259            if {!$itk_option(-editable)} {
260                $itk_component(entry) configure -state disabled
261            }
262            set _mode "entry"
263        }
264        $itk_component(entry) configure -width $size
265
266    } elseif {[regexp {^([0-9]+)x([0-9]+)$} $size match w h]} {
267        #
268        # If the size is WWxHH, then flip to text mode, with
269        # a requested size of HH lines by WW characters.
270        #
271        if {$_mode != "text"} {
272            set val ""
273            if {$_mode == "entry"} {
274                set val [$itk_component(entry) get]
275                destroy $itk_component(entry)
276            }
277
278            itk_component add scrollbars {
279                Rappture::Scroller $itk_interior.scrl \
280                     -xscrollmode auto -yscrollmode auto
281            }
282            pack $itk_component(scrollbars) -expand yes -fill both
283
284            itk_component add text {
285                text $itk_component(scrollbars).text \
286                    -width 1 -height 1 -wrap word
287            } {
288                usual
289                rename -background -textbackground textBackground Background
290                rename -foreground -textforeground textForeground Foreground
291            }
292            $itk_component(text) configure \
293                -background $itk_option(-textbackground) \
294                -foreground $itk_option(-textforeground)
295            $itk_component(scrollbars) contents $itk_component(text)
296
297            itk_component add tmenu {
298                menu $itk_component(text).menu -tearoff 0
299            }
300            $itk_component(tmenu) add command -label "Cut" -accelerator "^X" \
301                -command [list event generate $itk_component(text) <<Cut>>]
302            $itk_component(tmenu) add command -label "Copy" -accelerator "^C" \
303                -command [list event generate $itk_component(text) <<Copy>>]
304            $itk_component(tmenu) add command -label "Paste" -accelerator "^V" \
305                -command [list event generate $itk_component(text) <<Paste>>]
306            bind $itk_component(text) <<PopupMenu>> {
307                tk_popup %W.menu %X %Y
308            }
309
310            $itk_component(text) insert end $val
311            if {!$itk_option(-editable)} {
312                $itk_component(text) configure -state disabled
313                $itk_component(menu) entryconfigure "Cut" -state disabled
314                $itk_component(menu) entryconfigure "Copy" -state disabled
315                $itk_component(menu) entryconfigure "Paste" -state disabled
316            }
317            set _mode "text"
318        }
319        $itk_component(text) configure -width $w -height $h
320    }
321
322    #
323    # Fix the overall widget size according to -width / -height
324    #
325    if {$itk_option(-width) == 0 && $itk_option(-height) == 0} {
326        pack propagate $itk_component(hull) yes
327    } else {
328        pack propagate $itk_component(hull) no
329        component hull configure \
330            -width $itk_option(-width) -height $itk_option(-width)
331    }
332}
333
334# ----------------------------------------------------------------------
335# CONFIGURATION OPTION: -editable
336# ----------------------------------------------------------------------
337itcl::configbody Rappture::TextEntry::editable {
338    if {![string is boolean -strict $itk_option(-editable)]} {
339        error "bad value \"$itk_option(-editable)\": should be boolean"
340    }
341
342    if {$itk_option(-editable)} {
343        set state normal
344    } else {
345        set state disabled
346    }
347    if {$_mode == "entry"} {
348        $itk_component(editor) configure -state $state
349        $itk_component(emenu) entryconfigure "Cut" -state $state
350        $itk_component(emenu) entryconfigure "Copy" -state $state
351        $itk_component(emenu) entryconfigure "Paste" -state $state
352    } elseif {$_mode == "text"} {
353        $itk_component(text) configure -state $state
354        $itk_component(tmenu) entryconfigure "Cut" -state $state
355        $itk_component(tmenu) entryconfigure "Copy" -state $state
356        $itk_component(tmenu) entryconfigure "Paste" -state $state
357    }
358}
359
360# ----------------------------------------------------------------------
361# CONFIGURATION OPTION: -width
362# ----------------------------------------------------------------------
363itcl::configbody Rappture::TextEntry::width {
364    # check size to see if it has the proper form
365    winfo pixels $itk_component(hull) $itk_option(-width)
366    $_dispatcher event -idle !layout
367}
368
369# ----------------------------------------------------------------------
370# CONFIGURATION OPTION: -height
371# ----------------------------------------------------------------------
372itcl::configbody Rappture::TextEntry::height {
373    # check size to see if it has the proper form
374    winfo pixels $itk_component(hull) $itk_option(-height)
375    $_dispatcher event -idle !layout
376}
Note: See TracBrowser for help on using the repository browser.