1# 2# Scrolledwidget 3# ---------------------------------------------------------------------- 4# Implements a general purpose base class for scrolled widgets, by 5# creating the necessary horizontal and vertical scrollbars and 6# providing protected methods for controlling their display. The 7# derived class needs to take advantage of the fact that the grid 8# is used and the vertical scrollbar is in row 0, column 2 and the 9# horizontal scrollbar in row 2, column 0. 10# 11# ---------------------------------------------------------------------- 12# AUTHOR: Mark Ulferts mulferts@austin.dsccc.com 13# 14# @(#) $Id: scrolledwidget.itk,v 1.2 2001/08/07 19:56:48 smithc Exp $ 15# ---------------------------------------------------------------------- 16# Copyright (c) 1997 DSC Technologies Corporation 17# ====================================================================== 18# Permission to use, copy, modify, distribute and license this software 19# and its documentation for any purpose, and without fee or written 20# agreement with DSC, is hereby granted, provided that the above copyright 21# notice appears in all copies and that both the copyright notice and 22# warranty disclaimer below appear in supporting documentation, and that 23# the names of DSC Technologies Corporation or DSC Communications 24# Corporation not be used in advertising or publicity pertaining to the 25# software without specific, written prior permission. 26# 27# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 28# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON- 29# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE 30# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 31# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 32# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 33# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 34# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, 35# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 36# SOFTWARE. 37# ====================================================================== 38 39# 40# Usual options. 41# 42itk::usual Scrolledwidget { 43 keep -background -borderwidth -cursor -highlightcolor -highlightthickness 44 keep -activebackground -activerelief -jump -troughcolor 45 keep -labelfont -foreground 46} 47 48# ------------------------------------------------------------------ 49# SCROLLEDWIDGET 50# ------------------------------------------------------------------ 51itcl::class iwidgets::Scrolledwidget { 52 inherit iwidgets::Labeledwidget 53 54 constructor {args} {} 55 destructor {} 56 57 itk_option define -sbwidth sbWidth Width 15 58 itk_option define -scrollmargin scrollMargin ScrollMargin 3 59 itk_option define -vscrollmode vscrollMode VScrollMode static 60 itk_option define -hscrollmode hscrollMode HScrollMode static 61 itk_option define -width width Width 30 62 itk_option define -height height Height 30 63 64 protected method _scrollWidget {wid first last} 65 protected method _vertScrollbarDisplay {mode} 66 protected method _horizScrollbarDisplay {mode} 67 protected method _configureEvent {} 68 69 protected variable _vmode off ;# Vertical scroll mode 70 protected variable _hmode off ;# Vertical scroll mode 71 protected variable _recheckHoriz 1 ;# Flag to check need for 72 ;# horizontal scrollbar 73 protected variable _recheckVert 1 ;# Flag to check need for 74 ;# vertical scrollbar 75 76 protected variable _interior {} 77} 78 79# 80# Provide a lowercased access method for the Scrolledwidget class. 81# 82proc ::iwidgets::scrolledwidget {pathName args} { 83 uplevel ::iwidgets::Scrolledwidget $pathName $args 84} 85 86# 87# Use option database to override default resources of base classes. 88# 89option add *Scrolledwidget.labelPos n widgetDefault 90 91# ------------------------------------------------------------------ 92# CONSTRUCTOR 93# ------------------------------------------------------------------ 94itcl::body iwidgets::Scrolledwidget::constructor {args} { 95 96 # 97 # Turn off the borderwidth on the hull and save off the 98 # interior for later use. 99 # 100 component hull configure -borderwidth 0 101 set _interior $itk_interior 102 103 # 104 # Check if the scrollbars need mapping upon a configure event. 105 # 106 bind $_interior <Configure> [itcl::code $this _configureEvent] 107 108 # 109 # Turn off propagation in the containing shell. 110 # 111 # Due to a bug in the tk4.2 grid, we have to check the 112 # propagation before setting it. Setting it to the same 113 # value it already is will cause it to toggle. 114 # 115 if {[grid propagate $_interior]} { 116 grid propagate $_interior no 117 } 118 119 # 120 # Create the vertical scroll bar 121 # 122 itk_component add vertsb { 123 scrollbar $itk_interior.vertsb -orient vertical 124 } { 125 usual 126 keep -borderwidth -elementborderwidth -jump -relief 127 rename -highlightbackground -background background Background 128 } 129 130 # 131 # Create the horizontal scrollbar 132 # 133 itk_component add horizsb { 134 scrollbar $itk_interior.horizsb -orient horizontal 135 } { 136 usual 137 keep -borderwidth -elementborderwidth -jump -relief 138 rename -highlightbackground -background background Background 139 } 140 141 # 142 # Initialize the widget based on the command line options. 143 # 144 eval itk_initialize $args 145} 146 147# ------------------------------------------------------------------ 148# DESTURCTOR 149# ------------------------------------------------------------------ 150itcl::body iwidgets::Scrolledwidget::destructor {} { 151} 152 153# ------------------------------------------------------------------ 154# OPTIONS 155# ------------------------------------------------------------------ 156 157# ------------------------------------------------------------------ 158# OPTION: -sbwidth 159# 160# Set the width of the scrollbars. 161# ------------------------------------------------------------------ 162itcl::configbody iwidgets::Scrolledwidget::sbwidth { 163 $itk_component(vertsb) configure -width $itk_option(-sbwidth) 164 $itk_component(horizsb) configure -width $itk_option(-sbwidth) 165} 166 167# ------------------------------------------------------------------ 168# OPTION: -scrollmargin 169# 170# Set the distance between the scrollbars and the list box. 171# ------------------------------------------------------------------ 172itcl::configbody iwidgets::Scrolledwidget::scrollmargin { 173 set pixels [winfo pixels $_interior $itk_option(-scrollmargin)] 174 175 if {$_hmode == "on"} { 176 grid rowconfigure $_interior 1 -minsize $pixels 177 } 178 179 if {$_vmode == "on"} { 180 grid columnconfigure $_interior 1 -minsize $pixels 181 } 182} 183 184# ------------------------------------------------------------------ 185# OPTION: -vscrollmode 186# 187# Enable/disable display and mode of veritcal scrollbars. 188# ------------------------------------------------------------------ 189itcl::configbody iwidgets::Scrolledwidget::vscrollmode { 190 switch $itk_option(-vscrollmode) { 191 static { 192 _vertScrollbarDisplay on 193 } 194 195 dynamic - 196 none { 197 _vertScrollbarDisplay off 198 } 199 200 default { 201 error "bad vscrollmode option\ 202 \"$itk_option(-vscrollmode)\": should be\ 203 static, dynamic, or none" 204 } 205 } 206} 207 208# ------------------------------------------------------------------ 209# OPTION: -hscrollmode 210# 211# Enable/disable display and mode of horizontal scrollbars. 212# ------------------------------------------------------------------ 213itcl::configbody iwidgets::Scrolledwidget::hscrollmode { 214 switch $itk_option(-hscrollmode) { 215 static { 216 _horizScrollbarDisplay on 217 } 218 219 dynamic - 220 none { 221 _horizScrollbarDisplay off 222 } 223 224 default { 225 error "bad hscrollmode option\ 226 \"$itk_option(-hscrollmode)\": should be\ 227 static, dynamic, or none" 228 } 229 } 230} 231 232# ------------------------------------------------------------------ 233# OPTION: -width 234# 235# Specifies the width of the scrolled widget. The value may be 236# specified in any of the forms acceptable to Tk_GetPixels. 237# ------------------------------------------------------------------ 238itcl::configbody iwidgets::Scrolledwidget::width { 239 $_interior configure -width \ 240 [winfo pixels $_interior $itk_option(-width)] 241} 242 243# ------------------------------------------------------------------ 244# OPTION: -height 245# 246# Specifies the height of the scrolled widget. The value may be 247# specified in any of the forms acceptable to Tk_GetPixels. 248# ------------------------------------------------------------------ 249itcl::configbody iwidgets::Scrolledwidget::height { 250 $_interior configure -height \ 251 [winfo pixels $_interior $itk_option(-height)] 252} 253 254# ------------------------------------------------------------------ 255# METHODS 256# ------------------------------------------------------------------ 257 258# ------------------------------------------------------------------ 259# PROTECTED METHOD: _vertScrollbarDisplay mode 260# 261# Displays the vertical scrollbar based on the input mode. 262# ------------------------------------------------------------------ 263itcl::body iwidgets::Scrolledwidget::_vertScrollbarDisplay {mode} { 264 switch $mode { 265 on { 266 set _vmode on 267 268 grid columnconfigure $_interior 1 -minsize \ 269 [winfo pixels $_interior $itk_option(-scrollmargin)] 270 grid $itk_component(vertsb) -row 0 -column 2 -sticky ns 271 } 272 273 off { 274 set _vmode off 275 276 grid columnconfigure $_interior 1 -minsize 0 277 grid forget $itk_component(vertsb) 278 } 279 280 default { 281 error "invalid argument \"$mode\": should be on or off" 282 } 283 } 284} 285 286# ------------------------------------------------------------------ 287# PROTECTED METHOD: _horizScrollbarDisplay mode 288# 289# Displays the horizontal scrollbar based on the input mode. 290# ------------------------------------------------------------------ 291itcl::body iwidgets::Scrolledwidget::_horizScrollbarDisplay {mode} { 292 switch $mode { 293 on { 294 set _hmode on 295 296 grid rowconfigure $_interior 1 -minsize \ 297 [winfo pixels $_interior $itk_option(-scrollmargin)] 298 grid $itk_component(horizsb) -row 2 -column 0 -sticky ew 299 } 300 301 off { 302 set _hmode off 303 304 grid rowconfigure $_interior 1 -minsize 0 305 grid forget $itk_component(horizsb) 306 } 307 308 default { 309 error "invalid argument \"$mode\": should be on or off" 310 } 311 } 312} 313 314# ------------------------------------------------------------------ 315# PROTECTED METHOD: _scrollWidget wid first last 316# 317# Performs scrolling and display of scrollbars based on the total 318# and maximum frame size as well as the current -vscrollmode and 319# -hscrollmode settings. Parameters are automatic scroll parameters. 320# ------------------------------------------------------------------ 321itcl::body iwidgets::Scrolledwidget::_scrollWidget {wid first last} { 322 $wid set $first $last 323 324 if {$wid == $itk_component(vertsb)} { 325 if {$itk_option(-vscrollmode) == "dynamic"} { 326 if {($_recheckVert != 1) && ($_vmode == "on")} { 327 return 328 } else { 329 set _recheckVert 0 330 } 331 332 if {($first == 0) && ($last == 1)} { 333 if {$_vmode != "off"} { 334 _vertScrollbarDisplay off 335 } 336 337 } else { 338 if {$_vmode != "on"} { 339 _vertScrollbarDisplay on 340 } 341 } 342 } 343 344 } elseif {$wid == $itk_component(horizsb)} { 345 if {$itk_option(-hscrollmode) == "dynamic"} { 346 if {($_recheckHoriz != 1) && ($_hmode == "on")} { 347 return 348 } else { 349 set _recheckHoriz 0 350 } 351 352 if {($first == 0) && ($last == 1)} { 353 if {$_hmode != "off"} { 354 _horizScrollbarDisplay off 355 } 356 357 } else { 358 if {$_hmode != "on"} { 359 _horizScrollbarDisplay on 360 } 361 } 362 } 363 } 364} 365 366# ------------------------------------------------------------------ 367# PROTECTED METHOD: _configureEvent 368# 369# Resets the recheck flags which determine if we'll try and map 370# the scrollbars in dynamic mode. 371# ------------------------------------------------------------------ 372itcl::body iwidgets::Scrolledwidget::_configureEvent {} { 373 update idletasks 374 set _recheckVert 1 375 set _recheckHoriz 1 376} 377