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,173 @@
|
|
|
1
|
+
if { [lsearch [package names] tcltest] == -1 } {
|
|
2
|
+
package require tcltest
|
|
3
|
+
namespace import tcltest::*
|
|
4
|
+
}
|
|
5
|
+
lappend auto_path /home/ericm/bwidget
|
|
6
|
+
package require BWidget
|
|
7
|
+
|
|
8
|
+
option add *Entry.borderWidth 2
|
|
9
|
+
option add *Entry.highlightThickness 2
|
|
10
|
+
option add *Entry.font {Helvetica -12}
|
|
11
|
+
option add *Entry.relief sunken
|
|
12
|
+
|
|
13
|
+
Entry .e
|
|
14
|
+
pack .e
|
|
15
|
+
update
|
|
16
|
+
set i 0
|
|
17
|
+
foreach test {
|
|
18
|
+
{-background #ff0000 #ff0000 non-existent \
|
|
19
|
+
{unknown color name "non-existent"}}
|
|
20
|
+
{-bd 4 4 bad Value {bad screen distance "badValue"}}
|
|
21
|
+
{-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}
|
|
22
|
+
{-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
|
|
23
|
+
{-command foo foo {} {}}
|
|
24
|
+
{-disabledforeground blue blue non-existent \
|
|
25
|
+
{unknown color name "non-existent"}}
|
|
26
|
+
{-editable false false shazbot {expected boolean value but got "shazbot"}}
|
|
27
|
+
{-exportselection yes 1 xyzzy {expected boolean value but got "xyzzy"}}
|
|
28
|
+
{-fg #110022 #110022 bogus {unknown color name "bogus"}}
|
|
29
|
+
{-font {Helvetica 12 italic} {Helvetica 12 italic} {} \
|
|
30
|
+
{font "" doesn't exist}}
|
|
31
|
+
{-foreground #110022 #110022 bogus {unknown color name "bogus"}}
|
|
32
|
+
{-highlightbackground #123456 #123456 ugly {unknown color name "ugly"}}
|
|
33
|
+
{-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
|
|
34
|
+
{-highlightthickness 6 6 bogus {bad screen distance "bogus"}}
|
|
35
|
+
{-highlightthickness -2 0 {} {}}
|
|
36
|
+
{-insertbackground #110022 #110022 bogus {unknown color name "bogus"}}
|
|
37
|
+
{-insertborderwidth 1.3 1 2.6x {bad screen distance "2.6x"}}
|
|
38
|
+
{-insertofftime 100 100 3.2 {expected integer but got "3.2"}}
|
|
39
|
+
{-insertontime 100 100 3.2 {expected integer but got "3.2"}}
|
|
40
|
+
{-justify right right bogus \
|
|
41
|
+
{bad justification "bogus": must be left, right, or center}}
|
|
42
|
+
{-relief groove groove 1.5 \
|
|
43
|
+
{bad relief "1.5": must be flat, groove, raised, ridge,\
|
|
44
|
+
solid, or sunken}}
|
|
45
|
+
{-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
|
|
46
|
+
{-selectborderwidth 1.3 1 badValue {bad screen distance "badValue"}}
|
|
47
|
+
{-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}
|
|
48
|
+
{-show * * {} {}}
|
|
49
|
+
{-state normal normal bogus \
|
|
50
|
+
{bad state "bogus": must be disabled or normal}}
|
|
51
|
+
{-takefocus "any string" "any string" {} {}}
|
|
52
|
+
{-text foobar foobar {} {}}
|
|
53
|
+
{-textvariable i i {} {}}
|
|
54
|
+
{-width 402 402 3p {expected integer but got "3p"}}
|
|
55
|
+
{-xscrollcommand {Some command} {Some command} {} {}}
|
|
56
|
+
} {
|
|
57
|
+
set name [lindex $test 0]
|
|
58
|
+
test entry-1.$i {configuration options} {
|
|
59
|
+
.e configure $name [lindex $test 1]
|
|
60
|
+
list [lindex [.e configure $name] 4] [.e cget $name]
|
|
61
|
+
} [list [lindex $test 2] [lindex $test 2]]
|
|
62
|
+
incr i
|
|
63
|
+
}
|
|
64
|
+
destroy .e
|
|
65
|
+
|
|
66
|
+
test Entry-2.1 {Entry} {
|
|
67
|
+
list [catch {Entry} msg] $msg
|
|
68
|
+
} {1 {no value given for parameter "path" to "Entry"}}
|
|
69
|
+
test Entry-2.2 {Entry} {
|
|
70
|
+
list [catch {Entry gorp} msg] $msg
|
|
71
|
+
} {1 {bad window path name "gorp"}}
|
|
72
|
+
test Entry-2.3 {Entry procedure} {
|
|
73
|
+
Entry .e
|
|
74
|
+
set res [list [winfo exists .e] [winfo class .e] [info commands .e]]
|
|
75
|
+
destroy .e
|
|
76
|
+
set res
|
|
77
|
+
} {1 Entry .e}
|
|
78
|
+
test Entry-2.4 {Entr procedure} {
|
|
79
|
+
list [catch {Entry .e -gorp foo} msg] $msg [winfo exists .e] \
|
|
80
|
+
[info commands .e]
|
|
81
|
+
} {1 {unknown option "-gorp"} 0 {}}
|
|
82
|
+
|
|
83
|
+
test Entry-3.1 {disabled state grays widget} {
|
|
84
|
+
Entry .e -disabledforeground blue -foreground red -state normal
|
|
85
|
+
set res [list [.e cget -foreground] [.e cget -disabledforeground] \
|
|
86
|
+
[.e:cmd cget -foreground]]
|
|
87
|
+
.e configure -state disabled
|
|
88
|
+
lappend res [.e:cmd cget -foreground]
|
|
89
|
+
.e configure -state normal
|
|
90
|
+
lappend res [.e:cmd cget -foreground]
|
|
91
|
+
destroy .e
|
|
92
|
+
set res
|
|
93
|
+
} {red blue red blue red}
|
|
94
|
+
test Entry-3.2 {changing disabledforeground of an enabled entry} {
|
|
95
|
+
Entry .e -disabledforeground blue -foreground red -state normal
|
|
96
|
+
set res [list [.e cget -foreground] [.e cget -disabledforeground] \
|
|
97
|
+
[.e:cmd cget -foreground]]
|
|
98
|
+
.e configure -disabledforeground green
|
|
99
|
+
lappend res [.e:cmd cget -foreground]
|
|
100
|
+
destroy .e
|
|
101
|
+
set res
|
|
102
|
+
} {red blue red red}
|
|
103
|
+
test Entry-3.3 {changing normal foreground of a disabled entry} {
|
|
104
|
+
Entry .e -disabledforeground blue -foreground red -state disabled
|
|
105
|
+
set res [list [.e cget -foreground] [.e cget -disabledforeground] \
|
|
106
|
+
[.e:cmd cget -foreground]]
|
|
107
|
+
.e configure -foreground green
|
|
108
|
+
lappend res [.e:cmd cget -foreground]
|
|
109
|
+
destroy .e
|
|
110
|
+
set res
|
|
111
|
+
} {red blue blue blue}
|
|
112
|
+
test Entry-3.4 {changing disabled foreground of a disabled entry} {
|
|
113
|
+
Entry .e -disabledforeground blue -foreground red -state disabled
|
|
114
|
+
set res [list [.e cget -foreground] [.e cget -disabledforeground] \
|
|
115
|
+
[.e:cmd cget -foreground]]
|
|
116
|
+
.e configure -disabledforeground green
|
|
117
|
+
lappend res [.e:cmd cget -foreground]
|
|
118
|
+
destroy .e
|
|
119
|
+
set res
|
|
120
|
+
} {red blue blue green}
|
|
121
|
+
|
|
122
|
+
test Entry-4.1 {editable flag enables/disables editing} {
|
|
123
|
+
Entry .e -editable true
|
|
124
|
+
set res [expr {[lsearch [bindtags .e] BwDisabledEntry] == -1}]
|
|
125
|
+
.e configure -editable false
|
|
126
|
+
lappend res [expr {[lsearch [bindtags .e] BwDisabledEntry] != -1}]
|
|
127
|
+
destroy .e
|
|
128
|
+
set res
|
|
129
|
+
} {1 1}
|
|
130
|
+
test Entry-4.2 {editable flag does not impact foreground color} {
|
|
131
|
+
Entry .e -editable 1 -foreground red -disabledforeground blue -state normal
|
|
132
|
+
set res [list [.e:cmd cget -foreground]]
|
|
133
|
+
.e configure -editable false
|
|
134
|
+
lappend res [.e:cmd cget -foreground]
|
|
135
|
+
destroy .e
|
|
136
|
+
set res
|
|
137
|
+
} {red red}
|
|
138
|
+
test Entry-4.3 {editable flag changes cursor} {
|
|
139
|
+
Entry .e -editable 1
|
|
140
|
+
set res [list [.e:cmd cget -cursor]]
|
|
141
|
+
.e configure -editable 0
|
|
142
|
+
lappend res [.e:cmd cget -cursor]
|
|
143
|
+
destroy .e
|
|
144
|
+
set res
|
|
145
|
+
} [list xterm left_ptr]
|
|
146
|
+
|
|
147
|
+
test Entry-5.1 {-text flag gets entry text} {
|
|
148
|
+
Entry .e
|
|
149
|
+
.e delete 0 end
|
|
150
|
+
.e insert end foobar
|
|
151
|
+
set res [.e cget -text]
|
|
152
|
+
destroy .e
|
|
153
|
+
set res
|
|
154
|
+
} foobar
|
|
155
|
+
test Entry-5.2 {-text flag sets entry text} {
|
|
156
|
+
Entry .e
|
|
157
|
+
.e delete 0 end
|
|
158
|
+
.e configure -text barbaz
|
|
159
|
+
set res [.e get]
|
|
160
|
+
destroy .e
|
|
161
|
+
set res
|
|
162
|
+
} barbaz
|
|
163
|
+
|
|
164
|
+
test Entry-6.1 {-command works} {
|
|
165
|
+
set ::foo 0
|
|
166
|
+
Entry .e -command {incr ::foo}
|
|
167
|
+
Entry::invoke .e
|
|
168
|
+
destroy .e
|
|
169
|
+
set ::foo
|
|
170
|
+
} 1
|
|
171
|
+
|
|
172
|
+
tcltest::cleanupTests
|
|
173
|
+
exit
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# ------------------------------------------------------------------------------
|
|
2
|
+
# titleframe.tcl
|
|
3
|
+
# This file is part of Unifix BWidget Toolkit
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Index of commands:
|
|
6
|
+
# - TitleFrame::create
|
|
7
|
+
# - TitleFrame::configure
|
|
8
|
+
# - TitleFrame::cget
|
|
9
|
+
# - TitleFrame::getframe
|
|
10
|
+
# - TitleFrame::_place
|
|
11
|
+
# ------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
namespace eval TitleFrame {
|
|
14
|
+
Widget::define TitleFrame titleframe
|
|
15
|
+
|
|
16
|
+
Widget::declare TitleFrame {
|
|
17
|
+
{-relief TkResource groove 0 frame}
|
|
18
|
+
{-borderwidth TkResource 2 0 frame}
|
|
19
|
+
{-font TkResource "" 0 label}
|
|
20
|
+
{-foreground TkResource "" 0 label}
|
|
21
|
+
{-state TkResource "" 0 label}
|
|
22
|
+
{-background TkResource "" 0 frame}
|
|
23
|
+
{-text String "" 0}
|
|
24
|
+
{-ipad Int 4 0 "%d >=0"}
|
|
25
|
+
{-side Enum left 0 {left center right}}
|
|
26
|
+
{-baseline Enum center 0 {top center bottom}}
|
|
27
|
+
{-fg Synonym -foreground}
|
|
28
|
+
{-bg Synonym -background}
|
|
29
|
+
{-bd Synonym -borderwidth}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Widget::addmap TitleFrame "" :cmd {-background {}}
|
|
33
|
+
Widget::addmap TitleFrame "" .l {
|
|
34
|
+
-background {} -foreground {} -text {} -font {}
|
|
35
|
+
}
|
|
36
|
+
Widget::addmap TitleFrame "" .l {-state {}}
|
|
37
|
+
Widget::addmap TitleFrame "" .p {-background {}}
|
|
38
|
+
Widget::addmap TitleFrame "" .b {
|
|
39
|
+
-background {} -relief {} -borderwidth {}
|
|
40
|
+
}
|
|
41
|
+
Widget::addmap TitleFrame "" .b.p {-background {}}
|
|
42
|
+
Widget::addmap TitleFrame "" .f {-background {}}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ------------------------------------------------------------------------------
|
|
47
|
+
# Command TitleFrame::create
|
|
48
|
+
# ------------------------------------------------------------------------------
|
|
49
|
+
proc TitleFrame::create { path args } {
|
|
50
|
+
Widget::init TitleFrame $path $args
|
|
51
|
+
|
|
52
|
+
set frame [eval [list frame $path] [Widget::subcget $path :cmd] \
|
|
53
|
+
-class TitleFrame -relief flat -bd 0 -highlightthickness 0]
|
|
54
|
+
|
|
55
|
+
set padtop [eval [list frame $path.p] [Widget::subcget $path :cmd] \
|
|
56
|
+
-relief flat -borderwidth 0]
|
|
57
|
+
set border [eval [list frame $path.b] [Widget::subcget $path .b] -highlightthickness 0]
|
|
58
|
+
set label [eval [list label $path.l] [Widget::subcget $path .l] \
|
|
59
|
+
-highlightthickness 0 \
|
|
60
|
+
-relief flat \
|
|
61
|
+
-bd 0 -padx 2 -pady 0]
|
|
62
|
+
set padbot [eval [list frame $border.p] [Widget::subcget $path .p] \
|
|
63
|
+
-relief flat -bd 0 -highlightthickness 0]
|
|
64
|
+
set frame [eval [list frame $path.f] [Widget::subcget $path .f] \
|
|
65
|
+
-relief flat -bd 0 -highlightthickness 0]
|
|
66
|
+
set height [winfo reqheight $label]
|
|
67
|
+
|
|
68
|
+
switch [Widget::getoption $path -side] {
|
|
69
|
+
left { set relx 0.0; set x 5; set anchor nw }
|
|
70
|
+
center { set relx 0.5; set x 0; set anchor n }
|
|
71
|
+
right { set relx 1.0; set x -5; set anchor ne }
|
|
72
|
+
}
|
|
73
|
+
set bd [Widget::getoption $path -borderwidth]
|
|
74
|
+
switch [Widget::getoption $path -baseline] {
|
|
75
|
+
top {
|
|
76
|
+
set y 0
|
|
77
|
+
set htop $height
|
|
78
|
+
set hbot 1
|
|
79
|
+
}
|
|
80
|
+
center {
|
|
81
|
+
set y 0
|
|
82
|
+
set htop [expr {$height/2}]
|
|
83
|
+
set hbot [expr {$height/2+$height%2+1}]
|
|
84
|
+
}
|
|
85
|
+
bottom {
|
|
86
|
+
set y [expr {$bd+1}]
|
|
87
|
+
set htop 1
|
|
88
|
+
set hbot $height
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
$padtop configure -height $htop
|
|
92
|
+
$padbot configure -height $hbot
|
|
93
|
+
|
|
94
|
+
set pad [Widget::getoption $path -ipad]
|
|
95
|
+
pack $padbot -side top -fill x
|
|
96
|
+
pack $frame -in $border -fill both -expand yes -padx $pad -pady $pad
|
|
97
|
+
|
|
98
|
+
pack $padtop -side top -fill x
|
|
99
|
+
pack $border -fill both -expand yes
|
|
100
|
+
|
|
101
|
+
place $label -relx $relx -x $x -anchor $anchor -y $y
|
|
102
|
+
|
|
103
|
+
bind $label <Configure> [list TitleFrame::_place $path]
|
|
104
|
+
bind $path <Destroy> [list Widget::destroy %W]
|
|
105
|
+
|
|
106
|
+
return [Widget::create TitleFrame $path]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# ------------------------------------------------------------------------------
|
|
111
|
+
# Command TitleFrame::configure
|
|
112
|
+
# ------------------------------------------------------------------------------
|
|
113
|
+
proc TitleFrame::configure { path args } {
|
|
114
|
+
set res [Widget::configure $path $args]
|
|
115
|
+
|
|
116
|
+
if { [Widget::hasChanged $path -ipad pad] } {
|
|
117
|
+
pack configure $path.f -padx $pad -pady $pad
|
|
118
|
+
}
|
|
119
|
+
if { [Widget::hasChanged $path -borderwidth val] |
|
|
120
|
+
[Widget::hasChanged $path -font val] |
|
|
121
|
+
[Widget::hasChanged $path -side val] |
|
|
122
|
+
[Widget::hasChanged $path -baseline val] } {
|
|
123
|
+
_place $path
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return $res
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# ------------------------------------------------------------------------------
|
|
131
|
+
# Command TitleFrame::cget
|
|
132
|
+
# ------------------------------------------------------------------------------
|
|
133
|
+
proc TitleFrame::cget { path option } {
|
|
134
|
+
return [Widget::cget $path $option]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# ------------------------------------------------------------------------------
|
|
139
|
+
# Command TitleFrame::getframe
|
|
140
|
+
# ------------------------------------------------------------------------------
|
|
141
|
+
proc TitleFrame::getframe { path } {
|
|
142
|
+
return $path.f
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ------------------------------------------------------------------------------
|
|
147
|
+
# Command TitleFrame::_place
|
|
148
|
+
# ------------------------------------------------------------------------------
|
|
149
|
+
proc TitleFrame::_place { path } {
|
|
150
|
+
set height [winfo height $path.l]
|
|
151
|
+
switch [Widget::getoption $path -side] {
|
|
152
|
+
left { set relx 0.0; set x 10; set anchor nw }
|
|
153
|
+
center { set relx 0.5; set x 0; set anchor n }
|
|
154
|
+
right { set relx 1.0; set x -10; set anchor ne }
|
|
155
|
+
}
|
|
156
|
+
set bd [Widget::getoption $path -borderwidth]
|
|
157
|
+
switch [Widget::getoption $path -baseline] {
|
|
158
|
+
top { set htop $height; set hbot 1; set y 0 }
|
|
159
|
+
center { set htop [expr {$height/2}]; set hbot [expr {$height/2+$height%2+1}]; set y 0 }
|
|
160
|
+
bottom { set htop 1; set hbot $height; set y [expr {$bd+1}] }
|
|
161
|
+
}
|
|
162
|
+
$path.p configure -height $htop
|
|
163
|
+
$path.b.p configure -height $hbot
|
|
164
|
+
|
|
165
|
+
place $path.l -relx $relx -x $x -anchor $anchor -y $y
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
@@ -0,0 +1,2228 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------
|
|
2
|
+
# tree.tcl
|
|
3
|
+
# This file is part of Unifix BWidget Toolkit
|
|
4
|
+
# $Id: tree.tcl,v 1.54 2006/09/28 15:46:06 dev_null42a Exp $
|
|
5
|
+
# ----------------------------------------------------------------------------
|
|
6
|
+
# Index of commands:
|
|
7
|
+
# - Tree::create
|
|
8
|
+
# - Tree::configure
|
|
9
|
+
# - Tree::cget
|
|
10
|
+
# - Tree::insert
|
|
11
|
+
# - Tree::itemconfigure
|
|
12
|
+
# - Tree::itemcget
|
|
13
|
+
# - Tree::bindArea
|
|
14
|
+
# - Tree::bindText
|
|
15
|
+
# - Tree::bindImage
|
|
16
|
+
# - Tree::delete
|
|
17
|
+
# - Tree::move
|
|
18
|
+
# - Tree::reorder
|
|
19
|
+
# - Tree::selection
|
|
20
|
+
# - Tree::exists
|
|
21
|
+
# - Tree::parent
|
|
22
|
+
# - Tree::index
|
|
23
|
+
# - Tree::nodes
|
|
24
|
+
# - Tree::see
|
|
25
|
+
# - Tree::opentree
|
|
26
|
+
# - Tree::closetree
|
|
27
|
+
# - Tree::edit
|
|
28
|
+
# - Tree::xview
|
|
29
|
+
# - Tree::yview
|
|
30
|
+
# - Tree::_update_edit_size
|
|
31
|
+
# - Tree::_destroy
|
|
32
|
+
# - Tree::_see
|
|
33
|
+
# - Tree::_recexpand
|
|
34
|
+
# - Tree::_subdelete
|
|
35
|
+
# - Tree::_update_scrollregion
|
|
36
|
+
# - Tree::_cross_event
|
|
37
|
+
# - Tree::_draw_node
|
|
38
|
+
# - Tree::_draw_subnodes
|
|
39
|
+
# - Tree::_update_nodes
|
|
40
|
+
# - Tree::_draw_tree
|
|
41
|
+
# - Tree::_redraw_tree
|
|
42
|
+
# - Tree::_redraw_selection
|
|
43
|
+
# - Tree::_redraw_idle
|
|
44
|
+
# - Tree::_drag_cmd
|
|
45
|
+
# - Tree::_drop_cmd
|
|
46
|
+
# - Tree::_over_cmd
|
|
47
|
+
# - Tree::_auto_scroll
|
|
48
|
+
# - Tree::_scroll
|
|
49
|
+
# ----------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
namespace eval Tree {
|
|
52
|
+
Widget::define Tree tree DragSite DropSite DynamicHelp
|
|
53
|
+
|
|
54
|
+
namespace eval Node {
|
|
55
|
+
Widget::declare Tree::Node {
|
|
56
|
+
{-text String "" 0}
|
|
57
|
+
{-font TkResource "" 0 listbox}
|
|
58
|
+
{-image TkResource "" 0 label}
|
|
59
|
+
{-window String "" 0}
|
|
60
|
+
{-fill TkResource black 0 {listbox -foreground}}
|
|
61
|
+
{-data String "" 0}
|
|
62
|
+
{-open Boolean 0 0}
|
|
63
|
+
{-selectable Boolean 1 0}
|
|
64
|
+
{-drawcross Enum auto 0 {auto always never allways}}
|
|
65
|
+
{-padx Int -1 0 "%d >= -1"}
|
|
66
|
+
{-deltax Int -1 0 "%d >= -1"}
|
|
67
|
+
{-anchor String "w" 0 ""}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
DynamicHelp::include Tree::Node balloon
|
|
72
|
+
|
|
73
|
+
Widget::tkinclude Tree canvas .c \
|
|
74
|
+
remove {
|
|
75
|
+
-insertwidth -insertbackground -insertborderwidth -insertofftime
|
|
76
|
+
-insertontime -selectborderwidth -closeenough -confine -scrollregion
|
|
77
|
+
-xscrollincrement -yscrollincrement -width -height
|
|
78
|
+
} \
|
|
79
|
+
initialize {
|
|
80
|
+
-relief sunken -borderwidth 2 -takefocus 1
|
|
81
|
+
-highlightthickness 1 -width 200
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Widget::declare Tree {
|
|
85
|
+
{-deltax Int 10 0 "%d >= 0"}
|
|
86
|
+
{-deltay Int 15 0 "%d >= 0"}
|
|
87
|
+
{-padx Int 20 0 "%d >= 0"}
|
|
88
|
+
{-background TkResource "" 0 listbox}
|
|
89
|
+
{-selectbackground TkResource "" 0 listbox}
|
|
90
|
+
{-selectforeground TkResource "" 0 listbox}
|
|
91
|
+
{-selectcommand String "" 0}
|
|
92
|
+
{-width TkResource "" 0 listbox}
|
|
93
|
+
{-height TkResource "" 0 listbox}
|
|
94
|
+
{-selectfill Boolean 0 0}
|
|
95
|
+
{-showlines Boolean 1 0}
|
|
96
|
+
{-linesfill TkResource black 0 {listbox -foreground}}
|
|
97
|
+
{-linestipple TkResource "" 0 {label -bitmap}}
|
|
98
|
+
{-crossfill TkResource black 0 {listbox -foreground}}
|
|
99
|
+
{-redraw Boolean 1 0}
|
|
100
|
+
{-opencmd String "" 0}
|
|
101
|
+
{-closecmd String "" 0}
|
|
102
|
+
{-dropovermode Flag "wpn" 0 "wpn"}
|
|
103
|
+
{-bg Synonym -background}
|
|
104
|
+
|
|
105
|
+
{-crossopenimage String "" 0}
|
|
106
|
+
{-crosscloseimage String "" 0}
|
|
107
|
+
{-crossopenbitmap String "" 0}
|
|
108
|
+
{-crossclosebitmap String "" 0}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
DragSite::include Tree "TREE_NODE" 1
|
|
112
|
+
DropSite::include Tree {
|
|
113
|
+
TREE_NODE {copy {} move {}}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
Widget::addmap Tree "" .c {-deltay -yscrollincrement}
|
|
117
|
+
|
|
118
|
+
# Trees on windows have a white (system window) background
|
|
119
|
+
if { $::tcl_platform(platform) == "windows" } {
|
|
120
|
+
option add *Tree.c.background SystemWindow widgetDefault
|
|
121
|
+
option add *TreeNode.fill SystemWindowText widgetDefault
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
bind Tree <FocusIn> [list after idle {BWidget::refocus %W %W.c}]
|
|
125
|
+
bind Tree <Destroy> [list Tree::_destroy %W]
|
|
126
|
+
bind Tree <Configure> [list Tree::_update_scrollregion %W]
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
bind TreeSentinalStart <Button-1> {
|
|
130
|
+
if { $::Tree::sentinal(%W) } {
|
|
131
|
+
set ::Tree::sentinal(%W) 0
|
|
132
|
+
break
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
bind TreeSentinalEnd <Button-1> {
|
|
137
|
+
set ::Tree::sentinal(%W) 0
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
bind TreeFocus <Button-1> [list focus %W]
|
|
141
|
+
|
|
142
|
+
variable _edit
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ----------------------------------------------------------------------------
|
|
147
|
+
# Command Tree::create
|
|
148
|
+
# ----------------------------------------------------------------------------
|
|
149
|
+
proc Tree::create { path args } {
|
|
150
|
+
variable $path
|
|
151
|
+
upvar 0 $path data
|
|
152
|
+
|
|
153
|
+
Widget::init Tree $path $args
|
|
154
|
+
set ::Tree::sentinal($path.c) 0
|
|
155
|
+
|
|
156
|
+
if {[Widget::cget $path -crossopenbitmap] == ""} {
|
|
157
|
+
set file [file join $::BWIDGET::LIBRARY images "minus.xbm"]
|
|
158
|
+
Widget::configure $path [list -crossopenbitmap @$file]
|
|
159
|
+
}
|
|
160
|
+
if {[Widget::cget $path -crossclosebitmap] == ""} {
|
|
161
|
+
set file [file join $::BWIDGET::LIBRARY images "plus.xbm"]
|
|
162
|
+
Widget::configure $path [list -crossclosebitmap @$file]
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
set data(root) {{}}
|
|
166
|
+
set data(selnodes) {}
|
|
167
|
+
set data(upd,level) 0
|
|
168
|
+
set data(upd,nodes) {}
|
|
169
|
+
set data(upd,afterid) ""
|
|
170
|
+
set data(dnd,scroll) ""
|
|
171
|
+
set data(dnd,afterid) ""
|
|
172
|
+
set data(dnd,selnodes) {}
|
|
173
|
+
set data(dnd,node) ""
|
|
174
|
+
|
|
175
|
+
frame $path -class Tree -bd 0 -highlightthickness 0 -relief flat \
|
|
176
|
+
-takefocus 0
|
|
177
|
+
# For 8.4+ we don't want to inherit the padding
|
|
178
|
+
catch {$path configure -padx 0 -pady 0}
|
|
179
|
+
eval [list canvas $path.c] [Widget::subcget $path .c] -xscrollincrement 8
|
|
180
|
+
bindtags $path.c [list TreeSentinalStart TreeFocus $path.c Canvas \
|
|
181
|
+
[winfo toplevel $path] all TreeSentinalEnd]
|
|
182
|
+
pack $path.c -expand yes -fill both
|
|
183
|
+
$path.c bind cross <ButtonPress-1> [list Tree::_cross_event $path]
|
|
184
|
+
|
|
185
|
+
# Added by ericm@scriptics.com
|
|
186
|
+
# These allow keyboard traversal of the tree
|
|
187
|
+
bind $path.c <KeyPress-Up> [list Tree::_keynav up $path]
|
|
188
|
+
bind $path.c <KeyPress-Down> [list Tree::_keynav down $path]
|
|
189
|
+
bind $path.c <KeyPress-Right> [list Tree::_keynav right $path]
|
|
190
|
+
bind $path.c <KeyPress-Left> [list Tree::_keynav left $path]
|
|
191
|
+
bind $path.c <KeyPress-space> [list +Tree::_keynav space $path]
|
|
192
|
+
|
|
193
|
+
# These allow keyboard control of the scrolling
|
|
194
|
+
bind $path.c <Control-KeyPress-Up> [list $path.c yview scroll -1 units]
|
|
195
|
+
bind $path.c <Control-KeyPress-Down> [list $path.c yview scroll 1 units]
|
|
196
|
+
bind $path.c <Control-KeyPress-Left> [list $path.c xview scroll -1 units]
|
|
197
|
+
bind $path.c <Control-KeyPress-Right> [list $path.c xview scroll 1 units]
|
|
198
|
+
# ericm@scriptics.com
|
|
199
|
+
|
|
200
|
+
BWidget::bindMouseWheel $path.c
|
|
201
|
+
|
|
202
|
+
DragSite::setdrag $path $path.c Tree::_init_drag_cmd \
|
|
203
|
+
[Widget::cget $path -dragendcmd] 1
|
|
204
|
+
DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd 1
|
|
205
|
+
|
|
206
|
+
Widget::create Tree $path
|
|
207
|
+
|
|
208
|
+
set w [Widget::cget $path -width]
|
|
209
|
+
set h [Widget::cget $path -height]
|
|
210
|
+
set dy [Widget::cget $path -deltay]
|
|
211
|
+
$path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]
|
|
212
|
+
|
|
213
|
+
# ericm
|
|
214
|
+
# Bind <Button-1> to select the clicked node -- no reason not to, right?
|
|
215
|
+
|
|
216
|
+
## Bind button 1 to select the node via the _mouse_select command.
|
|
217
|
+
## This command will generate the proper <<TreeSelect>> virtual event
|
|
218
|
+
## when necessary.
|
|
219
|
+
set selectcmd Tree::_mouse_select
|
|
220
|
+
Tree::bindText $path <Button-1> [list $selectcmd $path set]
|
|
221
|
+
Tree::bindImage $path <Button-1> [list $selectcmd $path set]
|
|
222
|
+
Tree::bindText $path <Control-Button-1> [list $selectcmd $path toggle]
|
|
223
|
+
Tree::bindImage $path <Control-Button-1> [list $selectcmd $path toggle]
|
|
224
|
+
|
|
225
|
+
# Add sentinal bindings for double-clicking on items, to handle the
|
|
226
|
+
# gnarly Tk bug wherein:
|
|
227
|
+
# ButtonClick
|
|
228
|
+
# ButtonClick
|
|
229
|
+
# On a canvas item translates into button click on the item, button click
|
|
230
|
+
# on the canvas, double-button on the item, single button click on the
|
|
231
|
+
# canvas (which can happen if the double-button on the item causes some
|
|
232
|
+
# other event to be handled in between when the button clicks are examined
|
|
233
|
+
# for the canvas)
|
|
234
|
+
$path.c bind TreeItemSentinal <Double-Button-1> \
|
|
235
|
+
[list set ::Tree::sentinal($path.c) 1]
|
|
236
|
+
# ericm
|
|
237
|
+
|
|
238
|
+
return $path
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# ----------------------------------------------------------------------------
|
|
243
|
+
# Command Tree::configure
|
|
244
|
+
# ----------------------------------------------------------------------------
|
|
245
|
+
proc Tree::configure { path args } {
|
|
246
|
+
variable $path
|
|
247
|
+
upvar 0 $path data
|
|
248
|
+
|
|
249
|
+
set res [Widget::configure $path $args]
|
|
250
|
+
|
|
251
|
+
set ch1 [expr {[Widget::hasChanged $path -deltax val] |
|
|
252
|
+
[Widget::hasChanged $path -deltay dy] |
|
|
253
|
+
[Widget::hasChanged $path -padx val] |
|
|
254
|
+
[Widget::hasChanged $path -showlines val]}]
|
|
255
|
+
|
|
256
|
+
set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
|
|
257
|
+
[Widget::hasChanged $path -selectforeground val]}]
|
|
258
|
+
|
|
259
|
+
if { [Widget::hasChanged $path -linesfill fill] |
|
|
260
|
+
[Widget::hasChanged $path -linestipple stipple] } {
|
|
261
|
+
$path.c itemconfigure line -fill $fill -stipple $stipple
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if { [Widget::hasChanged $path -crossfill fill] } {
|
|
265
|
+
$path.c itemconfigure cross -foreground $fill
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if {[Widget::hasChanged $path -selectfill fill]} {
|
|
269
|
+
# Make sure that the full-width boxes have either all or none
|
|
270
|
+
# of the standard node bindings
|
|
271
|
+
if {$fill} {
|
|
272
|
+
foreach event [$path.c bind "node"] {
|
|
273
|
+
$path.c bind "box" $event [$path.c bind "node" $event]
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
foreach event [$path.c bind "node"] {
|
|
277
|
+
$path.c bind "box" $event {}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if { $ch1 } {
|
|
283
|
+
_redraw_idle $path 3
|
|
284
|
+
} elseif { $ch2 } {
|
|
285
|
+
_redraw_idle $path 1
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if { [Widget::hasChanged $path -height h] } {
|
|
289
|
+
$path.c configure -height [expr {$h*$dy}]
|
|
290
|
+
}
|
|
291
|
+
if { [Widget::hasChanged $path -width w] } {
|
|
292
|
+
$path.c configure -width [expr {$w*8}]
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if { [Widget::hasChanged $path -redraw bool] && $bool } {
|
|
296
|
+
set upd $data(upd,level)
|
|
297
|
+
set data(upd,level) 0
|
|
298
|
+
_redraw_idle $path $upd
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
set force [Widget::hasChanged $path -dragendcmd dragend]
|
|
302
|
+
DragSite::setdrag $path $path.c Tree::_init_drag_cmd $dragend $force
|
|
303
|
+
DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd
|
|
304
|
+
|
|
305
|
+
return $res
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
# ----------------------------------------------------------------------------
|
|
310
|
+
# Command Tree::cget
|
|
311
|
+
# ----------------------------------------------------------------------------
|
|
312
|
+
proc Tree::cget { path option } {
|
|
313
|
+
return [Widget::cget $path $option]
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
# ----------------------------------------------------------------------------
|
|
318
|
+
# Command Tree::insert
|
|
319
|
+
# ----------------------------------------------------------------------------
|
|
320
|
+
proc Tree::insert { path index parent node args } {
|
|
321
|
+
variable $path
|
|
322
|
+
upvar 0 $path data
|
|
323
|
+
|
|
324
|
+
set node [_node_name $path $node]
|
|
325
|
+
set node [Widget::nextIndex $path $node]
|
|
326
|
+
|
|
327
|
+
if { [info exists data($node)] } {
|
|
328
|
+
return -code error "node \"$node\" already exists"
|
|
329
|
+
}
|
|
330
|
+
if { ![info exists data($parent)] } {
|
|
331
|
+
return -code error "node \"$parent\" does not exist"
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
Widget::init Tree::Node $path.$node $args
|
|
335
|
+
if {[string equal $index "end"]} {
|
|
336
|
+
lappend data($parent) $node
|
|
337
|
+
} else {
|
|
338
|
+
incr index
|
|
339
|
+
set data($parent) [linsert $data($parent) $index $node]
|
|
340
|
+
}
|
|
341
|
+
set data($node) [list $parent]
|
|
342
|
+
|
|
343
|
+
if { [string equal $parent "root"] } {
|
|
344
|
+
_redraw_idle $path 3
|
|
345
|
+
} elseif { [visible $path $parent] } {
|
|
346
|
+
# parent is visible...
|
|
347
|
+
if { [Widget::getMegawidgetOption $path.$parent -open] } {
|
|
348
|
+
# ...and opened -> redraw whole
|
|
349
|
+
_redraw_idle $path 3
|
|
350
|
+
} else {
|
|
351
|
+
# ...and closed -> redraw cross
|
|
352
|
+
lappend data(upd,nodes) $parent 8
|
|
353
|
+
_redraw_idle $path 2
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return $node
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
# ----------------------------------------------------------------------------
|
|
362
|
+
# Command Tree::itemconfigure
|
|
363
|
+
# ----------------------------------------------------------------------------
|
|
364
|
+
proc Tree::itemconfigure { path node args } {
|
|
365
|
+
variable $path
|
|
366
|
+
upvar 0 $path data
|
|
367
|
+
|
|
368
|
+
set node [_node_name $path $node]
|
|
369
|
+
if { [string equal $node "root"] || ![info exists data($node)] } {
|
|
370
|
+
return -code error "node \"$node\" does not exist"
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
set result [Widget::configure $path.$node $args]
|
|
374
|
+
|
|
375
|
+
_set_help $path $node
|
|
376
|
+
|
|
377
|
+
if { [visible $path $node] } {
|
|
378
|
+
set lopt {}
|
|
379
|
+
set flag 0
|
|
380
|
+
foreach opt {-window -image -drawcross -font -text -fill} {
|
|
381
|
+
set flag [expr {$flag << 1}]
|
|
382
|
+
if { [Widget::hasChanged $path.$node $opt val] } {
|
|
383
|
+
set flag [expr {$flag | 1}]
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if { [Widget::hasChanged $path.$node -open val] } {
|
|
388
|
+
if {[llength $data($node)] > 1} {
|
|
389
|
+
# node have subnodes - full redraw
|
|
390
|
+
_redraw_idle $path 3
|
|
391
|
+
} else {
|
|
392
|
+
# force a redraw of the plus/minus sign
|
|
393
|
+
set flag [expr {$flag | 8}]
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if {$data(upd,level) < 3 && [Widget::hasChanged $path.$node -padx x]} {
|
|
398
|
+
_redraw_idle $path 3
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if { $data(upd,level) < 3 && $flag } {
|
|
402
|
+
if { [set idx [lsearch -exact $data(upd,nodes) $node]] == -1 } {
|
|
403
|
+
lappend data(upd,nodes) $node $flag
|
|
404
|
+
} else {
|
|
405
|
+
incr idx
|
|
406
|
+
set flag [expr {[lindex $data(upd,nodes) $idx] | $flag}]
|
|
407
|
+
set data(upd,nodes) [lreplace $data(upd,nodes) $idx $idx $flag]
|
|
408
|
+
}
|
|
409
|
+
_redraw_idle $path 2
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return $result
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
# ----------------------------------------------------------------------------
|
|
417
|
+
# Command Tree::itemcget
|
|
418
|
+
# ----------------------------------------------------------------------------
|
|
419
|
+
proc Tree::itemcget { path node option } {
|
|
420
|
+
# Instead of upvar'ing $path as data for this test, just directly refer to
|
|
421
|
+
# it, as that is faster.
|
|
422
|
+
set node [_node_name $path $node]
|
|
423
|
+
if { [string equal $node "root"] || \
|
|
424
|
+
![info exists ::Tree::${path}($node)] } {
|
|
425
|
+
return -code error "node \"$node\" does not exist"
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return [Widget::cget $path.$node $option]
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
# ----------------------------------------------------------------------------
|
|
432
|
+
# Command Tree::bindArea
|
|
433
|
+
# ----------------------------------------------------------------------------
|
|
434
|
+
proc Tree::bindArea { path event script } {
|
|
435
|
+
bind $path.c $event $script
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
# ----------------------------------------------------------------------------
|
|
439
|
+
# Command Tree::bindText
|
|
440
|
+
# ----------------------------------------------------------------------------
|
|
441
|
+
proc Tree::bindText { path event script } {
|
|
442
|
+
if {[string length $script]} {
|
|
443
|
+
append script " \[Tree::_get_node_name [list $path] current 2\]"
|
|
444
|
+
}
|
|
445
|
+
$path.c bind "node" $event $script
|
|
446
|
+
if {[Widget::getoption $path -selectfill]} {
|
|
447
|
+
$path.c bind "box" $event $script
|
|
448
|
+
} else {
|
|
449
|
+
$path.c bind "box" $event {}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
# ----------------------------------------------------------------------------
|
|
455
|
+
# Command Tree::bindImage
|
|
456
|
+
# ----------------------------------------------------------------------------
|
|
457
|
+
proc Tree::bindImage { path event script } {
|
|
458
|
+
if {[string length $script]} {
|
|
459
|
+
append script " \[Tree::_get_node_name [list $path] current 2\]"
|
|
460
|
+
}
|
|
461
|
+
$path.c bind "img" $event $script
|
|
462
|
+
if {[Widget::getoption $path -selectfill]} {
|
|
463
|
+
$path.c bind "box" $event $script
|
|
464
|
+
} else {
|
|
465
|
+
$path.c bind "box" $event {}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
# ----------------------------------------------------------------------------
|
|
471
|
+
# Command Tree::delete
|
|
472
|
+
# ----------------------------------------------------------------------------
|
|
473
|
+
proc Tree::delete { path args } {
|
|
474
|
+
variable $path
|
|
475
|
+
upvar 0 $path data
|
|
476
|
+
|
|
477
|
+
set sel 0
|
|
478
|
+
foreach lnodes $args {
|
|
479
|
+
foreach node $lnodes {
|
|
480
|
+
set node [_node_name $path $node]
|
|
481
|
+
if { ![string equal $node "root"] && [info exists data($node)] } {
|
|
482
|
+
set parent [lindex $data($node) 0]
|
|
483
|
+
set idx [lsearch -exact $data($parent) $node]
|
|
484
|
+
set data($parent) [lreplace $data($parent) $idx $idx]
|
|
485
|
+
incr sel [_subdelete $path [list $node]]
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if {$sel} {
|
|
490
|
+
# if selection changed, call the selectcommand
|
|
491
|
+
__call_selectcmd $path
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
_redraw_idle $path 3
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
# ----------------------------------------------------------------------------
|
|
499
|
+
# Command Tree::move
|
|
500
|
+
# ----------------------------------------------------------------------------
|
|
501
|
+
proc Tree::move { path parent node index } {
|
|
502
|
+
variable $path
|
|
503
|
+
upvar 0 $path data
|
|
504
|
+
|
|
505
|
+
set node [_node_name $path $node]
|
|
506
|
+
if { [string equal $node "root"] || ![info exists data($node)] } {
|
|
507
|
+
return -code error "node \"$node\" does not exist"
|
|
508
|
+
}
|
|
509
|
+
if { ![info exists data($parent)] } {
|
|
510
|
+
return -code error "node \"$parent\" does not exist"
|
|
511
|
+
}
|
|
512
|
+
set p $parent
|
|
513
|
+
while { ![string equal $p "root"] } {
|
|
514
|
+
if { [string equal $p $node] } {
|
|
515
|
+
return -code error "node \"$parent\" is a descendant of \"$node\""
|
|
516
|
+
}
|
|
517
|
+
set p [parent $path $p]
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
set oldp [lindex $data($node) 0]
|
|
521
|
+
set idx [lsearch -exact $data($oldp) $node]
|
|
522
|
+
set data($oldp) [lreplace $data($oldp) $idx $idx]
|
|
523
|
+
set data($node) [concat [list $parent] [lrange $data($node) 1 end]]
|
|
524
|
+
if { [string equal $index "end"] } {
|
|
525
|
+
lappend data($parent) $node
|
|
526
|
+
} else {
|
|
527
|
+
incr index
|
|
528
|
+
set data($parent) [linsert $data($parent) $index $node]
|
|
529
|
+
}
|
|
530
|
+
if { ([string equal $oldp "root"] ||
|
|
531
|
+
([visible $path $oldp] && [Widget::getoption $path.$oldp -open])) ||
|
|
532
|
+
([string equal $parent "root"] ||
|
|
533
|
+
([visible $path $parent] && [Widget::getoption $path.$parent -open])) } {
|
|
534
|
+
_redraw_idle $path 3
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
# ----------------------------------------------------------------------------
|
|
540
|
+
# Command Tree::reorder
|
|
541
|
+
# ----------------------------------------------------------------------------
|
|
542
|
+
proc Tree::reorder { path node neworder } {
|
|
543
|
+
variable $path
|
|
544
|
+
upvar 0 $path data
|
|
545
|
+
|
|
546
|
+
set node [_node_name $path $node]
|
|
547
|
+
if { ![info exists data($node)] } {
|
|
548
|
+
return -code error "node \"$node\" does not exist"
|
|
549
|
+
}
|
|
550
|
+
set children [lrange $data($node) 1 end]
|
|
551
|
+
if { [llength $children] } {
|
|
552
|
+
set children [BWidget::lreorder $children $neworder]
|
|
553
|
+
set data($node) [linsert $children 0 [lindex $data($node) 0]]
|
|
554
|
+
if { [visible $path $node] && [Widget::getoption $path.$node -open] } {
|
|
555
|
+
_redraw_idle $path 3
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
# ----------------------------------------------------------------------------
|
|
562
|
+
# Command Tree::selection
|
|
563
|
+
# ----------------------------------------------------------------------------
|
|
564
|
+
proc Tree::selection { path cmd args } {
|
|
565
|
+
variable $path
|
|
566
|
+
upvar 0 $path data
|
|
567
|
+
|
|
568
|
+
switch -- $cmd {
|
|
569
|
+
toggle {
|
|
570
|
+
foreach node $args {
|
|
571
|
+
set node [_node_name $path $node]
|
|
572
|
+
if {![info exists data($node)]} {
|
|
573
|
+
return -code error \
|
|
574
|
+
"$path selection toggle: Cannot toggle unknown node \"$node\"."
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
foreach node $args {
|
|
578
|
+
set node [_node_name $path $node]
|
|
579
|
+
if {[$path selection includes $node]} {
|
|
580
|
+
$path selection remove $node
|
|
581
|
+
} else {
|
|
582
|
+
$path selection add $node
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
set {
|
|
587
|
+
foreach node $args {
|
|
588
|
+
set node [_node_name $path $node]
|
|
589
|
+
if {![info exists data($node)]} {
|
|
590
|
+
return -code error \
|
|
591
|
+
"$path selection set: Cannot select unknown node \"$node\"."
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
set data(selnodes) {}
|
|
595
|
+
foreach node $args {
|
|
596
|
+
set node [_node_name $path $node]
|
|
597
|
+
if { [Widget::getoption $path.$node -selectable] } {
|
|
598
|
+
if { [lsearch -exact $data(selnodes) $node] == -1 } {
|
|
599
|
+
lappend data(selnodes) $node
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
__call_selectcmd $path
|
|
604
|
+
}
|
|
605
|
+
add {
|
|
606
|
+
foreach node $args {
|
|
607
|
+
set node [_node_name $path $node]
|
|
608
|
+
if {![info exists data($node)]} {
|
|
609
|
+
return -code error \
|
|
610
|
+
"$path selection add: Cannot select unknown node \"$node\"."
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
foreach node $args {
|
|
614
|
+
set node [_node_name $path $node]
|
|
615
|
+
if { [Widget::getoption $path.$node -selectable] } {
|
|
616
|
+
if { [lsearch -exact $data(selnodes) $node] == -1 } {
|
|
617
|
+
lappend data(selnodes) $node
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
__call_selectcmd $path
|
|
622
|
+
}
|
|
623
|
+
range {
|
|
624
|
+
# Here's our algorithm:
|
|
625
|
+
# make a list of all nodes, then take the range from node1
|
|
626
|
+
# to node2 and select those nodes
|
|
627
|
+
#
|
|
628
|
+
# This works because of how this widget handles redraws:
|
|
629
|
+
# The tree is always completely redrawn, and always from
|
|
630
|
+
# top to bottom. So the list of visible nodes *is* the
|
|
631
|
+
# list of nodes, and we can use that to decide which nodes
|
|
632
|
+
# to select.
|
|
633
|
+
|
|
634
|
+
if {[llength $args] != 2} {
|
|
635
|
+
return -code error \
|
|
636
|
+
"wrong#args: Expected $path selection range node1 node2"
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
foreach {node1 node2} $args break
|
|
640
|
+
|
|
641
|
+
set node1 [_node_name $path $node1]
|
|
642
|
+
set node2 [_node_name $path $node2]
|
|
643
|
+
if {![info exists data($node1)]} {
|
|
644
|
+
return -code error \
|
|
645
|
+
"$path selection range: Cannot start range at unknown node \"$node1\"."
|
|
646
|
+
}
|
|
647
|
+
if {![info exists data($node2)]} {
|
|
648
|
+
return -code error \
|
|
649
|
+
"$path selection range: Cannot end range at unknown node \"$node2\"."
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
set nodes {}
|
|
653
|
+
foreach nodeItem [$path.c find withtag node] {
|
|
654
|
+
set node [Tree::_get_node_name $path $nodeItem 2]
|
|
655
|
+
if { [Widget::getoption $path.$node -selectable] } {
|
|
656
|
+
lappend nodes $node
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
# surles: Set the root string to the first element on the list.
|
|
660
|
+
if {$node1 == "root"} {
|
|
661
|
+
set node1 [lindex $nodes 0]
|
|
662
|
+
}
|
|
663
|
+
if {$node2 == "root"} {
|
|
664
|
+
set node2 [lindex $nodes 0]
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
# Find the first visible ancestor of node1, starting with node1
|
|
668
|
+
while {[set index1 [lsearch -exact $nodes $node1]] == -1} {
|
|
669
|
+
set node1 [lindex $data($node1) 0]
|
|
670
|
+
}
|
|
671
|
+
# Find the first visible ancestor of node2, starting with node2
|
|
672
|
+
while {[set index2 [lsearch -exact $nodes $node2]] == -1} {
|
|
673
|
+
set node2 [lindex $data($node2) 0]
|
|
674
|
+
}
|
|
675
|
+
# If the nodes were given in backwards order, flip the
|
|
676
|
+
# indices now
|
|
677
|
+
if { $index2 < $index1 } {
|
|
678
|
+
incr index1 $index2
|
|
679
|
+
set index2 [expr {$index1 - $index2}]
|
|
680
|
+
set index1 [expr {$index1 - $index2}]
|
|
681
|
+
}
|
|
682
|
+
set data(selnodes) [lrange $nodes $index1 $index2]
|
|
683
|
+
__call_selectcmd $path
|
|
684
|
+
}
|
|
685
|
+
remove {
|
|
686
|
+
foreach node $args {
|
|
687
|
+
set node [_node_name $path $node]
|
|
688
|
+
if { [set idx [lsearch -exact $data(selnodes) $node]] != -1 } {
|
|
689
|
+
set data(selnodes) [lreplace $data(selnodes) $idx $idx]
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
__call_selectcmd $path
|
|
693
|
+
}
|
|
694
|
+
clear {
|
|
695
|
+
if {[llength $args] != 0} {
|
|
696
|
+
return -code error \
|
|
697
|
+
"wrong#args: Expected $path selection clear"
|
|
698
|
+
}
|
|
699
|
+
set data(selnodes) {}
|
|
700
|
+
__call_selectcmd $path
|
|
701
|
+
}
|
|
702
|
+
get {
|
|
703
|
+
if {[llength $args] != 0} {
|
|
704
|
+
return -code error \
|
|
705
|
+
"wrong#args: Expected $path selection get"
|
|
706
|
+
}
|
|
707
|
+
return $data(selnodes)
|
|
708
|
+
}
|
|
709
|
+
includes {
|
|
710
|
+
if {[llength $args] != 1} {
|
|
711
|
+
return -code error \
|
|
712
|
+
"wrong#args: Expected $path selection includes node"
|
|
713
|
+
}
|
|
714
|
+
set node [lindex $args 0]
|
|
715
|
+
set node [_node_name $path $node]
|
|
716
|
+
return [expr {[lsearch -exact $data(selnodes) $node] != -1}]
|
|
717
|
+
}
|
|
718
|
+
default {
|
|
719
|
+
return
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
_redraw_idle $path 1
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
proc Tree::getcanvas { path } {
|
|
727
|
+
return $path.c
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
proc Tree::__call_selectcmd { path } {
|
|
732
|
+
variable $path
|
|
733
|
+
upvar 0 $path data
|
|
734
|
+
|
|
735
|
+
set selectcmd [Widget::getoption $path -selectcommand]
|
|
736
|
+
if {[llength $selectcmd]} {
|
|
737
|
+
lappend selectcmd $path
|
|
738
|
+
lappend selectcmd $data(selnodes)
|
|
739
|
+
uplevel \#0 $selectcmd
|
|
740
|
+
}
|
|
741
|
+
return
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
# ----------------------------------------------------------------------------
|
|
745
|
+
# Command Tree::exists
|
|
746
|
+
# ----------------------------------------------------------------------------
|
|
747
|
+
proc Tree::exists { path node } {
|
|
748
|
+
variable $path
|
|
749
|
+
upvar 0 $path data
|
|
750
|
+
|
|
751
|
+
set node [_node_name $path $node]
|
|
752
|
+
return [info exists data($node)]
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
# ----------------------------------------------------------------------------
|
|
757
|
+
# Command Tree::visible
|
|
758
|
+
# ----------------------------------------------------------------------------
|
|
759
|
+
proc Tree::visible { path node } {
|
|
760
|
+
set node [_node_name $path $node]
|
|
761
|
+
set idn [$path.c find withtag n:$node]
|
|
762
|
+
return [llength $idn]
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
# ----------------------------------------------------------------------------
|
|
767
|
+
# Command Tree::parent
|
|
768
|
+
# ----------------------------------------------------------------------------
|
|
769
|
+
proc Tree::parent { path node } {
|
|
770
|
+
variable $path
|
|
771
|
+
upvar 0 $path data
|
|
772
|
+
|
|
773
|
+
set node [_node_name $path $node]
|
|
774
|
+
if { ![info exists data($node)] } {
|
|
775
|
+
return -code error "node \"$node\" does not exist"
|
|
776
|
+
}
|
|
777
|
+
return [lindex $data($node) 0]
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
# ----------------------------------------------------------------------------
|
|
782
|
+
# Command Tree::index
|
|
783
|
+
# ----------------------------------------------------------------------------
|
|
784
|
+
proc Tree::index { path node } {
|
|
785
|
+
variable $path
|
|
786
|
+
upvar 0 $path data
|
|
787
|
+
|
|
788
|
+
set node [_node_name $path $node]
|
|
789
|
+
if { [string equal $node "root"] || ![info exists data($node)] } {
|
|
790
|
+
return -code error "node \"$node\" does not exist"
|
|
791
|
+
}
|
|
792
|
+
set parent [lindex $data($node) 0]
|
|
793
|
+
return [expr {[lsearch -exact $data($parent) $node] - 1}]
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
# ----------------------------------------------------------------------------
|
|
798
|
+
# Tree::find
|
|
799
|
+
# Returns the node given a position.
|
|
800
|
+
# findInfo @x,y ?confine?
|
|
801
|
+
# lineNumber
|
|
802
|
+
# ----------------------------------------------------------------------------
|
|
803
|
+
proc Tree::find {path findInfo {confine ""}} {
|
|
804
|
+
if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
|
|
805
|
+
set x [$path.c canvasx $x]
|
|
806
|
+
set y [$path.c canvasy $y]
|
|
807
|
+
} elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
|
|
808
|
+
set dy [Widget::getoption $path -deltay]
|
|
809
|
+
set y [expr {$dy*($lineNumber+0.5)}]
|
|
810
|
+
set confine ""
|
|
811
|
+
} else {
|
|
812
|
+
return -code error "invalid find spec \"$findInfo\""
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
set found 0
|
|
816
|
+
set region [$path.c bbox all]
|
|
817
|
+
if {[llength $region]} {
|
|
818
|
+
set xi [lindex $region 0]
|
|
819
|
+
set xs [lindex $region 2]
|
|
820
|
+
foreach id [$path.c find overlapping $xi $y $xs $y] {
|
|
821
|
+
set ltags [$path.c gettags $id]
|
|
822
|
+
set item [lindex $ltags 1]
|
|
823
|
+
if { [string equal $item "node"] ||
|
|
824
|
+
[string equal $item "img"] ||
|
|
825
|
+
[string equal $item "win"] } {
|
|
826
|
+
# item is the label or image/window of the node
|
|
827
|
+
set node [Tree::_get_node_name $path $id 2]
|
|
828
|
+
set found 1
|
|
829
|
+
break
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if {$found} {
|
|
835
|
+
if {![string equal $confine ""]} {
|
|
836
|
+
# test if x stand inside node bbox
|
|
837
|
+
set padx [_get_node_padx $path $node]
|
|
838
|
+
set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx}]
|
|
839
|
+
set xs [lindex [$path.c bbox n:$node] 2]
|
|
840
|
+
if {$x >= $xi && $x <= $xs} {
|
|
841
|
+
return $node
|
|
842
|
+
}
|
|
843
|
+
} else {
|
|
844
|
+
return $node
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return ""
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
# ----------------------------------------------------------------------------
|
|
852
|
+
# Command Tree::line
|
|
853
|
+
# Returns the line where a node was drawn.
|
|
854
|
+
# ----------------------------------------------------------------------------
|
|
855
|
+
proc Tree::line {path node} {
|
|
856
|
+
set node [_node_name $path $node]
|
|
857
|
+
set item [$path.c find withtag n:$node]
|
|
858
|
+
if {[string length $item]} {
|
|
859
|
+
set dy [Widget::getoption $path -deltay]
|
|
860
|
+
set y [lindex [$path.c coords $item] 1]
|
|
861
|
+
set line [expr {int($y/$dy)}]
|
|
862
|
+
} else {
|
|
863
|
+
set line -1
|
|
864
|
+
}
|
|
865
|
+
return $line
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
# ----------------------------------------------------------------------------
|
|
870
|
+
# Command Tree::nodes
|
|
871
|
+
# ----------------------------------------------------------------------------
|
|
872
|
+
proc Tree::nodes { path node {first ""} {last ""} } {
|
|
873
|
+
variable $path
|
|
874
|
+
upvar 0 $path data
|
|
875
|
+
|
|
876
|
+
set node [_node_name $path $node]
|
|
877
|
+
if { ![info exists data($node)] } {
|
|
878
|
+
return -code error "node \"$node\" does not exist"
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if { ![string length $first] } {
|
|
882
|
+
return [lrange $data($node) 1 end]
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
if { ![string length $last] } {
|
|
886
|
+
return [lindex [lrange $data($node) 1 end] $first]
|
|
887
|
+
} else {
|
|
888
|
+
return [lrange [lrange $data($node) 1 end] $first $last]
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
# Tree::visiblenodes --
|
|
894
|
+
#
|
|
895
|
+
# Retrieve a list of all the nodes in a tree.
|
|
896
|
+
#
|
|
897
|
+
# Arguments:
|
|
898
|
+
# path tree to retrieve nodes for.
|
|
899
|
+
#
|
|
900
|
+
# Results:
|
|
901
|
+
# nodes list of nodes in the tree.
|
|
902
|
+
|
|
903
|
+
proc Tree::visiblenodes { path } {
|
|
904
|
+
variable $path
|
|
905
|
+
upvar 0 $path data
|
|
906
|
+
|
|
907
|
+
# Root is always open (?), so all of its children automatically get added
|
|
908
|
+
# to the result, and to the stack.
|
|
909
|
+
set st [lrange $data(root) 1 end]
|
|
910
|
+
set result $st
|
|
911
|
+
|
|
912
|
+
while {[llength $st]} {
|
|
913
|
+
set node [lindex $st end]
|
|
914
|
+
set st [lreplace $st end end]
|
|
915
|
+
# Danger, danger! Using getMegawidgetOption is fragile, but much
|
|
916
|
+
# much faster than going through cget.
|
|
917
|
+
if { [Widget::getMegawidgetOption $path.$node -open] } {
|
|
918
|
+
set nodes [lrange $data($node) 1 end]
|
|
919
|
+
set result [concat $result $nodes]
|
|
920
|
+
set st [concat $st $nodes]
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
return $result
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
# ----------------------------------------------------------------------------
|
|
927
|
+
# Command Tree::see
|
|
928
|
+
# ----------------------------------------------------------------------------
|
|
929
|
+
proc Tree::see { path node } {
|
|
930
|
+
variable $path
|
|
931
|
+
upvar 0 $path data
|
|
932
|
+
|
|
933
|
+
set node [_node_name $path $node]
|
|
934
|
+
if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
|
|
935
|
+
after cancel $data(upd,afterid)
|
|
936
|
+
_redraw_tree $path
|
|
937
|
+
}
|
|
938
|
+
set idn [$path.c find withtag n:$node]
|
|
939
|
+
if { $idn != "" } {
|
|
940
|
+
Tree::_see $path $idn
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
# ----------------------------------------------------------------------------
|
|
946
|
+
# Command Tree::opentree
|
|
947
|
+
# ----------------------------------------------------------------------------
|
|
948
|
+
# JDC: added option recursive
|
|
949
|
+
proc Tree::opentree { path node {recursive 1} } {
|
|
950
|
+
variable $path
|
|
951
|
+
upvar 0 $path data
|
|
952
|
+
|
|
953
|
+
set node [_node_name $path $node]
|
|
954
|
+
if { [string equal $node "root"] || ![info exists data($node)] } {
|
|
955
|
+
return -code error "node \"$node\" does not exist"
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
_recexpand $path $node 1 $recursive [Widget::getoption $path -opencmd]
|
|
959
|
+
_redraw_idle $path 3
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
# ----------------------------------------------------------------------------
|
|
964
|
+
# Command Tree::closetree
|
|
965
|
+
# ----------------------------------------------------------------------------
|
|
966
|
+
proc Tree::closetree { path node {recursive 1} } {
|
|
967
|
+
variable $path
|
|
968
|
+
upvar 0 $path data
|
|
969
|
+
|
|
970
|
+
set node [_node_name $path $node]
|
|
971
|
+
if { [string equal $node "root"] || ![info exists data($node)] } {
|
|
972
|
+
return -code error "node \"$node\" does not exist"
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
_recexpand $path $node 0 $recursive [Widget::getoption $path -closecmd]
|
|
976
|
+
_redraw_idle $path 3
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
proc Tree::toggle { path node } {
|
|
981
|
+
if {[$path itemcget $node -open]} {
|
|
982
|
+
$path closetree $node 0
|
|
983
|
+
} else {
|
|
984
|
+
$path opentree $node 0
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
# ----------------------------------------------------------------------------
|
|
990
|
+
# Command Tree::edit
|
|
991
|
+
# ----------------------------------------------------------------------------
|
|
992
|
+
proc Tree::edit { path node text {verifycmd ""} {clickres 0} {select 1}} {
|
|
993
|
+
variable _edit
|
|
994
|
+
variable $path
|
|
995
|
+
upvar 0 $path data
|
|
996
|
+
|
|
997
|
+
set node [_node_name $path $node]
|
|
998
|
+
if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
|
|
999
|
+
after cancel $data(upd,afterid)
|
|
1000
|
+
_redraw_tree $path
|
|
1001
|
+
}
|
|
1002
|
+
set idn [$path.c find withtag n:$node]
|
|
1003
|
+
if { $idn != "" } {
|
|
1004
|
+
Tree::_see $path $idn
|
|
1005
|
+
|
|
1006
|
+
set oldfg [$path.c itemcget $idn -fill]
|
|
1007
|
+
set sbg [Widget::getoption $path -selectbackground]
|
|
1008
|
+
set coords [$path.c coords $idn]
|
|
1009
|
+
set x [lindex $coords 0]
|
|
1010
|
+
set y [lindex $coords 1]
|
|
1011
|
+
set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
|
|
1012
|
+
set w [expr {[winfo width $path] - 2*$bd}]
|
|
1013
|
+
set wmax [expr {[$path.c canvasx $w]-$x}]
|
|
1014
|
+
|
|
1015
|
+
set _edit(text) $text
|
|
1016
|
+
set _edit(wait) 0
|
|
1017
|
+
|
|
1018
|
+
$path.c itemconfigure $idn -fill [Widget::getoption $path -background]
|
|
1019
|
+
$path.c itemconfigure s:$node -fill {} -outline {}
|
|
1020
|
+
|
|
1021
|
+
set frame [frame $path.edit \
|
|
1022
|
+
-relief flat -borderwidth 0 -highlightthickness 0 \
|
|
1023
|
+
-background [Widget::getoption $path -background]]
|
|
1024
|
+
set ent [entry $frame.edit \
|
|
1025
|
+
-width 0 \
|
|
1026
|
+
-relief solid \
|
|
1027
|
+
-borderwidth 1 \
|
|
1028
|
+
-highlightthickness 0 \
|
|
1029
|
+
-foreground [Widget::getoption $path.$node -fill] \
|
|
1030
|
+
-background [Widget::getoption $path -background] \
|
|
1031
|
+
-selectforeground [Widget::getoption $path -selectforeground] \
|
|
1032
|
+
-selectbackground $sbg \
|
|
1033
|
+
-font [Widget::getoption $path.$node -font] \
|
|
1034
|
+
-textvariable Tree::_edit(text)]
|
|
1035
|
+
pack $ent -ipadx 8 -anchor w
|
|
1036
|
+
|
|
1037
|
+
set idw [$path.c create window $x $y -window $frame -anchor w]
|
|
1038
|
+
trace variable Tree::_edit(text) w \
|
|
1039
|
+
[list Tree::_update_edit_size $path $ent $idw $wmax]
|
|
1040
|
+
tkwait visibility $ent
|
|
1041
|
+
grab $frame
|
|
1042
|
+
BWidget::focus set $ent
|
|
1043
|
+
|
|
1044
|
+
_update_edit_size $path $ent $idw $wmax
|
|
1045
|
+
update
|
|
1046
|
+
if { $select } {
|
|
1047
|
+
$ent selection range 0 end
|
|
1048
|
+
$ent icursor end
|
|
1049
|
+
$ent xview end
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
bindtags $ent [list $ent Entry]
|
|
1053
|
+
bind $ent <Escape> {set Tree::_edit(wait) 0}
|
|
1054
|
+
bind $ent <Return> {set Tree::_edit(wait) 1}
|
|
1055
|
+
if { $clickres == 0 || $clickres == 1 } {
|
|
1056
|
+
bind $frame <Button> [list set Tree::_edit(wait) $clickres]
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
set ok 0
|
|
1060
|
+
while { !$ok } {
|
|
1061
|
+
tkwait variable Tree::_edit(wait)
|
|
1062
|
+
if { !$_edit(wait) || [llength $verifycmd]==0 ||
|
|
1063
|
+
[uplevel \#0 $verifycmd [list $_edit(text)]] } {
|
|
1064
|
+
set ok 1
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
trace vdelete Tree::_edit(text) w \
|
|
1069
|
+
[list Tree::_update_edit_size $path $ent $idw $wmax]
|
|
1070
|
+
grab release $frame
|
|
1071
|
+
BWidget::focus release $ent
|
|
1072
|
+
destroy $frame
|
|
1073
|
+
$path.c delete $idw
|
|
1074
|
+
$path.c itemconfigure $idn -fill $oldfg
|
|
1075
|
+
$path.c itemconfigure s:$node -fill $sbg -outline $sbg
|
|
1076
|
+
|
|
1077
|
+
if { $_edit(wait) } {
|
|
1078
|
+
return $_edit(text)
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return ""
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
# ----------------------------------------------------------------------------
|
|
1086
|
+
# Command Tree::xview
|
|
1087
|
+
# ----------------------------------------------------------------------------
|
|
1088
|
+
proc Tree::xview { path args } {
|
|
1089
|
+
return [eval [linsert $args 0 $path.c xview]]
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
# ----------------------------------------------------------------------------
|
|
1094
|
+
# Command Tree::yview
|
|
1095
|
+
# ----------------------------------------------------------------------------
|
|
1096
|
+
proc Tree::yview { path args } {
|
|
1097
|
+
return [eval [linsert $args 0 $path.c yview]]
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
# ----------------------------------------------------------------------------
|
|
1102
|
+
# Command Tree::_update_edit_size
|
|
1103
|
+
# ----------------------------------------------------------------------------
|
|
1104
|
+
proc Tree::_update_edit_size { path entry idw wmax args } {
|
|
1105
|
+
set entw [winfo reqwidth $entry]
|
|
1106
|
+
if { $entw+8 >= $wmax } {
|
|
1107
|
+
$path.c itemconfigure $idw -width $wmax
|
|
1108
|
+
} else {
|
|
1109
|
+
$path.c itemconfigure $idw -width 0
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
# ----------------------------------------------------------------------------
|
|
1115
|
+
# Command Tree::_see
|
|
1116
|
+
# ----------------------------------------------------------------------------
|
|
1117
|
+
proc Tree::_see { path idn } {
|
|
1118
|
+
set bbox [$path.c bbox $idn]
|
|
1119
|
+
set scrl [$path.c cget -scrollregion]
|
|
1120
|
+
|
|
1121
|
+
set ymax [lindex $scrl 3]
|
|
1122
|
+
set dy [$path.c cget -yscrollincrement]
|
|
1123
|
+
set yv [$path yview]
|
|
1124
|
+
set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}]
|
|
1125
|
+
set yv1 [expr {round([lindex $yv 1]*$ymax/$dy)}]
|
|
1126
|
+
set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
|
|
1127
|
+
if { $y < $yv0 } {
|
|
1128
|
+
$path.c yview scroll [expr {$y-$yv0}] units
|
|
1129
|
+
} elseif { $y >= $yv1 } {
|
|
1130
|
+
$path.c yview scroll [expr {$y-$yv1+1}] units
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
set xmax [lindex $scrl 2]
|
|
1134
|
+
set dx [$path.c cget -xscrollincrement]
|
|
1135
|
+
set xv [$path xview]
|
|
1136
|
+
set x0 [expr {int([lindex $bbox 0]/$dx)}]
|
|
1137
|
+
set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}]
|
|
1138
|
+
set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}]
|
|
1139
|
+
if { $x0 >= $xv1 || $x0 < $xv0 } {
|
|
1140
|
+
$path.c xview scroll [expr {$x0-$xv0}] units
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
# ----------------------------------------------------------------------------
|
|
1146
|
+
# Command Tree::_recexpand
|
|
1147
|
+
# ----------------------------------------------------------------------------
|
|
1148
|
+
# JDC : added option recursive
|
|
1149
|
+
proc Tree::_recexpand { path node expand recursive cmd } {
|
|
1150
|
+
variable $path
|
|
1151
|
+
upvar 0 $path data
|
|
1152
|
+
|
|
1153
|
+
if { [Widget::getoption $path.$node -open] != $expand } {
|
|
1154
|
+
Widget::setoption $path.$node -open $expand
|
|
1155
|
+
if {[llength $cmd]} {
|
|
1156
|
+
uplevel \#0 $cmd [list $node]
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
if { $recursive } {
|
|
1161
|
+
foreach subnode [lrange $data($node) 1 end] {
|
|
1162
|
+
_recexpand $path $subnode $expand $recursive $cmd
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
# ----------------------------------------------------------------------------
|
|
1169
|
+
# Command Tree::_subdelete
|
|
1170
|
+
# ----------------------------------------------------------------------------
|
|
1171
|
+
proc Tree::_subdelete { path lnodes } {
|
|
1172
|
+
variable $path
|
|
1173
|
+
upvar 0 $path data
|
|
1174
|
+
|
|
1175
|
+
set sel $data(selnodes)
|
|
1176
|
+
set selchanged 0
|
|
1177
|
+
|
|
1178
|
+
while { [llength $lnodes] } {
|
|
1179
|
+
set lsubnodes [list]
|
|
1180
|
+
foreach node $lnodes {
|
|
1181
|
+
foreach subnode [lrange $data($node) 1 end] {
|
|
1182
|
+
lappend lsubnodes $subnode
|
|
1183
|
+
}
|
|
1184
|
+
unset data($node)
|
|
1185
|
+
set idx [lsearch -exact $sel $node]
|
|
1186
|
+
if { $idx >= 0 } {
|
|
1187
|
+
set sel [lreplace $sel $idx $idx]
|
|
1188
|
+
incr selchanged
|
|
1189
|
+
}
|
|
1190
|
+
if { [set win [Widget::getoption $path.$node -window]] != "" } {
|
|
1191
|
+
destroy $win
|
|
1192
|
+
}
|
|
1193
|
+
Widget::destroy $path.$node
|
|
1194
|
+
}
|
|
1195
|
+
set lnodes $lsubnodes
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
set data(selnodes) $sel
|
|
1199
|
+
# return number of sel items changes
|
|
1200
|
+
return $selchanged
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
# ----------------------------------------------------------------------------
|
|
1205
|
+
# Command Tree::_update_scrollregion
|
|
1206
|
+
# ----------------------------------------------------------------------------
|
|
1207
|
+
proc Tree::_update_scrollregion { path } {
|
|
1208
|
+
set bd [expr {2*([$path.c cget -borderwidth]+[$path.c cget -highlightthickness])}]
|
|
1209
|
+
set w [expr {[winfo width $path] - $bd}]
|
|
1210
|
+
set h [expr {[winfo height $path] - $bd}]
|
|
1211
|
+
set xinc [$path.c cget -xscrollincrement]
|
|
1212
|
+
set yinc [$path.c cget -yscrollincrement]
|
|
1213
|
+
set bbox [$path.c bbox node]
|
|
1214
|
+
if { [llength $bbox] } {
|
|
1215
|
+
set xs [lindex $bbox 2]
|
|
1216
|
+
set ys [lindex $bbox 3]
|
|
1217
|
+
|
|
1218
|
+
if { $w < $xs } {
|
|
1219
|
+
set w [expr {int($xs)}]
|
|
1220
|
+
if { [set r [expr {$w % $xinc}]] } {
|
|
1221
|
+
set w [expr {$w+$xinc-$r}]
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
if { $h < $ys } {
|
|
1225
|
+
set h [expr {int($ys)}]
|
|
1226
|
+
if { [set r [expr {$h % $yinc}]] } {
|
|
1227
|
+
set h [expr {$h+$yinc-$r}]
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
$path.c configure -scrollregion [list 0 0 $w $h]
|
|
1233
|
+
|
|
1234
|
+
if {[Widget::getoption $path -selectfill]} {
|
|
1235
|
+
_redraw_selection $path
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
# ----------------------------------------------------------------------------
|
|
1241
|
+
# Command Tree::_cross_event
|
|
1242
|
+
# ----------------------------------------------------------------------------
|
|
1243
|
+
proc Tree::_cross_event { path } {
|
|
1244
|
+
variable $path
|
|
1245
|
+
upvar 0 $path data
|
|
1246
|
+
|
|
1247
|
+
set node [Tree::_get_node_name $path current 1]
|
|
1248
|
+
if { [Widget::getoption $path.$node -open] } {
|
|
1249
|
+
Tree::itemconfigure $path $node -open 0
|
|
1250
|
+
if {[llength [set cmd [Widget::getoption $path -closecmd]]]} {
|
|
1251
|
+
uplevel \#0 $cmd [list $node]
|
|
1252
|
+
}
|
|
1253
|
+
} else {
|
|
1254
|
+
Tree::itemconfigure $path $node -open 1
|
|
1255
|
+
if {[llength [set cmd [Widget::getoption $path -opencmd]]]} {
|
|
1256
|
+
uplevel \#0 $cmd [list $node]
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
proc Tree::_draw_cross { path node open x y } {
|
|
1263
|
+
set idc [$path.c find withtag c:$node]
|
|
1264
|
+
|
|
1265
|
+
if { $open } {
|
|
1266
|
+
set img [Widget::cget $path -crossopenimage]
|
|
1267
|
+
set bmp [Widget::cget $path -crossopenbitmap]
|
|
1268
|
+
} else {
|
|
1269
|
+
set img [Widget::cget $path -crosscloseimage]
|
|
1270
|
+
set bmp [Widget::cget $path -crossclosebitmap]
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
## If we already have a cross for this node, we just adjust the image.
|
|
1274
|
+
if {$idc != ""} {
|
|
1275
|
+
if {$img == ""} {
|
|
1276
|
+
$path.c itemconfigure $idc -bitmap $bmp
|
|
1277
|
+
} else {
|
|
1278
|
+
$path.c itemconfigure $idc -image $img
|
|
1279
|
+
}
|
|
1280
|
+
return
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
## Create a new image for the cross. If the user has specified an
|
|
1284
|
+
## image, it overrides a bitmap.
|
|
1285
|
+
if {$img == ""} {
|
|
1286
|
+
$path.c create bitmap $x $y \
|
|
1287
|
+
-bitmap $bmp \
|
|
1288
|
+
-background [$path.c cget -background] \
|
|
1289
|
+
-foreground [Widget::getoption $path -crossfill] \
|
|
1290
|
+
-tags [list cross c:$node] -anchor c
|
|
1291
|
+
} else {
|
|
1292
|
+
$path.c create image $x $y \
|
|
1293
|
+
-image $img \
|
|
1294
|
+
-tags [list cross c:$node] -anchor c
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
# ----------------------------------------------------------------------------
|
|
1300
|
+
# Command Tree::_draw_node
|
|
1301
|
+
# ----------------------------------------------------------------------------
|
|
1302
|
+
proc Tree::_draw_node { path node x0 y0 deltax deltay padx showlines } {
|
|
1303
|
+
variable $path
|
|
1304
|
+
upvar 0 $path data
|
|
1305
|
+
|
|
1306
|
+
set x1 [expr {$x0+$deltax+5}]
|
|
1307
|
+
set y1 $y0
|
|
1308
|
+
if { $showlines } {
|
|
1309
|
+
$path.c create line $x0 $y0 $x1 $y0 \
|
|
1310
|
+
-fill [Widget::getoption $path -linesfill] \
|
|
1311
|
+
-stipple [Widget::getoption $path -linestipple] \
|
|
1312
|
+
-tags line
|
|
1313
|
+
}
|
|
1314
|
+
$path.c create text [expr {$x1+$padx}] $y0 \
|
|
1315
|
+
-text [Widget::getoption $path.$node -text] \
|
|
1316
|
+
-fill [Widget::getoption $path.$node -fill] \
|
|
1317
|
+
-font [Widget::getoption $path.$node -font] \
|
|
1318
|
+
-anchor w \
|
|
1319
|
+
-tags [Tree::_get_node_tags $path $node [list node n:$node]]
|
|
1320
|
+
set len [expr {[llength $data($node)] > 1}]
|
|
1321
|
+
set dc [Widget::getoption $path.$node -drawcross]
|
|
1322
|
+
set exp [Widget::getoption $path.$node -open]
|
|
1323
|
+
|
|
1324
|
+
if { $len && $exp } {
|
|
1325
|
+
set y1 [_draw_subnodes $path [lrange $data($node) 1 end] \
|
|
1326
|
+
[expr {$x0+$deltax}] $y0 $deltax $deltay $padx $showlines]
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
if {![string equal $dc "never"]
|
|
1330
|
+
&& ($len || [string equal $dc "always"] || [string equal $dc "allways"])} {
|
|
1331
|
+
_draw_cross $path $node $exp $x0 $y0
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
if { [set win [Widget::getoption $path.$node -window]] != "" } {
|
|
1335
|
+
set a [Widget::cget $path.$node -anchor]
|
|
1336
|
+
$path.c create window $x1 $y0 -window $win -anchor $a \
|
|
1337
|
+
-tags [Tree::_get_node_tags $path $node [list win i:$node]]
|
|
1338
|
+
} elseif { [set img [Widget::getoption $path.$node -image]] != "" } {
|
|
1339
|
+
set a [Widget::cget $path.$node -anchor]
|
|
1340
|
+
$path.c create image $x1 $y0 -image $img -anchor $a \
|
|
1341
|
+
-tags [Tree::_get_node_tags $path $node [list img i:$node]]
|
|
1342
|
+
}
|
|
1343
|
+
set box [$path.c bbox n:$node i:$node]
|
|
1344
|
+
set id [$path.c create rect 0 [lindex $box 1] \
|
|
1345
|
+
[winfo screenwidth $path] [lindex $box 3] \
|
|
1346
|
+
-tags [Tree::_get_node_tags $path $node [list box b:$node]] \
|
|
1347
|
+
-fill {} -outline {}]
|
|
1348
|
+
$path.c lower $id
|
|
1349
|
+
|
|
1350
|
+
_set_help $path $node
|
|
1351
|
+
|
|
1352
|
+
return $y1
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
# ----------------------------------------------------------------------------
|
|
1357
|
+
# Command Tree::_draw_subnodes
|
|
1358
|
+
# ----------------------------------------------------------------------------
|
|
1359
|
+
proc Tree::_draw_subnodes { path nodes x0 y0 deltax deltay padx showlines } {
|
|
1360
|
+
set y1 $y0
|
|
1361
|
+
foreach node $nodes {
|
|
1362
|
+
set padx [_get_node_padx $path $node]
|
|
1363
|
+
set deltax [_get_node_deltax $path $node]
|
|
1364
|
+
set yp $y1
|
|
1365
|
+
set y1 [_draw_node $path $node $x0 [expr {$y1+$deltay}] $deltax $deltay $padx $showlines]
|
|
1366
|
+
}
|
|
1367
|
+
if { $showlines && [llength $nodes] } {
|
|
1368
|
+
if {$y0 < 0} {
|
|
1369
|
+
# Adjust the drawing of the line to the first root node
|
|
1370
|
+
# to start at the vertical point (not go up).
|
|
1371
|
+
incr y0 $deltay
|
|
1372
|
+
}
|
|
1373
|
+
set id [$path.c create line $x0 $y0 $x0 [expr {$yp+$deltay}] \
|
|
1374
|
+
-fill [Widget::getoption $path -linesfill] \
|
|
1375
|
+
-stipple [Widget::getoption $path -linestipple] \
|
|
1376
|
+
-tags line]
|
|
1377
|
+
|
|
1378
|
+
$path.c lower $id
|
|
1379
|
+
}
|
|
1380
|
+
return $y1
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
# ----------------------------------------------------------------------------
|
|
1385
|
+
# Command Tree::_update_nodes
|
|
1386
|
+
# ----------------------------------------------------------------------------
|
|
1387
|
+
proc Tree::_update_nodes { path } {
|
|
1388
|
+
variable $path
|
|
1389
|
+
upvar 0 $path data
|
|
1390
|
+
|
|
1391
|
+
foreach {node flag} $data(upd,nodes) {
|
|
1392
|
+
set idn [$path.c find withtag "n:$node"]
|
|
1393
|
+
if { $idn == "" } {
|
|
1394
|
+
continue
|
|
1395
|
+
}
|
|
1396
|
+
set padx [_get_node_padx $path $node]
|
|
1397
|
+
set deltax [_get_node_deltax $path $node]
|
|
1398
|
+
set c [$path.c coords $idn]
|
|
1399
|
+
set x1 [expr {[lindex $c 0]-$padx}]
|
|
1400
|
+
set x0 [expr {$x1-$deltax-5}]
|
|
1401
|
+
set y0 [lindex $c 1]
|
|
1402
|
+
if { $flag & 48 } {
|
|
1403
|
+
# -window or -image modified
|
|
1404
|
+
set win [Widget::getoption $path.$node -window]
|
|
1405
|
+
set img [Widget::getoption $path.$node -image]
|
|
1406
|
+
set anc [Widget::cget $path.$node -anchor]
|
|
1407
|
+
set idi [$path.c find withtag i:$node]
|
|
1408
|
+
set type [lindex [$path.c gettags $idi] 1]
|
|
1409
|
+
if { [string length $win] } {
|
|
1410
|
+
if { [string equal $type "win"] } {
|
|
1411
|
+
$path.c itemconfigure $idi -window $win
|
|
1412
|
+
} else {
|
|
1413
|
+
$path.c delete $idi
|
|
1414
|
+
$path.c create window $x1 $y0 -window $win -anchor $anc \
|
|
1415
|
+
-tags [_get_node_tags $path $node [list win i:$node]]
|
|
1416
|
+
}
|
|
1417
|
+
} elseif { [string length $img] } {
|
|
1418
|
+
if { [string equal $type "img"] } {
|
|
1419
|
+
$path.c itemconfigure $idi -image $img
|
|
1420
|
+
} else {
|
|
1421
|
+
$path.c delete $idi
|
|
1422
|
+
$path.c create image $x1 $y0 -image $img -anchor $anc \
|
|
1423
|
+
-tags [_get_node_tags $path $node [list img i:$node]]
|
|
1424
|
+
}
|
|
1425
|
+
} else {
|
|
1426
|
+
$path.c delete $idi
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
if { $flag & 8 } {
|
|
1431
|
+
# -drawcross modified
|
|
1432
|
+
set len [expr {[llength $data($node)] > 1}]
|
|
1433
|
+
set dc [Widget::getoption $path.$node -drawcross]
|
|
1434
|
+
set exp [Widget::getoption $path.$node -open]
|
|
1435
|
+
|
|
1436
|
+
if {![string equal $dc "never"]
|
|
1437
|
+
&& ($len || [string equal $dc "always"] || [string equal $dc "allways"])} {
|
|
1438
|
+
_draw_cross $path $node $exp $x0 $y0
|
|
1439
|
+
} else {
|
|
1440
|
+
set idc [$path.c find withtag c:$node]
|
|
1441
|
+
$path.c delete $idc
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
if { $flag & 7 } {
|
|
1446
|
+
# -font, -text or -fill modified
|
|
1447
|
+
$path.c itemconfigure $idn \
|
|
1448
|
+
-text [Widget::getoption $path.$node -text] \
|
|
1449
|
+
-fill [Widget::getoption $path.$node -fill] \
|
|
1450
|
+
-font [Widget::getoption $path.$node -font]
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
# ----------------------------------------------------------------------------
|
|
1457
|
+
# Command Tree::_draw_tree
|
|
1458
|
+
# ----------------------------------------------------------------------------
|
|
1459
|
+
proc Tree::_draw_tree { path } {
|
|
1460
|
+
variable $path
|
|
1461
|
+
upvar 0 $path data
|
|
1462
|
+
|
|
1463
|
+
$path.c delete all
|
|
1464
|
+
set cursor [$path.c cget -cursor]
|
|
1465
|
+
$path.c configure -cursor watch
|
|
1466
|
+
_draw_subnodes $path [lrange $data(root) 1 end] 8 \
|
|
1467
|
+
[expr {-[Widget::getoption $path -deltay]/2}] \
|
|
1468
|
+
[Widget::getoption $path -deltax] \
|
|
1469
|
+
[Widget::getoption $path -deltay] \
|
|
1470
|
+
[Widget::getoption $path -padx] \
|
|
1471
|
+
[Widget::getoption $path -showlines]
|
|
1472
|
+
$path.c configure -cursor $cursor
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
# ----------------------------------------------------------------------------
|
|
1477
|
+
# Command Tree::_redraw_tree
|
|
1478
|
+
# ----------------------------------------------------------------------------
|
|
1479
|
+
proc Tree::_redraw_tree { path } {
|
|
1480
|
+
variable $path
|
|
1481
|
+
upvar 0 $path data
|
|
1482
|
+
|
|
1483
|
+
if { [Widget::getoption $path -redraw] } {
|
|
1484
|
+
if { $data(upd,level) == 2 } {
|
|
1485
|
+
_update_nodes $path
|
|
1486
|
+
} elseif { $data(upd,level) == 3 } {
|
|
1487
|
+
_draw_tree $path
|
|
1488
|
+
}
|
|
1489
|
+
_redraw_selection $path
|
|
1490
|
+
_update_scrollregion $path
|
|
1491
|
+
set data(upd,nodes) {}
|
|
1492
|
+
set data(upd,level) 0
|
|
1493
|
+
set data(upd,afterid) ""
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
# ----------------------------------------------------------------------------
|
|
1499
|
+
# Command Tree::_redraw_selection
|
|
1500
|
+
# ----------------------------------------------------------------------------
|
|
1501
|
+
proc Tree::_redraw_selection { path } {
|
|
1502
|
+
variable $path
|
|
1503
|
+
upvar 0 $path data
|
|
1504
|
+
|
|
1505
|
+
set selbg [Widget::getoption $path -selectbackground]
|
|
1506
|
+
set selfg [Widget::getoption $path -selectforeground]
|
|
1507
|
+
set fill [Widget::getoption $path -selectfill]
|
|
1508
|
+
if {$fill} {
|
|
1509
|
+
set scroll [$path.c cget -scrollregion]
|
|
1510
|
+
if {[llength $scroll]} {
|
|
1511
|
+
set xmax [expr {[lindex $scroll 2]-1}]
|
|
1512
|
+
} else {
|
|
1513
|
+
set xmax [winfo width $path]
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
foreach id [$path.c find withtag sel] {
|
|
1517
|
+
set node [Tree::_get_node_name $path $id 1]
|
|
1518
|
+
$path.c itemconfigure "n:$node" -fill [Widget::getoption $path.$node -fill]
|
|
1519
|
+
}
|
|
1520
|
+
$path.c delete sel
|
|
1521
|
+
foreach node $data(selnodes) {
|
|
1522
|
+
set bbox [$path.c bbox "n:$node"]
|
|
1523
|
+
if { [llength $bbox] } {
|
|
1524
|
+
if {$fill} {
|
|
1525
|
+
# get the image to (if any), as it may have different height
|
|
1526
|
+
set bbox [$path.c bbox "n:$node" "i:$node"]
|
|
1527
|
+
set bbox [list 0 [lindex $bbox 1] $xmax [lindex $bbox 3]]
|
|
1528
|
+
}
|
|
1529
|
+
set id [$path.c create rectangle $bbox -tags [list sel s:$node] \
|
|
1530
|
+
-fill $selbg -outline $selbg]
|
|
1531
|
+
$path.c itemconfigure "n:$node" -fill $selfg
|
|
1532
|
+
$path.c lower $id
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
# ----------------------------------------------------------------------------
|
|
1539
|
+
# Command Tree::_redraw_idle
|
|
1540
|
+
# ----------------------------------------------------------------------------
|
|
1541
|
+
proc Tree::_redraw_idle { path level } {
|
|
1542
|
+
variable $path
|
|
1543
|
+
upvar 0 $path data
|
|
1544
|
+
|
|
1545
|
+
if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } {
|
|
1546
|
+
set data(upd,afterid) [after idle [list Tree::_redraw_tree $path]]
|
|
1547
|
+
}
|
|
1548
|
+
if { $level > $data(upd,level) } {
|
|
1549
|
+
set data(upd,level) $level
|
|
1550
|
+
}
|
|
1551
|
+
return ""
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
# ----------------------------------------------------------------------------
|
|
1556
|
+
# Command Tree::_init_drag_cmd
|
|
1557
|
+
# ----------------------------------------------------------------------------
|
|
1558
|
+
proc Tree::_init_drag_cmd { path X Y top } {
|
|
1559
|
+
set path [winfo parent $path]
|
|
1560
|
+
set ltags [$path.c gettags current]
|
|
1561
|
+
set item [lindex $ltags 1]
|
|
1562
|
+
if { [string equal $item "node"] ||
|
|
1563
|
+
[string equal $item "img"] ||
|
|
1564
|
+
[string equal $item "win"] } {
|
|
1565
|
+
set node [Tree::_get_node_name $path current 2]
|
|
1566
|
+
if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
|
|
1567
|
+
return [uplevel \#0 $cmd [list $path $node $top]]
|
|
1568
|
+
}
|
|
1569
|
+
if { [set type [Widget::getoption $path -dragtype]] == "" } {
|
|
1570
|
+
set type "TREE_NODE"
|
|
1571
|
+
}
|
|
1572
|
+
if { [set img [Widget::getoption $path.$node -image]] != "" } {
|
|
1573
|
+
pack [label $top.l -image $img -padx 0 -pady 0]
|
|
1574
|
+
}
|
|
1575
|
+
return [list $type {copy move link} $node]
|
|
1576
|
+
}
|
|
1577
|
+
return {}
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
|
|
1581
|
+
# ----------------------------------------------------------------------------
|
|
1582
|
+
# Command Tree::_drop_cmd
|
|
1583
|
+
# ----------------------------------------------------------------------------
|
|
1584
|
+
proc Tree::_drop_cmd { path source X Y op type dnddata } {
|
|
1585
|
+
set path [winfo parent $path]
|
|
1586
|
+
variable $path
|
|
1587
|
+
upvar 0 $path data
|
|
1588
|
+
|
|
1589
|
+
$path.c delete drop
|
|
1590
|
+
if { [string length $data(dnd,afterid)] } {
|
|
1591
|
+
after cancel $data(dnd,afterid)
|
|
1592
|
+
set data(dnd,afterid) ""
|
|
1593
|
+
}
|
|
1594
|
+
set data(dnd,scroll) ""
|
|
1595
|
+
if {[llength $data(dnd,node)]
|
|
1596
|
+
&& [llength [set cmd [Widget::getoption $path -dropcmd]]]} {
|
|
1597
|
+
return [uplevel \#0 $cmd \
|
|
1598
|
+
[list $path $source $data(dnd,node) $op $type $dnddata]]
|
|
1599
|
+
}
|
|
1600
|
+
return 0
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
|
|
1604
|
+
# ----------------------------------------------------------------------------
|
|
1605
|
+
# Command Tree::_over_cmd
|
|
1606
|
+
# ----------------------------------------------------------------------------
|
|
1607
|
+
proc Tree::_over_cmd { path source event X Y op type dnddata } {
|
|
1608
|
+
set path [winfo parent $path]
|
|
1609
|
+
variable $path
|
|
1610
|
+
upvar 0 $path data
|
|
1611
|
+
|
|
1612
|
+
if { [string equal $event "leave"] } {
|
|
1613
|
+
# we leave the window tree
|
|
1614
|
+
$path.c delete drop
|
|
1615
|
+
if { [string length $data(dnd,afterid)] } {
|
|
1616
|
+
after cancel $data(dnd,afterid)
|
|
1617
|
+
set data(dnd,afterid) ""
|
|
1618
|
+
}
|
|
1619
|
+
set data(dnd,scroll) ""
|
|
1620
|
+
return 0
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
if { [string equal $event "enter"] } {
|
|
1624
|
+
# we enter the window tree - dnd data initialization
|
|
1625
|
+
set mode [Widget::getoption $path -dropovermode]
|
|
1626
|
+
set data(dnd,mode) 0
|
|
1627
|
+
foreach c {w p n} {
|
|
1628
|
+
set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}]
|
|
1629
|
+
}
|
|
1630
|
+
set bbox [$path.c bbox all]
|
|
1631
|
+
if { [llength $bbox] } {
|
|
1632
|
+
set data(dnd,xs) [lindex $bbox 2]
|
|
1633
|
+
set data(dnd,empty) 0
|
|
1634
|
+
} else {
|
|
1635
|
+
set data(dnd,xs) 0
|
|
1636
|
+
set data(dnd,empty) 1
|
|
1637
|
+
}
|
|
1638
|
+
set data(dnd,node) {}
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
set x [expr {$X-[winfo rootx $path]}]
|
|
1642
|
+
set y [expr {$Y-[winfo rooty $path]}]
|
|
1643
|
+
$path.c delete drop
|
|
1644
|
+
set data(dnd,node) {}
|
|
1645
|
+
|
|
1646
|
+
# test for auto-scroll unless mode is widget only
|
|
1647
|
+
if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } {
|
|
1648
|
+
return 2
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
if { $data(dnd,mode) & 4 } {
|
|
1652
|
+
# dropovermode includes widget
|
|
1653
|
+
set target [list widget]
|
|
1654
|
+
set vmode 4
|
|
1655
|
+
} else {
|
|
1656
|
+
set target [list ""]
|
|
1657
|
+
set vmode 0
|
|
1658
|
+
}
|
|
1659
|
+
if { ($data(dnd,mode) & 2) && $data(dnd,empty) } {
|
|
1660
|
+
# dropovermode includes position and tree is empty
|
|
1661
|
+
lappend target [list root 0]
|
|
1662
|
+
set vmode [expr {$vmode | 2}]
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
set xc [$path.c canvasx $x]
|
|
1666
|
+
set xs $data(dnd,xs)
|
|
1667
|
+
if { $xc <= $xs } {
|
|
1668
|
+
set yc [$path.c canvasy $y]
|
|
1669
|
+
set dy [$path.c cget -yscrollincrement]
|
|
1670
|
+
set line [expr {int($yc/$dy)}]
|
|
1671
|
+
set xi 0
|
|
1672
|
+
set yi [expr {$line*$dy}]
|
|
1673
|
+
set ys [expr {$yi+$dy}]
|
|
1674
|
+
set found 0
|
|
1675
|
+
foreach id [$path.c find overlapping $xi $yi $xs $ys] {
|
|
1676
|
+
set ltags [$path.c gettags $id]
|
|
1677
|
+
set item [lindex $ltags 1]
|
|
1678
|
+
if { [string equal $item "node"] ||
|
|
1679
|
+
[string equal $item "img"] ||
|
|
1680
|
+
[string equal $item "win"] } {
|
|
1681
|
+
# item is the label or image/window of the node
|
|
1682
|
+
set node [Tree::_get_node_name $path $id 2]
|
|
1683
|
+
set found 1
|
|
1684
|
+
break
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
if {$found} {
|
|
1688
|
+
set padx [_get_node_padx $path $node]
|
|
1689
|
+
set deltax [_get_node_deltax $path $node]
|
|
1690
|
+
set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx - 1}]
|
|
1691
|
+
if { $data(dnd,mode) & 1 } {
|
|
1692
|
+
# dropovermode includes node
|
|
1693
|
+
lappend target $node
|
|
1694
|
+
set vmode [expr {$vmode | 1}]
|
|
1695
|
+
} else {
|
|
1696
|
+
lappend target ""
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
if { $data(dnd,mode) & 2 } {
|
|
1700
|
+
# dropovermode includes position
|
|
1701
|
+
if { $yc >= $yi+$dy/2 } {
|
|
1702
|
+
# position is after $node
|
|
1703
|
+
if { [Widget::getoption $path.$node -open] &&
|
|
1704
|
+
[llength $data($node)] > 1 } {
|
|
1705
|
+
# $node is open and have subnodes
|
|
1706
|
+
# drop position is 0 in children of $node
|
|
1707
|
+
set parent $node
|
|
1708
|
+
set index 0
|
|
1709
|
+
set xli [expr {$xi-5}]
|
|
1710
|
+
} else {
|
|
1711
|
+
# $node is not open and doesn't have subnodes
|
|
1712
|
+
# drop position is after $node in children of parent of $node
|
|
1713
|
+
set parent [lindex $data($node) 0]
|
|
1714
|
+
set index [lsearch -exact $data($parent) $node]
|
|
1715
|
+
set xli [expr {$xi - $deltax - 5}]
|
|
1716
|
+
}
|
|
1717
|
+
set yl $ys
|
|
1718
|
+
} else {
|
|
1719
|
+
# position is before $node
|
|
1720
|
+
# drop position is before $node in children of parent of $node
|
|
1721
|
+
set parent [lindex $data($node) 0]
|
|
1722
|
+
set index [expr {[lsearch -exact $data($parent) $node] - 1}]
|
|
1723
|
+
set xli [expr {$xi - $deltax - 5}]
|
|
1724
|
+
set yl $yi
|
|
1725
|
+
}
|
|
1726
|
+
lappend target [list $parent $index]
|
|
1727
|
+
set vmode [expr {$vmode | 2}]
|
|
1728
|
+
} else {
|
|
1729
|
+
lappend target {}
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
if { ($vmode & 3) == 3 } {
|
|
1733
|
+
# result have both node and position
|
|
1734
|
+
# we compute what is the preferred method
|
|
1735
|
+
if { $yc-$yi <= 3 || $ys-$yc <= 3 } {
|
|
1736
|
+
lappend target "position"
|
|
1737
|
+
} else {
|
|
1738
|
+
lappend target "node"
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
if {$vmode && [llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
|
|
1745
|
+
# user-defined dropover command
|
|
1746
|
+
set res [uplevel \#0 $cmd [list $path $source $target $op $type $dnddata]]
|
|
1747
|
+
set code [lindex $res 0]
|
|
1748
|
+
set newmode 0
|
|
1749
|
+
if { $code & 1 } {
|
|
1750
|
+
# update vmode
|
|
1751
|
+
set mode [lindex $res 1]
|
|
1752
|
+
if { ($vmode & 1) && [string equal $mode "node"] } {
|
|
1753
|
+
set newmode 1
|
|
1754
|
+
} elseif { ($vmode & 2) && [string equal $mode "position"] } {
|
|
1755
|
+
set newmode 2
|
|
1756
|
+
} elseif { ($vmode & 4) && [string equal $mode "widget"] } {
|
|
1757
|
+
set newmode 4
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
set vmode $newmode
|
|
1761
|
+
} else {
|
|
1762
|
+
if { ($vmode & 3) == 3 } {
|
|
1763
|
+
# result have both item and position
|
|
1764
|
+
# we choose the preferred method
|
|
1765
|
+
if { [string equal [lindex $target 3] "position"] } {
|
|
1766
|
+
set vmode [expr {$vmode & ~1}]
|
|
1767
|
+
} else {
|
|
1768
|
+
set vmode [expr {$vmode & ~2}]
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
if { $data(dnd,mode) == 4 || $data(dnd,mode) == 0 } {
|
|
1773
|
+
# dropovermode is widget or empty - recall is not necessary
|
|
1774
|
+
set code 1
|
|
1775
|
+
} else {
|
|
1776
|
+
set code 3
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
if {!$data(dnd,empty)} {
|
|
1781
|
+
# draw dnd visual following vmode
|
|
1782
|
+
if { $vmode & 1 } {
|
|
1783
|
+
set data(dnd,node) [list "node" [lindex $target 1]]
|
|
1784
|
+
$path.c create rectangle $xi $yi $xs $ys -tags drop
|
|
1785
|
+
} elseif { $vmode & 2 } {
|
|
1786
|
+
set data(dnd,node) [concat "position" [lindex $target 2]]
|
|
1787
|
+
$path.c create line $xli [expr {$yl-$dy/2}] $xli $yl $xs $yl -tags drop
|
|
1788
|
+
} elseif { $vmode & 4 } {
|
|
1789
|
+
set data(dnd,node) [list "widget"]
|
|
1790
|
+
} else {
|
|
1791
|
+
set code [expr {$code & 2}]
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
if { $code & 1 } {
|
|
1796
|
+
DropSite::setcursor based_arrow_down
|
|
1797
|
+
} else {
|
|
1798
|
+
DropSite::setcursor dot
|
|
1799
|
+
}
|
|
1800
|
+
return $code
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
# ----------------------------------------------------------------------------
|
|
1805
|
+
# Command Tree::_auto_scroll
|
|
1806
|
+
# ----------------------------------------------------------------------------
|
|
1807
|
+
proc Tree::_auto_scroll { path x y } {
|
|
1808
|
+
variable $path
|
|
1809
|
+
upvar 0 $path data
|
|
1810
|
+
|
|
1811
|
+
set xmax [winfo width $path]
|
|
1812
|
+
set ymax [winfo height $path]
|
|
1813
|
+
set scroll {}
|
|
1814
|
+
if { $y <= 6 } {
|
|
1815
|
+
if { [lindex [$path.c yview] 0] > 0 } {
|
|
1816
|
+
set scroll [list yview -1]
|
|
1817
|
+
DropSite::setcursor sb_up_arrow
|
|
1818
|
+
}
|
|
1819
|
+
} elseif { $y >= $ymax-6 } {
|
|
1820
|
+
if { [lindex [$path.c yview] 1] < 1 } {
|
|
1821
|
+
set scroll [list yview 1]
|
|
1822
|
+
DropSite::setcursor sb_down_arrow
|
|
1823
|
+
}
|
|
1824
|
+
} elseif { $x <= 6 } {
|
|
1825
|
+
if { [lindex [$path.c xview] 0] > 0 } {
|
|
1826
|
+
set scroll [list xview -1]
|
|
1827
|
+
DropSite::setcursor sb_left_arrow
|
|
1828
|
+
}
|
|
1829
|
+
} elseif { $x >= $xmax-6 } {
|
|
1830
|
+
if { [lindex [$path.c xview] 1] < 1 } {
|
|
1831
|
+
set scroll [list xview 1]
|
|
1832
|
+
DropSite::setcursor sb_right_arrow
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
if { [string length $data(dnd,afterid)] && ![string equal $data(dnd,scroll) $scroll] } {
|
|
1837
|
+
after cancel $data(dnd,afterid)
|
|
1838
|
+
set data(dnd,afterid) ""
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
set data(dnd,scroll) $scroll
|
|
1842
|
+
if { [string length $scroll] && ![string length $data(dnd,afterid)] } {
|
|
1843
|
+
set data(dnd,afterid) [after 200 [list Tree::_scroll $path $scroll]]
|
|
1844
|
+
}
|
|
1845
|
+
return $data(dnd,afterid)
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
# ----------------------------------------------------------------------------
|
|
1850
|
+
# Command Tree::_scroll
|
|
1851
|
+
# ----------------------------------------------------------------------------
|
|
1852
|
+
proc Tree::_scroll { path cmd dir } {
|
|
1853
|
+
variable $path
|
|
1854
|
+
upvar 0 $path data
|
|
1855
|
+
|
|
1856
|
+
if { ($dir == -1 && [lindex [$path.c $cmd] 0] > 0) ||
|
|
1857
|
+
($dir == 1 && [lindex [$path.c $cmd] 1] < 1) } {
|
|
1858
|
+
$path.c $cmd scroll $dir units
|
|
1859
|
+
set data(dnd,afterid) [after 100 [list Tree::_scroll $path $cmd $dir]]
|
|
1860
|
+
} else {
|
|
1861
|
+
set data(dnd,afterid) ""
|
|
1862
|
+
DropSite::setcursor dot
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
# Tree::_keynav --
|
|
1867
|
+
#
|
|
1868
|
+
# Handle navigational keypresses on the tree.
|
|
1869
|
+
#
|
|
1870
|
+
# Arguments:
|
|
1871
|
+
# which tag indicating the direction of motion:
|
|
1872
|
+
# up move to the node graphically above current
|
|
1873
|
+
# down move to the node graphically below current
|
|
1874
|
+
# left close current if open, else move to parent
|
|
1875
|
+
# right open current if closed, else move to child
|
|
1876
|
+
# open open current if closed, close current if open
|
|
1877
|
+
# win name of the tree widget
|
|
1878
|
+
#
|
|
1879
|
+
# Results:
|
|
1880
|
+
# None.
|
|
1881
|
+
|
|
1882
|
+
proc Tree::_keynav {which win} {
|
|
1883
|
+
# check for an empty tree
|
|
1884
|
+
if {[$win nodes root] eq ""} {
|
|
1885
|
+
return
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
# Keyboard navigation is riddled with special cases. In order to avoid
|
|
1889
|
+
# the complex logic, we will instead make a list of all the visible,
|
|
1890
|
+
# selectable nodes, then do a simple next or previous operation.
|
|
1891
|
+
|
|
1892
|
+
# One easy way to get all of the visible nodes is to query the canvas
|
|
1893
|
+
# object for all the items with the "node" tag; since the tree is always
|
|
1894
|
+
# completely redrawn, this list will be in vertical order.
|
|
1895
|
+
set nodes {}
|
|
1896
|
+
foreach nodeItem [$win.c find withtag node] {
|
|
1897
|
+
set node [Tree::_get_node_name $win $nodeItem 2]
|
|
1898
|
+
if { [Widget::cget $win.$node -selectable] } {
|
|
1899
|
+
lappend nodes $node
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
# Keyboard navigation is all relative to the current node
|
|
1904
|
+
# surles: Get the current node for single or multiple selection schemas.
|
|
1905
|
+
set node [_get_current_node $win]
|
|
1906
|
+
|
|
1907
|
+
switch -exact -- $which {
|
|
1908
|
+
"up" {
|
|
1909
|
+
# Up goes to the node that is vertically above the current node
|
|
1910
|
+
# (NOT necessarily the current node's parent)
|
|
1911
|
+
if { [string equal $node ""] } {
|
|
1912
|
+
return
|
|
1913
|
+
}
|
|
1914
|
+
set index [lsearch -exact $nodes $node]
|
|
1915
|
+
incr index -1
|
|
1916
|
+
if { $index >= 0 } {
|
|
1917
|
+
$win selection set [lindex $nodes $index]
|
|
1918
|
+
_set_current_node $win [lindex $nodes $index]
|
|
1919
|
+
$win see [lindex $nodes $index]
|
|
1920
|
+
return
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
"down" {
|
|
1924
|
+
# Down goes to the node that is vertically below the current node
|
|
1925
|
+
if { [string equal $node ""] } {
|
|
1926
|
+
$win selection set [lindex $nodes 0]
|
|
1927
|
+
_set_current_node $win [lindex $nodes 0]
|
|
1928
|
+
$win see [lindex $nodes 0]
|
|
1929
|
+
return
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
set index [lsearch -exact $nodes $node]
|
|
1933
|
+
incr index
|
|
1934
|
+
if { $index < [llength $nodes] } {
|
|
1935
|
+
$win selection set [lindex $nodes $index]
|
|
1936
|
+
_set_current_node $win [lindex $nodes $index]
|
|
1937
|
+
$win see [lindex $nodes $index]
|
|
1938
|
+
return
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
"right" {
|
|
1942
|
+
# On a right arrow, if the current node is closed, open it.
|
|
1943
|
+
# If the current node is open, go to its first child
|
|
1944
|
+
if { [string equal $node ""] } {
|
|
1945
|
+
return
|
|
1946
|
+
}
|
|
1947
|
+
set open [$win itemcget $node -open]
|
|
1948
|
+
if { $open } {
|
|
1949
|
+
if { [llength [$win nodes $node]] } {
|
|
1950
|
+
set index [lsearch -exact $nodes $node]
|
|
1951
|
+
incr index
|
|
1952
|
+
if { $index < [llength $nodes] } {
|
|
1953
|
+
$win selection set [lindex $nodes $index]
|
|
1954
|
+
_set_current_node $win [lindex $nodes $index]
|
|
1955
|
+
$win see [lindex $nodes $index]
|
|
1956
|
+
return
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
} else {
|
|
1960
|
+
$win itemconfigure $node -open 1
|
|
1961
|
+
if {[llength [set cmd [Widget::getoption $win -opencmd]]]} {
|
|
1962
|
+
uplevel \#0 $cmd [list $node]
|
|
1963
|
+
}
|
|
1964
|
+
return
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
"left" {
|
|
1968
|
+
# On a left arrow, if the current node is open, close it.
|
|
1969
|
+
# If the current node is closed, go to its parent.
|
|
1970
|
+
if { [string equal $node ""] } {
|
|
1971
|
+
return
|
|
1972
|
+
}
|
|
1973
|
+
set open [$win itemcget $node -open]
|
|
1974
|
+
if { $open } {
|
|
1975
|
+
$win itemconfigure $node -open 0
|
|
1976
|
+
if {[llength [set cmd [Widget::getoption $win -closecmd]]]} {
|
|
1977
|
+
uplevel \#0 $cmd [list $node]
|
|
1978
|
+
}
|
|
1979
|
+
return
|
|
1980
|
+
} else {
|
|
1981
|
+
set parent [$win parent $node]
|
|
1982
|
+
if { [string equal $parent "root"] } {
|
|
1983
|
+
set parent $node
|
|
1984
|
+
} else {
|
|
1985
|
+
while { ![$win itemcget $parent -selectable] } {
|
|
1986
|
+
set parent [$win parent $parent]
|
|
1987
|
+
if { [string equal $parent "root"] } {
|
|
1988
|
+
set parent $node
|
|
1989
|
+
break
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
$win selection set $parent
|
|
1994
|
+
_set_current_node $win $parent
|
|
1995
|
+
$win see $parent
|
|
1996
|
+
return
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
"space" {
|
|
2000
|
+
if { [string equal $node ""] } {
|
|
2001
|
+
return
|
|
2002
|
+
}
|
|
2003
|
+
set open [$win itemcget $node -open]
|
|
2004
|
+
if { [llength [$win nodes $node]] } {
|
|
2005
|
+
|
|
2006
|
+
# Toggle the open status of the chosen node.
|
|
2007
|
+
|
|
2008
|
+
$win itemconfigure $node -open [expr {$open?0:1}]
|
|
2009
|
+
|
|
2010
|
+
if {$open} {
|
|
2011
|
+
# Node was open, is now closed. Call the close-cmd
|
|
2012
|
+
|
|
2013
|
+
if {[llength [set cmd [Widget::getoption $win -closecmd]]]} {
|
|
2014
|
+
uplevel \#0 $cmd [list $node]
|
|
2015
|
+
}
|
|
2016
|
+
} else {
|
|
2017
|
+
# Node was closed, is now open. Call the open-cmd
|
|
2018
|
+
|
|
2019
|
+
if {[llength [set cmd [Widget::getoption $win -opencmd]]]} {
|
|
2020
|
+
uplevel \#0 $cmd [list $node]
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
return
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
# Tree::_get_current_node --
|
|
2030
|
+
#
|
|
2031
|
+
# Get the current node for either single or multiple
|
|
2032
|
+
# node selection trees. If the tree allows for
|
|
2033
|
+
# multiple selection, return the cursor node. Otherwise,
|
|
2034
|
+
# if there is a selection, return the first node in the
|
|
2035
|
+
# list. If there is no selection, return the root node.
|
|
2036
|
+
#
|
|
2037
|
+
# arguments:
|
|
2038
|
+
# win name of the tree widget
|
|
2039
|
+
#
|
|
2040
|
+
# Results:
|
|
2041
|
+
# The current node.
|
|
2042
|
+
|
|
2043
|
+
proc Tree::_get_current_node {win} {
|
|
2044
|
+
if {[info exists selectTree::selectCursor($win)]} {
|
|
2045
|
+
set result $selectTree::selectCursor($win)
|
|
2046
|
+
} elseif {[llength [set selList [$win selection get]]]} {
|
|
2047
|
+
set result [lindex $selList 0]
|
|
2048
|
+
} else {
|
|
2049
|
+
set result ""
|
|
2050
|
+
}
|
|
2051
|
+
return $result
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
# Tree::_set_current_node --
|
|
2055
|
+
#
|
|
2056
|
+
# Set the current node for either single or multiple
|
|
2057
|
+
# node selection trees.
|
|
2058
|
+
#
|
|
2059
|
+
# arguments:
|
|
2060
|
+
# win Name of the tree widget
|
|
2061
|
+
# node The current node.
|
|
2062
|
+
#
|
|
2063
|
+
# Results:
|
|
2064
|
+
# None.
|
|
2065
|
+
|
|
2066
|
+
proc Tree::_set_current_node {win node} {
|
|
2067
|
+
if {[info exists selectTree::selectCursor($win)]} {
|
|
2068
|
+
set selectTree::selectCursor($win) $node
|
|
2069
|
+
}
|
|
2070
|
+
return
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
# Tree::_get_node_name --
|
|
2074
|
+
#
|
|
2075
|
+
# Given a canvas item, get the name of the tree node represented by that
|
|
2076
|
+
# item.
|
|
2077
|
+
#
|
|
2078
|
+
# Arguments:
|
|
2079
|
+
# path tree to query
|
|
2080
|
+
# item Optional canvas item to examine; if omitted,
|
|
2081
|
+
# defaults to "current"
|
|
2082
|
+
# tagindex Optional tag index, since the n:nodename tag is not
|
|
2083
|
+
# in the same spot for all canvas items. If omitted,
|
|
2084
|
+
# defaults to "end-1", so it works with "current" item.
|
|
2085
|
+
#
|
|
2086
|
+
# Results:
|
|
2087
|
+
# node name of the tree node.
|
|
2088
|
+
|
|
2089
|
+
proc Tree::_get_node_name {path {item current} {tagindex end-1}} {
|
|
2090
|
+
return [string range [lindex [$path.c gettags $item] $tagindex] 2 end]
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
# Tree::_get_node_padx --
|
|
2094
|
+
#
|
|
2095
|
+
# Given a node in the tree, return it's padx value. If the value is
|
|
2096
|
+
# less than 0, default to the padx of the entire tree.
|
|
2097
|
+
#
|
|
2098
|
+
# Arguments:
|
|
2099
|
+
# path Tree to query
|
|
2100
|
+
# node Node in the tree
|
|
2101
|
+
#
|
|
2102
|
+
# Results:
|
|
2103
|
+
# padx The numeric padx value
|
|
2104
|
+
proc Tree::_get_node_padx {path node} {
|
|
2105
|
+
set padx [Widget::getoption $path.$node -padx]
|
|
2106
|
+
if {$padx < 0} { set padx [Widget::getoption $path -padx] }
|
|
2107
|
+
return $padx
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
# Tree::_get_node_deltax --
|
|
2111
|
+
#
|
|
2112
|
+
# Given a node in the tree, return it's deltax value. If the value is
|
|
2113
|
+
# less than 0, default to the deltax of the entire tree.
|
|
2114
|
+
#
|
|
2115
|
+
# Arguments:
|
|
2116
|
+
# path Tree to query
|
|
2117
|
+
# node Node in the tree
|
|
2118
|
+
#
|
|
2119
|
+
# Results:
|
|
2120
|
+
# deltax The numeric deltax value
|
|
2121
|
+
proc Tree::_get_node_deltax {path node} {
|
|
2122
|
+
set deltax [Widget::getoption $path.$node -deltax]
|
|
2123
|
+
if {$deltax < 0} { set deltax [Widget::getoption $path -deltax] }
|
|
2124
|
+
return $deltax
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
# Tree::_get_node_tags --
|
|
2129
|
+
#
|
|
2130
|
+
# Given a node in the tree, return a list of tags to apply to its
|
|
2131
|
+
# canvas item.
|
|
2132
|
+
#
|
|
2133
|
+
# Arguments:
|
|
2134
|
+
# path Tree to query
|
|
2135
|
+
# node Node in the tree
|
|
2136
|
+
# tags A list of tags to add to the final list
|
|
2137
|
+
#
|
|
2138
|
+
# Results:
|
|
2139
|
+
# list The list of tags to apply to the canvas item
|
|
2140
|
+
proc Tree::_get_node_tags {path node {tags ""}} {
|
|
2141
|
+
eval [linsert $tags 0 lappend list TreeItemSentinal]
|
|
2142
|
+
if {[Widget::getoption $path.$node -helptext] == ""} { return $list }
|
|
2143
|
+
|
|
2144
|
+
switch -- [Widget::getoption $path.$node -helptype] {
|
|
2145
|
+
balloon {
|
|
2146
|
+
lappend list BwHelpBalloon
|
|
2147
|
+
}
|
|
2148
|
+
variable {
|
|
2149
|
+
lappend list BwHelpVariable
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return $list
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
# Tree::_set_help --
|
|
2156
|
+
#
|
|
2157
|
+
# Register dynamic help for a node in the tree.
|
|
2158
|
+
#
|
|
2159
|
+
# Arguments:
|
|
2160
|
+
# path Tree to query
|
|
2161
|
+
# node Node in the tree
|
|
2162
|
+
# force Optional argument to force a reset of the help
|
|
2163
|
+
#
|
|
2164
|
+
# Results:
|
|
2165
|
+
# none
|
|
2166
|
+
proc Tree::_set_help { path node } {
|
|
2167
|
+
Widget::getVariable $path help
|
|
2168
|
+
|
|
2169
|
+
set item $path.$node
|
|
2170
|
+
set opts [list -helptype -helptext -helpvar]
|
|
2171
|
+
foreach {cty ctx cv} [eval [linsert $opts 0 Widget::hasChangedX $item]] break
|
|
2172
|
+
set text [Widget::getoption $item -helptext]
|
|
2173
|
+
|
|
2174
|
+
## If we've never set help for this item before, and text is not blank,
|
|
2175
|
+
## we need to setup help. We also need to reset help if any of the
|
|
2176
|
+
## options have changed.
|
|
2177
|
+
if { (![info exists help($node)] && $text != "") || $cty || $ctx || $cv } {
|
|
2178
|
+
set help($node) 1
|
|
2179
|
+
set type [Widget::getoption $item -helptype]
|
|
2180
|
+
switch $type {
|
|
2181
|
+
balloon {
|
|
2182
|
+
DynamicHelp::register $path.c balloon n:$node $text
|
|
2183
|
+
DynamicHelp::register $path.c balloon i:$node $text
|
|
2184
|
+
DynamicHelp::register $path.c balloon b:$node $text
|
|
2185
|
+
}
|
|
2186
|
+
variable {
|
|
2187
|
+
set var [Widget::getoption $item -helpvar]
|
|
2188
|
+
DynamicHelp::register $path.c variable n:$node $var $text
|
|
2189
|
+
DynamicHelp::register $path.c variable i:$node $var $text
|
|
2190
|
+
DynamicHelp::register $path.c variable b:$node $var $text
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
proc Tree::_mouse_select { path cmd args } {
|
|
2197
|
+
eval [linsert $args 0 selection $path $cmd]
|
|
2198
|
+
switch -- $cmd {
|
|
2199
|
+
"add" - "clear" - "remove" - "set" - "toggle" {
|
|
2200
|
+
event generate $path <<TreeSelect>>
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
|
|
2206
|
+
proc Tree::_node_name { path node } {
|
|
2207
|
+
set map [list & _ | _ ^ _ ! _]
|
|
2208
|
+
return [string map $map $node]
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
|
|
2212
|
+
# ----------------------------------------------------------------------------
|
|
2213
|
+
# Command Tree::_destroy
|
|
2214
|
+
# ----------------------------------------------------------------------------
|
|
2215
|
+
proc Tree::_destroy { path } {
|
|
2216
|
+
variable $path
|
|
2217
|
+
upvar 0 $path data
|
|
2218
|
+
|
|
2219
|
+
if { $data(upd,afterid) != "" } {
|
|
2220
|
+
after cancel $data(upd,afterid)
|
|
2221
|
+
}
|
|
2222
|
+
if { $data(dnd,afterid) != "" } {
|
|
2223
|
+
after cancel $data(dnd,afterid)
|
|
2224
|
+
}
|
|
2225
|
+
_subdelete $path [lrange $data(root) 1 end]
|
|
2226
|
+
Widget::destroy $path
|
|
2227
|
+
unset data
|
|
2228
|
+
}
|