3 # This file implements the TixOptionMenu widget.
5 # Copyright (c) 1996, Expert Interface Technologies
7 # See the file "license.terms" for information on usage and redistribution
8 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 tixWidgetClass tixOptionMenu {
13 -classname TixOptionMenu
14 -superclass tixLabelWidget
16 add delete disable enable entrycget entryconfigure entries
19 -command -disablecallback -dynamicgeometry -value -variable
26 {-command command Command ""}
27 {-disablecallback disableCallback DisableCallback 0 tixVerifyBoolean}
28 {-dynamicgeometry dynamicGeometry DynamicGeometry 0 tixVerifyBoolean}
29 {-state state State normal}
30 {-value value Value ""}
31 {-validatecmd validateCmd ValidateCmd ""}
32 {-variable variable Variable ""}
35 {.highlightThickness 0}
37 {.frame.menubutton.relief raised}
38 {.frame.menubutton.borderWidth 2}
39 {.frame.menubutton.anchor w}
40 {.frame.menubutton.highlightThickness 2}
41 {.frame.menubutton.takeFocus 1}
45 proc tixOptionMenu:InitWidgetRec {w} {
48 tixChainMethod $w InitWidgetRec
57 proc tixOptionMenu:ConstructFramedWidget {w frame} {
60 tixChainMethod $w ConstructFramedWidget $frame
62 set data(w:menubutton) [menubutton $frame.menubutton -indicatoron 1]
63 set data(w:menu) [menu $frame.menubutton.menu -tearoff 0]
64 pack $data(w:menubutton) -side left -expand yes -fill both
66 $data(w:menubutton) config -menu $data(w:menu)
68 bind $data(w:menubutton) <Up> [bind Menubutton <space>]
69 bind $data(w:menubutton) <Down> [bind Menubutton <space>]
71 tixSetMegaWidget $data(w:menubutton) $w
74 proc tixOptionMenu:SetBindings {w} {
77 tixChainMethod $w SetBindings
80 #----------------------------------------------------------------------
82 #----------------------------------------------------------------------
83 proc tixOptionMenu:Invoke {w name} {
86 if {"$data(-state)" == "normal"} {
87 tixOptionMenu:SetValue $w $name
91 proc tixOptionMenu:SetValue {w value {noUpdate 0}} {
94 if {$data(-validatecmd) != ""} {
95 set value [tixEvalCmdBinding $w $data(-validatecmd) "" $value]
100 if {$name == "" || [info exists data(varInited)]} {
101 # variable may contain a bogus value
102 if {![info exists data($name,index)]} {
104 tixVariable:UpdateVariable $w
105 $data(w:menubutton) config -text ""
110 if [info exists data($name,index)] {
111 $data(w:menubutton) config -text $data($name,label)
113 set data(-value) $value
116 tixVariable:UpdateVariable $w
119 if {$data(-command) != "" && !$data(-disablecallback)} {
120 if {![info exists data(varInited)]} {
122 tixEvalCmdBinding $w $data(-command) bind $value
126 error "item \"$value\" does not exist"
130 proc tixOptionMenu:SetMaxWidth {w} {
133 foreach name $data(items) {
134 set len [string length $data($name,label)]
135 if {$data(maxWidth) < $len} {
136 set data(maxWidth) $len
140 if {$data(maxWidth) > 0} {
141 $data(w:menubutton) config -width $data(maxWidth)
145 #----------------------------------------------------------------------
147 #----------------------------------------------------------------------
148 proc tixOptionMenu:config-state {w value} {
151 if ![info exists data(w:label)] {
155 if {$value == "normal"} {
157 $data(w:label) config -fg \
158 [$data(w:menubutton) cget -foreground]
160 $data(w:menubutton) config -state $value
163 $data(w:label) config -fg \
164 [$data(w:menubutton) cget -disabledforeground]
166 $data(w:menubutton) config -state $value
170 proc tixOptionMenu:config-value {w value} {
173 tixOptionMenu:SetValue $w $value
175 # This will tell the Intrinsics: "Please use this value"
176 # because "value" might be altered by SetValues
181 proc tixOptionMenu:config-variable {w arg} {
184 if [tixVariable:ConfigVariable $w $arg] {
185 # The value of data(-value) is changed if tixVariable:ConfigVariable
187 tixOptionMenu:SetValue $w $data(-value) 1
190 unset data(varInited)
192 set data(-variable) $arg
195 #----------------------------------------------------------------------
197 #----------------------------------------------------------------------
198 proc tixOptionMenu:add {w type name args} {
201 if [info exists data($name,index)] {
202 error "item $name already exists in the option menu $w"
211 set opt(-label) $name
213 tixHandleOptions -nounknown opt $validOptions $args
215 if {$opt(-command) != ""} {
216 error "option -command cannot be specified"
219 # Create a new item inside the menu
221 eval $data(w:menu) add command $args \
222 [list -label $opt(-label) \
223 -command "tixOptionMenu:Invoke $w \{$name\}"]
224 set index $data(nItems)
226 # Store info about this item
228 set data($index,name) $name
229 set data($name,type) cmd
230 set data($name,label) $opt(-label)
231 set data($name,index) $index
234 $data(w:menubutton) config -text $data($name,label)
235 tixOptionMenu:SetValue $w $name
239 lappend data(items) $name
241 if $data(-dynamicgeometry) {
242 tixOptionMenu:SetMaxWidth $w
246 $data(w:menu) add separator
248 set index $data(nItems)
249 # Store info about this item
251 set data($index,name) $name
252 set data($name,type) sep
253 set data($name,label) ""
254 set data($name,index) $index
257 lappend data(items) $name
260 error "only types \"separator\" and \"command\" are allowed"
267 proc tixOptionMenu:delete {w item} {
270 if {![info exists data($item,index)]} {
271 error "item $item does not exist in $w"
274 # Rehash the item list
278 foreach name $data(items) {
279 if {$item == $name} {
280 unset data($name,label)
281 unset data($name,index)
282 unset data($name,type)
283 $data(w:menu) delete $oldIndex
285 set data($name,index) $newIndex
286 set data($newIndex,name) $name
288 lappend newItems $name
292 incr oldIndex -1; unset data($oldIndex,name)
293 set data(nItems) $newIndex
294 set data(items) $newItems
296 if {$data(-value) == $item} {
298 foreach item $data(items) {
299 if {$data($item,type) == "cmd"} {
303 tixOptionMenu:SetValue $w $newVal
310 proc tixOptionMenu:disable {w item} {
313 if {![info exists data($item,index)]} {
314 error "item $item does not exist in $w"
316 catch {$data(w:menu) entryconfig $data($item,index) -state disabled}
320 proc tixOptionMenu:enable {w item} {
323 if {![info exists data($item,index)]} {
324 error "item $item does not exist in $w"
326 catch {$data(w:menu) entryconfig $data($item,index) -state normal}
330 proc tixOptionMenu:entryconfigure {w item args} {
333 if {![info exists data($item,index)]} {
334 error "item $item does not exist in $w"
336 return [eval $data(w:menu) entryconfig $data($item,index) $args]
340 proc tixOptionMenu:entrycget {w item arg} {
343 if {![info exists data($item,index)]} {
344 error "item $item does not exist in $w"
346 return [$data(w:menu) entrycget $data($item,index) $arg]
350 proc tixOptionMenu:entries {w} {
357 proc tixOptionMenu:Destructor {w} {
359 tixVariable:DeleteVariable $w
361 # Chain this to the superclass
363 tixChainMethod $w Destructor
366 #----------------------------------------------------------------------
368 # These have been replaced by new commands in Tk 4.0
370 proc tixOptionMenu:Post {w} {
373 set rootx [winfo rootx $data(w:frame)]
374 set rooty [winfo rooty $data(w:frame)]
376 # adjust for the border of the menu and frame
378 incr rootx [lindex [$data(w:menu) config -border] 4]
379 incr rooty [lindex [$data(w:frame) config -border] 4]
380 incr rooty [lindex [$data(w:menu) config -border] 4]
382 set value $data(-value)
383 set y [$data(w:menu) yposition $data($value,index)]
385 $data(w:menu) post $rootx [expr $rooty - $y]
386 $data(w:menu) activate $data($value,index)
387 grab -global $data(w:menubutton)