<< Prev | - Up - |
In the following we want to look at a small example which provides for a generic interactive help popup window. The idea is that if the mouse pointer stays over a widget for some time without pressing a mouse button, a small help text is displayed. The help text should disappear if the mouse pointer leaves the screen area covered by the widget.
We will build a procedure AttachHelp
such that help texts are enabled by application of the procedure to a widget and a help text. We proceed in three steps, the first is to create a function to create a toplevel widget that displays the help text, the second is a listener class (that is, a subclass of Tk.listener
), and the last step is the definition of AttachHelp
itself.
The procedure MakePopup
shown in Figure 5.12 takes a widget and the help text as its argument and returns a function to create a toplevel widget containing the text at a position relative to the widget on the screen.
fun {MakePopup Parent Text}
fun {$}
[X Y H]={Map [rootx rooty height]
fun {$ WI}
{Tk.returnInt winfo(WI Parent)}
end}
W={New Tk.toplevel tkInit(withdraw:true bg:black)}
M={New Tk.message
tkInit(parent:W text:Text bg:khaki aspect:400)}
in
{Tk.batch [wm(overrideredirect W true)
wm(geometry W '+'#X+10#'+'#Y+H)
pack(M padx:2 pady:2)
wm(deiconify W)]}
W
end
end
The returned function creates a toplevel widget in withdrawn state and configures the toplevel widget such that it:
is not equipped with a frame from the window manager. This is done by using the window manager command overrideredirect
: the window manager is advised to not ``redirect'' the toplevel widget into a frame.
appears at a position relative to X
and Y
coordinates of the widget parent, which done by the geometry
window manager command.
appears on the screen by deiconifying it.
The listener class HelpListener
is shown in Figure 5.13. The method init
initializes an instance of this class by creating a procedure for creation of the popup widget.
class HelpListener from Tk.listener
attr
cancel: unit
popup: unit
meth init(parent:P text:T)
popup := {MakePopup P T}
Tk.listener,tkInit
end
meth enter
C
in
cancel := C
thread A={Alarm 1000} in
{WaitOr C A}
if {IsDet A} then W={@popup} in
{Wait C} {W tkClose}
end
end
end
meth leave
@cancel=unit
end
end
When the mouse pointer enters the parent widget, the method enter
gets executed. This method stores a new variable C
in the attribute cancel
which serves as flag whether the help popup must be closed. The newly created thread waits until either one second has elapsed (A
gets bound after 1000 milliseconds) or the widget has been left (C
gets bound). Then possibly the widget for the help text is created, which gets closed when the parent widget is left. Note that if both A
and C
happen to be bound at the same time, the popup will be created and then closed immediately.
The leave
method signals that the help popup must be closed by binding the variable stored in cancel
.
AttachHelp
The definition of AttachHelp
is shown in Figure 5.14. It creates a listener and creates event bindings that are served by that listener.
local
<Definition of MakePopup>
<Definition of HelpListener>
in
proc {AttachHelp Widget Text}
L={New HelpListener init(parent:Widget text:Text)}
in
{Widget tkBind(event:'<Enter>' action:L#enter append:true)}
{Widget tkBind(event:'<Leave>' action:L#leave append:true)}
{Widget tkBind(event:'<Button>' action:L#leave append:true)}
end
end
A small example that shows how to use help popups is shown in Figure 5.15.
Bs={Map ['Okay' # 'Do nothing meaningful.'
'Cancel' # 'Do nothing at all.'
'Quit' # 'Close the window.']
fun {$ Text # Help}
B={New Tk.button tkInit(parent:W text:Text)}
in
{AttachHelp B Help} B
end}
{Tk.send pack(b(Bs) side:left padx:2#m pady:2#m)}
<< Prev | - Up - |