1 # General purpose code for being a tray applet
3 proc manyset {list args} {
4 foreach val $list var $args {
12 package require tktray
14 #----- general machinery -----
18 # tk::tktray widget is called .i
23 # applet::setup-tooltip ON-VISIBLE ON-INVISIBLE
24 # to make applet have a tooltip.
26 # ON-VISIBLE and ON-INVISIBLE will be globally eval'd
27 # when the tooltip becomes visible and invisible.
30 # applet::tooltip-set TEXT-MAYBE-MULTILINE
36 # applet::setimage IMAGE
39 # Inner window subprocess:
41 # Caller that needs access to inner window should define
42 # proc innerwindow {} { ... }
46 # .i.i.b frame to contain container
47 # .i.i.b.c actual container
51 # Caller may bind .i.i <ButtonPress-$b>
53 # Alternatively caller may call applet::setup-button-menu $b
54 # which will generate a menu .m$b which the user can configure
55 # and which will automatically be posted and unposted etc.
56 # In this case the caller should arrange that all of their
57 # menus, when an item is selected, call
62 tktray::icon .i -class example
63 .i configure -docked 1
66 namespace eval applet {
69 # used by both menus and tooltips
74 proc setup-button-menu {b} {
75 bind .i.i <ButtonPress> { applet::menubuttonpressed %b %X %Y }
79 proc menubuttonpressed {b x y} {
83 puts "unpost $posted toggle"
86 } elseif {[winfo exists .m$b]} {
89 puts "unpost $posted other"
102 #----- tooltips -----
104 variable tooltip_on_vis {}
105 variable tooltip_on_invis {}
107 proc tooltip-starttimer {state x y} {
108 variable tooltip_after
110 variable tooltip_inwindow
111 if {$state || $posted || !$tooltip_inwindow} { tooltip-cancel; return }
112 catch { after cancel $tooltip_after }
113 set tooltip_after [after 500 applet::tooltip-show $x $y]
116 proc tooltip-cancel {} {
117 variable tooltip_after
118 variable tooltip_on_invis
119 catch { after cancel $tooltip_after }
120 catch { unset $tooltip_after }
122 uplevel #0 $tooltip_on_invis
125 set tooltip_inwindow 0
127 proc tooltip-enter {state x y} {
128 variable tooltip_inwindow
129 set tooltip_inwindow 1
130 tooltip-starttimer $state $x $y
133 proc tooltip-leave {} {
134 variable tooltip_inwindow
135 set tooltip_inwindow 0
139 proc setup-tooltip {on_vis on_invis} {
140 foreach v {vis invis} {
141 variable tooltip_on_$v [set on_$v]
143 bind .i <Enter> { applet::tooltip-enter %s %X %Y }
144 bind .i <Leave> { applet::tooltip-leave }
145 bind .i <ButtonRelease> {
146 applet::tooltip-cancel
147 applet::tooltip-starttimer %s %X %Y
149 bind .i <Motion> { applet::tooltip-starttimer %s %X %Y }
150 toplevel .tt -background black
152 wm overrideredirect .tt 1
153 label .tt.t -justify left -background {#EEE1B3}
154 pack .tt.t -padx 1 -pady 1
158 proc tooltip-set {s} {
159 .tt.t configure -text $s
162 proc tooltip-show {x y} {
163 variable tooltip_on_vis
166 wm geometry .tt +$x+$y
168 uplevel #0 $tooltip_on_vis
171 #----- simple images -----
173 proc setimage {image} {
174 .i configure -image $image
180 proc innerwindow-resetup-required {why} {
181 variable innerwindow_after
183 if {[info exists innerwindow_after]} return
184 set innerwindow_after [after idle innerwindow-resetup]
187 proc innerwindow-resetup {} {
188 variable innerwindow_after
189 unset innerwindow_after
193 innerwindow-destroying
195 catch { destroy .i.i.c }
196 if {![winfo exists .i.i]} return
197 destroy [frame .i.i.make-exist]
198 catch { destroy .i.i.b.c }
199 catch { destroy .i.i.b }
201 pack .i.i.b -fill both -side left -expand 1
202 frame .i.i.b.c -container 1 -background orange
203 pack .i.i.b.c -fill both -side left -expand 1
205 global inner_lastw inner_lasth
206 #set w [winfo width .i.i]
207 # set w [winfo width .i.i]
208 # set h [winfo height .i.i]
210 # if {$w != $inner_lastw || $h != $inner_lasth} {
213 # innerwindow-ph-dummy configure -width $w -height 2
218 proc setupinnerwindow {w} {
219 global inner_lastw inner_lasth
223 image create photo innerwindow-ph-dummy -width $w -height 2
224 .i configure -image innerwindow-ph-dummy
226 destroy [frame .i.make-exist]
227 destroy [frame .i.i.make-exist]
228 bind .i <<IconConfigure>> { innerwindow-resetup-required IconConfigure }