Changeset 2943 for trunk/gui


Ignore:
Timestamp:
Apr 5, 2012 1:37:35 PM (12 years ago)
Author:
mmc
Message:

Fixed the "Clear" button on the ResultSet? so that you can either
"Clear All" or "Clear One" result. This is nice when you have
generated a lot of results and you want to get rid of a bad one.
Removed the "Parameters..." button and popup. That's almost useless.
We need something like a table that lets you view all datasets and
turn them on/off. The simple "Clear One" sort of works for now.

Fixed the Balloon widget to have a -background option. The newer
style for Rappture going forward will be to use a solid color
(like black) for the balloon background and set the borderwidth
to zero.

Location:
trunk/gui/scripts
Files:
5 edited

Legend:

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

    r2783 r2943  
    5555    public method reset {{when -eventually}}
    5656    public method load {xmlobj}
    57     public method clear {}
     57    public method clear {{xmlobj ""}}
    5858    public method download {option args}
    5959
     
    641641
    642642# ----------------------------------------------------------------------
    643 # USAGE: clear
    644 #
    645 # Discards all results previously loaded into the analyzer.
    646 # ----------------------------------------------------------------------
    647 itcl::body Rappture::Analyzer::clear {} {
    648     foreach obj $_runs {
    649         itcl::delete object $obj
    650     }
    651     set _runs ""
    652 
    653     $itk_component(resultset) clear
    654 
    655     # reset the size of the controls area
    656     set ht [winfo height $itk_component(results)]
    657     set cntlht [$itk_component(resultset) size -controlarea]
    658     set frac [expr {double($cntlht)/$ht}]
    659     $itk_component(results) fraction end $frac
    660 
    661     foreach label [array names _label2page] {
    662         set page $_label2page($label)
    663         destroy $page.rviewer
    664         #$page.rviewer clear
    665     }
    666     $itk_component(resultselector) value ""
    667     $itk_component(resultselector) choices delete 0 end
    668     catch {unset _label2page}
    669     catch {unset _label2desc}
    670     set _plotlist ""
    671 
    672     $itk_component(resultselector) choices insert end --- "---"
    673     $itk_component(resultselector) choices insert end \
    674         @download [Rappture::filexfer::label download]
    675     set _lastlabel ""
     643# USAGE: clear ?<xmlobj>?
     644#
     645# Discards one or more results previously loaded into the analyzer.
     646# If an <xmlobj> is specified, then that one result is cleared.
     647# Otherwise, all results are cleared.
     648# ----------------------------------------------------------------------
     649itcl::body Rappture::Analyzer::clear {{xmlobj ""}} {
     650    if {$xmlobj ne ""} {
     651        set i [lsearch -exact $_runs $xmlobj]
     652        if {$i >= 0} {
     653            itcl::delete object $xmlobj
     654            set _runs [lreplace $_runs $i $i]
     655
     656            # delete this result from all viewers
     657            foreach label [array names _label2page] {
     658                set page $_label2page($label)
     659                $page.rviewer clear $xmlobj
     660            }
     661        }
     662    } else {
     663        # clear everything
     664        foreach obj $_runs {
     665            itcl::delete object $obj
     666        }
     667        set _runs ""
     668    }
     669
     670    if {[llength $_runs] == 0} {
     671        # reset the size of the controls area
     672        set ht [winfo height $itk_component(results)]
     673        set cntlht [$itk_component(resultset) size -controlarea]
     674        set frac [expr {double($cntlht)/$ht}]
     675        $itk_component(results) fraction end $frac
     676
     677        foreach label [array names _label2page] {
     678            set page $_label2page($label)
     679            destroy $page.rviewer
     680        }
     681        $itk_component(resultselector) value ""
     682        $itk_component(resultselector) choices delete 0 end
     683        catch {unset _label2page}
     684        catch {unset _label2desc}
     685        set _plotlist ""
     686
     687        $itk_component(resultselector) choices insert end --- "---"
     688        $itk_component(resultselector) choices insert end \
     689            @download [Rappture::filexfer::label download]
     690        set _lastlabel ""
     691    }
    676692
    677693    #
  • trunk/gui/scripts/balloon.tcl

    r2766 r2943  
    3030    inherit itk::Toplevel
    3131
     32    itk_option define -background background Background ""
    3233    itk_option define -deactivatecommand deactivateCommand DeactivateCommand ""
    3334    itk_option define -dismissbutton dismissButton DismissButton "on"
     
    322323            set bg $itk_option(-background)
    323324            set rgb [winfo rgb . $bg]
    324             set flatbg [format "#%03x%03x%03x" [lindex $rgb 0] [lindex $rgb 1] [lindex $rgb 2]]
     325            set flatbg [format "#%04x%04x%04x" [lindex $rgb 0] [lindex $rgb 1] [lindex $rgb 2]]
    325326            switch -- $itk_option(-relief) {
    326327                raised {
     
    340341                }
    341342            }
    342             set rgb [winfo rgb . $bg]
    343             set bg [format "#%03x%03x%03x" [lindex $rgb 0] [lindex $rgb 1] [lindex $rgb 2]]
     343            set bg [format "#%04x%04x%04x" [lindex $rgb 0] [lindex $rgb 1] [lindex $rgb 2]]
    344344
    345345            $_fills($dir) put $bg -to 0 0 $sw $sh
     
    502502
    503503# ----------------------------------------------------------------------
     504# CONFIGURATION OPTION: -background
     505# ----------------------------------------------------------------------
     506itcl::configbody Rappture::Balloon::background {
     507    _createStems
     508}
     509
     510# ----------------------------------------------------------------------
    504511# CONFIGURATION OPTION: -stemlength
    505512#
  • trunk/gui/scripts/resultset.tcl

    r2783 r2943  
    4141    itk_option define -boldfont boldFont Font ""
    4242    itk_option define -foreground foreground Foreground ""
    43     itk_option define -missingdata missingData MissingData ""
    4443    itk_option define -clearcommand clearCommand ClearCommand ""
    4544    itk_option define -settingscommand settingsCommand SettingsCommand ""
     
    5049
    5150    public method add {xmlobj}
    52     public method clear {}
     51    public method clear {{xmlobj ""}}
    5352    public method activate {column}
    5453    public method contains {xmlobj}
    5554    public method size {{what -results}}
    5655
    57     protected method _doClear {}
     56    protected method _doClear {what}
    5857    protected method _doSettings {{cmd ""}}
    59     protected method _doPrompt {state}
    6058    protected method _control {option args}
    6159    protected method _fixControls {args}
    6260    protected method _fixLayout {args}
     61    protected method _fixNumResults {}
    6362    protected method _fixSettings {args}
    64     protected method _fixExplore {}
    6563    protected method _fixValue {column why}
    6664    protected method _drawValue {column widget wmax}
     
    6967    protected method _getTooltip {role column}
    7068    protected method _getParamDesc {which {index "current"}}
     69    protected method _addOneResult {tuples xmlobj {simnum ""}}
    7170
    7271    private variable _dispatcher ""  ;# dispatchers for !events
    7372    private variable _results ""     ;# tuple of known results
     73    private variable _resultnum 0    ;# counter for result #1, #2, etc.
    7474    private variable _recent ""      ;# most recent result in _results
    7575    private variable _active ""      ;# column with active control
     
    116116    set _results [Rappture::Tuples ::#auto]
    117117    $_results column insert end -name xmlobj -label "top-level XML object"
     118    $_results column insert end -name simnum -label "simulation number"
    118119
    119120
     
    127128    pack $itk_component(cntls) -fill x -pady {0 2}
    128129
    129     itk_component add clear {
    130         button $itk_component(cntls).clear -text "Clear" -state disabled \
     130    itk_component add clearall {
     131        button $itk_component(cntls).clearall -text "Clear" -state disabled \
    131132            -padx 1 -pady 1 \
    132133            -relief flat -overrelief raised \
    133             -command [itcl::code $this _doClear]
     134            -command [itcl::code $this _doClear all]
    134135    } {
    135136        usual
     
    138139        rename -highlightbackground -controlbarbackground controlbarBackground Background
    139140    }
     141    pack $itk_component(clearall) -side right -padx 2 -pady 1
     142    Rappture::Tooltip::for $itk_component(clearall) \
     143        "Clears all results collected so far."
     144
     145    itk_component add clear {
     146        button $itk_component(cntls).clear -text "Clear One" -state disabled \
     147            -padx 1 -pady 1 \
     148            -relief flat -overrelief raised \
     149            -command [itcl::code $this _doClear current]
     150    } {
     151        usual
     152        rename -background -controlbarbackground controlbarBackground Background
     153        rename -foreground -controlbarforeground controlbarForeground Foreground
     154        rename -highlightbackground -controlbarbackground controlbarBackground Background
     155    }
    140156    pack $itk_component(clear) -side right -padx 2 -pady 1
    141157    Rappture::Tooltip::for $itk_component(clear) \
    142         "Clears all results collected so far."
     158        "Clears the result that is currently selected."
    143159
    144160    itk_component add status {
     
    153169    pack $itk_component(status) -side left -padx 2 -pady {2 0}
    154170
    155     itk_component add parameters {
    156         button $itk_component(cntls).params -text "Parameters..." \
    157             -state disabled -padx 1 -pady 1 \
    158             -relief flat -overrelief raised \
    159             -command [list $itk_component(hull).popup activate $itk_component(cntls).params above]
    160     } {
    161         usual
    162         rename -background -controlbarbackground controlbarBackground Background
    163         rename -foreground -controlbarforeground controlbarForeground Foreground
    164         rename -highlightbackground -controlbarbackground controlbarBackground Background
    165     }
    166     pack $itk_component(parameters) -side left -padx 8 -pady 1
    167     Rappture::Tooltip::for $itk_component(parameters) \
    168         "Click to access all parameters."
    169 
    170171    itk_component add dials {
    171172        frame $itk_interior.dials
     
    192193    label $dials.labelmore.arrow -bitmap [Rappture::icon empty] -borderwidth 0
    193194    pack $dials.labelmore.arrow -side left -fill y
    194     _control bind $dials.labelmore.arrow @more
    195195    label $dials.labelmore.name -text "more parameters..." -font $fn \
    196196        -borderwidth 0 -padx 0 -pady 1
     
    198198    label $dials.labelmore.value
    199199    pack $dials.labelmore.value -side left
    200     _control bind $dials.labelmore.name @more
    201     Rappture::Tooltip::for $dials.labelmore \
    202         "@[itcl::code $this _getTooltip more more]"
    203 
    204     # use this pop-up for access to all controls
    205     Rappture::Balloon $itk_component(hull).popup \
    206         -title "Change Parameters" -padx 0 -pady 0
    207     set inner [$itk_component(hull).popup component inner]
    208 
    209     frame $inner.cntls
    210     pack $inner.cntls -side bottom -fill x
    211     frame $inner.cntls.sep -height 2 -borderwidth 1 -relief sunken
    212     pack $inner.cntls.sep -side top -fill x -padx 4 -pady 4
    213     checkbutton $inner.cntls.explore -font $fn \
    214         -text "Explore combinations with no results" \
    215         -variable [itcl::scope _explore] \
    216         -command [itcl::code $this _fixExplore]
    217     pack $inner.cntls.explore -side top -anchor w
    218     Rappture::Tooltip::for $inner.cntls.explore \
    219         "When this option is turned on, you can set parameters to various combinations that have not yet been simulated.  The Simulate button will light up, and you can simulate these missing combinations.\n\nWhen turned off, controls will avoid missing combinations, and automatically snap to the closest available dataset."
    220 
    221     itk_component add options {
    222         Rappture::Scroller $inner.scrl -xscrollmode auto -yscrollmode auto
    223     }
    224     pack $itk_component(options) -expand yes -fill both
    225 
    226     set popup [$itk_component(options) contents frame]
    227     frame $popup.bg
    228200
    229201    eval itk_initialize $args
     
    242214# Adds a new result to this result set.  Scans through all existing
    243215# results to look for a difference compared to previous results.
    244 # Returns the index of this new result to the caller.  The various
    245 # data objects for this result set should be added to their result
    246 # viewers at the same index.
     216# Returns the simulation number (#1, #2, #3, etc.) of this new result
     217# to the caller.  The various data objects for this result set should
     218# be added to their result viewers at the same index.
    247219# ----------------------------------------------------------------------
    248220itcl::body Rappture::ResultSet::add {xmlobj} {
     
    257229    if {"" == $xmlobj0} {
    258230        # first element -- always add
    259         $_results insert end [list $xmlobj]
     231        set simnum "#[incr _resultnum]"
     232        $_results insert end [list $xmlobj $simnum]
     233        _fixNumResults
    260234        set _recent $xmlobj
    261         $itk_component(status) configure -text "1 result"
    262         $itk_component(clear) configure -state normal
    263         if {[$_results size] >= 2} {
    264             $itk_component(parameters) configure -state normal
    265         } else {
    266             $itk_component(parameters) configure -state disabled
    267         }
     235        return $simnum
     236    }
     237
     238    #
     239    # For all later results, find the diffs and add any new columns
     240    # into the results tuple.  The latest result is the most recent.
     241    #
     242    set simnum [_addOneResult $_results $xmlobj]
     243    set _recent $xmlobj
     244    _fixNumResults
     245
     246    return $simnum
     247}
     248
     249# ----------------------------------------------------------------------
     250# USAGE: clear ?<xmlobj>?
     251#
     252# Clears one or all results in this result set.  If no specific
     253# result object is specified, then all results are cleared.
     254# ----------------------------------------------------------------------
     255itcl::body Rappture::ResultSet::clear {{xmlobj ""}} {
     256    set shortlist $itk_component(dials)
     257    set controlsChanged 0
     258
     259    # clear any currently highlighted result
     260    _doSettings
     261
     262    if {$xmlobj ne ""} {
     263        #
     264        # Delete just one result.  Look for the result among the
     265        # tuples and remove it.  Then, rebuild all of the tuples
     266        # by scanning back through them and building them back up.
     267        # This will rebuild the columns/controls as they should
     268        # be now, removing anything that is no longer necessary.
     269        #
     270        set irun [$_results find -format xmlobj $xmlobj]
     271        if {[llength $irun] == 1} {
     272            # figure out where we are in the active control, and
     273            # what value we should display after this one is deleted
     274            set vlist ""
     275            foreach {label val} [_getValues $_active all] {
     276                lappend vlist $label
     277            }
     278            set ipos [lsearch $vlist $_cntlInfo($this-$_active-value)]
     279
     280            set vcurr ""
     281            set vnext ""
     282            if {$ipos >= 0} {
     283                # try to stay at this value, if we can
     284                set vcurr [lindex $vlist $ipos]
     285
     286                # fall back to this value, if we have to
     287                if {$ipos > 0} { incr ipos -1 } else { incr ipos }
     288                set vnext [lindex $vlist $ipos]
     289            }
     290
     291            # delete the value from the tuples of all results
     292            $_results delete $irun
     293
     294            set new [Rappture::Tuples ::#auto]
     295            $new column insert end -name xmlobj -label "top-level XML object"
     296            $new column insert end -name simnum -label "simulation number"
     297
     298            for {set n 0} {$n < [$_results size]} {incr n} {
     299                set rec [lindex [$_results get -format {xmlobj simnum} $n] 0]
     300                foreach {obj num} $rec break
     301                if {$n == 0} {
     302                    $new insert end [list $obj $num]
     303                } else {
     304                    _addOneResult $new $obj $num
     305                }
     306            }
     307
     308            # plug in the new set of rebuilt tuples
     309            itcl::delete object $_results
     310            set _results $new
     311
     312            # delete any adjuster controls that disappeared
     313            foreach col $_cntlInfo($this-all) {
     314                if {[$_results column names $col] eq ""} {
     315                    set id $_cntlInfo($this-$col-id)
     316                    destroy $shortlist.label$id
     317                    array unset _cntlInfo $this-$col*
     318
     319                    set i [lsearch -exact $_cntlInfo($this-all) $col]
     320                    if {$i >= 0} {
     321                        set _cntlInfo($this-all) [lreplace $_cntlInfo($this-all) $i $i]
     322                    }
     323
     324                    if {$col == $_active} {
     325                        # control is going away -- switch to sim # control
     326                        set simnum0 [$_results get -format simnum 0]
     327                        set _cntlInfo($this-simnum-value) $simnum0
     328                        activate simnum
     329                    }
     330                    set controlsChanged 1
     331                }
     332            }
     333
     334            # can we find a tuple with the desired value for the active col?
     335            if {$_active ne "" && $vcurr ne ""} {
     336                set found ""
     337                if {[$_results find -format $_active $vcurr] ne ""} {
     338                    set found $vcurr
     339                } elseif {$vnext ne "" && [$_results find -format $_active $vnext] ne ""} {
     340                    set found $vnext
     341                }
     342
     343                if {$found ne ""} {
     344                    # set the control to a value we were able to find
     345                    # this will trigger !settings and other adjustments
     346                    set _cntlInfo($this-$_active-value) $found
     347                } else {
     348                    # if all else fails, show solution #1
     349                    set simnum0 [$_results get -format simnum 0]
     350                    set _cntlInfo($this-simnum-value) $simnum0
     351                    activate simnum
     352                }
     353            }
     354        }
     355    } else {
     356        #
     357        # Delete all results.
     358        #
     359        $_results delete 0 end
     360
     361        # delete all adjuster controls
     362        foreach col $_cntlInfo($this-all) {
     363            set id $_cntlInfo($this-$col-id)
     364            destroy $shortlist.label$id
     365        }
     366        set controlsChanged 1
     367    }
     368
     369    if {[$_results size] == 0} {
     370        #
     371        # No results left?  Then clean everything up.
     372        #
     373
     374        array unset _cntlInfo $this-*
     375        # clean up control info
     376        foreach key [array names _cntlInfo $this-*] {
     377            catch {unset _cntlInfo($key)}
     378        }
     379        set _cntlInfo($this-all) ""
     380        set _counter 0
     381        set _resultnum 0
     382
     383        # clear out all results
     384        eval $_results column delete [lrange [$_results column names] 2 end]
     385        set _recent ""
     386        set _active ""
     387
     388        set _plotall 0
     389        $itk_component(dials).all configure -relief raised \
     390            -background $itk_option(-background) \
     391            -foreground $itk_option(-foreground)
     392    }
     393
     394    # update status and Clear button
     395    _fixNumResults
     396    $_dispatcher event -idle !fixcntls
     397
     398    # let clients know that the number of controls has changed
     399    if {$controlsChanged} {
     400        event generate $itk_component(hull) <<Control>>
     401    }
     402
     403    # if there's a callback for clearing, invoke it now...
     404    if {[string length $itk_option(-clearcommand)] > 0} {
     405        uplevel #0 $itk_option(-clearcommand) $xmlobj
     406    }
     407}
     408
     409# ----------------------------------------------------------------------
     410# USAGE: activate <column>
     411#
     412# Clients use this to activate a particular column in the set of
     413# controls.  When a column is active, its label is bold and its
     414# value has a radiodial in the "short list" area.
     415# ----------------------------------------------------------------------
     416itcl::body Rappture::ResultSet::activate {column} {
     417    set allowed [$_results column names]
     418    if {[lsearch $allowed $column] < 0} {
     419        error "bad value \"$column\": should be one of [join $allowed {, }]"
     420    }
     421
     422    # column is now active
     423    set _active $column
     424
     425    # keep track of usage, so we know which controls are popular
     426    incr _cntlInfo($this-$column-usage)
     427
     428    # fix controls at next idle point
     429    $_dispatcher event -idle !layout why data
     430    $_dispatcher event -idle !settings column $_active
     431}
     432
     433# ----------------------------------------------------------------------
     434# USAGE: contains <xmlobj>
     435#
     436# Checks to see if the given <xmlobj> is already represented by
     437# some result in this result set.  This comes in handy when checking
     438# to see if an input case is already covered.
     439#
     440# Returns 1 if the result set already contains this result, and
     441# 0 otherwise.
     442# ----------------------------------------------------------------------
     443itcl::body Rappture::ResultSet::contains {xmlobj} {
     444    # no results? then this must be new
     445    if {[$_results size] == 0} {
    268446        return 0
    269447    }
     
    274452    # is a column to represent the quantity with the difference.
    275453    #
     454    set xmlobj0 [$_results get -format xmlobj end]
    276455    foreach {op vpath oldval newval} [$xmlobj0 diff $xmlobj] {
    277456        if {[$xmlobj get $vpath.about.diffs] == "ignore"} {
     
    283462            continue
    284463        }
    285 
    286         # make sure that these values really are different
    287         set oldval [lindex [Rappture::LibraryObj::value $xmlobj0 $vpath] 0]
    288         set newval [lindex [Rappture::LibraryObj::value $xmlobj $vpath] 0]
    289 
    290         if {$oldval != $newval && [$_results column names $vpath] == ""} {
    291             # no column for this quantity yet
    292             $_results column insert end -name $vpath -default $oldval
    293         }
    294     }
    295 
    296     # build a tuple for this new object
    297     set cols ""
    298     set tuple ""
    299     foreach col [lrange [$_results column names] 1 end] {
    300         lappend cols $col
    301         set raw [lindex [Rappture::LibraryObj::value $xmlobj $col] 0]
    302         lappend tuple $raw  ;# use the "raw" (user-readable) label
    303     }
    304 
    305     # find a matching tuple? then replace it -- only need one
    306     if {[llength $cols] > 0} {
    307         set ilist [$_results find -format $cols -- $tuple]
    308     } else {
    309         set ilist 0  ;# no diffs -- must match first entry
    310     }
    311 
    312     # add all remaining columns for this new entry
    313     set tuple [linsert $tuple 0 $xmlobj]
    314 
    315     if {[llength $ilist] > 0} {
    316         if {[llength $ilist] > 1} {
    317             error "why so many matching results?"
    318         }
    319 
    320         # overwrite the first matching entry
    321         set index [lindex $ilist 0]
    322         $_results put $index $tuple
    323         set _recent $xmlobj
    324     } else {
    325         set index [$_results size]
    326         $_results insert end $tuple
    327         set _recent $xmlobj
    328     }
    329 
    330     if {[$_results size] == 1} {
    331         $itk_component(status) configure -text "1 result"
    332     } else {
    333         $itk_component(status) configure -text "[$_results size] results"
    334         $itk_component(parameters) configure -state normal
    335     }
    336     $itk_component(clear) configure -state normal
    337 
    338     return $index
    339 }
    340 
    341 # ----------------------------------------------------------------------
    342 # USAGE: clear
    343 #
    344 # Clears all results in this result set.
    345 # ----------------------------------------------------------------------
    346 itcl::body Rappture::ResultSet::clear {} {
    347     _doSettings
    348 
    349     # delete all adjuster controls
    350     set popup [$itk_component(options) contents frame]
    351     set shortlist $itk_component(dials)
    352 
    353     foreach col $_cntlInfo($this-all) {
    354         set id $_cntlInfo($this-$col-id)
    355         destroy $popup.label$id $popup.dial$id $popup.all$id
    356         destroy $shortlist.label$id
    357     }
    358 
    359     array unset _cntlInfo $this-*
    360     # clean up control info
    361     foreach key [array names _cntlInfo $this-*] {
    362         catch {unset _cntlInfo($key)}
    363     }
    364     set _cntlInfo($this-all) ""
    365     set _counter 0
    366 
    367     # clear out all results
    368     $_results delete 0 end
    369     eval $_results column delete [lrange [$_results column names] 1 end]
    370     set _recent ""
    371     set _active ""
    372 
    373     set _plotall 0
    374     $itk_component(dials).all configure -relief raised \
    375         -background $itk_option(-background) \
    376         -foreground $itk_option(-foreground)
    377 
    378     # update status and Clear button
    379     $itk_component(status) configure -text "No results"
    380     $itk_component(parameters) configure -state disabled
    381     $itk_component(clear) configure -state disabled
    382     $_dispatcher event -idle !fixcntls
    383 
    384     # let clients know that the number of controls has changed
    385     event generate $itk_component(hull) <<Control>>
    386 }
    387 
    388 # ----------------------------------------------------------------------
    389 # USAGE: activate <column>
    390 #
    391 # Clients use this to activate a particular column in the set of
    392 # controls.  When a column is active, its label is bold and its
    393 # value has a radiodial in the "short list" area.
    394 # ----------------------------------------------------------------------
    395 itcl::body Rappture::ResultSet::activate {column} {
    396     if {$column == "@more"} {
    397         $itk_component(hull).popup activate \
    398             $itk_component(dials).labelmore.name above
    399         return
    400     }
    401 
    402     set allowed [$_results column names]
    403     if {[lsearch $allowed $column] < 0} {
    404         error "bad value \"$column\": should be one of [join $allowed {, }]"
    405     }
    406 
    407     # column is now active
    408     set _active $column
    409 
    410     # keep track of usage, so we know which controls are popular
    411     incr _cntlInfo($this-$column-usage)
    412 
    413     # fix controls at next idle point
    414     $_dispatcher event -idle !layout why data
    415     $_dispatcher event -idle !settings column $_active
    416 }
    417 
    418 # ----------------------------------------------------------------------
    419 # USAGE: contains <xmlobj>
    420 #
    421 # Checks to see if the given <xmlobj> is already represented by
    422 # some result in this result set.  This comes in handy when checking
    423 # to see if an input case is already covered.
    424 #
    425 # Returns 1 if the result set already contains this result, and
    426 # 0 otherwise.
    427 # ----------------------------------------------------------------------
    428 itcl::body Rappture::ResultSet::contains {xmlobj} {
    429     # no results? then this must be new
    430     if {[$_results size] == 0} {
    431         return 0
    432     }
    433 
    434     #
    435     # Compare this new object against the last XML object in the
    436     # results set.  If it has a difference, make sure that there
    437     # is a column to represent the quantity with the difference.
    438     #
    439     set xmlobj0 [$_results get -format xmlobj end]
    440     foreach {op vpath oldval newval} [$xmlobj0 diff $xmlobj] {
    441         if {[$xmlobj get $vpath.about.diffs] == "ignore"} {
    442             continue
    443         }
    444         if {$op == "+" || $op == "-"} {
    445             # ignore differences where parameters come and go
    446             # such differences make it hard to work controls
    447             continue
    448         }
    449464        if {[$_results column names $vpath] == ""} {
    450465            # no column for this quantity yet
     
    459474    set format ""
    460475    set tuple ""
    461     foreach col [lrange [$_results column names] 1 end] {
     476    foreach col [lrange [$_results column names] 2 end] {
    462477        lappend format $col
    463478        set raw [lindex [Rappture::LibraryObj::value $xmlobj $col] 0]
     
    536551
    537552# ----------------------------------------------------------------------
    538 # USAGE: _doClear
    539 #
    540 # Invoked automatically when the user presses the Clear button.
    541 # Invokes the -clearcommand to clear all data from this resultset
    542 # and all other resultsets in an Analyzer.
    543 # ----------------------------------------------------------------------
    544 itcl::body Rappture::ResultSet::_doClear {} {
    545     if {[string length $itk_option(-clearcommand)] > 0} {
    546         uplevel #0 $itk_option(-clearcommand)
     553# USAGE: _doClear all|current
     554#
     555# Invoked automatically when the user presses the "Clear One" or
     556# "Clear All" buttons.  Invokes the -clearcommand to clear all data
     557# from this resultset and all other resultsets in an Analyzer.
     558# ----------------------------------------------------------------------
     559itcl::body Rappture::ResultSet::_doClear {what} {
     560    switch -- $what {
     561        current {
     562            set xmlobj ""
     563            # value of xmlobj control is something like "#1" or "#2"
     564            set irun [$_results find -format simnum $_cntlInfo($this-simnum-value)]
     565            if {$irun ne ""} {
     566                # convert index to a real xmlobj object
     567                set xmlobj [$_results get -format xmlobj $irun]
     568            }
     569            clear $xmlobj
     570        }
     571        all {
     572            clear
     573        }
     574        default { error "bad option \"$what\": should be current or all" }
    547575    }
    548576}
     
    558586    if {[string length $itk_option(-settingscommand)] > 0} {
    559587        uplevel #0 $itk_option(-settingscommand) $cmd
    560     }
    561 }
    562 
    563 # ----------------------------------------------------------------------
    564 # USAGE: _doPrompt <state>
    565 #
    566 # Used internally whenever the current settings represent a point
    567 # with no data.  Invokes the -promptcommand with an explanation of
    568 # the missing data, prompting the user to simulate it.
    569 # ----------------------------------------------------------------------
    570 itcl::body Rappture::ResultSet::_doPrompt {state} {
    571     if {[string length $itk_option(-promptcommand)] > 0} {
    572         if {$state} {
    573             set message "No data for these settings"
    574             set settings ""
    575             foreach col [lrange [$_results column names] 1 end] {
    576                 set val $_cntlInfo($this-$col-value)
    577                 lappend settings $col $val
    578             }
    579             uplevel #0 $itk_option(-promptcommand) [list on $message $settings]
    580         } else {
    581             uplevel #0 $itk_option(-promptcommand) off
    582         }
    583588    }
    584589}
     
    682687    }
    683688
    684     set popup [$itk_component(options) contents frame]
    685     grid columnconfigure $popup 0 -minsize 16
    686     grid columnconfigure $popup 1 -weight 1
    687 
    688689    set shortlist $itk_component(dials)
    689690    grid columnconfigure $shortlist 1 -weight 1
     
    704705        #
    705706        if {![info exists _cntlInfo($this-$col-id)]} {
    706             set row [lindex [grid size $popup] 1]
    707             set row2 [expr {$row+1}]
    708 
    709707            set tip ""
    710             if {$col == "xmlobj"} {
     708            if {$col eq "xmlobj"} {
     709                continue
     710            } elseif {$col eq "simnum"} {
    711711                set quantity "Simulation"
    712712                set tip "List of all simulations that you have performed so far."
     
    725725            }
    726726
    727             #
    728             # Build the main control in the pop-up panel.
    729             #
     727            # Create the controls for the "short list" area.
    730728            set fn $itk_option(-textfont)
    731             set w $popup.label$_counter
     729            set w $shortlist.label$_counter
     730            set row [lindex [grid size $shortlist] 1]
    732731            frame $w
    733             grid $w -row $row -column 2 -sticky ew -padx 4 -pady {4 0}
     732            grid $w -row $row -column 1 -sticky ew
    734733            label $w.arrow -bitmap [Rappture::icon empty] -borderwidth 0
    735734            pack $w.arrow -side left -fill y
     
    750749            Rappture::Tooltip::for $w \
    751750                "@[itcl::code $this _getTooltip label $col]"
    752 
    753             set w $popup.dial$_counter
    754             Rappture::Radiodial $w -valuewidth 0
    755             grid $w -row $row2 -column 2 -sticky ew -padx 4 -pady {0 4}
    756             $w configure -variable ::Rappture::ResultSet::_cntlInfo($this-$col-value)
    757             Rappture::Tooltip::for $w \
    758                 "@[itcl::code $this _getTooltip dial $col]"
    759 
    760             set w $popup.all$_counter
    761             label $w -text "All" -padx 8 \
    762                 -borderwidth 1 -relief raised -font $fn
    763             grid $w -row $row -rowspan 2 -column 1 -sticky nsew -padx 2 -pady 4
    764             Rappture::Tooltip::for $w \
    765                 "@[itcl::code $this _getTooltip all $col]"
    766             bind $w <ButtonRelease> [itcl::code $this _toggleAll $col]
    767 
    768             # Create the controls for the "short list" area.
    769             set w $shortlist.label$_counter
    770             frame $w
    771             grid $w -row $row -column 1 -sticky ew
    772             label $w.arrow -bitmap [Rappture::icon empty] -borderwidth 0
    773             pack $w.arrow -side left -fill y
    774             _control bind $w.arrow $col
    775 
    776             label $w.name -text $quantity -anchor w \
    777                 -borderwidth 0 -padx 0 -pady 1 -font $fn
    778             pack $w.name -side left
    779             bind $w.name <Configure> [itcl::code $this _fixValue $col resize]
    780             _control bind $w.name $col
    781 
    782             label $w.value -anchor w \
    783                 -borderwidth 0 -padx 0 -pady 1 -font $fn
    784             pack $w.value -side left
    785             bind $w.value <Configure> [itcl::code $this _fixValue $col resize]
    786             _control bind $w.value $col
    787 
    788             Rappture::Tooltip::for $w \
    789                 "@[itcl::code $this _getTooltip label $col]"
    790 
    791             # if this is the "Simulation #" control, add a separator
    792             if {$col == "xmlobj"} {
    793                 grid $popup.all$_counter -column 0
    794                 grid $popup.label$_counter -column 1 -columnspan 2
    795                 grid $popup.dial$_counter -column 1 -columnspan 2
    796 
    797                 if {![winfo exists $popup.sep]} {
    798                     frame $popup.sep -height 1 -borderwidth 0 -background black
    799                 }
    800                 grid $popup.sep -row [expr {$row+2}] -column 0 \
    801                     -columnspan 3 -sticky ew -pady 4
    802 
    803                 if {![winfo exists $popup.paraml]} {
    804                     label $popup.paraml -text "Parameters:" -font $fn
    805                 }
    806                 grid $popup.paraml -row [expr {$row+3}] -column 0 \
    807                     -columnspan 3 -sticky w -padx 4 -pady {0 4}
    808             }
    809751
    810752            # create a record for this control
     
    837779        #
    838780        set id $_cntlInfo($this-$col-id)
    839         set popup [$itk_component(options) contents frame]
    840         set dial $popup.dial$id
    841 
    842         _control load $popup.dial$id $col
    843781
    844782        if {$col == $_layout(active)} {
     
    855793    #
    856794    if {$nadded > 0} {
    857         if {[$_results column names] == 2 || $nadded == 1} {
     795        if {[$_results column names] == 3 || $nadded == 1} {
    858796            activate [lindex $_cntlInfo($this-all) end]
    859797        } else {
    860             activate xmlobj
     798            activate simnum
    861799        }
    862800    }
     
    867805    # will then fix all other controls to match the one that changed.
    868806    #
    869     if {"" != $_recent} {
    870         set raw [lindex [$_results find -format xmlobj $_recent] 0]
    871         set raw "#[expr {$raw+1}]"
    872         set _cntlInfo($this-xmlobj-value) $raw
     807    set irun [lindex [$_results find -format xmlobj $_recent] 0]
     808    if {$irun ne ""} {
     809        set simnum [$_results get -format simnum $irun]
     810        set _cntlInfo($this-simnum-value) $simnum
    873811    }
    874812}
     
    881819# so that the active control is displayed, and other recent controls
    882820# are shown above and/or below.  At the very least, we must show the
    883 # "more options..." control, which pops up a panel of all controls.
     821# "more options..." control.
    884822# ----------------------------------------------------------------------
    885823itcl::body Rappture::ResultSet::_fixLayout {args} {
    886824    array set eventdata $args
    887825
    888     set popup [$itk_component(options) contents frame]
    889826    set shortlist $itk_component(dials)
    890827
     
    900837    foreach col $_cntlInfo($this-all) {
    901838        set id $_cntlInfo($this-$col-id)
    902         $popup.label$id configure -background $bg
    903         $popup.label$id.arrow configure -background $bg \
    904             -bitmap [Rappture::icon empty]
    905         $popup.label$id.name configure -font $fn -background $bg
    906         $popup.label$id.value configure -background $bg
    907         $popup.all$id configure -background $bg -foreground $fg \
    908             -relief raised
    909         $popup.dial$id configure -background $bg
    910839        $shortlist.label$id configure -background $bg
    911840        $shortlist.label$id.arrow configure -background $bg \
     
    988917
    989918        if {$col == $_active} {
    990             # put the background behind the active control in the popup
    991             set id $_cntlInfo($this-$_active-id)
    992             array set ginfo [grid info $popup.label$id]
    993             grid $popup.bg -row $ginfo(-row) -rowspan 2 \
    994                 -column 0 -columnspan 3 -sticky nsew
    995             lower $popup.bg
    996 
    997919            if {$_layout(mode) == "usual"} {
    998920                # put the background behind the active control in the shortlist
     
    1026948        set fg $itk_option(-activecontrolforeground)
    1027949        set bg $itk_option(-activecontrolbackground)
    1028 
    1029         $popup.label$id configure -background $bg
    1030         $popup.label$id.arrow configure -foreground $fg -background $bg \
    1031             -bitmap [Rappture::icon rarrow]
    1032         $popup.label$id.name configure -foreground $fg -background $bg \
    1033             -font $bf
    1034         $popup.label$id.value configure -foreground $fg -background $bg
    1035         $popup.dial$id configure -background $bg
    1036         $popup.bg configure -background $bg
    1037 
    1038         if {$_plotall} {
    1039             $popup.all$id configure -relief sunken \
    1040                 -background $itk_option(-togglebackground) \
    1041                 -foreground $itk_option(-toggleforeground)
    1042         } else {
    1043             $popup.all$id configure -relief raised \
    1044                 -background $itk_option(-activecontrolbackground) \
    1045                 -foreground $itk_option(-activecontrolforeground)
    1046         }
    1047950
    1048951        if {$_layout(mode) == "usual"} {
     
    1065968
    1066969# ----------------------------------------------------------------------
     970# USAGE: _fixNumResults
     971#
     972# Used internally to update the number of results displayed near the
     973# top of this widget.  If there is only 1 result, then there is also
     974# a single "Clear" button.  If there are no results, the clear button
     975# is diabled.
     976# ----------------------------------------------------------------------
     977itcl::body Rappture::ResultSet::_fixNumResults {} {
     978    switch [$_results size] {
     979        0 {
     980            $itk_component(status) configure -text "No results"
     981            $itk_component(clearall) configure -state disabled -text "Clear"
     982            pack forget $itk_component(clear)
     983        }
     984        1 {
     985            $itk_component(status) configure -text "1 result"
     986            $itk_component(clearall) configure -state normal -text "Clear"
     987            pack forget $itk_component(clear)
     988        }
     989        default {
     990            $itk_component(status) configure -text "[$_results size] results"
     991            $itk_component(clearall) configure -state normal -text "Clear All"
     992            $itk_component(clear) configure -state normal
     993            pack $itk_component(clear) -side right \
     994                -after $itk_component(clearall) -padx {0 6}
     995        }
     996    }
     997}
     998
     999# ----------------------------------------------------------------------
    10671000# USAGE: _fixSettings ?<eventArgs...>?
    10681001#
     
    10811014        set changed ""
    10821015    }
    1083     _doPrompt off
    10841016
    10851017    if {[info exists _cntlInfo($this-$_active-label)]} {
     
    11001032        1 {
    11011033            # only one data set? then plot it
     1034            set simnum [$_results get -format simnum 0]
    11021035            _doSettings [list \
    1103                 0 [list -width 2 \
     1036                $simnum [list -width 2 \
    11041037                        -param [_getValues $_active current] \
    11051038                        -description [_getParamDesc all] \
     
    11161049    # for a tuple that matches the current settings.
    11171050    #
    1118     if {$changed == "xmlobj"} {
    1119         # value is "#2" -- skip # and adjust range starting from 0
    1120         set irun [string range $_cntlInfo($this-xmlobj-value) 1 end]
    1121         if {"" != $irun} { set irun [expr {$irun-1}] }
     1051    if {$changed == "xmlobj" || $changed == "simnum"} {
     1052        set irun [$_results find -format simnum $_cntlInfo($this-simnum-value)]
    11221053    } else {
    11231054        set format ""
    11241055        set tuple ""
    1125         foreach col [lrange [$_results column names] 1 end] {
     1056        foreach col [lrange [$_results column names] 2 end] {
    11261057            lappend format $col
    11271058            lappend tuple $_cntlInfo($this-$col-value)
     
    11291060        set irun [lindex [$_results find -format $format -- $tuple] 0]
    11301061
    1131         if {"" == $irun && "" != $changed
    1132              && $itk_option(-missingdata) == "skip"} {
    1133             #
    1134             # No data for these settings.  Try leaving the next
    1135             # column open, then the next, and so forth, until
    1136             # we find some data.
    1137             #
    1138             # allcols:  foo bar baz qux
    1139             #               ^^^changed
    1140             #
    1141             # search:   baz qux foo
    1142             #
    1143             set val $_cntlInfo($this-$changed-value)
    1144             set allcols [lrange [$_results column names] 1 end]
    1145             set i [lsearch -exact $allcols $changed]
    1146             set search [concat \
    1147                 [lrange $allcols [expr {$i+1}] end] \
    1148                 [lrange $allcols 0 [expr {$i-1}]] \
    1149             ]
    1150             set nsearch [llength $search]
    1151 
    1152             for {set i 0} {$i < $nsearch} {incr i} {
    1153                 set format $changed
    1154                 set tuple [list $val]
    1155                 for {set j [expr {$i+1}]} {$j < $nsearch} {incr j} {
    1156                     set col [lindex $search $j]
    1157                     lappend format $col
    1158                     lappend tuple $_cntlInfo($this-$col-value)
    1159                 }
    1160                 set irun [lindex [$_results find -format $format -- $tuple] 0]
    1161                 if {"" != $irun} {
    1162                     break
    1163                 }
    1164             }
    1165         }
     1062        if {"" == $irun && "" != $changed} {
     1063            #
     1064            # No data for these settings.  Try leaving the next
     1065            # column open, then the next, and so forth, until
     1066            # we find some data.
     1067            #
     1068            # allcols:  foo bar baz qux
     1069            #               ^^^changed
     1070            #
     1071            # search:   baz qux foo
     1072            #
     1073            set val $_cntlInfo($this-$changed-value)
     1074            set allcols [lrange [$_results column names] 2 end]
     1075            set i [lsearch -exact $allcols $changed]
     1076            set search [concat \
     1077                [lrange $allcols [expr {$i+1}] end] \
     1078                [lrange $allcols 0 [expr {$i-1}]] \
     1079            ]
     1080            set nsearch [llength $search]
     1081
     1082            for {set i 0} {$i < $nsearch} {incr i} {
     1083                set format $changed
     1084                set tuple [list $val]
     1085                for {set j [expr {$i+1}]} {$j < $nsearch} {incr j} {
     1086                    set col [lindex $search $j]
     1087                    lappend format $col
     1088                    lappend tuple $_cntlInfo($this-$col-value)
     1089                }
     1090                set irun [lindex [$_results find -format $format -- $tuple] 0]
     1091                if {"" != $irun} {
     1092                    break
     1093                }
     1094            }
     1095        }
    11661096    }
    11671097
     
    11741104        set _settings 1
    11751105
    1176         set format [lrange [$_results column names] 1 end]
     1106        set format [lrange [$_results column names] 2 end]
    11771107        if {[llength $format] == 1} {
    11781108            set data [$_results get -format $format $irun]
     
    11841114            set _cntlInfo($this-$col-value) $val
    11851115        }
    1186         set _cntlInfo($this-xmlobj-value) "#[expr {$irun+1}]"
     1116        set simnum [$_results get -format simnum $irun]
     1117        set _cntlInfo($this-simnum-value) $simnum
    11871118
    11881119        # okay, react to value changes again
     
    11941125    # plot them.
    11951126    #
    1196     if {$_plotall && $_active == "xmlobj"} {
     1127    if {$_plotall && $_active == "simnum"} {
    11971128        set format ""
    11981129    } else {
    11991130        set format ""
    12001131        set tuple ""
    1201         foreach col [lrange [$_results column names] 1 end] {
     1132        foreach col [lrange [$_results column names] 2 end] {
    12021133            if {!$_plotall || $col != $_active} {
    12031134                lappend format $col
     
    12171148        set format ""
    12181149        set tuple ""
    1219         foreach col [lrange [$_results column names] 1 end] {
     1150        foreach col [lrange [$_results column names] 2 end] {
    12201151            lappend format $col
    12211152            lappend tuple $_cntlInfo($this-$col-value)
    12221153        }
    12231154        set icurr [$_results find -format $format -- $tuple]
    1224 
    1225         # no data for these settings? prompt the user to simulate
    1226         if {"" == $icurr} {
    1227             _doPrompt on
    1228         }
    12291155
    12301156        if {[llength $ilist] == 1} {
    12311157            # single result -- always use active color
    12321158            set i [lindex $ilist 0]
     1159            set simnum [$_results get -format simnum $i]
    12331160            set plist [list \
    1234                 $i [list -width 2 \
     1161                $simnum [list -width 2 \
    12351162                         -param [_getValues $_active $i] \
    12361163                         -description [_getParamDesc all $i] \
     
    12451172            set plist [list params $params]
    12461173            foreach i $ilist {
     1174                set simnum [$_results get -format simnum $i]
    12471175                if {$i == $icurr} {
    1248                     lappend plist $i [list -width 3 -raise 1 \
     1176                    lappend plist $simnum [list -width 3 -raise 1 \
    12491177                        -param [_getValues $_active $i] \
    12501178                        -description [_getParamDesc all $i]]
    12511179                } else {
    1252                     lappend plist $i [list -brightness 0.7 -width 1 \
     1180                    lappend plist $simnum [list -brightness 0.7 -width 1 \
    12531181                        -param [_getValues $_active $i] \
    12541182                        -description [_getParamDesc all $i]]
     
    12611189        #
    12621190        _doSettings $plist
    1263 
    1264     } elseif {$itk_option(-missingdata) == "prompt"} {
    1265         # prompt the user to simulate these settings
    1266         _doPrompt on
    1267         _doSettings  ;# clear plotting area
    1268 
    1269         # clear the current run selection -- there is no run for this
    1270         set _settings 1
    1271         set _cntlInfo($this-xmlobj-value) ""
    1272         set _settings 0
    1273     }
    1274 }
    1275 
    1276 # ----------------------------------------------------------------------
    1277 # USAGE: _fixExplore
    1278 #
    1279 # Called automatically whenever the user toggles the "Explore" button
    1280 # on the parameter popup.  Changes the -missingdata option back and
    1281 # forth, to allow for missing data or skip it.
    1282 # ----------------------------------------------------------------------
    1283 itcl::body Rappture::ResultSet::_fixExplore {} {
    1284     if {$_explore} {
    1285         configure -missingdata prompt
    1286     } else {
    1287         configure -missingdata skip
    12881191    }
    12891192}
     
    13001203    if {[info exists _cntlInfo($this-$col-id)]} {
    13011204        set id $_cntlInfo($this-$col-id)
    1302 
    1303         set popup [$itk_component(options) contents frame]
    1304         set widget $popup.label$id
    1305         set wmax [winfo width $popup.dial$id]
    1306         _drawValue $col $widget $wmax
    13071205
    13081206        set widget $itk_component(dials).label$id
     
    14251323    }
    14261324    set id $_cntlInfo($this-$col-id)
    1427     set popup [$itk_component(options) contents frame]
    1428     set pbutton $popup.all$id
    1429     set current [$pbutton cget -relief]
    14301325    set sbutton $itk_component(dials).all
    1431 
    1432     foreach c $_cntlInfo($this-all) {
    1433         set id $_cntlInfo($this-$c-id)
    1434         $popup.all$id configure -relief raised \
    1435             -background $itk_option(-background) \
    1436             -foreground $itk_option(-foreground)
    1437     }
     1326    set current [$sbutton cget -relief]
    14381327
    14391328    if {$current == "sunken"} {
    1440         $pbutton configure -relief raised \
    1441             -background $itk_option(-activecontrolbackground) \
    1442             -foreground $itk_option(-activecontrolforeground)
    14431329        $sbutton configure -relief raised \
    14441330            -background $itk_option(-activecontrolbackground) \
     
    14461332        set _plotall 0
    14471333    } else {
    1448         $pbutton configure -relief sunken \
    1449             -background $itk_option(-togglebackground) \
    1450             -foreground $itk_option(-toggleforeground)
    14511334        $sbutton configure -relief sunken \
    14521335            -background $itk_option(-togglebackground) \
     
    14691352# ----------------------------------------------------------------------
    14701353itcl::body Rappture::ResultSet::_getValues {col {which ""}} {
    1471     if {$col == "xmlobj"} {
     1354    if {$col == "simnum"} {
    14721355        # load the Simulation # control
    14731356        set nruns [$_results size]
    14741357        for {set n 0} {$n < $nruns} {incr n} {
    1475             set v "#[expr {$n+1}]"
     1358            set v [$_results get -format simnum $n]
    14761359            set label2val($v) $n
    14771360        }
     
    15191402        default {
    15201403            if {[string is integer $which]} {
    1521                 if {$col == "xmlobj"} {
    1522                     set val "#[expr {$which+1}]"
     1404                if {$col == "simnum"} {
     1405                    set val [$_results get -format simnum $which]
    15231406                } else {
    15241407                    # Be careful giving singleton elements as the "columns"
     
    15771460            append tip "\n\nCurrently, plotting $what.  Click to toggle."
    15781461        }
    1579         more {
    1580             set tip "Click to access all parameters."
    1581         }
    15821462    }
    15831463    return [string trim $tip]
     
    15961476        set format ""
    15971477        set tuple ""
    1598         foreach col [lrange [$_results column names] 1 end] {
     1478        foreach col [lrange [$_results column names] 2 end] {
    15991479            lappend format $col
    16001480            lappend tuple $_cntlInfo($this-$col-value)
     
    16191499                # argument to "Tuples::get". It is expecting a list.
    16201500                set val [lindex [$_results get -format [list $col] $index] 0]
    1621                 if {$col == "xmlobj"} {
    1622                     set num [lindex [$_results find -format xmlobj $val] 0]
    1623                     set val "#[expr {$num+1}]"
     1501                if {$col == "simnum"} {
     1502                    set irun [lindex [$_results find -format xmlobj $val] 0]
     1503                    set val [$_results get -format simnum $irun]
    16241504                }
    16251505                append desc "$quantity = $val\n"
     
    16341514
    16351515# ----------------------------------------------------------------------
    1636 # OPTION: -missingdata
    1637 # ----------------------------------------------------------------------
    1638 itcl::configbody Rappture::ResultSet::missingdata {
    1639     set opts {prompt skip}
    1640     if {[lsearch -exact $opts $itk_option(-missingdata)] < 0} {
    1641         error "bad value \"$itk_option(-missingdata)\": should be [join $opts {, }]"
    1642     }
    1643     set _explore [expr {$itk_option(-missingdata) != "skip"}]
     1516# USAGE: _addOneResult <tuples> <xmlobj> ?<simNum>?
     1517#
     1518# Used internally to add one new <xmlobj> to the given <tuples>
     1519# object.  If the new xmlobj contains different input parameters
     1520# that are not already columns in the tuple, then this routine
     1521# creates the new columns.  If the optional <simNum> is specified,
     1522# then it is added as the simulation number #1, #2, #3, etc.  If
     1523# not, then the new object is automatically numbered.
     1524# ----------------------------------------------------------------------
     1525itcl::body Rappture::ResultSet::_addOneResult {tuples xmlobj {simnum ""}} {
     1526    #
     1527    # Compare this new object against the last XML object in the
     1528    # results set.  If it has a difference, make sure that there
     1529    # is a column to represent the quantity with the difference.
     1530    #
     1531    set xmlobj0 [$tuples get -format xmlobj end]
     1532    foreach {op vpath oldval newval} [$xmlobj0 diff $xmlobj] {
     1533        if {[$xmlobj get $vpath.about.diffs] == "ignore"} {
     1534            continue
     1535        }
     1536        if {$op == "+" || $op == "-"} {
     1537            # ignore differences where parameters come and go
     1538            # such differences make it hard to work controls
     1539            continue
     1540        }
     1541
     1542        # make sure that these values really are different
     1543        set oldval [lindex [Rappture::LibraryObj::value $xmlobj0 $vpath] 0]
     1544        set newval [lindex [Rappture::LibraryObj::value $xmlobj $vpath] 0]
     1545
     1546        if {$oldval != $newval && [$tuples column names $vpath] == ""} {
     1547            # no column for this quantity yet
     1548            $tuples column insert end -name $vpath -default $oldval
     1549        }
     1550    }
     1551
     1552    # build a tuple for this new object
     1553    set cols ""
     1554    set tuple ""
     1555    foreach col [lrange [$tuples column names] 2 end] {
     1556        lappend cols $col
     1557        set raw [lindex [Rappture::LibraryObj::value $xmlobj $col] 0]
     1558        lappend tuple $raw  ;# use the "raw" (user-readable) label
     1559    }
     1560
     1561    # find a matching tuple? then replace it -- only need one
     1562    if {[llength $cols] > 0} {
     1563        set ilist [$tuples find -format $cols -- $tuple]
     1564    } else {
     1565        set ilist 0  ;# no diffs -- must match first entry
     1566    }
     1567
     1568    # add all remaining columns for this new entry
     1569    set tuple [linsert $tuple 0 $xmlobj]
     1570    set cols [linsert $cols 0 "xmlobj"]
     1571
     1572    if {[llength $ilist] > 0} {
     1573        if {[llength $ilist] > 1} {
     1574            error "why so many matching results?"
     1575        }
     1576
     1577        # overwrite the first matching entry
     1578        set index [lindex $ilist 0]
     1579        $tuples put -format $cols $index $tuple
     1580    } else {
     1581        if {$simnum eq ""} {
     1582            set simnum "#[incr _resultnum]"
     1583        }
     1584        set tuple [linsert $tuple 1 $simnum]
     1585        $tuples insert end $tuple
     1586    }
     1587    return $simnum
    16441588}
    16451589
  • trunk/gui/scripts/resultviewer.tcl

    r2941 r2943  
    3636    protected method _plotAdd {xmlobj {settings ""}}
    3737    protected method _fixScale {args}
    38     protected proc _xml2data {xmlobj path}
     38    protected method _xml2data {xmlobj path}
     39    protected method _cleanIndex {index}
    3940
    4041    private variable _dispatcher ""  ;# dispatchers for !events
     
    4243    private variable _mode2widget    ;# maps plotting mode => widget
    4344    private variable _dataslots ""   ;# list of all data objects in this widget
     45    private variable _xml2data       ;# maps xmlobj => data obj in _dataslots
    4446}
    4547
     
    7981# ----------------------------------------------------------------------
    8082itcl::body Rappture::ResultViewer::add {index xmlobj path} {
     83    set index [_cleanIndex $index]
    8184    set dobj [_xml2data $xmlobj $path]
    8285
     
    9699
    97100# ----------------------------------------------------------------------
    98 # USAGE: clear ?<index>?
    99 #
    100 # Clears one or all results in this result viewer.
     101# USAGE: clear ?<index>|<xmlobj>?
     102#
     103# Clears one or all results in this result viewer.  If a particular
     104# <index> is specified, then all data objects at that index are
     105# deleted.  If a particular <xmlobj> is specified, then all data
     106# objects related to that <xmlobj> are removed--regardless of whether
     107# they reside at one or more indices.
    101108# ----------------------------------------------------------------------
    102109itcl::body Rappture::ResultViewer::clear {{index ""}} {
    103     if {"" != $index} {
     110    if {$index ne ""} {
    104111        # clear one result
    105         if {$index >= 0 && $index < [llength $_dataslots]} {
    106             set slot [lindex $_dataslots $index]
    107             foreach dobj $slot {
     112        if {[catch {_cleanIndex $index} i] == 0} {
     113            if {$i >= 0 && $i < [llength $_dataslots]} {
     114                set slot [lindex $_dataslots $i]
     115                foreach dobj $slot {
     116                    itcl::delete object $dobj
     117                }
     118                set _dataslots [lreplace $_dataslots $i $i ""]
     119                $_dispatcher event -idle !scale
     120            }
     121        } else {
     122            foreach key [array names _xml2data $index-*] {
     123                set dobj $_xml2data($key)
     124
     125                # search for and remove all references to this data object
     126                for {set n 0} {$n < [llength $_dataslots]} {incr n} {
     127                    set slot [lindex $_dataslots $n]
     128                    set pos [lsearch -exact $slot $dobj]
     129                    if {$pos >= 0} {
     130                        set slot [lreplace $slot $pos $pos]
     131                        set _dataslots [lreplace $_dataslots $n $n $slot]
     132                        $_dispatcher event -idle !scale
     133                    }
     134                }
     135
     136                # destroy the object and forget it
    108137                itcl::delete object $dobj
    109             }
    110             set _dataslots [lreplace $_dataslots $index $index ""]
     138                unset _xml2data($key)
     139            }
    111140        }
    112141    } else {
     
    119148        }
    120149        set _dataslots ""
     150        catch {unset _xml2data}
    121151    }
    122152}
     
    139169
    140170# ----------------------------------------------------------------------
    141 # USAGE: plot add ?<index> <settings> <index> <settings> ...?
     171# USAGE: plot add ?<simnum> <settings> <simnum> <settings> ...?
    142172# USAGE: plot clear
    143173#
     
    145175# command clears the current viewer.  Data is still stored in the
    146176# widget, but the results are not shown on screen.  The "plot add"
    147 # command adds the data at the specified <index> to the plot.  If
     177# command adds the data at the specified <simnum> to the plot.  Each
     178# <simnum> is the simulation number, like "#1", "#2", "#3", etc.  If
    148179# the optional <settings> are specified, then they are applied
    149180# to the plot; otherwise, default settings are used.
     
    158189                    continue
    159190                }
     191
     192                set index [_cleanIndex $index]
    160193                set reset "-color autoreset"
    161194                set slot [lindex $_dataslots $index]
     
    475508# ----------------------------------------------------------------------
    476509itcl::body Rappture::ResultViewer::_xml2data {xmlobj path} {
     510    if {[info exists _xml2data($xmlobj-$path)]} {
     511        return $_xml2data($xmlobj-$path)
     512    }
     513
    477514    set type [$xmlobj element -as type $path]
    478515    switch -- $type {
    479516        curve {
    480             return [Rappture::Curve ::#auto $xmlobj $path]
     517            set dobj [Rappture::Curve ::#auto $xmlobj $path]
    481518        }
    482519        datatable {
    483             return [Rappture::DataTable ::#auto $xmlobj $path]
     520            set dobj [Rappture::DataTable ::#auto $xmlobj $path]
    484521        }
    485522        histogram {
    486             return [Rappture::Histogram ::#auto $xmlobj $path]
     523            set dobj [Rappture::Histogram ::#auto $xmlobj $path]
    487524        }
    488525        field {
    489             return [Rappture::Field ::#auto $xmlobj $path]
     526            set dobj [Rappture::Field ::#auto $xmlobj $path]
    490527        }
    491528        mesh {
    492             return [Rappture::Mesh ::#auto $xmlobj $path]
     529            set dobj [Rappture::Mesh ::#auto $xmlobj $path]
    493530        }
    494531        table {
    495             return [Rappture::Table ::#auto $xmlobj $path]
     532            set dobj [Rappture::Table ::#auto $xmlobj $path]
    496533        }
    497534        image {
    498             return [Rappture::Image ::#auto $xmlobj $path]
     535            set dobj [Rappture::Image ::#auto $xmlobj $path]
    499536        }
    500537        sequence {
    501             return [Rappture::Sequence ::#auto $xmlobj $path]
     538            set dobj [Rappture::Sequence ::#auto $xmlobj $path]
    502539        }
    503540        string - log {
    504             return [$xmlobj element -as object $path]
     541            set dobj [$xmlobj element -as object $path]
    505542        }
    506543        structure {
    507             return [$xmlobj element -as object $path]
     544            set dobj [$xmlobj element -as object $path]
    508545        }
    509546        number - integer - boolean - choice {
    510             return [$xmlobj element -as object $path]
     547            set dobj [$xmlobj element -as object $path]
    511548        }
    512549        drawing3d - drawing {
    513             return [Rappture::Drawing ::#auto $xmlobj $path]
     550            set dobj [Rappture::Drawing ::#auto $xmlobj $path]
    514551        }
    515552        time - status {
    516             return ""
    517         }
    518     }
    519     error "don't know how to plot <$type> data path=$path"
     553            set dobj ""
     554        }
     555        default {
     556            error "don't know how to plot <$type> data path=$path"
     557        }
     558    }
     559
     560    # store the mapping xmlobj=>dobj so we can find this result later
     561    if {$dobj ne ""} {
     562        set _xml2data($xmlobj-$path) $dobj
     563    }
     564    return $dobj
     565}
     566
     567# ----------------------------------------------------------------------
     568# USAGE: _cleanIndex <index>
     569#
     570# Used internally to create a data object for the data at the
     571# specified <path> in the <xmlobj>.
     572# ----------------------------------------------------------------------
     573itcl::body Rappture::ResultViewer::_cleanIndex {index} {
     574    if {[regexp {^#([0-9]+)} $index match num]} {
     575        return [expr {$num-1}]  ;# start from 0 instead of 1
     576    } elseif {[string is integer -strict $index]} {
     577        return $index
     578    }
     579    error "bad plot index \"$index\": should be 0,1,2,... or #1,#2,#3,..."
    520580}
    521581
  • trunk/gui/scripts/xylegend.tcl

    r2744 r2943  
    249249    }
    250250    foreach elem [$_graph element show] {
    251         set label [$_graph element cget $elem -label]
    252         if { $label == "" } {
    253             set label $elem
    254         }
    255         Add $elem $label
     251        if {[catch {$_graph element cget $elem -label} label] == 0} {
     252            if {$label eq ""} {
     253                set label $elem
     254            }
     255            Add $elem $label
     256        }
    256257    }
    257258    $itk_component(legend) open -recurse root
Note: See TracChangeset for help on using the changeset viewer.