The current tooltip implementation has some quirks:
 * tiny font: when normal font is readable, tiny font is
   less readable :/
 * when entering an element with a tooltip the tooltip pops
   up even when the mouse has left the element in the
   meantime
 * tooltip stays open 15 seconds - assuming that everybody
   can read every tooltip in less than 15s; such
   assumptions are almost ever wrong

The patch is basically a reimplementation of tooltip.tcl:
 * use normal font
 * immediatly open/close a tooltip after entering/leaving an
   element
 * let the tooltip stay open until the mouse leaves the
   element
 * no useless method layer between events and the
   tooltip-display method; and no obscure locking mechanisms

The change integrates the snippet by Chris Edwards at
http://wiki.tcl.tk/1954.
---
 tcl/utils/tooltip.tcl | 145 ++++++++++++++++++++------------------------------
 1 file changed, 57 insertions(+), 88 deletions(-)

diff --git a/tcl/utils/tooltip.tcl b/tcl/utils/tooltip.tcl
index b5d4b0f..14d08e1 100644
--- a/tcl/utils/tooltip.tcl
+++ b/tcl/utils/tooltip.tcl
@@ -6,18 +6,14 @@
 namespace eval ::utils::tooltip {}
 
 set ::utils::tooltip::showToolTips 1
-set ::utils::tooltip::time 0
-set ::utils::tooltip::enteredWidget {}
-set ::utils::tooltip::tooltipDelay 400
+set ::utils::tooltip::tooltipDelay 500
 set ::utils::tooltip::tooltipWidth 30
 
-array set ::utils::tooltip::message {}
-
 # Construct tooltip window:
 #
 toplevel .tooltip
 label .tooltip.text -relief solid -borderwidth 1 -justify left \
-    -background #f5f5f5 -padx 3 -pady 1 -font font_Tiny
+    -background #f5f5f5 -padx 3 -pady 1
 pack .tooltip.text -side left
 wm overrideredirect .tooltip 1
 if { $macOS }  {
@@ -32,27 +28,18 @@ wm withdraw .tooltip
 #   Set the tooltip message for <button> to be <msg>
 #
 proc ::utils::tooltip::Set { button msg } {
+  variable showToolTips
   variable message
+  variable tooltipDelay
+  if {! $showToolTips} { return }
   set msg [string trim $msg]
   if {$msg == ""} { return }
   regsub {\\n} $msg "\n" msg
   set msg [::utils::tooltip::trimWidth $msg]
-  set message($button) $msg
-  bind $button <Any-Enter> +[list ::utils::tooltip::Enter $button]
-  bind $button <Any-Leave> +[list ::utils::tooltip::Leave $button]
-}
-
-# ::utils::tooltip::SetTag
-#
-#   remove a tooltip message for a given button
-#
-proc ::utils::tooltip::UnSet { button } {
-  variable message
-  if { [info exists ::utils::tooltip::message($button)] } {
-         unset message($button)
-         bind $button <Any-Enter> ""
-         bind $button <Any-Leave> ""
-  }
+  bind $button <Any-Enter> [list after $tooltipDelay [list 
::utils::tooltip::Show %W $msg]]
+  bind $button <Any-Leave> [list after $tooltipDelay [list destroy %W.tooltip]]
+  bind $button <Any-KeyPress> [list after $tooltipDelay [list destroy 
%W.tooltip]]
+  bind $button <Any-Button> [list after $tooltipDelay [list destroy 
%W.tooltip]]
 }
 
 # ::utils::tooltip::SetTag
@@ -60,85 +47,68 @@ proc ::utils::tooltip::UnSet { button } {
 #   Set the tooltip message for a text with tag <tag> to be <msg>
 #
 proc ::utils::tooltip::SetTag { text_widget msg tag } {
+  variable showToolTips
   variable message
+  if {! $showToolTips} { return }
   set msg [string trim $msg]
   if {$msg == ""} { return }
   regsub {\\n} $msg "\n" msg
   set msg [::utils::tooltip::trimWidth $msg]
-  set message(${tag}_$text_widget) $msg
-  $text_widget tag bind $tag <Any-Enter> +[list ::utils::tooltip::Enter 
${tag}_$text_widget]
-  $text_widget tag bind $tag <Any-Leave> +[list ::utils::tooltip::Leave 
${tag}_$text_widget]
+  $text_widget tag bind $tag <Any-Enter> [list after $tooltipDelay [list 
::utils::tooltip::Show ${tag}_$text_widget $msg]
+  $text_widget tag bind $tag <Any-Leave> [list after $tooltipDelay [list 
destroy ${tag}_$text_widget.tooltip]]
+  $text_widget tag bind $tag <Any-KeyPress> [list after $tooltipDelay [list 
destroy ${tag}_$text_widget.tooltip]]
+  $text_widget tag bind $tag <Any-Button> [list after $tooltipDelay [list 
destroy ${tag}_$text_widget.tooltip]]
 }
 
-# ::utils::tooltip::Enter
-#
-#   Handles the mouse entering a button which has a tooltip.
-#
-proc ::utils::tooltip::Enter {button} {
-  variable showToolTips
-  variable enteredWidget
-  variable tooltipDelay
-  
-  if {! $showToolTips} { return }
-  set enteredWidget $button
-  after $tooltipDelay [list ::utils::tooltip::Check $button]
-}
-
-
-# ::utils::tooltip::Check
+# ::utils::tooltip::Show
 #
 #   Called a set time after the mouse has entered a button with a
-#   tooltip, to check if it is still there. If so, the tooltip
-#   message is displayed.
+#   tooltip, to display a tooltip if necesarry.
 #
-proc ::utils::tooltip::Check {button} {
-  variable enteredWidget
-  
-  if {$enteredWidget != $button} {
-    # The mouse cursor has moved somewhere else; display no tooltip
+proc ::utils::tooltip::Show {button text} {
+  global tcl_platform
+
+  if { [string match $button* [winfo containing  [winfo pointerx .] [winfo 
pointery .]] ] == 0  } {
     return
   }
-  
-  if {! [info exists ::utils::tooltip::message($button)]} { return }
-  
-  .tooltip.text configure -text [tr $::utils::tooltip::message($button)]
-  set x [winfo pointerx .]
-  set y [winfo pointery .]
-  incr x 10
-  incr y 4
-  catch {wm transient .tooltip [winfo toplevel $button]}
-  
-  # make the tooltip visible
-  set maxw [ winfo vrootwidth .]
-  set maxh [ winfo vrootheight .]
-  set w [winfo reqwidth .tooltip]
-  set h [winfo reqheight .tooltip]
-  if { [expr $x + $w] > $maxw } {
-    set x [expr $maxw - $w]
+
+  catch {destroy $button.tooltip}
+
+  set scrh [winfo screenheight $button]
+  set scrw [winfo screenwidth $button]
+  set tooltip [toplevel $button.tooltip -bd 1 -bg black]
+  wm geometry $tooltip +$scrh+$scrw
+  wm overrideredirect $tooltip 1
+
+  if {$tcl_platform(platform) == {windows}} {
+          wm attributes $tooltip -topmost 1
   }
-  if { [expr $y + $h] > $maxh } {
-    set y [expr $maxh - $h]
+  pack [label $tooltip.label -bg lightyellow -fg black -text $text -justify 
left]
+
+  set width [winfo reqwidth $tooltip.label]
+  set height [winfo reqheight $tooltip.label]
+
+  # Is the pointer in the bottom half of the screen?
+  set pointer_below_midline [expr [winfo pointery .] > [expr [winfo 
screenheight .] / 2.0]]                
+  # Tooltip is centred horizontally on pointer.
+  set positionX [expr [winfo pointerx .] - round($width / 2.0)]
+  # Tooltip is displayed above or below depending on pointer Y position.
+  set positionY [expr [winfo pointery .] + 35 * ($pointer_below_midline * -2 + 
1) - round($height / 2.0)]  
+
+  # Ad-hockery: Set positionX so the entire tooltip widget will be displayed.
+  # Simplified slightly and modified to handle horizontally-centred tooltips 
and the left screen edge.
+  if  {[expr $positionX + $width] > [winfo screenwidth .]} {
+          set positionX [expr [winfo screenwidth .] - $width]
+  } elseif {$positionX < 0} {
+          set positionX 0
   }
-  
-  catch {wm geometry .tooltip +$x+$y}
-  wm deiconify .tooltip
-  raise .tooltip
-  
-  # Automatically erase tooltip after a short delay
-  after 15000 [ list ::utils::tooltip::Leave $button ]
-}
 
+  wm geometry $tooltip [join  "$width x $height + $positionX + $positionY" {}]
+  raise $tooltip
 
-# ::utils::tooltip::Leave
-#
-#   Handles the mouse leaving a button which has a tooltip.
-#
-proc ::utils::tooltip::Leave {button} {
-  after cancel [ list ::utils::tooltip::Leave $button ]
-  variable showToolTips
-  if {! $showToolTips} { return }
-  wm withdraw .tooltip
-  after cancel [list ::utils::tooltip::Check $button]
+  # Defeat rare artifact by passing mouse over a tooltip to destroy it.
+  bind $button.tooltip <Any-Enter> {destroy %W}
+  bind $button.tooltip <Any-Leave> {destroy %W}
 }
 
 # ::utils::tooltip::ToWidth
@@ -148,14 +118,14 @@ proc ::utils::tooltip::Leave {button} {
 proc ::utils::tooltip::trimWidth { msg } {
   set ret ""
   foreach line [split $msg "\n"] {
-    
+
     if {[string length $line] < $::utils::tooltip::tooltipWidth} {
       append ret "$line\n"
       continue
     } else  {
       # must split the line
       set words [split $line " "]
-      
+
       while {[llength $words] > 0} {
         set tmp [lindex $words 0]
         set words [lreplace $words 0 0]
@@ -165,7 +135,6 @@ proc ::utils::tooltip::trimWidth { msg } {
         }
         append ret $tmp "\n"
       }
-      
     }
   }
   return [string trim $ret]
-- 
2.1.4


------------------------------------------------------------------------------
_______________________________________________
Scid-users mailing list
Scid-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/scid-users

Reply via email to