source: branches/uq/gui/scripts/probdisteditor.tcl @ 5166

Last change on this file since 5166 was 5166, checked in by mmh, 10 years ago

snapshot of uq work

File size: 25.3 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2# ----------------------------------------------------------------------
3#  COMPONENT: ProbDistEditor - probability distribution editor
4#
5#  This widget displays a probability distribution and lets the user
6#  edit it in various flavors.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2010  Purdue University
10#
11#  See the file "license.terms" for information on usage and
12#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13# ======================================================================
14package require Itk
15package require BLT
16
17option add *ProbDistEditor.fillColor blue widgetDefault
18option add *ProbDistEditor*Entry.background white widgetDefault
19option add *ProbDistEditor*Entry.width 10 widgetDefault
20
21    itcl::class Rappture::ProbDistEditor {
22    inherit itk::Widget
23
24    itk_option define -fillcolor fillColor FillColor ""
25
26    constructor {args} { # defined below }
27    public method value {{newval ""}}
28    public method mode {{newval ""}}
29    public method reset {}
30
31    protected method _redraw {}
32    protected method _axisLabels {which graph val}
33    protected method _apply {op {widget ""}}
34
35    protected variable _dispatcher ""   ;# dispatcher for !events
36    protected variable _mode ""         ;# type of distribution function
37    protected variable _value           ;# data values for mode-detail
38    protected variable _uvalue          ;# data values for mode-detail with units
39    protected variable _umin             ;# minimum allowed value for tool with units
40    protected variable _umax             ;# maximum allowed value for tool with units
41    protected variable _units           ;# units for min and max
42}
43
44itk::usual ProbDistEditor {
45    keep -cursor -font -foreground -background
46    keep -fillcolor
47}
48
49# ----------------------------------------------------------------------
50# CONSTRUCTOR
51# ----------------------------------------------------------------------
52itcl::body Rappture::ProbDistEditor::constructor {min max} {
53    # create a dispatcher for events
54    puts "PDE::constructor $min $max"
55
56    # These are the tool min and max values.  May be empty.
57    set _umin $min
58    set _umax $max
59    set _units [Rappture::Units::Search::for $_umin]
60
61    Rappture::dispatcher _dispatcher
62    $_dispatcher register !redraw
63    $_dispatcher dispatch $this !redraw "[itcl::code $this _redraw]; list"
64
65    itk_component add vals {
66        frame $itk_interior.vals
67    }
68    pack $itk_component(vals) -side left -fill both -padx {0 10}
69    #
70    # EXACT value options
71    #
72    itk_component add exactvals {
73        frame $itk_component(vals).exact
74    }
75    itk_component add evl {
76        label $itk_component(exactvals).l -text "Value:"
77    }
78    entry $itk_component(exactvals).val
79    _apply bindings $itk_component(exactvals).val
80    grid $itk_component(evl) -row 0 -column 0 -sticky e
81    grid $itk_component(exactvals).val -row 0 -column 1 -sticky ew -pady 2
82    grid rowconfigure $itk_component(exactvals) 1 -weight 1
83    #
84    # UNIFORM value options
85    #
86    itk_component add uniformvals {
87        frame $itk_component(vals).uniform
88    }
89    itk_component add uvl0 {
90        label $itk_component(uniformvals).l0 -text "Minimum:"
91    }
92    entry $itk_component(uniformvals).min
93    _apply bindings $itk_component(uniformvals).min
94    grid $itk_component(uvl0) -row 0 -column 0 -sticky e
95    grid $itk_component(uniformvals).min -row 0 -column 1 -sticky ew -pady 2
96
97    itk_component add uvl1 {
98        label $itk_component(uniformvals).l1 -text "Maximum:"
99    }
100    entry $itk_component(uniformvals).max
101    _apply bindings $itk_component(uniformvals).max
102    grid $itk_component(uvl1) -row 1 -column 0 -sticky e
103    grid $itk_component(uniformvals).max -row 1 -column 1 -sticky ew -pady 2
104    grid rowconfigure $itk_component(uniformvals) 2 -weight 1
105
106    #
107    # GAUSSIAN value options
108    #
109    itk_component add gaussianvals {
110        frame $itk_component(vals).gaussian
111    }
112    itk_component add gvlm {
113        label $itk_component(gaussianvals).lm -text "Mean:"
114    }
115    entry $itk_component(gaussianvals).mean
116    _apply bindings $itk_component(gaussianvals).mean
117    grid $itk_component(gvlm) -row 0 -column 0 -sticky e
118    grid $itk_component(gaussianvals).mean -row 0 -column 1 -sticky ew -pady 2
119
120    itk_component add gvls {
121        label $itk_component(gaussianvals).ls -text "Std Deviation:"
122    }
123    entry $itk_component(gaussianvals).stddev
124    _apply bindings $itk_component(gaussianvals).stddev
125    grid $itk_component(gvls) -row 1 -column 0 -sticky e
126    grid $itk_component(gaussianvals).stddev -row 1 -column 1 -sticky ew -pady 2
127
128    itk_component add gvl0 {
129        label $itk_component(gaussianvals).l0 -text "Minimum:" -state disabled
130    }
131    entry $itk_component(gaussianvals).min -state readonly
132    _apply bindings $itk_component(gaussianvals).min
133    grid $itk_component(gvl0) -row 2 -column 0 -sticky e
134    grid $itk_component(gaussianvals).min -row 2 -column 1 -sticky ew -pady 2
135
136    itk_component add gvl1 {
137        label $itk_component(gaussianvals).l1 -text "Maximum:" -state disabled
138    }
139    entry $itk_component(gaussianvals).max -state readonly
140    _apply bindings $itk_component(gaussianvals).max
141    grid $itk_component(gvl1) -row 3 -column 0 -sticky e
142    grid $itk_component(gaussianvals).max -row 3 -column 1 -sticky ew -pady 2
143    grid rowconfigure $itk_component(gaussianvals) 4 -weight 1
144
145    #
146    # Preview graph to display probability density function
147    #
148    itk_component add graph {
149        blt::graph $itk_interior.graph -width 2i -height 1i \
150            -plotborderwidth 1 -plotrelief solid -plotpadx 0 -plotpady 0 \
151            -highlightthickness 0
152    } {
153        keep -background -foreground -cursor -font
154    }
155    pack $itk_component(graph) -expand yes -fill both
156
157    $itk_component(graph) xaxis configure -ticklength 4 \
158        -command [itcl::code $this _axisLabels xaxis]
159    $itk_component(graph) yaxis configure -ticklength 4 \
160        -title "PDF" -command [itcl::code $this _axisLabels yaxis]
161    $itk_component(graph) grid off
162    $itk_component(graph) legend configure -hide yes
163
164    # start in exact mode with default values
165    mode "exact"
166
167    eval itk_initialize
168
169    #
170    # Figure out a good size for all panels of options and for the
171    # overall widget.
172    #
173    update idletasks
174    set maxw 0
175    set maxh 0
176    foreach panel {exact uniform gaussian} {
177        set w [winfo reqwidth $itk_component(${panel}vals)]
178        if {$w > $maxw} { set maxw $w }
179        set h [winfo reqheight $itk_component(${panel}vals)]
180        if {$h > $maxh} { set maxh $h }
181    }
182
183    pack propagate $itk_component(vals) off
184    $itk_component(vals) configure -width $maxw -height $maxh
185}
186
187# ----------------------------------------------------------------------
188# USAGE: value ?<setValue>?
189#
190# With no arguments, this returns the current value within the widget
191# as a list of key/value pairs:
192#   mode gaussian mean xxx stddev xxx min xxx max xxx
193#
194# Each value always has a "mode" that indicates its type, and other
195# values to characterize the type.
196#
197# If the value is specified, then it is interpreted as the sort of
198# value that is passed back, but used to set the value.
199# ----------------------------------------------------------------------
200itcl::body Rappture::ProbDistEditor::value {{newval ""}} {
201    puts "PDE::value $newval"
202
203    #FIXME: _value has numerical values _uvalue has value with units
204    if {"" == $newval} {
205        catch {_apply finalize}  ;# apply any outstanding changes
206
207        switch -- $_mode {
208            exact {
209                return $_uvalue(central)
210            }
211            uniform {
212                return [list uniform $_uvalue(min) $_uvalue(max)]
213            }
214            gaussian {
215                return [list gaussian $_uvalue(central) $_uvalue(stddev)]
216            }
217            default {
218                error "don't know how to format value for $_mode"
219            }
220        }
221    }
222
223    set newmode [lindex $newval 0]
224    switch -- $newmode {
225        uniform {
226            foreach {utmp(min) utmp(max)} [lrange $newval 1 2] break
227            if {[catch {Rappture::Units::convert $utmp(min) -units off} tmp(min)]} {
228                set tmp(min) $utmp(min)
229            }
230            if {[catch {Rappture::Units::convert $utmp(max) -units off} tmp(max)]} {
231                set tmp(max) $utmp(max)
232            }
233        }
234        gaussian {
235            foreach {utmp(central) utmp(stddev)} [lrange $newval 1 2] break
236            if {[catch {Rappture::Units::convert $utmp(central) -units off} tmp(central)]} {
237                set tmp(central) $utmp(central)
238            }
239            if {[catch {Rappture::Units::convert $utmp(stddev) -units off} tmp(stddev)]} {
240                set tmp(stddev) $utmp(stddev)
241            }
242            set units [Rappture::Units::Search::for $utmp(central)]
243            if {"" != $_umin} {
244                if {"" != $units} {
245                    set tmp(min) [Rappture::Units::convert $_umin -to $units -context $units -units off]
246                } else {
247                    set tmp(min) $_umin
248                }
249            }
250            if {"" != $_umax} {
251                if {"" != $units} {
252                    set tmp(max) [Rappture::Units::convert $_umax -to $units -context $units -units off]
253                } else {
254                    set tmp(max) $_umax
255                }
256            }
257        }
258        exact {
259            set utmp(central) [lindex $newval 1]
260            if {[catch {Rappture::Units::convert $utmp(central) -units off} tmp(central)]} {
261                set tmp(central) $utmp(central)
262            }
263        }
264        default {
265            set newmode exact
266            set utmp(central) [lindex $newval 0]
267            if {[catch {Rappture::Units::convert $utmp(central) -units off} tmp(central)]} {
268                set tmp(central) $utmp(central)
269            }
270        }
271    }
272    array set _value [array get tmp]
273    array set _uvalue [array get utmp]
274    mode $newmode  ;# assign this mode and copy in values for editing
275}
276
277# ----------------------------------------------------------------------
278# USAGE: mode ?<setMode>?
279#
280# With no arguments, this returns a list of allowed distribution
281# modes.  Otherwise, the value sets the mode of the distribution and
282# loads default or previous values for the distribution.  Note that
283# the mode is also reported as part of the "value" returned from
284# this widget.
285# ----------------------------------------------------------------------
286itcl::body Rappture::ProbDistEditor::mode {{newval ""}} {
287    puts "PDE::mode mode=$newval min=$_umin max=$_umax units=$_units"
288
289    set modes {exact uniform gaussian custom}
290    if {"" == $newval} {
291        return $modes
292    }
293    if {[lsearch $modes $newval] < 0} {
294        error "bad value \"$newval\": should be [join $modes {, }]"
295    }
296
297    # discard units from tool min/max
298    if {$_units == ""} {
299        set min $_umin
300        set max $_umax
301    } else {
302        if {$_umin == ""} {
303            set min ""
304        } else {
305            set min [Rappture::Units::convert $_umin -units off]
306        }
307        if {$_umax == ""} {
308            set max ""
309        } else {
310            set max [Rappture::Units::convert $_umax -units off]
311        }
312    }
313
314    # The mode was changed by the user.  Pick reasonable values.
315    switch -- $newval {
316        exact {
317            if {![info exists _value(central)]} {
318                if {$min != "" && $max != ""} {
319                    set _value(central) [expr {0.5*($max + $min)}]
320                } else {
321                    set _value(central) 0.5
322                }
323                set _uvalue(central) $_value(central)$_units
324            }
325        }
326        uniform {
327            if {![info exists _value(min)] || ![info exists _value(max)]} {
328                # puts "UNIFORM min=$min max=$max"
329                if {$min != "" && $max != ""} {
330                    set _value(min) $min
331                    set _value(max) $max
332                } elseif {$min != ""} {
333                    set _value(min) $min
334                    set _value(max) [expr $min + 1]
335                } elseif {$max != ""} {
336                    set _value(max) $max
337                    set _value(min) [expr $max - 1]
338                }
339                set _uvalue(min) $_value(min)$_units
340                set _uvalue(max) $_value(max)$_units
341            }
342        }
343        gaussian {
344            # puts "GAUSSIAN min=$min max=$max"
345            if {![info exists _value(central)]} {
346                if {[info exists _value(min)] && [info exists _value(max)]} {
347                    set _value(central) [expr {0.5*($_value(max) + $_value(min))}]
348                } else {
349                    set _value(central) [expr {0.5*($max + $min)}]
350                }
351            }
352            # puts "central=$_value(central)"
353            if {![info exists _value(stddev)]} {
354                if {[info exists _value(min)] && [info exists _value(max)]} {
355                    set _value(stddev) [expr {0.3*($_value(max) - $_value(min))}]
356                } elseif {$min != "" && $max != ""} {
357                    set _value(stddev) [expr {0.3*($max - $min)}]
358                } else {
359                    set _value(stddev)  [expr $_value(central) * 0.10]
360                }
361            }
362            if {$_value(stddev) <= 0} {
363                set _value(stddev) 1.0
364            }
365            # puts "stddev=$_value(stddev)"
366            # lower bound is -3 deviations or tool min
367            set trunc [expr {$_value(central) - 3*$_value(stddev)}]
368            if {$min == "" || $trunc > $min} {
369                set _value(min) $trunc
370            } else {
371                set _value(min) $min
372            }
373
374            # upper bound is +3 deviations or tool max
375            set trunc [expr {$_value(central) + 3*$_value(stddev)}]
376            if {$max == "" || $trunc < $max} {
377                set _value(max) $trunc
378            } else {
379                set _value(max) $max
380            }
381
382            set _uvalue(min) $_value(min)$_units
383            set _uvalue(max) $_value(max)$_units
384            set _uvalue(central) $_value(central)$_units
385            set _uvalue(stddev) $_value(stddev)$_units
386        }
387    }
388
389    # pop up the panel of editing options for this mode
390    foreach w [pack slaves $itk_component(vals)] {
391        pack forget $w
392    }
393    pack $itk_component(${newval}vals) -expand yes -fill both
394
395    switch -- $newval {
396        exact {
397            $itk_component(exactvals).val delete 0 end
398            $itk_component(exactvals).val insert end $_uvalue(central)
399            focus $itk_component(exactvals).val
400        }
401        uniform {
402            $itk_component(uniformvals).min delete 0 end
403            $itk_component(uniformvals).min insert end $_uvalue(min)
404            $itk_component(uniformvals).max delete 0 end
405            $itk_component(uniformvals).max insert end $_uvalue(max)
406            focus $itk_component(uniformvals).min
407        }
408        gaussian {
409            $itk_component(gaussianvals).mean delete 0 end
410            $itk_component(gaussianvals).mean insert end $_uvalue(central)
411            $itk_component(gaussianvals).stddev delete 0 end
412            $itk_component(gaussianvals).stddev insert end $_uvalue(stddev)
413
414            $itk_component(gaussianvals).min configure -state normal
415            $itk_component(gaussianvals).min delete 0 end
416            $itk_component(gaussianvals).min insert end $_uvalue(min)
417            $itk_component(gaussianvals).min configure -state readonly
418
419            $itk_component(gaussianvals).max configure -state normal
420            $itk_component(gaussianvals).max delete 0 end
421            $itk_component(gaussianvals).max insert end $_uvalue(max)
422            $itk_component(gaussianvals).max configure -state readonly
423
424            focus $itk_component(gaussianvals).mean
425        }
426    }
427
428    set _mode $newval
429    $_dispatcher event -idle !redraw
430}
431
432# ----------------------------------------------------------------------
433# USAGE: reset
434#
435# Clears all value information so that the next value application
436# starts from scratch.  Without a reset, the widget carries information
437# like the "central" value, in case the user changes modes and then
438# changes back.  Reset discards that info and starts fresh.
439# ----------------------------------------------------------------------
440itcl::body Rappture::ProbDistEditor::reset {} {
441    set _mode ""
442    catch {unset _value}
443    catch {unset _uvalue}
444    $_dispatcher event -idle !redraw
445}
446
447# ----------------------------------------------------------------------
448# USAGE: _redraw
449#
450# Used internally to reconfigure the graph to display the current
451# distribution plot.
452# ----------------------------------------------------------------------
453itcl::body Rappture::ProbDistEditor::_redraw {} {
454    set g $itk_component(graph)
455    eval $g element delete [$g element names]
456    eval $g mark delete [$g mark names]
457    switch -- $_mode {
458        exact {
459            $g xaxis configure -majorticks {} -min 0 -max 1 -stepsize 0.1
460            $g yaxis configure -min 0 -max 1
461            $g element create delta \
462                -xdata {0 0.48 0.49 0.50 0.51 0.52 1} \
463                -ydata {0    0 0.05 0.93 0.05    0 0} \
464                -color $itk_option(-foreground) -symbol "" \
465                -areaforeground $itk_option(-fillcolor) -areapattern solid
466            # $g marker create image -anchor nw -coords {0.5 0.95} \
467                -xoffset -6 -yoffset -3 -image [Rappture::icon delta]
468        }
469        uniform {
470            $g xaxis configure -majorticks {} -min 0 -max 1 -stepsize 0.1
471            $g yaxis configure -min 0 -max 1
472
473            # uniform distribution throughout
474            $g element create uniform \
475                -xdata {-0.1 -0.1 1.1 1.1} -ydata {-0.1 0.5 0.5 -0.1} \
476                -color $itk_option(-foreground) -symbol "" \
477                -areaforeground $itk_option(-fillcolor) -areapattern solid
478
479            # left/right limits
480            $g marker create polygon \
481                -coords {-0.1 -0.1 0.1 -0.1 0.1 1.1 -0.1 1.1} \
482                -outline gray -linewidth 1 -fill gray -stipple gray25
483            $g marker create polygon \
484                -coords {1.1 -0.1 0.9 -0.1 0.9 1.1 1.1 1.1} \
485                -outline gray -linewidth 1 -fill gray -stipple gray25
486        }
487        gaussian {
488            set min $_value(min)
489            set max $_value(max)
490            set dx [expr {$max - $min}]
491            set realmin [expr {$min - 0.1 * $dx}]
492            set realmax [expr {$max + 0.1 * $dx}]
493            set mean $_value(central)
494            set sig2 [expr {$_value(stddev) * $_value(stddev)}]
495            $g xaxis configure -min $realmin -max $realmax \
496                -majorticks [list $min $mean $max]
497            $g yaxis configure -min 0 -max 1.1
498            set xdata ""
499            set ydata ""
500            for {set n 0} {$n <= 50} {incr n} {
501                set x [expr {($realmax - $realmin) / 50.0 * $n + $realmin}]
502                lappend xdata $x
503                set expon [expr {-0.5 * ($x - $mean) * ($x - $mean) / $sig2}]
504                if {$expon < -200} {
505                    lappend ydata 0.0
506                } else {
507                    lappend ydata [expr {exp($expon)}]
508                }
509            }
510            $g element create bellcurve \
511                -xdata $xdata -ydata $ydata \
512                -color $itk_option(-foreground) -symbol "" \
513                -areaforeground $itk_option(-fillcolor) -areapattern solid
514
515            # left/right limits
516            set x0m [expr {$min - 0.2 * $dx}]
517            set x0 $min
518            set x1 $max
519            set x1p [expr {$max + 0.2 * $dx}]
520            $g marker create polygon \
521                -coords [list $x0m -0.1 $x0 -0.1 $x0 1.2 $x0m 1.2] \
522                -outline gray -linewidth 1 -fill gray -stipple gray25
523            $g marker create polygon \
524                -coords [list $x1p -0.1 $x1 -0.1 $x1 1.2 $x1p 1.2] \
525                -outline gray -linewidth 1 -fill gray -stipple gray25
526
527            # lines for standard deviation
528            set x0 [expr {$_value(central)-$_value(stddev)}]
529            set x1 [expr {$_value(central)+$_value(stddev)}]
530            $g marker create line \
531                -coords [list $x0 -0.1 $x0 1.2] -linewidth 1 \
532                -outline gray -dashes 2
533            $g marker create line \
534                -coords [list $x1 -0.1 $x1 1.2] -linewidth 1 \
535                -outline gray -dashes 2
536        }
537        custom {
538        }
539        default {
540            error "don't know how to redraw for mode \"$_mode\""
541        }
542    }
543}
544
545# ----------------------------------------------------------------------
546# USAGE: _axisLabels <which> <graph> <val>
547#
548# Used internally to generate axis labels for the x- and y-axes of
549# the graph.  The y-axis doesn't usually have labels since the values
550# aren't meaningful.  The x-axis should show values according to the
551# current mode of input.
552# ----------------------------------------------------------------------
553itcl::body Rappture::ProbDistEditor::_axisLabels {which graph val} {
554    switch -- $which {
555        xaxis {
556            switch -- $_mode {
557                exact {
558                    if {$val == 0.5} {
559                        return $_value(central)
560                    }
561                    return ""
562                }
563                uniform {
564                    if {$val == 0.1} {
565                        return [expr {$_value(min) < $_value(max)
566                            ? $_value(min) : $_value(max)}]
567                    } elseif {$val == 0.9} {
568                        return [expr {$_value(min) > $_value(max)
569                            ? $_value(min) : $_value(max)}]
570                    }
571                    return ""
572                }
573                gaussian {
574                    return $val
575                }
576            }
577        }
578        yaxis {
579            return ""  ;# no labels for y-axis values
580        }
581    }
582}
583
584# ----------------------------------------------------------------------
585# USAGE: _apply bindings <widget>
586# USAGE: _apply value <widget>
587# USAGE: _apply finalize
588#
589# Called automatically whenever a value is edited to check/apply the
590# value and redraw the PDF plot.  If the value is bad, then it is
591# reloaded for editing.  Otherwise, it is applied.
592# ----------------------------------------------------------------------
593itcl::body Rappture::ProbDistEditor::_apply {op {widget ""}} {
594    puts "_apply $op $widget"
595    if {$op != "bindings"} {
596        # need this for value/finalize
597        array set w2uvalue [list \
598            $itk_component(exactvals).val _uvalue(central) \
599            $itk_component(uniformvals).min _uvalue(min) \
600            $itk_component(uniformvals).max _uvalue(max) \
601            $itk_component(gaussianvals).mean _uvalue(central) \
602            $itk_component(gaussianvals).stddev _uvalue(stddev) \
603            $itk_component(gaussianvals).min _uvalue(min) \
604            $itk_component(gaussianvals).max _uvalue(max) \
605        ]
606        array set w2value [list \
607            $itk_component(exactvals).val _value(central) \
608            $itk_component(uniformvals).min _value(min) \
609            $itk_component(uniformvals).max _value(max) \
610            $itk_component(gaussianvals).mean _value(central) \
611            $itk_component(gaussianvals).stddev _value(stddev) \
612            $itk_component(gaussianvals).min _value(min) \
613            $itk_component(gaussianvals).max _value(max) \
614        ]
615    }
616
617    if {$op == "finalize"} {
618        # one of our widgets has focus?
619        set widget [focus]
620        if {![info exists w2value($widget)]} {
621            # nope -- nevermind, nothing to do
622            return
623        }
624        # yes -- continue onward trying to finalize the value in that widget
625        set op "value"
626    }
627
628    switch -- $op {
629        bindings {
630            bind $widget <KeyPress-Tab> [itcl::code $this _apply value %W]
631            bind $widget <KeyPress-Return> [itcl::code $this _apply value %W]
632            bind $widget <FocusOut> [itcl::code $this _apply value %W]
633        }
634        value {
635            set var $w2value($widget)
636            set uvar $w2uvalue($widget)
637            if {$_units == ""} {
638                set newval [$widget get]
639            } else {
640                set newval [Rappture::Units::convert [$widget get] -context $_units]
641            }
642            puts "widget=$widget"
643            set itk $itk_component(gaussianvals).stddev
644            puts "itk=$itk"
645            if {$widget != $itk && [catch {Rappture::Units::mcheck_range $newval $_umin $_umax $_units} err]} {
646                # oops! value is bad -- edit again
647                bell
648                Rappture::Tooltip::cue $widget $err
649                $widget delete 0 end
650                $widget insert end [set $var]
651                $widget select from 0
652                $widget select to end
653                focus $widget
654                return -code break  ;# stop other bindings like tab-traversal
655            }
656            $widget delete 0 end
657            $widget insert end $newval
658            set $uvar $newval
659
660            if {[catch {Rappture::Units::convert $newval -units off} nvar]} {
661                set nvar $newval
662            }
663            set $var $nvar
664
665            $_dispatcher event -idle !redraw
666        }
667        default {
668            error "bad option \"$opt\": should be bindings, value"
669        }
670    }
671}
672
673# ----------------------------------------------------------------------
674# CONFIGURATION OPTION: -fillcolor
675# ----------------------------------------------------------------------
676itcl::configbody Rappture::ProbDistEditor::fillcolor {
677    $_dispatcher event -idle !redraw
678}
Note: See TracBrowser for help on using the repository browser.