Ignore:
Timestamp:
May 14, 2006 6:49:38 PM (18 years ago)
Author:
mmc
Message:

Fixed the <enable> facility so that it will work correctly even
when an <enable> statement references an element that is loaded
dynamically into a <structure> parameters section. The element
is not found at first, so Rappture prints out a warning message
to stderr. But when the element is loaded later, the <enable>
condition works as expected.

NOTE: When referencing an element that produces one of these
warnings, you must use the standard notation (i.e., type(name))
for each element in the path. Otherwise, the enable/disable
won't work, but you won't get an error about it.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/controlOwner.tcl

    r437 r438  
    2525    public method valuefor {path args}
    2626    public method dependenciesfor {path args}
     27    public method ownerfor {path {skip ""}}
    2728    public method changed {path}
    2829    public method regularize {path}
     
    3132    public method tool {}
    3233
     34    protected method _slave {option args}
     35
    3336    protected variable _owner ""     ;# ControlOwner containing this one
    3437    protected variable _path ""      ;# paths within are relative to this
     38    protected variable _slaves ""    ;# this owner has these slaves
    3539    protected variable _xmlobj ""    ;# Rappture XML description
    3640    private variable _path2widget    ;# maps path => widget on this page
     
    4448# ----------------------------------------------------------------------
    4549itcl::body Rappture::ControlOwner::constructor {owner} {
    46     set parts [split $owner @]
    47     set _owner [lindex $parts 0]
    48     set _path [lindex $parts 1]
     50    if {"" != $owner} {
     51        set parts [split $owner @]
     52        set _owner [lindex $parts 0]
     53        set _path [lindex $parts 1]
     54        $_owner _slave add $this
     55    }
    4956}
    5057
     
    7683    # if this is a query operation, then look for the path
    7784    if {[llength $args] == 0} {
     85        set owner [ownerfor $path]
     86        if {$owner != $this && $owner != ""} {
     87            return [$owner widgetfor $path]
     88        }
    7889        if {[info exists _path2widget($path)]} {
    7990            return $_path2widget($path)
     
    103114# ----------------------------------------------------------------------
    104115itcl::body Rappture::ControlOwner::valuefor {path args} {
     116    set owner [ownerfor $path]
     117
    105118    # if this is a query operation, then look for the path
    106119    if {[llength $args] == 0} {
     120        if {$owner != $this && $owner != ""} {
     121            return [$owner valuefor $path]
     122        }
    107123        if {[info exists _path2widget($path)]} {
    108124            return [$_path2widget($path) value]
    109125        }
     126        # can't find the path? try removing the prefix for this owner
     127        set plen [string length $_path]
     128        if {[string equal -length $plen $_path $path]} {
     129            set relpath [string range $path [expr {$plen+1}] end]
     130            if {[info exists _path2widget($relpath)]} {
     131                return [$_path2widget($relpath) value]
     132            }
     133        }
    110134        return ""
    111135    }
    112136
    113137    # otherwise, set the value
     138    if {$owner != $this && $owner != ""} {
     139        return [eval $owner valuefor $path $args]
     140    }
    114141    if {[llength $args] > 1} {
    115142        error "wrong # args: should be \"valuefor path ?newValue?\""
     
    133160# ----------------------------------------------------------------------
    134161itcl::body Rappture::ControlOwner::dependenciesfor {path args} {
     162    if {"" != $_owner} {
     163        #
     164        # Keep all dependencies at the highest level.
     165        # That way, a structure can come and go, but the
     166        # dependencies remain fixed in the topmost tool.
     167        #
     168        set plen [string length $_path]
     169        if {"" != $_path && ![string equal -length $plen $_path $path]} {
     170            set path $_path.$path
     171        }
     172        return [eval $_owner dependenciesfor $path $args]
     173    }
     174
    135175    # if this is a query operation, then look for the path
    136176    if {[llength $args] == 0} {
     
    151191        }
    152192    }
     193}
     194
     195# ----------------------------------------------------------------------
     196# USAGE: ownerfor <path> ?<skip>?
     197#
     198# Returns the ControlOwner that directly controls the specified <path>.
     199# ----------------------------------------------------------------------
     200itcl::body Rappture::ControlOwner::ownerfor {path {skip ""}} {
     201    if {[info exists _path2widget($path)]} {
     202        return $this
     203    }
     204
     205    # can't find the path? try removing the prefix for this owner
     206    set plen [string length $_path]
     207    if {[string equal -length $plen $_path $path]} {
     208        set relpath [string range $path [expr {$plen+1}] end]
     209        if {[info exists _path2widget($relpath)]} {
     210            return $this
     211        }
     212    }
     213
     214    # couldn't find this path?  then check all subordinates
     215    foreach slave $_slaves {
     216        if {$slave == $skip} {
     217            continue  ;# skip this slave if it's already been searched
     218        }
     219        set rval [$slave ownerfor $path $this]
     220        if {"" != $rval} {
     221            return $rval
     222        }
     223    }
     224
     225    # check the owner as a last resort
     226    if {"" != $_owner && $_owner != $skip} {
     227        set rval [$_owner ownerfor $path $this]
     228        if {"" != $rval} {
     229            return $rval
     230        }
     231    }
     232
     233    return ""
    153234}
    154235
     
    191272itcl::body Rappture::ControlOwner::changed {path} {
    192273    if {"" != $_owner} {
     274        set plen [string length $_path]
     275        if {"" != $_path && ![string equal -length $plen $_path $path]} {
     276            set path $_path.$path
     277        }
    193278        $_owner changed $path
    194279    } else {
     280        # send out any callback notifications
    195281        foreach owner [array names _owner2paths] {
    196282            foreach pattern $_owner2paths($owner) {
     
    201287            }
    202288        }
     289
     290        # find the control panel for each dependency, and tell it
     291        # to update its layout.
     292        foreach cpath [dependenciesfor $path] {
     293            set wv [widgetfor $cpath]
     294            while {"" != $wv} {
     295                set wv [winfo parent $wv]
     296                if {[winfo class $wv] == "Controls"} {
     297                    $wv refresh
     298                    break
     299                }
     300            }
     301        }
    203302    }
    204303}
     
    211310# ----------------------------------------------------------------------
    212311itcl::body Rappture::ControlOwner::regularize {path} {
    213     set rpath [$_xmlobj element -as path $path]
    214     if {"" == $rpath} {
    215         #
    216         # Couldn't find this path?  Then this might be a full path.
    217         # Subtract off the context for this control owner and
    218         # look for the relative path.
    219         #
    220         set plen [string length $_path]
    221         if {[string equal -length $plen $_path $path]} {
    222             set relpath [string range $path [expr {$plen+1}] end]
    223             set rpath [$_xmlobj element -as path $relpath]
     312    set owner [ownerfor $path]
     313    if {$owner != $this && $owner != ""} {
     314        return [$owner regularize $path]
     315    }
     316    set rpath ""
     317    if {"" != $_xmlobj} {
     318        set rpath [$_xmlobj element -as path $path]
     319
     320        # can't find the path? try removing the prefix for this owner
     321        if {"" == $rpath} {
     322            set plen [string length $_path]
     323            if {[string equal -length $plen $_path $path]} {
     324                set relpath [string range $path [expr {$plen+2}] end]
     325                set rpath [$_xmlobj element -as path $relpath]
     326            }
     327        }
     328
     329        if {"" != $rpath && "" != $_path} {
     330            # return a full name for the path
     331            set rpath "$_path.$rpath"
    224332        }
    225333    }
     
    328436# ----------------------------------------------------------------------
    329437itcl::body Rappture::ControlOwner::sync {} {
    330     foreach path [array names _path2widget] {
    331         $_xmlobj put $path.current [$_path2widget($path) value]
     438    # sync all of the widgets under control of this owner
     439    if {"" != $_xmlobj} {
     440        foreach path [array names _path2widget] {
     441            set type [$_xmlobj element -as type $path]
     442            if {[lsearch {group separator control} $type] >= 0} {
     443                continue
     444            }
     445            $_xmlobj put $path.current [$_path2widget($path) value]
     446        }
     447    }
     448
     449    # sync all subordinate slaves as well
     450    foreach slave $_slaves {
     451        $slave sync
    332452    }
    333453}
     
    346466    return $this
    347467}
     468
     469# ----------------------------------------------------------------------
     470# USAGE: _slave add <newobj>...
     471#
     472# Used internally to register the parent-child relationship whenever
     473# one ControlOwner is registered to another.  When the parent syncs,
     474# it causes all of its children to sync.  When a name is being
     475# resolved, it is resolved locally first, then up to the parent for
     476# further resolution.
     477# ----------------------------------------------------------------------
     478itcl::body Rappture::ControlOwner::_slave {option args} {
     479    switch -- $option {
     480        add {
     481            eval lappend _slaves $args
     482        }
     483        default {
     484            error "bad option \"$option\": should be add"
     485        }
     486    }
     487}
Note: See TracChangeset for help on using the changeset viewer.