arcadia 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. data/README +126 -123
  2. data/arcadia.rb +770 -756
  3. data/base/a-contracts.rb +130 -93
  4. data/base/a-ext.rb +280 -280
  5. data/base/a-libs.rb +5 -11
  6. data/base/a-utils.rb +235 -44
  7. data/conf/arcadia.conf +20 -16
  8. data/conf/arcadia.init.rb +0 -0
  9. data/conf/arcadia.res.rb +74 -0
  10. data/ext/ae-complete-code/ae-complete-code.conf +0 -0
  11. data/ext/ae-complete-code/ae-complete-code.rb +80 -79
  12. data/ext/ae-debug/ae-debug.conf +0 -0
  13. data/ext/ae-debug/ae-debug.rb +2 -6
  14. data/ext/ae-debug/debug1.57.rb +0 -0
  15. data/ext/ae-doc-code/ae-doc-code.conf +15 -0
  16. data/ext/ae-doc-code/ae-doc-code.rb +289 -0
  17. data/ext/ae-editor/ae-editor.conf +17 -8
  18. data/ext/ae-editor/ae-editor.rb +738 -396
  19. data/ext/ae-event-log/ae-event-log.conf +0 -0
  20. data/ext/ae-event-log/ae-event-log.rb +0 -0
  21. data/ext/ae-file-history/ae-file-history.conf +2 -2
  22. data/ext/ae-file-history/ae-file-history.rb +286 -290
  23. data/ext/ae-inspector/ae-inspector.conf +0 -0
  24. data/ext/ae-inspector/ae-inspector.rb +0 -0
  25. data/ext/ae-output-event/ae-output-event.conf +2 -2
  26. data/ext/ae-output/ae-output.conf +2 -2
  27. data/ext/ae-output/ae-output.rb +173 -178
  28. data/ext/ae-palette/ae-palette.conf +0 -0
  29. data/ext/ae-palette/ae-palette.rb +0 -0
  30. data/ext/ae-shell/ae-shell.conf +0 -0
  31. data/ext/ae-shell/ae-shell.rb +54 -54
  32. data/lib/tk/al-tk.rb +3076 -3082
  33. data/lib/tk/al-tk.res.rb +0 -0
  34. data/lib/tk/al-tkarcadia.rb +0 -0
  35. data/lib/tk/al-tkcustom.rb +0 -0
  36. data/lib/tkext/al-bwidget.rb +0 -0
  37. data/lib/tkext/al-iwidgets.rb +0 -0
  38. data/lib/tkext/al-tile.rb +0 -0
  39. data/lib/tkext/al-tktable.rb +0 -0
  40. data/tcl/BWidget-1.8.0/BWman/ArrowButton.html +276 -0
  41. data/tcl/BWidget-1.8.0/BWman/BWidget.html +228 -0
  42. data/tcl/BWidget-1.8.0/BWman/Button.html +273 -0
  43. data/tcl/BWidget-1.8.0/BWman/ButtonBox.html +264 -0
  44. data/tcl/BWidget-1.8.0/BWman/ComboBox.html +402 -0
  45. data/tcl/BWidget-1.8.0/BWman/Dialog.html +314 -0
  46. data/tcl/BWidget-1.8.0/BWman/DragSite.html +139 -0
  47. data/tcl/BWidget-1.8.0/BWman/DropSite.html +254 -0
  48. data/tcl/BWidget-1.8.0/BWman/DynamicHelp.html +248 -0
  49. data/tcl/BWidget-1.8.0/BWman/Entry.html +341 -0
  50. data/tcl/BWidget-1.8.0/BWman/Label.html +331 -0
  51. data/tcl/BWidget-1.8.0/BWman/LabelEntry.html +194 -0
  52. data/tcl/BWidget-1.8.0/BWman/LabelFrame.html +144 -0
  53. data/tcl/BWidget-1.8.0/BWman/ListBox.html +678 -0
  54. data/tcl/BWidget-1.8.0/BWman/MainFrame.html +283 -0
  55. data/tcl/BWidget-1.8.0/BWman/MessageDlg.html +218 -0
  56. data/tcl/BWidget-1.8.0/BWman/NoteBook.html +374 -0
  57. data/tcl/BWidget-1.8.0/BWman/PagesManager.html +180 -0
  58. data/tcl/BWidget-1.8.0/BWman/PanedWindow.html +142 -0
  59. data/tcl/BWidget-1.8.0/BWman/PanelFrame.html +153 -0
  60. data/tcl/BWidget-1.8.0/BWman/PasswdDlg.html +214 -0
  61. data/tcl/BWidget-1.8.0/BWman/ProgressBar.html +152 -0
  62. data/tcl/BWidget-1.8.0/BWman/ProgressDlg.html +145 -0
  63. data/tcl/BWidget-1.8.0/BWman/ScrollView.html +130 -0
  64. data/tcl/BWidget-1.8.0/BWman/ScrollableFrame.html +191 -0
  65. data/tcl/BWidget-1.8.0/BWman/ScrolledWindow.html +116 -0
  66. data/tcl/BWidget-1.8.0/BWman/SelectColor.html +164 -0
  67. data/tcl/BWidget-1.8.0/BWman/SelectFont.html +152 -0
  68. data/tcl/BWidget-1.8.0/BWman/Separator.html +77 -0
  69. data/tcl/BWidget-1.8.0/BWman/SpinBox.html +250 -0
  70. data/tcl/BWidget-1.8.0/BWman/StatusBar.html +147 -0
  71. data/tcl/BWidget-1.8.0/BWman/TitleFrame.html +107 -0
  72. data/tcl/BWidget-1.8.0/BWman/Tree.html +947 -0
  73. data/tcl/BWidget-1.8.0/BWman/Widget.html +502 -0
  74. data/tcl/BWidget-1.8.0/BWman/contents.html +84 -0
  75. data/tcl/BWidget-1.8.0/BWman/index.html +7 -0
  76. data/tcl/BWidget-1.8.0/BWman/navtree.html +41 -0
  77. data/tcl/BWidget-1.8.0/BWman/options.htm +458 -0
  78. data/tcl/BWidget-1.8.0/CHANGES.txt +266 -0
  79. data/tcl/BWidget-1.8.0/ChangeLog +1641 -0
  80. data/tcl/BWidget-1.8.0/LICENSE.txt +41 -0
  81. data/tcl/BWidget-1.8.0/README.txt +127 -0
  82. data/tcl/BWidget-1.8.0/arrow.tcl +551 -0
  83. data/tcl/BWidget-1.8.0/bitmap.tcl +94 -0
  84. data/tcl/BWidget-1.8.0/button.tcl +324 -0
  85. data/tcl/BWidget-1.8.0/buttonbox.tcl +403 -0
  86. data/tcl/BWidget-1.8.0/color.tcl +493 -0
  87. data/tcl/BWidget-1.8.0/combobox.tcl +809 -0
  88. data/tcl/BWidget-1.8.0/demo/basic.tcl +199 -0
  89. data/tcl/BWidget-1.8.0/demo/bwidget.xbm +46 -0
  90. data/tcl/BWidget-1.8.0/demo/demo.tcl +212 -0
  91. data/tcl/BWidget-1.8.0/demo/dnd.tcl +42 -0
  92. data/tcl/BWidget-1.8.0/demo/manager.tcl +141 -0
  93. data/tcl/BWidget-1.8.0/demo/select.tcl +59 -0
  94. data/tcl/BWidget-1.8.0/demo/tmpldlg.tcl +214 -0
  95. data/tcl/BWidget-1.8.0/demo/tree.tcl +260 -0
  96. data/tcl/BWidget-1.8.0/demo/x1.xbm +2258 -0
  97. data/tcl/BWidget-1.8.0/dialog.tcl +345 -0
  98. data/tcl/BWidget-1.8.0/dragsite.tcl +197 -0
  99. data/tcl/BWidget-1.8.0/dropsite.tcl +455 -0
  100. data/tcl/BWidget-1.8.0/dynhelp.tcl +625 -0
  101. data/tcl/BWidget-1.8.0/entry.tcl +469 -0
  102. data/tcl/BWidget-1.8.0/font.tcl +566 -0
  103. data/tcl/BWidget-1.8.0/images/bold.gif +0 -0
  104. data/tcl/BWidget-1.8.0/images/copy.gif +0 -0
  105. data/tcl/BWidget-1.8.0/images/cut.gif +0 -0
  106. data/tcl/BWidget-1.8.0/images/dragfile.gif +0 -0
  107. data/tcl/BWidget-1.8.0/images/dragicon.gif +0 -0
  108. data/tcl/BWidget-1.8.0/images/error.gif +0 -0
  109. data/tcl/BWidget-1.8.0/images/file.gif +0 -0
  110. data/tcl/BWidget-1.8.0/images/folder.gif +0 -0
  111. data/tcl/BWidget-1.8.0/images/hourglass.gif +0 -0
  112. data/tcl/BWidget-1.8.0/images/info.gif +0 -0
  113. data/tcl/BWidget-1.8.0/images/italic.gif +0 -0
  114. data/tcl/BWidget-1.8.0/images/minus.xbm +5 -0
  115. data/tcl/BWidget-1.8.0/images/new.gif +0 -0
  116. data/tcl/BWidget-1.8.0/images/opcopy.xbm +5 -0
  117. data/tcl/BWidget-1.8.0/images/open.gif +0 -0
  118. data/tcl/BWidget-1.8.0/images/openfold.gif +0 -0
  119. data/tcl/BWidget-1.8.0/images/oplink.xbm +5 -0
  120. data/tcl/BWidget-1.8.0/images/opmove.xbm +5 -0
  121. data/tcl/BWidget-1.8.0/images/overstrike.gif +0 -0
  122. data/tcl/BWidget-1.8.0/images/palette.gif +0 -0
  123. data/tcl/BWidget-1.8.0/images/passwd.gif +0 -0
  124. data/tcl/BWidget-1.8.0/images/paste.gif +0 -0
  125. data/tcl/BWidget-1.8.0/images/plus.xbm +5 -0
  126. data/tcl/BWidget-1.8.0/images/print.gif +0 -0
  127. data/tcl/BWidget-1.8.0/images/question.gif +0 -0
  128. data/tcl/BWidget-1.8.0/images/redo.gif +0 -0
  129. data/tcl/BWidget-1.8.0/images/save.gif +0 -0
  130. data/tcl/BWidget-1.8.0/images/target.xbm +9 -0
  131. data/tcl/BWidget-1.8.0/images/underline.gif +0 -0
  132. data/tcl/BWidget-1.8.0/images/undo.gif +0 -0
  133. data/tcl/BWidget-1.8.0/images/warning.gif +0 -0
  134. data/tcl/BWidget-1.8.0/init.tcl +40 -0
  135. data/tcl/BWidget-1.8.0/label.tcl +271 -0
  136. data/tcl/BWidget-1.8.0/labelentry.tcl +100 -0
  137. data/tcl/BWidget-1.8.0/labelframe.tcl +160 -0
  138. data/tcl/BWidget-1.8.0/lang/da.rc +52 -0
  139. data/tcl/BWidget-1.8.0/lang/de.rc +52 -0
  140. data/tcl/BWidget-1.8.0/lang/en.rc +52 -0
  141. data/tcl/BWidget-1.8.0/lang/es.rc +53 -0
  142. data/tcl/BWidget-1.8.0/lang/fr.rc +52 -0
  143. data/tcl/BWidget-1.8.0/listbox.tcl +1638 -0
  144. data/tcl/BWidget-1.8.0/mainframe.tcl +711 -0
  145. data/tcl/BWidget-1.8.0/messagedlg.tcl +128 -0
  146. data/tcl/BWidget-1.8.0/notebook.tcl +1164 -0
  147. data/tcl/BWidget-1.8.0/pagesmgr.tcl +294 -0
  148. data/tcl/BWidget-1.8.0/panedw.tcl +381 -0
  149. data/tcl/BWidget-1.8.0/panelframe.tcl +246 -0
  150. data/tcl/BWidget-1.8.0/passwddlg.tcl +178 -0
  151. data/tcl/BWidget-1.8.0/pkgIndex.tcl +47 -0
  152. data/tcl/BWidget-1.8.0/progressbar.tcl +208 -0
  153. data/tcl/BWidget-1.8.0/progressdlg.tcl +87 -0
  154. data/tcl/BWidget-1.8.0/scrollframe.tcl +226 -0
  155. data/tcl/BWidget-1.8.0/scrollview.tcl +254 -0
  156. data/tcl/BWidget-1.8.0/scrollw.tcl +280 -0
  157. data/tcl/BWidget-1.8.0/separator.tcl +75 -0
  158. data/tcl/BWidget-1.8.0/spinbox.tcl +331 -0
  159. data/tcl/BWidget-1.8.0/statusbar.tcl +422 -0
  160. data/tcl/BWidget-1.8.0/tests/entry.test +173 -0
  161. data/tcl/BWidget-1.8.0/titleframe.tcl +170 -0
  162. data/tcl/BWidget-1.8.0/tree.tcl +2228 -0
  163. data/tcl/BWidget-1.8.0/utils.tcl +645 -0
  164. data/tcl/BWidget-1.8.0/widget.tcl +1576 -0
  165. data/tcl/BWidget-1.8.0/wizard.tcl +1028 -0
  166. data/tcl/BWidget-1.8.0/xpm2image.tcl +115 -0
  167. metadata +141 -5
@@ -0,0 +1,1576 @@
1
+ # ----------------------------------------------------------------------------
2
+ # widget.tcl
3
+ # This file is part of Unifix BWidget Toolkit
4
+ # $Id: widget.tcl,v 1.29 2005/07/28 00:40:42 hobbs Exp $
5
+ # ----------------------------------------------------------------------------
6
+ # Index of commands:
7
+ # - Widget::tkinclude
8
+ # - Widget::bwinclude
9
+ # - Widget::declare
10
+ # - Widget::addmap
11
+ # - Widget::init
12
+ # - Widget::destroy
13
+ # - Widget::setoption
14
+ # - Widget::configure
15
+ # - Widget::cget
16
+ # - Widget::subcget
17
+ # - Widget::hasChanged
18
+ # - Widget::options
19
+ # - Widget::_get_tkwidget_options
20
+ # - Widget::_test_tkresource
21
+ # - Widget::_test_bwresource
22
+ # - Widget::_test_synonym
23
+ # - Widget::_test_string
24
+ # - Widget::_test_flag
25
+ # - Widget::_test_enum
26
+ # - Widget::_test_int
27
+ # - Widget::_test_boolean
28
+ # ----------------------------------------------------------------------------
29
+ # Each megawidget gets a namespace of the same name inside the Widget namespace
30
+ # Each of these has an array opt, which contains information about the
31
+ # megawidget options. It maps megawidget options to a list with this format:
32
+ # {optionType defaultValue isReadonly {additionalOptionalInfo}}
33
+ # Option types and their additional optional info are:
34
+ # TkResource {genericTkWidget genericTkWidgetOptionName}
35
+ # BwResource {nothing}
36
+ # Enum {list of enumeration values}
37
+ # Int {Boundary information}
38
+ # Boolean {nothing}
39
+ # String {nothing}
40
+ # Flag {string of valid flag characters}
41
+ # Synonym {nothing}
42
+ # Color {nothing}
43
+ #
44
+ # Next, each namespace has an array map, which maps class options to their
45
+ # component widget options:
46
+ # map(-foreground) => {.e -foreground .f -foreground}
47
+ #
48
+ # Each has an array ${path}:opt, which contains the value of each megawidget
49
+ # option for a particular instance $path of the megawidget, and an array
50
+ # ${path}:mod, which stores the "changed" status of configuration options.
51
+
52
+ # Steps for creating a bwidget megawidget:
53
+ # 1. parse args to extract subwidget spec
54
+ # 2. Create frame with appropriate class and command line options
55
+ # 3. Get initialization options from optionDB, using frame
56
+ # 4. create subwidgets
57
+
58
+ # Uses newer string operations
59
+ package require Tcl 8.1.1
60
+
61
+ namespace eval Widget {
62
+ variable _optiontype
63
+ variable _class
64
+ variable _tk_widget
65
+
66
+ # This controls whether we try to use themed widgets from Tile
67
+ variable _theme 0
68
+
69
+ variable _aqua [expr {($::tcl_version >= 8.4) &&
70
+ [string equal [tk windowingsystem] "aqua"]}]
71
+
72
+ array set _optiontype {
73
+ TkResource Widget::_test_tkresource
74
+ BwResource Widget::_test_bwresource
75
+ Enum Widget::_test_enum
76
+ Int Widget::_test_int
77
+ Boolean Widget::_test_boolean
78
+ String Widget::_test_string
79
+ Flag Widget::_test_flag
80
+ Synonym Widget::_test_synonym
81
+ Color Widget::_test_color
82
+ Padding Widget::_test_padding
83
+ }
84
+
85
+ proc use {} {}
86
+ }
87
+
88
+
89
+ # ----------------------------------------------------------------------------
90
+ # Command Widget::tkinclude
91
+ # Includes tk widget resources to BWidget widget.
92
+ # class class name of the BWidget
93
+ # tkwidget tk widget to include
94
+ # subpath subpath to configure
95
+ # args additionnal args for included options
96
+ # ----------------------------------------------------------------------------
97
+ proc Widget::tkinclude { class tkwidget subpath args } {
98
+ foreach {cmd lopt} $args {
99
+ # cmd can be
100
+ # include options to include lopt = {opt ...}
101
+ # remove options to remove lopt = {opt ...}
102
+ # rename options to rename lopt = {opt newopt ...}
103
+ # prefix options to prefix lopt = {pref opt opt ..}
104
+ # initialize set default value for options lopt = {opt value ...}
105
+ # readonly set readonly flag for options lopt = {opt flag ...}
106
+ switch -- $cmd {
107
+ remove {
108
+ foreach option $lopt {
109
+ set remove($option) 1
110
+ }
111
+ }
112
+ include {
113
+ foreach option $lopt {
114
+ set include($option) 1
115
+ }
116
+ }
117
+ prefix {
118
+ set prefix [lindex $lopt 0]
119
+ foreach option [lrange $lopt 1 end] {
120
+ set rename($option) "-$prefix[string range $option 1 end]"
121
+ }
122
+ }
123
+ rename -
124
+ readonly -
125
+ initialize {
126
+ array set $cmd $lopt
127
+ }
128
+ default {
129
+ return -code error "invalid argument \"$cmd\""
130
+ }
131
+ }
132
+ }
133
+
134
+ namespace eval $class {}
135
+ upvar 0 ${class}::opt classopt
136
+ upvar 0 ${class}::map classmap
137
+ upvar 0 ${class}::map$subpath submap
138
+ upvar 0 ${class}::optionExports exports
139
+
140
+ set foo [$tkwidget ".ericFoo###"]
141
+ # create resources informations from tk widget resources
142
+ foreach optdesc [_get_tkwidget_options $tkwidget] {
143
+ set option [lindex $optdesc 0]
144
+ if { (![info exists include] || [info exists include($option)]) &&
145
+ ![info exists remove($option)] } {
146
+ if { [llength $optdesc] == 3 } {
147
+ # option is a synonym
148
+ set syn [lindex $optdesc 1]
149
+ if { ![info exists remove($syn)] } {
150
+ # original option is not removed
151
+ if { [info exists rename($syn)] } {
152
+ set classopt($option) [list Synonym $rename($syn)]
153
+ } else {
154
+ set classopt($option) [list Synonym $syn]
155
+ }
156
+ }
157
+ } else {
158
+ if { [info exists rename($option)] } {
159
+ set realopt $option
160
+ set option $rename($option)
161
+ } else {
162
+ set realopt $option
163
+ }
164
+ if { [info exists initialize($option)] } {
165
+ set value $initialize($option)
166
+ } else {
167
+ set value [lindex $optdesc 1]
168
+ }
169
+ if { [info exists readonly($option)] } {
170
+ set ro $readonly($option)
171
+ } else {
172
+ set ro 0
173
+ }
174
+ set classopt($option) \
175
+ [list TkResource $value $ro [list $tkwidget $realopt]]
176
+
177
+ # Add an option database entry for this option
178
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
179
+ if { ![string equal $subpath ":cmd"] } {
180
+ set optionDbName "$subpath$optionDbName"
181
+ }
182
+ option add *${class}$optionDbName $value widgetDefault
183
+ lappend exports($option) "$optionDbName"
184
+
185
+ # Store the forward and backward mappings for this
186
+ # option <-> realoption pair
187
+ lappend classmap($option) $subpath "" $realopt
188
+ set submap($realopt) $option
189
+ }
190
+ }
191
+ }
192
+ ::destroy $foo
193
+ }
194
+
195
+
196
+ # ----------------------------------------------------------------------------
197
+ # Command Widget::bwinclude
198
+ # Includes BWidget resources to BWidget widget.
199
+ # class class name of the BWidget
200
+ # subclass BWidget class to include
201
+ # subpath subpath to configure
202
+ # args additionnal args for included options
203
+ # ----------------------------------------------------------------------------
204
+ proc Widget::bwinclude { class subclass subpath args } {
205
+ foreach {cmd lopt} $args {
206
+ # cmd can be
207
+ # include options to include lopt = {opt ...}
208
+ # remove options to remove lopt = {opt ...}
209
+ # rename options to rename lopt = {opt newopt ...}
210
+ # prefix options to prefix lopt = {prefix opt opt ...}
211
+ # initialize set default value for options lopt = {opt value ...}
212
+ # readonly set readonly flag for options lopt = {opt flag ...}
213
+ switch -- $cmd {
214
+ remove {
215
+ foreach option $lopt {
216
+ set remove($option) 1
217
+ }
218
+ }
219
+ include {
220
+ foreach option $lopt {
221
+ set include($option) 1
222
+ }
223
+ }
224
+ prefix {
225
+ set prefix [lindex $lopt 0]
226
+ foreach option [lrange $lopt 1 end] {
227
+ set rename($option) "-$prefix[string range $option 1 end]"
228
+ }
229
+ }
230
+ rename -
231
+ readonly -
232
+ initialize {
233
+ array set $cmd $lopt
234
+ }
235
+ default {
236
+ return -code error "invalid argument \"$cmd\""
237
+ }
238
+ }
239
+ }
240
+
241
+ namespace eval $class {}
242
+ upvar 0 ${class}::opt classopt
243
+ upvar 0 ${class}::map classmap
244
+ upvar 0 ${class}::map$subpath submap
245
+ upvar 0 ${class}::optionExports exports
246
+ upvar 0 ${subclass}::opt subclassopt
247
+ upvar 0 ${subclass}::optionExports subexports
248
+
249
+ # create resources informations from BWidget resources
250
+ foreach {option optdesc} [array get subclassopt] {
251
+ set subOption $option
252
+ if { (![info exists include] || [info exists include($option)]) &&
253
+ ![info exists remove($option)] } {
254
+ set type [lindex $optdesc 0]
255
+ if { [string equal $type "Synonym"] } {
256
+ # option is a synonym
257
+ set syn [lindex $optdesc 1]
258
+ if { ![info exists remove($syn)] } {
259
+ if { [info exists rename($syn)] } {
260
+ set classopt($option) [list Synonym $rename($syn)]
261
+ } else {
262
+ set classopt($option) [list Synonym $syn]
263
+ }
264
+ }
265
+ } else {
266
+ if { [info exists rename($option)] } {
267
+ set realopt $option
268
+ set option $rename($option)
269
+ } else {
270
+ set realopt $option
271
+ }
272
+ if { [info exists initialize($option)] } {
273
+ set value $initialize($option)
274
+ } else {
275
+ set value [lindex $optdesc 1]
276
+ }
277
+ if { [info exists readonly($option)] } {
278
+ set ro $readonly($option)
279
+ } else {
280
+ set ro [lindex $optdesc 2]
281
+ }
282
+ set classopt($option) \
283
+ [list $type $value $ro [lindex $optdesc 3]]
284
+
285
+ # Add an option database entry for this option
286
+ foreach optionDbName $subexports($subOption) {
287
+ if { ![string equal $subpath ":cmd"] } {
288
+ set optionDbName "$subpath$optionDbName"
289
+ }
290
+ # Only add the option db entry if we are overriding the
291
+ # normal widget default
292
+ if { [info exists initialize($option)] } {
293
+ option add *${class}$optionDbName $value \
294
+ widgetDefault
295
+ }
296
+ lappend exports($option) "$optionDbName"
297
+ }
298
+
299
+ # Store the forward and backward mappings for this
300
+ # option <-> realoption pair
301
+ lappend classmap($option) $subpath $subclass $realopt
302
+ set submap($realopt) $option
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+
309
+ # ----------------------------------------------------------------------------
310
+ # Command Widget::declare
311
+ # Declares new options to BWidget class.
312
+ # ----------------------------------------------------------------------------
313
+ proc Widget::declare { class optlist } {
314
+ variable _optiontype
315
+
316
+ namespace eval $class {}
317
+ upvar 0 ${class}::opt classopt
318
+ upvar 0 ${class}::optionExports exports
319
+ upvar 0 ${class}::optionClass optionClass
320
+
321
+ foreach optdesc $optlist {
322
+ set option [lindex $optdesc 0]
323
+ set optdesc [lrange $optdesc 1 end]
324
+ set type [lindex $optdesc 0]
325
+
326
+ if { ![info exists _optiontype($type)] } {
327
+ # invalid resource type
328
+ return -code error "invalid option type \"$type\""
329
+ }
330
+
331
+ if { [string equal $type "Synonym"] } {
332
+ # test existence of synonym option
333
+ set syn [lindex $optdesc 1]
334
+ if { ![info exists classopt($syn)] } {
335
+ return -code error "unknow option \"$syn\" for Synonym \"$option\""
336
+ }
337
+ set classopt($option) [list Synonym $syn]
338
+ continue
339
+ }
340
+
341
+ # all other resource may have default value, readonly flag and
342
+ # optional arg depending on type
343
+ set value [lindex $optdesc 1]
344
+ set ro [lindex $optdesc 2]
345
+ set arg [lindex $optdesc 3]
346
+
347
+ if { [string equal $type "BwResource"] } {
348
+ # We don't keep BwResource. We simplify to type of sub BWidget
349
+ set subclass [lindex $arg 0]
350
+ set realopt [lindex $arg 1]
351
+ if { ![string length $realopt] } {
352
+ set realopt $option
353
+ }
354
+
355
+ upvar 0 ${subclass}::opt subclassopt
356
+ if { ![info exists subclassopt($realopt)] } {
357
+ return -code error "unknow option \"$realopt\""
358
+ }
359
+ set suboptdesc $subclassopt($realopt)
360
+ if { $value == "" } {
361
+ # We initialize default value
362
+ set value [lindex $suboptdesc 1]
363
+ }
364
+ set type [lindex $suboptdesc 0]
365
+ set ro [lindex $suboptdesc 2]
366
+ set arg [lindex $suboptdesc 3]
367
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
368
+ option add *${class}${optionDbName} $value widgetDefault
369
+ set exports($option) $optionDbName
370
+ set classopt($option) [list $type $value $ro $arg]
371
+ continue
372
+ }
373
+
374
+ # retreive default value for TkResource
375
+ if { [string equal $type "TkResource"] } {
376
+ set tkwidget [lindex $arg 0]
377
+ set foo [$tkwidget ".ericFoo##"]
378
+ set realopt [lindex $arg 1]
379
+ if { ![string length $realopt] } {
380
+ set realopt $option
381
+ }
382
+ set tkoptions [_get_tkwidget_options $tkwidget]
383
+ if { ![string length $value] } {
384
+ # We initialize default value
385
+ set ind [lsearch $tkoptions [list $realopt *]]
386
+ set value [lindex [lindex $tkoptions $ind] end]
387
+ }
388
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
389
+ option add *${class}${optionDbName} $value widgetDefault
390
+ set exports($option) $optionDbName
391
+ set classopt($option) [list TkResource $value $ro \
392
+ [list $tkwidget $realopt]]
393
+ set optionClass($option) [lindex [$foo configure $realopt] 1]
394
+ ::destroy $foo
395
+ continue
396
+ }
397
+
398
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
399
+ option add *${class}${optionDbName} $value widgetDefault
400
+ set exports($option) $optionDbName
401
+ # for any other resource type, we keep original optdesc
402
+ set classopt($option) [list $type $value $ro $arg]
403
+ }
404
+ }
405
+
406
+
407
+ proc Widget::define { class filename args } {
408
+ variable ::BWidget::use
409
+ set use($class) $args
410
+ set use($class,file) $filename
411
+ lappend use(classes) $class
412
+
413
+ if {[set x [lsearch -exact $args "-classonly"]] > -1} {
414
+ set args [lreplace $args $x $x]
415
+ } else {
416
+ interp alias {} ::${class} {} ${class}::create
417
+ proc ::${class}::use {} {}
418
+
419
+ bind $class <Destroy> [list Widget::destroy %W]
420
+ }
421
+
422
+ foreach class $args { ${class}::use }
423
+ }
424
+
425
+
426
+ proc Widget::create { class path {rename 1} } {
427
+ if {$rename} { rename $path ::$path:cmd }
428
+ proc ::$path { cmd args } \
429
+ [subst {return \[eval \[linsert \$args 0 ${class}::\$cmd [list $path]\]\]}]
430
+ return $path
431
+ }
432
+
433
+
434
+ # ----------------------------------------------------------------------------
435
+ # Command Widget::addmap
436
+ # ----------------------------------------------------------------------------
437
+ proc Widget::addmap { class subclass subpath options } {
438
+ upvar 0 ${class}::opt classopt
439
+ upvar 0 ${class}::optionExports exports
440
+ upvar 0 ${class}::optionClass optionClass
441
+ upvar 0 ${class}::map classmap
442
+ upvar 0 ${class}::map$subpath submap
443
+
444
+ foreach {option realopt} $options {
445
+ if { ![string length $realopt] } {
446
+ set realopt $option
447
+ }
448
+ set val [lindex $classopt($option) 1]
449
+ set optDb ".[lindex [_configure_option $realopt ""] 0]"
450
+ if { ![string equal $subpath ":cmd"] } {
451
+ set optDb "$subpath$optDb"
452
+ }
453
+ option add *${class}${optDb} $val widgetDefault
454
+ lappend exports($option) $optDb
455
+ # Store the forward and backward mappings for this
456
+ # option <-> realoption pair
457
+ lappend classmap($option) $subpath $subclass $realopt
458
+ set submap($realopt) $option
459
+ }
460
+ }
461
+
462
+
463
+ # ----------------------------------------------------------------------------
464
+ # Command Widget::syncoptions
465
+ # ----------------------------------------------------------------------------
466
+ proc Widget::syncoptions { class subclass subpath options } {
467
+ upvar 0 ${class}::sync classync
468
+
469
+ foreach {option realopt} $options {
470
+ if { ![string length $realopt] } {
471
+ set realopt $option
472
+ }
473
+ set classync($option) [list $subpath $subclass $realopt]
474
+ }
475
+ }
476
+
477
+
478
+ # ----------------------------------------------------------------------------
479
+ # Command Widget::init
480
+ # ----------------------------------------------------------------------------
481
+ proc Widget::init { class path options } {
482
+ variable _inuse
483
+
484
+ upvar 0 ${class}::opt classopt
485
+ upvar 0 ${class}::$path:opt pathopt
486
+ upvar 0 ${class}::$path:mod pathmod
487
+ upvar 0 ${class}::map classmap
488
+ upvar 0 ${class}::$path:init pathinit
489
+
490
+ if { [info exists pathopt] } {
491
+ unset pathopt
492
+ }
493
+ if { [info exists pathmod] } {
494
+ unset pathmod
495
+ }
496
+ # We prefer to use the actual widget for option db queries, but if it
497
+ # doesn't exist yet, do the next best thing: create a widget of the
498
+ # same class and use that.
499
+ set fpath $path
500
+ set rdbclass [string map [list :: ""] $class]
501
+ if { ![winfo exists $path] } {
502
+ set fpath ".#BWidget.#Class#$class"
503
+ # encapsulation frame to not pollute '.' childspace
504
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
505
+ if { ![winfo exists $fpath] } {
506
+ frame $fpath -class $rdbclass
507
+ }
508
+ }
509
+ foreach {option optdesc} [array get classopt] {
510
+ set pathmod($option) 0
511
+ if { [info exists classmap($option)] } {
512
+ continue
513
+ }
514
+ set type [lindex $optdesc 0]
515
+ if { [string equal $type "Synonym"] } {
516
+ continue
517
+ }
518
+ if { [string equal $type "TkResource"] } {
519
+ set alt [lindex [lindex $optdesc 3] 1]
520
+ } else {
521
+ set alt ""
522
+ }
523
+ set optdb [lindex [_configure_option $option $alt] 0]
524
+ set def [option get $fpath $optdb $rdbclass]
525
+ if { [string length $def] } {
526
+ set pathopt($option) $def
527
+ } else {
528
+ set pathopt($option) [lindex $optdesc 1]
529
+ }
530
+ }
531
+
532
+ if {![info exists _inuse($class)]} { set _inuse($class) 0 }
533
+ incr _inuse($class)
534
+
535
+ set Widget::_class($path) $class
536
+ foreach {option value} $options {
537
+ if { ![info exists classopt($option)] } {
538
+ unset pathopt
539
+ unset pathmod
540
+ return -code error "unknown option \"$option\""
541
+ }
542
+ set optdesc $classopt($option)
543
+ set type [lindex $optdesc 0]
544
+ if { [string equal $type "Synonym"] } {
545
+ set option [lindex $optdesc 1]
546
+ set optdesc $classopt($option)
547
+ set type [lindex $optdesc 0]
548
+ }
549
+ set pathopt($option) [$Widget::_optiontype($type) $option $value [lindex $optdesc 3]]
550
+ set pathinit($option) $pathopt($option)
551
+ }
552
+ }
553
+
554
+ # Bastien Chevreux (bach@mwgdna.com)
555
+ #
556
+ # copyinit performs basically the same job as init, but it uses a
557
+ # existing template to initialize its values. So, first a perferct copy
558
+ # from the template is made just to be altered by any existing options
559
+ # afterwards.
560
+ # But this still saves time as the first initialization parsing block is
561
+ # skipped.
562
+ # As additional bonus, items that differ in just a few options can be
563
+ # initialized faster by leaving out the options that are equal.
564
+
565
+ # This function is currently used only by ListBox::multipleinsert, but other
566
+ # calls should follow :)
567
+
568
+ # ----------------------------------------------------------------------------
569
+ # Command Widget::copyinit
570
+ # ----------------------------------------------------------------------------
571
+ proc Widget::copyinit { class templatepath path options } {
572
+ upvar 0 ${class}::opt classopt \
573
+ ${class}::$path:opt pathopt \
574
+ ${class}::$path:mod pathmod \
575
+ ${class}::$path:init pathinit \
576
+ ${class}::$templatepath:opt templatepathopt \
577
+ ${class}::$templatepath:mod templatepathmod \
578
+ ${class}::$templatepath:init templatepathinit
579
+
580
+ if { [info exists pathopt] } {
581
+ unset pathopt
582
+ }
583
+ if { [info exists pathmod] } {
584
+ unset pathmod
585
+ }
586
+
587
+ # We use the template widget for option db copying, but it has to exist!
588
+ array set pathmod [array get templatepathmod]
589
+ array set pathopt [array get templatepathopt]
590
+ array set pathinit [array get templatepathinit]
591
+
592
+ set Widget::_class($path) $class
593
+ foreach {option value} $options {
594
+ if { ![info exists classopt($option)] } {
595
+ unset pathopt
596
+ unset pathmod
597
+ return -code error "unknown option \"$option\""
598
+ }
599
+ set optdesc $classopt($option)
600
+ set type [lindex $optdesc 0]
601
+ if { [string equal $type "Synonym"] } {
602
+ set option [lindex $optdesc 1]
603
+ set optdesc $classopt($option)
604
+ set type [lindex $optdesc 0]
605
+ }
606
+ set pathopt($option) [$Widget::_optiontype($type) $option $value [lindex $optdesc 3]]
607
+ set pathinit($option) $pathopt($option)
608
+ }
609
+ }
610
+
611
+ # Widget::parseArgs --
612
+ #
613
+ # Given a widget class and a command-line spec, cannonize and validate
614
+ # the given options, and return a keyed list consisting of the
615
+ # component widget and its masked portion of the command-line spec, and
616
+ # one extra entry consisting of the portion corresponding to the
617
+ # megawidget itself.
618
+ #
619
+ # Arguments:
620
+ # class widget class to parse for.
621
+ # options command-line spec
622
+ #
623
+ # Results:
624
+ # result keyed list of portions of the megawidget and that segment of
625
+ # the command line in which that portion is interested.
626
+
627
+ proc Widget::parseArgs {class options} {
628
+ upvar 0 ${class}::opt classopt
629
+ upvar 0 ${class}::map classmap
630
+
631
+ foreach {option val} $options {
632
+ if { ![info exists classopt($option)] } {
633
+ error "unknown option \"$option\""
634
+ }
635
+ set optdesc $classopt($option)
636
+ set type [lindex $optdesc 0]
637
+ if { [string equal $type "Synonym"] } {
638
+ set option [lindex $optdesc 1]
639
+ set optdesc $classopt($option)
640
+ set type [lindex $optdesc 0]
641
+ }
642
+ if { [string equal $type "TkResource"] } {
643
+ # Make sure that the widget used for this TkResource exists
644
+ Widget::_get_tkwidget_options [lindex [lindex $optdesc 3] 0]
645
+ }
646
+ set val [$Widget::_optiontype($type) $option $val [lindex $optdesc 3]]
647
+
648
+ if { [info exists classmap($option)] } {
649
+ foreach {subpath subclass realopt} $classmap($option) {
650
+ lappend maps($subpath) $realopt $val
651
+ }
652
+ } else {
653
+ lappend maps($class) $option $val
654
+ }
655
+ }
656
+ return [array get maps]
657
+ }
658
+
659
+ # Widget::initFromODB --
660
+ #
661
+ # Initialize a megawidgets options with information from the option
662
+ # database and from the command-line arguments given.
663
+ #
664
+ # Arguments:
665
+ # class class of the widget.
666
+ # path path of the widget -- should already exist.
667
+ # options command-line arguments.
668
+ #
669
+ # Results:
670
+ # None.
671
+
672
+ proc Widget::initFromODB {class path options} {
673
+ variable _inuse
674
+ variable _class
675
+
676
+ upvar 0 ${class}::$path:opt pathopt
677
+ upvar 0 ${class}::$path:mod pathmod
678
+ upvar 0 ${class}::map classmap
679
+
680
+ if { [info exists pathopt] } {
681
+ unset pathopt
682
+ }
683
+ if { [info exists pathmod] } {
684
+ unset pathmod
685
+ }
686
+ # We prefer to use the actual widget for option db queries, but if it
687
+ # doesn't exist yet, do the next best thing: create a widget of the
688
+ # same class and use that.
689
+ set fpath [_get_window $class $path]
690
+ set rdbclass [string map [list :: ""] $class]
691
+ if { ![winfo exists $path] } {
692
+ set fpath ".#BWidget.#Class#$class"
693
+ # encapsulation frame to not pollute '.' childspace
694
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
695
+ if { ![winfo exists $fpath] } {
696
+ frame $fpath -class $rdbclass
697
+ }
698
+ }
699
+
700
+ foreach {option optdesc} [array get ${class}::opt] {
701
+ set pathmod($option) 0
702
+ if { [info exists classmap($option)] } {
703
+ continue
704
+ }
705
+ set type [lindex $optdesc 0]
706
+ if { [string equal $type "Synonym"] } {
707
+ continue
708
+ }
709
+ if { [string equal $type "TkResource"] } {
710
+ set alt [lindex [lindex $optdesc 3] 1]
711
+ } else {
712
+ set alt ""
713
+ }
714
+ set optdb [lindex [_configure_option $option $alt] 0]
715
+ set def [option get $fpath $optdb $rdbclass]
716
+ if { [string length $def] } {
717
+ set pathopt($option) $def
718
+ } else {
719
+ set pathopt($option) [lindex $optdesc 1]
720
+ }
721
+ }
722
+
723
+ if {![info exists _inuse($class)]} { set _inuse($class) 0 }
724
+ incr _inuse($class)
725
+
726
+ set _class($path) $class
727
+ array set pathopt $options
728
+ }
729
+
730
+
731
+
732
+ # ----------------------------------------------------------------------------
733
+ # Command Widget::destroy
734
+ # ----------------------------------------------------------------------------
735
+ proc Widget::destroy { path } {
736
+ variable _class
737
+ variable _inuse
738
+
739
+ if {![info exists _class($path)]} { return }
740
+
741
+ set class $_class($path)
742
+ upvar 0 ${class}::$path:opt pathopt
743
+ upvar 0 ${class}::$path:mod pathmod
744
+ upvar 0 ${class}::$path:init pathinit
745
+
746
+ if {[info exists _inuse($class)]} { incr _inuse($class) -1 }
747
+
748
+ if {[info exists pathopt]} {
749
+ unset pathopt
750
+ }
751
+ if {[info exists pathmod]} {
752
+ unset pathmod
753
+ }
754
+ if {[info exists pathinit]} {
755
+ unset pathinit
756
+ }
757
+
758
+ if {![string equal [info commands $path] ""]} { rename $path "" }
759
+
760
+ ## Unset any variables used in this widget.
761
+ foreach var [info vars ::${class}::$path:*] { unset $var }
762
+
763
+ unset _class($path)
764
+ }
765
+
766
+
767
+ # ----------------------------------------------------------------------------
768
+ # Command Widget::configure
769
+ # ----------------------------------------------------------------------------
770
+ proc Widget::configure { path options } {
771
+ set len [llength $options]
772
+ if { $len <= 1 } {
773
+ return [_get_configure $path $options]
774
+ } elseif { $len % 2 == 1 } {
775
+ return -code error "incorrect number of arguments"
776
+ }
777
+
778
+ variable _class
779
+ variable _optiontype
780
+
781
+ set class $_class($path)
782
+ upvar 0 ${class}::opt classopt
783
+ upvar 0 ${class}::map classmap
784
+ upvar 0 ${class}::$path:opt pathopt
785
+ upvar 0 ${class}::$path:mod pathmod
786
+
787
+ set window [_get_window $class $path]
788
+ foreach {option value} $options {
789
+ if { ![info exists classopt($option)] } {
790
+ return -code error "unknown option \"$option\""
791
+ }
792
+ set optdesc $classopt($option)
793
+ set type [lindex $optdesc 0]
794
+ if { [string equal $type "Synonym"] } {
795
+ set option [lindex $optdesc 1]
796
+ set optdesc $classopt($option)
797
+ set type [lindex $optdesc 0]
798
+ }
799
+ if { ![lindex $optdesc 2] } {
800
+ set newval [$_optiontype($type) $option $value [lindex $optdesc 3]]
801
+ if { [info exists classmap($option)] } {
802
+ set window [_get_window $class $window]
803
+ foreach {subpath subclass realopt} $classmap($option) {
804
+ if { [string length $subclass] } {
805
+ set curval [${subclass}::cget $window$subpath $realopt]
806
+ ${subclass}::configure $window$subpath $realopt $newval
807
+ } else {
808
+ set curval [$window$subpath cget $realopt]
809
+ $window$subpath configure $realopt $newval
810
+ }
811
+ }
812
+ } else {
813
+ set curval $pathopt($option)
814
+ set pathopt($option) $newval
815
+ }
816
+ set pathmod($option) [expr {![string equal $newval $curval]}]
817
+ }
818
+ }
819
+
820
+ return {}
821
+ }
822
+
823
+
824
+ # ----------------------------------------------------------------------------
825
+ # Command Widget::cget
826
+ # ----------------------------------------------------------------------------
827
+ proc Widget::cget { path option } {
828
+ if { ![info exists ::Widget::_class($path)] } {
829
+ return -code error "unknown widget $path"
830
+ }
831
+
832
+ set class $::Widget::_class($path)
833
+ if { ![info exists ${class}::opt($option)] } {
834
+ return -code error "unknown option \"$option\""
835
+ }
836
+
837
+ set optdesc [set ${class}::opt($option)]
838
+ set type [lindex $optdesc 0]
839
+ if {[string equal $type "Synonym"]} {
840
+ set option [lindex $optdesc 1]
841
+ }
842
+
843
+ if { [info exists ${class}::map($option)] } {
844
+ foreach {subpath subclass realopt} [set ${class}::map($option)] {break}
845
+ set path "[_get_window $class $path]$subpath"
846
+ return [$path cget $realopt]
847
+ }
848
+ upvar 0 ${class}::$path:opt pathopt
849
+ set pathopt($option)
850
+ }
851
+
852
+
853
+ # ----------------------------------------------------------------------------
854
+ # Command Widget::subcget
855
+ # ----------------------------------------------------------------------------
856
+ proc Widget::subcget { path subwidget } {
857
+ set class $::Widget::_class($path)
858
+ upvar 0 ${class}::$path:opt pathopt
859
+ upvar 0 ${class}::map$subwidget submap
860
+ upvar 0 ${class}::$path:init pathinit
861
+
862
+ set result {}
863
+ foreach realopt [array names submap] {
864
+ if { [info exists pathinit($submap($realopt))] } {
865
+ lappend result $realopt $pathopt($submap($realopt))
866
+ }
867
+ }
868
+ return $result
869
+ }
870
+
871
+
872
+ # ----------------------------------------------------------------------------
873
+ # Command Widget::hasChanged
874
+ # ----------------------------------------------------------------------------
875
+ proc Widget::hasChanged { path option pvalue } {
876
+ upvar $pvalue value
877
+ set class $::Widget::_class($path)
878
+ upvar 0 ${class}::$path:mod pathmod
879
+
880
+ set value [Widget::cget $path $option]
881
+ set result $pathmod($option)
882
+ set pathmod($option) 0
883
+
884
+ return $result
885
+ }
886
+
887
+ proc Widget::hasChangedX { path option args } {
888
+ set class $::Widget::_class($path)
889
+ upvar 0 ${class}::$path:mod pathmod
890
+
891
+ set result $pathmod($option)
892
+ set pathmod($option) 0
893
+ foreach option $args {
894
+ lappend result $pathmod($option)
895
+ set pathmod($option) 0
896
+ }
897
+
898
+ set result
899
+ }
900
+
901
+
902
+ # ----------------------------------------------------------------------------
903
+ # Command Widget::setoption
904
+ # ----------------------------------------------------------------------------
905
+ proc Widget::setoption { path option value } {
906
+ # variable _class
907
+
908
+ # set class $_class($path)
909
+ # upvar 0 ${class}::$path:opt pathopt
910
+
911
+ # set pathopt($option) $value
912
+ Widget::configure $path [list $option $value]
913
+ }
914
+
915
+
916
+ # ----------------------------------------------------------------------------
917
+ # Command Widget::getoption
918
+ # ----------------------------------------------------------------------------
919
+ proc Widget::getoption { path option } {
920
+ # set class $::Widget::_class($path)
921
+ # upvar 0 ${class}::$path:opt pathopt
922
+
923
+ # return $pathopt($option)
924
+ return [Widget::cget $path $option]
925
+ }
926
+
927
+ # Widget::getMegawidgetOption --
928
+ #
929
+ # Bypass the superfluous checks in cget and just directly peer at the
930
+ # widget's data space. This is much more fragile than cget, so it
931
+ # should only be used with great care, in places where speed is critical.
932
+ #
933
+ # Arguments:
934
+ # path widget to lookup options for.
935
+ # option option to retrieve.
936
+ #
937
+ # Results:
938
+ # value option value.
939
+
940
+ proc Widget::getMegawidgetOption {path option} {
941
+ set class $::Widget::_class($path)
942
+ upvar 0 ${class}::${path}:opt pathopt
943
+ set pathopt($option)
944
+ }
945
+
946
+ # Widget::setMegawidgetOption --
947
+ #
948
+ # Bypass the superfluous checks in cget and just directly poke at the
949
+ # widget's data space. This is much more fragile than configure, so it
950
+ # should only be used with great care, in places where speed is critical.
951
+ #
952
+ # Arguments:
953
+ # path widget to lookup options for.
954
+ # option option to retrieve.
955
+ # value option value.
956
+ #
957
+ # Results:
958
+ # value option value.
959
+
960
+ proc Widget::setMegawidgetOption {path option value} {
961
+ set class $::Widget::_class($path)
962
+ upvar 0 ${class}::${path}:opt pathopt
963
+ set pathopt($option) $value
964
+ }
965
+
966
+ # ----------------------------------------------------------------------------
967
+ # Command Widget::_get_window
968
+ # returns the window corresponding to widget path
969
+ # ----------------------------------------------------------------------------
970
+ proc Widget::_get_window { class path } {
971
+ set idx [string last "#" $path]
972
+ if { $idx != -1 && [string equal [string range $path [expr {$idx+1}] end] $class] } {
973
+ return [string range $path 0 [expr {$idx-1}]]
974
+ } else {
975
+ return $path
976
+ }
977
+ }
978
+
979
+
980
+ # ----------------------------------------------------------------------------
981
+ # Command Widget::_get_configure
982
+ # returns the configuration list of options
983
+ # (as tk widget do - [$w configure ?option?])
984
+ # ----------------------------------------------------------------------------
985
+ proc Widget::_get_configure { path options } {
986
+ variable _class
987
+
988
+ set class $_class($path)
989
+ upvar 0 ${class}::opt classopt
990
+ upvar 0 ${class}::map classmap
991
+ upvar 0 ${class}::$path:opt pathopt
992
+ upvar 0 ${class}::$path:mod pathmod
993
+
994
+ set len [llength $options]
995
+ if { !$len } {
996
+ set result {}
997
+ foreach option [lsort [array names classopt]] {
998
+ set optdesc $classopt($option)
999
+ set type [lindex $optdesc 0]
1000
+ if { [string equal $type "Synonym"] } {
1001
+ set syn $option
1002
+ set option [lindex $optdesc 1]
1003
+ set optdesc $classopt($option)
1004
+ set type [lindex $optdesc 0]
1005
+ } else {
1006
+ set syn ""
1007
+ }
1008
+ if { [string equal $type "TkResource"] } {
1009
+ set alt [lindex [lindex $optdesc 3] 1]
1010
+ } else {
1011
+ set alt ""
1012
+ }
1013
+ set res [_configure_option $option $alt]
1014
+ if { $syn == "" } {
1015
+ lappend result [concat $option $res [list [lindex $optdesc 1]] [list [cget $path $option]]]
1016
+ } else {
1017
+ lappend result [list $syn [lindex $res 0]]
1018
+ }
1019
+ }
1020
+ return $result
1021
+ } elseif { $len == 1 } {
1022
+ set option [lindex $options 0]
1023
+ if { ![info exists classopt($option)] } {
1024
+ return -code error "unknown option \"$option\""
1025
+ }
1026
+ set optdesc $classopt($option)
1027
+ set type [lindex $optdesc 0]
1028
+ if { [string equal $type "Synonym"] } {
1029
+ set option [lindex $optdesc 1]
1030
+ set optdesc $classopt($option)
1031
+ set type [lindex $optdesc 0]
1032
+ }
1033
+ if { [string equal $type "TkResource"] } {
1034
+ set alt [lindex [lindex $optdesc 3] 1]
1035
+ } else {
1036
+ set alt ""
1037
+ }
1038
+ set res [_configure_option $option $alt]
1039
+ return [concat $option $res [list [lindex $optdesc 1]] [list [cget $path $option]]]
1040
+ }
1041
+ }
1042
+
1043
+
1044
+ # ----------------------------------------------------------------------------
1045
+ # Command Widget::_configure_option
1046
+ # ----------------------------------------------------------------------------
1047
+ proc Widget::_configure_option { option altopt } {
1048
+ variable _optiondb
1049
+ variable _optionclass
1050
+
1051
+ if { [info exists _optiondb($option)] } {
1052
+ set optdb $_optiondb($option)
1053
+ } else {
1054
+ set optdb [string range $option 1 end]
1055
+ }
1056
+ if { [info exists _optionclass($option)] } {
1057
+ set optclass $_optionclass($option)
1058
+ } elseif { [string length $altopt] } {
1059
+ if { [info exists _optionclass($altopt)] } {
1060
+ set optclass $_optionclass($altopt)
1061
+ } else {
1062
+ set optclass [string range $altopt 1 end]
1063
+ }
1064
+ } else {
1065
+ set optclass [string range $option 1 end]
1066
+ }
1067
+ return [list $optdb $optclass]
1068
+ }
1069
+
1070
+
1071
+ # ----------------------------------------------------------------------------
1072
+ # Command Widget::_get_tkwidget_options
1073
+ # ----------------------------------------------------------------------------
1074
+ proc Widget::_get_tkwidget_options { tkwidget } {
1075
+ variable _tk_widget
1076
+ variable _optiondb
1077
+ variable _optionclass
1078
+
1079
+ set widget ".#BWidget.#$tkwidget"
1080
+ # encapsulation frame to not pollute '.' childspace
1081
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
1082
+ if { ![winfo exists $widget] || ![info exists _tk_widget($tkwidget)] } {
1083
+ set widget [$tkwidget $widget]
1084
+ # JDC: Withdraw toplevels, otherwise visible
1085
+ if {[string equal $tkwidget "toplevel"]} {
1086
+ wm withdraw $widget
1087
+ }
1088
+ set config [$widget configure]
1089
+ foreach optlist $config {
1090
+ set opt [lindex $optlist 0]
1091
+ if { [llength $optlist] == 2 } {
1092
+ set refsyn [lindex $optlist 1]
1093
+ # search for class
1094
+ set idx [lsearch $config [list * $refsyn *]]
1095
+ if { $idx == -1 } {
1096
+ if { [string index $refsyn 0] == "-" } {
1097
+ # search for option (tk8.1b1 bug)
1098
+ set idx [lsearch $config [list $refsyn * *]]
1099
+ } else {
1100
+ # last resort
1101
+ set idx [lsearch $config [list -[string tolower $refsyn] * *]]
1102
+ }
1103
+ if { $idx == -1 } {
1104
+ # fed up with "can't read classopt()"
1105
+ return -code error "can't find option of synonym $opt"
1106
+ }
1107
+ }
1108
+ set syn [lindex [lindex $config $idx] 0]
1109
+ # JDC: used 4 (was 3) to get def from optiondb
1110
+ set def [lindex [lindex $config $idx] 4]
1111
+ lappend _tk_widget($tkwidget) [list $opt $syn $def]
1112
+ } else {
1113
+ # JDC: used 4 (was 3) to get def from optiondb
1114
+ set def [lindex $optlist 4]
1115
+ lappend _tk_widget($tkwidget) [list $opt $def]
1116
+ set _optiondb($opt) [lindex $optlist 1]
1117
+ set _optionclass($opt) [lindex $optlist 2]
1118
+ }
1119
+ }
1120
+ }
1121
+ return $_tk_widget($tkwidget)
1122
+ }
1123
+
1124
+
1125
+ # ----------------------------------------------------------------------------
1126
+ # Command Widget::_test_tkresource
1127
+ # ----------------------------------------------------------------------------
1128
+ proc Widget::_test_tkresource { option value arg } {
1129
+ # set tkwidget [lindex $arg 0]
1130
+ # set realopt [lindex $arg 1]
1131
+ foreach {tkwidget realopt} $arg break
1132
+ set path ".#BWidget.#$tkwidget"
1133
+ set old [$path cget $realopt]
1134
+ $path configure $realopt $value
1135
+ set res [$path cget $realopt]
1136
+ $path configure $realopt $old
1137
+
1138
+ return $res
1139
+ }
1140
+
1141
+
1142
+ # ----------------------------------------------------------------------------
1143
+ # Command Widget::_test_bwresource
1144
+ # ----------------------------------------------------------------------------
1145
+ proc Widget::_test_bwresource { option value arg } {
1146
+ return -code error "bad option type BwResource in widget"
1147
+ }
1148
+
1149
+
1150
+ # ----------------------------------------------------------------------------
1151
+ # Command Widget::_test_synonym
1152
+ # ----------------------------------------------------------------------------
1153
+ proc Widget::_test_synonym { option value arg } {
1154
+ return -code error "bad option type Synonym in widget"
1155
+ }
1156
+
1157
+ # ----------------------------------------------------------------------------
1158
+ # Command Widget::_test_color
1159
+ # ----------------------------------------------------------------------------
1160
+ proc Widget::_test_color { option value arg } {
1161
+ if {[catch {winfo rgb . $value} color]} {
1162
+ return -code error "bad $option value \"$value\": must be a colorname \
1163
+ or #RRGGBB triplet"
1164
+ }
1165
+
1166
+ return $value
1167
+ }
1168
+
1169
+
1170
+ # ----------------------------------------------------------------------------
1171
+ # Command Widget::_test_string
1172
+ # ----------------------------------------------------------------------------
1173
+ proc Widget::_test_string { option value arg } {
1174
+ set value
1175
+ }
1176
+
1177
+
1178
+ # ----------------------------------------------------------------------------
1179
+ # Command Widget::_test_flag
1180
+ # ----------------------------------------------------------------------------
1181
+ proc Widget::_test_flag { option value arg } {
1182
+ set len [string length $value]
1183
+ set res ""
1184
+ for {set i 0} {$i < $len} {incr i} {
1185
+ set c [string index $value $i]
1186
+ if { [string first $c $arg] == -1 } {
1187
+ return -code error "bad [string range $option 1 end] value \"$value\": characters must be in \"$arg\""
1188
+ }
1189
+ if { [string first $c $res] == -1 } {
1190
+ append res $c
1191
+ }
1192
+ }
1193
+ return $res
1194
+ }
1195
+
1196
+
1197
+ # -----------------------------------------------------------------------------
1198
+ # Command Widget::_test_enum
1199
+ # -----------------------------------------------------------------------------
1200
+ proc Widget::_test_enum { option value arg } {
1201
+ if { [lsearch $arg $value] == -1 } {
1202
+ set last [lindex $arg end]
1203
+ set sub [lreplace $arg end end]
1204
+ if { [llength $sub] } {
1205
+ set str "[join $sub ", "] or $last"
1206
+ } else {
1207
+ set str $last
1208
+ }
1209
+ return -code error "bad [string range $option 1 end] value \"$value\": must be $str"
1210
+ }
1211
+ return $value
1212
+ }
1213
+
1214
+
1215
+ # -----------------------------------------------------------------------------
1216
+ # Command Widget::_test_int
1217
+ # -----------------------------------------------------------------------------
1218
+ proc Widget::_test_int { option value arg } {
1219
+ if { ![string is int -strict $value] || \
1220
+ ([string length $arg] && \
1221
+ ![expr [string map [list %d $value] $arg]]) } {
1222
+ return -code error "bad $option value\
1223
+ \"$value\": must be integer ($arg)"
1224
+ }
1225
+ return $value
1226
+ }
1227
+
1228
+
1229
+ # -----------------------------------------------------------------------------
1230
+ # Command Widget::_test_boolean
1231
+ # -----------------------------------------------------------------------------
1232
+ proc Widget::_test_boolean { option value arg } {
1233
+ if { ![string is boolean -strict $value] } {
1234
+ return -code error "bad $option value \"$value\": must be boolean"
1235
+ }
1236
+
1237
+ # Get the canonical form of the boolean value (1 for true, 0 for false)
1238
+ return [string is true $value]
1239
+ }
1240
+
1241
+
1242
+ # -----------------------------------------------------------------------------
1243
+ # Command Widget::_test_padding
1244
+ # -----------------------------------------------------------------------------
1245
+ proc Widget::_test_padding { option values arg } {
1246
+ set len [llength $values]
1247
+ if {$len < 1 || $len > 2} {
1248
+ return -code error "bad pad value \"$values\":\
1249
+ must be positive screen distance"
1250
+ }
1251
+
1252
+ foreach value $values {
1253
+ if { ![string is int -strict $value] || \
1254
+ ([string length $arg] && \
1255
+ ![expr [string map [list %d $value] $arg]]) } {
1256
+ return -code error "bad pad value \"$value\":\
1257
+ must be positive screen distance ($arg)"
1258
+ }
1259
+ }
1260
+ return $values
1261
+ }
1262
+
1263
+
1264
+ # Widget::_get_padding --
1265
+ #
1266
+ # Return the requesting padding value for a padding option.
1267
+ #
1268
+ # Arguments:
1269
+ # path Widget to get the options for.
1270
+ # option The name of the padding option.
1271
+ # index The index of the padding. If the index is empty,
1272
+ # the first padding value is returned.
1273
+ #
1274
+ # Results:
1275
+ # Return a numeric value that can be used for padding.
1276
+ proc Widget::_get_padding { path option {index 0} } {
1277
+ set pad [Widget::cget $path $option]
1278
+ set val [lindex $pad $index]
1279
+ if {$val == ""} { set val [lindex $pad 0] }
1280
+ return $val
1281
+ }
1282
+
1283
+
1284
+ # -----------------------------------------------------------------------------
1285
+ # Command Widget::focusNext
1286
+ # Same as tk_focusNext, but call Widget::focusOK
1287
+ # -----------------------------------------------------------------------------
1288
+ proc Widget::focusNext { w } {
1289
+ set cur $w
1290
+ while 1 {
1291
+
1292
+ # Descend to just before the first child of the current widget.
1293
+
1294
+ set parent $cur
1295
+ set children [winfo children $cur]
1296
+ set i -1
1297
+
1298
+ # Look for the next sibling that isn't a top-level.
1299
+
1300
+ while 1 {
1301
+ incr i
1302
+ if {$i < [llength $children]} {
1303
+ set cur [lindex $children $i]
1304
+ if {[string equal [winfo toplevel $cur] $cur]} {
1305
+ continue
1306
+ } else {
1307
+ break
1308
+ }
1309
+ }
1310
+
1311
+ # No more siblings, so go to the current widget's parent.
1312
+ # If it's a top-level, break out of the loop, otherwise
1313
+ # look for its next sibling.
1314
+
1315
+ set cur $parent
1316
+ if {[string equal [winfo toplevel $cur] $cur]} {
1317
+ break
1318
+ }
1319
+ set parent [winfo parent $parent]
1320
+ set children [winfo children $parent]
1321
+ set i [lsearch -exact $children $cur]
1322
+ }
1323
+ if {[string equal $cur $w] || [focusOK $cur]} {
1324
+ return $cur
1325
+ }
1326
+ }
1327
+ }
1328
+
1329
+
1330
+ # -----------------------------------------------------------------------------
1331
+ # Command Widget::focusPrev
1332
+ # Same as tk_focusPrev, except:
1333
+ # + Don't traverse from a child to a direct ancestor
1334
+ # + Call Widget::focusOK instead of tk::focusOK
1335
+ # -----------------------------------------------------------------------------
1336
+ proc Widget::focusPrev { w } {
1337
+ set cur $w
1338
+ set origParent [winfo parent $w]
1339
+ while 1 {
1340
+
1341
+ # Collect information about the current window's position
1342
+ # among its siblings. Also, if the window is a top-level,
1343
+ # then reposition to just after the last child of the window.
1344
+
1345
+ if {[string equal [winfo toplevel $cur] $cur]} {
1346
+ set parent $cur
1347
+ set children [winfo children $cur]
1348
+ set i [llength $children]
1349
+ } else {
1350
+ set parent [winfo parent $cur]
1351
+ set children [winfo children $parent]
1352
+ set i [lsearch -exact $children $cur]
1353
+ }
1354
+
1355
+ # Go to the previous sibling, then descend to its last descendant
1356
+ # (highest in stacking order. While doing this, ignore top-levels
1357
+ # and their descendants. When we run out of descendants, go up
1358
+ # one level to the parent.
1359
+
1360
+ while {$i > 0} {
1361
+ incr i -1
1362
+ set cur [lindex $children $i]
1363
+ if {[string equal [winfo toplevel $cur] $cur]} {
1364
+ continue
1365
+ }
1366
+ set parent $cur
1367
+ set children [winfo children $parent]
1368
+ set i [llength $children]
1369
+ }
1370
+ set cur $parent
1371
+ if {[string equal $cur $w]} {
1372
+ return $cur
1373
+ }
1374
+ # If we are just at the original parent of $w, skip it as a
1375
+ # potential focus accepter. Extra safety in this is to see if
1376
+ # that parent is also a proc (not a C command), which is what
1377
+ # BWidgets makes for any megawidget. Could possibly also check
1378
+ # for '[info commands ::${origParent}:cmd] != ""'. [Bug 765667]
1379
+ if {[string equal $cur $origParent]
1380
+ && [info procs ::$origParent] != ""} {
1381
+ continue
1382
+ }
1383
+ if {[focusOK $cur]} {
1384
+ return $cur
1385
+ }
1386
+ }
1387
+ }
1388
+
1389
+
1390
+ # ----------------------------------------------------------------------------
1391
+ # Command Widget::focusOK
1392
+ # Same as tk_focusOK, but handles -editable option and whole tags list.
1393
+ # ----------------------------------------------------------------------------
1394
+ proc Widget::focusOK { w } {
1395
+ set code [catch {$w cget -takefocus} value]
1396
+ if { $code == 1 } {
1397
+ return 0
1398
+ }
1399
+ if {($code == 0) && ($value != "")} {
1400
+ if {$value == 0} {
1401
+ return 0
1402
+ } elseif {$value == 1} {
1403
+ return [winfo viewable $w]
1404
+ } else {
1405
+ set value [uplevel \#0 $value $w]
1406
+ if {$value != ""} {
1407
+ return $value
1408
+ }
1409
+ }
1410
+ }
1411
+ if {![winfo viewable $w]} {
1412
+ return 0
1413
+ }
1414
+ set code [catch {$w cget -state} value]
1415
+ if {($code == 0) && ($value == "disabled")} {
1416
+ return 0
1417
+ }
1418
+ set code [catch {$w cget -editable} value]
1419
+ if {($code == 0) && ($value == 0)} {
1420
+ return 0
1421
+ }
1422
+
1423
+ set top [winfo toplevel $w]
1424
+ foreach tags [bindtags $w] {
1425
+ if { ![string equal $tags $top] &&
1426
+ ![string equal $tags "all"] &&
1427
+ [regexp Key [bind $tags]] } {
1428
+ return 1
1429
+ }
1430
+ }
1431
+ return 0
1432
+ }
1433
+
1434
+
1435
+ proc Widget::traverseTo { w } {
1436
+ set focus [focus]
1437
+ if {![string equal $focus ""]} {
1438
+ event generate $focus <<TraverseOut>>
1439
+ }
1440
+ focus $w
1441
+
1442
+ event generate $w <<TraverseIn>>
1443
+ }
1444
+
1445
+
1446
+ # Widget::varForOption --
1447
+ #
1448
+ # Retrieve a fully qualified variable name for the option specified.
1449
+ # If the option is not one for which a variable exists, throw an error
1450
+ # (ie, those options that map directly to widget options).
1451
+ #
1452
+ # Arguments:
1453
+ # path megawidget to get an option var for.
1454
+ # option option to get a var for.
1455
+ #
1456
+ # Results:
1457
+ # varname name of the variable, fully qualified, suitable for tracing.
1458
+
1459
+ proc Widget::varForOption {path option} {
1460
+ variable _class
1461
+ variable _optiontype
1462
+
1463
+ set class $_class($path)
1464
+ upvar 0 ${class}::$path:opt pathopt
1465
+
1466
+ if { ![info exists pathopt($option)] } {
1467
+ error "unable to find variable for option \"$option\""
1468
+ }
1469
+ set varname "::Widget::${class}::$path:opt($option)"
1470
+ return $varname
1471
+ }
1472
+
1473
+ # Widget::getVariable --
1474
+ #
1475
+ # Get a variable from within the namespace of the widget.
1476
+ #
1477
+ # Arguments:
1478
+ # path Megawidget to get the variable for.
1479
+ # varName The variable name to retrieve.
1480
+ # newVarName The variable name to refer to in the calling proc.
1481
+ #
1482
+ # Results:
1483
+ # Creates a reference to newVarName in the calling proc.
1484
+ proc Widget::getVariable { path varName {newVarName ""} } {
1485
+ variable _class
1486
+ set class $_class($path)
1487
+ if {![string length $newVarName]} { set newVarName $varName }
1488
+ uplevel 1 [list upvar \#0 ${class}::$path:$varName $newVarName]
1489
+ }
1490
+
1491
+ # Widget::options --
1492
+ #
1493
+ # Return a key-value list of options for a widget. This can
1494
+ # be used to serialize the options of a widget and pass them
1495
+ # on to a new widget with the same options.
1496
+ #
1497
+ # Arguments:
1498
+ # path Widget to get the options for.
1499
+ # args A list of options. If empty, all options are returned.
1500
+ #
1501
+ # Results:
1502
+ # Returns list of options as: -option value -option value ...
1503
+ proc Widget::options { path args } {
1504
+ if {[llength $args]} {
1505
+ foreach option $args {
1506
+ lappend options [_get_configure $path $option]
1507
+ }
1508
+ } else {
1509
+ set options [_get_configure $path {}]
1510
+ }
1511
+
1512
+ set result [list]
1513
+ foreach list $options {
1514
+ if {[llength $list] < 5} { continue }
1515
+ lappend result [lindex $list 0] [lindex $list end]
1516
+ }
1517
+ return $result
1518
+ }
1519
+
1520
+
1521
+ # Widget::getOption --
1522
+ #
1523
+ # Given a list of widgets, determine which option value to use.
1524
+ # The widgets are given to the command in order of highest to
1525
+ # lowest. Starting with the lowest widget, whichever one does
1526
+ # not match the default option value is returned as the value.
1527
+ # If all the widgets are default, we return the highest widget's
1528
+ # value.
1529
+ #
1530
+ # Arguments:
1531
+ # option The option to check.
1532
+ # default The default value. If any widget in the list
1533
+ # does not match this default, its value is used.
1534
+ # args A list of widgets.
1535
+ #
1536
+ # Results:
1537
+ # Returns the value of the given option to use.
1538
+ #
1539
+ proc Widget::getOption { option default args } {
1540
+ for {set i [expr [llength $args] -1]} {$i >= 0} {incr i -1} {
1541
+ set widget [lindex $args $i]
1542
+ set value [Widget::cget $widget $option]
1543
+ if {[string equal $value $default]} { continue }
1544
+ return $value
1545
+ }
1546
+ return $value
1547
+ }
1548
+
1549
+
1550
+ proc Widget::nextIndex { path node } {
1551
+ Widget::getVariable $path autoIndex
1552
+ if {![info exists autoIndex]} { set autoIndex -1 }
1553
+ return [string map [list #auto [incr autoIndex]] $node]
1554
+ }
1555
+
1556
+
1557
+ proc Widget::exists { path } {
1558
+ variable _class
1559
+ return [info exists _class($path)]
1560
+ }
1561
+
1562
+ proc Widget::theme {{bool {}}} {
1563
+ # Private, *experimental* API that may change at any time - JH
1564
+ variable _theme
1565
+ if {[llength [info level 0]] == 2} {
1566
+ # set theme-ability
1567
+ if {[catch {package require tile 0.6}]
1568
+ && [catch {package require tile 1}]} {
1569
+ return -code error "BWidget's theming requires tile 0.6+"
1570
+ } else {
1571
+ catch {style default BWSlim.Toolbutton -padding 0}
1572
+ }
1573
+ set _theme [string is true -strict $bool]
1574
+ }
1575
+ return $_theme
1576
+ }