source: trunk/gui/scripts/deviceEditor.tcl @ 13

Last change on this file since 13 was 13, checked in by mmc, 16 years ago

Many improvements, including a new energy level viewer
for Huckel-IV. Added support for a new <boolean> type.
Fixed the cloud/field stuff so that when a cloud is 1D,
it reverts to BLT vectors so it will plot correctly.
Fixed the install script to work better on Windows.

File size: 7.6 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: deviceEditor - general-purpose device editor
3#
4#  This widget takes a <structure> description and chooses a specific
5#  editor appropriate for the contents of the structure.  If the
6#  <structure> contains a molecule, then it chooses a MoleculeViewer.
7#  If it contains a 1D device, then it chooses a deviceViewer1D.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005
11#  Purdue Research Foundation, West Lafayette, IN
12# ======================================================================
13package require Itk
14
15option add *DeviceEditor.width 5i widgetDefault
16option add *DeviceEditor.height 5i widgetDefault
17
18itcl::class Rappture::DeviceEditor {
19    inherit itk::Widget
20
21    constructor {owner args} { # defined below }
22
23    public method value {args}
24
25    # used for syncing embedded widgets
26    public method widgetfor {path {widget ""}}
27    public method changed {path}
28    public method sync {}
29    public method tool {}
30
31    protected method _redraw {}
32    protected method _type {xmlobj}
33
34    private variable _owner ""       ;# owner containing this editor
35    private variable _xmlobj ""      ;# XML <structure> object
36    private variable _path2widget    ;# maps path => widget in this editor
37}
38                                                                               
39itk::usual DeviceEditor {
40}
41
42# ----------------------------------------------------------------------
43# CONSTRUCTOR
44# ----------------------------------------------------------------------
45itcl::body Rappture::DeviceEditor::constructor {owner args} {
46    set _owner $owner
47
48    itk_option add hull.width hull.height
49    pack propagate $itk_component(hull) no
50
51    itk_component add top {
52        frame $itk_interior.top
53    }
54    pack $itk_component(top) -fill x
55
56    itk_component add editors {
57        Rappture::Notebook $itk_interior.editors
58    }
59    pack $itk_component(editors) -expand yes -fill both
60
61    eval itk_initialize $args
62}
63
64
65# ----------------------------------------------------------------------
66# USAGE: value ?-check? ?<newval>?
67#
68# Clients use this to query/set the value for this widget.  With
69# no args, it returns the current value for the widget.  If the
70# <newval> is specified, it sets the value of the widget and
71# sends a <<Value>> event.  If the -check flag is included, the
72# new value is not actually applied, but just checked for correctness.
73# ----------------------------------------------------------------------
74itcl::body Rappture::DeviceEditor::value {args} {
75    set onlycheck 0
76    set i [lsearch -exact $args -check]
77    if {$i >= 0} {
78        set onlycheck 1
79        set args [lreplace $args $i $i]
80    }
81
82    if {[llength $args] == 1} {
83        # delete any existing object
84        if {$_xmlobj != ""} {
85            itcl::delete object $_xmlobj
86            set _xmlobj ""
87        }
88        set newval [lindex $args 0]
89        if {$newval != ""} {
90            if {$onlycheck} {
91                return
92            }
93            if {![Rappture::library isvalid $newval]} {
94                error "bad value \"$newval\": should be Rappture::Library"
95            }
96            set _xmlobj $newval
97        }
98        _redraw
99        event generate $itk_component(hull) <<Value>>
100
101    } elseif {[llength $args] == 0} {
102        sync  ;# querying -- must sync controls with the value
103    } else {
104        error "wrong # args: should be \"value ?-check? ?newval?\""
105    }
106    return $_xmlobj
107}
108
109# ----------------------------------------------------------------------
110# USAGE: widgetfor <path> ?<widget>?
111#
112# Used by embedded widgets such as a Controls panel to register the
113# various controls associated with this page.  That way, this editor
114# knows what widgets to look at when syncing itself to the underlying
115# XML data.
116# ----------------------------------------------------------------------
117itcl::body Rappture::DeviceEditor::widgetfor {path {widget ""}} {
118    # if this is a query operation, then look for the path
119    if {"" == $widget} {
120        if {[info exists _path2widget($path)]} {
121            return $_path2widget($path)
122        }
123        return ""
124    }
125
126    # otherwise, associate the path with the given widget
127    if {[info exists _path2widget($path)]} {
128        error "$path already associated with widget $_path2widget($path)"
129    }
130    set _path2widget($path) $widget
131}
132
133# ----------------------------------------------------------------------
134# USAGE: changed <path>
135#
136# Invoked automatically by the various widgets associated with this
137# editor whenever their value changes.  If this tool has a -analyzer,
138# then it is notified that input has changed, so it can reset itself
139# for a new analysis.
140# ----------------------------------------------------------------------
141itcl::body Rappture::DeviceEditor::changed {path} {
142    if {"" != $_owner} {
143        $_owner changed $path
144    }
145}
146
147# ----------------------------------------------------------------------
148# USAGE: sync
149#
150# Used by descendents such as a Controls panel to register the
151# various controls associated with this page.  That way, this Tool
152# knows what widgets to look at when syncing itself to the underlying
153# XML data.
154# ----------------------------------------------------------------------
155itcl::body Rappture::DeviceEditor::sync {} {
156    foreach path [array names _path2widget] {
157        $_xmlobj put $path.current [$_path2widget($path) value]
158    }
159}
160
161# ----------------------------------------------------------------------
162# USAGE: tool
163#
164# Clients use this to figure out which tool is associated with
165# this object.  Returns the tool containing this editor.
166# ----------------------------------------------------------------------
167itcl::body Rappture::Tool::tool {} {
168    return [$_owner tool]
169}
170
171# ----------------------------------------------------------------------
172# USAGE: _redraw
173#
174# Used internally to load new device data into the appropriate
175# editor.  If the editor needs to be created, it is created and
176# activated within this widget.  Then, the data is loaded into
177# the editor.
178# ----------------------------------------------------------------------
179itcl::body Rappture::DeviceEditor::_redraw {} {
180    switch -- [_type $_xmlobj] {
181        molecule {
182            if {[catch {$itk_component(editors) page molecule} p]} {
183                set p [$itk_component(editors) insert end molecule]
184                Rappture::MoleculeViewer $p.mol $this
185                pack $p.mol -expand yes -fill both
186            }
187            $p.mol configure -device $_xmlobj
188            $itk_component(editors) current molecule
189        }
190        device1D {
191            if {[catch {$itk_component(editors) page device1D} p]} {
192                set p [$itk_component(editors) insert end device1D]
193                Rappture::DeviceViewer1D $p.dev $this
194                pack $p.dev -expand yes -fill both
195            }
196            $p.dev configure -device $_xmlobj
197            $itk_component(editors) current device1D
198        }
199    }
200}
201
202# ----------------------------------------------------------------------
203# USAGE: _type <xmlobj>
204#
205# Used internally to determine the type of the device data stored
206# within the <xmlobj>.  Returns a name such as "molecule" or
207# "device1D" indicating the type of editor that should be used to
208# display the data.
209# ----------------------------------------------------------------------
210itcl::body Rappture::DeviceEditor::_type {xmlobj} {
211    if {$xmlobj == ""} {
212        return ""
213    }
214    if {[llength [$xmlobj children -type molecule components]] > 0} {
215        return "molecule"
216    }
217    return "device1D"
218}
Note: See TracBrowser for help on using the repository browser.