source: trunk/gui/scripts/combobox.tcl @ 111

Last change on this file since 111 was 52, checked in by mmc, 19 years ago
  • Added a back door so we can debug Rappture applications running in the nanoHUB environment.
  • Added format and label controls to the axes of an XY plot.
  • Added a <molecule><about><emblems> directive, a boolean control indicating whether or not the molecule viewer should show the atom labels by default. If missing or "off", the labels are turned off. To turn labels on by default, this must be set to a boolean true value.
  • Fixed the packing bug that was causing tabbed notebooks to be the wrong size (size of last page, rather than max overall size).
  • Added -state option to comboboxes, so they can be disabled.
  • Added a grab stack, so that when a balloon dialog has the grab and a combobox steals it away, the balloon gets it back.
File size: 11.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: combobox - entry widget with a drop-down list of values
3#
4#  This widget is a typical combobox, an entry widget with a drop-down
5#  list of values.  If the -editable option is turned off, then the
6#  value can be set only from the drop-down list.  Otherwise, the
7#  drop-down is treated as a list of preset choices, but the user can
8#  type anything in the entry area.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004-2005
12#  Purdue Research Foundation, West Lafayette, IN
13# ======================================================================
14package require Itk
15package require BLT
16
17option add *Combobox.borderWidth 2 widgetDefault
18option add *Combobox.relief sunken widgetDefault
19option add *Combobox.width 10 widgetDefault
20option add *Combobox.editable yes widgetDefault
21option add *Combobox.textBackground white widgetDefault
22option add *Combobox.textForeground black widgetDefault
23option add *Combobox.disabledBackground white widgetDefault
24option add *Combobox.disabledForeground gray widgetDefault
25option add *Combobox.font -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
26
27itcl::class Rappture::Combobox {
28    inherit itk::Widget
29
30    itk_option define -editable editable Editable ""
31    itk_option define -state state State "normal"
32    itk_option define -width width Width 0
33    itk_option define -disabledbackground disabledBackground DisabledBackground ""
34    itk_option define -disabledforeground disabledForeground DisabledForeground ""
35
36    constructor {args} { # defined below }
37
38    public method value {args}
39    public method translate {value}
40    public method choices {option args}
41
42    protected method _entry {option}
43    protected method _dropdown {option}
44    protected method _fixState {}
45
46    blt::bitmap define ComboboxArrow {
47        #define arrow_width 8
48        #define arrow_height 4
49        static unsigned char arrow_bits[] = {
50           0xfe, 0x7c, 0x38, 0x10};
51    }
52}
53                                                                               
54itk::usual Combobox {
55    keep -cursor -font
56    keep -foreground -background
57    keep -textforeground -textbackground
58    keep -selectbackground -selectforeground -selectborderwidth
59}
60
61# ----------------------------------------------------------------------
62# CONSTRUCTOR
63# ----------------------------------------------------------------------
64itcl::body Rappture::Combobox::constructor {args} {
65    itk_option add hull.borderwidth hull.relief
66
67    itk_component add button {
68        button $itk_interior.btn -bitmap ComboboxArrow -padx 0 \
69            -borderwidth 1 -relief raised -highlightthickness 0
70    } {
71        usual
72        ignore -highlightthickness -highlightbackground -highlightcolor
73        ignore -borderwidth -relief
74    }
75    pack $itk_component(button) -side right -fill y
76
77    itk_component add entry {
78        entry $itk_interior.entry -borderwidth 0 -relief flat
79    } {
80        usual
81        keep -width
82        rename -highlightbackground -textbackground textBackground Background
83        rename -background -textbackground textBackground Background
84        rename -foreground -textforeground textForeground Foreground
85        rename -disabledbackground -textbackground textBackground Background
86        rename -disabledforeground -textforeground textForeground Foreground
87        ignore -borderwidth -relief
88    }
89    pack $itk_component(entry) -side left -expand yes -fill both
90
91    bind $itk_component(entry) <KeyPress-Return> \
92        [itcl::code $this _entry apply]
93    bind $itk_component(entry) <ButtonPress> \
94        [itcl::code $this _entry click]
95
96    itk_component add ddlist {
97        Rappture::Dropdownlist $itk_component(button).ddlist \
98            -postcommand [itcl::code $this _dropdown post] \
99            -unpostcommand [itcl::code $this _dropdown unpost] \
100    }
101
102    bind $itk_component(ddlist) <<DropdownlistSelect>> \
103        [itcl::code $this _dropdown select]
104
105    $itk_component(button) configure -command \
106        [list $itk_component(ddlist) post $itk_component(hull) left]
107
108    eval itk_initialize $args
109}
110
111# ----------------------------------------------------------------------
112# USAGE: value ?<newval>?
113#
114# Clients use this to query/set the value for this widget.  With
115# no args, it returns the current value for the widget.  If the
116# <newval> is specified, it sets the value of the widget and
117# sends a <<Value>> event.
118# ----------------------------------------------------------------------
119itcl::body Rappture::Combobox::value {args} {
120    if {[llength $args] == 1} {
121        set newval [lindex $args 0]
122
123        $itk_component(entry) configure -state normal
124        $itk_component(entry) delete 0 end
125        $itk_component(entry) insert 0 $newval
126        if {!$itk_option(-editable)} {
127            $itk_component(entry) configure -state disabled
128        }
129
130        after 10 [list event generate $itk_component(hull) <<Value>>]
131    } elseif {[llength $args] != 0} {
132        error "wrong # args: should be \"value ?newval?\""
133    }
134    return [$itk_component(entry) get]
135}
136
137# ----------------------------------------------------------------------
138# USAGE: translate <value>
139#
140# Clients use this to translate a value from the entry part of the
141# combobox to one of the underlying values in the combobox.  If the
142# <value> string matches one of the labels for the choices, this
143# method returns the corresponding value.  Otherwise, it returns "".
144# ----------------------------------------------------------------------
145itcl::body Rappture::Combobox::translate {value} {
146    foreach {val label} [choices get -both] {
147        if {$label == $value} {
148            return $val
149        }
150    }
151    return ""
152}
153
154# ----------------------------------------------------------------------
155# USAGE: choices insert <pos> ?<value1> <label1> ...?
156# USAGE: choices delete <first> ?<last>?
157# USAGE: choices get ?-value|-label|-both? ?<index>?
158# USAGE: choices index <value>
159#
160# Clients use this to manipulate the list of choices in the drop-down
161# list.  Each choice is represented by a (computer-friendly) value
162# and its corresponding (human-friendly) label.  The "get" option
163# returns information about options on the list, including the value,
164# the label, or both.
165# ----------------------------------------------------------------------
166itcl::body Rappture::Combobox::choices {option args} {
167    eval $itk_component(ddlist) $option $args
168}
169
170# ----------------------------------------------------------------------
171# USAGE: _entry apply
172# USAGE: _entry click
173#
174# Used internally to handle the dropdown list for this combobox.  The
175# post/unpost options are invoked when the list is posted or unposted
176# to manage the relief of the controlling button.  The select option
177# is invoked whenever there is a selection from the list, to assign
178# the value back to the gauge.
179# ----------------------------------------------------------------------
180itcl::body Rappture::Combobox::_entry {option} {
181    switch -- $option {
182        apply {
183            if {$itk_option(-editable) && $itk_option(-state) == "normal"} {
184                event generate $itk_component(hull) <<Value>>
185            }
186        }
187        click {
188            if {!$itk_option(-editable) && $itk_option(-state) == "normal"} {
189                $itk_component(button) configure -relief sunken
190                update idletasks; after 100
191                $itk_component(button) configure -relief raised
192
193                $itk_component(ddlist) post $itk_component(hull) left
194            }
195        }
196        default {
197            error "bad option \"$option\": should be apply, click"
198        }
199    }
200}
201
202# ----------------------------------------------------------------------
203# USAGE: _dropdown post
204# USAGE: _dropdown unpost
205# USAGE: _dropdown select
206#
207# Used internally to handle the dropdown list for this combobox.  The
208# post/unpost options are invoked when the list is posted or unposted
209# to manage the relief of the controlling button.  The select option
210# is invoked whenever there is a selection from the list, to assign
211# the value back to the gauge.
212# ----------------------------------------------------------------------
213itcl::body Rappture::Combobox::_dropdown {option} {
214    switch -- $option {
215        post {
216            set value [$itk_component(entry) get]
217            set i [$itk_component(ddlist) index -label $value]
218            if {$i >= 0} {
219                $itk_component(ddlist) select clear 0 end
220                $itk_component(ddlist) select set $i
221            }
222        }
223        unpost {
224            if {$itk_option(-editable)} {
225                focus $itk_component(entry)
226            }
227        }
228        select {
229            set val [$itk_component(ddlist) current -label]
230            if {"" != $val} {
231                value $val
232            }
233        }
234        default {
235            error "bad option \"$option\": should be post, unpost, select"
236        }
237    }
238}
239
240# ----------------------------------------------------------------------
241# USAGE: _fixState
242#
243# Used internally to fix the widget state when the -editable/-state
244# options change.
245# ----------------------------------------------------------------------
246itcl::body Rappture::Combobox::_fixState {} {
247    if {$itk_option(-state) == "normal"} {
248        $itk_component(button) configure -state normal
249        $itk_component(entry) configure \
250            -background $itk_option(-textbackground) \
251            -foreground $itk_option(-textforeground) \
252            -disabledbackground $itk_option(-textbackground) \
253            -disabledforeground $itk_option(-textforeground)
254    } else {
255        $itk_component(button) configure -state disabled
256        $itk_component(entry) configure \
257            -background $itk_option(-disabledbackground) \
258            -foreground $itk_option(-disabledforeground) \
259            -disabledbackground $itk_option(-disabledbackground) \
260            -disabledforeground $itk_option(-disabledforeground)
261    }
262
263    if {$itk_option(-editable)} {
264        if {$itk_option(-state) == "normal"} {
265            $itk_component(entry) configure -state normal
266        } else {
267            $itk_component(entry) configure -state disabled
268        }
269    } else {
270        $itk_component(entry) configure -state disabled
271    }
272
273    if {!$itk_option(-editable) || $itk_option(-state) != "normal"} {
274        # can't keep focus here -- move it along to the next widget
275        if {[focus] == $itk_component(entry)} {
276            focus [tk_focusNext [focus]]
277        }
278    }
279}
280
281# ----------------------------------------------------------------------
282# CONFIGURATION OPTION: -editable
283# ----------------------------------------------------------------------
284itcl::configbody Rappture::Combobox::editable {
285    if {![string is boolean -strict $itk_option(-editable)]} {
286        error "bad value \"$itk_option(-editable)\": should be boolean"
287    }
288    _fixState
289}
290
291# ----------------------------------------------------------------------
292# CONFIGURATION OPTION: -state
293# ----------------------------------------------------------------------
294itcl::configbody Rappture::Combobox::state {
295    set valid {normal disabled}
296    if {[lsearch -exact $valid $itk_option(-state)] < 0} {
297        error "bad value \"$itk_option(-state)\": should be [join $valid {, }]"
298    }
299    _fixState
300}
Note: See TracBrowser for help on using the repository browser.