color.tcl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. # ------------------------------------------------------------------------------
  2. # color.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # ------------------------------------------------------------------------------
  5. # Index of commands:
  6. # - SelectColor::create
  7. # - SelectColor::setcolor
  8. # - SelectColor::_destroy
  9. # - SelectColor::_update_var
  10. # - SelectColor::_post_menu
  11. # - SelectColor::_tk_choose_color
  12. # - SelectColor::_activate
  13. # ------------------------------------------------------------------------------
  14. namespace eval SelectColor {
  15. Widget::declare SelectColor {
  16. {-title String "" 0}
  17. {-parent String "" 0}
  18. {-type Enum dialog 1 {dialog menubutton}}
  19. {-command String "" 0}
  20. {-color TkResource "" 0 {label -background}}
  21. {-variable String "" 0}
  22. {-width TkResource 15 0 frame}
  23. {-height TkResource 15 0 frame}
  24. }
  25. Widget::addmap SelectColor "" :cmd {-width {} -height {}}
  26. Widget::syncoptions SelectColor "" :cmd {-color -background}
  27. variable _tabcolors {
  28. \#0000ff \#000099 \#000000 white
  29. \#00ff00 \#009900 \#333333 white
  30. \#00ffff \#009999 \#666666 white
  31. \#ff0000 \#990000 \#999999 white
  32. \#ff00ff \#990099 \#cccccc white
  33. \#ffff00 \#999900 \#ffffff
  34. }
  35. # bindings
  36. bind SelectColor <ButtonPress-1> {SelectColor::_post_menu %W %X %Y}
  37. bind SelectColor <Destroy> {SelectColor::_destroy %W}
  38. variable _widget
  39. proc ::SelectColor { path args } { return [eval SelectColor::create $path $args] }
  40. proc use {} {}
  41. }
  42. # ------------------------------------------------------------------------------
  43. # Command SelectColor::create
  44. # ------------------------------------------------------------------------------
  45. proc SelectColor::create { path args } {
  46. variable _tabcolors
  47. variable _widget
  48. Widget::init SelectColor $path $args
  49. if { ![string compare [Widget::getoption $path -type] "menubutton"] } {
  50. if { [set var [Widget::getoption $path -variable]] != "" } {
  51. set _widget($path,var) $var
  52. if { [GlobalVar::exists $var] } {
  53. Widget::setoption $path -color [GlobalVar::getvar $var]
  54. } else {
  55. GlobalVar::setvar $var [Widget::getoption $path -color]
  56. }
  57. GlobalVar::tracevar variable $var w "SelectColor::_update_var $path"
  58. } else {
  59. set _widget($path,var) ""
  60. }
  61. eval frame $path [Widget::subcget $path :cmd] \
  62. -background [Widget::getoption $path -color] \
  63. -relief raised -borderwidth 2 -highlightthickness 0
  64. bindtags $path [list $path SelectColor . all]
  65. set _widget($path,idx) 0
  66. rename $path ::$path:cmd
  67. proc ::$path { cmd args } "return \[eval SelectColor::\$cmd $path \$args\]"
  68. } else {
  69. set parent [Widget::getoption $path -parent]
  70. set title [Widget::getoption $path -title]
  71. set lopt [list -initialcolor [Widget::getoption $path -color]]
  72. if { [winfo exists $parent] } {
  73. lappend lopt -parent $parent
  74. }
  75. if { $title != "" } {
  76. lappend lopt -title $title
  77. }
  78. set col [eval tk_chooseColor $lopt]
  79. Widget::destroy $path
  80. return $col
  81. }
  82. return $path
  83. }
  84. # ------------------------------------------------------------------------------
  85. # Command SelectColor::configure
  86. # ------------------------------------------------------------------------------
  87. proc SelectColor::configure { path args } {
  88. variable _widget
  89. set res [Widget::configure $path $args]
  90. if { [Widget::hasChanged $path -variable var] } {
  91. if { [string length $_widget($path,var)] } {
  92. GlobalVar::tracevar vdelete $_widget($path,var) w "SelectColor::_update_var $path"
  93. }
  94. set _widget($path,var) $var
  95. if { [string length $_widget($path,var)] } {
  96. Widget::hasChanged $path -color curval
  97. if { [GlobalVar::exists $_widget($path,var)] } {
  98. Widget::setoption $path -color [set curval [GlobalVar::getvar $_widget($path,var)]]
  99. } else {
  100. GlobalVar::setvar $_widget($path,var) $curval
  101. }
  102. GlobalVar::tracevar variable $_widget($path,var) w "SelectColor::_update_var $path"
  103. $path:cmd configure -background $curval
  104. }
  105. }
  106. if { [Widget::hasChanged $path -color curval] } {
  107. if { [string length $_widget($path,var)] } {
  108. Widget::setoption $path -color [GlobalVar::getvar $_widget($path,var)]
  109. } else {
  110. $path:cmd configure -background $curval
  111. }
  112. }
  113. return $res
  114. }
  115. # ------------------------------------------------------------------------------
  116. # Command SelectColor::cget
  117. # ------------------------------------------------------------------------------
  118. proc SelectColor::cget { path option } {
  119. return [Widget::cget $path $option]
  120. }
  121. # ------------------------------------------------------------------------------
  122. # Command SelectColor::setcolor
  123. # ------------------------------------------------------------------------------
  124. proc SelectColor::setcolor { index color } {
  125. variable _tabcolors
  126. variable _widget
  127. if { $index >= 1 && $index <= 5 } {
  128. set idx [expr {int($idx) * 3}]
  129. set _tabcolors [lreplace $_tabcolors $idx $idx $color]
  130. return 1
  131. }
  132. return 0
  133. }
  134. # ------------------------------------------------------------------------------
  135. # Command SelectColor::_destroy
  136. # ------------------------------------------------------------------------------
  137. proc SelectColor::_destroy { path } {
  138. variable _widget
  139. if { [string length $_widget($path,var)] } {
  140. GlobalVar::tracevar vdelete $_widget($path,var) w "SelectColor::_update_var $path"
  141. }
  142. unset _widget($path,var)
  143. unset _widget($path,idx)
  144. Widget::destroy $path
  145. rename $path {}
  146. }
  147. # ------------------------------------------------------------------------------
  148. # Command SelectColor::_update_var
  149. # ------------------------------------------------------------------------------
  150. proc SelectColor::_update_var { path args } {
  151. variable _tabcolors
  152. variable _widget
  153. set col [GlobalVar::getvar $_widget($path,var)]
  154. $path:cmd configure -background $col
  155. Widget::setoption $path -color $col
  156. set _widget($path,idx) [lsearch $_tabcolors $col]
  157. if { $_widget($path,idx) == -1 } {
  158. set _widget($path,idx) 0
  159. }
  160. }
  161. # ------------------------------------------------------------------------------
  162. # Command SelectColor::_post_menu
  163. # ------------------------------------------------------------------------------
  164. proc SelectColor::_post_menu { path X Y } {
  165. global env
  166. variable _tabcolors
  167. variable _widget
  168. if { [winfo exists $path.menu] } {
  169. if { [string compare [winfo containing $X $Y] $path] } {
  170. BWidget::grab release $path
  171. destroy $path.menu
  172. }
  173. return
  174. }
  175. set top [menu $path.menu]
  176. wm withdraw $top
  177. wm transient $top [winfo toplevel $path]
  178. set col 0
  179. set row 0
  180. set count 0
  181. set frame [frame $top.frame -highlightthickness 0 -relief raised -borderwidth 2]
  182. foreach color $_tabcolors {
  183. set f [frame $frame.c$count \
  184. -relief flat -bd 0 -highlightthickness 1 \
  185. -width 16 -height 16 -background $color]
  186. bind $f <ButtonRelease-1> "SelectColor::_activate $path %W"
  187. bind $f <Enter> {focus %W}
  188. grid $f -column $col -row $row -padx 1 -pady 1
  189. bindtags $f $f
  190. incr row
  191. incr count
  192. if { $row == 4 } {
  193. set row 0
  194. incr col
  195. }
  196. }
  197. set f [label $frame.c$count \
  198. -relief flat -bd 0 -highlightthickness 1 \
  199. -width 16 -height 16 -image [Bitmap::get palette]]
  200. grid $f -column $col -row $row -padx 1 -pady 1
  201. bind $f <ButtonRelease-1> "SelectColor::_tk_choose_color $path"
  202. bind $f <Enter> {focus %W}
  203. pack $frame
  204. BWidget::place $top 0 0 below $path
  205. wm deiconify $top
  206. raise $top
  207. focus $frame
  208. focus $top.frame.c$_widget($path,idx)
  209. BWidget::grab set $path
  210. }
  211. # ------------------------------------------------------------------------------
  212. # Command SelectColor::_tk_choose_color
  213. # ------------------------------------------------------------------------------
  214. proc SelectColor::_tk_choose_color { path } {
  215. variable _tabcolors
  216. variable _widget
  217. BWidget::grab release $path
  218. destroy $path.menu
  219. set parent [Widget::getoption $path -parent]
  220. set title [Widget::getoption $path -title]
  221. set lopt [list -initialcolor [$path:cmd cget -background]]
  222. if { [winfo exists $parent] } {
  223. lappend lopt -parent $parent
  224. }
  225. if { $title != "" } {
  226. lappend lopt -title $title
  227. }
  228. set col [eval tk_chooseColor $lopt]
  229. if { $col != "" } {
  230. if { $_widget($path,idx) % 4 == 3 } {
  231. set idx $_widget($path,idx)
  232. } else {
  233. set idx -1
  234. for {set i 3} {$i < 15} {incr i 4} {
  235. if { [lindex $_tabcolors $i] == "white" } {
  236. set idx $i
  237. break
  238. }
  239. }
  240. }
  241. if { $idx != -1 } {
  242. set _tabcolors [lreplace $_tabcolors $idx $idx $col]
  243. set _widget($path,idx) $idx
  244. }
  245. if { [info exists _widget($path,var)] } {
  246. GlobalVar::setvar $_widget($path,var) $col
  247. }
  248. if { [set cmd [Widget::getoption $path -command]] != "" } {
  249. uplevel \#0 $cmd
  250. }
  251. $path:cmd configure -background $col
  252. }
  253. }
  254. # ------------------------------------------------------------------------------
  255. # Command SelectColor::_activate
  256. # ------------------------------------------------------------------------------
  257. proc SelectColor::_activate { path cell } {
  258. variable _tabcolors
  259. variable _widget
  260. BWidget::grab release $path
  261. set col [$cell cget -background]
  262. destroy $path.menu
  263. if { [string length $_widget($path,var)] } {
  264. GlobalVar::setvar $_widget($path,var) $col
  265. }
  266. Widget::setoption $path -color $col
  267. $path:cmd configure -background $col
  268. if { [set cmd [Widget::getoption $path -command]] != "" } {
  269. uplevel \#0 $cmd
  270. }
  271. set _widget($path,idx) [string range [lindex [split $cell "."] end] 1 end]
  272. }