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

Last change on this file since 115 was 115, checked in by mmc, 19 years ago

Updated all copyright notices.

File size: 7.7 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.sashCursor sb_v_double_arrow
19
20itcl::class Rappture::Panes {
21    inherit itk::Widget
22
23    itk_option define -sashcursor sashCursor SashCursor ""
24
25    constructor {args} { # defined below }
26
27    public method insert {pos args}
28    public method pane {pos}
29    public method fraction {pos {newval ""}}
30
31    protected method _grab {pane X Y}
32    protected method _drag {pane X Y}
33    protected method _drop {pane X Y}
34    protected method _fixLayout {args}
35
36    private variable _dispatcher ""  ;# dispatcher for !events
37    private variable _panes ""       ;# list of pane frames
38    private variable _counter 0      ;# counter for auto-generated names
39    private variable _frac 1.0       ;# list of fractions
40}
41
42itk::usual Panes {
43    keep -background -cursor
44}
45
46# ----------------------------------------------------------------------
47# CONSTRUCTOR
48# ----------------------------------------------------------------------
49itcl::body Rappture::Panes::constructor {args} {
50    itk_option add hull.width hull.height
51
52    # create a dispatcher for events
53    Rappture::dispatcher _dispatcher
54    $_dispatcher register !layout
55    $_dispatcher dispatch $this !layout [itcl::code $this _fixLayout]
56
57    # fix the layout whenever the window size changes
58    bind Panes <Configure> [itcl::code %W _fixLayout]
59
60    set pname "pane[incr _counter]"
61    itk_component add $pname {
62        frame $itk_interior.$pname
63    }
64
65    lappend _panes $pname
66
67    eval itk_initialize $args
68
69    # make sure we fix up the layout at some point
70    $_dispatcher event -idle !layout
71}
72
73# ----------------------------------------------------------------------
74# USAGE: insert <pos> ?-fraction f?
75#
76# Adds a new page to this widget at the given position <pos>.
77# ----------------------------------------------------------------------
78itcl::body Rappture::Panes::insert {pos args} {
79    Rappture::getopts args params {
80        value -fraction 0.5
81    }
82    if {[llength $args] > 0} {
83        error "wrong # args: should be \"insert pos ?-fraction f?\""
84    }
85
86    set pname "pane[incr _counter]"
87    set sash "${pname}sash"
88    itk_component add $sash {
89        frame $itk_interior.$sash
90    } {
91        usual
92        rename -cursor -sashcursor sashCursor SashCursor
93    }
94
95    itk_component add ${sash}ridge {
96        frame $itk_component($sash).ridge \
97            -height 2 -borderwidth 1 -relief sunken
98    } {
99        usual
100        rename -cursor -sashcursor sashCursor SashCursor
101    }
102    pack $itk_component(${sash}ridge) -fill x -pady 4
103
104    foreach comp [list $sash ${sash}ridge] {
105        bind $itk_component($comp) <ButtonPress-1> \
106            [itcl::code $this _grab $pname %X %Y]
107        bind $itk_component($comp) <B1-Motion> \
108            [itcl::code $this _drag $pname %X %Y]
109        bind $itk_component($comp) <ButtonRelease-1> \
110            [itcl::code $this _drop $pname %X %Y]
111    }
112
113
114    itk_component add $pname {
115        frame $itk_interior.$pname
116    }
117    lappend _panes $pname
118
119    # fix the fractional sizes
120    set f $params(-fraction)
121    set _frac [list [expr {1-$f}] $f]
122
123    # make sure we fix up the layout at some point
124    $_dispatcher event -idle !layout
125
126    return $itk_component($pname)
127}
128
129# ----------------------------------------------------------------------
130# USAGE: pane <pos>
131#
132# Returns the frame representing the pane at position <pos>.
133# ----------------------------------------------------------------------
134itcl::body Rappture::Panes::pane {pos} {
135    set pname [lindex $_panes $pos]
136    if {[info exists itk_component($pname)]} {
137        return $itk_component($pname)
138    }
139    return ""
140}
141
142# ----------------------------------------------------------------------
143# USAGE: fraction <pos> ?<newval>?
144#
145# Clients use this to get/set the fraction of real estate associated
146# with the pane at position <pos>.
147# ----------------------------------------------------------------------
148itcl::body Rappture::Panes::fraction {pos {newval ""}} {
149    if {"" == $newval} {
150        return [lindex $_frac $pos]
151    }
152    if {![string is double $newval]} {
153        error "bad value \"$newval\": should be fraction 0-1"
154    }
155    if {$pos == "end" || ($pos >= 0 && $pos < [llength $_frac])} {
156        # if there are other panes, adjust their size according to this
157        if {[llength $_frac] > 1} {
158            set oldval [lindex $_frac $pos]
159            set delta [expr {double($oldval-$newval)/([llength $_frac]-1)}]
160            for {set i 0} {$i < [llength $_frac]} {incr i} {
161                set v [lindex $_frac $i]
162                set _frac [lreplace $_frac $i $i [expr {$v+$delta}]]
163            }
164        }
165        set _frac [lreplace $_frac $pos $pos $newval]
166        $_dispatcher event -idle !layout
167    } else {
168        error "bad index \"$pos\": out of range"
169    }
170}
171
172# ----------------------------------------------------------------------
173# USAGE: _grab <pane> <X> <Y>
174#
175# Invoked automatically when the user clicks on a sash, to initiate
176# movement.
177# ----------------------------------------------------------------------
178itcl::body Rappture::Panes::_grab {pname X Y} {
179}
180
181# ----------------------------------------------------------------------
182# USAGE: _drag <pane> <X> <Y>
183#
184# Invoked automatically as the user drags a sash, to resize the panes.
185# ----------------------------------------------------------------------
186itcl::body Rappture::Panes::_drag {pname X Y} {
187    set realY [expr {$Y-[winfo rooty $itk_component(hull)]}]
188    set Ymax  [winfo height $itk_component(hull)]
189    set frac [expr double($realY)/$Ymax]
190    if {$frac < 0.05} {
191        set frac 0.05
192    }
193    if {$frac > 0.95} {
194        set frac 0.95
195    }
196
197    set _frac [list $frac [expr {1-$frac}]]
198    _fixLayout
199
200    return $frac
201}
202
203# ----------------------------------------------------------------------
204# USAGE: _drop <pane> <X> <Y>
205#
206# Invoked automatically as the user drops a sash, to resize the panes.
207# ----------------------------------------------------------------------
208itcl::body Rappture::Panes::_drop {pname X Y} {
209    set frac [_drag $pname $X $Y]
210}
211
212# ----------------------------------------------------------------------
213# USAGE: _fixLayout ?<eventArgs>...?
214#
215# Used internally to update the layout of panes whenever a new pane
216# is added or a sash is moved.
217# ----------------------------------------------------------------------
218itcl::body Rappture::Panes::_fixLayout {args} {
219    set h [winfo height $itk_component(hull)]
220    foreach p [lrange $_panes 1 end] {
221        set h [expr {$h - [winfo height $itk_component(${p}sash)]}]
222    }
223
224    set y 0
225    foreach p $_panes f $_frac {
226        set sash ${p}sash
227        if {[info exists itk_component($sash)]} {
228            set sh [winfo reqheight $itk_component($sash)]
229            place $itk_component($sash) -y $y -relx 0.5 -anchor n \
230                -relwidth 1.0 -height $sh
231            set y [expr {$y + $sh}]
232        }
233
234        set ph [expr {$h*$f}]
235        place $itk_component($p) -y $y -relx 0.5 -anchor n \
236            -relwidth 1.0 -height $ph
237        set y [expr {$y + $ph}]
238    }
239}
Note: See TracBrowser for help on using the repository browser.