Introduction | Chapter 1 | Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | CLOS Intro

Allegro CL version 8.0

## Chapter 4: Drawing the Cycloidal Curve

1. Start Allegro CL if you exited in Chapter 3. Open the gui-builder-tutorial project we left in Chapter 3. (If you have restarted Allegro CL, a dialog may appear asking if you want to open that project, along with any other projects recently worked on. If not, use File | Open Project and choose the file gui-builder-tutorial.lpr in your tutorial project directory, which is C:\Program Files\allegro-projects\gui-builder-tutorial\ or allegro-projects/gui-builder-tutorial/ on Linux if you used the defaults. The Recent menu may also provide a way to open the project.) You should now be where you stopped at the end of Chapter 3.

## Activating the Draw All Button

2. Open the Project Manager (View | Project Manager) if necessary. Display the curve-dialog form by selecting it from the list on the General tab and clicking on the View Selected Form button.
3. Inspect the draw-all button. Switch to Events tab of the Inspector by clicking on the Events button. Click on the Extended Editor key (the one with 3 dots) for the on-change event.

> You will be placed in the curve-dialog buffer of the Editor Workbook. You'll see the defclass you pasted in earlier and some skeleton code for the on-change handler named curve-dialog-draw-all-button-on-change. You are going to replace this code.

> There is a class supplied by cycloid.cl (one of the files you copied to the tutorial project directory) that will draw itself, called cycloidal-curve. You are setting up the draw-all button to act on that class.

4. In the curve-dialog.cl editor, modify the curve-dialog-draw-all-button-on-change function to match the following:

>     (defun curve-dialog-draw-all-button-on-change
>         (widget new-value old-value)
>      (declare
>        (ignore-if-unused widget new-value old-value))
>      (when new-value
>        (draw-all (parent widget)))
>      (not new-value))

5. Now add the draw-all method to the same buffer.

>     (defmethod draw-all ((dialog curve-dialog))
>       (let ((curve-list
>              (find-component :curve-list dialog))
>             (pane (frame-child (owner dialog))))
>         (dolist (curve (range curve-list))
>           (draw-curve pane curve))))

> > ### What’s going on?

> > frame-child fills the client area of the Doodler window, and is a child-window of doodler. It is where cycloidal curves get drawn. As the Doodler window gets resized and moved, the frame-child gets repositioned and redrawn to match.

> > doodler has a frame-child because it inherits that property from non-refreshing-window; its parent class. You’re going to see some of the consequences of inheriting from non-refreshing-window soon.

6. Click on the Save All button or choose File | Save All.

7. Recompile everything by clicking Tools | Full Compile.
8. Run the doodler by clicking Run | Run Project or the Run button.
9. Display the Curves dialog and click on the Draw All button. You should see the top portion of a cycloidal curve displayed in the lower-right corner of the Doodler. If not, increase the width and height of your Doodler window.
10. Try minimizing and restoring the running Doodler window. (Or, move the Curves window over the drawing and then away from it.) Notice that the curve disappears. Close the running project and proceed to the next step.

> The drawing has not refreshed itself because the type of window (a subclass of non-refreshing-window) has no backing-store. This will be changed during step 16.

> Stop running the Doodler before continuing with the next step.

## Using a bitmap-window

11. In the Project Manager, select curve-dialog and click on the View Selected Code button.
12. Search for the call to draw-curve in the draw-all method. Place the cursor in between the open parenthesis and the draw-curve. Click Search | Find in Files.
13. The Definitions dialog should be displayed with the symbol set as draw-curve. Make sure the Project radio button is selected in the Search area in the middle of the dialog (the other choices are Editors and Directories). Click on the Search button in the dialog.
14. Two references should be found, one in curve-dialog.cl (which we are already looking at) and one in cycloid.cl. (You added the supplied file cycloid.cl to the project in chapter 1.) Double click on cycloid.cl and the source for draw-curve is displayed in a new editor called cycloid.cl.
15. In the Project Manager dialog choose the doodler form and click on it View Selected Code, displaying the associated code.
16. In the doodler.cl editor, change the defclass to match the following:

> >     (defclass doodler (bitmap-window)
> >         ((doodler-curve-dialog
> >           :accessor doodler-curve-dialog
> >           :initform nil)))

> (The only change is the superclass of doodler is now bitmap-window, not non-refreshing-window.)

17. Evaluate the new defclass.
18. Make sure that there is no currently running Doodler (close the running Doodler project if you find one). Click on the Run Project button to run the Doodler again. Save All files when prompted.

19. In the running Doodler, try drawing the curve and scrolling the Doodler window, etc.

> > ### What’s going on?

> > The cycloidal curve will now be redrawn whether you minimize/maximize or scroll up/scroll down because you've changed the Doodler class to one (bitmap-window) with a backing store.

> > The original choice of a parent class for doodler was non-refreshing-window. That was a reasonable choice for a parent if you thought your display would never need refreshing. non-refreshing-windows can display bitmaps but won’t repaint them. Since this window now needs occasional refreshing, you've changed the parent class portion of defclass to accommodate that. CLOS permits you to change these relationships dynamically and on-the-fly.

> > Graphics are usually best displayed in a bitmap-window unless you are using them as a splash screen or in a modal dialog.

> Leave the Doodler project running and go to the next step.

## Activating the Scroll to Center Button

20. In the doodler buffer, change the definition of doodler-toolbar-click to match the following:

> >     (defun doodler-toolbar-click
> >         (widget new-value old-value)
> >        (declare
> >          (ignore-if-unused widget new-value old-value))
> >        ;; Do the action only when a button is
> >        ;; being pressed (not unpressed)
> >        (when new-value
> >           (let ((doodler (parent (parent widget))))
> >              (case (first new-value)
> >                (:curve
> >                  (show-curve-dialog doodler))
> >                (:scroll-to-center
> >                  (scroll-to-center doodler))
> >                (t nil))))
> >        (not new-value))

> This code adds a scroll-to-center method. The method will be the next thing you test in the running project. It is already included in your project, in the util.cl file.

21. Save the doodler buffer and evaluate the new doodler-toolbar-click function.
22. In the running Doodler, click on the Scroll to Center button and watch the graphics reposition. Leave the running project open and go to the next step.

> > ### What happened?

> > You didn’t need to stop the running project or compile to see the changes provided by the new scroll-to-center method. An incremental evaluation and saving the buffer was all you needed for Lisp to be able to use the new method.

## Activating the Erase button

23. 23. In the doodler buffer, change doodler-toolbar-click to match the following:

>     (defun doodler-toolbar-click
>         (widget new-value old-value)
>        (declare
>          (ignore-if-unused widget new-value old-value))
>        ;; Do the action only when a button is
>        ;; being pressed (not unpressed)
>        (when new-value
>           (let ((doodler (parent (parent widget))))
>             (case (first new-value)
>               (:erase
>                 (erase-window doodler))
>               (:curve
>                 (show-curve-dialog doodler))
>               (:scroll-to-center
>                 (scroll-to-center doodler))
>               (t nil))))
>        (not new-value))

24. Evaluate the new doodler-toolbar-click function and save the doodler buffer.
25. In the doodler buffer, add the new erase-window method.

> >     (defmethod erase-window ((window doodler))
> >       (let ((pane (frame-child window)))
> >         (erase-contents-box pane (page-box pane))))

26. Evaluate the erase-window method and save the doodler buffer.
27. In the running Doodler, try clicking on the Erase button. Watch the graphics disappear.
28. Click on the Save All button to save all of your changes.
29. Go on to Chapter 5. If you wish to, you can stop working on the tutorial now and return to it later. All the work you have done has been saved.

Copyright © 2001-2004 Franz Inc. All rights reserved.

Introduction | Chapter 1 | Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | CLOS Intro

Allegro CL version 8.0