Upgrade to Tcl/Tk 8.5b2
[msysgit.git] / mingw / lib / tk8.5 / ttk / treeview.tcl
blob3ccb7468e7767d7718c9e2d8bce19fdc9175cefd
1 # $Id: treeview.tcl,v 1.2 2006/12/18 19:33:14 jenglish Exp $
3 # ttk::treeview widget bindings and utilities.
6 namespace eval ttk::treeview {
7 variable State
9 # Enter/Leave/Motion
11 set State(activeWidget) {}
12 set State(activeHeading) {}
14 # Press/drag/release:
16 set State(pressMode) none
17 set State(pressX) 0
19 # For pressMode == "resize"
20 set State(resizeColumn) #0
22 # For pressmode == "heading"
23 set State(heading) {}
25 # Provide [lassign] if not already present
26 # (@@@ TODO: check if this is still needed after horrible-identify purge)
28 if {![llength [info commands lassign]]} {
29 proc lassign {vals args} {
30 uplevel 1 [list foreach $args $vals break]
35 ### Widget bindings.
38 bind Treeview <Motion> { ttk::treeview::Motion %W %x %y }
39 bind Treeview <B1-Leave> { #nothing }
40 bind Treeview <Leave> { ttk::treeview::ActivateHeading {} {}}
41 bind Treeview <ButtonPress-1> { ttk::treeview::Press %W %x %y }
42 bind Treeview <Double-ButtonPress-1> { ttk::treeview::DoubleClick %W %x %y }
43 bind Treeview <ButtonRelease-1> { ttk::treeview::Release %W %x %y }
44 bind Treeview <B1-Motion> { ttk::treeview::Drag %W %x %y }
45 bind Treeview <KeyPress-Up> { ttk::treeview::Keynav %W up }
46 bind Treeview <KeyPress-Down> { ttk::treeview::Keynav %W down }
47 bind Treeview <KeyPress-Right> { ttk::treeview::Keynav %W right }
48 bind Treeview <KeyPress-Left> { ttk::treeview::Keynav %W left }
49 bind Treeview <KeyPress-Prior> { %W yview scroll -1 pages }
50 bind Treeview <KeyPress-Next> { %W yview scroll 1 pages }
51 bind Treeview <KeyPress-Return> { ttk::treeview::ToggleFocus %W }
52 bind Treeview <KeyPress-space> { ttk::treeview::ToggleFocus %W }
54 bind Treeview <Shift-ButtonPress-1> \
55 { ttk::treeview::Select %W %x %y extend }
56 bind Treeview <Control-ButtonPress-1> \
57 { ttk::treeview::Select %W %x %y toggle }
59 # Standard mousewheel bindings:
61 bind Treeview <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units }
62 if {[string equal "x11" [tk windowingsystem]]} {
63 bind Treeview <ButtonPress-4> { %W yview scroll -5 units }
64 bind Treeview <ButtonPress-5> { %W yview scroll 5 units }
67 ### Binding procedures.
70 ## Keynav -- Keyboard navigation
72 # @@@ TODO: verify/rewrite up and down code.
74 proc ttk::treeview::Keynav {w dir} {
75 set focus [$w focus]
76 if {$focus eq ""} { return }
78 switch -- $dir {
79 up {
80 if {[set up [$w prev $focus]] eq ""} {
81 set focus [$w parent $focus]
82 } else {
83 while {[$w item $up -open] && [llength [$w children $up]]} {
84 set up [lindex [$w children $up] end]
86 set focus $up
89 down {
90 if {[$w item $focus -open] && [llength [$w children $focus]]} {
91 set focus [lindex [$w children $focus] 0]
92 } else {
93 set up $focus
94 while {$up ne "" && [set down [$w next $up]] eq ""} {
95 set up [$w parent $up]
97 set focus $down
100 left {
101 if {[$w item $focus -open] && [llength [$w children $focus]]} {
102 CloseItem $w $focus
103 } else {
104 set focus [$w parent $focus]
107 right {
108 OpenItem $w $focus
112 if {$focus != {}} {
113 SelectOp $w $focus choose
117 ## Motion -- pointer motion binding.
118 # Sets cursor, active element ...
120 proc ttk::treeview::Motion {w x y} {
121 variable ::ttk::Cursors
122 variable State
124 set cursor {}
125 set activeHeading {}
127 lassign [$w identify $x $y] what where detail
128 switch -- $what {
129 separator { set cursor $Cursors(hresize) }
130 heading { set activeHeading $where }
133 if {[$w cget -cursor] ne $cursor} {
134 $w configure -cursor $cursor
136 ActivateHeading $w $activeHeading
139 ## ActivateHeading -- track active heading element
141 proc ttk::treeview::ActivateHeading {w heading} {
142 variable State
144 if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
145 if {$State(activeHeading) != {}} {
146 $State(activeWidget) heading $State(activeHeading) state !active
148 if {$heading != {}} {
149 $w heading $heading state active
151 set State(activeHeading) $heading
152 set State(activeWidget) $w
156 ## Select $w $x $y $selectop
157 # Binding procedure for selection operations.
158 # See "Selection modes", below.
160 proc ttk::treeview::Select {w x y op} {
161 if {[set item [$w identify row $x $y]] ne "" } {
162 SelectOp $w $item $op
166 ## DoubleClick -- Double-ButtonPress-1 binding.
168 proc ttk::treeview::DoubleClick {w x y} {
169 if {[set row [$w identify row $x $y]] ne ""} {
170 Toggle $w $row
171 } else {
172 Press $w $x $y ;# perform single-click action
176 ## Press -- ButtonPress binding.
178 proc ttk::treeview::Press {w x y} {
179 lassign [$w identify $x $y] what where detail
180 focus $w ;# or: ClickToFocus?
182 switch -- $what {
183 nothing { }
184 heading { heading.press $w $where }
185 separator { resize.press $w $x $where }
186 cell -
187 row -
188 item { SelectOp $w $where choose }
190 if {$what eq "item" && [string match *indicator $detail]} {
191 Toggle $w $where
195 ## Drag -- B1-Motion binding
197 proc ttk::treeview::Drag {w x y} {
198 variable State
199 switch $State(pressMode) {
200 resize { resize.drag $w $x }
201 heading { heading.drag $w $x $y }
205 proc ttk::treeview::Release {w x y} {
206 variable State
207 switch $State(pressMode) {
208 resize { resize.release $w $x }
209 heading { heading.release $w }
211 set State(pressMode) none
212 Motion $w $x $y
215 ### Interactive column resizing.
217 proc ttk::treeview::resize.press {w x column} {
218 variable State
219 set State(pressMode) "resize"
220 set State(resizeColumn) $column
223 proc ttk::treeview::resize.drag {w x} {
224 variable State
225 $w drag $State(resizeColumn) $x
228 proc ttk::treeview::resize.release {w x} {
229 # no-op
232 ### Heading activation.
235 proc ttk::treeview::heading.press {w column} {
236 variable State
237 set State(pressMode) "heading"
238 set State(heading) $column
239 $w heading $column state pressed
242 proc ttk::treeview::heading.drag {w x y} {
243 variable State
244 lassign [$w identify $x $y] what where detail
245 if {$what eq "heading" && $where eq $State(heading)} {
246 $w heading $State(heading) state pressed
247 } else {
248 $w heading $State(heading) state !pressed
252 proc ttk::treeview::heading.release {w} {
253 variable State
254 if {[lsearch -exact [$w heading $State(heading) state] pressed] >= 0} {
255 after idle [$w heading $State(heading) -command]
257 $w heading $State(heading) state !pressed
260 ### Selection modes.
263 ## SelectOp $w $item [ choose | extend | toggle ] --
264 # Dispatch to appropriate selection operation
265 # depending on current value of -selectmode.
267 proc ttk::treeview::SelectOp {w item op} {
268 select.$op.[$w cget -selectmode] $w $item
271 ## -selectmode none:
273 proc ttk::treeview::select.choose.none {w item} { $w focus $item }
274 proc ttk::treeview::select.toggle.none {w item} { $w focus $item }
275 proc ttk::treeview::select.extend.none {w item} { $w focus $item }
277 ## -selectmode browse:
279 proc ttk::treeview::select.choose.browse {w item} { BrowseTo $w $item }
280 proc ttk::treeview::select.toggle.browse {w item} { BrowseTo $w $item }
281 proc ttk::treeview::select.extend.browse {w item} { BrowseTo $w $item }
283 ## -selectmode multiple:
285 proc ttk::treeview::select.choose.extended {w item} {
286 BrowseTo $w $item
288 proc ttk::treeview::select.toggle.extended {w item} {
289 $w selection toggle $item
291 proc ttk::treeview::select.extend.extended {w item} {
292 if {[set anchor [$w focus]] ne ""} {
293 $w selection set [between $w $anchor $item]
294 } else {
295 BrowseTo $item
299 ### Tree structure utilities.
302 ## between $tv $item1 $item2 --
303 # Returns a list of all items between $item1 and $item2,
304 # in preorder traversal order. $item1 and $item2 may be
305 # in either order.
307 # NOTES:
308 # This routine is O(N) in the size of the tree.
309 # There's probably a way to do this that's O(N) in the number
310 # of items returned, but I'm not clever enough to figure it out.
312 proc ttk::treeview::between {tv item1 item2} {
313 variable between [list]
314 variable selectingBetween 0
315 ScanBetween $tv $item1 $item2 {}
316 return $between
319 ## ScanBetween --
320 # Recursive worker routine for ttk::treeview::between
322 proc ttk::treeview::ScanBetween {tv item1 item2 item} {
323 variable between
324 variable selectingBetween
326 if {$item eq $item1 || $item eq $item2} {
327 lappend between $item
328 set selectingBetween [expr {!$selectingBetween}]
329 } elseif {$selectingBetween} {
330 lappend between $item
332 foreach child [$tv children $item] {
333 ScanBetween $tv $item1 $item2 $child
337 ### User interaction utilities.
340 ## OpenItem, CloseItem -- Set the open state of an item, generate event
343 proc ttk::treeview::OpenItem {w item} {
344 $w focus $item
345 event generate $w <<TreeviewOpen>>
346 $w item $item -open true
349 proc ttk::treeview::CloseItem {w item} {
350 $w item $item -open false
351 $w focus $item
352 event generate $w <<TreeviewClose>>
355 ## Toggle -- toggle opened/closed state of item
357 proc ttk::treeview::Toggle {w item} {
358 if {[$w item $item -open]} {
359 CloseItem $w $item
360 } else {
361 OpenItem $w $item
365 ## ToggleFocus -- toggle opened/closed state of focus item
367 proc ttk::treeview::ToggleFocus {w} {
368 set item [$w focus]
369 if {$item ne ""} {
370 Toggle $w $item
374 ## BrowseTo -- navigate to specified item; set focus and selection
376 proc ttk::treeview::BrowseTo {w item} {
377 $w see $item
378 $w focus $item
379 $w selection set [list $item]
382 #*EOF*