source: trunk/gui/scripts/panes.tcl @ 551

Last change on this file since 551 was 428, checked in by mmc, 18 years ago
  • Added <sequence> for playing movie outputs and other sequences of related results.
  • Added <resize> option to <image> elements. This can be used to resize input items to a smaller size, so they don't take up so much real estate on the form.
  • Fixed a bug in right/below cases for popup balloons.
  • Reduced the tooltip delay time to 750ms to interact better with Rick's attention span.
  • Fixed the sash between grips to light up when you touch it, so it's easier to see.
File size: 11.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: Panes - creates a series of adjustable panes
3#
4#  This is a simple paned window with an adjustable sash.
5#  the same quantity, but for various ranges of input values.
6#  It also manages the controls to select and visualize the data.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005  Purdue Research Foundation
10#
11#  See the file "license.terms" for information on usage and
12#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13# ======================================================================
14package require Itk
15
16option add *Panes.width 3i widgetDefault
17option add *Panes.height 3i widgetDefault
18option add *Panes.sashRelief sunken widgetDefault
19option add *Panes.sashWidth 2 widgetDefault
20option add *Panes.sashPadding 4 widgetDefault
21option add *Panes.sashCursor sb_v_double_arrow
22
23itcl::class Rappture::Panes {
24    inherit itk::Widget
25
26    itk_option define -sashcursor sashCursor SashCursor ""
27    itk_option define -sashrelief sashRelief SashRelief ""
28    itk_option define -sashwidth sashWidth SashWidth 0
29    itk_option define -sashpadding sashPadding SashPadding 0
30
31    constructor {args} { # defined below }
32
33    public method insert {pos args}
34    public method pane {pos}
35    public method fraction {pos {newval ""}}
36    public method hilite {state sash}
37
38    protected method _grab {pane X Y}
39    protected method _drag {pane X Y}
40    protected method _drop {pane X Y}
41    protected method _fixLayout {args}
42    protected method _fixSashes {args}
43
44    private variable _dispatcher ""  ;# dispatcher for !events
45    private variable _panes ""       ;# list of pane frames
46    private variable _counter 0      ;# counter for auto-generated names
47    private variable _frac 1.0       ;# list of fractions
48}
49
50itk::usual Panes {
51    keep -background -cursor
52}
53
54# ----------------------------------------------------------------------
55# CONSTRUCTOR
56# ----------------------------------------------------------------------
57itcl::body Rappture::Panes::constructor {args} {
58    itk_option add hull.width hull.height
59
60    # create a dispatcher for events
61    Rappture::dispatcher _dispatcher
62    $_dispatcher register !layout
63    $_dispatcher dispatch $this !layout [itcl::code $this _fixLayout]
64    $_dispatcher register !sashes
65    $_dispatcher dispatch $this !sashes [itcl::code $this _fixSashes]
66
67    # fix the layout whenever the window size changes
68    bind Panes <Configure> [itcl::code %W _fixLayout]
69
70    set pname "pane[incr _counter]"
71    itk_component add $pname {
72        frame $itk_interior.$pname
73    }
74
75    lappend _panes $pname
76
77    eval itk_initialize $args
78
79    # make sure we fix up the layout at some point
80    $_dispatcher event -idle !layout
81}
82
83# ----------------------------------------------------------------------
84# USAGE: insert <pos> ?-fraction f?
85#
86# Adds a new page to this widget at the given position <pos>.
87# ----------------------------------------------------------------------
88itcl::body Rappture::Panes::insert {pos args} {
89    Rappture::getopts args params {
90        value -fraction 0.5
91    }
92    if {[llength $args] > 0} {
93        error "wrong # args: should be \"insert pos ?-fraction f?\""
94    }
95
96    set pname "pane[incr _counter]"
97    set sash "${pname}sash"
98    itk_component add $sash {
99        frame $itk_interior.$sash
100    } {
101        usual
102        rename -cursor -sashcursor sashCursor SashCursor
103    }
104    bind $itk_component($sash) <Enter> [itcl::code $this hilite on $sash]
105    bind $itk_component($sash) <Leave> [itcl::code $this hilite off $sash]
106
107    itk_component add ${sash}ridge {
108        frame $itk_component($sash).ridge
109    } {
110        usual
111        rename -cursor -sashcursor sashCursor SashCursor
112        rename -relief -sashrelief sashRelief SashRelief
113        ignore -borderwidth
114    }
115    pack $itk_component(${sash}ridge) -fill x
116
117    foreach comp [list $sash ${sash}ridge] {
118        bind $itk_component($comp) <ButtonPress-1> \
119            [itcl::code $this _grab $pname %X %Y]
120        bind $itk_component($comp) <B1-Motion> \
121            [itcl::code $this _drag $pname %X %Y]
122        bind $itk_component($comp) <ButtonRelease-1> \
123            [itcl::code $this _drop $pname %X %Y]
124    }
125
126
127    itk_component add $pname {
128        frame $itk_interior.$pname
129    }
130    lappend _panes $pname
131
132    # fix the fractional sizes
133    set f $params(-fraction)
134    set _frac [list [expr {1-$f}] $f]
135
136    # fix sash characteristics
137    $_dispatcher event -idle !sashes
138
139    # make sure we fix up the layout at some point
140    $_dispatcher event -idle !layout
141
142    return $itk_component($pname)
143}
144
145# ----------------------------------------------------------------------
146# USAGE: pane <pos>
147#
148# Returns the frame representing the pane at position <pos>.
149# ----------------------------------------------------------------------
150itcl::body Rappture::Panes::pane {pos} {
151    set pname [lindex $_panes $pos]
152    if {[info exists itk_component($pname)]} {
153        return $itk_component($pname)
154    }
155    return ""
156}
157
158# ----------------------------------------------------------------------
159# USAGE: fraction <pos> ?<newval>?
160#
161# Clients use this to get/set the fraction of real estate associated
162# with the pane at position <pos>.
163# ----------------------------------------------------------------------
164itcl::body Rappture::Panes::fraction {pos {newval ""}} {
165    if {"" == $newval} {
166        return [lindex $_frac $pos]
167    }
168    if {![string is double $newval]} {
169        error "bad value \"$newval\": should be fraction 0-1"
170    }
171    if {$pos == "end" || ($pos >= 0 && $pos < [llength $_frac])} {
172        # if there are other panes, adjust their size according to this
173        if {[llength $_frac] > 1} {
174            set oldval [lindex $_frac $pos]
175            set delta [expr {double($oldval-$newval)/([llength $_frac]-1)}]
176            for {set i 0} {$i < [llength $_frac]} {incr i} {
177                set v [lindex $_frac $i]
178                set _frac [lreplace $_frac $i $i [expr {$v+$delta}]]
179            }
180        }
181        set _frac [lreplace $_frac $pos $pos $newval]
182        $_dispatcher event -idle !layout
183    } else {
184        error "bad index \"$pos\": out of range"
185    }
186}
187
188# ----------------------------------------------------------------------
189# USAGE: hilite <state> <sash>
190#
191# Invoked automatically whenever the user touches a sash.  Highlights
192# the sash by changing its size or relief.
193# ----------------------------------------------------------------------
194itcl::body Rappture::Panes::hilite {state sash} {
195    switch -- $itk_option(-sashrelief) {
196      sunken {
197        if {$state} {
198            $itk_component(${sash}ridge) configure -relief raised
199        } else {
200            $itk_component(${sash}ridge) configure -relief sunken
201        }
202      }
203      raised {
204        if {$state} {
205            $itk_component(${sash}ridge) configure -relief sunken
206        } else {
207            $itk_component(${sash}ridge) configure -relief raised
208        }
209      }
210      solid {
211        if {$state} {
212            $itk_component($sash) configure -background black
213        } else {
214            $itk_component($sash) configure \
215                -background $itk_option(-background)
216        }
217      }
218    }
219}
220
221# ----------------------------------------------------------------------
222# USAGE: _grab <pane> <X> <Y>
223#
224# Invoked automatically when the user clicks on a sash, to initiate
225# movement.
226# ----------------------------------------------------------------------
227itcl::body Rappture::Panes::_grab {pname X Y} {
228}
229
230# ----------------------------------------------------------------------
231# USAGE: _drag <pane> <X> <Y>
232#
233# Invoked automatically as the user drags a sash, to resize the panes.
234# ----------------------------------------------------------------------
235itcl::body Rappture::Panes::_drag {pname X Y} {
236    set realY [expr {$Y-[winfo rooty $itk_component(hull)]}]
237    set Ymax  [winfo height $itk_component(hull)]
238    set frac [expr double($realY)/$Ymax]
239    if {$frac < 0.05} {
240        set frac 0.05
241    }
242    if {$frac > 0.95} {
243        set frac 0.95
244    }
245
246    set _frac [list $frac [expr {1-$frac}]]
247    _fixLayout
248
249    return $frac
250}
251
252# ----------------------------------------------------------------------
253# USAGE: _drop <pane> <X> <Y>
254#
255# Invoked automatically as the user drops a sash, to resize the panes.
256# ----------------------------------------------------------------------
257itcl::body Rappture::Panes::_drop {pname X Y} {
258    set frac [_drag $pname $X $Y]
259}
260
261# ----------------------------------------------------------------------
262# USAGE: _fixLayout ?<eventArgs>...?
263#
264# Used internally to update the layout of panes whenever a new pane
265# is added or a sash is moved.
266# ----------------------------------------------------------------------
267itcl::body Rappture::Panes::_fixLayout {args} {
268    set h [winfo height $itk_component(hull)]
269    foreach p [lrange $_panes 1 end] {
270        set h [expr {$h - [winfo height $itk_component(${p}sash)]}]
271    }
272
273    set y 0
274    foreach p $_panes f $_frac {
275        set sash ${p}sash
276        if {[info exists itk_component($sash)]} {
277            set sh [winfo reqheight $itk_component($sash)]
278            place $itk_component($sash) -y $y -relx 0.5 -anchor n \
279                -relwidth 1.0 -height $sh
280            set y [expr {$y + $sh}]
281        }
282
283        set ph [expr {$h*$f}]
284        place $itk_component($p) -y $y -relx 0.5 -anchor n \
285            -relwidth 1.0 -height $ph
286        set y [expr {$y + $ph}]
287    }
288}
289
290# ----------------------------------------------------------------------
291# USAGE: _fixSashes
292#
293# Used internally to fix the appearance of sashes whenever a new
294# sash appears or the controlling configuration options change.
295# ----------------------------------------------------------------------
296itcl::body Rappture::Panes::_fixSashes {args} {
297    set ht [winfo pixels $itk_component(hull) $itk_option(-sashwidth)]
298    set bd [expr {$ht/2}]
299    foreach pane $_panes {
300        set sash "${pane}sashridge"
301        if {[info exists itk_component($sash)]} {
302            $itk_component($sash) configure -height $ht -borderwidth $bd
303            if {$itk_option(-sashrelief) == "solid"} {
304                $itk_component($sash) configure -background black
305            } else {
306                $itk_component($sash) configure \
307                    -background $itk_option(-background)
308            }
309            pack $itk_component($sash) -pady $itk_option(-sashpadding)
310        }
311    }
312}
313
314# ----------------------------------------------------------------------
315# CONFIGURATION OPTION: -sashrelief
316# ----------------------------------------------------------------------
317itcl::configbody Rappture::Panes::sashrelief {
318    $_dispatcher event -idle !sashes
319}
320
321# ----------------------------------------------------------------------
322# CONFIGURATION OPTION: -sashwidth
323# ----------------------------------------------------------------------
324itcl::configbody Rappture::Panes::sashwidth {
325    $_dispatcher event -idle !sashes
326}
327
328# ----------------------------------------------------------------------
329# CONFIGURATION OPTION: -sashpadding
330# ----------------------------------------------------------------------
331itcl::configbody Rappture::Panes::sashpadding {
332    $_dispatcher event -idle !sashes
333}
Note: See TracBrowser for help on using the repository browser.