From e068f6b14b3d1bd9e48900cc80ea783c56ba8c0c Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Thu, 13 Nov 2003 18:26:59 +0000 Subject: text widget dbl-click single character fix --- ChangeLog | 5 +++ library/text.tcl | 58 +++++++++++++++--------- tests/event.test | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 174 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 454e2f8..b58d633 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-11-13 Vince Darley + + * tests/event.test: + * library/text.tcl: fixed the text widget portion of [Bug 542199] + 2003-11-13 Donal K. Fellows * generic/tkMenuDraw.c (TkPostSubmenu,AdjustMenuCoords): Rewrote diff --git a/library/text.tcl b/library/text.tcl index e4daa3f..93434a0 100644 --- a/library/text.tcl +++ b/library/text.tcl @@ -3,7 +3,7 @@ # This file defines the default bindings for Tk text widgets and provides # procedures that help in implementing the bindings. # -# RCS: @(#) $Id: text.tcl,v 1.28 2003/11/13 14:44:22 vincentdarley Exp $ +# RCS: @(#) $Id: text.tcl,v 1.29 2003/11/13 18:27:00 vincentdarley Exp $ # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. @@ -521,6 +521,14 @@ proc ::tk::TextButton1 {w x y} { set Priv(pressX) $x $w mark set insert [TextClosestGap $w $x $y] $w mark set anchor insert + # Set the anchor mark's gravity depending on the click position + # relative to the gap + set bbox [$w bbox [$w index anchor]] + if {$x > [lindex $bbox 0]} { + $w mark gravity anchor right + } else { + $w mark gravity anchor left + } # Allow focus in any case on Windows, because that will let the # selection be displayed even for state disabled text widgets. if {[string equal $::tcl_platform(platform) "windows"] \ @@ -552,7 +560,7 @@ proc ::tk::TextSelectTo {w x y {extend 0}} { if {[$w compare $cur != $anchor] || (abs($Priv(pressX) - $x) >= 3)} { set Priv(mouseMoved) 1 } - switch $Priv(selectMode) { + switch -- $Priv(selectMode) { char { if {[$w compare $cur < anchor]} { set first $cur @@ -563,30 +571,38 @@ proc ::tk::TextSelectTo {w x y {extend 0}} { } } word { - if {[$w compare $cur < anchor]} { - set first [TextPrevPos $w "$cur + 1c" tcl_wordBreakBefore] - if { !$extend } { - set last [TextNextPos $w "anchor" tcl_wordBreakAfter] - } else { - set last anchor - } + # Set initial range based only on the anchor (1 char min width) + if {[string equal [$w mark gravity anchor] "right"]} { + set first "anchor" + set last "anchor + 1c" } else { - set last [TextNextPos $w "$cur - 1c" tcl_wordBreakAfter] - if { !$extend } { - set first [TextPrevPos $w anchor tcl_wordBreakBefore] - } else { - set first anchor - } + set first "anchor - 1c" + set last "anchor" + } + # Extend range (if necessary) based on the current point + if {[$w compare $cur < $first]} { + set first $cur + } elseif {[$w compare $cur > $last]} { + set last $cur } + + # Now find word boundaries + set first [TextPrevPos $w "$first + 1c" tcl_wordBreakBefore] + set last [TextNextPos $w "$last - 1c" tcl_wordBreakAfter] } line { - if {[$w compare $cur < anchor]} { - set first [$w index "$cur linestart"] - set last [$w index "anchor - 1c lineend + 1c"] - } else { - set first [$w index "anchor linestart"] - set last [$w index "$cur lineend + 1c"] + # Set initial range based only on the anchor + set first "anchor linestart" + set last "anchor lineend" + + # Extend range (if necessary) based on the current point + if {[$w compare $cur < $first]} { + set first "$cur linestart" + } elseif {[$w compare $cur > $last]} { + set last "$cur lineend" } + set first [$w index $first] + set last [$w index "$last + 1c"] } } if {$Priv(mouseMoved) || ($Priv(selectMode) ne "char")} { diff --git a/tests/event.test b/tests/event.test index c726d68..35ea9bf 100644 --- a/tests/event.test +++ b/tests/event.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: event.test,v 1.14 2003/04/01 21:06:23 dgp Exp $ +# RCS: @(#) $Id: event.test,v 1.15 2003/11/13 18:27:00 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -475,7 +475,7 @@ test event-double-click-drag-1.1 { click down, click up, click down again, set result [list] lappend result [_get_selection $e] - # Insert cursor should be at end of "select" + # Insert cursor should be at beginning of "select" lappend result [$e index insert] # Move mouse one character to the left @@ -515,7 +515,7 @@ test event-double-click-drag-1.1 { click down, click up, click down again, lappend result [$e index insert] set result -} {select 1.11 1.7 select 1.4 { select} {Word select} 1.2} +} {select 1.5 1.7 select 1.4 { select} {Word select} 1.2} @@ -662,6 +662,135 @@ test event-button-state-1.1 { button press in a window that is then set motion } nomotion +test event-double-click-1.1 { A double click on a lone character + in a text widget should select that character. } { + destroy .t + set t [toplevel .t] + set e [text $t.e] + pack $e + tkwait visibility $e + focus -force $e + _keypress_string $e "On A letter" + + set anchor 1.3 + + # Get x,y coords just inside the left + # and right hand side of the letter A + foreach {x1 y1 width height} [$e bbox $anchor] break + + set middle_y [expr {$y1 + ($height / 2)}] + + set left_x [expr {$x1 + 2}] + set left_y $middle_y + + set right_x [expr {($x1 + $width) - 2}] + set right_y $middle_y + + # Double click near left hand egde of the letter A + + event generate $e + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + + set result [list] + lappend result [$e index insert] + lappend result [_get_selection $e] + + # Clear selection by clicking at 0,0 + + event generate $e -x 0 -y 0 + _pause 50 + event generate $e -x 0 -y 0 + _pause 50 + + # Double click near right hand edge of the letter A + + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + + lappend result [$e index insert] + lappend result [_get_selection $e] + + set result +} {1.3 A 1.3 A} + + +test event-double-click-1.2 { A double click on a lone character + in an entry widget should select that character. } {knownBug} { + destroy .t + set t [toplevel .t] + set e [entry $t.e] + pack $e + tkwait visibility $e + focus -force $e + _keypress_string $e "On A letter" + + set anchor 3 + + # Get x,y coords just inside the left + # and right hand side of the letter A + foreach {x1 y1 width height} [$e bbox $anchor] break + + set middle_y [expr {$y1 + ($height / 2)}] + + set left_x [expr {$x1 + 2}] + set left_y $middle_y + + set right_x [expr {($x1 + $width) - 2}] + set right_y $middle_y + + # Double click near left hand egde of the letter A + + event generate $e + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + event generate $e -x $left_x -y $left_y + _pause 50 + + set result [list] + lappend result [$e index insert] + lappend result [_get_selection $e] + + # Clear selection by clicking at 0,0 + + event generate $e -x 0 -y 0 + _pause 50 + event generate $e -x 0 -y 0 + _pause 50 + + # Double click near right hand edge of the letter A + + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + event generate $e -x $right_x -y $right_y + _pause 50 + + lappend result [$e index insert] + lappend result [_get_selection $e] + + set result +} {3 A 4 A} + # cleanup destroy .t -- cgit v0.12