scrollw.tcl 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. # ------------------------------------------------------------------------------
  2. # scrollw.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # $Id$
  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::_realize
  15. # ------------------------------------------------------------------------------
  16. namespace eval ScrolledWindow {
  17. Widget::declare ScrolledWindow {
  18. {-background TkResource "" 0 button}
  19. {-scrollbar Enum both 1 {none both vertical horizontal}}
  20. {-auto Enum both 0 {none both vertical horizontal}}
  21. {-relief TkResource flat 0 frame}
  22. {-borderwidth TkResource 0 0 frame}
  23. {-bg Synonym -background}
  24. {-bd Synonym -borderwidth}
  25. }
  26. Widget::addmap ScrolledWindow "" ._grid.f {-relief {} -borderwidth {}}
  27. proc ::ScrolledWindow { path args } { return [eval ScrolledWindow::create $path $args] }
  28. proc use {} {}
  29. variable _widget
  30. }
  31. # ------------------------------------------------------------------------------
  32. # Command ScrolledWindow::create
  33. # ------------------------------------------------------------------------------
  34. proc ScrolledWindow::create { path args } {
  35. variable _widget
  36. Widget::init ScrolledWindow $path $args
  37. set bg [Widget::cget $path -background]
  38. set sw [frame $path -relief flat -bd 0 -bg $bg -highlightthickness 0 -takefocus 0]
  39. set grid [frame $path._grid -relief flat -bd 0 -bg $bg -highlightthickness 0 -takefocus 0]
  40. set sb [lsearch {none horizontal vertical both} [Widget::cget $path -scrollbar]]
  41. set auto [lsearch {none horizontal vertical both} [Widget::cget $path -auto]]
  42. set rspan [expr {1 + !($sb & 1)}]
  43. set cspan [expr {1 + !($sb & 2)}]
  44. set _widget($path,realized) 0
  45. set _widget($path,sb) $sb
  46. set _widget($path,auto) $auto
  47. set _widget($path,hpack) [expr {$rspan == 1}]
  48. set _widget($path,vpack) [expr {$cspan == 1}]
  49. # scrollbar horizontale ou les deux
  50. if { $sb & 1 } {
  51. scrollbar $grid.hscroll \
  52. -highlightthickness 0 -takefocus 0 \
  53. -orient horiz \
  54. -relief sunken \
  55. -bg $bg
  56. $grid.hscroll set 0 1
  57. grid $grid.hscroll -column 0 -row 1 -sticky we -columnspan $cspan -pady 1
  58. }
  59. # scrollbar verticale ou les deux
  60. if { $sb & 2 } {
  61. scrollbar $grid.vscroll \
  62. -highlightthickness 0 -takefocus 0 \
  63. -orient vert \
  64. -relief sunken \
  65. -bg $bg
  66. $grid.vscroll set 0 1
  67. grid $grid.vscroll -column 1 -row 0 -sticky ns -rowspan $rspan -padx 1
  68. }
  69. eval frame $grid.f -bg $bg -highlightthickness 0 [Widget::subcget $path ._grid.f]
  70. grid $grid.f -column 0 -row 0 -sticky nwse -columnspan $cspan -rowspan $rspan
  71. grid columnconfigure $grid 0 -weight 1
  72. grid rowconfigure $grid 0 -weight 1
  73. pack $grid -fill both -expand yes
  74. bind $grid <Configure> "ScrolledWindow::_realize $path"
  75. bind $grid <Destroy> "ScrolledWindow::_destroy $path"
  76. rename $path ::$path:cmd
  77. proc ::$path { cmd args } "return \[eval ScrolledWindow::\$cmd $path \$args\]"
  78. return $path
  79. }
  80. # ------------------------------------------------------------------------------
  81. # Command ScrolledWindow::getframe
  82. # ------------------------------------------------------------------------------
  83. proc ScrolledWindow::getframe { path } {
  84. return $path
  85. }
  86. # ------------------------------------------------------------------------------
  87. # Command ScrolledWindow::setwidget
  88. # ------------------------------------------------------------------------------
  89. proc ScrolledWindow::setwidget { path widget } {
  90. variable _widget
  91. set grid $path._grid
  92. set sb $_widget($path,sb)
  93. set option {}
  94. pack $widget -in $grid.f -fill both -expand yes
  95. # scrollbar horizontale ou les deux
  96. if { $sb & 1 } {
  97. $grid.hscroll configure -command "$widget xview"
  98. lappend option "-xscrollcommand" "ScrolledWindow::_set_hscroll $path"
  99. }
  100. # scrollbar verticale ou les deux
  101. if { $sb & 2 } {
  102. $grid.vscroll configure -command "$widget yview"
  103. lappend option "-yscrollcommand" "ScrolledWindow::_set_vscroll $path"
  104. }
  105. if { [llength $option] } {
  106. eval $widget configure $option
  107. }
  108. }
  109. # ------------------------------------------------------------------------------
  110. # Command ScrolledWindow::configure
  111. # ------------------------------------------------------------------------------
  112. proc ScrolledWindow::configure { path args } {
  113. variable _widget
  114. set grid $path._grid
  115. set res [Widget::configure $path $args]
  116. if { [Widget::hasChanged $path -background bg] } {
  117. $path configure -background $bg
  118. $grid configure -background $bg
  119. $grid.f configure -background $bg
  120. catch {$grid.hscroll configure -background $bg}
  121. catch {$grid.vscroll configure -background $bg}
  122. }
  123. if { [Widget::hasChanged $path -auto auto] } {
  124. set _widget($path,auto) [lsearch {none horizontal vertical both} $auto]
  125. if { $_widget($path,sb) & 1 } {
  126. eval _set_hscroll $path [$grid.hscroll get]
  127. }
  128. if { $_widget($path,sb) & 2 } {
  129. eval _set_vscroll $path [$grid.vscroll get]
  130. }
  131. }
  132. return $res
  133. }
  134. # ------------------------------------------------------------------------------
  135. # Command ScrolledWindow::cget
  136. # ------------------------------------------------------------------------------
  137. proc ScrolledWindow::cget { path option } {
  138. return [Widget::cget $path $option]
  139. }
  140. # ------------------------------------------------------------------------------
  141. # Command ScrolledWindow::_destroy
  142. # ------------------------------------------------------------------------------
  143. proc ScrolledWindow::_destroy { path } {
  144. variable _widget
  145. unset _widget($path,sb)
  146. unset _widget($path,auto)
  147. unset _widget($path,hpack)
  148. unset _widget($path,vpack)
  149. Widget::destroy $path
  150. rename $path {}
  151. }
  152. # ------------------------------------------------------------------------------
  153. # Command ScrolledWindow::_set_hscroll
  154. # ------------------------------------------------------------------------------
  155. proc ScrolledWindow::_set_hscroll { path vmin vmax } {
  156. variable _widget
  157. if { $_widget($path,realized) } {
  158. set grid $path._grid
  159. if { $_widget($path,auto) & 1 } {
  160. if { $_widget($path,hpack) && $vmin == 0 && $vmax == 1 } {
  161. grid configure $grid.f -rowspan 2
  162. if { $_widget($path,sb) & 2 } {
  163. grid configure $grid.vscroll -rowspan 2
  164. }
  165. set _widget($path,hpack) 0
  166. } elseif { !$_widget($path,hpack) && ($vmin != 0 || $vmax != 1) } {
  167. grid configure $grid.f -rowspan 1
  168. if { $_widget($path,sb) & 2 } {
  169. grid configure $grid.vscroll -rowspan 1
  170. }
  171. set _widget($path,hpack) 1
  172. }
  173. }
  174. $grid.hscroll set $vmin $vmax
  175. }
  176. }
  177. # ------------------------------------------------------------------------------
  178. # Command ScrolledWindow::_set_vscroll
  179. # ------------------------------------------------------------------------------
  180. proc ScrolledWindow::_set_vscroll { path vmin vmax } {
  181. variable _widget
  182. if { $_widget($path,realized) } {
  183. set grid $path._grid
  184. if { $_widget($path,auto) & 2 } {
  185. if { $_widget($path,vpack) && $vmin == 0 && $vmax == 1 } {
  186. grid configure $grid.f -columnspan 2
  187. if { $_widget($path,sb) & 1 } {
  188. grid configure $grid.hscroll -columnspan 2
  189. }
  190. set _widget($path,vpack) 0
  191. } elseif { !$_widget($path,vpack) && ($vmin != 0 || $vmax != 1) } {
  192. grid configure $grid.f -columnspan 1
  193. if { $_widget($path,sb) & 1 } {
  194. grid configure $grid.hscroll -columnspan 1
  195. }
  196. set _widget($path,vpack) 1
  197. }
  198. }
  199. $grid.vscroll set $vmin $vmax
  200. }
  201. }
  202. # ------------------------------------------------------------------------------
  203. # Command ScrolledWindow::_realize
  204. # ------------------------------------------------------------------------------
  205. proc ScrolledWindow::_realize { path } {
  206. variable _widget
  207. set grid $path._grid
  208. bind $grid <Configure> {}
  209. set _widget($path,realized) 1
  210. place $grid -anchor nw -x 0 -y 0 -relwidth 1.0 -relheight 1.0
  211. }