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