2
#----------------------------------------------------------------------
6
# Package to create scroll bars that automatically appear when
7
# a window is too small to display its content.
10
# See http://mini.net/tcl/950.html
12
#----------------------------------------------------------------------
14
package provide autoscroll 1.0
16
namespace eval autoscroll {
17
namespace export autoscroll
19
bind Autoscroll <Delete> [namespace code [list delete %W]]
20
bind Autoscroll <Map> [namespace code [list map %W]]
23
#----------------------------------------------------------------------
25
# autoscroll::autoscroll --
27
# Create a scroll bar that disappears when it is not needed, and
28
# reappears when it is.
31
# w -- Path name of the scroll bar, which should already
32
# exist and have its geometry managed by the gridder.
38
# The widget command is renamed, so that the 'set' command can
39
# be intercepted and determine whether the widget should appear.
40
# In addition, the 'Autoscroll' bind tag is added to the widget,
41
# so that the <Destroy> event can be intercepted.
44
# It is an error to change the widget's gridding after
45
# calling 'autoscroll' on it.
47
#----------------------------------------------------------------------
49
proc autoscroll::autoscroll { w } {
54
rename $w [namespace current]::renamed$w
57
return \[eval \[list autoscroll::widgetCommand $w\] \$args\]
61
if { [string match {} $i] } {
62
error "$w is not gridded"
67
bindtags $w [linsert [bindtags $w] 1 Autoscroll]
69
eval [list ::$w set] [renamed$w get]
74
#----------------------------------------------------------------------
76
# autoscroll::widgetCommand --
78
# Widget command on an 'autoscroll' scrollbar
81
# w -- Path name of the scroll bar
82
# command -- Widget command being executed
83
# args -- Arguments to the commane
86
# Returns whatever the widget command returns
89
# Has whatever side effects the widget command has. In
90
# addition, the 'set' widget command is handled specially,
91
# by setting/unsetting the 'needed' flag and gridding/ungridding
92
# the scroll bar according to whether it is required.
94
#----------------------------------------------------------------------
96
proc autoscroll::widgetCommand { w command args } {
101
switch -exact -- $command {
103
foreach { min max } $args {}
104
if { $min <= 0 && $max >= 1 } {
105
if { [info exists needed($w)] } {
110
if { ! [info exists needed($w)] } {
112
eval [list grid $w] $grid($w)
118
return [eval [list renamed$w $command] $args]
121
#----------------------------------------------------------------------
123
# autoscroll::delete --
125
# Delete an automatic scroll bar
128
# w -- Path name of the scroll bar
134
# Cleans up internal memory.
136
#----------------------------------------------------------------------
138
proc autoscroll::delete { w } {
142
catch { unset grid($w) }
143
catch { unset needed($w) }
144
catch { rename renamed$w {} }
149
#----------------------------------------------------------------------
153
# Callback executed when an automatic scroll bar is mapped.
156
# w -- Path name of the scroll bar.
162
# Geometry of the scroll bar's top-level window is constrained.
164
# This procedure keeps the top-level window associated with an
165
# automatic scroll bar from being resized automatically after the
166
# scroll bar is mapped. This effect avoids a potential endless loop
167
# in the case where the resize of the top-level window resizes the
168
# widget being scrolled, causing the scroll bar no longer to be needed.
170
#----------------------------------------------------------------------
172
proc autoscroll::map { w } {
173
wm geometry [winfo toplevel $w] \
174
[wm geometry [winfo toplevel $w]]