source: trunk/gui/scripts/combochecks.tcl @ 3093

Last change on this file since 3093 was 3056, checked in by mmc, 12 years ago

Fixed an error in the builder "preview" mode related to the reorganization of
the Analyzer code and changed component names.

Fixed the "periodicelement" type in the builder to save/load properly and
offer drop-down lists for default value and other properties.

File size: 9.3 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: combochecks - like a combobox, but items with checkboxes
3#
4#  This widget looks a lot like a combobox, but has a drop-down list
5#  of checkbox items.  The list of checked items is shown in the
6#  entry area as a comma-separated list.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2012  Purdue Research Foundation
10#
11#  See the file "license.terms" for information on usage and
12#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13# ======================================================================
14package require Itk
15package require BLT
16
17option add *Combochecks.borderWidth 2 widgetDefault
18option add *Combochecks.relief sunken widgetDefault
19option add *Combochecks.width 10 widgetDefault
20option add *Combochecks.textBackground white widgetDefault
21option add *Combochecks.textForeground black widgetDefault
22option add *Combochecks.disabledBackground white widgetDefault
23option add *Combochecks.disabledForeground gray widgetDefault
24option add *Combochecks.font -*-helvetica-medium-r-normal-*-12-* widgetDefault
25
26itcl::class Rappture::Combochecks {
27    inherit itk::Widget
28
29    itk_option define -state state State "normal"
30    itk_option define -width width Width 0
31    itk_option define -disabledbackground disabledBackground DisabledBackground ""
32    itk_option define -disabledforeground disabledForeground DisabledForeground ""
33
34    constructor {args} { # defined below }
35
36    public method value {args}
37    public method current {}
38    public method choices {option args}
39
40    protected method _entry {option}
41    protected method _fixDisplay {}
42    protected method _fixState {}
43
44    blt::bitmap define CombochecksArrow {
45        #define arrow_width 8
46        #define arrow_height 4
47        static unsigned char arrow_bits[] = {
48           0xfe, 0x7c, 0x38, 0x10};
49    }
50    private variable _value2label
51    private variable _label2value
52}
53                                                                               
54itk::usual Combochecks {
55    keep -cursor -font
56    keep -foreground -background
57    keep -textforeground -textbackground
58}
59
60# ----------------------------------------------------------------------
61# CONSTRUCTOR
62# ----------------------------------------------------------------------
63itcl::body Rappture::Combochecks::constructor {args} {
64    itk_option add hull.borderwidth hull.relief
65
66    itk_component add button {
67        button $itk_interior.btn -bitmap CombochecksArrow -padx 0 \
68            -borderwidth 1 -relief raised -highlightthickness 0
69    } {
70        usual
71        ignore -highlightthickness -highlightbackground -highlightcolor
72        ignore -borderwidth -relief
73    }
74    pack $itk_component(button) -side right -fill y
75
76    itk_component add entry {
77        entry $itk_interior.entry -borderwidth 0 -relief flat -state disabled
78    } {
79        usual
80        keep -width
81        rename -highlightbackground -textbackground textBackground Background
82        rename -background -textbackground textBackground Background
83        rename -foreground -textforeground textForeground Foreground
84        rename -disabledbackground -textbackground textBackground Background
85        rename -disabledforeground -textforeground textForeground Foreground
86        ignore -borderwidth -relief
87    }
88    pack $itk_component(entry) -side left -expand yes -fill both
89
90    bind $itk_component(entry) <KeyPress-Return> \
91        [itcl::code $this _entry apply]
92    bind $itk_component(entry) <ButtonPress> \
93        [itcl::code $this _entry click]
94
95    itk_component add ddlist {
96        Rappture::Dropdownchecks $itk_component(button).ddlist
97    }
98    bind $itk_component(ddlist) <<DropdownchecksSelect>> \
99        [itcl::code $this _fixDisplay]
100
101    $itk_component(button) configure -command \
102        [list $itk_component(ddlist) post $itk_component(hull) left]
103
104    eval itk_initialize $args
105}
106
107# ----------------------------------------------------------------------
108# USAGE: value ?<newval>?
109#
110# Clients use this to query/set the value for this widget.  With
111# no args, it returns the current value for the widget.  If the
112# <newval> is specified, it sets the value of the widget and
113# sends a <<Value>> event.
114# ----------------------------------------------------------------------
115itcl::body Rappture::Combochecks::value {args} {
116    switch -- [llength $args] {
117        0 {
118            # return a list of checked optons
119            set max [$itk_component(ddlist) size]
120            set rlist ""
121            foreach val [$itk_component(ddlist) get -value] {
122                if {[$itk_component(ddlist) state $val]} {
123                    lappend rlist $val
124                }
125            }
126            return $rlist
127        }
128        1 {
129            set newval [lindex $args 0]
130
131            $itk_component(ddlist) reset
132            foreach part $newval {
133                $itk_component(ddlist) state $part 1
134            }
135            _fixDisplay
136
137            after 10 [list catch \
138                [list event generate $itk_component(hull) <<Value>>]]
139
140        }
141        default {
142            error "wrong # args: should be \"value ?newval?\""
143        }
144    }
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 state <value> ?on|off?
152# USAGE: choices index <value>
153#
154# Clients use this to manipulate the list of choices in the drop-down
155# list.  Each choice is represented by a (computer-friendly) value
156# and its corresponding (human-friendly) label.  The "get" option
157# returns information about options on the list, including the value,
158# the label, or both.
159# ----------------------------------------------------------------------
160itcl::body Rappture::Combochecks::choices {option args} {
161    eval $itk_component(ddlist) $option $args
162}
163
164# ----------------------------------------------------------------------
165# USAGE: _entry apply
166# USAGE: _entry click
167#
168# Used internally to handle the dropdown list for this combobox.  The
169# post/unpost options are invoked when the list is posted or unposted
170# to manage the relief of the controlling button.  The select option
171# is invoked whenever there is a selection from the list, to assign
172# the value back to the gauge.
173# ----------------------------------------------------------------------
174itcl::body Rappture::Combochecks::_entry {option} {
175    switch -- $option {
176        apply {
177            if {$itk_option(-state) == "normal"} {
178                event generate $itk_component(hull) <<Value>>
179            }
180        }
181        click {
182            if {$itk_option(-state) == "normal"} {
183                $itk_component(button) configure -relief sunken
184                update idletasks; after 100
185                $itk_component(button) configure -relief raised
186
187                $itk_component(ddlist) post $itk_component(hull) left
188            }
189        }
190        default {
191            error "bad option \"$option\": should be apply, click"
192        }
193    }
194}
195
196# ----------------------------------------------------------------------
197# USAGE: _fixDisplay
198#
199# Used internally to handle the dropdown list for this combobox.
200# Invoked whenever there is a selection from the list, to assign
201# the value back to the entry.
202# ----------------------------------------------------------------------
203itcl::body Rappture::Combochecks::_fixDisplay {} {
204    $itk_component(entry) configure -state normal
205    $itk_component(entry) delete 0 end
206    $itk_component(entry) insert end [join [value] {, }]
207    $itk_component(entry) configure -state disabled
208}
209
210# ----------------------------------------------------------------------
211# USAGE: _fixState
212#
213# Used internally to fix the widget state when the -state option
214# changes.
215# ----------------------------------------------------------------------
216itcl::body Rappture::Combochecks::_fixState {} {
217    if {$itk_option(-state) == "normal"} {
218        $itk_component(button) configure -state normal
219        $itk_component(entry) configure \
220            -background $itk_option(-textbackground) \
221            -foreground $itk_option(-textforeground) \
222            -disabledbackground $itk_option(-textbackground) \
223            -disabledforeground $itk_option(-textforeground)
224    } else {
225        $itk_component(button) configure -state disabled
226        $itk_component(entry) configure \
227            -background $itk_option(-disabledbackground) \
228            -foreground $itk_option(-disabledforeground) \
229            -disabledbackground $itk_option(-disabledbackground) \
230            -disabledforeground $itk_option(-disabledforeground)
231    }
232
233    if {$itk_option(-state) != "normal"} {
234        # can't keep focus here -- move it along to the next widget
235        if {[focus] == $itk_component(entry)} {
236            focus [tk_focusNext [focus]]
237        }
238    }
239}
240
241# ----------------------------------------------------------------------
242# CONFIGURATION OPTION: -state
243# ----------------------------------------------------------------------
244itcl::configbody Rappture::Combochecks::state {
245    set valid {normal disabled}
246    if {[lsearch -exact $valid $itk_option(-state)] < 0} {
247        error "bad value \"$itk_option(-state)\": should be [join $valid {, }]"
248    }
249    _fixState
250}
Note: See TracBrowser for help on using the repository browser.