~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tcl/mb/tix.tcl

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 # tix.tcl --
  2 #
  3 #       Popup tips for Tk
  4 
  5 # ---------------------------------------------------------------------------
  6 # This software is in the public domain, furnished "as is", without technical
  7 # support, and with no warranty, express or implied, as to its usefulness for
  8 # any purpose.
  9 #
 10 # tips.tcl
 11 # Popup tips for Tk
 12 # ---------------------------------------------------------------------------
 13 
 14 # -- module -----------------------------------------------------------------
 15 #
 16 # This package provides popup tips for widgets in Tcl/Tk.  Call "add_tip"
 17 # to add a tip to a widget, and "remove_tip" to remove it.
 18 #
 19 # ---------------------------------------------------------------------------
 20 
 21 package provide "tips" 1.0
 22 
 23 #
 24 # Programmatic defaults: feel free to adjust the first three.
 25 #
 26 array set tip_priv {
 27     window_delay             500
 28     y_offset                 5
 29     x_offset                 20
 30     currently_tipping        ""
 31     tips_enabled             1
 32     tips_initialized         0
 33 }
 34 
 35 # -- proc -------------------------------------------------------------------
 36 # add_tip
 37 #
 38 # Add a tip message to the given widget.  When the pointer enters the
 39 # widget, it'll wait a bit, then if it's still there, it'll map the
 40 # tip window.  As soon as the pointer leaves, then it unmaps it.
 41 # ---------------------------------------------------------------------------
 42 proc add_tip {window msg} {
 43     global tip_priv
 44 
 45     if {! $tip_priv(tips_initialized)} {tip_init_tips}
 46 
 47     # Save the message text for later use.
 48     set tip_priv($window) $msg
 49 
 50     # Add the tip bindings to the window ... now, it might already have
 51     # them if we got called to change the text, so check first.
 52     set tags [bindtags $window]
 53     if {[lsearch -exact $tags TipBindings] == -1} {
 54         # They're not in there, add 'em.
 55         bindtags $window [concat TipBindings [bindtags $window]]
 56     }
 57 }
 58 
 59 # -- proc -------------------------------------------------------------------
 60 # remove_tip
 61 #
 62 # Remove the popup tip for this window.
 63 # ---------------------------------------------------------------------------
 64 proc remove_tip {window} {
 65     global tip_priv
 66 
 67     # Do we have saved text for this window?  If so, then we have to get rid of it
 68     # and the window's class binding, too.
 69     if [info exists tip_priv($window)] {
 70         # Okay, nuke the text.
 71         unset tip_priv($window)
 72 
 73         # Now, get the tags and see if the TipBindings is among them.
 74         set tags [bindtags $window]
 75         if {[set index [lsearch -exact $tags TipBindings]] >= 0} {
 76             # Yep, it's there.  Set the new bindings without TipBindings present.
 77             bindtags $window [lreplace $tags $index $index]
 78         }
 79 
 80         # Also, if the tip window is visible for this widget, nuke it.
 81         if {$tip_priv(currently_tipping) == $window} {
 82             destroy .tip
 83             set tip_priv(currently_tipping) ""
 84         }
 85     } else {
 86         # It's not set?  Well, I never.
 87         error "No popup tip set for $window"
 88     }
 89 }
 90 
 91 # -- proc -------------------------------------------------------------------
 92 # enable_tips
 93 #
 94 # With boolean true, enable all popup tips.  False, disable all of them.
 95 # ---------------------------------------------------------------------------
 96 proc enable_tips {bool} {
 97     global tip_priv
 98 
 99     set tip_priv(tips_enabled) $bool
100     if {! $bool && $tip_priv(currently_tipping) != ""} {
101         destroy $tip_priv(currently_tipping)
102         set tip_priv(currently_tipping) ""
103     }
104 }
105 
106 # -- proc -------------------------------------------------------------------
107 # tip_make_window
108 #
109 # Make and map the tip window for the given widget.
110 # ---------------------------------------------------------------------------
111 proc tip_make_window {window} {
112     global tip_priv
113 
114     # Note that we're mapping the tip window.
115     set tip_priv(currently_tipping) $window
116 
117     # Get rid of it if it already exists
118     catch {destroy .tip}
119 
120     # Figure out the X and Y coord of the tip window.  It should be below the widget it's tipping,
121     # and slightly to the right of its left edge, too.
122     set y [expr [winfo rooty $window] + [winfo height $window] + $tip_priv(y_offset)]
123     set x [expr [winfo rootx $window] + $tip_priv(x_offset)]
124 
125     # Create it at the correct coords, and prevent the window manager from slapping a border around it.
126     toplevel .tip -class Tip
127     wm overrideredirect .tip yes
128     wm geometry .tip +$x+$y
129     # Insert the message and we're done.
130     pack [message .tip.message -text $tip_priv($window) -bg beige]
131 }
132 
133 # -- proc -------------------------------------------------------------------
134 # tip_cancel_tip
135 #
136 # Cancel any currently displayed tip by unmapping the window (if it's mapped)
137 # and by canceling the timer to display a window.
138 # ---------------------------------------------------------------------------
139 proc tip_cancel_tip {} {
140     global tip_priv
141 
142     if {! $tip_priv(tips_enabled)} return
143 
144     if {$tip_priv(currently_tipping) != ""} {
145         catch {destroy .tip}
146         set tip_priv(currently_tipping) ""
147     }
148     catch {after cancel $tip_priv(after_id)}
149 }
150 
151 # -- proc -------------------------------------------------------------------
152 # tip_init_tips
153 #
154 # Initialize the tips.  Currently, this just means adding X resources
155 # and setting up bindings.  Override these in your own X resources, if
156 # you must.  (Note that if you use Vue, you likely have things like
157 # "*background", which will override these settings no matter what.
158 # You may want to add these settings in that case.)
159 # ---------------------------------------------------------------------------
160 proc tip_init_tips {} {
161     global tip_priv
162 
163     # X defaults for the popup.
164     option add "*tip.message.background"  "LemonChiffon"                widgetDefault
165     option add "*tip.message.foreground"  "Black"                       widgetDefault
166     option add "*tip.message.relief"      "raised"                      widgetDefault
167     option add "*tip.message.borderWidth" "2"                           widgetDefault
168     option add "*tip.message.justify"     "left"                        widgetDefault
169     option add "*tip.message.aspect"      "350"                         widgetDefault
170     option add "*tip.message.font"        "-*-helvetica-medium-r-normal-*-*-120-*-*-*-*-*-*" widgetDefault
171 
172     # Bindings for the TipBindings tag.
173     bind TipBindings <Enter> {
174         global tip_priv
175 
176         if {! $tip_priv(tips_enabled)} continue
177 
178         set tip_priv(currently_tipping) ""
179         set tip_priv(after_id) [after $tip_priv(window_delay) tip_make_window %W]
180     }
181     bind TipBindings <Leave> {
182         tip_cancel_tip
183     }
184     bind TipBindings <Button-1> {
185         tip_cancel_tip
186     }
187     bind TipBindings <space> {
188         tip_cancel_tip
189     }
190 
191     set tip_priv(tips_initialized) 1
192 }
193 
194 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.