|
Allegro CL version 8.0 |
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.
(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))
(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))))
Whats 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. Youre going to see some of the consequences of inheriting from non-refreshing-window soon.
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.
(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.)
Whats 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 wont 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.
(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.
What happened?
You didnt 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.
(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))
(defmethod erase-window ((window doodler)) (let ((pane (frame-child window))) (erase-contents-box pane (page-box pane))))
Copyright © 2001-2004 Franz Inc. All rights reserved.
|
Allegro CL version 8.0 |