1# ----------------------------------------------------------------------------- 2# scrollw.tcl 3# This file is part of Unifix BWidget Toolkit 4# $Id: scrollw.tcl,v 1.7 2003/05/07 06:26:59 hobbs Exp $ 5# ----------------------------------------------------------------------------- 6# Index of commands: 7# - ScrolledWindow::create 8# - ScrolledWindow::getframe 9# - ScrolledWindow::setwidget 10# - ScrolledWindow::configure 11# - ScrolledWindow::cget 12# - ScrolledWindow::_set_hframe 13# - ScrolledWindow::_set_vscroll 14# - ScrolledWindow::_setData 15# - ScrolledWindow::_setSBSize 16# - ScrolledWindow::_realize 17# ----------------------------------------------------------------------------- 18 19namespace eval ScrolledWindow { 20 Widget::declare ScrolledWindow { 21 {-background TkResource "" 0 button} 22 {-scrollbar Enum both 0 {none both vertical horizontal}} 23 {-auto Enum both 0 {none both vertical horizontal}} 24 {-sides Enum se 0 {ne en nw wn se es sw ws}} 25 {-size Int 0 1 "%d >= 0"} 26 {-ipad Int 1 1 "%d >= 0"} 27 {-managed Boolean 1 1} 28 {-relief TkResource flat 0 frame} 29 {-borderwidth TkResource 0 0 frame} 30 {-bg Synonym -background} 31 {-bd Synonym -borderwidth} 32 } 33 34 Widget::addmap ScrolledWindow "" :cmd {-relief {} -borderwidth {}} 35 36 proc ::ScrolledWindow {path args} { 37 return [eval [list ScrolledWindow::create $path] $args] 38 } 39 proc use {} {} 40} 41 42 43# ----------------------------------------------------------------------------- 44# Command ScrolledWindow::create 45# ----------------------------------------------------------------------------- 46proc ScrolledWindow::create { path args } { 47 upvar \#0 ScrolledWindow::$path data 48 49 Widget::init ScrolledWindow $path $args 50 51 set bg [Widget::cget $path -background] 52 set sbsize [Widget::cget $path -size] 53 set sw [frame $path \ 54 -relief flat -borderwidth 0 -background $bg \ 55 -highlightthickness 0 -takefocus 0] 56 57 scrollbar $path.hscroll \ 58 -highlightthickness 0 -takefocus 0 \ 59 -orient horiz \ 60 -relief sunken \ 61 -bg $bg 62 scrollbar $path.vscroll \ 63 -highlightthickness 0 -takefocus 0 \ 64 -orient vert \ 65 -relief sunken \ 66 -bg $bg 67 68 set data(realized) 0 69 70 _setData $path \ 71 [Widget::cget $path -scrollbar] \ 72 [Widget::cget $path -auto] \ 73 [Widget::cget $path -sides] 74 75 if {[Widget::cget $path -managed]} { 76 set data(hsb,packed) $data(hsb,present) 77 set data(vsb,packed) $data(vsb,present) 78 } else { 79 set data(hsb,packed) 0 80 set data(vsb,packed) 0 81 } 82 if {$sbsize} { 83 $path.vscroll configure -width $sbsize 84 $path.hscroll configure -width $sbsize 85 } else { 86 set sbsize [$path.vscroll cget -width] 87 } 88 set data(ipad) [Widget::cget $path -ipad] 89 90 if {$data(hsb,packed)} { 91 grid $path.hscroll -column 1 -row $data(hsb,row) \ 92 -sticky ew -ipady $data(ipad) 93 } 94 if {$data(vsb,packed)} { 95 grid $path.vscroll -column $data(vsb,column) -row 1 \ 96 -sticky ns -ipadx $data(ipad) 97 } 98 99 grid columnconfigure $path 1 -weight 1 100 grid rowconfigure $path 1 -weight 1 101 102 bind $path <Configure> [list ScrolledWindow::_realize $path] 103 bind $path <Destroy> [list ScrolledWindow::_destroy $path] 104 rename $path ::$path:cmd 105 proc ::$path { cmd args } "return \[eval ScrolledWindow::\$cmd $path \$args\]" 106 107 return $path 108} 109 110 111# ----------------------------------------------------------------------------- 112# Command ScrolledWindow::getframe 113# ----------------------------------------------------------------------------- 114proc ScrolledWindow::getframe { path } { 115 return $path 116} 117 118 119# ----------------------------------------------------------------------------- 120# Command ScrolledWindow::setwidget 121# ----------------------------------------------------------------------------- 122proc ScrolledWindow::setwidget { path widget } { 123 upvar \#0 ScrolledWindow::$path data 124 125 if {[info exists data(widget)] && ![string equal $data(widget) $widget]} { 126 grid remove $data(widget) 127 $data(widget) configure -xscrollcommand "" -yscrollcommand "" 128 } 129 set data(widget) $widget 130 grid $widget -in $path -row 1 -column 1 -sticky news 131 132 $path.hscroll configure -command [list $widget xview] 133 $path.vscroll configure -command [list $widget yview] 134 $widget configure \ 135 -xscrollcommand [list ScrolledWindow::_set_hscroll $path] \ 136 -yscrollcommand [list ScrolledWindow::_set_vscroll $path] 137} 138 139 140# ----------------------------------------------------------------------------- 141# Command ScrolledWindow::configure 142# ----------------------------------------------------------------------------- 143proc ScrolledWindow::configure { path args } { 144 upvar \#0 ScrolledWindow::$path data 145 146 set res [Widget::configure $path $args] 147 if { [Widget::hasChanged $path -background bg] } { 148 $path configure -background $bg 149 catch {$path.hscroll configure -background $bg} 150 catch {$path.vscroll configure -background $bg} 151 } 152 153 if {[Widget::hasChanged $path -scrollbar scrollbar] | \ 154 [Widget::hasChanged $path -auto auto] | \ 155 [Widget::hasChanged $path -sides sides]} { 156 _setData $path $scrollbar $auto $sides 157 foreach {vmin vmax} [$path.hscroll get] { break } 158 set data(hsb,packed) [expr {$data(hsb,present) && \ 159 (!$data(hsb,auto) || ($vmin != 0 || $vmax != 1))}] 160 foreach {vmin vmax} [$path.vscroll get] { break } 161 set data(vsb,packed) [expr {$data(vsb,present) && \ 162 (!$data(vsb,auto) || ($vmin != 0 || $vmax != 1))}] 163 164 set data(ipad) [Widget::cget $path -ipad] 165 166 if {$data(hsb,packed)} { 167 grid $path.hscroll -column 1 -row $data(hsb,row) \ 168 -sticky ew -ipady $data(ipad) 169 } 170 if {$data(vsb,packed)} { 171 grid $path.vscroll -column $data(vsb,column) -row 1 \ 172 -sticky ns -ipadx $data(ipad) 173 } 174 } 175 return $res 176} 177 178 179# ----------------------------------------------------------------------------- 180# Command ScrolledWindow::cget 181# ----------------------------------------------------------------------------- 182proc ScrolledWindow::cget { path option } { 183 return [Widget::cget $path $option] 184} 185 186 187# ----------------------------------------------------------------------------- 188# Command ScrolledWindow::_destroy 189# ----------------------------------------------------------------------------- 190proc ScrolledWindow::_destroy { path } { 191 upvar \#0 ScrolledWindow::$path data 192 193 unset data 194 Widget::destroy $path 195 rename $path {} 196} 197 198 199# ----------------------------------------------------------------------------- 200# Command ScrolledWindow::_set_hscroll 201# ----------------------------------------------------------------------------- 202proc ScrolledWindow::_set_hscroll { path vmin vmax } { 203 upvar \#0 ScrolledWindow::$path data 204 205 if {$data(realized) && $data(hsb,present)} { 206 if {$data(hsb,auto)} { 207 if {$data(hsb,packed) && $vmin == 0 && $vmax == 1} { 208 if {![info exists data(hlock)]} { 209 set data(hsb,packed) 0 210 grid remove $path.hscroll 211 } 212 } elseif {!$data(hsb,packed) && ($vmin != 0 || $vmax != 1)} { 213 set data(hsb,packed) 1 214 grid $path.hscroll -column 1 -row $data(hsb,row) \ 215 -sticky ew -ipady $data(ipad) 216 set data(hlock) 1 217 update idletasks 218 unset data(hlock) 219 } 220 } 221 $path.hscroll set $vmin $vmax 222 } 223} 224 225 226# ----------------------------------------------------------------------------- 227# Command ScrolledWindow::_set_vscroll 228# ----------------------------------------------------------------------------- 229proc ScrolledWindow::_set_vscroll { path vmin vmax } { 230 upvar \#0 ScrolledWindow::$path data 231 232 if {$data(realized) && $data(vsb,present)} { 233 if {$data(vsb,auto)} { 234 if {$data(vsb,packed) && $vmin == 0 && $vmax == 1} { 235 if {![info exists data(vlock)]} { 236 set data(vsb,packed) 0 237 grid remove $path.vscroll 238 } 239 } elseif {!$data(vsb,packed) && ($vmin != 0 || $vmax != 1) } { 240 set data(vsb,packed) 1 241 grid $path.vscroll -column $data(vsb,column) -row 1 \ 242 -sticky ns -ipadx $data(ipad) 243 set data(vlock) 1 244 update idletasks 245 unset data(vlock) 246 } 247 } 248 $path.vscroll set $vmin $vmax 249 } 250} 251 252 253proc ScrolledWindow::_setData {path scrollbar auto sides} { 254 upvar \#0 ScrolledWindow::$path data 255 256 set sb [lsearch {none horizontal vertical both} $scrollbar] 257 set auto [lsearch {none horizontal vertical both} $auto] 258 259 set data(hsb,present) [expr {($sb & 1) != 0}] 260 set data(hsb,auto) [expr {($auto & 1) != 0}] 261 set data(hsb,row) [expr {[string match *n* $sides] ? 0 : 2}] 262 263 set data(vsb,present) [expr {($sb & 2) != 0}] 264 set data(vsb,auto) [expr {($auto & 2) != 0}] 265 set data(vsb,column) [expr {[string match *w* $sides] ? 0 : 2}] 266} 267 268# ----------------------------------------------------------------------------- 269# Command ScrolledWindow::_realize 270# ----------------------------------------------------------------------------- 271proc ScrolledWindow::_realize { path } { 272 upvar \#0 ScrolledWindow::$path data 273 274 bind $path <Configure> {} 275 set data(realized) 1 276} 277