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

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

Fixed all fonts to set pixelsize instead of pointsize, so that fonts in
the latest X distribution look right.

Added initial Rappture::bugreport::submit command for submitting bug
reports to nanoHUB.org. This isn't tied in yet, but it's a start.

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