44# checkbutton, and radiobutton widgets and provides procedures
55# that help in implementing those bindings.
66#
7- # RCS: @(#) $Id: button.tcl,v 1.19 2005/07/25 09:06:01 dkf Exp $
7+ # RCS: @(#) $Id: button.tcl,v 1.19.4.1 2009/10/24 00:12:03 dkf Exp $
88#
99# Copyright (c) 1992-1994 The Regents of the University of California.
1010# Copyright (c) 1994-1996 Sun Microsystems, Inc.
@@ -37,6 +37,9 @@ if {[tk windowingsystem] eq "aqua"} {
3737 bind Checkbutton <ButtonRelease-1> {
3838 tk::ButtonUp %W
3939 }
40+ bind Checkbutton <Leave> {
41+ tk::ButtonLeave %W
42+ }
4043}
4144if {" windows" eq $tcl_platform(platform) } {
4245 bind Checkbutton <equal> {
@@ -57,6 +60,9 @@ if {"windows" eq $tcl_platform(platform)} {
5760 bind Checkbutton <Enter> {
5861 tk::CheckRadioEnter %W
5962 }
63+ bind Checkbutton <Leave> {
64+ tk::ButtonLeave %W
65+ }
6066
6167 bind Radiobutton <1> {
6268 tk::CheckRadioDown %W
@@ -71,7 +77,7 @@ if {"windows" eq $tcl_platform(platform)} {
7177if {" x11" eq [tk windowingsystem]} {
7278 bind Checkbutton <Return> {
7379 if {!$tk_strictMotif } {
74- tk::CheckRadioInvoke %W
80+ tk::CheckInvoke %W
7581 }
7682 }
7783 bind Radiobutton <Return> {
@@ -80,17 +86,20 @@ if {"x11" eq [tk windowingsystem]} {
8086 }
8187 }
8288 bind Checkbutton <1> {
83- tk::CheckRadioInvoke %W
89+ tk::CheckInvoke %W
8490 }
8591 bind Radiobutton <1> {
8692 tk::CheckRadioInvoke %W
8793 }
8894 bind Checkbutton <Enter> {
89- tk::ButtonEnter %W
95+ tk::CheckEnter %W
9096 }
9197 bind Radiobutton <Enter> {
9298 tk::ButtonEnter %W
9399 }
100+ bind Checkbutton <Leave> {
101+ tk::CheckLeave %W
102+ }
94103}
95104
96105bind Button <space> {
@@ -118,9 +127,6 @@ bind Button <ButtonRelease-1> {
118127}
119128
120129bind Checkbutton <FocusIn> {}
121- bind Checkbutton <Leave> {
122- tk::ButtonLeave %W
123- }
124130
125131bind Radiobutton <FocusIn> {}
126132bind Radiobutton <Leave> {
@@ -635,3 +641,108 @@ proc ::tk::CheckRadioInvoke {w {cmd invoke}} {
635641 uplevel #0 [list $w $cmd ]
636642 }
637643}
644+
645+ # Special versions of the handlers for checkbuttons on Unix that do the magic
646+ # to make things work right when the checkbutton indicator is hidden;
647+ # radiobuttons don't need this complexity.
648+
649+ # ::tk::CheckInvoke --
650+ # The procedure below invokes the checkbutton, like ButtonInvoke, but handles
651+ # what to do when the checkbutton indicator is missing. Only used on Unix.
652+ #
653+ # Arguments:
654+ # w - The name of the widget.
655+
656+ proc ::tk::CheckInvoke {w} {
657+ variable ::tk::Priv
658+ if {[$w cget -state] ne " disabled" } {
659+ # Additional logic to switch the "selected" colors around if necessary
660+ # (when we're indicator-less).
661+
662+ if {![$w cget -indicatoron]} {
663+ if {[$w cget -selectcolor] eq $Priv($w,aselectcolor) } {
664+ $w configure -selectcolor $Priv($w,selectcolor)
665+ } else {
666+ $w configure -selectcolor $Priv($w,aselectcolor)
667+ }
668+ }
669+ uplevel #0 [list $w invoke]
670+ }
671+ }
672+
673+ # ::tk::CheckEnter --
674+ # The procedure below enters the checkbutton, like ButtonEnter, but handles
675+ # what to do when the checkbutton indicator is missing. Only used on Unix.
676+ #
677+ # Arguments:
678+ # w - The name of the widget.
679+
680+ proc ::tk::CheckEnter {w} {
681+ variable ::tk::Priv
682+ if {[$w cget -state] ne " disabled" } {
683+ # On unix the state is active just with mouse-over
684+ $w configure -state active
685+
686+ # If the mouse button is down, set the relief to sunken on entry.
687+ # Overwise, if there's an -overrelief value, set the relief to that.
688+
689+ set Priv($w ,relief) [$w cget -relief]
690+ if {$Priv(buttonWindow) eq $w } {
691+ $w configure -relief sunken
692+ set Priv($w ,prelief) sunken
693+ } elseif {[set over [$w cget -overrelief]] ne " " } {
694+ $w configure -relief $over
695+ set Priv($w ,prelief) $over
696+ }
697+
698+ # Compute what the "selected and active" color should be.
699+
700+ if {![$w cget -indicatoron]} {
701+ set Priv($w ,selectcolor) [$w cget -selectcolor]
702+ lassign [winfo rgb $w [$w cget -selectcolor]] r1 g1 b1
703+ lassign [winfo rgb $w [$w cget -activebackground]] r2 g2 b2
704+ set Priv($w ,aselectcolor) \
705+ [format " #%04x%04x%04x" [expr {($r1 +$r2 )/2}] \
706+ [expr {($g1 +$g2 )/2}] [expr {($b1 +$b2 )/2}]]
707+ if {[set ::[$w cget -variable]] eq [$w cget -onvalue]} {
708+ $w configure -selectcolor $Priv($w,aselectcolor)
709+ }
710+ }
711+ }
712+ set Priv(window) $w
713+ }
714+
715+ # ::tk::CheckLeave --
716+ # The procedure below leaves the checkbutton, like ButtonLeave, but handles
717+ # what to do when the checkbutton indicator is missing. Only used on Unix.
718+ #
719+ # Arguments:
720+ # w - The name of the widget.
721+
722+ proc ::tk::CheckLeave {w} {
723+ variable ::tk::Priv
724+ if {[$w cget -state] ne " disabled" } {
725+ $w configure -state normal
726+ }
727+
728+ # Restore the original button "selected" color; assume that the user
729+ # wasn't monkeying around with things too much.
730+
731+ if {![$w cget -indicatoron] && [info exist Priv($w ,selectcolor)]} {
732+ $w configure -selectcolor $Priv($w,selectcolor)
733+ }
734+ unset -nocomplain Priv($w ,selectcolor) Priv($w ,aselectcolor)
735+
736+ # Restore the original button relief if it was changed by Tk. That is
737+ # signaled by the existence of Priv($w,prelief).
738+
739+ if {[info exists Priv($w ,relief)]} {
740+ if {[info exists Priv($w ,prelief)] && \
741+ $Priv($w,prelief) eq [$w cget -relief]} {
742+ $w configure -relief $Priv($w,relief)
743+ }
744+ unset -nocomplain Priv($w ,relief) Priv($w ,prelief)
745+ }
746+
747+ set Priv(window) " "
748+ }
0 commit comments