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

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

initial import

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