SWindow.tcl 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
  2. #
  3. # $Id: SWindow.tcl,v 1.4 2001/12/09 05:04:02 idiscovery Exp $
  4. #
  5. # SWindow.tcl --
  6. #
  7. # This file implements Scrolled Window widgets
  8. #
  9. # Copyright (c) 1993-1999 Ioi Kim Lam.
  10. # Copyright (c) 2000-2001 Tix Project Group.
  11. #
  12. # See the file "license.terms" for information on usage and redistribution
  13. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  14. #
  15. #
  16. #
  17. # Example:
  18. #
  19. # tixScrolledWindow .w
  20. # set window [.w subwidget window]
  21. # # Now you can put a whole widget hierachy inside $window.
  22. # #
  23. # button $window.b
  24. # pack $window.b
  25. #
  26. # Author's note
  27. #
  28. # Note, the current implementation does not allow the child window
  29. # to be outside of the parent window when the parent's size is larger
  30. # than the child's size. This is fine for normal operations. However,
  31. # it is not suitable for an MDI master window. Therefore, you will notice
  32. # that the MDI master window is not a subclass of ScrolledWidget at all.
  33. #
  34. #
  35. tixWidgetClass tixScrolledWindow {
  36. -classname TixScrolledWindow
  37. -superclass tixScrolledWidget
  38. -method {
  39. }
  40. -flag {
  41. -expandmode -shrink -xscrollincrement -yscrollincrement
  42. }
  43. -static {
  44. }
  45. -configspec {
  46. {-expandmode expandMode ExpandMode expand}
  47. {-shrink shrink Shrink ""}
  48. {-xscrollincrement xScrollIncrement ScrollIncrement ""}
  49. {-yscrollincrement yScrollIncrement ScrollIncrement ""}
  50. {-scrollbarspace scrollbarSpace ScrollbarSpace {both}}
  51. }
  52. -default {
  53. {.scrollbar auto}
  54. {*window.borderWidth 1}
  55. {*f1.borderWidth 1}
  56. {*Scrollbar.borderWidth 1}
  57. {*Scrollbar.takeFocus 0}
  58. }
  59. }
  60. proc tixScrolledWindow:InitWidgetRec {w} {
  61. upvar #0 $w data
  62. tixChainMethod $w InitWidgetRec
  63. set data(dx) 0
  64. set data(dy) 0
  65. }
  66. proc tixScrolledWindow:ConstructWidget {w} {
  67. upvar #0 $w data
  68. global tcl_platform
  69. tixChainMethod $w ConstructWidget
  70. set data(pw:f1) \
  71. [frame $w.f1 -relief sunken]
  72. set data(pw:f2) \
  73. [frame $w.f2 -bd 0]
  74. set data(w:window) \
  75. [frame $w.f2.window -bd 0]
  76. pack $data(pw:f2) -in $data(pw:f1) -expand yes -fill both
  77. set data(w:hsb) \
  78. [scrollbar $w.hsb -orient horizontal -takefocus 0]
  79. set data(w:vsb) \
  80. [scrollbar $w.vsb -orient vertical -takefocus 0]
  81. # set data(w:pann) \
  82. # [frame $w.pann -bd 2 -relief groove]
  83. $data(pw:f1) config -highlightthickness \
  84. [$data(w:hsb) cget -highlightthickness]
  85. set data(pw:client) $data(pw:f1)
  86. }
  87. proc tixScrolledWindow:SetBindings {w} {
  88. upvar #0 $w data
  89. tixChainMethod $w SetBindings
  90. $data(w:hsb) config -command "tixScrolledWindow:ScrollBarCB $w x"
  91. $data(w:vsb) config -command "tixScrolledWindow:ScrollBarCB $w y"
  92. tixManageGeometry $data(w:window) "tixScrolledWindow:WindowGeomProc $w"
  93. }
  94. # This guy just keeps asking for a same size as the w:window
  95. #
  96. proc tixScrolledWindow:WindowGeomProc {w args} {
  97. upvar #0 $w data
  98. set rw [winfo reqwidth $data(w:window)]
  99. set rh [winfo reqheight $data(w:window)]
  100. if {$rw != [winfo reqwidth $data(pw:f2)] ||
  101. $rh != [winfo reqheight $data(pw:f2)]} {
  102. tixGeometryRequest $data(pw:f2) $rw $rh
  103. }
  104. }
  105. proc tixScrolledWindow:Scroll {w axis total window first args} {
  106. upvar #0 $w data
  107. case [lindex $args 0] {
  108. "scroll" {
  109. set amt [lindex $args 1]
  110. set unit [lindex $args 2]
  111. case $unit {
  112. "units" {
  113. set incr $axis\scrollincrement
  114. if {$data(-$incr) != ""} {
  115. set by $data(-$incr)
  116. } else {
  117. set by [expr $window / 16]
  118. }
  119. set first [expr $first + $amt * $by]
  120. }
  121. "pages" {
  122. set first [expr $first + $amt * $window]
  123. }
  124. }
  125. }
  126. "moveto" {
  127. set to [lindex $args 1]
  128. set first [expr int($to * $total)]
  129. }
  130. }
  131. if {[expr $first + $window] > $total} {
  132. set first [expr $total - $window]
  133. }
  134. if {$first < 0} {
  135. set first 0
  136. }
  137. return $first
  138. }
  139. proc tixScrolledWindow:ScrollBarCB {w axis args} {
  140. upvar #0 $w data
  141. set bd \
  142. [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  143. set fw [expr [winfo width $data(pw:f1)] - 2*$bd]
  144. set fh [expr [winfo height $data(pw:f1)] - 2*$bd]
  145. set ww [winfo reqwidth $data(w:window)]
  146. set wh [winfo reqheight $data(w:window)]
  147. if {$axis == "x"} {
  148. set data(dx) \
  149. [eval tixScrolledWindow:Scroll $w $axis $ww $fw $data(dx) $args]
  150. } else {
  151. set data(dy) \
  152. [eval tixScrolledWindow:Scroll $w $axis $wh $fh $data(dy) $args]
  153. }
  154. tixWidgetDoWhenIdle tixScrolledWindow:PlaceWindow $w
  155. }
  156. proc tixScrolledWindow:PlaceWindow {w} {
  157. upvar #0 $w data
  158. set bd \
  159. [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  160. set fw [expr [winfo width $data(pw:f1)] - 2*$bd]
  161. set fh [expr [winfo height $data(pw:f1)] - 2*$bd]
  162. set ww [winfo reqwidth $data(w:window)]
  163. set wh [winfo reqheight $data(w:window)]
  164. tixMapWindow $data(w:window)
  165. if {$data(-expandmode) == "expand"} {
  166. if {$ww < $fw} {
  167. set ww $fw
  168. }
  169. if {$wh < $fh} {
  170. set wh $fh
  171. }
  172. }
  173. if {$data(-shrink) == "x"} {
  174. if {$fw < $ww} {
  175. set ww $fw
  176. }
  177. }
  178. tixMoveResizeWindow $data(w:window) -$data(dx) -$data(dy) $ww $wh
  179. set first [expr $data(dx).0 / $ww.0]
  180. set last [expr $first + ($fw.0 / $ww.0)]
  181. $data(w:hsb) set $first $last
  182. set first [expr $data(dy).0 / $wh.0]
  183. set last [expr $first + ($fh.0 / $wh.0)]
  184. $data(w:vsb) set $first $last
  185. }
  186. #----------------------------------------------------------------------
  187. # virtual functions to query the client window's scroll requirement
  188. #
  189. # When this function is called, the scrolled window is going to be
  190. # mapped, if it is still unmapped. Also, it is going to change its
  191. # size. Therefore, it is a good time to check whether the w:window needs
  192. # to be re-positioned due to the new parent window size.
  193. #----------------------------------------------------------------------
  194. proc tixScrolledWindow:GeometryInfo {w mW mH} {
  195. upvar #0 $w data
  196. set bd \
  197. [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  198. set fw [expr $mW -2*$bd]
  199. set fh [expr $mH -2*$bd]
  200. set ww [winfo reqwidth $data(w:window)]
  201. set wh [winfo reqheight $data(w:window)]
  202. # Calculate the X info
  203. #
  204. if {$fw >= $ww} {
  205. if {$data(dx) > 0} {
  206. set data(dx) 0
  207. }
  208. set xinfo [list 0.0 1.0]
  209. } else {
  210. set maxdx [expr $ww - $fw]
  211. if {$data(dx) > $maxdx} {
  212. set data(dx) $maxdx
  213. }
  214. set first [expr $data(dx).0 / $ww.0]
  215. set last [expr $first + ($fw.0 / $ww.0)]
  216. set xinfo [list $first $last]
  217. }
  218. # Calculate the Y info
  219. #
  220. if {$fh >= $wh} {
  221. if {$data(dy) > 0} {
  222. set data(dy) 0
  223. }
  224. set yinfo [list 0.0 1.0]
  225. } else {
  226. set maxdy [expr $wh - $fh]
  227. if {$data(dy) > $maxdy} {
  228. set data(dy) $maxdy
  229. }
  230. set first [expr $data(dy).0 / $wh.0]
  231. set last [expr $first + ($fh.0 / $wh.0)]
  232. set yinfo [list $first $last]
  233. }
  234. return [list $xinfo $yinfo]
  235. }