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

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

Fix for support ticket #1773 "bad window path name ".main.area..."
Added a band-aid into the whole GUI loading process. MOSFET has been
having trouble loading its structure. A fix for that caused this
problem in CNTbands v2.0. This will hold for now.

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