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

Last change on this file since 3513 was 3513, checked in by gah, 9 years ago

Add string trim to select 'xml get' calls

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