In our tutorial so far, every time our window has been damaged we have had to manually redraw it. The application program is always responsible for redrawing its windows when they have been damaged. This can be accomplished by associating a callback with the window telling ProXL what to do when the window needs to be redrawn.
The steps required to automatically redraw our window are:
expose
event of the window, so
that the callback is invoked when the window needs to be redrawn
First, we must define the callback procedure to redraw our window:
| ?- compile(user). | redraw(Window, Pixel3, Pixel4) :- Xdisplacement = 4, Ydisplacement = 5, A = 20, X0 is 2+Xdisplacement, Y0 is 2+A+Ydisplacement, X1 is 2, Y1 is 2+A, put_graphics_attributes(Window, [foreground(Pixel4)]), draw_string(Window, X0, Y0, 'Hello, world!!'), put_graphics_attributes(Window, [foreground(Pixel3)]), draw_string(Window, X1, Y1, 'Hello, world!!'). | ^D % user compiled, 0.383 sec 380 bytes yes
Next we must register the callback for expose
events sent to our
window:
| ?- win(Window), colors(_, _, Pixel3, Pixel4), put_window_attributes(Window, [callback(expose, [count(0)], redraw(Window,Pixel3,Pixel4))]). Window = window(2376568), Pixel3 = 8, Pixel4 = 1
Here we have told ProXL that when the X server determines that it is
necessary to redraw the window, by sending expose
events, the
procedure redraw/3
should be called. The X server may send several
expose
events, each specifying a different part of the window
to be redrawn. Since this is a simple example, we don't bother to
redraw the window part by part. We just redraw the entire window
whenever any part of it needs to be redrawn. The second argument,
count(0)
, accomplishes this by telling ProXL that it should call
redraw/3
only if this is the last expose
message in the
group.2
Now if you do something to force X to redraw our window, like iconifying and then uniconifying it, or hiding it behind another window and then exposing it, you will find that the window is automatically refreshed. Try it.
Since an expose
event is sent to a window when it is
first mapped (appears on the screen), it is not necessary to write
separate code that initially draws the window and subsequently redraws
the window.
If we had wanted to do more precise redrawing, we would
have put [position(
X,
Y),size(
W,
H)]
as the second argument in our
callback specification, in place of [count(0)]
, and passed X, Y,
W, and H to the callback procedure. The callback procedure would then
only redraw the area of the window thus specified.