2 # ttk::treeview widget bindings and utilities.
5 namespace eval ttk
::treeview {
10 set State
(activeWidget
) {}
11 set State
(activeHeading
) {}
15 set State
(pressMode
) none
18 # For pressMode == "resize"
19 set State
(resizeColumn
) #0
21 # For pressmode == "heading"
28 bind Treeview
<Motion
> { ttk
::treeview::Motion %W
%x
%y
}
29 bind Treeview
<B1-Leave
> { #nothing }
30 bind Treeview
<Leave
> { ttk
::treeview::ActivateHeading {} {}}
31 bind Treeview
<ButtonPress-1
> { ttk
::treeview::Press %W
%x
%y
}
32 bind Treeview
<Double-ButtonPress-1
> { ttk
::treeview::DoubleClick %W
%x
%y
}
33 bind Treeview
<ButtonRelease-1
> { ttk
::treeview::Release %W
%x
%y
}
34 bind Treeview
<B1-Motion
> { ttk
::treeview::Drag %W
%x
%y
}
35 bind Treeview
<KeyPress-Up
> { ttk
::treeview::Keynav %W up
}
36 bind Treeview
<KeyPress-Down
> { ttk
::treeview::Keynav %W down
}
37 bind Treeview
<KeyPress-Right
> { ttk
::treeview::Keynav %W right
}
38 bind Treeview
<KeyPress-Left
> { ttk
::treeview::Keynav %W left
}
39 bind Treeview
<KeyPress-Prior
> { %W yview scroll
-1 pages
}
40 bind Treeview
<KeyPress-Next
> { %W yview scroll
1 pages
}
41 bind Treeview
<KeyPress-Return
> { ttk
::treeview::ToggleFocus %W
}
42 bind Treeview
<KeyPress-space
> { ttk
::treeview::ToggleFocus %W
}
44 bind Treeview
<Shift-ButtonPress-1
> \
45 { ttk
::treeview::Select %W
%x
%y extend
}
46 bind Treeview
<Control-ButtonPress-1
> \
47 { ttk
::treeview::Select %W
%x
%y toggle
}
49 ttk
::copyBindings TtkScrollable Treeview
51 ### Binding procedures.
54 ## Keynav -- Keyboard navigation
56 # @@@ TODO: verify/rewrite up and down code.
58 proc ttk
::treeview::Keynav {w dir
} {
60 if {$focus eq
""} { return }
64 if {[set up
[$w prev
$focus]] eq
""} {
65 set focus [$w parent
$focus]
67 while {[$w item
$up -open] && [llength [$w children
$up]]} {
68 set up
[lindex [$w children
$up] end
]
74 if {[$w item
$focus -open] && [llength [$w children
$focus]]} {
75 set focus [lindex [$w children
$focus] 0]
78 while {$up ne
"" && [set down
[$w next
$up]] eq
""} {
79 set up
[$w parent
$up]
85 if {[$w item
$focus -open] && [llength [$w children
$focus]]} {
88 set focus [$w parent
$focus]
97 SelectOp
$w $focus choose
101 ## Motion -- pointer motion binding.
102 # Sets cursor, active element ...
104 proc ttk
::treeview::Motion {w x y
} {
108 switch -- [$w identify region
$x $y] {
109 separator
{ set cursor hresize
}
110 heading
{ set activeHeading
[$w identify column
$x $y] }
113 ttk
::setCursor $w $cursor
114 ActivateHeading
$w $activeHeading
117 ## ActivateHeading -- track active heading element
119 proc ttk
::treeview::ActivateHeading {w heading
} {
122 if {$w != $State(activeWidget
) ||
$heading != $State(activeHeading
)} {
123 if {$State(activeHeading
) != {}} {
124 $State(activeWidget
) heading
$State(activeHeading
) state
!active
126 if {$heading != {}} {
127 $w heading
$heading state active
129 set State
(activeHeading
) $heading
130 set State
(activeWidget
) $w
134 ## Select $w $x $y $selectop
135 # Binding procedure for selection operations.
136 # See "Selection modes", below.
138 proc ttk
::treeview::Select {w x y op
} {
139 if {[set item
[$w identify row
$x $y]] ne
"" } {
140 SelectOp
$w $item $op
144 ## DoubleClick -- Double-ButtonPress-1 binding.
146 proc ttk
::treeview::DoubleClick {w x y
} {
147 if {[set row
[$w identify row
$x $y]] ne
""} {
150 Press
$w $x $y ;# perform single-click action
154 ## Press -- ButtonPress binding.
156 proc ttk
::treeview::Press {w x y
} {
158 switch -- [$w identify region
$x $y] {
160 heading
{ heading.press
$w $x $y }
161 separator
{ resize.press
$w $x $y }
164 set item
[$w identify item
$x $y]
165 SelectOp
$w $item choose
166 switch -glob -- [$w identify element
$x $y] {
168 *disclosure
{ Toggle
$w $item }
174 ## Drag -- B1-Motion binding
176 proc ttk
::treeview::Drag {w x y
} {
178 switch $State(pressMode
) {
179 resize
{ resize.drag
$w $x }
180 heading
{ heading.drag
$w $x $y }
184 proc ttk
::treeview::Release {w x y
} {
186 switch $State(pressMode
) {
187 resize
{ resize.release
$w $x }
188 heading
{ heading.release
$w }
190 set State
(pressMode
) none
194 ### Interactive column resizing.
196 proc ttk
::treeview::resize.press
{w x y
} {
198 set State
(pressMode
) "resize"
199 set State
(resizeColumn
) [$w identify column
$x $y]
202 proc ttk
::treeview::resize.drag
{w x
} {
204 $w drag
$State(resizeColumn
) $x
207 proc ttk
::treeview::resize.release
{w x
} {
211 ### Heading activation.
214 proc ttk
::treeview::heading.press
{w x y
} {
216 set column
[$w identify column
$x $y]
217 set State
(pressMode
) "heading"
218 set State
(heading
) $column
219 $w heading
$column state pressed
222 proc ttk
::treeview::heading.drag
{w x y
} {
224 if { [$w identify region
$x $y] eq
"heading"
225 && [$w identify column
$x $y] eq
$State(heading
)
227 $w heading
$State(heading
) state pressed
229 $w heading
$State(heading
) state
!pressed
233 proc ttk
::treeview::heading.release
{w
} {
235 if {[lsearch -exact [$w heading
$State(heading
) state
] pressed
] >= 0} {
236 after 0 [$w heading
$State(heading
) -command]
238 $w heading
$State(heading
) state
!pressed
244 ## SelectOp $w $item [ choose | extend | toggle ] --
245 # Dispatch to appropriate selection operation
246 # depending on current value of -selectmode.
248 proc ttk
::treeview::SelectOp {w item op
} {
249 select.
$op.
[$w cget
-selectmode] $w $item
254 proc ttk
::treeview::select.choose.none
{w item
} { $w focus $item }
255 proc ttk
::treeview::select.toggle.none
{w item
} { $w focus $item }
256 proc ttk
::treeview::select.extend.none
{w item
} { $w focus $item }
258 ## -selectmode browse:
260 proc ttk
::treeview::select.choose.browse
{w item
} { BrowseTo
$w $item }
261 proc ttk
::treeview::select.toggle.browse
{w item
} { BrowseTo
$w $item }
262 proc ttk
::treeview::select.extend.browse
{w item
} { BrowseTo
$w $item }
264 ## -selectmode multiple:
266 proc ttk
::treeview::select.choose.extended
{w item
} {
269 proc ttk
::treeview::select.toggle.extended
{w item
} {
270 $w selection toggle
[list $item]
272 proc ttk
::treeview::select.extend.extended
{w item
} {
273 if {[set anchor
[$w focus]] ne
""} {
274 $w selection set [between
$w $anchor $item]
280 ### Tree structure utilities.
283 ## between $tv $item1 $item2 --
284 # Returns a list of all items between $item1 and $item2,
285 # in preorder traversal order. $item1 and $item2 may be
289 # This routine is O(N) in the size of the tree.
290 # There's probably a way to do this that's O(N) in the number
291 # of items returned, but I'm not clever enough to figure it out.
293 proc ttk
::treeview::between {tv item1 item2
} {
294 variable between
[list]
295 variable selectingBetween
0
296 ScanBetween
$tv $item1 $item2 {}
301 # Recursive worker routine for ttk::treeview::between
303 proc ttk
::treeview::ScanBetween {tv item1 item2 item
} {
305 variable selectingBetween
307 if {$item eq
$item1 ||
$item eq
$item2} {
308 lappend between
$item
309 set selectingBetween
[expr {!$selectingBetween}]
310 } elseif
{$selectingBetween} {
311 lappend between
$item
313 foreach child
[$tv children
$item] {
314 ScanBetween
$tv $item1 $item2 $child
318 ### User interaction utilities.
321 ## OpenItem, CloseItem -- Set the open state of an item, generate event
324 proc ttk
::treeview::OpenItem {w item
} {
326 event generate
$w <<TreeviewOpen
>>
327 $w item
$item -open true
330 proc ttk
::treeview::CloseItem {w item
} {
331 $w item
$item -open false
333 event generate
$w <<TreeviewClose
>>
336 ## Toggle -- toggle opened/closed state of item
338 proc ttk
::treeview::Toggle {w item
} {
339 if {[$w item
$item -open]} {
346 ## ToggleFocus -- toggle opened/closed state of focus item
348 proc ttk
::treeview::ToggleFocus {w
} {
355 ## BrowseTo -- navigate to specified item; set focus and selection
357 proc ttk
::treeview::BrowseTo {w item
} {
360 $w selection set [list $item]