blob: 1920d82cba56feeb7f6aa4588d53354f54b3cf56 [file] [log] [blame]
#
# Scrolledwidget
# ----------------------------------------------------------------------
# Implements a general purpose base class for scrolled widgets, by
# creating the necessary horizontal and vertical scrollbars and
# providing protected methods for controlling their display. The
# derived class needs to take advantage of the fact that the grid
# is used and the vertical scrollbar is in row 0, column 2 and the
# horizontal scrollbar in row 2, column 0.
#
# ----------------------------------------------------------------------
# AUTHOR: Mark Ulferts mulferts@austin.dsccc.com
#
# @(#) $Id: scrolledwidget.itk,v 1.2 2001/08/07 19:56:48 smithc Exp $
# ----------------------------------------------------------------------
# Copyright (c) 1997 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 Scrolledwidget {
keep -background -borderwidth -cursor -highlightcolor -highlightthickness
keep -activebackground -activerelief -jump -troughcolor
keep -labelfont -foreground
}
# ------------------------------------------------------------------
# SCROLLEDWIDGET
# ------------------------------------------------------------------
itcl::class iwidgets::Scrolledwidget {
inherit iwidgets::Labeledwidget
constructor {args} {}
destructor {}
itk_option define -sbwidth sbWidth Width 15
itk_option define -scrollmargin scrollMargin ScrollMargin 3
itk_option define -vscrollmode vscrollMode VScrollMode static
itk_option define -hscrollmode hscrollMode HScrollMode static
itk_option define -width width Width 30
itk_option define -height height Height 30
protected method _scrollWidget {wid first last}
protected method _vertScrollbarDisplay {mode}
protected method _horizScrollbarDisplay {mode}
protected method _configureEvent {}
protected variable _vmode off ;# Vertical scroll mode
protected variable _hmode off ;# Vertical scroll mode
protected variable _recheckHoriz 1 ;# Flag to check need for
;# horizontal scrollbar
protected variable _recheckVert 1 ;# Flag to check need for
;# vertical scrollbar
protected variable _interior {}
}
#
# Provide a lowercased access method for the Scrolledwidget class.
#
proc ::iwidgets::scrolledwidget {pathName args} {
uplevel ::iwidgets::Scrolledwidget $pathName $args
}
#
# Use option database to override default resources of base classes.
#
option add *Scrolledwidget.labelPos n widgetDefault
# ------------------------------------------------------------------
# CONSTRUCTOR
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::constructor {args} {
#
# Turn off the borderwidth on the hull and save off the
# interior for later use.
#
component hull configure -borderwidth 0
set _interior $itk_interior
#
# Check if the scrollbars need mapping upon a configure event.
#
bind $_interior <Configure> [itcl::code $this _configureEvent]
#
# Turn off propagation in the containing shell.
#
# Due to a bug in the tk4.2 grid, we have to check the
# propagation before setting it. Setting it to the same
# value it already is will cause it to toggle.
#
if {[grid propagate $_interior]} {
grid propagate $_interior no
}
#
# Create the vertical scroll bar
#
itk_component add vertsb {
scrollbar $itk_interior.vertsb -orient vertical
} {
usual
keep -borderwidth -elementborderwidth -jump -relief
rename -highlightbackground -background background Background
}
#
# Create the horizontal scrollbar
#
itk_component add horizsb {
scrollbar $itk_interior.horizsb -orient horizontal
} {
usual
keep -borderwidth -elementborderwidth -jump -relief
rename -highlightbackground -background background Background
}
#
# Initialize the widget based on the command line options.
#
eval itk_initialize $args
}
# ------------------------------------------------------------------
# DESTURCTOR
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::destructor {} {
}
# ------------------------------------------------------------------
# OPTIONS
# ------------------------------------------------------------------
# ------------------------------------------------------------------
# OPTION: -sbwidth
#
# Set the width of the scrollbars.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::sbwidth {
$itk_component(vertsb) configure -width $itk_option(-sbwidth)
$itk_component(horizsb) configure -width $itk_option(-sbwidth)
}
# ------------------------------------------------------------------
# OPTION: -scrollmargin
#
# Set the distance between the scrollbars and the list box.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::scrollmargin {
set pixels [winfo pixels $_interior $itk_option(-scrollmargin)]
if {$_hmode == "on"} {
grid rowconfigure $_interior 1 -minsize $pixels
}
if {$_vmode == "on"} {
grid columnconfigure $_interior 1 -minsize $pixels
}
}
# ------------------------------------------------------------------
# OPTION: -vscrollmode
#
# Enable/disable display and mode of veritcal scrollbars.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::vscrollmode {
switch $itk_option(-vscrollmode) {
static {
_vertScrollbarDisplay on
}
dynamic -
none {
_vertScrollbarDisplay off
}
default {
error "bad vscrollmode option\
\"$itk_option(-vscrollmode)\": should be\
static, dynamic, or none"
}
}
}
# ------------------------------------------------------------------
# OPTION: -hscrollmode
#
# Enable/disable display and mode of horizontal scrollbars.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::hscrollmode {
switch $itk_option(-hscrollmode) {
static {
_horizScrollbarDisplay on
}
dynamic -
none {
_horizScrollbarDisplay off
}
default {
error "bad hscrollmode option\
\"$itk_option(-hscrollmode)\": should be\
static, dynamic, or none"
}
}
}
# ------------------------------------------------------------------
# OPTION: -width
#
# Specifies the width of the scrolled widget. The value may be
# specified in any of the forms acceptable to Tk_GetPixels.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::width {
$_interior configure -width \
[winfo pixels $_interior $itk_option(-width)]
}
# ------------------------------------------------------------------
# OPTION: -height
#
# Specifies the height of the scrolled widget. The value may be
# specified in any of the forms acceptable to Tk_GetPixels.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Scrolledwidget::height {
$_interior configure -height \
[winfo pixels $_interior $itk_option(-height)]
}
# ------------------------------------------------------------------
# METHODS
# ------------------------------------------------------------------
# ------------------------------------------------------------------
# PROTECTED METHOD: _vertScrollbarDisplay mode
#
# Displays the vertical scrollbar based on the input mode.
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::_vertScrollbarDisplay {mode} {
switch $mode {
on {
set _vmode on
grid columnconfigure $_interior 1 -minsize \
[winfo pixels $_interior $itk_option(-scrollmargin)]
grid $itk_component(vertsb) -row 0 -column 2 -sticky ns
}
off {
set _vmode off
grid columnconfigure $_interior 1 -minsize 0
grid forget $itk_component(vertsb)
}
default {
error "invalid argument \"$mode\": should be on or off"
}
}
}
# ------------------------------------------------------------------
# PROTECTED METHOD: _horizScrollbarDisplay mode
#
# Displays the horizontal scrollbar based on the input mode.
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::_horizScrollbarDisplay {mode} {
switch $mode {
on {
set _hmode on
grid rowconfigure $_interior 1 -minsize \
[winfo pixels $_interior $itk_option(-scrollmargin)]
grid $itk_component(horizsb) -row 2 -column 0 -sticky ew
}
off {
set _hmode off
grid rowconfigure $_interior 1 -minsize 0
grid forget $itk_component(horizsb)
}
default {
error "invalid argument \"$mode\": should be on or off"
}
}
}
# ------------------------------------------------------------------
# PROTECTED METHOD: _scrollWidget wid first last
#
# Performs scrolling and display of scrollbars based on the total
# and maximum frame size as well as the current -vscrollmode and
# -hscrollmode settings. Parameters are automatic scroll parameters.
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::_scrollWidget {wid first last} {
$wid set $first $last
if {$wid == $itk_component(vertsb)} {
if {$itk_option(-vscrollmode) == "dynamic"} {
if {($_recheckVert != 1) && ($_vmode == "on")} {
return
} else {
set _recheckVert 0
}
if {($first == 0) && ($last == 1)} {
if {$_vmode != "off"} {
_vertScrollbarDisplay off
}
} else {
if {$_vmode != "on"} {
_vertScrollbarDisplay on
}
}
}
} elseif {$wid == $itk_component(horizsb)} {
if {$itk_option(-hscrollmode) == "dynamic"} {
if {($_recheckHoriz != 1) && ($_hmode == "on")} {
return
} else {
set _recheckHoriz 0
}
if {($first == 0) && ($last == 1)} {
if {$_hmode != "off"} {
_horizScrollbarDisplay off
}
} else {
if {$_hmode != "on"} {
_horizScrollbarDisplay on
}
}
}
}
}
# ------------------------------------------------------------------
# PROTECTED METHOD: _configureEvent
#
# Resets the recheck flags which determine if we'll try and map
# the scrollbars in dynamic mode.
# ------------------------------------------------------------------
itcl::body iwidgets::Scrolledwidget::_configureEvent {} {
update idletasks
set _recheckVert 1
set _recheckHoriz 1
}