Programming in XPCE/Prolog: Section 5.1

## 5.1 Graphical building blocks

A window is the most generic window class of XPCE. Drawings are often displayed on a picture, which is a window with scrollbars. The drawing area of a window is two-dimensional and infinitely large (both positive and negative). The query below creates a picture and opens it on the screen.

    1 ?- new(@p, picture('Demo Picture')),
         send(@p, open).

The following queries draw various primitive graphicals on this picture.

    2 ?- send(@p, display,
              new(@bo, box(100,100))).
    3 ?- send(@p, display,
              new(@ci, circle(50)), point(25,25)).
    4 ?- send(@p, display,
              new(@bm, bitmap('32x32/books.xpm')), point(100,100)).
    5 ?- send(@p, display,
              new(@tx, text('Hello')), point(120, 50)).
    6 ?- send(@p, display,
              new(@bz, bezier_curve(point(50,100),
                                    point(120,132),
                                    point(50, 160),
                                    point(120, 200)))).

XPCE's graphics infrastructure automatically takes care of the necessary repaint operations when graphical objects are manipulated. Try the queries below to appreciate this. The result is shown in figure 12.

    7  ?- send(@bo, radius, 10).
    8  ?- send(@ci, fill_pattern, colour(orange)).
    9  ?- send(@tx, font, font(times, bold, 18)).
    10 ?- send(@bz, arrows, both).

Figure 12 : Example graphics

XPCE avoids unnecessary repaint operations and expensive computations involved in updating the screen. The screen is only updated after all available input has been processed or on an explicit request to update it. The following code illustrates this. Running `?- square_to_circle(@bo).` will show the box immediately as a circle without showing any of the intermediate results.

    :- require([between/3, forall/2]).

    square_to_circle(Box) :-
            get(Box, height, H),
            MaxRadius is H // 2,
            forall(between(0, MaxRadius, Radius),
                   send(Box, radius, Radius)).

To get the intended animating behaviour, use `graphical`->`flush' to explicitly force redraw right now:

    :- require([between/3, forall/2]).

    square_to_circle(Box) :-
            get(Box, height, H),
            MaxRadius is H // 2,
            forall(between(0, MaxRadius, Radius),
                   (   send(Box, radius, Radius),
                       send(Box, flush)
                   )).

### 5.1.1 Available primitive graphical objects

An overview of the available primitive graphical classes is most easily obtained using the Class Hierarchy tool described in section 3.3.4. Table table 2 provides an overview of the primitive graphicals.

arrow | Arrow-head. Normally used implicitly by class line.
bezier | Bezier curve. Both quadratic and cubic Biezer curves are supported.
bitmap | Visualisation of an image. Both monochrome and full-colour images are supported. Images can have shape. See section 10.10.
pixmap | Subclass of bitmap only for coloured images.
box | Rectangle. Can be rounded and filled.
circle | Special case of ellipse.
ellipse | Elliptical shape. May be filled.
arc | Part of an ellipse. Can have arrows. Can show as pie-slice.
line | Straight line segment. Can have arrows.
path | Poly-line through multiple points. Can have arrows. Can be smooth.
text | Visualisation of a string in some font. Can have various attributes, can be clipped, formatted, etc.

Table 2 : Primitive graphical objects