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.
- data/README +126 -123
- data/arcadia.rb +770 -756
- data/base/a-contracts.rb +130 -93
- data/base/a-ext.rb +280 -280
- data/base/a-libs.rb +5 -11
- data/base/a-utils.rb +235 -44
- data/conf/arcadia.conf +20 -16
- data/conf/arcadia.init.rb +0 -0
- data/conf/arcadia.res.rb +74 -0
- data/ext/ae-complete-code/ae-complete-code.conf +0 -0
- data/ext/ae-complete-code/ae-complete-code.rb +80 -79
- data/ext/ae-debug/ae-debug.conf +0 -0
- data/ext/ae-debug/ae-debug.rb +2 -6
- data/ext/ae-debug/debug1.57.rb +0 -0
- data/ext/ae-doc-code/ae-doc-code.conf +15 -0
- data/ext/ae-doc-code/ae-doc-code.rb +289 -0
- data/ext/ae-editor/ae-editor.conf +17 -8
- data/ext/ae-editor/ae-editor.rb +738 -396
- data/ext/ae-event-log/ae-event-log.conf +0 -0
- data/ext/ae-event-log/ae-event-log.rb +0 -0
- data/ext/ae-file-history/ae-file-history.conf +2 -2
- data/ext/ae-file-history/ae-file-history.rb +286 -290
- data/ext/ae-inspector/ae-inspector.conf +0 -0
- data/ext/ae-inspector/ae-inspector.rb +0 -0
- data/ext/ae-output-event/ae-output-event.conf +2 -2
- data/ext/ae-output/ae-output.conf +2 -2
- data/ext/ae-output/ae-output.rb +173 -178
- data/ext/ae-palette/ae-palette.conf +0 -0
- data/ext/ae-palette/ae-palette.rb +0 -0
- data/ext/ae-shell/ae-shell.conf +0 -0
- data/ext/ae-shell/ae-shell.rb +54 -54
- data/lib/tk/al-tk.rb +3076 -3082
- data/lib/tk/al-tk.res.rb +0 -0
- data/lib/tk/al-tkarcadia.rb +0 -0
- data/lib/tk/al-tkcustom.rb +0 -0
- data/lib/tkext/al-bwidget.rb +0 -0
- data/lib/tkext/al-iwidgets.rb +0 -0
- data/lib/tkext/al-tile.rb +0 -0
- data/lib/tkext/al-tktable.rb +0 -0
- data/tcl/BWidget-1.8.0/BWman/ArrowButton.html +276 -0
- data/tcl/BWidget-1.8.0/BWman/BWidget.html +228 -0
- data/tcl/BWidget-1.8.0/BWman/Button.html +273 -0
- data/tcl/BWidget-1.8.0/BWman/ButtonBox.html +264 -0
- data/tcl/BWidget-1.8.0/BWman/ComboBox.html +402 -0
- data/tcl/BWidget-1.8.0/BWman/Dialog.html +314 -0
- data/tcl/BWidget-1.8.0/BWman/DragSite.html +139 -0
- data/tcl/BWidget-1.8.0/BWman/DropSite.html +254 -0
- data/tcl/BWidget-1.8.0/BWman/DynamicHelp.html +248 -0
- data/tcl/BWidget-1.8.0/BWman/Entry.html +341 -0
- data/tcl/BWidget-1.8.0/BWman/Label.html +331 -0
- data/tcl/BWidget-1.8.0/BWman/LabelEntry.html +194 -0
- data/tcl/BWidget-1.8.0/BWman/LabelFrame.html +144 -0
- data/tcl/BWidget-1.8.0/BWman/ListBox.html +678 -0
- data/tcl/BWidget-1.8.0/BWman/MainFrame.html +283 -0
- data/tcl/BWidget-1.8.0/BWman/MessageDlg.html +218 -0
- data/tcl/BWidget-1.8.0/BWman/NoteBook.html +374 -0
- data/tcl/BWidget-1.8.0/BWman/PagesManager.html +180 -0
- data/tcl/BWidget-1.8.0/BWman/PanedWindow.html +142 -0
- data/tcl/BWidget-1.8.0/BWman/PanelFrame.html +153 -0
- data/tcl/BWidget-1.8.0/BWman/PasswdDlg.html +214 -0
- data/tcl/BWidget-1.8.0/BWman/ProgressBar.html +152 -0
- data/tcl/BWidget-1.8.0/BWman/ProgressDlg.html +145 -0
- data/tcl/BWidget-1.8.0/BWman/ScrollView.html +130 -0
- data/tcl/BWidget-1.8.0/BWman/ScrollableFrame.html +191 -0
- data/tcl/BWidget-1.8.0/BWman/ScrolledWindow.html +116 -0
- data/tcl/BWidget-1.8.0/BWman/SelectColor.html +164 -0
- data/tcl/BWidget-1.8.0/BWman/SelectFont.html +152 -0
- data/tcl/BWidget-1.8.0/BWman/Separator.html +77 -0
- data/tcl/BWidget-1.8.0/BWman/SpinBox.html +250 -0
- data/tcl/BWidget-1.8.0/BWman/StatusBar.html +147 -0
- data/tcl/BWidget-1.8.0/BWman/TitleFrame.html +107 -0
- data/tcl/BWidget-1.8.0/BWman/Tree.html +947 -0
- data/tcl/BWidget-1.8.0/BWman/Widget.html +502 -0
- data/tcl/BWidget-1.8.0/BWman/contents.html +84 -0
- data/tcl/BWidget-1.8.0/BWman/index.html +7 -0
- data/tcl/BWidget-1.8.0/BWman/navtree.html +41 -0
- data/tcl/BWidget-1.8.0/BWman/options.htm +458 -0
- data/tcl/BWidget-1.8.0/CHANGES.txt +266 -0
- data/tcl/BWidget-1.8.0/ChangeLog +1641 -0
- data/tcl/BWidget-1.8.0/LICENSE.txt +41 -0
- data/tcl/BWidget-1.8.0/README.txt +127 -0
- data/tcl/BWidget-1.8.0/arrow.tcl +551 -0
- data/tcl/BWidget-1.8.0/bitmap.tcl +94 -0
- data/tcl/BWidget-1.8.0/button.tcl +324 -0
- data/tcl/BWidget-1.8.0/buttonbox.tcl +403 -0
- data/tcl/BWidget-1.8.0/color.tcl +493 -0
- data/tcl/BWidget-1.8.0/combobox.tcl +809 -0
- data/tcl/BWidget-1.8.0/demo/basic.tcl +199 -0
- data/tcl/BWidget-1.8.0/demo/bwidget.xbm +46 -0
- data/tcl/BWidget-1.8.0/demo/demo.tcl +212 -0
- data/tcl/BWidget-1.8.0/demo/dnd.tcl +42 -0
- data/tcl/BWidget-1.8.0/demo/manager.tcl +141 -0
- data/tcl/BWidget-1.8.0/demo/select.tcl +59 -0
- data/tcl/BWidget-1.8.0/demo/tmpldlg.tcl +214 -0
- data/tcl/BWidget-1.8.0/demo/tree.tcl +260 -0
- data/tcl/BWidget-1.8.0/demo/x1.xbm +2258 -0
- data/tcl/BWidget-1.8.0/dialog.tcl +345 -0
- data/tcl/BWidget-1.8.0/dragsite.tcl +197 -0
- data/tcl/BWidget-1.8.0/dropsite.tcl +455 -0
- data/tcl/BWidget-1.8.0/dynhelp.tcl +625 -0
- data/tcl/BWidget-1.8.0/entry.tcl +469 -0
- data/tcl/BWidget-1.8.0/font.tcl +566 -0
- data/tcl/BWidget-1.8.0/images/bold.gif +0 -0
- data/tcl/BWidget-1.8.0/images/copy.gif +0 -0
- data/tcl/BWidget-1.8.0/images/cut.gif +0 -0
- data/tcl/BWidget-1.8.0/images/dragfile.gif +0 -0
- data/tcl/BWidget-1.8.0/images/dragicon.gif +0 -0
- data/tcl/BWidget-1.8.0/images/error.gif +0 -0
- data/tcl/BWidget-1.8.0/images/file.gif +0 -0
- data/tcl/BWidget-1.8.0/images/folder.gif +0 -0
- data/tcl/BWidget-1.8.0/images/hourglass.gif +0 -0
- data/tcl/BWidget-1.8.0/images/info.gif +0 -0
- data/tcl/BWidget-1.8.0/images/italic.gif +0 -0
- data/tcl/BWidget-1.8.0/images/minus.xbm +5 -0
- data/tcl/BWidget-1.8.0/images/new.gif +0 -0
- data/tcl/BWidget-1.8.0/images/opcopy.xbm +5 -0
- data/tcl/BWidget-1.8.0/images/open.gif +0 -0
- data/tcl/BWidget-1.8.0/images/openfold.gif +0 -0
- data/tcl/BWidget-1.8.0/images/oplink.xbm +5 -0
- data/tcl/BWidget-1.8.0/images/opmove.xbm +5 -0
- data/tcl/BWidget-1.8.0/images/overstrike.gif +0 -0
- data/tcl/BWidget-1.8.0/images/palette.gif +0 -0
- data/tcl/BWidget-1.8.0/images/passwd.gif +0 -0
- data/tcl/BWidget-1.8.0/images/paste.gif +0 -0
- data/tcl/BWidget-1.8.0/images/plus.xbm +5 -0
- data/tcl/BWidget-1.8.0/images/print.gif +0 -0
- data/tcl/BWidget-1.8.0/images/question.gif +0 -0
- data/tcl/BWidget-1.8.0/images/redo.gif +0 -0
- data/tcl/BWidget-1.8.0/images/save.gif +0 -0
- data/tcl/BWidget-1.8.0/images/target.xbm +9 -0
- data/tcl/BWidget-1.8.0/images/underline.gif +0 -0
- data/tcl/BWidget-1.8.0/images/undo.gif +0 -0
- data/tcl/BWidget-1.8.0/images/warning.gif +0 -0
- data/tcl/BWidget-1.8.0/init.tcl +40 -0
- data/tcl/BWidget-1.8.0/label.tcl +271 -0
- data/tcl/BWidget-1.8.0/labelentry.tcl +100 -0
- data/tcl/BWidget-1.8.0/labelframe.tcl +160 -0
- data/tcl/BWidget-1.8.0/lang/da.rc +52 -0
- data/tcl/BWidget-1.8.0/lang/de.rc +52 -0
- data/tcl/BWidget-1.8.0/lang/en.rc +52 -0
- data/tcl/BWidget-1.8.0/lang/es.rc +53 -0
- data/tcl/BWidget-1.8.0/lang/fr.rc +52 -0
- data/tcl/BWidget-1.8.0/listbox.tcl +1638 -0
- data/tcl/BWidget-1.8.0/mainframe.tcl +711 -0
- data/tcl/BWidget-1.8.0/messagedlg.tcl +128 -0
- data/tcl/BWidget-1.8.0/notebook.tcl +1164 -0
- data/tcl/BWidget-1.8.0/pagesmgr.tcl +294 -0
- data/tcl/BWidget-1.8.0/panedw.tcl +381 -0
- data/tcl/BWidget-1.8.0/panelframe.tcl +246 -0
- data/tcl/BWidget-1.8.0/passwddlg.tcl +178 -0
- data/tcl/BWidget-1.8.0/pkgIndex.tcl +47 -0
- data/tcl/BWidget-1.8.0/progressbar.tcl +208 -0
- data/tcl/BWidget-1.8.0/progressdlg.tcl +87 -0
- data/tcl/BWidget-1.8.0/scrollframe.tcl +226 -0
- data/tcl/BWidget-1.8.0/scrollview.tcl +254 -0
- data/tcl/BWidget-1.8.0/scrollw.tcl +280 -0
- data/tcl/BWidget-1.8.0/separator.tcl +75 -0
- data/tcl/BWidget-1.8.0/spinbox.tcl +331 -0
- data/tcl/BWidget-1.8.0/statusbar.tcl +422 -0
- data/tcl/BWidget-1.8.0/tests/entry.test +173 -0
- data/tcl/BWidget-1.8.0/titleframe.tcl +170 -0
- data/tcl/BWidget-1.8.0/tree.tcl +2228 -0
- data/tcl/BWidget-1.8.0/utils.tcl +645 -0
- data/tcl/BWidget-1.8.0/widget.tcl +1576 -0
- data/tcl/BWidget-1.8.0/wizard.tcl +1028 -0
- data/tcl/BWidget-1.8.0/xpm2image.tcl +115 -0
- 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
|
+
}
|