3 # This file defines the default bindings for Tk label, button,
4 # checkbutton, and radiobutton widgets and provides procedures
5 # that help in implementing those bindings.
7 # RCS: @(#) $Id: button.tcl,v 1.17.2.1 2006/01/25 18:21:41 dgp Exp $
9 # Copyright (c) 1992-1994 The Regents of the University of California.
10 # Copyright (c) 1994-1996 Sun Microsystems, Inc.
11 # Copyright (c) 2002 ActiveState Corporation.
13 # See the file "license.terms" for information on usage and redistribution
14 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
17 #-------------------------------------------------------------------------
18 # The code below creates the default class bindings for buttons.
19 #-------------------------------------------------------------------------
21 if {[tk windowingsystem
] eq
"classic" ||
[tk windowingsystem
] eq
"aqua"} {
22 bind Radiobutton
<Enter
> {
25 bind Radiobutton
<1> {
28 bind Radiobutton
<ButtonRelease-1
> {
31 bind Checkbutton
<Enter
> {
34 bind Checkbutton
<1> {
37 bind Checkbutton
<ButtonRelease-1
> {
41 if {"windows" eq
$tcl_platform(platform
)} {
42 bind Checkbutton
<equal
> {
43 tk::CheckRadioInvoke %W select
45 bind Checkbutton
<plus
> {
46 tk::CheckRadioInvoke %W select
48 bind Checkbutton
<minus
> {
49 tk::CheckRadioInvoke %W deselect
51 bind Checkbutton
<1> {
54 bind Checkbutton
<ButtonRelease-1
> {
57 bind Checkbutton
<Enter
> {
58 tk::CheckRadioEnter %W
61 bind Radiobutton
<1> {
64 bind Radiobutton
<ButtonRelease-1
> {
67 bind Radiobutton
<Enter
> {
68 tk::CheckRadioEnter %W
71 if {"x11" eq
[tk windowingsystem
]} {
72 bind Checkbutton
<Return
> {
73 if {!$tk_strictMotif} {
74 tk::CheckRadioInvoke %W
77 bind Radiobutton
<Return
> {
78 if {!$tk_strictMotif} {
79 tk::CheckRadioInvoke %W
82 bind Checkbutton
<1> {
83 tk::CheckRadioInvoke %W
85 bind Radiobutton
<1> {
86 tk::CheckRadioInvoke %W
88 bind Checkbutton
<Enter
> {
91 bind Radiobutton
<Enter
> {
99 bind Checkbutton
<space
> {
100 tk::CheckRadioInvoke %W
102 bind Radiobutton
<space
> {
103 tk::CheckRadioInvoke %W
106 bind Button
<FocusIn
> {}
107 bind Button
<Enter
> {
110 bind Button
<Leave
> {
116 bind Button
<ButtonRelease-1
> {
120 bind Checkbutton
<FocusIn
> {}
121 bind Checkbutton
<Leave
> {
125 bind Radiobutton
<FocusIn
> {}
126 bind Radiobutton
<Leave
> {
130 if {"windows" eq
$tcl_platform(platform
)} {
132 #########################
133 # Windows implementation
134 #########################
136 # ::tk::ButtonEnter --
137 # The procedure below is invoked when the mouse pointer enters a
138 # button widget. It records the button we're in and changes the
139 # state of the button to active unless the button is disabled.
142 # w - The name of the widget.
144 proc ::tk::ButtonEnter w
{
146 if {[$w cget
-state] ne
"disabled"} {
148 # If the mouse button is down, set the relief to sunken on entry.
149 # Overwise, if there's an -overrelief value, set the relief to that.
151 set Priv
($w,relief
) [$w cget
-relief]
152 if {$Priv(buttonWindow
) eq
$w} {
153 $w configure
-relief sunken
-state active
154 set Priv
($w,prelief
) sunken
155 } elseif
{[set over
[$w cget
-overrelief]] ne
""} {
156 $w configure
-relief $over
157 set Priv
($w,prelief
) $over
163 # ::tk::ButtonLeave --
164 # The procedure below is invoked when the mouse pointer leaves a
165 # button widget. It changes the state of the button back to inactive.
166 # Restore any modified relief too.
169 # w - The name of the widget.
171 proc ::tk::ButtonLeave w
{
173 if {[$w cget
-state] ne
"disabled"} {
174 $w configure
-state normal
177 # Restore the original button relief if it was changed by Tk.
178 # That is signaled by the existence of Priv($w,prelief).
180 if {[info exists Priv
($w,relief
)]} {
181 if {[info exists Priv
($w,prelief
)] && \
182 $Priv($w,prelief
) eq
[$w cget
-relief]} {
183 $w configure
-relief $Priv($w,relief
)
185 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
191 # ::tk::ButtonDown --
192 # The procedure below is invoked when the mouse button is pressed in
193 # a button widget. It records the fact that the mouse is in the button,
194 # saves the button's relief so it can be restored later, and changes
195 # the relief to sunken.
198 # w - The name of the widget.
200 proc ::tk::ButtonDown w
{
203 # Only save the button's relief if it does not yet exist. If there
204 # is an overrelief setting, Priv($w,relief) will already have been set,
205 # and the current value of the -relief option will be incorrect.
207 if {![info exists Priv
($w,relief
)]} {
208 set Priv
($w,relief
) [$w cget
-relief]
211 if {[$w cget
-state] ne
"disabled"} {
212 set Priv
(buttonWindow
) $w
213 $w configure
-relief sunken
-state active
214 set Priv
($w,prelief
) sunken
216 # If this button has a repeatdelay set up, get it going with an after
217 after cancel
$Priv(afterId
)
218 set delay
[$w cget
-repeatdelay]
221 set Priv
(afterId
) [after $delay [list tk::ButtonAutoInvoke $w]]
227 # The procedure below is invoked when the mouse button is released
228 # in a button widget. It restores the button's relief and invokes
229 # the command as long as the mouse hasn't left the button.
232 # w - The name of the widget.
234 proc ::tk::ButtonUp w
{
236 if {$Priv(buttonWindow
) eq
$w} {
237 set Priv
(buttonWindow
) ""
239 # Restore the button's relief if it was cached.
241 if {[info exists Priv
($w,relief
)]} {
242 if {[info exists Priv
($w,prelief
)] && \
243 $Priv($w,prelief
) eq
[$w cget
-relief]} {
244 $w configure
-relief $Priv($w,relief
)
246 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
249 # Clean up the after event from the auto-repeater
250 after cancel
$Priv(afterId
)
252 if {$Priv(window
) eq
$w && [$w cget
-state] ne
"disabled"} {
253 $w configure
-state normal
255 # Only invoke the command if it wasn't already invoked by the
256 # auto-repeater functionality
257 if { $Priv(repeated
) == 0 } {
258 uplevel #0 [list $w invoke]
264 # ::tk::CheckRadioEnter --
265 # The procedure below is invoked when the mouse pointer enters a
266 # checkbutton or radiobutton widget. It records the button we're in
267 # and changes the state of the button to active unless the button is
271 # w - The name of the widget.
273 proc ::tk::CheckRadioEnter w
{
275 if {[$w cget
-state] ne
"disabled"} {
276 if {$Priv(buttonWindow
) eq
$w} {
277 $w configure
-state active
279 if {[set over
[$w cget
-overrelief]] ne
""} {
280 set Priv
($w,relief
) [$w cget
-relief]
281 set Priv
($w,prelief
) $over
282 $w configure
-relief $over
288 # ::tk::CheckRadioDown --
289 # The procedure below is invoked when the mouse button is pressed in
290 # a button widget. It records the fact that the mouse is in the button,
291 # saves the button's relief so it can be restored later, and changes
292 # the relief to sunken.
295 # w - The name of the widget.
297 proc ::tk::CheckRadioDown w
{
299 if {![info exists Priv
($w,relief
)]} {
300 set Priv
($w,relief
) [$w cget
-relief]
302 if {[$w cget
-state] ne
"disabled"} {
303 set Priv
(buttonWindow
) $w
305 $w configure
-state active
311 if {"x11" eq
[tk windowingsystem
]} {
313 #####################
314 # Unix implementation
315 #####################
317 # ::tk::ButtonEnter --
318 # The procedure below is invoked when the mouse pointer enters a
319 # button widget. It records the button we're in and changes the
320 # state of the button to active unless the button is disabled.
323 # w - The name of the widget.
325 proc ::tk::ButtonEnter {w
} {
327 if {[$w cget
-state] ne
"disabled"} {
328 # On unix the state is active just with mouse-over
329 $w configure
-state active
331 # If the mouse button is down, set the relief to sunken on entry.
332 # Overwise, if there's an -overrelief value, set the relief to that.
334 set Priv
($w,relief
) [$w cget
-relief]
335 if {$Priv(buttonWindow
) eq
$w} {
336 $w configure
-relief sunken
337 set Priv
($w,prelief
) sunken
338 } elseif
{[set over
[$w cget
-overrelief]] ne
""} {
339 $w configure
-relief $over
340 set Priv
($w,prelief
) $over
346 # ::tk::ButtonLeave --
347 # The procedure below is invoked when the mouse pointer leaves a
348 # button widget. It changes the state of the button back to inactive.
349 # Restore any modified relief too.
352 # w - The name of the widget.
354 proc ::tk::ButtonLeave w
{
356 if {[$w cget
-state] ne
"disabled"} {
357 $w configure
-state normal
360 # Restore the original button relief if it was changed by Tk.
361 # That is signaled by the existence of Priv($w,prelief).
363 if {[info exists Priv
($w,relief
)]} {
364 if {[info exists Priv
($w,prelief
)] && \
365 $Priv($w,prelief
) eq
[$w cget
-relief]} {
366 $w configure
-relief $Priv($w,relief
)
368 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
374 # ::tk::ButtonDown --
375 # The procedure below is invoked when the mouse button is pressed in
376 # a button widget. It records the fact that the mouse is in the button,
377 # saves the button's relief so it can be restored later, and changes
378 # the relief to sunken.
381 # w - The name of the widget.
383 proc ::tk::ButtonDown w
{
386 # Only save the button's relief if it does not yet exist. If there
387 # is an overrelief setting, Priv($w,relief) will already have been set,
388 # and the current value of the -relief option will be incorrect.
390 if {![info exists Priv
($w,relief
)]} {
391 set Priv
($w,relief
) [$w cget
-relief]
394 if {[$w cget
-state] ne
"disabled"} {
395 set Priv
(buttonWindow
) $w
396 $w configure
-relief sunken
397 set Priv
($w,prelief
) sunken
399 # If this button has a repeatdelay set up, get it going with an after
400 after cancel
$Priv(afterId
)
401 set delay
[$w cget
-repeatdelay]
404 set Priv
(afterId
) [after $delay [list tk::ButtonAutoInvoke $w]]
410 # The procedure below is invoked when the mouse button is released
411 # in a button widget. It restores the button's relief and invokes
412 # the command as long as the mouse hasn't left the button.
415 # w - The name of the widget.
417 proc ::tk::ButtonUp w
{
419 if {$w eq
$Priv(buttonWindow
)} {
420 set Priv
(buttonWindow
) ""
422 # Restore the button's relief if it was cached.
424 if {[info exists Priv
($w,relief
)]} {
425 if {[info exists Priv
($w,prelief
)] && \
426 $Priv($w,prelief
) eq
[$w cget
-relief]} {
427 $w configure
-relief $Priv($w,relief
)
429 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
432 # Clean up the after event from the auto-repeater
433 after cancel
$Priv(afterId
)
435 if {$Priv(window
) eq
$w && [$w cget
-state] ne
"disabled"} {
436 # Only invoke the command if it wasn't already invoked by the
437 # auto-repeater functionality
438 if { $Priv(repeated
) == 0 } {
439 uplevel #0 [list $w invoke]
447 if {[tk windowingsystem
] eq
"classic" ||
[tk windowingsystem
] eq
"aqua"} {
453 # ::tk::ButtonEnter --
454 # The procedure below is invoked when the mouse pointer enters a
455 # button widget. It records the button we're in and changes the
456 # state of the button to active unless the button is disabled.
459 # w - The name of the widget.
461 proc ::tk::ButtonEnter {w
} {
463 if {[$w cget
-state] ne
"disabled"} {
465 # If there's an -overrelief value, set the relief to that.
467 if {$Priv(buttonWindow
) eq
$w} {
468 $w configure
-state active
469 } elseif
{[set over
[$w cget
-overrelief]] ne
""} {
470 set Priv
($w,relief
) [$w cget
-relief]
471 set Priv
($w,prelief
) $over
472 $w configure
-relief $over
478 # ::tk::ButtonLeave --
479 # The procedure below is invoked when the mouse pointer leaves a
480 # button widget. It changes the state of the button back to
481 # inactive. If we're leaving the button window with a mouse button
482 # pressed (Priv(buttonWindow) == $w), restore the relief of the
486 # w - The name of the widget.
488 proc ::tk::ButtonLeave w
{
490 if {$w eq
$Priv(buttonWindow
)} {
491 $w configure
-state normal
494 # Restore the original button relief if it was changed by Tk.
495 # That is signaled by the existence of Priv($w,prelief).
497 if {[info exists Priv
($w,relief
)]} {
498 if {[info exists Priv
($w,prelief
)] && \
499 $Priv($w,prelief
) eq
[$w cget
-relief]} {
500 $w configure
-relief $Priv($w,relief
)
502 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
508 # ::tk::ButtonDown --
509 # The procedure below is invoked when the mouse button is pressed in
510 # a button widget. It records the fact that the mouse is in the button,
511 # saves the button's relief so it can be restored later, and changes
512 # the relief to sunken.
515 # w - The name of the widget.
517 proc ::tk::ButtonDown w
{
520 if {[$w cget
-state] ne
"disabled"} {
521 set Priv
(buttonWindow
) $w
522 $w configure
-state active
524 # If this button has a repeatdelay set up, get it going with an after
525 after cancel
$Priv(afterId
)
527 if { ![catch {$w cget
-repeatdelay} delay
] } {
529 set Priv
(afterId
) [after $delay [list tk::ButtonAutoInvoke $w]]
536 # The procedure below is invoked when the mouse button is released
537 # in a button widget. It restores the button's relief and invokes
538 # the command as long as the mouse hasn't left the button.
541 # w - The name of the widget.
543 proc ::tk::ButtonUp w
{
545 if {$Priv(buttonWindow
) eq
$w} {
546 set Priv
(buttonWindow
) ""
547 $w configure
-state normal
549 # Restore the button's relief if it was cached.
551 if {[info exists Priv
($w,relief
)]} {
552 if {[info exists Priv
($w,prelief
)] && \
553 $Priv($w,prelief
) eq
[$w cget
-relief]} {
554 $w configure
-relief $Priv($w,relief
)
556 unset -nocomplain Priv
($w,relief
) Priv
($w,prelief
)
559 # Clean up the after event from the auto-repeater
560 after cancel
$Priv(afterId
)
562 if {$Priv(window
) eq
$w && [$w cget
-state] ne
"disabled"} {
563 # Only invoke the command if it wasn't already invoked by the
564 # auto-repeater functionality
565 if { $Priv(repeated
) == 0 } {
566 uplevel #0 [list $w invoke]
578 # ::tk::ButtonInvoke --
579 # The procedure below is called when a button is invoked through
580 # the keyboard. It simulate a press of the button via the mouse.
583 # w - The name of the widget.
585 proc ::tk::ButtonInvoke w
{
586 if {[$w cget
-state] ne
"disabled"} {
587 set oldRelief
[$w cget
-relief]
588 set oldState
[$w cget
-state]
589 $w configure
-state active
-relief sunken
592 $w configure
-state $oldState -relief $oldRelief
593 uplevel #0 [list $w invoke]
597 # ::tk::ButtonAutoInvoke --
599 # Invoke an auto-repeating button, and set it up to continue to repeat.
602 # w button to invoke.
608 # May create an after event to call ::tk::ButtonAutoInvoke.
610 proc ::tk::ButtonAutoInvoke {w
} {
612 after cancel
$Priv(afterId
)
613 set delay
[$w cget
-repeatinterval]
614 if {$Priv(window
) eq
$w} {
616 uplevel #0 [list $w invoke]
619 set Priv
(afterId
) [after $delay [list tk::ButtonAutoInvoke $w]]
623 # ::tk::CheckRadioInvoke --
624 # The procedure below is invoked when the mouse button is pressed in
625 # a checkbutton or radiobutton widget, or when the widget is invoked
626 # through the keyboard. It invokes the widget if it
630 # w - The name of the widget.
631 # cmd - The subcommand to invoke (one of invoke, select, or deselect).
633 proc ::tk::CheckRadioInvoke {w
{cmd invoke
}} {
634 if {[$w cget
-state] ne
"disabled"} {
635 uplevel #0 [list $w $cmd]