buttonbox.tcl 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # ------------------------------------------------------------------------------
  2. # buttonbox.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # ------------------------------------------------------------------------------
  5. # Index of commands:
  6. # - ButtonBox::create
  7. # - ButtonBox::configure
  8. # - ButtonBox::cget
  9. # - ButtonBox::add
  10. # - ButtonBox::itemconfigure
  11. # - ButtonBox::itemcget
  12. # - ButtonBox::setfocus
  13. # - ButtonBox::invoke
  14. # - ButtonBox::index
  15. # - ButtonBox::_destroy
  16. # ------------------------------------------------------------------------------
  17. namespace eval ButtonBox {
  18. Button::use
  19. Widget::declare ButtonBox {
  20. {-background TkResource "" 0 frame}
  21. {-orient Enum horizontal 1 {horizontal vertical}}
  22. {-homogeneous Boolean 1 1}
  23. {-spacing Int 10 0 {=0}}
  24. {-padx TkResource "" 0 button}
  25. {-pady TkResource "" 0 button}
  26. {-default Int -1 0 {=-1}}
  27. {-bg Synonym -background}
  28. }
  29. Widget::addmap ButtonBox "" :cmd {-background {}}
  30. proc ::ButtonBox { path args } { return [eval ButtonBox::create $path $args] }
  31. proc use {} {}
  32. }
  33. # ------------------------------------------------------------------------------
  34. # Command ButtonBox::create
  35. # ------------------------------------------------------------------------------
  36. proc ButtonBox::create { path args } {
  37. Widget::init ButtonBox $path $args
  38. variable $path
  39. upvar 0 $path data
  40. eval frame $path [Widget::subcget $path :cmd] -takefocus 0 -highlightthickness 0
  41. set data(default) [Widget::getoption $path -default]
  42. set data(nbuttons) 0
  43. set data(max) 0
  44. bind $path <Destroy> "ButtonBox::_destroy $path"
  45. rename $path ::$path:cmd
  46. proc ::$path { cmd args } "return \[eval ButtonBox::\$cmd $path \$args\]"
  47. return $path
  48. }
  49. # ------------------------------------------------------------------------------
  50. # Command ButtonBox::configure
  51. # ------------------------------------------------------------------------------
  52. proc ButtonBox::configure { path args } {
  53. variable $path
  54. upvar 0 $path data
  55. set res [Widget::configure $path $args]
  56. if { [Widget::hasChanged $path -default val] } {
  57. if { $data(default) != -1 && $val != -1 } {
  58. set but $path.b$data(default)
  59. if { [winfo exists $but] } {
  60. $but configure -default normal
  61. }
  62. set but $path.b$val
  63. if { [winfo exists $but] } {
  64. $but configure -default active
  65. }
  66. set data(default) $val
  67. } else {
  68. Widget::setoption $path -default $data(default)
  69. }
  70. }
  71. return $res
  72. }
  73. # ------------------------------------------------------------------------------
  74. # Command ButtonBox::cget
  75. # ------------------------------------------------------------------------------
  76. proc ButtonBox::cget { path option } {
  77. return [Widget::cget $path $option]
  78. }
  79. # ------------------------------------------------------------------------------
  80. # Command ButtonBox::add
  81. # ------------------------------------------------------------------------------
  82. proc ButtonBox::add { path args } {
  83. variable $path
  84. upvar 0 $path data
  85. set but $path.b$data(nbuttons)
  86. set spacing [Widget::getoption $path -spacing]
  87. if { $data(nbuttons) == $data(default) } {
  88. set style active
  89. } elseif { $data(default) == -1 } {
  90. set style disabled
  91. } else {
  92. set style normal
  93. }
  94. eval Button::create $but \
  95. -background [Widget::getoption $path -background]\
  96. -padx [Widget::getoption $path -padx] \
  97. -pady [Widget::getoption $path -pady] \
  98. $args \
  99. -default $style
  100. set idx [expr {2*$data(nbuttons)}]
  101. if { ![string compare [Widget::getoption $path -orient] "horizontal"] } {
  102. grid $but -column $idx -row 0 -sticky nsew
  103. if { [Widget::getoption $path -homogeneous] } {
  104. set req [winfo reqwidth $but]
  105. if { $req > $data(max) } {
  106. for {set i 0} {$i < $data(nbuttons)} {incr i} {
  107. grid columnconfigure $path [expr {2*$i}] -minsize $req
  108. }
  109. set data(max) $req
  110. }
  111. grid columnconfigure $path $idx -minsize $data(max) -weight 1
  112. } else {
  113. grid columnconfigure $path $idx -weight 0
  114. }
  115. if { $data(nbuttons) > 0 } {
  116. grid columnconfigure $path [expr {$idx-1}] -minsize $spacing
  117. }
  118. } else {
  119. grid $but -column 0 -row $idx -sticky nsew
  120. grid rowconfigure $path $idx -weight 0
  121. if { $data(nbuttons) > 0 } {
  122. grid rowconfigure $path [expr {$idx-1}] -minsize $spacing
  123. }
  124. }
  125. incr data(nbuttons)
  126. return $but
  127. }
  128. # ------------------------------------------------------------------------------
  129. # Command ButtonBox::itemconfigure
  130. # ------------------------------------------------------------------------------
  131. proc ButtonBox::itemconfigure { path index args } {
  132. if { [set idx [lsearch $args -default]] != -1 } {
  133. set args [lreplace $args $idx [expr {$idx+1}]]
  134. }
  135. return [eval Button::configure $path.b[index $path $index] $args]
  136. }
  137. # ------------------------------------------------------------------------------
  138. # Command ButtonBox::itemcget
  139. # ------------------------------------------------------------------------------
  140. proc ButtonBox::itemcget { path index option } {
  141. return [Button::cget $path.b[index $path $index] $option]
  142. }
  143. # ------------------------------------------------------------------------------
  144. # Command ButtonBox::setfocus
  145. # ------------------------------------------------------------------------------
  146. proc ButtonBox::setfocus { path index } {
  147. set but $path.b[index $path $index]
  148. if { [winfo exists $but] } {
  149. focus $but
  150. }
  151. }
  152. # ------------------------------------------------------------------------------
  153. # Command ButtonBox::invoke
  154. # ------------------------------------------------------------------------------
  155. proc ButtonBox::invoke { path index } {
  156. set but $path.b[index $path $index]
  157. if { [winfo exists $but] } {
  158. Button::invoke $but
  159. }
  160. }
  161. # ------------------------------------------------------------------------------
  162. # Command ButtonBox::index
  163. # ------------------------------------------------------------------------------
  164. proc ButtonBox::index { path index } {
  165. if { ![string compare $index "default"] } {
  166. set res [Widget::getoption $path -default]
  167. } elseif { ![string compare $index "end"] || ![string compare $index "last"] } {
  168. variable $path
  169. upvar 0 $path data
  170. set res [expr {$data(nbuttons)-1}]
  171. } else {
  172. set res $index
  173. }
  174. return $res
  175. }
  176. # ------------------------------------------------------------------------------
  177. # Command ButtonBox::_destroy
  178. # ------------------------------------------------------------------------------
  179. proc ButtonBox::_destroy { path } {
  180. variable $path
  181. upvar 0 $path data
  182. Widget::destroy $path
  183. unset data
  184. rename $path {}
  185. }