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
|
set rcsId {$Id: scroll.tcl,v 1.9 1998/10/04 14:57:52 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] horizontal [new scrollbar $path] 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
grid rowconfigure $path 0 -weight 1
grid columnconfigure $path 0 -weight 1
set scroll::($this,0,1,path) $composite::($this,vertical,path)
set scroll::($this,1,0,path) $composite::($this,horizontal,path)
composite::complete $this
}
proc ~scroll {this} {}
proc options {this} {
return [list\
[list -automatic automatic Automatic 1 1]\
[list\
-scrollbarborderwidth scrollbarBorderWidth ScrollbarBorderWidth\
$widget::(default,ScrollbarBorderWidth) $widget::(default,ScrollbarBorderWidth)\
]\
[list\
-scrollbarelementborderwidth scrollbarElementBorderWidth ScrollbarElementBorderWidth\
$widget::(default,ScrollbarElementBorderWidth) $widget::(default,ScrollbarElementBorderWidth)\
]\
[list\
-scrollbarwidth scrollbarWidth ScrollbarWidth $widget::(default,ScrollbarWidth) $widget::(default,ScrollbarWidth)\
]\
[list -height height Height $widget::(default,CanvasHeight)]\
[list -horizontal horizontal Horizontal 1 1]\
[list -vertical vertical Vertical 1 1]\
[list -width width Width $widget::(default,CanvasWidth)]\
]
}
foreach option {-automatic -horizontal -vertical} {
proc set$option {this value} "
if {\$composite::(\$this,complete)} {
error {option $option cannot be set dynamically}
}
"
}
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 update {this row column first last} {
set path $scroll::($this,$row,$column,path)
foreach {previousFirst previousLast} [$path get] {}
if {($first!=$previousFirst)||($last!=$previousLast)} { ;# update only when necessary
$path set $first $last
}
set visible [llength [grid info $path]]
if {!$composite::($this,-automatic)||(($last-$first)<1)} {
if {!$visible} { ;# map both scrollbars at the same time to avoid vibrations
if {$composite::($this,-vertical)} {
grid $composite::($this,vertical,path) -row 0 -column 1 -sticky nsew
}
if {$composite::($this,-horizontal)} {
grid $composite::($this,horizontal,path) -row 1 -column 0 -sticky nsew
}
grid $composite::($this,filler,path) -sticky nsew -column 1 -row 1
}
} else {
foreach {first last} [$scroll::($this,$column,$row,path) get] {} ;# look at other scrollbar range
if {$visible&&(($last-$first)>=1)} { ;# unmap both scrollbars at the same time to avoid vibrations
grid remove $scroll::($this,0,1,path)
grid remove $scroll::($this,1,0,path)
grid remove $composite::($this,filler,path)
}
}
}
}
|