[AJB] - I put this together because I'm tired of having to set up the scrollbars, and I don't always want to load packages that have a lot of dependencies. More and more I am interested in packaging [Snit] with all of my apps, so here is a wrapper for any scrollable widget that will take care of all of your scrollbar woes. PS, not tested on Mac. Sorry. [AJB] - Oct 18, 04 - A few changes to incorporate a -scalewidget option based on this [http://wiki.tcl.tk/2475]. If the option is set to true, the widget uses scales instead of scrollbars. [PAK] - Jan 5, 05 - Suppress scrollbar thrashing on text widget when only the last line is too long. When that happens, a horizontal scroll bar is needed, which means the last line gets replaced by the scroll bar, which means that none of the visible lines are too long, which means that the scroll bar gets removed, which means the last line is too long.... ########################################## # # snitscrollwindow.tcl # # Package to provide a wrapper around any scrollable widget # i.e. - text, listbox, canvas # # The scrollbars should have all of the proper bindings # The scrollbars will auto hide/appear as needed # # Options: # -windowtype -- defaults to canvas, but can be any scrollable widget # -scalewidget -- boolean option, if set to true scale widgets will be used in # place of the scrollbars # these options can only be set at creation time # -- all other options are passed to the internal widget itself # -- scrollbar options can be configured using the xscroll/yscroll methods # # Methods: # xscroll -- calling xscroll will cause all remaining args to be sent to the x-scrollbar # example $win xscroll configure -width 12 # -- all of the usual default snit methods configure, cget, etc # # Results: # calling snit::widget with the path of an empty container widget will provide a -windowtype with # scrollbars that appear and disappear as needed, and that have all of the correct bindings package provide snitScrollWindow 0.2 package require Tk package require snit snit::widget snitScrollWindow { # since this option is configured in the constructor, it should not be set to read-only ! option -windowtype -default canvas -validatemethod IsScrollableWidget -readonly no option -scalewidget -default 0 -validatemethod BooleanOption -readonly yes delegate option * to mainWindow delegate method * to mainWindow variable mainWindow variable scrollGrid -array {} constructor {args} { catch {$self configurelist $args} set widget [$self cget -windowtype] set mainWindow [$widget $win.main] $self configure -yscrollcommand [mymethod ScrollHandle $win.y] -xscrollcommand [mymethod ScrollHandle $win.x] grid $mainWindow -row 0 -column 0 -sticky nesw grid columnconfigure $win 0 -weight 1 grid rowconfigure $win 0 -weight 1 if {[$self cget -scalewidget]} { scale $win.y -orient vertical -command [mymethod WindowScaleScroll $mainWindow yview] -width 12 -from 0 -to 1000 -show 0 scale $win.x -orient horizontal -command [mymethod WindowScaleScroll $mainWindow xview] -width 12 -from 0 -to 1000 -show 0 } else { scrollbar $win.y -orient vertical -command [list $self yview] -width 12 scrollbar $win.x -orient horizontal -command [list $self xview] -width 12 } grid $win.y -row 0 -column 1 -sticky ns grid $win.x -row 1 -column 0 -sticky ew set scrollGrid($win.y) [grid info $win.y] set scrollGrid($win.x) [grid info $win.x] if {$widget eq "canvas"} {bind $mainWindow {%W configure -scrollregion [%W bbox all]}} bind $mainWindow [list $self yview scroll -1 units] bind $mainWindow [list $self yview scroll 1 units] bind $mainWindow [list $self xview scroll -1 units] bind $mainWindow [list $self xview scroll 1 units] bind $mainWindow