source: branches/blt4/gui/scripts/drawing.tcl @ 1923

Last change on this file since 1923 was 1923, checked in by gah, 14 years ago
File size: 7.9 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: drawing - 2D drawing of data
3# ======================================================================
4#  AUTHOR:  Michael McLennan, Purdue University
5#  Copyright (c) 2004-2007  Purdue Research Foundation
6#
7#  See the file "license.terms" for information on usage and
8#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9# ======================================================================
10package require Itk
11
12option add *Drawing.width 4i widgetDefault
13option add *Drawing.height 3i widgetDefault
14
15itcl::class Rappture::Drawing {
16    inherit itk::Widget
17
18#    constructor {owner path args} {
19#        Rappture::ControlOwner::constructor $owner
20#    } { # defined below }
21    constructor {owner path args} { # defined below }
22private variable _xmlobj ""
23private variable _owner ""
24private variable _path ""
25
26    public method value {args}
27    public method hilite {elem state}
28    public method activate {elem x y}
29
30    protected method _buildPopup {elem}
31
32    private variable _elem2popup  ;# maps drawing elem => popup of controls
33}
34
35itk::usual Drawing {
36    keep -cursor -background
37}
38
39# ----------------------------------------------------------------------
40# CONSTRUCTOR
41# ----------------------------------------------------------------------
42itcl::body Rappture::Drawing::constructor {owner path args} {
43    set _owner $owner
44    set _path $path
45
46    itk_component add canvas {
47        canvas $itk_interior.canv
48    } {
49        usual
50        keep -width -height
51    }
52    pack $itk_component(canvas) -expand yes -fill both
53
54    eval itk_initialize $args
55}
56
57# ----------------------------------------------------------------------
58# USAGE: value ?-check? ?<newval>?
59#
60# Clients use this to query/set the value for this widget.  With
61# no args, it returns the current value for the widget.  If the
62# <newval> is specified, it sets the value of the widget and
63# sends a <<Value>> event.  If the -check flag is included, the
64# new value is not actually applied, but just checked for correctness.
65# ----------------------------------------------------------------------
66itcl::body Rappture::Drawing::value {args} {
67    set onlycheck 0
68    set i [lsearch -exact $args -check]
69    if {$i >= 0} {
70        set onlycheck 1
71        set args [lreplace $args $i $i]
72    }
73
74    if {[llength $args] == 0} {
75        return $_xmlobj
76    } elseif {[llength $args] > 1} {
77        error "wrong # args: should be \"value ?-check? ?newval?\""
78    }
79
80    if {$onlycheck} {
81        # someday we may add validation...
82        return
83    }
84
85    set c $itk_component(canvas)
86    $c delete all
87    foreach elem [array names _elem2popup] {
88        destroy $_elem2popup($elem)
89    }
90    catch {unset $elem}
91    set _xmlobj [lindex $args 0]
92
93    if {"" != $_xmlobj} {
94        foreach elem [$_xmlobj children] {
95            switch -glob -- $elem {
96                about* {
97                    continue
98                }
99                rectangle* {
100                    set xy0 [$_xmlobj get $elem.xya]
101                    set xy1 [$_xmlobj get $elem.xyb]
102                    set fill [$_xmlobj get $elem.fill]
103                    set outl [$_xmlobj get $elem.outl]
104                    set wdth [$_xmlobj get $elem.width]
105                    if {"" != $wdth && $wdth > 0 && $outl == ""} {
106                        set outl black
107                    }
108                    if {"" == $fill && "" == $outl} {
109                        _buildPopup $elem
110
111                        # this part gets highlighted
112                        eval $c create rect $xy0 $xy1 [list -outline "" -fill "" -tags $elem]
113                        # this part is the sensor that detects events
114                        set id [eval $c create rect $xy0 $xy1 [list -outline "" -fill ""]]
115                        $c bind $id <Enter> [itcl::code $this hilite $elem on]
116                        $c bind $id <Leave> [itcl::code $this hilite $elem off]
117                        $c bind $id <ButtonPress> [itcl::code $this activate $elem %X %Y]
118                    } else {
119                        if {"" == $fill} { set fill "{}" }
120                        if {"" == $outl} { set outl "{}" }
121                        eval $c create rect $xy0 $xy1 -width $wdth -outline $outl -fill $fill
122                    }
123                }
124                oval* {
125                    set xy0 [$_xmlobj get $elem.xya]
126                    set xy1 [$_xmlobj get $elem.xyb]
127                    set fill [$_xmlobj get $elem.fill]
128                    set outl [$_xmlobj get $elem.outl]
129                    set wdth [$_xmlobj get $elem.width]
130                    if {"" != $wdth && $wdth > 0 && $outl == ""} {
131                        set outl black
132                    }
133                    if {"" == $fill && "" == $outl} {
134                    } else {
135                        if {"" == $fill} { set fill "{}" }
136                        if {"" == $outl} { set outl "{}" }
137                    }
138                    eval $c create oval $xy0 $xy1 -width $wdth -outline $outl -fill $fill
139                }
140                polygon* {
141                    set xy [$_xmlobj get $elem.xy]
142                    regsub -all "\n" $xy " " xy
143                    set smth [$_xmlobj get $elem.smooth]
144                    set fill [$_xmlobj get $elem.fill]
145                    set outl [$_xmlobj get $elem.outl]
146                    set wdth [$_xmlobj get $elem.width]
147                    if {"" != $wdth && $wdth > 0 && $outl == ""} {
148                        set outl black
149                    }
150                    if {"" == $fill && "" == $outl} {
151                    } else {
152                        if {"" == $fill} { set fill "{}" }
153                        if {"" == $outl} { set outl "{}" }
154                    }
155                    eval $c create polygon $xy -width $wdth -outline $outl -fill $fill -smooth $smth
156                }
157                text* {
158                    set xy [$_xmlobj get $elem.xy]
159                    set txt [$_xmlobj get $elem.text]
160                    eval $c create text $xy -text $txt
161                }
162            }
163        }
164    }
165    return $_xmlobj
166}
167
168# ----------------------------------------------------------------------
169# USAGE: hilite <elem> <state>
170#
171# Used internally to highlight parts of the drawing when the mouse
172# passes over it.
173# ----------------------------------------------------------------------
174itcl::body Rappture::Drawing::hilite {elem state} {
175    if {$state} {
176        $itk_component(canvas) itemconfigure $elem -outline red -width 2
177    } else {
178        $itk_component(canvas) itemconfigure $elem -width 0
179    }
180}
181
182# ----------------------------------------------------------------------
183# USAGE: activate <elem> <x> <y>
184#
185# Pops up the controls associated with a drawing element.
186# ----------------------------------------------------------------------
187itcl::body Rappture::Drawing::activate {elem x y} {
188    if {[info exists _elem2popup($elem)]} {
189        after 10 [list $_elem2popup($elem) activate @$x,$y above]
190    }
191}
192
193# ----------------------------------------------------------------------
194# USAGE: _buildPopup <elem>
195#
196# Pops up the controls associated with a drawing element.
197# ----------------------------------------------------------------------
198itcl::body Rappture::Drawing::_buildPopup {elem} {
199    if {![info exists _elem2popup($elem)]} {
200        set n 0
201        while {1} {
202            set popup $itk_component(canvas).popup[incr n]
203            if {![winfo exists $popup]} {
204                break
205            }
206        }
207        Rappture::Balloon $popup -title [$_xmlobj get $elem.parameters.about.label]
208        set inner [$popup component inner]
209        Rappture::Controls $inner.cntls $_owner
210        pack $inner.cntls -expand yes -fill both
211        foreach child [$_xmlobj children $elem.parameters] {
212            if {[string match about* $child]} {
213                continue
214            }
215            $inner.cntls insert end $_path.$elem.parameters.$child
216        }
217
218        set _elem2popup($elem) $popup
219    }
220}
Note: See TracBrowser for help on using the repository browser.