PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/02-development/uDrawGraph-3.1/lib/BWidget-1.7.0/arrow.tcl

https://bitbucket.org/jmelo_lyncode/thesis
TCL | 552 lines | 428 code | 50 blank | 74 comment | 125 complexity | 3d1cb870356ed9f5291e978ca50216a7 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-3.0
  1. # ------------------------------------------------------------------------------
  2. # arrow.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # ------------------------------------------------------------------------------
  5. # Index of commands:
  6. # Public commands
  7. # - ArrowButton::create
  8. # - ArrowButton::configure
  9. # - ArrowButton::cget
  10. # - ArrowButton::invoke
  11. # Private commands (redraw commands)
  12. # - ArrowButton::_redraw
  13. # - ArrowButton::_redraw_state
  14. # - ArrowButton::_redraw_relief
  15. # - ArrowButton::_redraw_whole
  16. # Private commands (event bindings)
  17. # - ArrowButton::_destroy
  18. # - ArrowButton::_enter
  19. # - ArrowButton::_leave
  20. # - ArrowButton::_press
  21. # - ArrowButton::_release
  22. # - ArrowButton::_repeat
  23. # ------------------------------------------------------------------------------
  24. namespace eval ArrowButton {
  25. Widget::define ArrowButton arrow DynamicHelp
  26. Widget::tkinclude ArrowButton button .c \
  27. include [list \
  28. -borderwidth -bd \
  29. -relief -highlightbackground \
  30. -highlightcolor -highlightthickness -takefocus]
  31. Widget::declare ArrowButton [list \
  32. [list -type Enum button 0 [list arrow button]] \
  33. [list -dir Enum top 0 [list top bottom left right]] \
  34. [list -width Int 15 0 "%d >= 0"] \
  35. [list -height Int 15 0 "%d >= 0"] \
  36. [list -ipadx Int 0 0 "%d >= 0"] \
  37. [list -ipady Int 0 0 "%d >= 0"] \
  38. [list -clean Int 2 0 "%d >= 0 && %d <= 2"] \
  39. [list -activeforeground TkResource "" 0 button] \
  40. [list -activebackground TkResource "" 0 button] \
  41. [list -disabledforeground TkResource "" 0 button] \
  42. [list -foreground TkResource "" 0 button] \
  43. [list -background TkResource "" 0 button] \
  44. [list -state TkResource "" 0 button] \
  45. [list -troughcolor TkResource "" 0 scrollbar] \
  46. [list -arrowbd Int 1 0 "%d >= 0 && %d <= 2"] \
  47. [list -arrowrelief Enum raised 0 [list raised sunken]] \
  48. [list -command String "" 0] \
  49. [list -armcommand String "" 0] \
  50. [list -disarmcommand String "" 0] \
  51. [list -repeatdelay Int 0 0 "%d >= 0"] \
  52. [list -repeatinterval Int 0 0 "%d >= 0"] \
  53. [list -fg Synonym -foreground] \
  54. [list -bg Synonym -background] \
  55. ]
  56. DynamicHelp::include ArrowButton balloon
  57. bind BwArrowButtonC <Enter> {ArrowButton::_enter %W}
  58. bind BwArrowButtonC <Leave> {ArrowButton::_leave %W}
  59. bind BwArrowButtonC <ButtonPress-1> {ArrowButton::_press %W}
  60. bind BwArrowButtonC <ButtonRelease-1> {ArrowButton::_release %W}
  61. bind BwArrowButtonC <Key-space> {ArrowButton::invoke %W; break}
  62. bind BwArrowButtonC <Return> {ArrowButton::invoke %W; break}
  63. bind BwArrowButton <Configure> {ArrowButton::_redraw_whole %W %w %h}
  64. bind BwArrowButton <Destroy> {ArrowButton::_destroy %W}
  65. variable _grab
  66. variable _moved
  67. array set _grab {current "" pressed "" oldstate "" oldrelief ""}
  68. }
  69. # -----------------------------------------------------------------------------
  70. # Command ArrowButton::create
  71. # -----------------------------------------------------------------------------
  72. proc ArrowButton::create { path args } {
  73. # Initialize configuration mappings and parse arguments
  74. array set submaps [list ArrowButton [list ] .c [list ]]
  75. array set submaps [Widget::parseArgs ArrowButton $args]
  76. # Create the class frame (so we can do the option db queries)
  77. frame $path -class ArrowButton -borderwidth 0 -highlightthickness 0
  78. Widget::initFromODB ArrowButton $path $submaps(ArrowButton)
  79. # Create the canvas with the initial options
  80. eval canvas $path.c $submaps(.c)
  81. # Compute the width and height of the canvas from the width/height
  82. # of the ArrowButton and the borderwidth/hightlightthickness.
  83. set w [Widget::getMegawidgetOption $path -width]
  84. set h [Widget::getMegawidgetOption $path -height]
  85. set bd [Widget::cget $path -borderwidth]
  86. set ht [Widget::cget $path -highlightthickness]
  87. set pad [expr {2*($bd+$ht)}]
  88. $path.c configure -width [expr {$w-$pad}] -height [expr {$h-$pad}]
  89. bindtags $path [list $path BwArrowButton [winfo toplevel $path] all]
  90. bindtags $path.c [list $path.c BwArrowButtonC [winfo toplevel $path.c] all]
  91. pack $path.c -expand yes -fill both
  92. DynamicHelp::sethelp $path $path.c 1
  93. set ::ArrowButton::_moved($path) 0
  94. return [Widget::create ArrowButton $path]
  95. }
  96. # -----------------------------------------------------------------------------
  97. # Command ArrowButton::configure
  98. # -----------------------------------------------------------------------------
  99. proc ArrowButton::configure { path args } {
  100. set res [Widget::configure $path $args]
  101. set ch1 [expr {[Widget::hasChanged $path -width w] |
  102. [Widget::hasChanged $path -height h] |
  103. [Widget::hasChanged $path -borderwidth bd] |
  104. [Widget::hasChanged $path -highlightthickness ht]}]
  105. set ch2 [expr {[Widget::hasChanged $path -type val] |
  106. [Widget::hasChanged $path -ipadx val] |
  107. [Widget::hasChanged $path -ipady val] |
  108. [Widget::hasChanged $path -arrowbd val] |
  109. [Widget::hasChanged $path -clean val] |
  110. [Widget::hasChanged $path -dir val]}]
  111. if { $ch1 } {
  112. set pad [expr {2*($bd+$ht)}]
  113. $path.c configure \
  114. -width [expr {$w-$pad}] -height [expr {$h-$pad}] \
  115. -borderwidth $bd -highlightthickness $ht
  116. set ch2 1
  117. }
  118. if { $ch2 } {
  119. _redraw_whole $path [winfo width $path] [winfo height $path]
  120. } else {
  121. _redraw_relief $path
  122. _redraw_state $path
  123. }
  124. DynamicHelp::sethelp $path $path.c
  125. return $res
  126. }
  127. # -----------------------------------------------------------------------------
  128. # Command ArrowButton::cget
  129. # -----------------------------------------------------------------------------
  130. proc ArrowButton::cget { path option } {
  131. return [Widget::cget $path $option]
  132. }
  133. # ------------------------------------------------------------------------------
  134. # Command ArrowButton::invoke
  135. # ------------------------------------------------------------------------------
  136. proc ArrowButton::invoke { path } {
  137. if { ![string equal [winfo class $path] "ArrowButton"] } {
  138. set path [winfo parent $path]
  139. }
  140. if { ![string equal [Widget::getoption $path -state] "disabled"] } {
  141. set oldstate [Widget::getoption $path -state]
  142. if { [string equal [Widget::getoption $path -type] "button"] } {
  143. set oldrelief [Widget::getoption $path -relief]
  144. configure $path -state active -relief sunken
  145. } else {
  146. set oldrelief [Widget::getoption $path -arrowrelief]
  147. configure $path -state active -arrowrelief sunken
  148. }
  149. update idletasks
  150. if { [set cmd [Widget::getoption $path -armcommand]] != "" } {
  151. uplevel \#0 $cmd
  152. }
  153. after 10
  154. if { [string equal [Widget::getoption $path -type] "button"] } {
  155. configure $path -state $oldstate -relief $oldrelief
  156. } else {
  157. configure $path -state $oldstate -arrowrelief $oldrelief
  158. }
  159. if { [set cmd [Widget::getoption $path -disarmcommand]] != "" } {
  160. uplevel \#0 $cmd
  161. }
  162. if { [set cmd [Widget::getoption $path -command]] != "" } {
  163. uplevel \#0 $cmd
  164. }
  165. }
  166. }
  167. # ------------------------------------------------------------------------------
  168. # Command ArrowButton::_redraw
  169. # ------------------------------------------------------------------------------
  170. proc ArrowButton::_redraw { path width height } {
  171. variable _moved
  172. set _moved($path) 0
  173. set type [Widget::getoption $path -type]
  174. set dir [Widget::getoption $path -dir]
  175. set bd [expr {[$path.c cget -borderwidth] + [$path.c cget -highlightthickness] + 1}]
  176. set clean [Widget::getoption $path -clean]
  177. if { [string equal $type "arrow"] } {
  178. if { [set id [$path.c find withtag rect]] == "" } {
  179. $path.c create rectangle $bd $bd [expr {$width-$bd-1}] [expr {$height-$bd-1}] -tags rect
  180. } else {
  181. $path.c coords $id $bd $bd [expr {$width-$bd-1}] [expr {$height-$bd-1}]
  182. }
  183. $path.c lower rect
  184. set arrbd [Widget::getoption $path -arrowbd]
  185. set bd [expr {$bd+$arrbd-1}]
  186. } else {
  187. $path.c delete rect
  188. }
  189. # w and h are max width and max height of arrow
  190. set w [expr {$width - 2*([Widget::getoption $path -ipadx]+$bd)}]
  191. set h [expr {$height - 2*([Widget::getoption $path -ipady]+$bd)}]
  192. if { $w < 2 } {set w 2}
  193. if { $h < 2 } {set h 2}
  194. if { $clean > 0 } {
  195. # arrange for base to be odd
  196. if { [string equal $dir "top"] ||
  197. [string equal $dir "bottom"] } {
  198. if { !($w % 2) } {
  199. incr w -1
  200. }
  201. if { $clean == 2 } {
  202. # arrange for h = (w+1)/2
  203. set h2 [expr {($w+1)/2}]
  204. if { $h2 > $h } {
  205. set w [expr {2*$h-1}]
  206. } else {
  207. set h $h2
  208. }
  209. }
  210. } else {
  211. if { !($h % 2) } {
  212. incr h -1
  213. }
  214. if { $clean == 2 } {
  215. # arrange for w = (h+1)/2
  216. set w2 [expr {($h+1)/2}]
  217. if { $w2 > $w } {
  218. set h [expr {2*$w-1}]
  219. } else {
  220. set w $w2
  221. }
  222. }
  223. }
  224. }
  225. set x0 [expr {($width-$w)/2}]
  226. set y0 [expr {($height-$h)/2}]
  227. set x1 [expr {$x0+$w-1}]
  228. set y1 [expr {$y0+$h-1}]
  229. switch $dir {
  230. top {
  231. set xd [expr {($x0+$x1)/2}]
  232. if { [set id [$path.c find withtag poly]] == "" } {
  233. $path.c create polygon $x0 $y1 $x1 $y1 $xd $y0 -tags poly
  234. } else {
  235. $path.c coords $id $x0 $y1 $x1 $y1 $xd $y0
  236. }
  237. if { [string equal $type "arrow"] } {
  238. if { [set id [$path.c find withtag bot]] == "" } {
  239. $path.c create line $x0 $y1 $x1 $y1 $xd $y0 -tags bot
  240. } else {
  241. $path.c coords $id $x0 $y1 $x1 $y1 $xd $y0
  242. }
  243. if { [set id [$path.c find withtag top]] == "" } {
  244. $path.c create line $x0 $y1 $xd $y0 -tags top
  245. } else {
  246. $path.c coords $id $x0 $y1 $xd $y0
  247. }
  248. $path.c itemconfigure top -width $arrbd
  249. $path.c itemconfigure bot -width $arrbd
  250. } else {
  251. $path.c delete top
  252. $path.c delete bot
  253. }
  254. }
  255. bottom {
  256. set xd [expr {($x0+$x1)/2}]
  257. if { [set id [$path.c find withtag poly]] == "" } {
  258. $path.c create polygon $x1 $y0 $x0 $y0 $xd $y1 -tags poly
  259. } else {
  260. $path.c coords $id $x1 $y0 $x0 $y0 $xd $y1
  261. }
  262. if { [string equal $type "arrow"] } {
  263. if { [set id [$path.c find withtag top]] == "" } {
  264. $path.c create line $x1 $y0 $x0 $y0 $xd $y1 -tags top
  265. } else {
  266. $path.c coords $id $x1 $y0 $x0 $y0 $xd $y1
  267. }
  268. if { [set id [$path.c find withtag bot]] == "" } {
  269. $path.c create line $x1 $y0 $xd $y1 -tags bot
  270. } else {
  271. $path.c coords $id $x1 $y0 $xd $y1
  272. }
  273. $path.c itemconfigure top -width $arrbd
  274. $path.c itemconfigure bot -width $arrbd
  275. } else {
  276. $path.c delete top
  277. $path.c delete bot
  278. }
  279. }
  280. left {
  281. set yd [expr {($y0+$y1)/2}]
  282. if { [set id [$path.c find withtag poly]] == "" } {
  283. $path.c create polygon $x1 $y0 $x1 $y1 $x0 $yd -tags poly
  284. } else {
  285. $path.c coords $id $x1 $y0 $x1 $y1 $x0 $yd
  286. }
  287. if { [string equal $type "arrow"] } {
  288. if { [set id [$path.c find withtag bot]] == "" } {
  289. $path.c create line $x1 $y0 $x1 $y1 $x0 $yd -tags bot
  290. } else {
  291. $path.c coords $id $x1 $y0 $x1 $y1 $x0 $yd
  292. }
  293. if { [set id [$path.c find withtag top]] == "" } {
  294. $path.c create line $x1 $y0 $x0 $yd -tags top
  295. } else {
  296. $path.c coords $id $x1 $y0 $x0 $yd
  297. }
  298. $path.c itemconfigure top -width $arrbd
  299. $path.c itemconfigure bot -width $arrbd
  300. } else {
  301. $path.c delete top
  302. $path.c delete bot
  303. }
  304. }
  305. right {
  306. set yd [expr {($y0+$y1)/2}]
  307. if { [set id [$path.c find withtag poly]] == "" } {
  308. $path.c create polygon $x0 $y1 $x0 $y0 $x1 $yd -tags poly
  309. } else {
  310. $path.c coords $id $x0 $y1 $x0 $y0 $x1 $yd
  311. }
  312. if { [string equal $type "arrow"] } {
  313. if { [set id [$path.c find withtag top]] == "" } {
  314. $path.c create line $x0 $y1 $x0 $y0 $x1 $yd -tags top
  315. } else {
  316. $path.c coords $id $x0 $y1 $x0 $y0 $x1 $yd
  317. }
  318. if { [set id [$path.c find withtag bot]] == "" } {
  319. $path.c create line $x0 $y1 $x1 $yd -tags bot
  320. } else {
  321. $path.c coords $id $x0 $y1 $x1 $yd
  322. }
  323. $path.c itemconfigure top -width $arrbd
  324. $path.c itemconfigure bot -width $arrbd
  325. } else {
  326. $path.c delete top
  327. $path.c delete bot
  328. }
  329. }
  330. }
  331. }
  332. # ------------------------------------------------------------------------------
  333. # Command ArrowButton::_redraw_state
  334. # ------------------------------------------------------------------------------
  335. proc ArrowButton::_redraw_state { path } {
  336. set state [Widget::getoption $path -state]
  337. if { [string equal [Widget::getoption $path -type] "button"] } {
  338. switch $state {
  339. normal {set bg -background; set fg -foreground}
  340. active {set bg -activebackground; set fg -activeforeground}
  341. disabled {set bg -background; set fg -disabledforeground}
  342. }
  343. set fg [Widget::getoption $path $fg]
  344. $path.c configure -background [Widget::getoption $path $bg]
  345. $path.c itemconfigure poly -fill $fg -outline $fg
  346. } else {
  347. switch $state {
  348. normal {set stipple ""; set bg [Widget::getoption $path -background] }
  349. active {set stipple ""; set bg [Widget::getoption $path -activebackground] }
  350. disabled {set stipple gray50; set bg black }
  351. }
  352. set thrc [Widget::getoption $path -troughcolor]
  353. $path.c configure -background [Widget::getoption $path -background]
  354. $path.c itemconfigure rect -fill $thrc -outline $thrc
  355. $path.c itemconfigure poly -fill $bg -outline $bg -stipple $stipple
  356. }
  357. }
  358. # ------------------------------------------------------------------------------
  359. # Command ArrowButton::_redraw_relief
  360. # ------------------------------------------------------------------------------
  361. proc ArrowButton::_redraw_relief { path } {
  362. variable _moved
  363. if { [string equal [Widget::getoption $path -type] "button"] } {
  364. if { [string equal [Widget::getoption $path -relief] "sunken"] } {
  365. if { !$_moved($path) } {
  366. $path.c move poly 1 1
  367. set _moved($path) 1
  368. }
  369. } else {
  370. if { $_moved($path) } {
  371. $path.c move poly -1 -1
  372. set _moved($path) 0
  373. }
  374. }
  375. } else {
  376. set col3d [BWidget::get3dcolor $path [Widget::getoption $path -background]]
  377. switch [Widget::getoption $path -arrowrelief] {
  378. raised {set top [lindex $col3d 1]; set bot [lindex $col3d 0]}
  379. sunken {set top [lindex $col3d 0]; set bot [lindex $col3d 1]}
  380. }
  381. $path.c itemconfigure top -fill $top
  382. $path.c itemconfigure bot -fill $bot
  383. }
  384. }
  385. # ------------------------------------------------------------------------------
  386. # Command ArrowButton::_redraw_whole
  387. # ------------------------------------------------------------------------------
  388. proc ArrowButton::_redraw_whole { path width height } {
  389. _redraw $path $width $height
  390. _redraw_relief $path
  391. _redraw_state $path
  392. }
  393. # ------------------------------------------------------------------------------
  394. # Command ArrowButton::_enter
  395. # ------------------------------------------------------------------------------
  396. proc ArrowButton::_enter { path } {
  397. variable _grab
  398. set path [winfo parent $path]
  399. set _grab(current) $path
  400. if { ![string equal [Widget::getoption $path -state] "disabled"] } {
  401. set _grab(oldstate) [Widget::getoption $path -state]
  402. configure $path -state active
  403. if { $_grab(pressed) == $path } {
  404. if { [string equal [Widget::getoption $path -type] "button"] } {
  405. set _grab(oldrelief) [Widget::getoption $path -relief]
  406. configure $path -relief sunken
  407. } else {
  408. set _grab(oldrelief) [Widget::getoption $path -arrowrelief]
  409. configure $path -arrowrelief sunken
  410. }
  411. }
  412. }
  413. }
  414. # ------------------------------------------------------------------------------
  415. # Command ArrowButton::_leave
  416. # ------------------------------------------------------------------------------
  417. proc ArrowButton::_leave { path } {
  418. variable _grab
  419. set path [winfo parent $path]
  420. set _grab(current) ""
  421. if { ![string equal [Widget::getoption $path -state] "disabled"] } {
  422. configure $path -state $_grab(oldstate)
  423. if { $_grab(pressed) == $path } {
  424. if { [string equal [Widget::getoption $path -type] "button"] } {
  425. configure $path -relief $_grab(oldrelief)
  426. } else {
  427. configure $path -arrowrelief $_grab(oldrelief)
  428. }
  429. }
  430. }
  431. }
  432. # ------------------------------------------------------------------------------
  433. # Command ArrowButton::_press
  434. # ------------------------------------------------------------------------------
  435. proc ArrowButton::_press { path } {
  436. variable _grab
  437. set path [winfo parent $path]
  438. if { ![string equal [Widget::getoption $path -state] "disabled"] } {
  439. set _grab(pressed) $path
  440. if { [string equal [Widget::getoption $path -type] "button"] } {
  441. set _grab(oldrelief) [Widget::getoption $path -relief]
  442. configure $path -relief sunken
  443. } else {
  444. set _grab(oldrelief) [Widget::getoption $path -arrowrelief]
  445. configure $path -arrowrelief sunken
  446. }
  447. if { [set cmd [Widget::getoption $path -armcommand]] != "" } {
  448. uplevel \#0 $cmd
  449. if { [set delay [Widget::getoption $path -repeatdelay]] > 0 ||
  450. [set delay [Widget::getoption $path -repeatinterval]] > 0 } {
  451. after $delay "ArrowButton::_repeat $path"
  452. }
  453. }
  454. }
  455. }
  456. # ------------------------------------------------------------------------------
  457. # Command ArrowButton::_release
  458. # ------------------------------------------------------------------------------
  459. proc ArrowButton::_release { path } {
  460. variable _grab
  461. set path [winfo parent $path]
  462. if { $_grab(pressed) == $path } {
  463. set _grab(pressed) ""
  464. if { [string equal [Widget::getoption $path -type] "button"] } {
  465. configure $path -relief $_grab(oldrelief)
  466. } else {
  467. configure $path -arrowrelief $_grab(oldrelief)
  468. }
  469. if { [set cmd [Widget::getoption $path -disarmcommand]] != "" } {
  470. uplevel \#0 $cmd
  471. }
  472. if { $_grab(current) == $path &&
  473. ![string equal [Widget::getoption $path -state] "disabled"] &&
  474. [set cmd [Widget::getoption $path -command]] != "" } {
  475. uplevel \#0 $cmd
  476. }
  477. }
  478. }
  479. # ------------------------------------------------------------------------------
  480. # Command ArrowButton::_repeat
  481. # ------------------------------------------------------------------------------
  482. proc ArrowButton::_repeat { path } {
  483. variable _grab
  484. if { $_grab(current) == $path && $_grab(pressed) == $path &&
  485. ![string equal [Widget::getoption $path -state] "disabled"] &&
  486. [set cmd [Widget::getoption $path -armcommand]] != "" } {
  487. uplevel \#0 $cmd
  488. }
  489. if { $_grab(pressed) == $path &&
  490. ([set delay [Widget::getoption $path -repeatinterval]] > 0 ||
  491. [set delay [Widget::getoption $path -repeatdelay]] > 0) } {
  492. after $delay "ArrowButton::_repeat $path"
  493. }
  494. }
  495. # ------------------------------------------------------------------------------
  496. # Command ArrowButton::_destroy
  497. # ------------------------------------------------------------------------------
  498. proc ArrowButton::_destroy { path } {
  499. variable _moved
  500. Widget::destroy $path
  501. unset _moved($path)
  502. }