summaryrefslogtreecommitdiff
path: root/iwidgets/generic/panedwindow.itk
diff options
context:
space:
mode:
Diffstat (limited to 'iwidgets/generic/panedwindow.itk')
-rw-r--r--iwidgets/generic/panedwindow.itk942
1 files changed, 942 insertions, 0 deletions
diff --git a/iwidgets/generic/panedwindow.itk b/iwidgets/generic/panedwindow.itk
new file mode 100644
index 00000000000..180ead43a24
--- /dev/null
+++ b/iwidgets/generic/panedwindow.itk
@@ -0,0 +1,942 @@
+#
+# Panedwindow
+# ----------------------------------------------------------------------
+# Implements a multiple paned window widget capable of orienting the panes
+# either vertically or horizontally. Each pane is itself a frame acting
+# as a child site for other widgets. The border separating each pane
+# contains a sash which allows user positioning of the panes relative to
+# one another.
+#
+# ----------------------------------------------------------------------
+# AUTHOR: Mark L. Ulferts EMAIL: mulferts@austin.dsccc.com
+#
+# @(#) $Id$
+# ----------------------------------------------------------------------
+# Copyright (c) 1995 DSC Technologies Corporation
+# ======================================================================
+# Permission to use, copy, modify, distribute and license this software
+# and its documentation for any purpose, and without fee or written
+# agreement with DSC, is hereby granted, provided that the above copyright
+# notice appears in all copies and that both the copyright notice and
+# warranty disclaimer below appear in supporting documentation, and that
+# the names of DSC Technologies Corporation or DSC Communications
+# Corporation not be used in advertising or publicity pertaining to the
+# software without specific, written prior permission.
+#
+# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
+# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
+# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
+# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+# ======================================================================
+
+#
+# Usual options.
+#
+itk::usual Panedwindow {
+ keep -background -cursor -sashcursor
+}
+
+# ------------------------------------------------------------------
+# PANEDWINDOW
+# ------------------------------------------------------------------
+itcl::class iwidgets::Panedwindow {
+ inherit itk::Widget
+
+ constructor {args} {}
+
+ itk_option define -orient orient Orient horizontal
+ itk_option define -sashborderwidth sashBorderWidth SashBorderWidth 2
+ itk_option define -sashcursor sashCursor SashCursor crosshair
+ itk_option define -sashwidth sashWidth SashWidth 10
+ itk_option define -sashheight sashHeight SashHeight 10
+ itk_option define -thickness thickness Thickness 3
+ itk_option define -sashindent sashIndent SashIndent -10
+ itk_option define -showhandle showHandle ShowHandle 1
+
+ public method index {index}
+ public method childsite {args}
+ public method fraction {args}
+ public method add {tag args}
+ public method insert {index tag args}
+ public method delete {index}
+ public method hide {index}
+ public method show {index}
+ public method paneconfigure {index args}
+ public method reset {}
+
+ protected method _pwConfigureEventHandler {width height}
+ protected method _startGrip {where num}
+ protected method _endGrip {where num}
+ protected method _configGrip {where num}
+ protected method _handleGrip {where num}
+ protected method _moveSash {where num}
+
+ private method _setFracArray {}
+ private method _setActivePanes {}
+ private method _calcFraction {where num}
+ private method _makeSashes {}
+ private method _placeSash {i}
+ private method _placePanes {{start 0} {end end}}
+
+ private variable _initialized 0 ;# Denotes initialized state.
+ private variable _panes {} ;# List of panes.
+ private variable _activePanes {} ;# List of active panes.
+ private variable _sashes {} ;# List of sashes.
+ private variable _separators {} ;# List of separators.
+ private variable _frac ;# Array of fraction percentages.
+ private variable _lowerlimit ;# Margin distance above/left of sash.
+ private variable _upperlimit ;# Margin distance below/right of sash.
+ private variable _dimension ;# Width/Height at start of drag.
+ private variable _sashloc ;# Array of dist of sash from above/left.
+ private variable _pixels ;# Array of dist of sash from above/left.
+ private variable _minheight ;# Array of min heights for panes.
+ private variable _minsashmoved ;# Lowest sash moved during dragging.
+ private variable _maxsashmoved ;# Highest sash moved during dragging.
+ private variable _dragging 0 ;# Boolean for dragging enabled.
+ private variable _movecount 0 ;# Kludge counter to get sashes to
+ ;# display without calling update
+ ;# idletasks too often.
+ private variable _width 0 ;# hull's width.
+ private variable _height 0 ;# hull's height.
+ private variable _unique -1 ;# Unique number for pane names.
+
+ private variable _relief ;# relief for -showhandle
+}
+
+#
+# Provide a lowercased access method for the Panedwindow class.
+#
+proc ::iwidgets::panedwindow {pathName args} {
+ uplevel ::iwidgets::Panedwindow $pathName $args
+}
+
+#
+# Use option database to override default resources of base classes.
+#
+option add *Panedwindow.width 10 widgetDefault
+option add *Panedwindow.height 10 widgetDefault
+
+# ------------------------------------------------------------------
+# CONSTRUCTOR
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::constructor {args} {
+ itk_option add hull.width hull.height
+
+ pack propagate $itk_component(hull) no
+
+ #
+ # Add binding for the configure event.
+ #
+ bind pw-config-$this <Configure> [itcl::code $this _pwConfigureEventHandler %w %h]
+ bindtags $itk_component(hull) \
+ [linsert [bindtags $itk_component(hull)] 0 pw-config-$this]
+
+ array set _relief {0 sunken 1 raised}
+
+ eval itk_initialize $args
+}
+
+# ------------------------------------------------------------------
+# OPTIONS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# OPTION: -orient
+#
+# Specifies the orientation of the sashes. Once the paned window
+# has been mapped, set the sash bindings and place the panes.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::orient {
+ if {$_initialized} {
+ switch $itk_option(-orient) {
+ vertical {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ bind $itk_component(sash$i) <Button-1> \
+ [itcl::code $this _startGrip %x $i]
+ bind $itk_component(sash$i) <B1-Motion> \
+ [itcl::code $this _handleGrip %x $i]
+ bind $itk_component(sash$i) <B1-ButtonRelease-1> \
+ [itcl::code $this _endGrip %x $i]
+ bind $itk_component(sash$i) <Configure> \
+ [itcl::code $this _configGrip %x $i]
+ }
+
+ _setFracArray
+ _makeSashes
+ _placePanes
+ }
+
+ horizontal {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ bind $itk_component(sash$i) <Button-1> \
+ [itcl::code $this _startGrip %y $i]
+ bind $itk_component(sash$i) <B1-Motion> \
+ [itcl::code $this _handleGrip %y $i]
+ bind $itk_component(sash$i) <B1-ButtonRelease-1> \
+ [itcl::code $this _endGrip %y $i]
+ bind $itk_component(sash$i) <Configure> \
+ [itcl::code $this _configGrip %y $i]
+ }
+
+ _setFracArray
+ _makeSashes
+ _placePanes
+ }
+
+ default {
+ error "bad orientation option \"$itk_option(-orient)\":\
+ should be horizontal or vertical"
+ }
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -sashborderwidth
+#
+# Specifies a non-negative value indicating the width of the 3-D
+# border to draw around the outside of the sash.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::sashborderwidth {
+ set pixels [winfo pixels $itk_component(hull) \
+ $itk_option(-sashborderwidth)]
+ set itk_option(-sashborderwidth) $pixels
+
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ $itk_component(sash$i) configure \
+ -borderwidth $itk_option(-sashborderwidth)
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -sashcursor
+#
+# Specifies the type of cursor to be used when over the sash.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::sashcursor {
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ $itk_component(sash$i) configure -cursor $itk_option(-sashcursor)
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -sashwidth
+#
+# Specifies the width of the sash.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::sashwidth {
+ set pixels [winfo pixels $itk_component(hull) \
+ $itk_option(-sashwidth)]
+ set itk_option(-sashwidth) $pixels
+
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ $itk_component(sash$i) configure \
+ -width $itk_option(-sashwidth)
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -sashheight
+#
+# Specifies the height of the sash,
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::sashheight {
+ set pixels [winfo pixels $itk_component(hull) \
+ $itk_option(-sashheight)]
+ set itk_option(-sashheight) $pixels
+
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ $itk_component(sash$i) configure \
+ -height $itk_option(-sashheight)
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -showhandle
+#
+# Specifies whether or not to show the sash handle. If not, then the
+# whole separator becomes the handle. Valid values are 0 or 1.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::showhandle {
+ switch $itk_option(-showhandle) {
+ 0 - 1 {
+ # Update the sashes.
+ _makeSashes
+ _placePanes
+ }
+ default {
+ error "Invalid option for -showhandle: $itk_option(-showhandle).\
+ Must be 1 or 0."
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------
+# OPTION: -thickness
+#
+# Specifies the thickness of the separators. It sets the width and
+# height of the separator to the thickness value and the borderwidth
+# to half the thickness.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::thickness {
+ set pixels [winfo pixels $itk_component(hull) \
+ $itk_option(-thickness)]
+ set itk_option(-thickness) $pixels
+
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ $itk_component(separator$i) configure \
+ -height $itk_option(-thickness)
+ $itk_component(separator$i) configure \
+ -width $itk_option(-thickness)
+ $itk_component(separator$i) configure \
+ -borderwidth [expr {$itk_option(-thickness) / 2}]
+ }
+
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ _placeSash $i
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -sashindent
+#
+# Specifies the placement of the sash along the panes. A positive
+# value causes the sash to be offset from the near (left/top) side
+# of the pane, and a negative value causes the sash to be offset from
+# the far (right/bottom) side. If the offset is greater than the
+# width, then the sash is placed flush against the side.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Panedwindow::sashindent {
+ set pixels [winfo pixels $itk_component(hull) \
+ $itk_option(-sashindent)]
+ set itk_option(-sashindent) $pixels
+
+ if {$_initialized} {
+ for {set i 1} {$i < [llength $_activePanes]} {incr i} {
+ _placeSash $i
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# METHODS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# METHOD: index index
+#
+# Searches the panes in the paned window for the one with the
+# requested tag, numerical index, or keyword "end". Returns the pane's
+# numerical index if found, otherwise error.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::index {index} {
+ if {[llength $_panes] > 0} {
+ if {[regexp {(^[0-9]+$)} $index]} {
+ if {$index < [llength $_panes]} {
+ return $index
+ } else {
+ error "Panedwindow index \"$index\" is out of range"
+ }
+
+ } elseif {$index == "end"} {
+ return [expr {[llength $_panes] - 1}]
+
+ } else {
+ if {[set idx [lsearch $_panes $index]] != -1} {
+ return $idx
+ }
+
+ error "bad Panedwindow index \"$index\": must be number, end,\
+ or pattern"
+ }
+
+ } else {
+ error "Panedwindow \"$itk_component(hull)\" has no panes"
+ }
+}
+
+# ------------------------------------------------------------------
+# METHOD: childsite ?index?
+#
+# Given an index return the specifc childsite path name. Invoked
+# without an index return a list of all the child site panes. The
+# list is ordered from the near side (left/top).
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::childsite {args} {
+ if {! $_initialized} {
+ set _initialized 1
+ reset
+ }
+
+ if {[llength $args] == 0} {
+ set children {}
+
+ foreach pane $_panes {
+ lappend children [$itk_component($pane) childSite]
+ }
+
+ return $children
+
+ } else {
+ set index [index [lindex $args 0]]
+ return [$itk_component([lindex $_panes $index]) childSite]
+ }
+}
+
+# ------------------------------------------------------------------
+# METHOD: fraction percentage percentage ?percentage ...?
+#
+# Sets the visible percentage of the panes. Specifies a list of
+# percentages which are applied to the currently visible panes from
+# the near side (left/top). The number of percentages must be equal
+# to the current number of visible (mapped) panes and add up to 100.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::fraction {args} {
+ #set args [linsert $args 0 $percentage1 $percentage2]
+
+
+ if {[llength $args] == [llength $_activePanes]} {
+ set sum 0
+
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ set sum [expr {$sum + [lindex $args $i]}]
+ }
+
+ if {$sum == 100} {
+ set perc 0.0
+
+ for {set i 0} {$i < [llength $_activePanes]} {incr i} {
+ set _frac($i) $perc
+ set perc [expr {$perc + [expr {[lindex $args $i] / 100.0}]}]
+ }
+
+ set _frac($i) 1.0
+
+ if {[winfo ismapped $itk_component(hull)]} {
+ _placePanes
+ }
+
+ } else {
+ error "bad fraction arguments \"$args\": they should add\
+ up to 100"
+ }
+
+ } elseif {[llength $args] == 0} {
+
+ for {set i 0; set j 1} {$j < [llength $_activePanes]} {incr i; incr j} {
+ lappend _ret [expr {round(($_frac($j) - $_frac($i))*100)}]
+ }
+ lappend _ret [eval expr {100 - ([join $_ret +])}]
+
+ return $_ret
+ } else {
+ error "wrong # args: should be \"$itk_component(hull)\
+ fraction percentage percentage ?percentage ...?\",\
+ where the number of percentages is\
+ [llength $_activePanes] and equal 100
+ or \"$itk_component(hull) fraction\"
+ which will return a list of the current percentages"
+ }
+}
+
+# ------------------------------------------------------------------
+# METHOD: add tag ?option value option value ...?
+#
+# Add a new pane to the paned window to the far (right/bottom) side.
+# The method takes additional options which are passed on to the
+# pane constructor. These include -margin, and -minimum. The path
+# of the pane is returned.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::add {tag args} {
+ #
+ # Create panes.
+ #
+ itk_component add $tag {
+ eval iwidgets::Pane $itk_interior.pane[incr _unique] $args
+ } {
+ keep -background -cursor
+ }
+
+ lappend _panes $tag
+ lappend _activePanes $tag
+
+ reset
+
+ return $itk_component($tag)
+}
+
+# ------------------------------------------------------------------
+# METHOD: insert index tag ?option value option value ...?
+#
+# Insert the specified pane in the paned window just before the one
+# given by index. Any additional options which are passed on to the
+# pane constructor. These include -margin, -minimum. The path of
+# the pane is returned.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::insert {index tag args} {
+ #
+ # Create panes.
+ #
+ itk_component add $tag {
+ eval iwidgets::Pane $itk_interior.pane[incr _unique] $args
+ } {
+ keep -background -cursor
+ }
+
+ set index [index $index]
+ set _panes [linsert $_panes $index $tag]
+ lappend _activePanes $tag
+
+ reset
+
+ return $itk_component($tag)
+}
+
+# ------------------------------------------------------------------
+# METHOD: delete index
+#
+# Delete the specified pane.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::delete {index} {
+ set index [index $index]
+ set tag [lindex $_panes $index]
+
+ destroy $itk_component($tag)
+
+ set _panes [lreplace $_panes $index $index]
+
+ reset
+}
+
+# ------------------------------------------------------------------
+# METHOD: hide index
+#
+# Remove the specified pane from the paned window.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::hide {index} {
+ set index [index $index]
+ set tag [lindex $_panes $index]
+
+ if {[set idx [lsearch -exact $_activePanes $tag]] != -1} {
+ set _activePanes [lreplace $_activePanes $idx $idx]
+ }
+
+ reset
+}
+
+# ------------------------------------------------------------------
+# METHOD: show index
+#
+# Display the specified pane in the paned window.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::show {index} {
+ set index [index $index]
+ set tag [lindex $_panes $index]
+
+ if {[lsearch -exact $_activePanes $tag] == -1} {
+ lappend _activePanes $tag
+ }
+
+ reset
+}
+
+# ------------------------------------------------------------------
+# METHOD: paneconfigure index ?option? ?value option value ...?
+#
+# Configure a specified pane. This method allows configuration of
+# panes from the Panedwindow level. The options may have any of the
+# values accepted by the add method.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::paneconfigure {index args} {
+ set index [index $index]
+ set tag [lindex $_panes $index]
+
+ return [uplevel $itk_component($tag) configure $args]
+}
+
+# ------------------------------------------------------------------
+# METHOD: reset
+#
+# Redisplay the panes based on the default percentages of the panes.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::reset {} {
+ if {$_initialized && [llength $_panes]} {
+ _setActivePanes
+ _setFracArray
+
+ _makeSashes
+ _placePanes
+ }
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _pwConfigureEventHandler
+#
+# Performs operations necessary following a configure event. This
+# includes placing the panes.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_pwConfigureEventHandler {width height} {
+ set _width $width
+ set _height $height
+ if {$_initialized} {
+ _placePanes
+ } else {
+ set _initialized 1
+ reset
+ }
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _startGrip where num
+#
+# Starts the sash drag and drop operation. At the start of the drag
+# operation all the information is known as for the upper and lower
+# limits for sash movement. The calculation is made at this time and
+# stored in protected variables for later access during the drag
+# handling routines.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_startGrip {where num} {
+ if {$itk_option(-orient) == "horizontal"} {
+ set _dimension $_height
+ } else {
+ set _dimension $_width
+ }
+
+ set _minsashmoved $num
+ set _maxsashmoved $num
+ set totMinHeight 0
+ set cnt [llength $_activePanes]
+ set _sashloc(0) 0
+ set _pixels($cnt) [expr {int($_dimension)}]
+ for {set i 0} {$i < $cnt} {incr i} {
+ set _pixels($i) [expr {int($_frac($i) * $_dimension)}]
+ set margaft [$itk_component([lindex $_activePanes $i]) cget -margin]
+ set minaft [$itk_component([lindex $_activePanes $i]) cget -minimum]
+ set _minheight($i) [expr {$minaft + (2 * $margaft)}]
+ incr totMinHeight $_minheight($i)
+ }
+ set _dragging [expr {$_dimension > $totMinHeight}]
+
+ grab $itk_component(sash$num)
+ raise $itk_component(separator$num)
+ raise $itk_component(sash$num)
+
+ $itk_component(sash$num) configure -relief sunken
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _endGrip where num
+#
+# Ends the sash drag and drop operation.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_endGrip {where num} {
+ $itk_component(sash$num) configure -relief $_relief($itk_option(-showhandle))
+ grab release $itk_component(sash$num)
+ if {$_dragging} {
+ _calcFraction [expr {$_sashloc($num) + $where}] $num
+ _placePanes [expr {$_minsashmoved - 1}] $_maxsashmoved
+ set _dragging 0
+ }
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _configGrip where num
+#
+# Configure action for sash.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_configGrip {where num} {
+ set _sashloc($num) $where
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _handleGrip where num
+#
+# Motion action for sash.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_handleGrip {where num} {
+ if {$_dragging} {
+ _moveSash [expr {$where + $_sashloc($num)}] $num
+ incr _movecount
+ if {$_movecount>4} {
+ set _movecount 0
+ update idletasks
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# PROTECTED METHOD: _moveSash where num
+#
+# Move the sash to the absolute pixel location
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_moveSash {where num} {
+ set _minsashmoved [expr {($_minsashmoved<$num)?$_minsashmoved:$num}]
+ set _maxsashmoved [expr {($_maxsashmoved>$num)?$_maxsashmoved:$num}]
+ set oldfrac $_frac($num)
+ _calcFraction $where $num
+ if {$_frac($num)!=$oldfrac} { _placeSash $num }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setFracArray
+#
+# Calculates the percentages for the fraction array which lists the
+# percentages for each pane.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_setFracArray {} {
+ set perc 0.0
+ if {[llength $_activePanes] != 0} {
+ set percIncr [expr {1.0 / [llength $_activePanes]}]
+ }
+
+ for {set i 0} {$i < [llength $_activePanes]} {incr i} {
+ set _frac($i) $perc
+ set perc [expr {$perc + $percIncr}]
+ }
+
+ set _frac($i) 1.0
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setActivePanes
+#
+# Resets the active pane list.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_setActivePanes {} {
+ set _prevActivePanes $_activePanes
+
+ set _activePanes {}
+
+ foreach pane $_panes {
+ if {[lsearch -exact $_prevActivePanes $pane] != -1} {
+ lappend _activePanes $pane
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _calcFraction where num
+#
+# Determines the fraction for the sash. Make sure the fraction does
+# not go past the minimum for the pane on each side of the separator.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_calcFraction {where num} {
+
+ set numi [expr {$num + 1}]
+ set numd [expr {$num - 1}]
+
+ set _lowerlimit [expr {$_pixels($numd) + $_minheight($numd)}]
+ set _upperlimit [expr {$_pixels($numi) - $_minheight($num)}]
+
+ set dir [expr {$where - $_pixels($num)}]
+
+ if {$where < $_lowerlimit && $dir <= 0} {
+ if {$num == 1} {
+ set _pixels($num) $_lowerlimit
+ } {
+ _moveSash [expr {$where - $_minheight($numd)}] $numd
+ set _pixels($num) [expr {$_pixels($numd) + $_minheight($numd)}]
+ }
+ } elseif {$where > $_upperlimit && $dir >= 0} {
+ if {$numi == [llength $_activePanes]} {
+ set _pixels($num) $_upperlimit
+ } {
+ _moveSash [expr {$where + $_minheight($num)}] $numi
+ set _pixels($num) \
+ [expr {$_pixels($numi) - $_minheight($num)}]
+ }
+ } else {
+ set _pixels($num) $where
+ }
+ set _frac($num) [expr $_pixels($num).0 / $_dimension]
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _makeSashes
+#
+# Removes any previous sashes and separators and creates new one.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_makeSashes {} {
+ #
+ # Remove any existing sashes and separators.
+ #
+ foreach sash $_sashes {
+ destroy $itk_component($sash)
+ }
+
+ foreach separator $_separators {
+ destroy $itk_component($separator)
+ }
+
+ set _sashes {}
+ set _separators {}
+
+ #
+ # Create one less separator and sash than the number of panes.
+ #
+ for {set id 1} {$id < [llength $_activePanes]} {incr id} {
+ itk_component add sash$id {
+ frame $itk_interior.sash$id -relief $_relief($itk_option(-showhandle)) \
+ -borderwidth $itk_option(-sashborderwidth) \
+ -cursor $itk_option(-sashcursor) \
+ -width $itk_option(-sashwidth) \
+ -height $itk_option(-sashheight)
+ } {
+ keep -background
+ }
+
+ lappend _sashes sash$id
+
+ switch $itk_option(-orient) {
+ vertical {
+ bind $itk_component(sash$id) <Button-1> \
+ [itcl::code $this _startGrip %x $id]
+ bind $itk_component(sash$id) <B1-Motion> \
+ [itcl::code $this _handleGrip %x $id]
+ bind $itk_component(sash$id) <B1-ButtonRelease-1> \
+ [itcl::code $this _endGrip %x $id]
+ bind $itk_component(sash$id) <Configure> \
+ [itcl::code $this _configGrip %x $id]
+ }
+
+ horizontal {
+ bind $itk_component(sash$id) <Button-1> \
+ [itcl::code $this _startGrip %y $id]
+ bind $itk_component(sash$id) <B1-Motion> \
+ [itcl::code $this _handleGrip %y $id]
+ bind $itk_component(sash$id) <B1-ButtonRelease-1> \
+ [itcl::code $this _endGrip %y $id]
+ bind $itk_component(sash$id) <Configure> \
+ [itcl::code $this _configGrip %y $id]
+ }
+ }
+
+ itk_component add separator$id {
+ frame $itk_interior.separator$id -relief sunken \
+ -height $itk_option(-thickness) \
+ -width $itk_option(-thickness) \
+ -borderwidth [expr {$itk_option(-thickness) / 2}]
+ } {
+ keep -background -cursor
+ }
+
+ lappend _separators separator$id
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _placeSash i
+#
+# Places the position of the sash and separator.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_placeSash {i} {
+ if {$itk_option(-orient) == "horizontal"} {
+ place $itk_component(separator$i) -in $itk_component(hull) \
+ -x 0 -relwidth 1 -rely $_frac($i) -anchor w \
+ -height $itk_option(-thickness)
+
+ if {$itk_option(-sashindent) < 0} {
+ set sashPos [expr {$_width + $itk_option(-sashindent)}]
+ set sashAnchor e
+ } else {
+ set sashPos $itk_option(-sashindent)
+ set sashAnchor w
+ }
+
+ if {$itk_option(-showhandle)} {
+ place $itk_component(sash$i) -in $itk_component(hull) \
+ -x $sashPos -rely $_frac($i) -anchor $sashAnchor
+ } else {
+ place $itk_component(sash$i) -in $itk_component(hull) \
+ -x 0 -relwidth 1 -rely $_frac($i) -anchor w \
+ -height $itk_option(-thickness)
+ }
+
+ } else {
+ place $itk_component(separator$i) -in $itk_component(hull) \
+ -y 0 -relheight 1 -relx $_frac($i) -anchor n \
+ -width $itk_option(-thickness)
+
+ if {$itk_option(-sashindent) < 0} {
+ set sashPos [expr {$_height + $itk_option(-sashindent)}]
+ set sashAnchor s
+ } else {
+ set sashPos $itk_option(-sashindent)
+ set sashAnchor n
+ }
+
+ if {$itk_option(-showhandle)} {
+
+ place $itk_component(sash$i) -in $itk_component(hull) \
+ -y $sashPos -relx $_frac($i) -anchor $sashAnchor
+ } else {
+ place $itk_component(sash$i) -in $itk_component(hull) \
+ -y 0 -relheight 1 -relx $_frac($i) -anchor n \
+ -width $itk_option(-thickness)
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _placePanes
+#
+# Resets the panes of the window following movement of the sash.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Panedwindow::_placePanes {{start 0} {end end}} {
+ if {$end=="end"} { set end [expr {[llength $_activePanes] - 1}] }
+ set _updatePanes [lrange $_activePanes $start $end]
+ if {$_updatePanes == $_activePanes} {
+ set _forgetPanes $_panes
+ } {
+ set _forgetPanes $_updatePanes
+ }
+ foreach pane $_forgetPanes {
+ place forget $itk_component($pane)
+ }
+
+
+ if {$itk_option(-orient) == "horizontal"} {
+ set i $start
+ foreach pane $_updatePanes {
+ place $itk_component($pane) -in $itk_component(hull) \
+ -x 0 -rely $_frac($i) -relwidth 1 \
+ -relheight [expr {$_frac([expr {$i + 1}]) - $_frac($i)}]
+ incr i
+ }
+
+ } else {
+ set i $start
+ foreach pane $_updatePanes {
+ place $itk_component($pane) -in $itk_component(hull) \
+ -y 0 -relx $_frac($i) -relheight 1 \
+ -relwidth [expr {$_frac([expr {$i + 1}]) - $_frac($i)}]
+ incr i
+ }
+
+ }
+
+ for {set i [expr {$start+1}]} {$i <= $end} {incr i} {
+ if {[array names itk_component separator$i] != ""} {
+ _placeSash $i
+ raise $itk_component(separator$i)
+ raise $itk_component(sash$i)
+ }
+ }
+}