Select.tcl 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
  2. #
  3. # $Id: Select.tcl,v 1.3 2001/12/09 05:04:02 idiscovery Exp $
  4. #
  5. # Select.tcl --
  6. #
  7. # Implement the tixSelect widget.
  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. tixWidgetClass tixSelect {
  16. -superclass tixLabelWidget
  17. -classname TixSelect
  18. -method {
  19. add button invoke
  20. }
  21. -flag {
  22. -allowzero -buttontype -command -disablecallback -orientation
  23. -orient -padx -pady -radio -selectedbg -state -validatecmd
  24. -value -variable
  25. }
  26. -forcecall {
  27. -variable -state
  28. }
  29. -static {
  30. -allowzero -orientation -padx -pady -radio
  31. }
  32. -configspec {
  33. {-allowzero allowZero AllowZero 0 tixVerifyBoolean}
  34. {-buttontype buttonType ButtonType button}
  35. {-command command Command ""}
  36. {-disablecallback disableCallback DisableCallback 0 tixVerifyBoolean}
  37. {-orientation orientation Orientation horizontal}
  38. {-padx padx Pad 0}
  39. {-pady pady Pad 0}
  40. {-radio radio Radio 0 tixVerifyBoolean}
  41. {-selectedbg selectedBg SelectedBg gray}
  42. {-state state State normal}
  43. {-validatecmd validateCmd ValidateCmd ""}
  44. {-value value Value ""}
  45. {-variable variable Variable ""}
  46. }
  47. -alias {
  48. {-orient -orientation}
  49. }
  50. -default {
  51. {*frame.borderWidth 1}
  52. {*frame.relief sunken}
  53. {*Button.borderWidth 2}
  54. {*Button.highlightThickness 0}
  55. }
  56. }
  57. proc tixSelect:InitWidgetRec {w} {
  58. upvar #0 $w data
  59. tixChainMethod $w InitWidgetRec
  60. set data(items) ""
  61. set data(buttonbg) ""
  62. set data(varInited) 0
  63. }
  64. #----------------------------------------------------------------------
  65. # CONFIG OPTIONS
  66. #----------------------------------------------------------------------
  67. proc tixSelect:config-state {w arg} {
  68. upvar #0 $w data
  69. if {$arg == "disabled"} {
  70. foreach item $data(items) {
  71. $data(w:$item) config -state disabled -relief raised \
  72. -bg $data(buttonbg)
  73. }
  74. if {![info exists data(labelFg)]} {
  75. set data(labelFg) [$data(w:label) cget -foreground]
  76. catch {
  77. $data(w:label) config -fg [tix option get disabled_fg]
  78. }
  79. }
  80. } else {
  81. foreach item $data(items) {
  82. if {[lsearch $data(-value) $item] != -1} {
  83. # This button is selected
  84. #
  85. $data(w:$item) config -relief sunken -bg $data(-selectedbg) \
  86. -state normal
  87. } else {
  88. $data(w:$item) config -relief raised -bg $data(buttonbg) \
  89. -command "$w invoke $item" -state normal
  90. }
  91. }
  92. if {[info exists data(labelFg)]} {
  93. catch {
  94. $data(w:label) config -fg $data(labelFg)
  95. }
  96. unset data(labelFg)
  97. }
  98. }
  99. return ""
  100. }
  101. proc tixSelect:config-variable {w arg} {
  102. upvar #0 $w data
  103. set oldValue $data(-value)
  104. if {[tixVariable:ConfigVariable $w $arg]} {
  105. # The value of data(-value) is changed if tixVariable:ConfigVariable
  106. # returns true
  107. set newValue $data(-value)
  108. set data(-value) $oldValue
  109. tixSelect:config-value $w $newValue
  110. }
  111. catch {
  112. unset data(varInited)
  113. }
  114. set data(-variable) $arg
  115. }
  116. proc tixSelect:config-value {w value} {
  117. upvar #0 $w data
  118. # sanity checking
  119. #
  120. foreach item $value {
  121. if {[lsearch $data(items) $item] == "-1"} {
  122. error "subwidget \"$item\" does not exist"
  123. }
  124. }
  125. tixSelect:SetValue $w $value
  126. }
  127. #----------------------------------------------------------------------
  128. # WIDGET COMMANDS
  129. #----------------------------------------------------------------------
  130. proc tixSelect:add {w name args} {
  131. upvar #0 $w data
  132. set data(w:$name) [eval $data(-buttontype) $data(w:frame).$name -command \
  133. [list "$w invoke $name"] -takefocus 0 $args]
  134. if {$data(-orientation) == "horizontal"} {
  135. pack $data(w:$name) -side left -expand yes -fill y\
  136. -padx $data(-padx) -pady $data(-pady)
  137. } else {
  138. pack $data(w:$name) -side top -expand yes -fill x\
  139. -padx $data(-padx) -pady $data(-pady)
  140. }
  141. if {$data(-state) == "disabled"} {
  142. $data(w:$name) config -relief raised -state disabled
  143. }
  144. # find out the background of the buttons
  145. #
  146. if {$data(buttonbg) == ""} {
  147. set data(buttonbg) [lindex [$data(w:$name) config -background] 4]
  148. }
  149. lappend data(items) $name
  150. }
  151. # Obsolete command
  152. #
  153. proc tixSelect:button {w name args} {
  154. upvar #0 $w data
  155. if {$args != ""} {
  156. return [eval $data(w:$name) $args]
  157. } else {
  158. return $w.$name
  159. }
  160. }
  161. # This is called when a button is invoked
  162. #
  163. proc tixSelect:invoke {w button} {
  164. upvar #0 $w data
  165. if {$data(-state) != "normal"} {
  166. return
  167. }
  168. set newValue $data(-value)
  169. if {[lsearch $data(-value) $button] != -1} {
  170. # This button was selected
  171. #
  172. if {[llength $data(-value)] > 1 || [tixGetBoolean $data(-allowzero)]} {
  173. # Take the button from the selected list
  174. #
  175. set newValue ""
  176. foreach item $data(-value) {
  177. if {$item != $button} {
  178. lappend newValue $item
  179. }
  180. }
  181. }
  182. } else {
  183. # This button was not selected
  184. #
  185. if {[tixGetBoolean $data(-radio)]} {
  186. # The button become the sole item in the list
  187. #
  188. set newValue [list $button]
  189. } else {
  190. # Add this button into the list
  191. #
  192. lappend newValue $button
  193. }
  194. }
  195. if {$newValue != $data(-value)} {
  196. tixSelect:SetValue $w $newValue
  197. }
  198. }
  199. #----------------------------------------------------------------------
  200. # Private functions
  201. #----------------------------------------------------------------------
  202. proc tixSelect:SetValue {w newValue {noUpdate 0}} {
  203. upvar #0 $w data
  204. set oldValue $data(-value)
  205. if {$data(-validatecmd) != ""} {
  206. set data(-value) [tixEvalCmdBinding $w $data(-validatecmd) "" $newValue]
  207. } else {
  208. if {[tixGetBoolean $data(-radio)] && [llength $newValue] > 1} {
  209. error "cannot choose more than one items in a radio box"
  210. }
  211. if {![tixGetBoolean $data(-allowzero)] && [llength $newValue] == 0} {
  212. error "empty selection not allowed"
  213. }
  214. set data(-value) $newValue
  215. }
  216. if {! $noUpdate} {
  217. tixVariable:UpdateVariable $w
  218. }
  219. # Reset all to be unselected
  220. #
  221. foreach item $data(items) {
  222. if {[lsearch $data(-value) $item] == -1} {
  223. # Is unselected
  224. #
  225. if {[lsearch $oldValue $item] != -1} {
  226. # was selected
  227. # -> popup the button, call command
  228. #
  229. $data(w:$item) config -relief raised -bg $data(buttonbg)
  230. tixSelect:CallCommand $w $item 0
  231. }
  232. } else {
  233. # Is selected
  234. #
  235. if {[lsearch $oldValue $item] == -1} {
  236. # was unselected
  237. # -> push down the button, call command
  238. #
  239. $data(w:$item) config -relief sunken -bg $data(-selectedbg)
  240. tixSelect:CallCommand $w $item 1
  241. }
  242. }
  243. }
  244. }
  245. proc tixSelect:CallCommand {w name value} {
  246. upvar #0 $w data
  247. if {!$data(-disablecallback) && $data(-command) != ""} {
  248. if {![info exists data(varInited)]} {
  249. set bind(specs) "name value"
  250. set bind(name) $name
  251. set bind(value) $value
  252. tixEvalCmdBinding $w $data(-command) bind $name $value
  253. }
  254. }
  255. }
  256. proc tixSelect:Destructor {w} {
  257. tixVariable:DeleteVariable $w
  258. # Chain this to the superclass
  259. #
  260. tixChainMethod $w Destructor
  261. }