source: trunk/gui/scripts/radiodial.tcl @ 1400

Last change on this file since 1400 was 1400, checked in by mmc, 16 years ago

Fixed support ticket #5831, which produced an error message like:

can't set _cntlInfo(...): bad value "1e+18/cm3"

The problem arose when you simulated two values like 1e+18 and 1.0e+18.
The Radiodial understood that these were the same value, but it honored
only one of the string representations and rejected the other when you
tried to adjust the dials. It now keeps all recognized string values,
and maps the string onto the real value when you're manipulating the
control. Also fixed the ResultSet? to avoid creating the Radiodial when
the value is numerically the same even though strings are different.

File size: 25.6 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: Radiodial - selector, like the dial on a car radio
3#
4#  This widget looks like the dial on an old-fashioned car radio.
5#  It draws a series of values along an axis, and allows a selector
6#  to move back and forth to select the values.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005  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
15
16option add *Radiodial.thickness 10 widgetDefault
17option add *Radiodial.length 2i widgetDefault
18option add *Radiodial.knobImage knob widgetDefault
19option add *Radiodial.knobPosition n@middle widgetDefault
20option add *Radiodial.dialOutlineColor black widgetDefault
21option add *Radiodial.dialFillColor white widgetDefault
22option add *Radiodial.lineColor gray widgetDefault
23option add *Radiodial.activeLineColor black widgetDefault
24option add *Radiodial.padding 0 widgetDefault
25option add *Radiodial.valueWidth 10 widgetDefault
26option add *Radiodial.valuePadding 0.1 widgetDefault
27option add *Radiodial.foreground black widgetDefault
28option add *Radiodial.font \
29    -*-helvetica-medium-r-normal-*-12-* widgetDefault
30
31itcl::class Rappture::Radiodial {
32    inherit itk::Widget
33
34    itk_option define -min min Min ""
35    itk_option define -max max Max ""
36    itk_option define -variable variable Variable ""
37
38    itk_option define -thickness thickness Thickness 0
39    itk_option define -length length Length 0
40    itk_option define -padding padding Padding 0
41
42    itk_option define -foreground foreground Foreground "black"
43    itk_option define -dialoutlinecolor dialOutlineColor Color "black"
44    itk_option define -dialfillcolor dialFillColor Color "white"
45    itk_option define -dialprogresscolor dialProgressColor Color ""
46    itk_option define -linecolor lineColor Color "black"
47    itk_option define -activelinecolor activeLineColor Color "black"
48    itk_option define -knobimage knobImage KnobImage ""
49    itk_option define -knobposition knobPosition KnobPosition ""
50
51    itk_option define -font font Font ""
52    itk_option define -valuewidth valueWidth ValueWidth 0
53    itk_option define -valuepadding valuePadding ValuePadding 0
54
55
56    constructor {args} { # defined below }
57    destructor { # defined below }
58
59    public method add {label {value ""}}
60    public method clear {}
61    public method get {args}
62    public method current {args}
63    public method color {value}
64                                                                               
65    protected method _setCurrent {val}
66    protected method _redraw {}
67    protected method _click {x y}
68    protected method _navigate {offset}
69    protected method _limits {}
70    protected method _findLabel {str}
71    protected method _fixSize {}
72    protected method _fixValue {args}
73
74    private variable _values ""       ;# list of all values on the dial
75    private variable _val2label       ;# maps value => string label(s)
76    private variable _current ""      ;# current value (where pointer is)
77    private variable _variable ""     ;# variable associated with -variable
78
79    private variable _knob ""         ;# image for knob
80    private variable _spectrum ""     ;# width allocated for values
81    private variable _activecolor ""  ;# width allocated for values
82    private variable _vwidth 0        ;# width allocated for values
83}
84                                                                               
85itk::usual Radiodial {
86    keep -background -foreground -cursor -font
87}
88
89# ----------------------------------------------------------------------
90# CONSTRUCTOR
91# ----------------------------------------------------------------------
92itcl::body Rappture::Radiodial::constructor {args} {
93    itk_component add dial {
94        canvas $itk_interior.dial
95    }
96    pack $itk_component(dial) -expand yes -fill both
97    bind $itk_component(dial) <Configure> [itcl::code $this _redraw]
98
99    bind $itk_component(dial) <ButtonPress-1> [itcl::code $this _click %x %y]
100    bind $itk_component(dial) <B1-Motion> [itcl::code $this _click %x %y]
101    bind $itk_component(dial) <ButtonRelease-1> [itcl::code $this _click %x %y]
102
103    bind $itk_component(hull) <KeyPress-Left> [itcl::code $this _navigate -1]
104    bind $itk_component(hull) <KeyPress-Right> [itcl::code $this _navigate 1]
105
106    eval itk_initialize $args
107
108    _fixSize
109}
110
111# ----------------------------------------------------------------------
112# DESTRUCTOR
113# ----------------------------------------------------------------------
114itcl::body Rappture::Radiodial::destructor {} {
115    configure -variable ""  ;# remove variable trace
116    after cancel [itcl::code $this _redraw]
117}
118
119# ----------------------------------------------------------------------
120# USAGE: add <label> ?<value>?
121#
122# Clients use this to add new values to the dial.  Values are always
123# sorted in order along the dial.  If the value is not specified,
124# then it is created automatically based on the number of elements
125# on the dial.
126# ----------------------------------------------------------------------
127itcl::body Rappture::Radiodial::add {label {value ""}} {
128    if {"" == $value} {
129        set value [llength $_values]
130    }
131
132    # Add this value if we've never see it before
133    if {[lsearch -real $_values $value] < 0} {
134        lappend _values $value
135        set _values [lsort -real $_values]
136    }
137
138    # Keep all equivalent strings for this value.
139    # That way, we can later select either "1e18" or "1.0e+18"
140    lappend _val2label($value) $label
141
142    if {"" == $_current} {
143        _setCurrent $value
144    }
145
146    after cancel [itcl::code $this _redraw]
147    after idle [itcl::code $this _redraw]
148}
149
150# ----------------------------------------------------------------------
151# USAGE: clear
152#
153# Clients use this to remove all existing values from the dial.
154# ----------------------------------------------------------------------
155itcl::body Rappture::Radiodial::clear {} {
156    set _values ""
157    _setCurrent ""
158    catch {unset _val2label}
159
160    after cancel [itcl::code $this _redraw]
161    after idle [itcl::code $this _redraw]
162}
163
164# ----------------------------------------------------------------------
165# USAGE: get ?-format what? ?current|@index?
166#
167# Clients use this to query values within this radiodial.  With no
168# args, it returns a list of all values stored in the widget.  The
169# "current" arg requests only the current value on the radiodial.
170# The @index syntax can be used to request a particular value at
171# an index within the list of values.
172#
173# By default, this method returns the label for each value.  The
174# format option can be used to request the label, the value, or
175# both.
176# ----------------------------------------------------------------------
177itcl::body Rappture::Radiodial::get {args} {
178    Rappture::getopts args params {
179        value -format "label"
180    }
181    if {[llength $args] > 1} {
182        error "wrong # args: should be \"get ?-format f? ?current|@index\""
183    }
184    set index [lindex $args 0]
185    if {"" == $index} {
186        set ilist ""
187        for {set i 0} {$i < [llength $_values]} {incr i} {
188            lappend ilist $i
189        }
190    } elseif {"current" == $index} {
191        set ilist [lsearch -exact $_values $_current]
192        if {$ilist < 0} {
193            set ilist ""
194        }
195    } elseif {[regexp {^@([0-9]+|end)$} $index match i]} {
196        set ilist $i
197    }
198    if {[llength $ilist] == 1} {
199        set op set
200    } else {
201        set op lappend
202    }
203
204    set rlist ""
205    foreach i $ilist {
206        switch -- $params(-format) {
207            label {
208                set v [lindex $_values $i]
209                $op rlist [lindex $_val2label($v) 0]
210            }
211            value {
212                $op rlist [lindex $_values $i]
213            }
214            position {
215                foreach {min max} [_limits] break
216                set v [lindex $_values $i]
217                set frac [expr {double($v-$min)/($max-$min)}]
218                $op rlist $frac
219            }
220            all {
221                set v [lindex $_values $i]
222                foreach {min max} [_limits] break
223                set frac [expr {double($v-$min)/($max-$min)}]
224                set l [lindex $_val2label($v) 0]
225                $op rlist [list $l $v $frac]
226            }
227            default {
228                error "bad value \"$v\": should be label, value, position, all"
229            }
230        }
231    }
232    return $rlist
233}
234
235# ----------------------------------------------------------------------
236# USAGE: current ?<newval>?
237#
238# Clients use this to get/set the current value for this widget.
239# ----------------------------------------------------------------------
240itcl::body Rappture::Radiodial::current {args} {
241    if {[llength $args] == 0} {
242        return $_current
243    } elseif {[llength $args] == 1} {
244        set newval [lindex $args 0]
245        _findLabel $newval  ;# make sure this label is recognized
246        _setCurrent $newval
247
248        after cancel [itcl::code $this _redraw]
249        after idle [itcl::code $this _redraw]
250        event generate $itk_component(hull) <<Value>>
251
252        return $_current
253    }
254    error "wrong # args: should be \"current ?newval?\""
255}
256
257# ----------------------------------------------------------------------
258# USAGE: color <value>
259#
260# Clients use this to query the color associated with a <value>
261# along the dial.
262# ----------------------------------------------------------------------
263itcl::body Rappture::Radiodial::color {value} {
264    _findLabel $value  ;# make sure this label is recognized
265
266    if {"" != $_spectrum} {
267        foreach {min max} [_limits] break
268        set frac [expr {double($value-$min)/($max-$min)}]
269        set color [$_spectrum get $frac]
270    } else {
271        if {$value == $_current} {
272            set color $_activecolor
273        } else {
274            set color $itk_option(-linecolor)
275        }
276    }
277    return $color
278}
279
280# ----------------------------------------------------------------------
281# USAGE: _setCurrent <value>
282#
283# Called automatically whenever the widget changes size to redraw
284# all elements within it.
285# ----------------------------------------------------------------------
286itcl::body Rappture::Radiodial::_setCurrent {value} {
287    set _current $value
288    if {"" != $_variable} {
289        upvar #0 $_variable var
290        if {[info exists _val2label($value)]} {
291            set var [lindex $_val2label($value) 0]
292        } else {
293            set var $value
294        }
295    }
296}
297
298# ----------------------------------------------------------------------
299# USAGE: _redraw
300#
301# Called automatically whenever the widget changes size to redraw
302# all elements within it.
303# ----------------------------------------------------------------------
304itcl::body Rappture::Radiodial::_redraw {} {
305    set c $itk_component(dial)
306    $c delete all
307
308    set fg $itk_option(-foreground)
309
310    set w [winfo width $c]
311    set h [winfo height $c]
312    set p [winfo pixels $c $itk_option(-padding)]
313    set t [expr {$itk_option(-thickness)+1}]
314    set y1 [expr {$h-1}]
315
316    if {"" != $_knob} {
317        set kw [image width $_knob]
318        set kh [image height $_knob]
319
320        switch -- $itk_option(-knobposition) {
321            n@top - nw@top - ne@top {
322                set extra [expr {$t-$kh}]
323                if {$extra < 0} {set extra 0}
324                set y1 [expr {$h-$extra-1}]
325            }
326            n@middle - nw@middle - ne@middle {
327                set extra [expr {int(ceil($kh-0.5*$t))}]
328                if {$extra < 0} {set extra 0}
329                set y1 [expr {$h-$extra-1}]
330            }
331            n@bottom - nw@bottom - ne@bottom {
332                set y1 [expr {$h-$kh-1}]
333            }
334
335            e@top - w@top - center@top -
336            e@bottom - w@bottom - center@bottom {
337                set extra [expr {int(ceil(0.5*$kh))}]
338                set y1 [expr {$h-$extra-1}]
339            }
340            e@middle - w@middle - center@middle {
341                set extra [expr {int(ceil(0.5*($kh-$t)))}]
342                if {$extra < 0} {set extra 0}
343                set y1 [expr {$h-$extra-1}]
344            }
345
346            s@top - sw@top - se@top -
347            s@middle - sw@middle - se@middle -
348            s@bottom - sw@bottom - se@bottom {
349                set y1 [expr {$h-2}]
350            }
351        }
352    }
353    set y0 [expr {$y1-$t}]
354    set x0 [expr {$p+1}]
355    set x1 [expr {$w-$_vwidth-$p-4}]
356    foreach {min max} [_limits] break
357
358    # draw the background rectangle
359    $c create rectangle $x0 $y0 $x1 $y1 \
360        -outline $itk_option(-dialoutlinecolor) \
361        -fill $itk_option(-dialfillcolor)
362
363    # draw the optional progress bar, from start to current
364    if {"" != $itk_option(-dialprogresscolor)
365          && [llength $_values] > 0 && "" != $_current} {
366        if {$max != $min} {
367            set frac [expr {double($_current-$min)/($max-$min)}]
368        } else {
369            set frac 0.
370        }
371        set xx1 [expr {$frac*($x1-$x0) + $x0}]
372        $c create rectangle [expr {$x0+1}] [expr {$y0+3}] $xx1 [expr {$y1-2}] \
373            -outline "" -fill $itk_option(-dialprogresscolor)
374    }
375
376    # draw lines for all values
377    if {$max > $min} {
378        foreach v $_values {
379            set frac [expr {double($v-$min)/($max-$min)}]
380            if {"" != $_spectrum} {
381                set color [$_spectrum get $frac]
382            } else {
383                if {$v == $_current} {
384                    set color $_activecolor
385                } else {
386                    set color $itk_option(-linecolor)
387                }
388            }
389            set thick [expr {($v == $_current) ? 3 : 1}]
390
391            if {"" != $color} {
392                set x [expr {$frac*($x1-$x0) + $x0}]
393                $c create line $x [expr {$y0+1}] $x $y1 \
394                    -fill $color -width $thick
395            }
396        }
397
398        if {"" != $_current} {
399            set x [expr {double($_current-$min)/($max-$min)*($x1-$x0) + $x0}]
400            regexp {([nsew]+|center)@} $itk_option(-knobposition) match anchor
401            switch -glob -- $itk_option(-knobposition) {
402                *@top    { set kpos $y0 }
403                *@middle { set kpos [expr {int(ceil(0.5*($y1+$y0)))}] }
404                *@bottom { set kpos $y1 }
405            }
406            $c create image $x $kpos -anchor $anchor -image $_knob
407        }
408    }
409
410    # if the -valuewidth is > 0, then make room for the value
411    set vw $itk_option(-valuewidth)
412    if {$vw > 0 && "" != $_current} {
413        set str [lindex $_val2label($_current) 0]
414        if {[string length $str] >= $vw} {
415            set str "[string range $str 0 [expr {$vw-3}]]..."
416        }
417
418        set dy [expr {([font metrics $itk_option(-font) -linespace]
419                        - [font metrics $itk_option(-font) -ascent])/2}]
420
421        set id [$c create text [expr {$x1+4}] [expr {($y1+$y0)/2+$dy}] \
422            -anchor w -text $str -font $itk_option(-font) -foreground $fg]
423        foreach {x0 y0 x1 y1} [$c bbox $id] break
424        set x0 [expr {$x0 + 10}]
425
426        # set up a tooltip so you can mouse over truncated values
427        Rappture::Tooltip::text $c [lindex $_val2label($_current) 0]
428        $c bind $id <Enter> \
429            [list ::Rappture::Tooltip::tooltip pending %W +$x0,$y1]
430        $c bind $id <Leave> \
431            [list ::Rappture::Tooltip::tooltip cancel]
432        $c bind $id <ButtonPress> \
433            [list ::Rappture::Tooltip::tooltip cancel]
434        $c bind $id <KeyPress> \
435            [list ::Rappture::Tooltip::tooltip cancel]
436    }
437}
438
439# ----------------------------------------------------------------------
440# USAGE: _click <x> <y>
441#
442# Called automatically whenever the user clicks or drags on the widget
443# to select a value.  Moves the current value to the one nearest the
444# click point.  If the value actually changes, it generates a <<Value>>
445# event to notify clients.
446# ----------------------------------------------------------------------
447itcl::body Rappture::Radiodial::_click {x y} {
448    set c $itk_component(dial)
449    set w [winfo width $c]
450    set h [winfo height $c]
451    set x0 1
452    set x1 [expr {$w-$_vwidth-4}]
453
454    focus $itk_component(hull)
455
456    # draw lines for all values
457    foreach {min max} [_limits] break
458    if {$max > $min && $x >= $x0 && $x <= $x1} {
459        set dmin $w
460        set xnearest 0
461        set vnearest ""
462        foreach v $_values {
463            set xv [expr {double($v-$min)/($max-$min)*($x1-$x0) + $x0}]
464            if {abs($xv-$x) < $dmin} {
465                set dmin [expr {abs($xv-$x)}]
466                set xnearest $xv
467                set vnearest $v
468            }
469        }
470
471        if {$vnearest != $_current} {
472            _setCurrent $vnearest
473            _redraw
474
475            event generate $itk_component(hull) <<Value>>
476        }
477    }
478}
479
480# ----------------------------------------------------------------------
481# USAGE: _navigate <offset>
482#
483# Called automatically whenever the user presses left/right keys
484# to nudge the current value left or right by some <offset>.  If the
485# value actually changes, it generates a <<Value>> event to notify
486# clients.
487# ----------------------------------------------------------------------
488itcl::body Rappture::Radiodial::_navigate {offset} {
489    set index [lsearch -exact $_values $_current]
490    if {$index >= 0} {
491        incr index $offset
492        if {$index >= [llength $_values]} {
493            set index [expr {[llength $_values]-1}]
494        } elseif {$index < 0} {
495            set index 0
496        }
497
498        set newval [lindex $_values $index]
499        if {$newval != $_current} {
500            _setCurrent $newval
501            _redraw
502
503            event generate $itk_component(hull) <<Value>>
504        }
505    }
506}
507
508# ----------------------------------------------------------------------
509# USAGE: _limits
510#
511# Used internally to compute the overall min/max limits for the
512# radio dial.  Returns {min max}, representing the end values for
513# the scale.
514# ----------------------------------------------------------------------
515itcl::body Rappture::Radiodial::_limits {} {
516    if {[llength $_values] == 0} {
517        set min 0
518        set max 0
519    } else {
520        set min [lindex $_values 0]
521        set max $min
522        foreach v [lrange $_values 1 end] {
523            if {$v < $min} { set min $v }
524            if {$v > $max} { set max $v }
525        }
526        set del [expr {$max-$min}]
527        set min [expr {$min-$itk_option(-valuepadding)*$del}]
528        set max [expr {$max+$itk_option(-valuepadding)*$del}]
529    }
530
531    if {"" != $itk_option(-min)} {
532        set min $itk_option(-min)
533    }
534    if {"" != $itk_option(-max)} {
535        set max $itk_option(-max)
536    }
537    return [list $min $max]
538}
539
540# ----------------------------------------------------------------------
541# USAGE: _findLabel <string>
542#
543# Used internally to search for the given <string> label among the
544# known values.  Returns an index into the _values list, or throws
545# an error if the string is not recognized.  Given the null string,
546# it returns -1, indicating that the value is not in _values, but
547# it is valid.
548# ----------------------------------------------------------------------
549itcl::body Rappture::Radiodial::_findLabel {str} {
550    if {"" == $str} {
551        return -1
552    }
553    for {set nv 0} {$nv < [llength $_values]} {incr nv} {
554        set v [lindex $_values $nv]
555        if {[lsearch -exact $_val2label($v) $str] >= 0} {
556            return $nv
557        }
558    }
559    error "bad value \"$str\": should be something matching the raw values \"[join $_values ,]\""
560}
561
562# ----------------------------------------------------------------------
563# USAGE: _fixSize
564#
565# Used internally to compute the overall size of the widget based
566# on the -thickness and -length options.
567# ----------------------------------------------------------------------
568itcl::body Rappture::Radiodial::_fixSize {} {
569    set h [winfo pixels $itk_component(hull) $itk_option(-thickness)]
570
571    if {"" != $_knob} {
572        set kh [image height $_knob]
573
574        switch -- $itk_option(-knobposition) {
575            n@top - nw@top - ne@top -
576            s@bottom - sw@bottom - se@bottom {
577                if {$kh > $h} { set h $kh }
578            }
579            n@middle - nw@middle - ne@middle -
580            s@middle - sw@middle - se@middle {
581                set h [expr {int(ceil(0.5*$h + $kh))}]
582            }
583            n@bottom - nw@bottom - ne@bottom -
584            s@top - sw@top - se@top {
585                set h [expr {$h + $kh}]
586            }
587            e@middle - w@middle - center@middle {
588                set h [expr {(($h > $kh) ? $h : $kh) + 1}]
589            }
590            n@middle - ne@middle - nw@middle -
591            s@middle - se@middle - sw@middle {
592                set extra [expr {int(ceil($kh-0.5*$h))}]
593                if {$extra < 0} { set extra 0 }
594                set h [expr {$h+$extra}]
595            }
596        }
597    }
598    incr h 1
599
600    set w [winfo pixels $itk_component(hull) $itk_option(-length)]
601
602    # if the -valuewidth is > 0, then make room for the value
603    if {$itk_option(-valuewidth) > 0} {
604        set charw [font measure $itk_option(-font) "n"]
605        set _vwidth [expr {$itk_option(-valuewidth)*$charw}]
606        set w [expr {$w+$_vwidth+4}]
607    } else {
608        set _vwidth 0
609    }
610
611    $itk_component(dial) configure -width $w -height $h
612}
613
614# ----------------------------------------------------------------------
615# USAGE: _fixValue ?<name1> <name2> <op>?
616#
617# Invoked automatically whenever the -variable associated with this
618# widget is modified.  Copies the value to the current settings for
619# the widget.
620# ----------------------------------------------------------------------
621itcl::body Rappture::Radiodial::_fixValue {args} {
622    if {"" == $itk_option(-variable)} {
623        return
624    }
625    upvar #0 $itk_option(-variable) var
626
627    set newval $var
628    set n [_findLabel $newval]
629    set newval [expr {($n >= 0) ? [lindex $_values $n] : ""}]
630    set _current $newval  ;# set current directly, so we don't trigger again
631
632    after cancel [itcl::code $this _redraw]
633    after idle [itcl::code $this _redraw]
634    event generate $itk_component(hull) <<Value>>
635}
636
637# ----------------------------------------------------------------------
638# CONFIGURE: -thickness
639# ----------------------------------------------------------------------
640itcl::configbody Rappture::Radiodial::thickness {
641    _fixSize
642}
643
644# ----------------------------------------------------------------------
645# CONFIGURE: -length
646# ----------------------------------------------------------------------
647itcl::configbody Rappture::Radiodial::length {
648    _fixSize
649}
650
651# ----------------------------------------------------------------------
652# CONFIGURE: -font
653# ----------------------------------------------------------------------
654itcl::configbody Rappture::Radiodial::font {
655    _fixSize
656}
657
658# ----------------------------------------------------------------------
659# CONFIGURE: -valuewidth
660# ----------------------------------------------------------------------
661itcl::configbody Rappture::Radiodial::valuewidth {
662    if {![string is integer $itk_option(-valuewidth)]} {
663        error "bad value \"$itk_option(-valuewidth)\": should be integer"
664    }
665    _fixSize
666    after cancel [itcl::code $this _redraw]
667    after idle [itcl::code $this _redraw]
668}
669
670# ----------------------------------------------------------------------
671# CONFIGURE: -foreground
672# ----------------------------------------------------------------------
673itcl::configbody Rappture::Radiodial::foreground {
674    after cancel [itcl::code $this _redraw]
675    after idle [itcl::code $this _redraw]
676}
677
678# ----------------------------------------------------------------------
679# CONFIGURE: -dialoutlinecolor
680# ----------------------------------------------------------------------
681itcl::configbody Rappture::Radiodial::dialoutlinecolor {
682    after cancel [itcl::code $this _redraw]
683    after idle [itcl::code $this _redraw]
684}
685
686# ----------------------------------------------------------------------
687# CONFIGURE: -dialfillcolor
688# ----------------------------------------------------------------------
689itcl::configbody Rappture::Radiodial::dialfillcolor {
690    after cancel [itcl::code $this _redraw]
691    after idle [itcl::code $this _redraw]
692}
693
694# ----------------------------------------------------------------------
695# CONFIGURE: -dialprogresscolor
696# ----------------------------------------------------------------------
697itcl::configbody Rappture::Radiodial::dialprogresscolor {
698    after cancel [itcl::code $this _redraw]
699    after idle [itcl::code $this _redraw]
700}
701
702# ----------------------------------------------------------------------
703# CONFIGURE: -linecolor
704# ----------------------------------------------------------------------
705itcl::configbody Rappture::Radiodial::linecolor {
706    after cancel [itcl::code $this _redraw]
707    after idle [itcl::code $this _redraw]
708}
709
710# ----------------------------------------------------------------------
711# CONFIGURE: -activelinecolor
712# ----------------------------------------------------------------------
713itcl::configbody Rappture::Radiodial::activelinecolor {
714    set val $itk_option(-activelinecolor)
715    if {[catch {$val isa ::Rappture::Spectrum} valid] == 0 && $valid} {
716        set _spectrum $val
717        set _activecolor ""
718    } elseif {[catch {winfo rgb $itk_component(hull) $val}] == 0} {
719        set _spectrum ""
720        set _activecolor $val
721    } elseif {"" != $val} {
722        error "bad value \"$val\": should be Spectrum object or color"
723    }
724    after cancel [itcl::code $this _redraw]
725    after idle [itcl::code $this _redraw]
726}
727
728# ----------------------------------------------------------------------
729# CONFIGURE: -knobimage
730# ----------------------------------------------------------------------
731itcl::configbody Rappture::Radiodial::knobimage {
732    if {[regexp {^image[0-9]+$} $itk_option(-knobimage)]} {
733        set _knob $itk_option(-knobimage)
734    } elseif {"" != $itk_option(-knobimage)} {
735        set _knob [Rappture::icon $itk_option(-knobimage)]
736    } else {
737        set _knob ""
738    }
739    _fixSize
740
741    after cancel [itcl::code $this _redraw]
742    after idle [itcl::code $this _redraw]
743}
744
745# ----------------------------------------------------------------------
746# CONFIGURE: -knobposition
747# ----------------------------------------------------------------------
748itcl::configbody Rappture::Radiodial::knobposition {
749    if {![regexp {^([nsew]+|center)@(top|middle|bottom)$} $itk_option(-knobposition)]} {
750        error "bad value \"$itk_option(-knobposition)\": should be anchor@top|middle|bottom"
751    }
752    _fixSize
753
754    after cancel [itcl::code $this _redraw]
755    after idle [itcl::code $this _redraw]
756}
757
758# ----------------------------------------------------------------------
759# CONFIGURE: -padding
760# This adds padding on left/right side of dial background.
761# ----------------------------------------------------------------------
762itcl::configbody Rappture::Radiodial::padding {
763    if {[catch {winfo pixels $itk_component(hull) $itk_option(-padding)}]} {
764        error "bad value \"$itk_option(-padding)\": should be size in pixels"
765    }
766}
767
768# ----------------------------------------------------------------------
769# CONFIGURE: -valuepadding
770# This shifts min/max limits in by a fraction of the overall size.
771# ----------------------------------------------------------------------
772itcl::configbody Rappture::Radiodial::valuepadding {
773    if {![string is double $itk_option(-valuepadding)]
774          || $itk_option(-valuepadding) < 0} {
775        error "bad value \"$itk_option(-valuepadding)\": should be >= 0.0"
776    }
777}
778
779# ----------------------------------------------------------------------
780# CONFIGURE: -variable
781# ----------------------------------------------------------------------
782itcl::configbody Rappture::Radiodial::variable {
783    if {"" != $_variable} {
784        upvar #0 $_variable var
785        trace remove variable var write [itcl::code $this _fixValue]
786    }
787
788    set _variable $itk_option(-variable)
789
790    if {"" != $_variable} {
791        upvar #0 $_variable var
792        trace add variable var write [itcl::code $this _fixValue]
793
794        # sync to the current value of this variable
795        if {[info exists var]} {
796            _fixValue
797        }
798    }
799}
Note: See TracBrowser for help on using the repository browser.