source: trunk/gui/scripts/dropdownlist.tcl @ 83

Last change on this file since 83 was 11, checked in by mmc, 19 years ago

Major reorganization of the entire package. The config.xml file
is now irrelevant. All the action is in the tool.xml file. The
main program now organizes all input into 1) side-by-side pages,
2) input/result (wizard-style) pages, or 3) a series of wizard-
style pages. The <input> can have <phase> parts representing
the various pages.

Added a new ContourResult? widget based on Swaroop's vtk plotting
code.

Also, added easymesh and showmesh to the "tools" directory.
We need these for Eric Polizzi's code.

File size: 10.6 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: dropdownlist - drop-down list of items
3#
4#  This is a drop-down listbox, which might be used in conjunction
5#  with a combobox.
6#
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005
10#  Purdue Research Foundation, West Lafayette, IN
11# ======================================================================
12package require Itk
13
14option add *Dropdownlist.textBackground white widgetDefault
15option add *Dropdownlist.outline black widgetDefault
16option add *Dropdownlist.borderwidth 1 widgetDefault
17option add *Dropdownlist.relief flat widgetDefault
18option add *Dropdownlist.font \
19    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
20
21itcl::class Rappture::Dropdownlist {
22    inherit Rappture::Dropdown
23
24    constructor {args} { # defined below }
25
26    public method insert {pos args}
27    public method delete {first {last ""}}
28    public method index {args}
29    public method get {args}
30    public method size {}
31    public method select {option args}
32    public method current {{what -value}}
33
34    private variable _values ""  ;# values for all elems in list
35    private variable _labels ""  ;# labels for each of the _values
36
37    protected method _adjust {{widget ""}}
38    protected method _react {}
39}
40
41itk::usual Dropdownlist {
42    keep -background -outline -cursor -font
43}
44
45# ----------------------------------------------------------------------
46# CONSTRUCTOR
47# ----------------------------------------------------------------------
48itcl::body Rappture::Dropdownlist::constructor {args} {
49    itk_component add scroller {
50        Rappture::Scroller $itk_interior.sc \
51            -xscrollmode off -yscrollmode auto
52    }
53    pack $itk_component(scroller) -expand yes -fill both
54
55    itk_component add list {
56        listbox $itk_component(scroller).list \
57            -selectmode single -exportselection no \
58            -highlightthickness 0
59    } {
60        usual
61        rename -background -textbackground textBackground Background
62        rename -foreground -textforeground textForeground Foreground
63        ignore -highlightthickness -highlightbackground -highlightcolor
64        keep -relief
65    }
66    $itk_component(scroller) contents $itk_component(list)
67
68    # add bindings so the listbox can react to selections
69    bind RapptureDropdownlist-$this <ButtonRelease> [itcl::code $this _react]
70    bind RapptureDropdownlist-$this <KeyPress-Return> [itcl::code $this _react]
71    bind RapptureDropdownlist-$this <KeyPress-space> [itcl::code $this _react]
72    bind RapptureDropdownlist-$this <KeyPress-Escape> [itcl::code $this unpost]
73
74    set btags [bindtags $itk_component(list)]
75    set i [lsearch $btags [winfo class $itk_component(list)]]
76    if {$i < 0} {
77        set i end
78    }
79    set btags [linsert $btags [expr {$i+1}] RapptureDropdownlist-$this]
80    bindtags $itk_component(list) $btags
81
82    eval itk_initialize $args
83}
84
85# ----------------------------------------------------------------------
86# USAGE: insert <pos> ?<value1> <label1> <value2> <label2> ...?
87#
88# Inserts one or more values into this drop-down list.  Each value
89# has a keyword (computer-friendly value) and a label (human-friendly
90# value).  The labels appear in the listbox.  If the label is "--",
91# then the value is used as the label.
92# ----------------------------------------------------------------------
93itcl::body Rappture::Dropdownlist::insert {pos args} {
94    if {"end" == $pos} {
95        set pos [llength $_values]
96    } elseif {![string is integer -strict $pos]} {
97        error "bad index \"$pos\": should be integer or \"end\""
98    }
99
100    if {[llength $args] == 1} {
101        set args [lindex $args 0]
102    }
103    if {[llength $args] % 2 != 0} {
104        error "wrong # args: should be \"insert pos ?value label ...?\""
105    }
106
107    foreach {val label} $args {
108        if {$label == "--"} {
109            set label $val
110        }
111        set _values [linsert $_values $pos $val]
112        set _labels [linsert $_labels $pos $label]
113        $itk_component(list) insert $pos $label
114        incr pos
115    }
116}
117
118# ----------------------------------------------------------------------
119# USAGE: delete <first> ?<last>?
120#
121# Deletes one or more values from this drop-down list.  The indices
122# <first> and <last> should be integers from 0 or the keyword "end".
123# All values in the specified range are deleted.
124# ----------------------------------------------------------------------
125itcl::body Rappture::Dropdownlist::delete {first {last ""}} {
126    if {$last == ""} {
127        set last $first
128    }
129    if {![regexp {^[0-9]+|end$} $first]} {
130        error "bad index \"$first\": should be integer or \"end\""
131    }
132    if {![regexp {^[0-9]+|end$} $last]} {
133        error "bad index \"$last\": should be integer or \"end\""
134    }
135
136    set _values [lreplace $_values $first $last]
137    set _labels [lreplace $_labels $first $last]
138    $itk_component(list) delete $first $last
139}
140
141# ----------------------------------------------------------------------
142# USAGE: index ?-value|-label? <value>
143#
144# Returns the integer index for the position of the specified <value>
145# in the list.  Returns -1 if the value is not recognized.
146# ----------------------------------------------------------------------
147itcl::body Rappture::Dropdownlist::index {args} {
148    set format -value
149    set first [lindex $args 0]
150    if {$first == "-value" || $first == "-label"} {
151        set format $first
152        set args [lrange $args 1 end]
153    } elseif {[llength $args] > 1} {
154        error "bad option \"$first\": should be -value or -label"
155    }
156    if {[llength $args] != 1} {
157        error "wrong # args: should be \"index ?-value? ?-label? string\""
158    }
159    set value [lindex $args 0]
160
161    switch -- $format {
162        -value { return [lsearch -exact $_values $value] }
163        -label { return [lsearch -exact $_labels $value] }
164    }
165    return -1
166}
167
168# ----------------------------------------------------------------------
169# USAGE: get ?-value|-label|-both? ?<index>?
170#
171# Queries one or more values from the drop-down list.  With no args,
172# it returns a list of all values and labels in the list.  If the
173# index is specified, then it returns the value or label (or both)
174# for the specified index.
175# ----------------------------------------------------------------------
176itcl::body Rappture::Dropdownlist::get {args} {
177    set format -both
178    set first [lindex $args 0]
179    if {[string index $first 0] == "-"} {
180        set choices {-value -label -both}
181        if {[lsearch $choices $first] < 0} {
182            error "bad option \"$first\": should be [join [lsort $choices] {, }]"
183        }
184        set format $first
185        set args [lrange $args 1 end]
186    }
187
188    # return the whole list or just a single value
189    if {[llength $args] > 1} {
190        error "wrong # args: should be \"get ?-value|-label|-both? ?index?\""
191    }
192    if {[llength $args] == 0} {
193        set vlist $_values
194        set llist $_labels
195        set op lappend
196    } else {
197        set i [lindex $args 0]
198        set vlist [list [lindex $_values $i]]
199        set llist [list [lindex $_labels $i]]
200        set op set
201    }
202
203    # scan through and build up the return list
204    set rlist ""
205    foreach v $vlist l $llist {
206        switch -- $format {
207            -value { $op rlist $v }
208            -label { $op rlist $l }
209            -both  { lappend rlist $v $l }
210        }
211    }
212    return $rlist
213}
214
215# ----------------------------------------------------------------------
216# USAGE: size
217#
218# Returns the number of choices in this list.
219# ----------------------------------------------------------------------
220itcl::body Rappture::Dropdownlist::size {} {
221    return [llength $_values]
222}
223
224# ----------------------------------------------------------------------
225# USAGE: select <option> ?<arg> ...?
226#
227# Used to manipulate the selection in the listbox.  All options and
228# args are passed along to the underlying listbox.
229# ----------------------------------------------------------------------
230itcl::body Rappture::Dropdownlist::select {option args} {
231    if {$option == "set"} {
232        $itk_component(list) activate [lindex $args 0]
233    }
234    eval $itk_component(list) selection $option $args
235}
236
237# ----------------------------------------------------------------------
238# USAGE: current ?-value|-label|-both?
239#
240# Clients use this to query the current selection from the listbox.
241# Returns the value, label, or both, according to the option.
242# ----------------------------------------------------------------------
243itcl::body Rappture::Dropdownlist::current {{what -value}} {
244    set i [$itk_component(list) curselection]
245    if {$i != ""} {
246        switch -- $what {
247            -value { return [lindex $_values $i] }
248            -label { return [lindex $_labels $i] }
249            -both  { return [list [lindex $_values $i] [lindex $_labels $i]] }
250            default {
251                error "bad option \"$what\": should be -value, -label, -both"
252            }
253        }
254    }
255    return ""
256}
257
258# ----------------------------------------------------------------------
259# USAGE: _adjust ?<widget>?
260#
261# This method is invoked each time the dropdown is posted to adjust
262# its size and contents.  If the <widget> is specified, it is the
263# controlling widget.
264# ----------------------------------------------------------------------
265itcl::body Rappture::Dropdownlist::_adjust {{widget ""}} {
266    chain $widget
267
268    set fnt [$itk_component(list) cget -font]
269    set maxw 0
270    foreach str $_labels {
271        set w [font measure $fnt $str]
272        if {$w > $maxw} { set maxw $w }
273    }
274    if {$widget != ""} {
275        if {$maxw < [winfo width $widget]} { set maxw [winfo width $widget] }
276    }
277    set avg [font measure $fnt "n"]
278    $itk_component(list) configure -width [expr {round($maxw/double($avg))+1}]
279
280    if {$widget != ""} {
281        set y [expr {[winfo rooty $widget]+[winfo height $widget]}]
282        set h [font metrics $fnt -linespace]
283        set lines [expr {double([winfo screenheight $widget]-$y)/$h}]
284        if {[llength $_labels] < $lines} {
285            $itk_component(list) configure -height [llength $_labels]
286        } else {
287            $itk_component(list) configure -height 10
288        }
289    }
290
291    focus $itk_component(list)
292}
293
294# ----------------------------------------------------------------------
295# USAGE: _react
296#
297# Invoked automatically when the user has selected something from
298# the listbox.  Unposts the drop-down and generates an event letting
299# the client know that the selection has changed.
300# ----------------------------------------------------------------------
301itcl::body Rappture::Dropdownlist::_react {} {
302    unpost
303    event generate $itk_component(hull) <<DropdownlistSelect>>
304}
Note: See TracBrowser for help on using the repository browser.