proc scrollpane {w x y} {
frame $w -class ScrollPane -width $x -height $y
canvas $w.c -xscrollcommand [list $w.x set] -yscrollcommand [list $w.y set]
scrollbar $w.x -orient horizontal -command [list $w.c xview]
scrollbar $w.y -orient vertical -command [list $w.c yview]
set f [frame $w.c.content -borderwidth 0 -highlightthickness 0]
$w.c create window 0 0 -anchor nw -window $f
grid $w.c $w.y -sticky nsew
grid $w.x -sticky nsew
grid rowconfigure $w 0 -weight 1
grid columnconfigure $w 0 -weight 1
# This binding makes the scroll-region of the canvas behave correctly as
# you place more things in the content frame.
bind $f <Configure> [list scrollpane_cfg $w %w %h]
$w.c configure -borderwidth 0 -highlightthickness 0
return $f
}
proc scrollpane_cfg {w wide high} {
set newSR [list 0 0 $wide $high]
if {![string equals [$w cget -scrollregion] $newSR]} {
$w configure -scrollregion $newSR
}
}
### Demo code ###
set sp [scrollpane .s 95 235]
pack .s -fill both
pack [button .quit -text Quit -command exit] -fill both
for {set i 0} {$i<25} {incr i} {
set text "This is button #$i of a sequence"
pack [button $sp.b$i -text $text -command [list puts HI-$i]]
}