1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
# $Id: scroll.tcl,v 2.14 2004/10/02 12:40:54 jfontain Exp $
# generic scroll widget with automatic scrollbars for scrolling widgets with the common tk scroll interface
class scroll {
proc scroll {this scrollableClass parentPath args} composite {[new frame $parentPath] $args} {
# scrollable class widget must accept the -[xy]scrollcommand options and [xy]view commands, such as canvas, text, table, ...
set path $widget::($this,path)
composite::manage $this [new $scrollableClass $path] scrolled\
[new scrollbar $path -orient horizontal -highlightthickness 0] horizontal\
[new scrollbar $path -highlightthickness 0] vertical [new frame $path] filler
widget::configure $composite::($this,scrolled)\
-xscrollcommand "scroll::update $this 1 0" -yscrollcommand "scroll::update $this 0 1"
widget::configure $composite::($this,horizontal) -command "$composite::($this,scrolled,path) xview"
widget::configure $composite::($this,vertical) -command "$composite::($this,scrolled,path) yview"
grid propagate $widget::($this,path) 0 ;# turn off propagation so that setting width and height is possible
grid $composite::($this,scrolled,path) -sticky nsew -ipadx 0
grid rowconfigure $path 0 -weight 1
grid columnconfigure $path 0 -weight 1
set ($this,0,1,path) $composite::($this,vertical,path)
set ($this,1,0,path) $composite::($this,horizontal,path)
set ($this,0,1,map) 1
set ($this,1,0,map) 1
composite::complete $this
}
proc ~scroll {this} {}
proc options {this} {
return [list\
[list -automatic 1 1]\
[list -scrollbarborderwidth $widget::option(scrollbar,borderwidth) $widget::option(scrollbar,borderwidth)]\
[list\
-scrollbarelementborderwidth\
$widget::option(scrollbar,elementborderwidth) $widget::option(scrollbar,elementborderwidth)\
]\
[list -scrollbarwidth $widget::option(scrollbar,width) $widget::option(scrollbar,width)]\
[list -height $widget::option(canvas,height)]\
[list -horizontal $($this,1,0,map) $($this,1,0,map)]\
[list -vertical $($this,0,1,map) $($this,0,1,map)]\
[list -viewthreshold 0 0]\
[list -width $widget::option(canvas,width)]\
[list -xscrollcommand {} {}]\
[list -yscrollcommand {} {}]\
]
}
proc set-automatic {this value} {
if {$composite::($this,complete)} {
error {option -automatic cannot be set dynamically}
}
}
proc set-horizontal {this value} {
if {$composite::($this,complete)} {
error {option -horizontal cannot be set dynamically}
}
set ($this,1,0,map) $value
}
proc set-vertical {this value} {
if {$composite::($this,complete)} {
error {option -vertical cannot be set dynamically}
}
set ($this,0,1,map) $value
}
proc set-viewthreshold {this value} {}
foreach option {borderwidth elementborderwidth width} {
proc set-scrollbar$option {this value} "
\$composite::(\$this,vertical,path) configure -$option \$value
\$composite::(\$this,horizontal,path) configure -$option \$value
"
}
proc set-height {this value} {
$widget::($this,path) configure -height $value
}
proc set-width {this value} {
$widget::($this,path) configure -width $value
}
proc set-xscrollcommand {this value} {} ;# extra scroll commands
proc set-yscrollcommand {this value} {}
proc update {this row column first last} {
if {($last - $first) < $composite::($this,-viewthreshold)} return ;# eliminate stray events with span in the low percents
set path $($this,$row,$column,path)
foreach {previousFirst previousLast} [$path get] {}
if {($first == $previousFirst) && ($last == $previousLast)} return ;# no change
$path set $first $last ;# always set so that get always return valid values
set visible [llength [grid info $path]]
if {!$composite::($this,-automatic) || (($last - $first) < 1)} {
if {!$visible && $($this,$row,$column,map)} {
grid $path -row $row -column $column -sticky nsew
grid $composite::($this,filler,path) -sticky nsew -column 1 -row 1
set ($this,$row,$column,updating) {} ;# prevent infinite oscillations
::update idletasks
unset ($this,$row,$column,updating)
}
} elseif {![info exists ($this,$row,$column,updating)]} {
grid remove $path
set visible [llength [grid info $($this,$column,$row,path)]] ;# look at other scrollbar
if {!$visible} {
grid remove $composite::($this,filler,path)
}
}
if {$row} { ;# X scroll update
if {[string length $composite::($this,-xscrollcommand)] > 0} {
uplevel #0 $composite::($this,-xscrollcommand) $first $last
}
} else { ;# Y scroll update
if {[string length $composite::($this,-yscrollcommand)] > 0} {
uplevel #0 $composite::($this,-yscrollcommand) $first $last
}
}
}
}
|