source: trunk/gui/scripts/controls.tcl @ 3636

Last change on this file since 3636 was 3636, checked in by mmc, 9 years ago

Fixed the drawing widget to handle notifications from outside widgets, so
that canvas items react to value changes. Also added tooltips for drawing
items.

Nudged the next/back buttons for the pager in a bit, so they're a little
easier to press in the iPad app.

Fixed the Ruby template for the builder to include the overwrite/append flag.

File size: 26.9 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2# ----------------------------------------------------------------------
3#  COMPONENT: controls - a container for various Rappture controls
4#
5#  This widget is a smart frame acting as a container for controls.
6#  Controls are added to this panel, and the panel itself decides
7#  how to arrange them given available space.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
11#
12#  See the file "license.terms" for information on usage and
13#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14# ======================================================================
15package require Itk
16package require BLT
17
18option add *Controls.padding 4 widgetDefault
19option add *Controls.labelFont \
20    -*-helvetica-medium-r-normal-*-12-* widgetDefault
21
22itcl::class Rappture::Controls {
23    inherit itk::Widget
24
25    itk_option define -padding padding Padding 0
26
27    constructor {owner args} { # defined below }
28    destructor { # defined below }
29
30    public method insert {pos path}
31    public method delete {first {last ""}}
32    public method index {name}
33    public method control {args}
34    public method refresh {}
35
36    protected method _layout {}
37    protected method _monitor {name state}
38    protected method _controlChanged {name}
39    protected method _controlValue {path {units ""}}
40    protected method _formatLabel {str}
41    protected method _changeTabs {{why -program}}
42    protected method _resize {}
43
44    private variable _owner ""       ;# controls belong to this owner
45    private variable _tabs ""        ;# optional tabset for groups
46    private variable _frame ""       ;# pack controls into this frame
47    private variable _counter 0      ;# counter for control names
48    private variable _dispatcher ""  ;# dispatcher for !events
49    private variable _controls ""    ;# list of known controls
50    private variable _showing ""     ;# list of enabled (showing) controls
51    private variable _name2info      ;# maps control name => info
52    private variable _scheme ""      ;# layout scheme (tabs/hlabels)
53}
54                                                                               
55itk::usual Controls {
56}
57
58# ----------------------------------------------------------------------
59# CONSTRUCTOR
60# ----------------------------------------------------------------------
61itcl::body Rappture::Controls::constructor {owner args} {
62    Rappture::dispatcher _dispatcher
63    $_dispatcher register !layout
64    $_dispatcher dispatch $this !layout "[itcl::code $this _layout]; list"
65    $_dispatcher register !resize
66    $_dispatcher dispatch $this !resize "[itcl::code $this _resize]; list"
67
68    set _owner $owner
69
70    Rappture::Scroller $itk_interior.sc -xscrollmode none -yscrollmode auto
71    pack $itk_interior.sc -expand yes -fill both
72    set f [$itk_interior.sc contents frame]
73
74    set _tabs [blt::tabset $f.tabs -borderwidth 0 -relief flat \
75        -side top -tearoff 0 -highlightthickness 0 \
76        -selectbackground $itk_option(-background) \
77        -selectcommand [itcl::code $this _changeTabs -user]]
78
79    set _frame [frame $f.inner]
80    pack $_frame -expand yes -fill both
81
82    #
83    # Put this frame in whenever the control frame is empty.
84    # It forces the size to contract back now when controls are deleted.
85    #
86    frame $_frame.empty -width 1 -height 1
87
88    #
89    # Set up a binding that all inserted widgets will use so that
90    # we can monitor their size changes.
91    #
92    bind Controls-$this <Configure> \
93        [list $_dispatcher event -idle !resize]
94
95    eval itk_initialize $args
96}
97
98# ----------------------------------------------------------------------
99# DESTRUCTOR
100# ----------------------------------------------------------------------
101itcl::body Rappture::Controls::destructor {} {
102    delete 0 end
103}
104
105# ----------------------------------------------------------------------
106# USAGE: insert <pos> <path>
107#
108# Clients use this to insert a control into this panel.  The control
109# is inserted into the list at position <pos>, which can be an integer
110# starting from 0 or the keyword "end".  Information about the control
111# is taken from the specified <path>.
112#
113# Returns a name that can be used to identify the control in other
114# methods.
115# ----------------------------------------------------------------------
116itcl::body Rappture::Controls::insert {pos path} {
117    if {$pos ne "end" && ![string is integer $pos]} {
118        set pos [index $pos]
119    }
120
121    incr _counter
122    set name "control$_counter"
123    set path [$_owner xml element -as path $path]
124
125    set _name2info($name-path) $path
126    set _name2info($name-label) ""
127    set _name2info($name-type) ""
128    set _name2info($name-value) [set w $_frame.v$name]
129    set _name2info($name-enable) "yes"
130    set _name2info($name-disablestyle) "greyout"
131
132    set type [$_owner xml element -as type $path]
133    set _name2info($name-type) $type
134    switch -- $type {
135        choice {
136            Rappture::ChoiceEntry $w $_owner $path
137            bind $w <<Value>> [itcl::code $this _controlChanged $name]
138        }
139        group {
140            Rappture::GroupEntry $w $_owner $path
141        }
142        loader {
143            Rappture::Loader $w $_owner $path -tool [$_owner tool]
144            bind $w <<Value>> [itcl::code $this _controlChanged $name]
145        }
146        number {
147            Rappture::NumberEntry $w $_owner $path
148            bind $w <<Value>> [itcl::code $this _controlChanged $name]
149        }
150        integer {
151            Rappture::IntegerEntry $w $_owner $path
152            bind $w <<Value>> [itcl::code $this _controlChanged $name]
153        }
154        boolean {
155            Rappture::BooleanEntry $w $_owner $path
156            bind $w <<Value>> [itcl::code $this _controlChanged $name]
157        }
158        string {
159            Rappture::TextEntry $w $_owner $path
160            bind $w <<Value>> [itcl::code $this _controlChanged $name]
161        }
162        drawing {
163            Rappture::DrawingEntry $w $_owner $path
164        }
165        image {
166            Rappture::ImageEntry $w $_owner $path
167        }
168        control {
169            set label [string trim [$_owner xml get $path.label]]
170            if {"" == $label} {
171                set label "Simulate"
172            }
173            set service [string trim [$_owner xml get $path.service]]
174            button $w -text $label -command [list $service run]
175        }
176        separator {
177            # no widget to create
178            set _name2info($name-value) "--"
179        }
180        note {
181            Rappture::Note $w $_owner $path
182        }
183        periodicelement {
184            Rappture::PeriodicElementEntry $w $_owner $path
185            bind $w <<Value>> [itcl::code $this _controlChanged $name]
186        }
187        default {
188            error "don't know how to add control type \"$type\""
189        }
190    }
191
192    #
193    # If this element has an <enable> expression, then register
194    # its controlling widget here.
195    #
196    set notify [string trim [$_owner xml get $path.about.notify]]
197
198    set disablestyle [string trim [$_owner xml get $path.about.disablestyle]]
199    if { $disablestyle != "" } {
200        set _name2info($name-disablestyle) $disablestyle
201    }
202    #
203    # If this element has an <enable> expression, then register
204    # its controlling widget here.
205    #
206    set enable [string trim [$_owner xml get $path.about.enable]]
207    if {"" == $enable} {
208        set enable yes
209    }
210    if {![string is boolean $enable]} {
211        set re {([a-zA-Z_]+[0-9]*|\([^\(\)]+\)|[a-zA-Z_]+[0-9]*\([^\(\)]+\))(\.([a-zA-Z_]+[0-9]*|\([^\(\)]+\)|[a-zA-Z_]+[0-9]*\([^\(\)]+\)))*(:[-a-zA-Z0-9/]+)?}
212        set rest $enable
213        set enable ""
214        set deps ""
215        while {1} {
216            if {[regexp -indices $re $rest match]} {
217                foreach {s0 s1} $match break
218
219                if {[string index $rest [expr {$s0-1}]] == "\""} {
220                    # string in ""'s? then leave it alone
221                    append enable [string range $rest 0 [expr {$s0-1}]]
222                    set rest [string range $rest $s0 end]
223                    if {[regexp -indices {[^\"]+\"} $rest match]} {
224                        foreach {s0 s1} $match break
225                        append enable [string range $rest $s0 $s1]
226                        set rest [string range $rest [expr {$s1+1}] end]
227                    } else {
228                        puts stderr "WARNING: mismatched quote in enable condition for $path"
229                        puts stderr "   expr: [string trim [$_owner xml get $path.about.enable]]"
230                        set rest ""
231                    }
232                } else {
233                    #
234                    # This is a symbol which should be substituted
235                    # it can be either:
236                    #   input.foo.bar
237                    #   input.foo.bar:units
238                    #
239                    set cpath [string range $rest $s0 $s1]
240                    set parts [split $cpath :]
241                    set ccpath [lindex $parts 0]
242                    set units [lindex $parts 1]
243
244                    # make sure we have the standard path notation
245                    set stdpath [$_owner regularize $ccpath]
246                    if {"" == $stdpath} {
247                        puts stderr "WARNING: don't recognize parameter $cpath in <enable> expression for $path.  This may be buried in a structure that is not yet loaded."
248                        set stdpath $ccpath
249                    }
250                    # substitute [_controlValue ...] call in place of path
251                    append enable [string range $rest 0 [expr {$s0-1}]]
252                    append enable [format {[_controlValue %s %s]} $stdpath $units]
253                    lappend deps $stdpath
254                    set rest [string range $rest [expr {$s1+1}] end]
255                }
256            } else {
257                append enable $rest
258                break
259            }
260        }
261
262        foreach cpath $deps {
263            $_owner dependenciesfor $cpath $path
264        }
265    }
266    set _name2info($name-enable) $enable
267    $_owner widgetfor $path $w
268
269    if {[lsearch {control group drawing separator note} $type] < 0} {
270        # make a label for this control
271        set label [$w label]
272        if {$label ne ""} {
273            set _name2info($name-label) $_frame.l$name
274            set font [option get $itk_component(hull) labelFont Font]
275            label $_name2info($name-label) -text [_formatLabel $label] \
276                -font $font
277        }
278
279        # register the tooltip for this control
280        set tip [$w tooltip]
281        if {$tip ne ""} {
282            Rappture::Tooltip::for $w $tip -log $path
283
284            # add the tooltip to the label too, if there is one
285            if {$_name2info($name-label) ne ""} {
286                Rappture::Tooltip::for $_name2info($name-label) $tip -log $path
287            }
288        }
289    }
290
291    # insert the new control onto the known list
292    set _controls [linsert $_controls $pos $name]
293    _monitor $name on
294
295    # now that we have a new control, we should fix the layout
296    $_dispatcher event -idle !layout
297    _controlChanged $name
298
299    return $name
300}
301
302# ----------------------------------------------------------------------
303# USAGE: delete <first> ?<last>?
304#
305# Clients use this to delete one or more controls from this widget.
306# The <first> and <last> represent the integer index of the desired
307# control.  You can use the "index" method to convert a control name to
308# its integer index.  If only <first> is specified, then that one
309# control is deleted.  If <last> is specified, then all controls in the
310# range <first> to <last> are deleted.
311# ----------------------------------------------------------------------
312itcl::body Rappture::Controls::delete {first {last ""}} {
313    if {$last == ""} {
314        set last $first
315    }
316    if {![string is integer $first]} {
317        set first [index $first]
318    }
319    if {![string is integer $last]} {
320        set last [index $last]
321    }
322
323    foreach name [lrange $_controls $first $last] {
324        _monitor $name off
325
326        if {"" != $_name2info($name-label)} {
327            destroy $_name2info($name-label)
328        }
329        if {"" != $_name2info($name-value)} {
330            destroy $_name2info($name-value)
331        }
332        $_owner widgetfor $_name2info($name-path) ""
333        array unset _name2info $name-*
334    }
335    set _controls [lreplace $_controls $first $last]
336
337    $_dispatcher event -idle !layout
338}
339
340# ----------------------------------------------------------------------
341# USAGE: index <name>|<path>|@n|end
342#
343# Clients use this to convert a control <name> into its corresponding
344# integer index.  Returns an error if the <name> is not recognized.
345# ----------------------------------------------------------------------
346itcl::body Rappture::Controls::index {val} {
347    set i [lsearch $_controls $val]
348    if {$i >= 0} {
349        return $i
350    }
351    if {[regexp {^@([0-9]+)$} $val match i]} {
352        return $i
353    }
354    if {$val eq "end"} {
355        return [expr {[llength $_controls]-1}]
356    }
357
358    # treat as a path name and search for this path
359    foreach name $_controls {
360        if {$_name2info($name-path) eq $val} {
361            set i [lsearch $_controls $name]
362            if {$i >= 0} {
363                return $i
364            }
365        }
366    }
367
368    error "bad control name \"$name\": should be @int or \"end\" or path name or one of [join [lsort $_controls] {, }]"
369}
370
371# ----------------------------------------------------------------------
372# USAGE: control ?-label|-value|-path|-enable? ?<name>|@n?
373#
374# Clients use this to get information about controls.  With no args, it
375# returns a list of all control names.  Otherwise, it returns the frame
376# associated with a control name.  The -label option requests the label
377# widget instead of the value widget.  The -path option requests the
378# path within the XML that the control affects.  The -enable option
379# requests the enabling condition for this control.
380# ----------------------------------------------------------------------
381itcl::body Rappture::Controls::control {args} {
382    if {[llength $args] == 0} {
383        return $_controls
384    }
385    Rappture::getopts args params {
386        flag switch -value default
387        flag switch -label
388        flag switch -path
389        flag switch -enable
390        flag switch -disablestyle
391    }
392    if {[llength $args] == 0} {
393        error "missing control name"
394    }
395    set i [index [lindex $args 0]]
396    set name [lindex $_controls $i]
397
398    set opt $params(switch)
399    return $_name2info($name$opt)
400}
401
402# ----------------------------------------------------------------------
403# USAGE: refresh
404#
405# Clients use this to refresh the layout of the control panel
406# whenever a widget within the panel changes visibility state.
407# ----------------------------------------------------------------------
408itcl::body Rappture::Controls::refresh {} {
409    $_dispatcher event -idle !layout
410}
411
412# ----------------------------------------------------------------------
413# USAGE: _layout
414#
415# Used internally to fix the layout of controls whenever controls
416# are added or deleted, or when the control arrangement changes.
417# There are a lot of heuristics here trying to achieve a "good"
418# arrangement of controls.
419# ----------------------------------------------------------------------
420itcl::body Rappture::Controls::_layout {} {
421    #
422    # Clear any existing layout
423    #
424    foreach name $_controls {
425        foreach elem {label value} {
426            set w $_name2info($name-$elem)
427            if {$w != "" && [winfo exists $w]} {
428                grid forget $w
429            }
430        }
431    }
432    if {[$_tabs size] > 0} {
433        $_tabs delete 0 end
434    }
435    grid forget $_frame.empty
436
437    #
438    # Decide which widgets should be shown and which should be hidden.
439    #
440    set hidden ""
441    set showing ""
442    foreach name $_controls {
443        set show 1
444        set cond $_name2info($name-enable)
445        if {[catch {expr $cond} show] == 0} {
446            set type $_name2info($name-type)
447            set disablestyle $_name2info($name-disablestyle)
448            set lwidget $_name2info($name-label)
449            set vwidget $_name2info($name-value)
450            if {[lsearch -exact {group image structure} $type] >= 0 ||
451                $disablestyle == "hide" } {
452                if {$show ne "" && $show} {
453                    lappend showing $name
454                } else {
455                    lappend hidden $name
456                }
457            } else {
458                # show other objects, but enable/disable them
459                lappend showing $name
460                if {$show ne "" && $show} {
461                    if {[winfo exists $vwidget]} {
462                        $vwidget configure -state normal
463                    }
464                    if {[winfo exists $lwidget]} {
465                        $lwidget configure -foreground \
466                            [lindex [$lwidget configure -foreground] 3]
467                    }
468                } else {
469                    if {[winfo exists $vwidget]} {
470                        $vwidget configure -state disabled
471                    }
472                    if {[winfo exists $lwidget]} {
473                        $lwidget configure -foreground gray
474                    }
475                }
476            }
477        } else {
478            bgerror "Error in <enable> expression for \"$_name2info($name-path)\":\n  $show"
479        }
480    }
481
482    # store the showing tabs in the object so it can be used in _changeTabs
483    set _showing $showing
484
485    #
486    # Decide on a layout scheme:
487    #   tabs ...... best if all elements within are groups
488    #   hlabels ... horizontal labels (label: value)
489    #
490    if {[llength $showing] >= 2} {
491        # assume tabs for multiple groups
492        set _scheme tabs
493        foreach name $showing {
494            set w $_name2info($name-value)
495
496            if {$w == "--" || [winfo class $w] != "GroupEntry"} {
497                # something other than a group? then fall back on hlabels
498                set _scheme hlabels
499                break
500            }
501        }
502    } else {
503        set _scheme hlabels
504    }
505
506    switch -- $_scheme {
507      tabs {
508        #
509        # SCHEME: tabs
510        # put a series of groups into a tabbed notebook
511        #
512
513        # use inner frame within tabs to show current group
514        pack $_tabs -before $_frame -fill x
515
516        set gn 1
517        foreach name $showing {
518            set wv $_name2info($name-value)
519            $wv configure -heading no
520
521            set label [$wv component heading cget -text]
522            if {"" == $label} {
523                set label "Group #$gn"
524            }
525            set _name2info($name-label) $label
526            $_tabs insert end $name -text $label \
527                -activebackground $itk_option(-background)
528
529            incr gn
530        }
531
532        # compute the overall size
533        # BE CAREFUL: do this after setting "-heading no" above
534        $_dispatcher event -now !resize
535
536        grid propagate $_frame off
537        grid columnconfigure $_frame 0 -weight 1
538        grid rowconfigure $_frame 0 -weight 1
539
540        $_tabs select 0; _changeTabs
541      }
542
543      hlabels {
544        #
545        # SCHEME: hlabels
546        # simple "Label: Value" layout
547        #
548        pack forget $_tabs
549        grid propagate $_frame on
550        grid columnconfigure $_frame 0 -weight 0
551        grid rowconfigure $_frame 0 -weight 0
552
553        set expand 0  ;# most controls float to top
554        set row 0
555        foreach name $showing {
556            set wl $_name2info($name-label)
557            if {$wl != "" && [winfo exists $wl]} {
558                grid $wl -row $row -column 0 -sticky e
559            }
560
561            set wv $_name2info($name-value)
562            if {$wv != "" && [winfo exists $wv]} {
563                if {$wl != ""} {
564                    grid $wv -row $row -column 1 -sticky ew
565                } else {
566                    grid $wv -row $row -column 0 -columnspan 2 -sticky ew
567                }
568
569                grid rowconfigure $_frame $row -weight 0
570
571                switch -- [winfo class $wv] {
572                    TextEntry {
573                        if {[regexp {[0-9]+x[0-9]+} [$wv size]]} {
574                            grid $wl -sticky n -pady 4
575                            grid $wv -sticky nsew
576                            grid rowconfigure $_frame $row -weight 1
577                            grid columnconfigure $_frame 1 -weight 1
578                            set expand 1
579                        }
580                    }
581                    GroupEntry {
582                        $wv configure -heading yes
583
584                        #
585                        # Scan through all children in this group
586                        # and see if any demand more space.  If the
587                        # group contains a structure or a note, then
588                        # make sure that the group itself is set to
589                        # expand/fill.
590                        #
591                        set queue [winfo children $wv]
592                        set expandgroup 0
593                        while {[llength $queue] > 0} {
594                            set w [lindex $queue 0]
595                            set queue [lrange $queue 1 end]
596                            set c [winfo class $w]
597                            if {[lsearch {DeviceEditor Note} $c] >= 0} {
598                                set expandgroup 1
599                                break
600                            }
601                            eval lappend queue [winfo children $w]
602                        }
603                        if {$expandgroup} {
604                            set expand 1
605                            grid $wv -sticky nsew
606                            grid rowconfigure $_frame $row -weight 1
607                        }
608                    }
609                    Note {
610                        grid $wv -sticky nsew
611                        grid rowconfigure $_frame $row -weight 1
612                        set expand 1
613                    }
614                }
615                grid columnconfigure $_frame 1 -weight 1
616            } elseif {$wv == "--"} {
617                grid rowconfigure $_frame $row -minsize 10
618            }
619
620            incr row
621            grid rowconfigure $_frame $row -minsize $itk_option(-padding)
622            incr row
623        }
624        grid $_frame.empty -row $row
625
626        #
627        # If there are any hidden items, then make the bottom of
628        # this form fill up any extra space, so the form floats
629        # to the top.  Otherwise, it will jitter around as the
630        # hidden items come and go.
631        #
632        if {[llength $hidden] > 0 && !$expand} {
633            grid rowconfigure $_frame 99 -weight 1
634        } else {
635            grid rowconfigure $_frame 99 -weight 0
636        }
637      }
638    }
639}
640
641# ----------------------------------------------------------------------
642# USAGE: _monitor <name> <state>
643#
644# Used internally to add/remove bindings that cause the widget
645# associated with <name> to notify this controls widget of size
646# changes.  Whenever there is a size change, this controls widget
647# should fix its layout.
648# ----------------------------------------------------------------------
649itcl::body Rappture::Controls::_monitor {name state} {
650    set tag "Controls-$this"
651    set wv $_name2info($name-value)
652    if {$wv == "--" || [catch {bindtags $wv} btags]} {
653        return
654    }
655    set i [lsearch $btags $tag]
656
657    if {$state} {
658        if {$i < 0} {
659            bindtags $wv [linsert $btags 0 $tag]
660        }
661    } else {
662        if {$i >= 0} {
663            bindtags $wv [lreplace $btags $i $i]
664        }
665    }
666}
667
668# ----------------------------------------------------------------------
669# USAGE: _controlChanged <name>
670#
671# Invoked automatically whenever the value for a control changes.
672# Sends a notification along to the tool controlling this panel.
673# ----------------------------------------------------------------------
674itcl::body Rappture::Controls::_controlChanged {name} {
675    set path $_name2info($name-path)
676
677    #
678    # Let the owner know that this control changed.
679    #
680    if {"" != $_owner} {
681        $_owner changed $path
682    }
683}
684
685# ----------------------------------------------------------------------
686# USAGE: _controlValue <path> ?<units>?
687#
688# Used internally to get the value of a control with the specified
689# <path>.  Returns the current value for the control.
690# ----------------------------------------------------------------------
691itcl::body Rappture::Controls::_controlValue {path {units ""}} {
692    if {"" != $_owner} {
693        set val [$_owner valuefor $path]
694        if {"" != $units} {
695            set val [Rappture::Units::convert $val -to $units -units off]
696        }
697        return $val
698    }
699    return ""
700}
701
702# ----------------------------------------------------------------------
703# USAGE: _formatLabel <string>
704#
705# Used internally to format a label <string>.  Trims any excess
706# white space and adds a ":" to the end.  That way, all labels
707# have a uniform look.
708# ----------------------------------------------------------------------
709itcl::body Rappture::Controls::_formatLabel {str} {
710    set str [string trim $str]
711    if {"" != $str && [string index $str end] != ":"} {
712        append str ":"
713    }
714    return $str
715}
716
717# ----------------------------------------------------------------------
718# USAGE: _changeTabs ?-user|-program?
719#
720# Used internally to change tabs when the user clicks on a tab
721# in the "tabs" layout mode.  This mode is used when the widget
722# contains nothing but groups, as a compact way of representing
723# the groups.
724# ----------------------------------------------------------------------
725itcl::body Rappture::Controls::_changeTabs {{why -program}} {
726    set i [$_tabs index select]
727    # we use _showing here instead of _controls because sometimes tabs
728    # are disabled, and the index of the choosen tab always matches
729    # _showing, even if tabs are disabled.
730    set name [lindex $_showing $i]
731    if {$name ne ""} {
732        foreach w [grid slaves $_frame] {
733            grid forget $w
734        }
735
736        set wv $_name2info($name-value)
737        grid $wv -row 0 -column 0 -sticky new
738
739        if {$why eq "-user"} {
740            Rappture::Logger::log group $_name2info($name-path)
741        }
742    }
743}
744
745# ----------------------------------------------------------------------
746# USAGE: _resize
747#
748# Used internally to resize the widget when its contents change.
749# ----------------------------------------------------------------------
750itcl::body Rappture::Controls::_resize {} {
751    switch -- $_scheme {
752        tabs {
753            # compute the overall size
754            # BE CAREFUL: do this after setting "-heading no" above
755            set maxw 0
756            set maxh 0
757            update idletasks
758            foreach name $_controls {
759                set wv $_name2info($name-value)
760                set w [winfo reqwidth $wv]
761                if {$w > $maxw} { set maxw $w }
762                set h [winfo reqheight $wv]
763                if {$h > $maxh} { set maxh $h }
764            }
765            $_frame configure -width $maxw -height $maxh
766        }
767        hlabels {
768            # do nothing
769        }
770    }
771}
772
773# ----------------------------------------------------------------------
774# OPTION: -padding
775# ----------------------------------------------------------------------
776itcl::configbody Rappture::Controls::padding {
777    $_dispatcher event -idle !layout
778}
Note: See TracBrowser for help on using the repository browser.