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

Last change on this file since 1342 was 1342, checked in by gah, 16 years ago

preliminary HQ output from molvisviewer; unexpand tabs; all jpeg generation at 100%

File size: 24.8 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.