ResizeH.tcl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
  2. #
  3. # $Id: ResizeH.tcl,v 1.3 2001/12/09 05:04:02 idiscovery Exp $
  4. #
  5. # ResizeH.tcl --
  6. #
  7. # tixResizeHandle: A general purpose "resizing handle"
  8. # widget. You can use it to resize pictures, widgets, etc. When
  9. # using it to resize a widget, you can use the "attachwidget"
  10. # command to attach it to a widget and it will handle all the
  11. # events for you.
  12. #
  13. # Copyright (c) 1993-1999 Ioi Kim Lam.
  14. # Copyright (c) 2000-2001 Tix Project Group.
  15. #
  16. # See the file "license.terms" for information on usage and redistribution
  17. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  18. #
  19. #
  20. #
  21. tixWidgetClass tixResizeHandle {
  22. -classname TixResizeHandle
  23. -superclass tixVResize
  24. -method {
  25. attachwidget detachwidget hide show
  26. }
  27. -flag {
  28. -command -cursorfg -cursorbg -handlesize -hintcolor -hintwidth -x -y
  29. }
  30. -configspec {
  31. {-command command Command ""}
  32. {-cursorfg cursorFg CursorColor white}
  33. {-cursorbg cursorBg CursorColor red}
  34. {-handlesize handleSize HandleSize 6}
  35. {-hintcolor hintColor HintColor red}
  36. {-hintwidth hintWidth HintWidth 1}
  37. {-x x X 0}
  38. {-y y Y 0}
  39. }
  40. }
  41. proc tixResizeHandle:InitWidgetRec {w} {
  42. upvar #0 $w data
  43. tixChainMethod $w InitWidgetRec
  44. set data(shown) 0
  45. set data(widget) ""
  46. }
  47. proc tixResizeHandle:ConstructWidget {w} {
  48. upvar #0 $w data
  49. tixChainMethod $w ConstructWidget
  50. # Create the hints
  51. #
  52. set data(w_ht) $w:tix_priv_ht
  53. set data(w_hb) $w:tix_priv_hb
  54. set data(w_hl) $w:tix_priv_hl
  55. set data(w_hr) $w:tix_priv_hr
  56. frame $data(w_ht) -height $data(-hintwidth) -bg $data(-background)
  57. frame $data(w_hb) -height $data(-hintwidth) -bg $data(-background)
  58. frame $data(w_hl) -width $data(-hintwidth) -bg $data(-background)
  59. frame $data(w_hr) -width $data(-hintwidth) -bg $data(-background)
  60. # Create the corner resize handles
  61. #
  62. set data(w_r00) $w
  63. # Windows don't like this
  64. # $data(rootCmd) config\
  65. # -cursor "top_left_corner $data(-cursorbg) $data(-cursorfg)"
  66. $data(rootCmd) config -cursor top_left_corner
  67. set data(w_r01) $w:tix_priv_01
  68. set data(w_r10) $w:tix_priv_10
  69. set data(w_r11) $w:tix_priv_11
  70. frame $data(w_r01) -relief $data(-relief) -bd $data(-borderwidth) \
  71. -cursor "bottom_left_corner"\
  72. -bg $data(-background)
  73. frame $data(w_r10) -relief $data(-relief) -bd $data(-borderwidth) \
  74. -cursor "top_right_corner"\
  75. -bg $data(-background)
  76. frame $data(w_r11) -relief $data(-relief) -bd $data(-borderwidth) \
  77. -cursor "bottom_right_corner"\
  78. -bg $data(-background)
  79. # Create the border resize handles
  80. #
  81. set data(w_bt) $w:tix_priv_bt
  82. set data(w_bb) $w:tix_priv_bb
  83. set data(w_bl) $w:tix_priv_bl
  84. set data(w_br) $w:tix_priv_br
  85. frame $data(w_bt) -relief $data(-relief) -bd $data(-borderwidth) \
  86. -cursor "top_side"\
  87. -bg $data(-background)
  88. frame $data(w_bb) -relief $data(-relief) -bd $data(-borderwidth) \
  89. -cursor "bottom_side"\
  90. -bg $data(-background)
  91. frame $data(w_bl) -relief $data(-relief) -bd $data(-borderwidth) \
  92. -cursor "left_side"\
  93. -bg $data(-background)
  94. frame $data(w_br) -relief $data(-relief) -bd $data(-borderwidth) \
  95. -cursor "right_side"\
  96. -bg $data(-background)
  97. }
  98. proc tixResizeHandle:SetBindings {w} {
  99. upvar #0 $w data
  100. tixChainMethod $w SetBindings
  101. bind $data(w_r00) <1> \
  102. "tixResizeHandle:dragstart $w $data(w_r00) 1 %X %Y {1 1 -1 -1}"
  103. bind $data(w_r01) <1> \
  104. "tixResizeHandle:dragstart $w $data(w_r01) 1 %X %Y {1 0 -1 1}"
  105. bind $data(w_r10) <1> \
  106. "tixResizeHandle:dragstart $w $data(w_r10) 1 %X %Y {0 1 1 -1}"
  107. bind $data(w_r11) <1> \
  108. "tixResizeHandle:dragstart $w $data(w_r11) 1 %X %Y {0 0 1 1}"
  109. bind $data(w_bt) <1> \
  110. "tixResizeHandle:dragstart $w $data(w_bt) 1 %X %Y {0 1 0 -1}"
  111. bind $data(w_bb) <1> \
  112. "tixResizeHandle:dragstart $w $data(w_bb) 1 %X %Y {0 0 0 1}"
  113. bind $data(w_bl) <1> \
  114. "tixResizeHandle:dragstart $w $data(w_bl) 1 %X %Y {1 0 -1 0}"
  115. bind $data(w_br) <1> \
  116. "tixResizeHandle:dragstart $w $data(w_br) 1 %X %Y {0 0 1 0}"
  117. foreach win [list \
  118. $data(w_r00)\
  119. $data(w_r01)\
  120. $data(w_r10)\
  121. $data(w_r11)\
  122. $data(w_bt)\
  123. $data(w_bb)\
  124. $data(w_bl)\
  125. $data(w_br)\
  126. ] {
  127. bind $win <B1-Motion> "tixVResize:drag $w %X %Y"
  128. bind $win <ButtonRelease-1> "tixVResize:dragend $w $win 0 %X %Y"
  129. bind $win <Any-Escape> "tixVResize:dragend $w $win 1 0 0"
  130. }
  131. }
  132. #----------------------------------------------------------------------
  133. # Config Methods
  134. #----------------------------------------------------------------------
  135. proc tixResizeHandle:config-width {w value} {
  136. tixWidgetDoWhenIdle tixResizeHandle:ComposeWindow $w
  137. }
  138. proc tixResizeHandle:config-height {w value} {
  139. tixWidgetDoWhenIdle tixResizeHandle:ComposeWindow $w
  140. }
  141. proc tixResizeHandle:config-x {w value} {
  142. tixWidgetDoWhenIdle tixResizeHandle:ComposeWindow $w
  143. }
  144. proc tixResizeHandle:config-y {w value} {
  145. tixWidgetDoWhenIdle tixResizeHandle:ComposeWindow $w
  146. }
  147. #----------------------------------------------------------------------
  148. # Public Methods
  149. #----------------------------------------------------------------------
  150. proc tixResizeHandle:dragstart {w win depress rootx rooty mrect} {
  151. upvar #0 $w data
  152. set wx $data(-x)
  153. set wy $data(-y)
  154. set ww $data(-width)
  155. set wh $data(-height)
  156. tixVResize:dragstart $w $win $depress $rootx $rooty \
  157. [list $wx $wy $ww $wh] $mrect
  158. }
  159. # tixDeleteBindTag --
  160. #
  161. # Delete the bindtag(s) in the args list from the bindtags of the widget
  162. #
  163. proc tixDeleteBindTag {w args} {
  164. if {![winfo exists $w]} {
  165. return
  166. }
  167. set newtags ""
  168. foreach tag [bindtags $w] {
  169. if {[lsearch $args $tag] == -1} {
  170. lappend newtags $tag
  171. }
  172. }
  173. bindtags $w $newtags
  174. }
  175. proc tixAddBindTag {w args} {
  176. bindtags $w [concat [bindtags $w] $args]
  177. }
  178. proc tixResizeHandle:attachwidget {w widget args} {
  179. upvar #0 $w data
  180. set opt(-move) 0
  181. tixHandleOptions opt {-move} $args
  182. if {$data(widget) != ""} {
  183. tixDeleteBindTag $data(widget) TixResizeHandleTag:$w
  184. }
  185. set data(widget) $widget
  186. if {$data(widget) != ""} {
  187. # Just in case TixResizeHandleTag was already there
  188. tixDeleteBindTag $data(widget) TixResizeHandleTag:$w
  189. tixAddBindTag $data(widget) TixResizeHandleTag:$w
  190. set data(-x) [winfo x $data(widget)]
  191. set data(-y) [winfo y $data(widget)]
  192. set data(-width) [winfo width $data(widget)]
  193. set data(-height) [winfo height $data(widget)]
  194. tixResizeHandle:show $w
  195. tixResizeHandle:ComposeWindow $w
  196. # Now set the bindings
  197. #
  198. if {$opt(-move)} {
  199. bind TixResizeHandleTag:$w <1> \
  200. "tixResizeHandle:Attach $w %X %Y"
  201. bind TixResizeHandleTag:$w <B1-Motion> \
  202. "tixResizeHandle:BMotion $w %X %Y"
  203. bind TixResizeHandleTag:$w <Any-Escape> \
  204. "tixResizeHandle:BRelease $w 1 %X %Y"
  205. bind TixResizeHandleTag:$w <ButtonRelease-1>\
  206. "tixResizeHandle:BRelease $w 0 %X %Y"
  207. } else {
  208. # if "move" is false, then the widget won't be moved as a whole --
  209. # ResizeHandle will only move its sides
  210. bind TixResizeHandleTag:$w <1> {;}
  211. bind TixResizeHandleTag:$w <B1-Motion> {;}
  212. bind TixResizeHandleTag:$w <Any-Escape> {;}
  213. bind TixResizeHandleTag:$w <ButtonRelease-1> {;}
  214. }
  215. }
  216. }
  217. proc tixResizeHandle:detachwidget {w} {
  218. upvar #0 $w data
  219. if {$data(widget) != ""} {
  220. tixDeleteBindTag $data(widget) TixResizeHandleTag:$w
  221. }
  222. tixResizeHandle:hide $w
  223. }
  224. proc tixResizeHandle:show {w} {
  225. upvar #0 $w data
  226. set data(shown) 1
  227. raise $data(w_ht)
  228. raise $data(w_hb)
  229. raise $data(w_hl)
  230. raise $data(w_hr)
  231. raise $data(w_r00)
  232. raise $data(w_r01)
  233. raise $data(w_r10)
  234. raise $data(w_r11)
  235. raise $data(w_bt)
  236. raise $data(w_bb)
  237. raise $data(w_bl)
  238. raise $data(w_br)
  239. # tixCancleIdleTask tixResizeHandle:ComposeWindow $w
  240. tixResizeHandle:ComposeWindow $w
  241. }
  242. proc tixResizeHandle:hide {w} {
  243. upvar #0 $w data
  244. if {!$data(shown)} {
  245. return
  246. }
  247. set data(shown) 0
  248. place forget $data(w_r00)
  249. place forget $data(w_r01)
  250. place forget $data(w_r10)
  251. place forget $data(w_r11)
  252. place forget $data(w_bt)
  253. place forget $data(w_bb)
  254. place forget $data(w_bl)
  255. place forget $data(w_br)
  256. place forget $data(w_ht)
  257. place forget $data(w_hb)
  258. place forget $data(w_hl)
  259. place forget $data(w_hr)
  260. }
  261. proc tixResizeHandle:Destructor {w} {
  262. upvar #0 $w data
  263. if {$data(widget) != ""} {
  264. tixDeleteBindTag $data(widget) TixResizeHandleTag:$w
  265. }
  266. catch {destroy $data(w_r01)}
  267. catch {destroy $data(w_r10)}
  268. catch {destroy $data(w_r11)}
  269. catch {destroy $data(w_bt)}
  270. catch {destroy $data(w_bb)}
  271. catch {destroy $data(w_bl)}
  272. catch {destroy $data(w_br)}
  273. catch {destroy $data(w_ht)}
  274. catch {destroy $data(w_hb)}
  275. catch {destroy $data(w_hl)}
  276. catch {destroy $data(w_hr)}
  277. tixChainMethod $w Destructor
  278. }
  279. #----------------------------------------------------------------------
  280. # Private Methods Dealing With Attached Widgets
  281. #----------------------------------------------------------------------
  282. proc tixResizeHandle:Attach {w rx ry} {
  283. upvar #0 $w data
  284. tixResizeHandle:dragstart $w $data(widget) 0 $rx $ry {1 1 0 0}
  285. }
  286. proc tixResizeHandle:BMotion {w rx ry} {
  287. tixVResize:drag $w $rx $ry
  288. }
  289. proc tixResizeHandle:BRelease {w isAbort rx ry} {
  290. upvar #0 $w data
  291. tixVResize:dragend $w $data(widget) $isAbort $rx $ry
  292. }
  293. #----------------------------------------------------------------------
  294. # Private Methods
  295. #----------------------------------------------------------------------
  296. proc tixResizeHandle:DrawTmpLines {w} {
  297. upvar #0 $w data
  298. # I've seen this error - mike
  299. if {![info exists data(hf:x1)]} {return}
  300. set x1 $data(hf:x1)
  301. if {![info exists data(hf:y1)]} {return}
  302. set y1 $data(hf:y1)
  303. if {![info exists data(hf:x2)]} {return}
  304. set x2 $data(hf:x2)
  305. if {![info exists data(hf:y2)]} {return}
  306. set y2 $data(hf:y2)
  307. tixTmpLine $x1 $y1 $x2 $y1 $w
  308. tixTmpLine $x1 $y2 $x2 $y2 $w
  309. tixTmpLine $x1 $y1 $x1 $y2 $w
  310. tixTmpLine $x2 $y1 $x2 $y2 $w
  311. }
  312. # Place the hint frame to indicate the changes
  313. #
  314. proc tixResizeHandle:SetHintFrame {w x1 y1 width height} {
  315. upvar #0 $w data
  316. # The four sides of the window
  317. #
  318. set x2 [expr "$x1+$width"]
  319. set y2 [expr "$y1+$height"]
  320. set rx [winfo rootx [winfo parent $w]]
  321. set ry [winfo rooty [winfo parent $w]]
  322. incr x1 $rx
  323. incr y1 $ry
  324. incr x2 $rx
  325. incr y2 $ry
  326. if {[info exists data(hf:x1)]} {
  327. tixResizeHandle:DrawTmpLines $w
  328. }
  329. set data(hf:x1) $x1
  330. set data(hf:y1) $y1
  331. set data(hf:x2) $x2
  332. set data(hf:y2) $y2
  333. tixResizeHandle:DrawTmpLines $w
  334. }
  335. proc tixResizeHandle:ShowHintFrame {w} {
  336. upvar #0 $w data
  337. place forget $data(w_ht)
  338. place forget $data(w_hb)
  339. place forget $data(w_hl)
  340. place forget $data(w_hr)
  341. update
  342. }
  343. proc tixResizeHandle:HideHintFrame {w} {
  344. upvar #0 $w data
  345. tixResizeHandle:DrawTmpLines $w
  346. unset data(hf:x1)
  347. unset data(hf:y1)
  348. unset data(hf:x2)
  349. unset data(hf:y2)
  350. }
  351. proc tixResizeHandle:UpdateSize {w x y width height} {
  352. upvar #0 $w data
  353. set data(-x) $x
  354. set data(-y) $y
  355. set data(-width) $width
  356. set data(-height) $height
  357. tixResizeHandle:ComposeWindow $w
  358. if {$data(widget) != ""} {
  359. place $data(widget) -x $x -y $y -width $width -height $height
  360. }
  361. if {$data(-command) != ""} {
  362. eval $data(-command) $x $y $width $height
  363. }
  364. }
  365. proc tixResizeHandle:ComposeWindow {w} {
  366. upvar #0 $w data
  367. set px $data(-x)
  368. set py $data(-y)
  369. set pw $data(-width)
  370. set ph $data(-height)
  371. # Show the hint frames
  372. #
  373. set x1 $px
  374. set y1 $py
  375. set x2 [expr "$px+$pw"]
  376. set y2 [expr "$py+$ph"]
  377. place $data(w_ht) -x $x1 -y $y1 -width $pw -bordermode outside
  378. place $data(w_hb) -x $x1 -y $y2 -width $pw -bordermode outside
  379. place $data(w_hl) -x $x1 -y $y1 -height $ph -bordermode outside
  380. place $data(w_hr) -x $x2 -y $y1 -height $ph -bordermode outside
  381. # Set the four corner resize handles
  382. #
  383. set sz_2 [expr $data(-handlesize)/2]
  384. set x1 [expr "$px - $sz_2"]
  385. set y1 [expr "$py - $sz_2"]
  386. set x2 [expr "$px - $sz_2" + $pw]
  387. set y2 [expr "$py - $sz_2" + $ph]
  388. place $data(w_r00) -x $x1 -y $y1 \
  389. -width $data(-handlesize) -height $data(-handlesize)
  390. place $data(w_r01) -x $x1 -y $y2\
  391. -width $data(-handlesize) -height $data(-handlesize)
  392. place $data(w_r10) -x $x2 -y $y1\
  393. -width $data(-handlesize) -height $data(-handlesize)
  394. place $data(w_r11) -x $x2 -y $y2\
  395. -width $data(-handlesize) -height $data(-handlesize)
  396. # Set the four border resize handles
  397. #
  398. set mx [expr "$px + $pw/2 - $sz_2"]
  399. set my [expr "$py + $ph/2 - $sz_2"]
  400. place $data(w_bt) -x $mx -y $y1 \
  401. -width $data(-handlesize) -height $data(-handlesize)
  402. place $data(w_bb) -x $mx -y $y2 \
  403. -width $data(-handlesize) -height $data(-handlesize)
  404. place $data(w_bl) -x $x1 -y $my \
  405. -width $data(-handlesize) -height $data(-handlesize)
  406. place $data(w_br) -x $x2 -y $my \
  407. -width $data(-handlesize) -height $data(-handlesize)
  408. }