Changeset 919 for trunk/gui


Ignore:
Timestamp:
Mar 5, 2008 4:31:15 PM (16 years ago)
Author:
gah
Message:

replumbed all visualization viewers to use new visviewer base class

Location:
trunk/gui/scripts
Files:
7 edited

Legend:

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

    r770 r919  
    5151}
    5252
    53 # must use this name -- plugs into Rappture::resources::load
    54 proc deviceEditor_init_resources {} {
    55     Rappture::resources::register \
    56         molvis_server Rappture::DeviceEditor::setMolvisServer
    57 }
    58 
    5953# ----------------------------------------------------------------------
    6054# CONSTRUCTOR
     
    127121# ----------------------------------------------------------------------
    128122itcl::body Rappture::DeviceEditor::add {dataobj {settings ""}} {
    129 
    130123    set _xmlobj $dataobj
    131 
    132124    if {"" == $_current} {    # Make sure viewer instance exists
    133125        _redraw
    134126    }
    135 
    136127    eval $_current add $dataobj [list $settings]
    137128}
     
    144135# ----------------------------------------------------------------------
    145136itcl::body Rappture::DeviceEditor::delete {args} {
    146 
    147137    if {"" != $_current} {
    148138        eval $_current delete $args
     
    183173    switch -- [_type $_xmlobj] {
    184174        molecule {
    185             if {![winfo exists $itk_component(hull).mol]} {
    186                 catch {destroy $itk_component(hull).dev}
    187                 if {"" != $_molvisHosts} {
    188                     Rappture::MolvisViewer $itk_component(hull).mol $_molvisHosts
     175            if { ![winfo exists $itk_component(hull).mol] } {
     176                catch {
     177                    destroy $itk_component(hull).dev
     178                }
     179                set servers [Rappture::VisViewer::GetServerList "pymol"]
     180                if { "" != $servers } {
     181                    Rappture::MolvisViewer $itk_component(hull).mol $servers
    189182                } else {
    190183                    Rappture::MoleculeViewer $itk_component(hull).mol $this
     
    192185                pack $itk_component(hull).mol -expand yes -fill both
    193186            }
    194 
    195187            set _current $itk_component(hull).mol
    196188        }
    197189        device1D {
    198             if {![winfo exists $itk_component(hull).dev]} {
    199                 catch {destroy $itk_component(hull).mol}
     190            if { ![winfo exists $itk_component(hull).dev] } {
     191                catch {
     192                    destroy $itk_component(hull).mol
     193                }
    200194                Rappture::DeviceViewer1D $itk_component(hull).dev $this
    201195                pack $itk_component(hull).dev -expand yes -fill both
    202196            }
    203 
    204197            set _current $itk_component(hull).dev
    205198        }
  • trunk/gui/scripts/heightmapviewer.tcl

    r909 r919  
    6767    protected method _receive_legend {ivol vmin vmax size}
    6868    protected method _receive_echo {channel {data ""}}
    69     protected method _receive_data {args}
    7069
    7170    protected method _rebuild {}
     
    124123    $_parser alias image [itcl::code $this _receive_image]
    125124    $_parser alias legend [itcl::code $this _receive_legend]
    126     $_parser alias data [itcl::code $this _receive_data]
    127 
    128     set _view(theta) 45
    129     set _view(phi) 45
    130     set _view(psi) 0
    131     set _view(zoom) 1
    132     set _view(xfocus) 0
    133     set _view(yfocus) 0
    134     set _view(zfocus) 0
     125
     126    # Initialize the view to some default parameters.
     127    array set _view {
     128        theta   45
     129        phi     45
     130        psi     0
     131        zoom    1.0
     132        xfocus  0
     133        yfocus  0
     134        zfocus  0
     135    }
    135136    set _obj2id(count) 0
    136137
     
    469470
    470471# ----------------------------------------------------------------------
     472# USAGE: isconnected
     473#
     474# Clients use this method to see if we are currently connected to
     475# a server.
     476# ----------------------------------------------------------------------
     477itcl::body Rappture::HeightmapViewer::isconnected {} {
     478    return [VisViewer::IsConnected]
     479}
     480
     481# ----------------------------------------------------------------------
    471482# USAGE: Connect ?<host:port>,<host:port>...?
    472483#
     
    503514}
    504515
    505 # ----------------------------------------------------------------------
    506 # USAGE: isconnected
    507 #
    508 # Clients use this method to see if we are currently connected to
    509 # a server.
    510 # ----------------------------------------------------------------------
    511 itcl::body Rappture::HeightmapViewer::isconnected {} {
    512     return [VisViewer::IsConnected]
    513 }
    514 
    515 # ----------------------------------------------------------------------
    516 # USAGE: _send <string>
    517 #
    518 # Used internally to send commands off to the rendering server.
    519 # ----------------------------------------------------------------------
     516#
     517# _send
     518#
     519#       Send commands off to the rendering server.  If we're currently
     520#       sending data objects to the server, buffer the commands to be
     521#       sent later.
     522#
    520523itcl::body Rappture::HeightmapViewer::_send {string} {
    521     if { ![isconnected] } {
    522         $_dispatcher cancel !serverDown
    523         set x [expr {[winfo rootx $itk_component(area)]+10}]
    524         set y [expr {[winfo rooty $itk_component(area)]+10}]
    525         Rappture::Tooltip::cue @$x,$y "Connecting..."
    526 
    527         set code [catch { Connect } ok]
    528         if { $code == 0 && $ok} {
    529             set w [winfo width $itk_component(3dview)]
    530             set h [winfo height $itk_component(3dview)]
    531 
    532             if { [Send "screen $w $h"] } {
    533                 set _view(theta) 45
    534                 set _view(phi) 45
    535                 set _view(psi) 0
    536                 set _view(zoom) 1.0
    537                 $_dispatcher event -idle !rebuild
    538                 Rappture::Tooltip::cue hide
    539             }
    540         } else {
    541             Rappture::Tooltip::cue @$x,$y "Can't connect to visualization server.  This may be a network problem.  Wait a few moments and try resetting the view."
     524    if {[llength $_sendobjs] > 0} {
     525        append _outbuf $string "\n"
     526    } else {
     527        if {[SendBytes $string]} {
     528            foreach line [split $string \n] {
     529                SendEcho >>line $line
     530            }
    542531        }
    543     } else {
    544         # if we're transmitting objects, then buffer this command
    545         if {[llength $_sendobjs] > 0} {
    546             append _outbuf $string "\n"
    547         } else {
    548             if { [Send $string] } {
    549                 foreach line [split $string \n] {
    550                     SendEcho >>line $line
    551                 }
    552             }
    553         }
    554532    }
    555533}
     
    565543    blt::busy hold $itk_component(hull); update idletasks
    566544
     545    # Reset the overall limits
     546    if { $_sendobjs != "" } {
     547        set _limits(vmin) ""
     548        set _limits(vmax) ""
     549    }
    567550    foreach dataobj $_sendobjs {
    568551        foreach comp [$dataobj components] {
     
    570553            set data [$dataobj blob $comp]
    571554
     555            foreach { vmin vmax }  [$dataobj limits v] break
     556            if { $_limits(vmin) == "" || $vmin < $_limits(vmin) } {
     557                set _limits(vmin) $vmin
     558            }
     559            if { $_limits(vmax) == "" || $vmax > $_limits(vmax) } {
     560                set _limits(vmax) $vmax
     561            }
     562
    572563            # tell the engine to expect some data
    573             set length [string length $data]
    574             set cmdstr "heightmap data follows $length"
    575             if { ![Send $cmdstr] } {
     564            set nbytes [string length $data]
     565            if { ![SendBytes "heightmap data follows $nbytes"] } {
    576566                return
    577567            }
    578             while {[string length $data] > 0} {
    579                 update
    580 
    581                 set chunk [string range $data 0 8095]
    582                 set data [string range $data 8096 end]
    583                 if { ![Send $chunk -nonewline] } {
    584                     return
    585                 }
    586                 Flush
    587             }
    588             Send ""
    589 
     568            if { ![SendBytes $data] } {
     569                return
     570            }
    590571            set id $_obj2id(count)
    591572            incr _obj2id(count)
     
    600581            foreach {sname cmap wmap} [_getTransfuncData $dataobj $comp] break
    601582            set cmdstr [list "transfunc" "define" $sname $cmap $wmap]
    602             if {![Send $cmdstr]} {
     583            if {![SendBytes $cmdstr]} {
    603584                return
    604585            }
     
    627608
    628609    # if there are any commands in the buffer, send them now that we're done
    629     Send $_outbuf
     610    SendBytes $_outbuf
    630611    set _outbuf ""
    631612
     
    642623itcl::body Rappture::HeightmapViewer::_receive_image {option size} {
    643624    if {[isconnected]} {
    644         set bytes [Receive $size]
     625        set bytes [ReceiveBytes $size]
    645626        $_image(plot) configure -data $bytes
    646627        ReceiveEcho <<line "<read $size bytes for [image width $_image(plot)]x[image height $_image(plot)] image>"
     
    657638itcl::body Rappture::HeightmapViewer::_receive_legend {ivol vmin vmax size} {
    658639    if { [isconnected] } {
    659         set bytes [Receive $size]
     640        set bytes [ReceiveBytes $size]
    660641        $_image(legend) configure -data $bytes
    661642        ReceiveEcho <<line "<read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>"
     
    673654                 -fill $itk_option(-plotforeground) -tags vmax
    674655        }
    675         $c itemconfigure vmin -text $vmin
     656        $c itemconfigure vmin -text $_limits(vmin)
    676657        $c coords vmin 10 [expr {$h-8}]
    677         $c itemconfigure vmax -text $vmax
     658        $c itemconfigure vmax -text $_limits(vmax)
    678659        $c coords vmax [expr {$w-10}] [expr {$h-8}]
    679     }
    680 }
    681 
    682 # ----------------------------------------------------------------------
    683 # USAGE: _receive_data <id> <vmin> <vmax>
    684 #
    685 # Invoked automatically whenever the "legend" command comes in from
    686 # the rendering server.  Indicates that binary image data with the
    687 # specified <size> will follow.
    688 # ----------------------------------------------------------------------
    689 itcl::body Rappture::HeightmapViewer::_receive_data { args } {
    690     if { [isconnected] } {
    691         array set info $args
    692         set id $info(id)
    693         foreach { dataobj comp } $_id2obj($id) break
    694         if { ![info exists _limits($dataobj-vmin] } {
    695             set _limits($dataobj-vmin) $info(min)
    696             set _limits($dataobj-vmax) $info(max)
    697         } else {
    698             if { $_limits($dataobj-vmin) > $info(min) } {
    699                 set _limits($dataobj-vmin) $info(min)
    700             }
    701             if { $_limits($dataobj-vmax) > $info(max) } {
    702                 set _limits($dataobj-vmax) $info(max)
    703             }
    704         }           
    705         set _limits(vmin) $info(vmin)
    706         set _limits(vmax) $info(vmax)
    707         lappend _sendobjs2 $dataobj
    708         unset _receiveids($info(id))
    709         if { [array size _receiveids] == 0 } {
    710             #$_dispatcher event -idle !send_transfuncs
    711         }
    712660    }
    713661}
     
    725673        return
    726674    }
    727 
    728     #
    729     # Find any new data that needs to be sent to the server.
    730     # Queue this up on the _sendobjs list, and send it out
    731     # a little at a time.  Do this first, before we rebuild
    732     # the rest.
    733     #
     675    # Find any new data that needs to be sent to the server.  Queue this up on
     676    # the _sendobjs list, and send it out a little at a time.  Do this first,
     677    # before we rebuild the rest.
    734678    foreach dataobj [get] {
    735679        set comp [lindex [$dataobj components] 0]
     
    742686    }
    743687    if {[llength $_sendobjs] > 0} {
    744         # send off new data objects
     688        # Send off new data objects
    745689        $_dispatcher event -idle !send_dataobjs
    746690    } else {
    747         # nothing to send -- activate the proper volume
     691        # Nothing to send -- activate the proper volume
    748692        set first [lindex [get] 0]
    749693        if {"" != $first} {
     
    787731itcl::body Rappture::HeightmapViewer::_zoom {option} {
    788732    switch -- $option {
    789         in {
     733        "in" {
    790734            set _view(zoom) [expr {$_view(zoom)*1.25}]
    791             _send "camera zoom $_view(zoom)"
    792         }
    793         out {
     735        }
     736        "out" {
    794737            set _view(zoom) [expr {$_view(zoom)*0.8}]
    795             _send "camera zoom $_view(zoom)"
    796         }
    797         reset {
    798             set _view(theta) 45
    799             set _view(phi) 45
    800             set _view(psi) 0
    801             set _view(zoom) 1.0
     738        }
     739        "reset" {
     740            array set _view {
     741                theta   45
     742                phi     45
     743                psi     0
     744                zoom    1.0
     745            }
    802746            set xyz [Euler2XYZ $_view(theta) $_view(phi) $_view(psi)]
    803747            _send "camera angle $xyz"
    804             _send "camera zoom $_view(zoom)"
    805         }
    806     }
     748        }
     749    }
     750    _send "camera zoom $_view(zoom)"
    807751}
    808752
     
    819763        click {
    820764            $itk_component(3dview) configure -cursor fleur
    821             set _click(x) $x
    822             set _click(y) $y
    823             set _click(theta) $_view(theta)
    824             set _click(phi) $_view(phi)
     765            set _click(x)       $x
     766            set _click(y)       $y
     767            set _click(theta)   $_view(theta)
     768            set _click(phi)     $_view(phi)
    825769        }
    826770        drag {
     
    865809                }
    866810
    867                 set _view(theta) $theta
    868                 set _view(phi) $phi
    869                 set _view(psi) $psi
     811                set _view(theta)        $theta
     812                set _view(phi)          $phi
     813                set _view(psi)          $psi
    870814                set xyz [Euler2XYZ $_view(theta) $_view(phi) $_view(psi)]
    871815                _send "camera angle $xyz"
  • trunk/gui/scripts/isomarker.tcl

    r908 r919  
    2828
    2929    constructor {c obj args} {
    30         puts stderr "call IsoMarker constructor"
    3130        set _canvas $c
    3231        set _nvobj $obj
     
    4039                -anchor n -fill white -font "Helvetica 6" \
    4140                -tags "$this $obj" -state hidden]
    42         $c bind $_tick <Enter> [itcl::code $this handle_event "enter"]
    43         $c bind $_tick <Leave> [itcl::code $this handle_event "leave"]
     41        $c bind $_tick <Enter> [itcl::code $this HandleEvent "enter"]
     42        $c bind $_tick <Leave> [itcl::code $this HandleEvent "leave"]
    4443        $c bind $_tick <ButtonPress-1> \
    45             [itcl::code $this handle_event "start" %x %y]
     44            [itcl::code $this HandleEvent "start" %x %y]
    4645        $c bind $_tick <B1-Motion> \
    47             [itcl::code $this handle_event "update" %x %y]
     46            [itcl::code $this HandleEvent "update" %x %y]
    4847        $c bind $_tick <ButtonRelease-1> \
    49             [itcl::code $this handle_event "end" %x %y]
     48            [itcl::code $this HandleEvent "end" %x %y]
    5049    }
    5150    destructor {
     
    5352    }
    5453
    55     public method get_absolute_value {} {
     54    public method GetAbsoluteValue {} {
    5655        return $_value
    5756    }
    58     public method get_relative_value {} {
     57    public method GetRelativeValue {} {
    5958        array set limits [$_nvobj get_limits]
    6059        if { $limits(vmax) == $limits(vmin) } {
     
    6463        return [expr {($_value-$limits(vmin))/($limits(vmax) - $limits(vmin))}]
    6564    }
    66     public method activate { bool } {
     65    public method Activate { bool } {
    6766        if  { $bool || $_active_press || $_active_motion } {
    6867            $_canvas itemconfigure $_label -state normal
     
    7372        }
    7473    }
    75     public method show {} {
    76         set_absolute_value $_value
     74    public method Show {} {
     75        SetAbsoluteValue $_value
    7776        $_canvas itemconfigure $_tick -state normal
    7877        $_canvas raise $_tick
    7978    }
    80     public method hide {} {
     79    public method Hide {} {
    8180        $_canvas itemconfigure $_tick -state hidden
    8281    }
    83     public method get_screen_position { } {
    84         set x [get_relative_value]
     82    public method GetScreenPosition { } {
     83        set x [GetRelativeValue]
    8584        if { $x < 0.0 } {
    8685            set x 0.0
     
    9493        return $x
    9594    }
    96     public method set_absolute_value { x } {
     95    public method SetAbsoluteValue { x } {
    9796        set _value $x
    9897        set y 31
    9998        $_canvas itemconfigure $_label -text [format %.4g $_value]
    100         set x [get_screen_position]
     99        set x [GetScreenPosition]
    101100        $_canvas coords $_tick $x [expr {$y+3}]
    102101        $_canvas coords $_label $x [expr {$y+5}]
    103102    }
    104     public method set_relative_value { x } {
     103    public method SetRelativeValue { x } {
    105104        array set limits [$_nvobj get_limits]
    106105        if { $limits(vmax) == $limits(vmin) } {
     
    109108        }
    110109        set r [expr $limits(vmax) - $limits(vmin)]
    111         set_absolute_value [expr {($x * $r) + $limits(vmin)}]
     110        SetAbsoluteValue [expr {($x * $r) + $limits(vmin)}]
    112111    }
    113     public method handle_event { option args } {
     112    public method HandleEvent { option args } {
    114113        switch -- $option {
    115114            enter {
    116115                set _active_motion 1
    117                 activate yes
     116                Activate yes
    118117                $_canvas raise $_tick
    119118            }
    120119            leave {
    121120                set _active_motion 0
    122                 activate no
     121                Activate no
    123122            }
    124123            start {
    125124                $_canvas raise $_tick
    126125                set _active_press 1
    127                 activate yes
     126                Activate yes
    128127            }
    129128            update {
    130129                set w [winfo width $_canvas]
    131130                set x [lindex $args 0]
    132                 set_relative_value [expr {double($x-10)/($w-20)}]
     131                SetRelativeValue [expr {double($x-10)/($w-20)}]
    133132                $_nvobj OverIsoMarker $this $x
    134133                $_nvobj UpdateTransferFunction
     
    137136                set x [lindex $args 0]
    138137                if { ![$_nvobj RemoveDuplicateIsoMarker $this $x]} {
    139                     eval handle_event update $args
     138                    eval HandleEvent update $args
    140139                }
    141140                set _active_press 0
    142                 activate no
     141                Activate no
    143142            }
    144143            default {
  • trunk/gui/scripts/molvisviewer.tcl

    r772 r919  
     1
    12# ----------------------------------------------------------------------
    23#  COMPONENT: molvisviewer - view a molecule in 3D
     
    2324option add *MolvisViewer.font -*-helvetica-medium-r-normal-*-12-* widgetDefault
    2425
     26# must use this name -- plugs into Rappture::resources::load
     27proc MolvisViewer_init_resources {} {
     28    Rappture::resources::register \
     29        molvis_server [list Rappture::VisViewer::SetServerList "pymol"]
     30}
     31
     32set debug 1
     33proc debug { args } {
     34    global debug
     35    if { $debug } {
     36        puts stderr "[info level -1]: $args"
     37    }
     38}
     39
    2540itcl::class Rappture::MolvisViewer {
    26     inherit itk::Widget
     41    inherit Rappture::VisViewer
     42
    2743    itk_option define -device device Device ""
    2844
    29     constructor {hostlist args} { # defined below }
    30     destructor { # defined below }
    31 
    32     public method add {dataobj {settings ""}}
     45    constructor { hostlist args } {
     46        Rappture::VisViewer::constructor $hostlist
     47    } {
     48        # defined below
     49    }
     50    destructor {
     51        # defined below
     52    }
     53    public method Connect {}
     54    public method Disconnect {}
     55    public method isconnected {}
     56    public method download {option args}
     57
     58    public method add {dataobj {options ""}}
    3359    public method get {}
    3460    public method delete {args}
     
    3965    public method representation {option {model "all"} }
    4066
    41     public method connect {{hostlist ""}}
    42     public method disconnect {}
    43     public method isconnected {}
    44     public method download {option args}
    45     protected method _sendit {args}
    4667    protected method _send {args}
    47     protected method _receive { {sid ""} }
    4868    protected method _update { args }
    4969    protected method _rebuild { }
     
    5474    protected method _vmouse2 {option b m x y}
    5575    protected method _vmouse  {option b m x y}
    56     protected method _serverDown {}
    57 
    58     private variable _dispatcher "" ;# dispatcher for !events
    59     private variable _sid ""       ;# socket connection to nanovis server
    60     private variable _image        ;# image displayed in plotting area
     76
     77    private method _receive_image { args }
    6178
    6279    private variable _inrebuild 0
     
    7289    private variable _model
    7390    private variable _mlist
    74     private variable _mrepresentation "ball_and_stick"
     91    private variable _mrepresentation "ballnstick"
    7592
    7693    private variable _imagecache
     
    7895    private variable _labels  "default"
    7996    private variable _cacheid ""
    80     private variable _hostlist ""
    8197    private variable _cacheimage ""
    8298    private variable _busy 0
    83     private variable _mapped 0
    84 
    85     common settings  ;# array of settings for all known widgets
     99
     100    private common _settings  ;# array of settings for all known widgets
    86101}
    87102
     
    94109# ----------------------------------------------------------------------
    95110itcl::body Rappture::MolvisViewer::constructor {hostlist args} {
    96     #puts stderr "MolvisViewer::_constructor()"
     111    # Register events to the dispatcher.  Base class expects !rebuild
     112    # event to be registered.
     113
     114    # Rebuild
     115    $_dispatcher register !rebuild
     116    $_dispatcher dispatch $this !rebuild "[itcl::code $this _rebuild]; list"
     117    # Rocker
     118    $_dispatcher register !rocker
     119    $_dispatcher dispatch $this !rocker "[itcl::code $this rock step]; list"
     120    # Mouse Event
     121    $_dispatcher register !mevent
     122    $_dispatcher dispatch $this !mevent "[itcl::code $this _mevent]; list"
     123
     124    # Populate the slave interpreter with commands to handle responses from
     125    # the visualization server.
     126    $_parser alias image [itcl::code $this _receive_image]
    97127
    98128    set _rocker(dir) 1
     
    102132    set _state(server) 1
    103133    set _state(client) 1
    104 
    105     array set settings [list \
    106         $this-model $_mrepresentation \
    107         $this-modelimg [image create photo -width 64 -height 64] \
    108         $this-emblems 0 \
    109         $this-rock 0 \
    110     ]
    111     $settings($this-modelimg) copy [Rappture::icon ballnstick]
    112 
    113     Rappture::dispatcher _dispatcher
    114     $_dispatcher register !serverDown
    115     $_dispatcher dispatch $this !serverDown "[itcl::code $this _serverDown]; list"
     134    set _hostlist $hostlist
     135
     136    array set _settings [subst {
     137        $this-model $_mrepresentation
     138        $this-modelimg [Rappture::icon ballnstick]
     139        $this-emblems 0
     140        $this-rock 0
     141    }]
    116142
    117143    #
    118144    # Set up the widgets in the main body
    119145    #
    120     option add hull.width hull.height
    121     pack propagate $itk_component(hull) no
    122 
    123     itk_component add controls {
    124         frame $itk_interior.cntls
    125     } {
    126         usual
    127         rename -background -controlbackground controlBackground Background
    128     }
    129     pack $itk_component(controls) -side right -fill y
    130 
    131146    itk_component add zoom {
    132147        frame $itk_component(controls).zoom
     
    141156            -borderwidth 1 -padx 1 -pady 1 \
    142157            -bitmap [Rappture::icon reset] \
    143             -command [itcl::code $this _send reset]
     158            -command [itcl::code $this _send "reset"]
    144159    } {
    145160        usual
     
    199214    set fg [option get $itk_component(hull) font Font]
    200215
    201     label $inner.model.pict -image $settings($this-modelimg)
     216    label $inner.model.pict -image $_settings($this-modelimg)
    202217    pack $inner.model.pict -side left -anchor n
    203218    label $inner.model.heading -text "Method for drawing atoms:"
    204219    pack $inner.model.heading -side top -anchor w
    205220    radiobutton $inner.model.bstick -text "Balls and sticks" \
    206         -command [itcl::code $this representation ball_and_stick all] \
    207         -variable Rappture::MolvisViewer::settings($this-model) -value ball_and_stick
     221        -command [itcl::code $this representation ballnstick all] \
     222        -variable Rappture::MolvisViewer::_settings($this-model) \
     223        -value ballnstick
    208224    pack $inner.model.bstick -side top -anchor w
    209225    radiobutton $inner.model.spheres -text "Spheres" \
    210226        -command [itcl::code $this representation spheres all] \
    211         -variable Rappture::MolvisViewer::settings($this-model) -value spheres
     227        -variable Rappture::MolvisViewer::_settings($this-model) \
     228        -value spheres
    212229    pack $inner.model.spheres -side top -anchor w
    213230    radiobutton $inner.model.lines -text "Lines" \
    214231        -command [itcl::code $this representation lines all] \
    215         -variable Rappture::MolvisViewer::settings($this-model) -value lines
     232        -variable Rappture::MolvisViewer::_settings($this-model) \
     233        -value lines
    216234    pack $inner.model.lines -side top -anchor w
    217235
    218236    checkbutton $inner.labels -text "Show labels on atoms" \
    219237        -command [itcl::code $this emblems update] \
    220         -variable Rappture::MolvisViewer::settings($this-emblems)
     238        -variable Rappture::MolvisViewer::_settings($this-emblems)
    221239    pack $inner.labels -side top -anchor w -pady {4 1}
    222240
    223241    checkbutton $inner.rock -text "Rock model back and forth" \
    224242        -command [itcl::code $this rock toggle] \
    225         -variable Rappture::MolvisViewer::settings($this-rock)
     243        -variable Rappture::MolvisViewer::_settings($this-rock)
    226244    pack $inner.rock -side top -anchor w -pady {1 4}
    227245
     
    270288    #
    271289
    272     itk_component add area {
    273         frame $itk_interior.area
    274     }
    275     pack $itk_component(area) -expand yes -fill both
    276 
    277     set _image(plot) [image create photo]
    278290    set _image(id) ""
    279 
    280     itk_component add 3dview {
    281         label $itk_component(area).vol -image $_image(plot) \
    282             -highlightthickness 0
    283     } {
    284         usual
    285         ignore -highlightthickness
    286     }
    287     pack $itk_component(3dview) -expand yes -fill both
    288291
    289292    # set up bindings for rotation
     
    309312    #    [itcl::code $this _vmouse2 move 0 %s %x %y]
    310313
    311     connect $hostlist
    312 
    313314    bind $itk_component(3dview) <Configure> \
    314315        [itcl::code $this _configure %w %h]
     
    318319        [itcl::code $this _map]
    319320
    320     $_dispatcher register !rebuild
    321     $_dispatcher dispatch $this !rebuild "[itcl::code $this _rebuild]; list"
    322    
    323321    eval itk_initialize $args
     322    Connect
    324323}
    325324
     
    328327# ----------------------------------------------------------------------
    329328itcl::body Rappture::MolvisViewer::destructor {} {
    330     #puts stderr "MolvisViewer::destructor()"
    331     disconnect
     329    VisViewer::Disconnect
    332330
    333331    image delete $_image(plot)
    334     image delete $settings($this-modelimg)
    335     unset settings($this-emblems)
    336     unset settings($this-rock)
    337     unset settings($this-model)
    338     unset settings($this-modelimg)
     332    array unset _settings $this-*
    339333}
    340334
     
    362356}
    363357
    364 # ----------------------------------------------------------------------
    365 # USAGE: connect ?<host:port>,<host:port>...?
    366 #
    367 # Clients use this method to establish a connection to a new
    368 # server, or to reestablish a connection to the previous server.
    369 # Any existing connection is automatically closed.
    370 # ----------------------------------------------------------------------
    371 itcl::body Rappture::MolvisViewer::connect {{hostlist ""}} {
    372     #puts stderr "Rappture::MolvisViewer::connect($hostlist)"
    373 
    374     if { "" != $hostlist } { set _hostlist $hostlist }
    375 
    376     set hostlist $_hostlist
    377     $_image(plot) blank
    378 
    379     disconnect
    380 
    381     if {"" == $hostlist} {
     358#
     359# isconnected --
     360#
     361#       Indicates if we are currently connected to the visualization server.
     362#
     363itcl::body Rappture::MolvisViewer::isconnected {} {
     364    return [VisViewer::IsConnected]
     365}
     366
     367
     368#
     369# Connect --
     370#
     371#       Establishes a connection to a new visualization server.
     372#
     373itcl::body Rappture::MolvisViewer::Connect {} {
     374    #$_image(plot) blank
     375    set hosts [GetServerList "pymol"]
     376    if { "" == $hosts } {
    382377        return 0
    383378    }
    384 
    385     blt::busy hold $itk_component(hull) -cursor watch
    386    
    387     update idletasks
    388 
    389     # HACK ALERT! punt on this for now
    390     set memorySize 10000
    391 
    392     #
    393     # Connect to the molvis server. 
    394     # If it's too busy, that server may
    395     # forward us to another.
    396     #
    397 
    398     set hosts [split $hostlist ,]
    399 
    400     foreach {hostname port} [split [lindex $hosts 0] :] break
    401 
    402     set hosts [lrange $hosts 1 end]
    403     set result 0
    404 
    405     while {1} {
    406         if {[catch {socket $hostname $port} sid]} {
    407             if {[llength $hosts] == 0} {
    408                 break;
    409             }
    410             foreach {hostname port} [split [lindex $hosts 0] :] break
    411             set hosts [lrange $hosts 1 end]
    412             continue
    413         }
    414         fconfigure $sid -translation binary -encoding binary -buffering line -buffersize 1000
    415         #puts $sid "pymol"
    416         puts -nonewline $sid [binary format I $memorySize]
    417         flush $sid
    418 
    419         # read back a reconnection order
    420         set data [read $sid 4]
    421 
    422         if {[binary scan $data cccc b1 b2 b3 b4] != 4} {
    423             error "couldn't read redirection request"
    424         }
    425 
    426         set hostname [format "%u.%u.%u.%u" \
    427             [expr {$b1 & 0xff}] \
    428             [expr {$b2 & 0xff}] \
    429             [expr {$b3 & 0xff}] \
    430             [expr {$b4 & 0xff}]]
    431 
    432         if {[string equal $hostname "0.0.0.0"]} {
    433             set _sid $sid
    434             set _rocker(server) 0
    435             set _cacheid 0
    436 
    437             fileevent $_sid readable [itcl::code $this _receive $_sid]
    438 
    439             _send raw -defer set auto_color,0
    440             _send raw -defer set auto_show_lines,0
    441 
    442             set result 1
    443             break
    444         }
    445     }
    446 
    447     blt::busy release $itk_component(hull)
    448    
     379    set result [VisViewer::Connect $hosts]
     380    if { $result } {
     381        set _rocker(server) 0
     382        set _cacheid 0
     383        _send "raw -defer {set auto_color,0}"
     384        _send "raw -defer {set auto_show_lines,0}"
     385    }
    449386    return $result
    450387}
    451388
    452 # ----------------------------------------------------------------------
    453 # USAGE: disconnect
    454 #
    455 # Clients use this method to disconnect from the current rendering
    456 # server.
    457 # ----------------------------------------------------------------------
    458 itcl::body Rappture::MolvisViewer::disconnect {} {
    459     #puts stderr "MolvisViewer::disconnect()"
    460 
    461     catch { fileevent $_sid readable {} }
     389#
     390# Disconnect --
     391#
     392#       Clients use this method to disconnect from the current rendering
     393#       server.
     394#
     395itcl::body Rappture::MolvisViewer::Disconnect {} {
     396    VisViewer::Disconnect
     397
     398    # disconnected -- no more data sitting on server
    462399    catch { after cancel $_rocker(afterid) }
    463400    catch { after cancel $_mevent(afterid) }
    464     catch { close $_sid }
    465     catch { unset _dataobjs }
    466     catch { unset _model }
    467     catch { unset _mlist }
    468     catch { unset _imagecache }
    469 
    470     set _sid ""
     401    array unset _dataobjs
     402    array unset _model
     403    array unset _mlist
     404    array unset _imagecache
     405
    471406    set _state(server) 1
    472407    set _state(client) 1
    473 }
    474 
    475 # ----------------------------------------------------------------------
    476 # USAGE: isconnected
    477 #
    478 # Clients use this method to see if we are currently connected to
    479 # a server.
    480 # ----------------------------------------------------------------------
    481 itcl::body Rappture::MolvisViewer::isconnected {} {
    482     #puts stderr "MolvisViewer::isconnected()"
    483     return [expr {"" != $_sid}]
    484 }
    485 
    486 # ----------------------------------------------------------------------
    487 # USAGE: _send <arg> <arg> ...
    488 #
    489 # Used internally to send commands off to the rendering server.
    490 # ----------------------------------------------------------------------
    491 itcl::body Rappture::MolvisViewer::_sendit {args} {
    492     #puts stderr "Rappture::MolvisViewer::_sendit($args)"
    493 
    494     if { $_sid != "" } {
    495         if { ![catch { puts $_sid $args }] } {
    496             flush $_sid
    497             return 0
    498         } else {
    499             catch { close $_sid }
    500             set _sid ""
    501         }
    502     }
    503 
    504     $_dispatcher event -after 1 !rebuild
    505 
    506     return 1
    507 }
    508 
    509 itcl::body Rappture::MolvisViewer::_send {args} {
    510     #puts stderr "Rappture::MolvisViewer::_send($args)"
    511 
     408    set _outbuf ""
     409}
     410
     411itcl::body Rappture::MolvisViewer::_send { args } {
    512412    if { $_state(server) != $_state(client) } {
    513         if { [_sendit "frame -defer $_state(client)"] == 0 } {
     413        if { ![SendBytes "frame -defer $_state(client)"] } {
    514414            set _state(server) $_state(client)
    515415        }
     
    517417
    518418    if { $_rocker(server) != $_rocker(client) } {
    519         if { [_sendit "rock -defer $_rocker(client)"]  == 0 } {
     419        if { ![SendBytes "rock -defer $_rocker(client)"] } {
    520420            set _rocker(server) $_rocker(client)
    521421        }
    522422    }
    523 
    524     eval _sendit $args
    525 }
    526 
    527 # ----------------------------------------------------------------------
    528 # USAGE: _receive
    529 #
    530 # Invoked automatically whenever a command is received from the
    531 # rendering server.  Reads the incoming command and executes it in
    532 # a safe interpreter to handle the action.
    533 # ----------------------------------------------------------------------
    534 itcl::body Rappture::MolvisViewer::_receive { {sid ""} } {
    535     #puts stderr "Rappture::MolvisViewer::_receive($sid)"
    536 
    537     if { $sid == "" } {
    538         return
    539     }
    540 
    541     fileevent $sid readable {}
    542 
    543     if { $sid != $_sid } {
    544         return
    545     }
    546 
    547     fconfigure $_sid -buffering line -blocking 0
    548        
    549     if {[gets $_sid line] < 0} {
    550 
    551         if { ![fblocked $_sid] } {
    552             catch { close $_sid }
    553             set _sid ""
    554             $_dispatcher event -after 750 !serverDown
    555         }
    556 
    557     }  elseif {[regexp {^\s*nv>\s*image\s+(\d+)\s*(\d+)\s*,\s*(\d+)\s*,\s*(-{0,1}\d+)} $line whole match cacheid frame rock]} {
    558 
    559         set tag "$frame,$rock"
    560            
    561         if { $cacheid != $_cacheid } {
    562             catch { unset _imagecache }
    563             set _cacheid $cacheid
    564         }
    565 
    566         fconfigure $_sid -buffering none -blocking 1
    567         set _imagecache($tag) [read $_sid $match]
    568         #puts stderr "CACHED: $tag,$cacheid"
    569         $_image(plot) put $_imagecache($tag)
    570         set _image(id) $tag
    571 
    572         if { $_busy } {
    573             $itk_component(3dview) configure -cursor ""
    574             set _busy 0
    575         }
    576 
    577     } else {
    578         # this shows errors coming back from the engine
    579         puts $line
    580     }
    581    
    582     if { $_sid != "" } {
    583         fileevent $_sid readable [itcl::code $this _receive $_sid]
    584     }
    585 }
     423    eval SendBytes $args
     424}
     425
     426#
     427# _receive_image -bytes <size>
     428#
     429#     Invoked automatically whenever the "image" command comes in from
     430#     the rendering server.  Indicates that binary image data with the
     431#     specified <size> will follow.
     432#
     433itcl::body Rappture::MolvisViewer::_receive_image { size cacheid frame rock } {
     434    set tag "$frame,$rock"
     435    if { $cacheid != $_cacheid } {
     436        array unset _imagecache
     437        set _cacheid $cacheid
     438    }
     439    set _imagecache($tag) [ReceiveBytes $size]
     440 
     441    #puts stderr "CACHED: $tag,$cacheid"
     442    $_image(plot) configure -data $_imagecache($tag)
     443    set _image(id) $tag
     444}
     445
    586446
    587447# ----------------------------------------------------------------------
     
    593453# ----------------------------------------------------------------------
    594454itcl::body Rappture::MolvisViewer::_rebuild {} {
    595     #puts stderr "Rappture::MolvisViewer::_rebuild()"
    596 
    597455    if { $_inrebuild } {
    598456        # don't allow overlapping rebuild calls
     
    600458    }
    601459
    602     set _inrebuild 1
    603 
    604     if {"" == $_sid} {
    605         $_dispatcher cancel !serverDown
    606 
    607         set x [expr {[winfo rootx $itk_component(area)]+10}]
    608         set y [expr {[winfo rooty $itk_component(area)]+10}]
    609 
    610         Rappture::Tooltip::cue @$x,$y "Connecting..."
    611         update idletasks
    612 
    613         if {[catch {connect} ok] == 0 && $ok} {
    614             set w [winfo width $itk_component(3dview)]
    615             set h [winfo height $itk_component(3dview)]
    616             _send screen -defer $w $h
    617             Rappture::Tooltip::cue hide
    618         } else {
    619             Rappture::Tooltip::cue @$x,$y "Can't connect to visualization server.  This may be a network problem.  Wait a few moments and try resetting the view."
    620             set _inrebuild 0
    621             set _busy 1
    622             return
    623         }
    624     }
    625 
     460    #set _inrebuild 1
    626461    set changed 0
    627462    set _busy 1
     
    631466    # refresh GUI (primarily to make pending cursor changes visible)
    632467    update idletasks
    633 
    634468    set dlist [get]
    635 
    636469    foreach dev $dlist {
    637470        set model [$dev get components.molecule.model]
     
    653486            set _mlist($model) 2
    654487        }
    655 
    656488        if { ![info exists _dataobjs($model-$state)] } {
    657489            set data1      ""
     
    679511                incr serial
    680512            }
    681 
    682513            set data2 [$dev get components.molecule.pdb]
    683 
    684514            if {"" != $data1} {
    685                 eval _send loadpdb -defer \"$data1\" $model $state
     515                _send "loadpdb -defer \"$data1\" $model $state"
    686516                set _dataobjs($model-$state)  1
    687                 #puts stderr "loaded model $model into state $state"
     517                puts stderr "loaded model $model into state $state"
    688518            }
    689            
    690519            if {"" != $data2} {
    691                 eval _send loadpdb -defer \"$data2\" $model $state
     520                _send "loadpdb -defer \"$data2\" $model $state"
    692521                set _dataobjs($model-$state)  1
    693                 #puts stderr "loaded model $model into state $state"
     522                puts stderr "loaded model $model into state $state"
    694523            }
    695524        }
    696 
    697525        if { ![info exists _model($model-transparency)] } {
    698526            set _model($model-transparency) "undefined"
    699527        }
    700 
    701528        if { ![info exists _model($model-representation)] } {
    702529            set _model($model-representation) "undefined"
    703530            set _model($model-newrepresentation) $_mrepresentation
    704531        }
    705 
    706 
    707532        if { $_model($model-transparency) != $_dobj2transparency($dev) } {
    708             set  _model($model-newtransparency) $_dobj2transparency($dev)
     533            set _model($model-newtransparency) $_dobj2transparency($dev)
    709534        }
    710535    }
    711536
    712     # enable/disable models as required (0=off->off, 1=on->off, 2=off->on, 3=on->on)
     537    # enable/disable models as required (0=off->off, 1=on->off, 2=off->on,
     538    # 3=on->on)
    713539
    714540    foreach obj [array names _mlist] {
    715541        if { $_mlist($obj) == 1 } {
    716             _send disable -defer $obj
     542            _send "disable -defer $obj"
    717543            set _mlist($obj) 0
    718544            set changed 1
    719545        } elseif { $_mlist($obj) == 2 } {
    720546            set _mlist($obj) 1
    721             _send enable -defer $obj
     547            _send "enable -defer $obj"
    722548            if { $_labels } {
    723                 _send label -defer on
     549                _send "label -defer on"
    724550            } else {
    725                 _send label -defer off
     551                _send "label -defer off"
    726552            }
    727553            set changed 1
     
    730556        }
    731557
    732 
    733558        if { $_mlist($obj) == 1 } {
    734             if {  [info exists _model($obj-newtransparency)] || [info exists _model($obj-newrepresentation)] } {
     559            if {  [info exists _model($obj-newtransparency)] ||
     560                  [info exists _model($obj-newrepresentation)] } {
    735561                if { ![info exists _model($obj-newrepresentation)] } {
    736562                    set _model($obj-newrepresentation) $_model($obj-representation)
     
    739565                    set _model($obj-newtransparency) $_model($obj-transparency)
    740566                }
    741                 _send $_model($obj-newrepresentation) -defer -model $obj -$_model($obj-newtransparency)
     567                set rep $_model($obj-newrepresentation)
     568                set transp $_model($obj-newtransparency)
     569                _send "$_model($obj-newrepresentation) -defer -model $obj -$_model($obj-newtransparency)"
    742570                set changed 1
    743571                set _model($obj-transparency) $_model($obj-newtransparency)
     
    751579
    752580    }
    753 
    754581    if { $changed } {
    755         catch { unset _imagecache }
    756     }
    757 
     582        array unset _imagecache
     583    }
    758584    if { $dlist == "" } {
    759585        set _state(server) 1
    760586        set _state(client) 1
    761         _send frame -push 1
     587        _send "frame -push 1"
    762588    } elseif { ![info exists _imagecache($state,$_rocker(client))] } {
    763589        set _state(server) $state
    764590        set _state(client) $state
    765         _send frame -push $state
     591        _send "frame -push $state"
    766592    } else {
    767593        set _state(client) $state
     
    770596
    771597    set _inrebuild 0
    772 
    773     if { $_sid == "" } {
    774         # connection failed during rebuild, don't attempt to reconnect/rebuild
    775         # until user initiates some action
    776 
    777         disconnect
    778         $_dispatcher cancel !rebuild
    779         $_dispatcher event -after 750 !serverDown
    780     }
    781598    $itk_component(3dview) configure -cursor ""
    782599}
    783600
    784601itcl::body Rappture::MolvisViewer::_unmap { } {
    785     #puts stderr "Rappture::MolvisViewer::_unmap()"
    786 
    787602    #pause rocking loop while unmapped (saves CPU time)
    788603    rock pause
    789604
    790     # blank image, mark current image dirty
    791     # this will force reload from cache, or remain blank if cache is cleared
    792     # this prevents old image from briefly appearing when a new result is added
     605    # Blank image, mark current image dirty
     606    # This will force reload from cache, or remain blank if cache is cleared
     607    # This prevents old image from briefly appearing when a new result is added
    793608    # by result viewer
    794609
    795     set _mapped 0
    796     $_image(plot) blank
     610    #$_image(plot) blank
    797611    set _image(id) ""
    798612}
    799613
    800614itcl::body Rappture::MolvisViewer::_map { } {
    801     #puts stderr "Rappture::MolvisViewer::_map()"
    802 
    803     set _mapped 1
    804 
    805     # resume rocking loop if it was on
    806     rock unpause
    807 
    808     # rebuild image if modified, or redisplay cached image if not
    809     $_dispatcher event -idle !rebuild
     615    if { [isconnected] } {
     616        # resume rocking loop if it was on
     617        rock unpause
     618        # rebuild image if modified, or redisplay cached image if not
     619        $_dispatcher event -idle !rebuild
     620    }
    810621}
    811622
    812623itcl::body Rappture::MolvisViewer::_configure { w h } {
    813     #puts stderr "Rappture::MolvisViewer::_configure($w $h)"
    814 
    815624    $_image(plot) configure -width $w -height $h
    816    
    817625    # immediately invalidate cache, defer update until mapped
    818    
    819     catch { unset _imagecache }
    820 
    821     if { $_mapped } {
    822         _send screen $w $h
    823     } else {
    824         _send screen -defer $w $h
     626    array unset _imagecache
     627    if { [isconnected] } {
     628        if { [winfo ismapped $itk_component(3dview)] } {
     629            _send "screen $w $h"
     630            _send "reset -push"
     631        } else {
     632            _send "screen -defer $w $h"
     633            _send "reset -push"
     634        }
    825635    }
    826636}
     
    835645# ----------------------------------------------------------------------
    836646itcl::body Rappture::MolvisViewer::_zoom {option} {
    837     #puts stderr "MolvisViewer::_zoom()"
    838647    switch -- $option {
    839         in {
    840             _send zoom 10
    841         }
    842         out {
    843             _send zoom -10
    844         }
    845         reset {
    846             _send reset
     648        "in" {
     649            _send "zoom 10"
     650        }
     651        "out" {
     652            _send "zoom -10"
     653        }
     654        "reset" {
     655            _send "reset"
    847656        }
    848657    }
     
    850659
    851660itcl::body Rappture::MolvisViewer::_update { args } {
    852     #puts stderr "Rappture::MolvisViewer::_update($args)"
    853 
    854     if { $_image(id) != "$_state(client),$_rocker(client)" } {
    855         if { [info exists _imagecache($_state(client),$_rocker(client))] } {
     661    set tag "$_state(client),$_rocker(client)"
     662    if { $_image(id) != "$tag" } {
     663        if { [info exists _imagecache($tag)] } {
    856664            #puts stderr "DISPLAYING CACHED IMAGE"
    857             $_image(plot) put $_imagecache($_state(client),$_rocker(client))
    858             set _image(id) "$_state(client),$_rocker(client)"
     665            $_image(plot) configure -data $_imagecache($tag)
     666            set _image(id) "$tag"
    859667        }
    860668    }
     
    870678# ----------------------------------------------------------------------
    871679itcl::body Rappture::MolvisViewer::rock { option } {
    872     #puts "MolvisViewer::_rock($option,$_rocker(client))"
    873    
    874680    # cancel any pending rocks
    875681    if { [info exists _rocker(afterid)] } {
     
    885691        }
    886692    }
    887 
    888693    if { $option == "on" || ($option == "toggle" && !$_rocker(on)) } {
    889694        set _rocker(on) 1
    890         set settings($this-rock) 1
     695        set _settings($this-rock) 1
    891696        $itk_component(rock) configure -relief sunken
    892697    } elseif { $option == "off" || ($option == "toggle" && $_rocker(on)) } {
    893698        set _rocker(on) 0
    894         set settings($this-rock) 0
     699        set _settings($this-rock) 0
    895700        $itk_component(rock) configure -relief raised
    896701    } elseif { $option == "step"} {
    897 
    898702        if { $_rocker(client) >= 10 } {
    899703            set _rocker(dir) -1
     
    901705            set _rocker(dir) 1
    902706        }
    903 
    904707        set _rocker(client) [expr {$_rocker(client) + $_rocker(dir)}]
    905    
    906708        if { ![info exists _imagecache($_state(server),$_rocker(client))] } {
    907709            set _rocker(server) $_rocker(client)
    908             _send rock $_rocker(client)
     710            _send "rock $_rocker(client)"
    909711        }
    910712        _update
    911713    }
    912 
    913714    if { $_rocker(on) && $option != "pause" } {
    914715         set _rocker(afterid) [after 200 [itcl::code $this rock step]]
     
    935736
    936737        catch { set diff [expr $now - $_mevent(time)] }
    937 
    938738        if {$diff < 75} { # 75ms between motion updates
    939739            return
    940740        }
    941741    }
    942 
    943      _send vmouse $vButton $vModifier $vState $x $y
    944 
     742    _send "vmouse $vButton $vModifier $vState $x $y"
    945743    set _mevent(time) $now
    946744}
    947745
    948746itcl::body Rappture::MolvisViewer::_vmouse {option b m x y} {
    949     #puts stderr "Rappture::MolvisViewer::_vmouse($option,$b,$m,$x,$y)"
    950 
    951747    set now  [clock clicks -milliseconds]
    952 
    953748    # cancel any pending delayed dragging events
    954749    if { [info exists _mevent(afterid)] } {
     
    960755        set option "click"
    961756    }
    962 
    963757    if { $option == "click" } {
    964758        $itk_component(3dview) configure -cursor fleur
    965759    }
    966 
    967760    if { $option == "drag" || $option == "release" } {
    968761        set diff 0
    969762        catch { set diff [expr $now - $_mevent(time) ] }
    970 
    971763        if {$diff < 75 && $option == "drag" } { # 75ms between motion updates
    972764            set _mevent(afterid) [after [expr 75 - $diff] [itcl::code $this _vmouse drag $b $m $x $y]]
    973765            return
    974766        }
    975 
    976767        set w [winfo width $itk_component(3dview)]
    977768        set h [winfo height $itk_component(3dview)]
    978 
    979769        if {$w <= 0 || $h <= 0} {
    980770            return
    981771        }
    982 
    983772        set x1 [expr $w / 3]
    984773        set x2 [expr $x1 * 2]
     
    1006795            set mz $dx
    1007796        }
    1008 
    1009         _send rotate $mx $my $mz
    1010 
    1011     }
    1012 
     797        _send "rotate $mx $my $mz"
     798    }
    1013799    set _mevent(x) $x
    1014800    set _mevent(y) $y
    1015801    set _mevent(time) $now
    1016 
    1017802    if { $option == "release" } {
    1018803        $itk_component(3dview) configure -cursor ""
     
    1021806
    1022807# ----------------------------------------------------------------------
    1023 # USAGE: _serverDown
    1024 #
    1025 # Used internally to let the user know when the connection to the
    1026 # visualization server has been lost.  Puts up a tip encouraging the
    1027 # user to press any control to reconnect.
    1028 # ----------------------------------------------------------------------
    1029 itcl::body Rappture::MolvisViewer::_serverDown {} {
    1030     #puts stderr "MolvisViewer::_serverDown()"
    1031 
    1032     set x [expr {[winfo rootx $itk_component(area)]+10}]
    1033     set y [expr {[winfo rooty $itk_component(area)]+10}]
    1034 
    1035     if { $_busy } {
    1036         $itk_component(3dview) configure -cursor ""
    1037         set _busy 0
    1038     }
    1039 
    1040     Rappture::Tooltip::cue @$x,$y "Lost connection to visualization server.  This happens sometimes when there are too many users and the system runs out of memory.\n\nTo reconnect, reset the view or press any other control.  Your picture should come right back up."
    1041 }
    1042 
    1043 # ----------------------------------------------------------------------
    1044808# USAGE: representation spheres
    1045 # USAGE: representation ball_and_stick
     809# USAGE: representation ballnstick
    1046810# USAGE: representation lines
    1047811#
     
    1050814# ----------------------------------------------------------------------
    1051815itcl::body Rappture::MolvisViewer::representation {option {model "all"} } {
    1052     #puts stderr "Rappture::MolvisViewer::representation($option,$model)"
    1053 
    1054     if { $option == $_mrepresentation } { return }
    1055 
    1056     switch -- $option {
    1057         spheres {
    1058             $settings($this-modelimg) copy [Rappture::icon spheres]
    1059         }
    1060         ball_and_stick {
    1061             $settings($this-modelimg) copy [Rappture::icon ballnstick]
    1062         }
    1063         lines {
    1064             $settings($this-modelimg) copy [Rappture::icon lines]
    1065         }
    1066         default {
    1067             return
    1068         }
    1069     }
    1070 
    1071     # save the current option to set all radiobuttons -- just in case
    1072     # this method gets called without the user clicking on a radiobutton
    1073     set settings($this-model) $option
    1074 
     816    if { $option == $_mrepresentation } {
     817        return
     818    }
     819    set _settings($this-modelimg) [Rappture::icon $option]
     820    set inner [$itk_component(controls).panel component inner]
     821    $inner.model.pict configure -image $_settings($this-modelimg)
     822
     823    # Save the current option to set all radiobuttons -- just in case.
     824    # This method gets called without the user clicking on a radiobutton.
     825    set _settings($this-model) $option
    1075826    set _mrepresentation $option
    1076827
     
    1080831        set models $model
    1081832    }
    1082 
    1083833    foreach obj $models {
    1084834        if { [info exists _model($obj-representation)] } {
     
    1090840        }
    1091841    }
    1092 
    1093     $_dispatcher event -idle !rebuild
     842    if { [isconnected] } {
     843        $_dispatcher event -idle !rebuild
     844    }
    1094845}
    1095846
     
    1102853# ----------------------------------------------------------------------
    1103854itcl::body Rappture::MolvisViewer::emblems {option} {
    1104     #puts stderr "MolvisViewer::emblems($option)"
    1105 
    1106855    switch -- $option {
    1107856        on {
     
    1112861        }
    1113862        toggle {
    1114             if {$settings($this-emblems)} {
     863            if {$_settings($this-emblems)} {
    1115864                set emblem 0
    1116865            } else {
     
    1119868        }
    1120869        update {
    1121             set emblem $settings($this-emblems)
     870            set emblem $_settings($this-emblems)
    1122871        }
    1123872        default {
    1124             error "bad option \"$option\": should be on, off, toggle, update"
    1125         }
    1126     }
    1127 
     873            error "bad option \"$option\": should be on, off, toggle, or update"
     874        }
     875    }
    1128876    set _labels $emblem
    1129 
    1130     if {$emblem == $settings($this-emblems) && $option != "update"} {
     877    if {$emblem == $_settings($this-emblems) && $option != "update"} {
    1131878        # nothing to do
    1132879        return
     
    1135882    if {$emblem} {
    1136883        $itk_component(labels) configure -relief sunken
    1137         set settings($this-emblems) 1
    1138         _send label on
     884        set _settings($this-emblems) 1
     885        _send "label on"
    1139886    } else {
    1140887        $itk_component(labels) configure -relief raised
    1141         set settings($this-emblems) 0
    1142         _send label off
     888        set _settings($this-emblems) 0
     889        _send "label off"
    1143890    }
    1144891}
     
    1152899# -brightness and -raise do anything.
    1153900# ----------------------------------------------------------------------
    1154 itcl::body Rappture::MolvisViewer::add { dataobj {settings ""}} {
    1155     #puts stderr "Rappture::MolvisViewer::add($dataobj)"
    1156 
     901itcl::body Rappture::MolvisViewer::add { dataobj {options ""}} {
    1157902    array set params {
    1158         -color auto
    1159         -brightness 0
    1160         -width 1
    1161         -raise 0
    1162         -linestyle solid
    1163         -description ""
    1164         -param ""
    1165     }
    1166 
    1167     foreach {opt val} $settings {
     903        -color          auto
     904        -brightness     0
     905        -width          1
     906        -raise          0
     907        -linestyle      solid
     908        -description    ""
     909        -param          ""
     910    }
     911
     912    foreach {opt val} $options {
    1168913        if {![info exists params($opt)]} {
    1169914            error "bad settings \"$opt\": should be [join [lsort [array names params]] {, }]"
     
    1197942        set _dobj2raise($dataobj) $params(-raise)
    1198943
    1199         $_dispatcher event -idle !rebuild
     944        if { [isconnected] } {
     945            $_dispatcher event -idle !rebuild
     946        }
    1200947    }
    1201948}
     
    1208955# ----------------------------------------------------------------------
    1209956itcl::body Rappture::MolvisViewer::get {} {
    1210     #puts stderr "Rappture::MolvisViewer::get()"
    1211 
    1212957    # put the dataobj list in order according to -raise options
    1213958    set dlist $_dlist
     
    1231976# ----------------------------------------------------------------------
    1232977itcl::body Rappture::MolvisViewer::delete {args} {
    1233     #puts stderr "Rappture::MolvisViewer::delete($args)"
    1234 
    1235978    if {[llength $args] == 0} {
    1236979        set args $_dlist
     
    1254997    # if anything changed, then rebuild the plot
    1255998    if {$changed} {
    1256         $_dispatcher event -idle !rebuild
     999        if { [isconnected] } {
     1000            $_dispatcher event -idle !rebuild
     1001        }
    12571002    }
    12581003}
     
    12621007# ----------------------------------------------------------------------
    12631008itcl::configbody Rappture::MolvisViewer::device {
    1264     #puts stderr "Rappture::MolvisViewer::device($itk_option(-device))"
    1265 
    12661009    if {$itk_option(-device) != "" } {
    12671010
     
    12751018    }
    12761019
    1277     $_dispatcher event -idle !rebuild
    1278 }
     1020    if { [isconnected] } {
     1021        $_dispatcher event -idle !rebuild
     1022    }
     1023}
  • trunk/gui/scripts/nanovisviewer.tcl

    r907 r919  
    3232proc NanovisViewer_init_resources {} {
    3333    Rappture::resources::register \
    34         nanovis_server [list Rappture::VisViewer::SetServerList "nanovis" ]
     34        nanovis_server [list Rappture::VisViewer::SetServerList "nanovis"]
    3535}
    3636
     
    8686    protected method _fixLegend {}
    8787    protected method GenTransfuncData {dataobj comp}
    88     protected method UpdateTransferFunction {}
    89     protected method RemoveDuplicateIsoMarker { m x }
    90     protected method OverIsoMarker { m x }
    91     protected method AddIsoMarker { x y }
    92     protected method InitIsoMarkers {dataobj comp}
    93     protected method HideIsoMarkers {dataobj}
    94     protected method ShowIsoMarkers {dataobj}
     88    public method UpdateTransferFunction {}
     89    public method RemoveDuplicateIsoMarker { m x }
     90    public method OverIsoMarker { m x }
     91    private method AddIsoMarker { x y }
     92    private method InitIsoMarkers {dataobj comp}
     93    private method HideIsoMarkers {dataobj}
     94    private method ShowIsoMarkers {dataobj}
    9595
    9696    private variable _outbuf       ;# buffer for outgoing commands
     
    151151    $_parser alias data [itcl::code $this _receive_data]
    152152
    153     set _view(theta) 45
    154     set _view(phi) 45
    155     set _view(psi) 0
    156     set _view(zoom) 1
    157     set _view(xfocus) 0
    158     set _view(yfocus) 0
    159     set _view(zfocus) 0
     153    # Initialize the view to some default parameters.
     154    array set _view {
     155        theta   45
     156        phi     45
     157        psi     0
     158        zoom    1.0
     159        xfocus  0
     160        yfocus  0
     161        zfocus  0
     162    }
    160163    set _obj2id(count) 0
    161164    set _id2obj(count) 0
     
    637640        }
    638641        now {
    639             #
    640             # Hack alert!  Need data in binary format,
    641             # so we'll save to a file and read it back.
    642             #
    643             set tmpfile /tmp/image[pid].jpg
    644             $_image(download) write $tmpfile -format jpeg
    645             set fid [open $tmpfile r]
    646             fconfigure $fid -encoding binary -translation binary
    647             set bytes [read $fid]
    648             close $fid
    649             file delete -force $tmpfile
    650 
    651             return [list .jpg $bytes]
     642            # Doing an image base64 encode/decode has to be better than
     643            # writing the image to a file and reading it back in.
     644            set data [$_image(plot) data -format jpeg]
     645            set data [Rappture::encoding::decode -as b64 $data]
     646            return [list .jpg $data]
    652647        }
    653648        default {
     
    665660# ----------------------------------------------------------------------
    666661itcl::body Rappture::NanovisViewer::Connect {} {
    667     Disconnect
    668662    set _hosts [GetServerList "nanovis"]
    669663    if { "" == $_hosts } {
     
    674668}
    675669
    676 # ----------------------------------------------------------------------
    677 # USAGE: isconnected ?<host:port>,<host:port>...?
    678 #
    679 # Clients use this method to establish a connection to a new
    680 # server, or to reestablish a connection to the previous server.
    681 # Any existing connection is automatically closed.
    682 # ----------------------------------------------------------------------
     670#
     671# isconnected --
     672#
     673#       Indicates if we are currently connected to the visualization server.
     674#
    683675itcl::body Rappture::NanovisViewer::isconnected {} {
    684676    return [VisViewer::IsConnected]
    685677}
    686678
    687 # ----------------------------------------------------------------------
    688 # USAGE: Disconnect
    689 #
    690 # Clients use this method to disconnect from the current rendering
    691 # server.
    692 # ----------------------------------------------------------------------
     679#
     680# Disconnect --
     681#
     682#       Clients use this method to disconnect from the current rendering
     683#       server.
     684#
    693685itcl::body Rappture::NanovisViewer::Disconnect {} {
    694686    VisViewer::Disconnect
     
    704696}
    705697
    706 # ----------------------------------------------------------------------
    707 # USAGE: _send <string>
    708 #
    709 # Used internally to send commands off to the rendering server.
    710 # ----------------------------------------------------------------------
     698#
     699# _send
     700#
     701#       Send commands off to the rendering server.  If we're currently
     702#       sending data objects to the server, buffer the commands to be
     703#       sent later.
     704#
    711705itcl::body Rappture::NanovisViewer::_send {string} {
    712     if { ![isconnected]} {
    713         $_dispatcher cancel !serverDown
    714         set x [expr {[winfo rootx $itk_component(area)]+10}]
    715         set y [expr {[winfo rooty $itk_component(area)]+10}]
    716         Rappture::Tooltip::cue @$x,$y "Connecting..."
    717 
    718         set code [catch { Connect } ok]
    719         if { $code == 0 && $ok} {
    720             set w [winfo width $itk_component(3dview)]
    721             set h [winfo height $itk_component(3dview)]
    722 
    723             if { [Send "screen $w $h"] } {
    724                 set _view(theta) 45
    725                 set _view(phi) 45
    726                 set _view(psi) 0
    727                 set _view(zoom) 1.0
    728                 $_dispatcher event -idle !rebuild
    729                 Rappture::Tooltip::cue hide
    730             }
    731         } else {
    732             Rappture::Tooltip::cue @$x,$y "Can't connect to visualization server.  This may be a network problem.  Wait a few moments and try resetting the view."
     706    if {[llength $_sendobjs] > 0} {
     707        append _outbuf $string "\n"
     708    } else {
     709        if {[SendBytes $string]} {
     710            foreach line [split $string \n] {
     711                SendEcho >>line $line
     712            }
    733713        }
    734     } else {
    735         # If we're transmitting objects, then buffer this command.
    736         if {[llength $_sendobjs] > 0} {
    737             append _outbuf $string "\n"
    738         } else {
    739             if { [Send $string] } {
    740                 foreach line [split $string \n] {
    741                     SendEcho >>line $line
    742                 }
    743             }
    744         }
    745714    }
    746715}
     
    762731
    763732            # tell the engine to expect some data
    764             set cmdstr "volume data follows [string length $data]"
    765             if { ![Send $cmdstr] } {
     733            set nbytes [string length $data]
     734            if { ![SendBytes "volume data follows $nbytes"] } {
    766735                return
    767736            }
    768             while {[string length $data] > 0} {
    769                 update
    770 
    771                 set chunk [string range $data 0 8095]
    772                 set data [string range $data 8096 end]
    773                 if { ![Send $chunk -nonewline] } {
    774                     return
    775                 }
    776                 Flush
    777             }
    778             Send ""
    779 
     737            if { ![SendBytes $data] } {
     738                return
     739            }
    780740            set volId $_obj2id(count)
    781741            incr _obj2id(count)
     
    808768
    809769    # if there are any commands in the buffer, send them now that we're done
    810     Send $_outbuf
     770    SendBytes $_outbuf
    811771    set _outbuf ""
    812772
     
    832792            foreach {sname cmap wmap} [GenTransfuncData $dataobj $comp] break
    833793            set cmdstr [list transfunc define $sname $cmap $wmap]
    834             if {![Send $cmdstr] } {
     794            if {![SendBytes $cmdstr] } {
    835795                return
    836796            }
     
    852812    ShowIsoMarkers $first
    853813    # if there are any commands in the buffer, send them now that we're done
    854     Send $_outbuf
     814    SendBytes $_outbuf
    855815    set _outbuf ""
    856816    $_dispatcher event -idle !legend
     
    866826itcl::body Rappture::NanovisViewer::_receive_image {option size} {
    867827    if { [isconnected] } {
    868         set bytes [Receive $size]
     828        set bytes [ReceiveBytes $size]
    869829        $_image(plot) configure -data $bytes
    870830        ReceiveEcho <<line "<read $size bytes for [image width $_image(plot)]x[image height $_image(plot)] image>"
     
    881841itcl::body Rappture::NanovisViewer::_receive_legend { ivol vmin vmax size } {
    882842    if { [isconnected] } {
    883         set bytes [Receive $size]
     843        set bytes [ReceiveBytes $size]
    884844        $_image(legend) configure -data $bytes
    885845        ReceiveEcho <<line "<read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>"
     
    975935        $_dispatcher event -idle !send_dataobjs
    976936    } else {
     937        set w [winfo width $itk_component(3dview)]
     938        set h [winfo height $itk_component(3dview)]
     939        _send "screen $w $h"
    977940        # nothing to send -- activate the proper volume
    978941        set first [lindex [get] 0]
     
    10581021itcl::body Rappture::NanovisViewer::_zoom {option} {
    10591022    switch -- $option {
    1060         in {
    1061             set _view(zoom) [expr {$_view(zoom)*1.25}]
    1062             _send "camera zoom $_view(zoom)"
    1063         }
    1064         out {
    1065             set _view(zoom) [expr {$_view(zoom)*0.8}]
    1066             _send "camera zoom $_view(zoom)"
    1067         }
    1068         reset {
    1069             set _view(theta) 45
    1070             set _view(phi) 45
    1071             set _view(psi) 0
    1072             set _view(zoom) 1.0
     1023        "in" {
     1024            set _view(zoom) [expr {$_view(zoom)* 1.25}]
     1025        }
     1026        "out" {
     1027            set _view(zoom) [expr {$_view(zoom)* 0.8}]
     1028        }
     1029        "reset" {
     1030            array set _view {
     1031                theta 45
     1032                phi 45
     1033                psi 0
     1034                zoom 1.0
     1035            }
    10731036            set xyz [Euler2XYZ $_view(theta) $_view(phi) $_view(psi)]
    10741037            _send "camera angle $xyz"
    1075             _send "camera zoom $_view(zoom)"
    1076         }
    1077     }
     1038        }
     1039    }
     1040    _send "camera zoom $_view(zoom)"
    10781041}
    10791042
     
    11361099                }
    11371100
    1138                 set _view(theta) $theta
    1139                 set _view(phi) $phi
    1140                 set _view(psi) $psi
    1141                 set xyz [Euler2XYZ $_view(theta) $_view(phi) $_view(psi)]
     1101                array set _view [subst {
     1102                    theta $theta
     1103                    phi $phi
     1104                    psi $psi
     1105                }]
     1106                set xyz [Euler2XYZ $theta $phi $psi]
    11421107                _send "camera angle $xyz"
    11431108                set _click(x) $x
     
    12821247            }
    12831248        }
     1249
    12841250        transp {
    12851251            if {[isconnected]} {
     
    13061272                    set val [$inner.scales.thickness get]
    13071273                    # Scale values between 0.00001 and 0.01000
    1308                     set sval [expr {0.00001*double($val)}]
     1274                    set sval [expr {0.0001*double($val)}]
    13091275                    set _thickness($dataobj) $sval
    13101276                    UpdateTransferFunction
     
    13871353    set isovalues {}
    13881354    foreach m $_isomarkers($key) {
    1389         lappend isovalues [$m get_relative_value]
     1355        lappend isovalues [$m GetRelativeValue]
    13901356    }
    13911357
     
    14751441    if { [info exists _isomarkers($dataobj)] } {
    14761442        foreach m $_isomarkers($dataobj) {
    1477             $m hide
     1443            $m Hide
    14781444        }
    14791445    }
     
    14881454    }
    14891455    foreach m $_isomarkers($dataobj) {
    1490         $m show
     1456        $m Show
    14911457    }
    14921458}
     
    15061472            set value [expr {$value * 0.01}]
    15071473            set m [IsoMarker \#auto $c $this]
    1508             $m set_relative_value $value
     1474            $m SetRelativeValue $value
    15091475            lappend _isomarkers($dataobj) $m
    15101476        } elseif { $n == 2 && $suffix == "x" } {
     
    15171483                set x [expr {double($i)/($nLevels+1)}]
    15181484                set m [IsoMarker \#auto $c $this]
    1519                 $m set_relative_value $x
     1485                $m SetRelativeValue $x
    15201486                lappend _isomarkers($dataobj) $m
    15211487            }
     
    15231489            # ${n} : Set absolute value.
    15241490            set m [IsoMarker \#auto $c $this]
    1525             $m set_absolute_value $value
     1491            $m SetAbsoluteValue $value
    15261492            lappend _isomarkers($dataobj) $m
    15271493        }
     
    15641530    set m [IsoMarker \#auto $c $this]
    15651531    set w [winfo width $c]
    1566     $m set_relative_value [expr {double($x-10)/($w-20)}]
    1567     $m show
     1532    $m SetRelativeValue [expr {double($x-10)/($w-20)}]
     1533    $m Show
    15681534    lappend _isomarkers($dataobj) $m
    15691535    UpdateTransferFunction
     
    15811547        set marker [namespace tail $marker]
    15821548        foreach m $_isomarkers($dataobj) {
    1583             set sx [$m get_screen_position]
     1549            set sx [$m GetScreenPosition]
    15841550            if { $m != $marker } {
    15851551                if { $x >= ($sx-3) && $x <= ($sx+3) } {
    1586                     $marker set_relative_value [$m get_relative_value]
     1552                    $marker SetRelativeValue [$m GetRelativeValue]
    15871553                    itcl::delete object $m
    15881554                    bell
     
    16071573        set marker [namespace tail $marker]
    16081574        foreach m $_isomarkers($dataobj) {
    1609             set sx [$m get_screen_position]
     1575            set sx [$m GetScreenPosition]
    16101576            if { $m != $marker } {
    16111577                set bool [expr { $x >= ($sx-3) && $x <= ($sx+3) }]
    1612                 $m activate $bool
     1578                $m Activate $bool
    16131579            }
    16141580        }
  • trunk/gui/scripts/unirect2d.tcl

    r858 r919  
    145145            set axis "zaxis"
    146146        }
     147        default {
     148            error "unknown axis description \"$which\""
     149        }
    147150    }
    148151#     set val [$_field get $axis.min]
  • trunk/gui/scripts/visviewer.tcl

    r908 r919  
    55#  This class is the base class for the various visualization viewers
    66#  that use the nanoserver render farm.
    7 #
    8 #  My plan is to make this class the parent of the NanovisViewer and
    9 #  HeightmapViewer classes. I'm going to move out all the server-related
    10 #  methods like _send*, _receive*, connect, disconnect, etc. from those
    11 #  classes into this one.
    127#
    138# ======================================================================
     
    2621
    2722    private common _servers          ;# array of visualization server lists
    28     set _servers(nanovis) "128.210.189.216:2000"
    29     set _servers(pymol) barney
    30 
    31     protected variable _dispatcher "" ;# dispatcher for !events
    32     protected variable _hosts ""     ;# list of hosts for server
    33     protected variable _sid ""       ;# socket connection to server
    34     protected variable _parser ""    ;# interpreter for incoming commands
    35     protected variable _inbuf        ;# buffer for incoming/outgoing commands
    36     protected variable _busy 0
     23    set _servers(nanovis) ""
     24    set _servers(pymol)   ""
     25
     26    protected variable _dispatcher ""   ;# dispatcher for !events
     27    protected variable _hosts ""        ;# list of hosts for server
     28    protected variable _sid ""          ;# socket connection to server
     29    protected variable _parser ""       ;# interpreter for incoming commands
    3730    protected variable _image
     31    private common _done                ;# Used to indicate status of send.
     32    private variable _buffer            ;# buffer for incoming/outgoing commands
    3833
    3934    constructor { hostlist args } {
     
    4641    private method _CheckNameList {namelist}
    4742    private method _Shuffle { hostlist }
    48     private method _ReceiveCmd {}
     43    private method _ReceiveHelper {}
    4944    private method _ServerDown {}
     45    private method _SendHelper {}
    5046
    5147    protected method SendEcho {channel {data ""}}
     
    5450    protected method Disconnect {}
    5551    protected method IsConnected {}
    56     protected method Send { cmdstr { switch "" } }
    57     protected method Receive { nbytes }
     52    protected method SendBytes { bytes }
     53    protected method ReceiveBytes { nbytes }
    5854    protected method Flush {}
    5955    protected method Color2RGB {color}
     
    8076    _CheckNameList $hostlist
    8177    set _hostlist $hostlist
    82 
    83     set _inbuf ""
    84 
     78    set _buffer(in) ""
     79    set _buffer(out) ""
    8580    #
    8681    # Create a parser to handle incoming requests
     
    191186itcl::body Rappture::VisViewer::Connect { hostlist } {
    192187    blt::busy hold $itk_component(hull) -cursor watch
    193     update idletasks
     188    update
    194189
    195190    # Shuffle the list of servers so as to pick random
     
    232227
    233228        if { [string equal $addr "0.0.0.0"] } {
    234             # Success: Cancel any pending serverDown events and release the
    235             # busy window over the hull.
     229            # We're connected. Cancel any pending serverDown events and
     230            # release the busy window over the hull.
    236231            $_dispatcher cancel !serverDown
    237232            blt::busy release $itk_component(hull)
    238             fconfigure $_sid -buffering line 
    239             fileevent $_sid readable [itcl::code $this _ReceiveCmd]
     233            fconfigure $_sid -buffering line
     234            fileevent $_sid readable [itcl::code $this _ReceiveHelper]
    240235            return 1
    241236        }
     
    247242}
    248243
    249 
    250 #
    251 # SendEcho --
    252 #
    253 #     Used internally to echo sent data to clients interested in this widget.
    254 #     If the -sendcommand option is set, then it is invoked in the global scope
    255 #     with the <channel> and <data> values as arguments.  Otherwise, this does
    256 #     nothing.
    257 #
    258 itcl::body Rappture::VisViewer::SendEcho {channel {data ""}} {
    259     #puts stderr ">>line $data"
    260     if {[string length $itk_option(-sendcommand)] > 0} {
    261         uplevel #0 $itk_option(-sendcommand) [list $channel $data]
    262     }
    263 }
    264 
    265 #
    266 # ReceiveEcho --
    267 #
    268 #     Echoes received data tzo clients interested in this widget.  If the
    269 #     -receivecommand option is set, then it is # invoked in the global
    270 #     scope with the <channel> and <data> values # as arguments.  Otherwise,
    271 #     this does nothing.
    272 #
    273 itcl::body Rappture::VisViewer::ReceiveEcho {channel {data ""}} {
    274     #puts stderr "<<line $data"
    275     if {[string length $itk_option(-receivecommand)] > 0} {
    276         uplevel #0 $itk_option(-receivecommand) [list $channel $data]
    277     }
    278 }
    279244
    280245#
     
    290255        $_dispatcher event -after 750 !serverDown
    291256    }
    292     set _inbuf ""                       
     257    set _buffer(in) ""                 
    293258}
    294259
     
    303268
    304269#
    305 # Send --
    306 #
    307 #    Send a string to the visualization server.
    308 #
    309 itcl::body Rappture::VisViewer::Send { cmdstr { switch "" } } {
    310     SendEcho >>line $cmdstr
    311     if { $switch != "" } {
    312         set code [catch {puts $switch $_sid $cmdstr} err]
     270# _SendHelper --
     271#
     272#       Helper routine called from a file event to send data when the
     273#       connection is writable (i.e. not blocked).  Sends data in chunks
     274#       of 8k (or less).  Sets magic variable _done($this) to indicate
     275#       that we're either finished (success) or could not send bytes to
     276#       the server (failure).
     277#
     278itcl::body Rappture::VisViewer::_SendHelper {} {
     279    set bytesLeft [string length $_buffer(out)]
     280    if { $bytesLeft > 0} {
     281        # 8095
     282        set chunk [string range $_buffer(out) 0 9]
     283        # 8096
     284        set _buffer(out)  [string range $_buffer(out) 10 end]
     285        # -8096
     286        incr bytesLeft -10
     287        set code [catch {
     288            if { $bytesLeft > 0 } {
     289                puts -nonewline $_sid $chunk
     290            } else {
     291                puts $_sid $chunk
     292            }           
     293        } err]
     294        if { $code != 0 } {
     295            puts stderr "error sending data to $_sid: $err"
     296            Disconnect
     297            set _done($this) 0;         # Failure
     298        }
    313299    } else {
    314         set code [catch {puts $_sid $cmdstr} err]
    315     }
     300        set _done($this) 1;             # Success
     301    }
     302}
     303
     304#
     305# SendBytes --
     306#
     307#       Send a a string to the visualization server. 
     308#
     309itcl::body Rappture::VisViewer::SendBytes { bytes } {
     310    SendEcho >>line $bytes
     311
     312    if { ![IsConnected]} {
     313        # If we aren't connected, assume it's because the connection to the
     314        # visualization server broke. Try to open a connection and trigger a
     315        # rebuild.
     316        $_dispatcher cancel !serverDown
     317        set x [expr {[winfo rootx $itk_component(area)]+10}]
     318        set y [expr {[winfo rooty $itk_component(area)]+10}]
     319        Rappture::Tooltip::cue @$x,$y "Connecting..."
     320        set code [catch { Connect } ok]
     321        if { $code == 0 && $ok} {
     322            $_dispatcher event -idle !rebuild
     323            Rappture::Tooltip::cue hide
     324        } else {
     325            Rappture::Tooltip::cue @$x,$y "Can't connect to visualization server.  This may be a network problem.  Wait a few moments and try resetting the view."
     326        }
     327        return
     328    }
     329    set _done($this) 1
     330    set _buffer(out) $bytes
     331    fileevent $_sid writable [itcl::code $this _SendHelper]
     332    tkwait variable ::Rappture::VisViewer::_done($this)
     333    fileevent $_sid writable ""
    316334    flush $_sid
    317     if { $code != 0 } {
    318         puts stderr "error sending data to $_sid: $err"
    319         Disconnect
    320         return 0
    321     }
    322     return 1
    323 }
    324 
    325 
    326 #
    327 # Receive --
    328 #
    329 #    Read some number of bytes from the visualization server.
    330 #
    331 itcl::body Rappture::VisViewer::Receive { size } {
     335    set _buffer(out) ""
     336    return $_done($this)
     337}
     338
     339#
     340# ReceiveBytes --
     341#
     342#    Read some number of bytes from the visualization server.
     343#
     344itcl::body Rappture::VisViewer::ReceiveBytes { size } {
    332345    if { [eof $_sid] } {
    333346        error "unexpected eof on socket"
     
    338351}
    339352
    340 #
    341 # Flush --
    342 #
    343 #    Flushes the socket.
    344 #
    345 itcl::body Rappture::VisViewer::Flush {} {
    346     if { [IsConnected] } {
    347         flush $_sid
    348     }
    349 }
    350 
    351 #
    352 # _ReceiveCmd --
    353 #
    354 #     Invoked automatically whenever a command is received from the
    355 #     rendering server.  Reads the incoming command and executes it in
    356 #     a safe interpreter to handle the action.
    357 #
    358 itcl::body Rappture::VisViewer::_ReceiveCmd {} {
     353#
     354# _ReceiveHelper --
     355#
     356#       Helper routine called from a file event when the connection is
     357#       readable (i.e. a command response has been sent by the rendering
     358#       server.  Reads the incoming command and executes it in a safe
     359#       interpreter to handle the action.
     360#
     361#       Note: This routine currently only handles command responses from
     362#             the visualization server.  It doesn't handle non-blocking
     363#             reads from the visualization server.
     364#
     365#           nv>image -bytes 100000              yes
     366#           ...following 100000 bytes...        no             
     367#
     368itcl::body Rappture::VisViewer::_ReceiveHelper {} {
    359369    if { [IsConnected] } {
    360370        if { [eof $_sid] } {
    361371            error "_receive: unexpected eof on socket"
    362372        }
    363         if {[gets $_sid line] < 0} {
     373        if { [gets $_sid line] < 0 } {
    364374            Disconnect
    365375        } elseif {[string equal [string range $line 0 2] "nv>"]} {
    366376            ReceiveEcho <<line $line
    367             append _inbuf [string range $line 3 end]
    368             if {[info complete $_inbuf]} {
    369                 set request $_inbuf
    370                 set _inbuf ""
     377            append _buffer(in) [string range $line 3 end]
     378            append _buffer(in) "\n"
     379            if {[info complete $_buffer(in)]} {
     380                set request $_buffer(in)
     381                set _buffer(in) ""
    371382                $_parser eval $request
    372383            }
     
    381392
    382393#
     394# Flush --
     395#
     396#    Flushes the socket.
     397#
     398itcl::body Rappture::VisViewer::Flush {} {
     399    if { [IsConnected] } {
     400        flush $_sid
     401    }
     402}
     403
     404
     405#
    383406# Color2RGB --
    384407#
     
    407430    return [list $xangle $yangle $zangle]
    408431}
     432
     433
     434#
     435# SendEcho --
     436#
     437#     Used internally to echo sent data to clients interested in this widget.
     438#     If the -sendcommand option is set, then it is invoked in the global scope
     439#     with the <channel> and <data> values as arguments.  Otherwise, this does
     440#     nothing.
     441#
     442itcl::body Rappture::VisViewer::SendEcho {channel {data ""}} {
     443    #puts stderr ">>line $data"
     444    if {[string length $itk_option(-sendcommand)] > 0} {
     445        uplevel #0 $itk_option(-sendcommand) [list $channel $data]
     446    }
     447}
     448
     449#
     450# ReceiveEcho --
     451#
     452#     Echoes received data tzo clients interested in this widget.  If the
     453#     -receivecommand option is set, then it is # invoked in the global
     454#     scope with the <channel> and <data> values # as arguments.  Otherwise,
     455#     this does nothing.
     456#
     457itcl::body Rappture::VisViewer::ReceiveEcho {channel {data ""}} {
     458    #puts stderr "<<line $data"
     459    if {[string length $itk_option(-receivecommand)] > 0} {
     460        uplevel #0 $itk_option(-receivecommand) [list $channel $data]
     461    }
     462}
Note: See TracChangeset for help on using the changeset viewer.