diff options
Diffstat (limited to 'iwidgets/generic/panedwindow.itk')
-rw-r--r-- | iwidgets/generic/panedwindow.itk | 942 |
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) + } + } +} |