source: branches/r9/gui/scripts/combochecks.tcl @ 4988

Last change on this file since 4988 was 3330, checked in by gah, 11 years ago

merge (by hand) with Rappture1.2 branch

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