3 # This file defines the default bindings for Tk listbox widgets
4 # and provides procedures that help in implementing those bindings.
6 # Copyright (c) 1994 The Regents of the University of California.
7 # Copyright (c) 1994-1995 Sun Microsystems, Inc.
8 # Copyright (c) 1998 by Scriptics Corporation.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 #--------------------------------------------------------------------------
14 # tk::Priv elements used in this file:
16 # afterId - Token returned by "after" for autoscanning.
17 # listboxPrev - The last element to be selected or deselected
18 # during a selection operation.
19 # listboxSelection - All of the items that were selected before the
20 # current selection operation (such as a mouse
21 # drag) started; used to cancel an operation.
22 #--------------------------------------------------------------------------
24 #-------------------------------------------------------------------------
25 # The code below creates the default class bindings for listboxes.
26 #-------------------------------------------------------------------------
28 # Note: the check for existence of %W below is because this binding
29 # is sometimes invoked after a window has been deleted (e.g. because
30 # there is a double-click binding on the widget that deletes it). Users
31 # can put "break"s in their bindings to avoid the error, but this check
32 # makes that unnecessary.
35 if {[winfo exists
%W
]} {
36 tk::ListboxBeginSelect %W
[%W index
@%x
,%y
] 1
40 # Ignore double clicks so that users can define their own behaviors.
41 # Among other things, this prevents errors if the user deletes the
42 # listbox on a double click.
44 bind Listbox
<Double-1
> {
48 bind Listbox
<B1-Motion
> {
51 tk::ListboxMotion %W
[%W index
@%x
,%y
]
53 bind Listbox
<ButtonRelease-1
> {
57 bind Listbox
<Shift-1
> {
58 tk::ListboxBeginExtend %W
[%W index
@%x
,%y
]
60 bind Listbox
<Control-1
> {
61 tk::ListboxBeginToggle %W
[%W index
@%x
,%y
]
63 bind Listbox
<B1-Leave
> {
66 tk::ListboxAutoScan %W
68 bind Listbox
<B1-Enter
> {
73 tk::ListboxUpDown %W
-1
75 bind Listbox
<Shift-Up
> {
76 tk::ListboxExtendUpDown %W
-1
79 tk::ListboxUpDown %W
1
81 bind Listbox
<Shift-Down
> {
82 tk::ListboxExtendUpDown %W
1
85 %W xview scroll
-1 units
87 bind Listbox
<Control-Left
> {
88 %W xview scroll
-1 pages
90 bind Listbox
<Right
> {
91 %W xview scroll
1 units
93 bind Listbox
<Control-Right
> {
94 %W xview scroll
1 pages
96 bind Listbox
<Prior
> {
97 %W yview scroll
-1 pages
100 bind Listbox
<Next
> {
101 %W yview scroll
1 pages
104 bind Listbox
<Control-Prior
> {
105 %W xview scroll
-1 pages
107 bind Listbox
<Control-Next
> {
108 %W xview scroll
1 pages
110 bind Listbox
<Home
> {
116 bind Listbox
<Control-Home
> {
119 %W
selection clear
0 end
121 event generate
%W
<<ListboxSelect
>>
123 bind Listbox
<Shift-Control-Home
> {
124 tk::ListboxDataExtend %W
0
126 bind Listbox
<Control-End
> {
129 %W
selection clear
0 end
131 event generate
%W
<<ListboxSelect
>>
133 bind Listbox
<Shift-Control-End
> {
134 tk::ListboxDataExtend %W
[%W index end
]
136 bind Listbox
<<Copy
>> {
137 if {[selection own
-displayof %W
] eq
"%W"} {
138 clipboard clear
-displayof %W
139 clipboard append -displayof %W
[selection get
-displayof %W
]
142 bind Listbox
<space
> {
143 tk::ListboxBeginSelect %W
[%W index active
]
145 bind Listbox
<Select
> {
146 tk::ListboxBeginSelect %W
[%W index active
]
148 bind Listbox
<Control-Shift-space
> {
149 tk::ListboxBeginExtend %W
[%W index active
]
151 bind Listbox
<Shift-Select
> {
152 tk::ListboxBeginExtend %W
[%W index active
]
154 bind Listbox
<Escape
> {
157 bind Listbox
<Control-slash
> {
158 tk::ListboxSelectAll %W
160 bind Listbox
<Control-backslash
> {
161 if {[%W cget
-selectmode] ne
"browse"} {
162 %W
selection clear
0 end
163 event generate
%W
<<ListboxSelect
>>
167 # Additional Tk bindings that aren't part of the Motif look and feel:
172 bind Listbox
<B2-Motion
> {
176 # The MouseWheel will typically only fire on Windows and Mac OS X.
177 # However, someone could use the "event generate" command to produce
178 # one on other platforms.
180 if {[tk windowingsystem
] eq
"aqua"} {
181 bind Listbox
<MouseWheel
> {
182 %W yview scroll
[expr {- (%D
)}] units
184 bind Listbox
<Option-MouseWheel
> {
185 %W yview scroll
[expr {-10 * (%D
)}] units
187 bind Listbox
<Shift-MouseWheel
> {
188 %W xview scroll
[expr {- (%D
)}] units
190 bind Listbox
<Shift-Option-MouseWheel
> {
191 %W xview scroll
[expr {-10 * (%D
)}] units
194 bind Listbox
<MouseWheel
> {
195 %W yview scroll
[expr {- (%D
/ 120) * 4}] units
199 if {"x11" eq
[tk windowingsystem
]} {
200 # Support for mousewheels on Linux/Unix commonly comes through mapping
201 # the wheel to the extended buttons. If you have a mousewheel, find
202 # Linux configuration info at:
203 # http://www.inria.fr/koala/colas/mouse-wheel-scroll/
205 if {!$tk_strictMotif} {
206 %W yview scroll
-5 units
210 if {!$tk_strictMotif} {
211 %W yview scroll
5 units
216 # ::tk::ListboxBeginSelect --
218 # This procedure is typically invoked on button-1 presses. It begins
219 # the process of making a selection in the listbox. Its exact behavior
220 # depends on the selection mode currently in effect for the listbox;
221 # see the Motif documentation for details.
224 # w - The listbox widget.
225 # el - The element for the selection operation (typically the
226 # one under the pointer). Must be in numerical form.
228 proc ::tk::ListboxBeginSelect {w el
{focus 1}} {
230 if {[$w cget
-selectmode] eq
"multiple"} {
231 if {[$w selection includes
$el]} {
232 $w selection clear
$el
237 $w selection clear
0 end
239 $w selection anchor
$el
240 set Priv
(listboxSelection
) {}
241 set Priv
(listboxPrev
) $el
243 event generate
$w <<ListboxSelect
>>
244 # check existence as ListboxSelect may destroy us
245 if {$focus && [winfo exists
$w] && [$w cget
-state] eq
"normal"} {
250 # ::tk::ListboxMotion --
252 # This procedure is called to process mouse motion events while
253 # button 1 is down. It may move or extend the selection, depending
254 # on the listbox's selection mode.
257 # w - The listbox widget.
258 # el - The element under the pointer (must be a number).
260 proc ::tk::ListboxMotion {w el
} {
262 if {$el == $Priv(listboxPrev
)} {
265 set anchor
[$w index anchor
]
266 switch [$w cget
-selectmode] {
268 $w selection clear
0 end
270 set Priv
(listboxPrev
) $el
271 event generate
$w <<ListboxSelect
>>
274 set i
$Priv(listboxPrev
)
279 if {[$w selection includes anchor
]} {
280 $w selection clear
$i $el
281 $w selection set anchor
$el
283 $w selection clear
$i $el
284 $w selection clear anchor
$el
286 if {![info exists Priv
(listboxSelection
)]} {
287 set Priv
(listboxSelection
) [$w curselection
]
289 while {($i < $el) && ($i < $anchor)} {
290 if {[lsearch $Priv(listboxSelection
) $i] >= 0} {
295 while {($i > $el) && ($i > $anchor)} {
296 if {[lsearch $Priv(listboxSelection
) $i] >= 0} {
301 set Priv
(listboxPrev
) $el
302 event generate
$w <<ListboxSelect
>>
307 # ::tk::ListboxBeginExtend --
309 # This procedure is typically invoked on shift-button-1 presses. It
310 # begins the process of extending a selection in the listbox. Its
311 # exact behavior depends on the selection mode currently in effect
312 # for the listbox; see the Motif documentation for details.
315 # w - The listbox widget.
316 # el - The element for the selection operation (typically the
317 # one under the pointer). Must be in numerical form.
319 proc ::tk::ListboxBeginExtend {w el
} {
320 if {[$w cget
-selectmode] eq
"extended"} {
321 if {[$w selection includes anchor
]} {
324 # No selection yet; simulate the begin-select operation.
325 ListboxBeginSelect
$w $el
330 # ::tk::ListboxBeginToggle --
332 # This procedure is typically invoked on control-button-1 presses. It
333 # begins the process of toggling a selection in the listbox. Its
334 # exact behavior depends on the selection mode currently in effect
335 # for the listbox; see the Motif documentation for details.
338 # w - The listbox widget.
339 # el - The element for the selection operation (typically the
340 # one under the pointer). Must be in numerical form.
342 proc ::tk::ListboxBeginToggle {w el
} {
344 if {[$w cget
-selectmode] eq
"extended"} {
345 set Priv
(listboxSelection
) [$w curselection
]
346 set Priv
(listboxPrev
) $el
347 $w selection anchor
$el
348 if {[$w selection includes
$el]} {
349 $w selection clear
$el
353 event generate
$w <<ListboxSelect
>>
357 # ::tk::ListboxAutoScan --
358 # This procedure is invoked when the mouse leaves an entry window
359 # with button 1 down. It scrolls the window up, down, left, or
360 # right, depending on where the mouse left the window, and reschedules
361 # itself as an "after" command so that the window continues to scroll until
362 # the mouse moves back into the window or the mouse button is released.
365 # w - The entry window.
367 proc ::tk::ListboxAutoScan {w
} {
369 if {![winfo exists
$w]} return
372 if {$y >= [winfo height
$w]} {
373 $w yview scroll
1 units
375 $w yview scroll
-1 units
376 } elseif
{$x >= [winfo width
$w]} {
377 $w xview scroll
2 units
379 $w xview scroll
-2 units
383 ListboxMotion
$w [$w index
@$x,$y]
384 set Priv
(afterId
) [after 50 [list tk::ListboxAutoScan $w]]
387 # ::tk::ListboxUpDown --
389 # Moves the location cursor (active element) up or down by one element,
390 # and changes the selection if we're in browse or extended selection
394 # w - The listbox widget.
395 # amount - +1 to move down one item, -1 to move back one item.
397 proc ::tk::ListboxUpDown {w amount
} {
399 $w activate
[expr {[$w index active
] + $amount}]
401 switch [$w cget
-selectmode] {
403 $w selection clear
0 end
404 $w selection set active
405 event generate
$w <<ListboxSelect
>>
408 $w selection clear
0 end
409 $w selection set active
410 $w selection anchor active
411 set Priv
(listboxPrev
) [$w index active
]
412 set Priv
(listboxSelection
) {}
413 event generate
$w <<ListboxSelect
>>
418 # ::tk::ListboxExtendUpDown --
420 # Does nothing unless we're in extended selection mode; in this
421 # case it moves the location cursor (active element) up or down by
422 # one element, and extends the selection to that point.
425 # w - The listbox widget.
426 # amount - +1 to move down one item, -1 to move back one item.
428 proc ::tk::ListboxExtendUpDown {w amount
} {
430 if {[$w cget
-selectmode] ne
"extended"} {
433 set active
[$w index active
]
434 if {![info exists Priv
(listboxSelection
)]} {
435 $w selection set $active
436 set Priv
(listboxSelection
) [$w curselection
]
438 $w activate
[expr {$active + $amount}]
440 ListboxMotion
$w [$w index active
]
443 # ::tk::ListboxDataExtend
445 # This procedure is called for key-presses such as Shift-KEndData.
446 # If the selection mode isn't multiple or extend then it does nothing.
447 # Otherwise it moves the active element to el and, if we're in
448 # extended mode, extends the selection to that point.
451 # w - The listbox widget.
452 # el - An integer element number.
454 proc ::tk::ListboxDataExtend {w el
} {
455 set mode
[$w cget
-selectmode]
456 if {$mode eq
"extended"} {
459 if {[$w selection includes anchor
]} {
462 } elseif
{$mode eq
"multiple"} {
468 # ::tk::ListboxCancel
470 # This procedure is invoked to cancel an extended selection in
471 # progress. If there is an extended selection in progress, it
472 # restores all of the items between the active one and the anchor
473 # to their previous selection state.
476 # w - The listbox widget.
478 proc ::tk::ListboxCancel w
{
480 if {[$w cget
-selectmode] ne
"extended"} {
483 set first
[$w index anchor
]
484 set last
$Priv(listboxPrev
)
486 # Not actually doing any selection right now
489 if {$first > $last} {
494 $w selection clear
$first $last
495 while {$first <= $last} {
496 if {[lsearch $Priv(listboxSelection
) $first] >= 0} {
497 $w selection set $first
501 event generate
$w <<ListboxSelect
>>
504 # ::tk::ListboxSelectAll
506 # This procedure is invoked to handle the "select all" operation.
507 # For single and browse mode, it just selects the active element.
508 # Otherwise it selects everything in the widget.
511 # w - The listbox widget.
513 proc ::tk::ListboxSelectAll w
{
514 set mode
[$w cget
-selectmode]
515 if {$mode eq
"single" ||
$mode eq
"browse"} {
516 $w selection clear
0 end
517 $w selection set active
519 $w selection set 0 end
521 event generate
$w <<ListboxSelect
>>