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

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

Fixed all fonts to set pixelsize instead of pointsize, so that fonts in
the latest X distribution look right.

Added initial Rappture::bugreport::submit command for submitting bug
reports to nanoHUB.org. This isn't tied in yet, but it's a start.

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 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.