Chapter 5: Create the Coefficients Dialog
- Start Allegro CL if you exited in Chapter 4. Open the gui-builder-tutorial
project we left in Chapter 4. (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
4.
- In this chapter, you will create a Coefficients dialog similar to this one:

- Click on the New Form button on the Standard toolbar (or choose File
| New Form). Select dialog from the list and click OK.
This defines the new form as an instance of dialog.
- Reshape the new form to be roughly the same size as the illustration in Step 2.
- Inspect the new form (double-clicking on it will expose the Inspector window with the
new form inspected).
- In the inspector, change (where necessary) the minimize-button to nil, maximize-button
to nil, name to :coefficient-dialog, resizable to nil, child-p
to nil, and title to Coefficients.
- In the Project Manager dialog, select the coefficient-dialog and click on the View
Selected Code button.
- In the editor buffer, enter the following defclass.
(defclass coefficient-dialog (dialog)
())
- Evaluate the coefficient-dialog defclass. (Once again, we have create a
new subclass of dialog that we will specialize for our application without affecting other
instances of the class dialog.)
- Save the buffer to coeffiicient-dialog.cl to your tutorial directory using the Save
button or File | Save.
- In the coefficient-dialog inspector, change class to
coefficient-dialog.
- On the Coefficients form, sketch in a static-text control. The icon for
static-text is a capital A.
- Inspect the new static-text and change name to :a-text and value
to ~A:.
- Reshape the static-text sizing handles so that they closely surround the text.
Reposition the control so that it sits in the upper left part of the form. See the
illustration in Step 2. (This control provides a label for the editable text widget
displaying 200 in the picture).
- Now sketch in an editable-text control on the right-hand side of the static-text. The
icon for editable-text looks like ab|.
- Inspect the new editable-text control and change the name to
:a-coefficient-text.
- Reshape and reposition a-coefficient-text next to the static-text control (see the
illustration after step 2).
Want more control over repositioning components vertically?
You need to turn off the grid and component alignment options.
- Select Tools | Options. The Options dialog will
appear.
- Choose the Form tab.
- Clear the check boxes on Snap to Grid and Snap to Components.
- Click on Apply to apply the changes.
- Leave the Options dialog open while you make the adjustments you want
to the controls on the Coefficients dialog. Drag everything to the location that satisfies
you.
- Re-select Snap to Grid and Snap to Components before
clicking OK to close the Options dialog and moving on to
the next step. You'll need them again later.
If you only clear Snap to Grid you will still have trouble getting an
alignment of vertical centers because these components are so similarly sized that they
"stick" to the nearby edges of neighboring components. Clear both the Snap
to Grid and Snap to Components options to make this exercise
easier.
These two options comprise a feature called sticky alignment.
- Now sketch in an up-down-control next to the a-coefficient-text on the
right-hand side.

- Drag the new up-down-control so that it overlaps the right edge of the editable-text.
If done properly, the up-down-control will attach itself to the editable-text
control. You will be able to tell because the up-down-control will
reposition and resize itself to match the editable-text. It will also
accompany the editable-text if you drag it around on the form.
- Inspect the new up-down-control. Verify that its buddy-widget
is :a-coefficient-text. Change its name to :a-coefficient-control, range
to (1 1000), and value to 1.
The buddy-widget property helps unify these two controls and keep
their functions connected.
Note that it is a read-only property of the up-down-control. You must
change it graphically (using the mouse and the IDE); the inspector wouldnt know how
to reposition the controls if you changed it textually (by typing into the value location
in the Inspector).
- Click on the Save All button on the standard toolbar or choose File
| Save All.
- Set focus to the Coefficients form and click Run | Run Form.
Run Form versus Run Project
Run | Run Project (or the Run Project button) invokes
the project init function. This creates and displays the window associated with the main
(Doodler) form only. Other windows must be created and displayed programmatically. Run
| Run Project will not display the window we are working on since it is not the
main form.
Run | Run Form works here because it creates and displays the window
associated with the selected form whether or not it is the main form.
Another difference, not specifically relevant in this case, is that projects are run in
a new thread, different from the IDE thread (IDE GUI) while forms are run in the IDE
thread. (Display the Process Browser with View | Processes
and update it while running a project to see this.)
- When you are satisfied that the up-down-control and the editable-text
are working (clicking on the up-down-control arrows should change the
value in the editable-text) on the Coefficients dialog, click the Stop
button (or choose Run | Stop).
- Drag-select the static-text control for the A coefficient, the
editable-text, and the up-down-control on the coefficient-dialog form. All three controls
should be selected now. To drag-select, place the cursor just above and to the left of the
static-text control, depress the left mouse button and drag the cursor to
just below and to the right of the up-down-control. Release the mouse
button. All controls should be selected, as indicated by white squares in their corners, as
shown in this illustration:

Selecting More Than One Object
When multiple controls are group-selected, the selection handles for each control will
appear hollow and light colored rather than solid and dark colored. This indicates that
the controls can be moved as a group but not resized.
- Use drag-selection (click the mouse key, hold it down, and drag it across) to select a
group of widgets easily. This technique works best when not in a tight space.
- Use shift-selection (hold down the SHIFT key, then click on each object you want to
select) to select a group of items that prove difficult to drag-select.
- Copy the selected controls using the Edit | Copy command.
- Paste the controls using the Edit | Paste command.
The pasted controls appear to the right and below the controls being copied.
- Leave the pasted controls selected. Move them as a group into alignment with the
original group of controls. Refer to the illustration in Step 2 for the position of the B
coefficient control. Horizontal alignment marks will begin appearing to guide you when you
get close.
Turn sticky alignment back on (see step 17) if you don't have alignment guides and want
to see them. Although you have a group of controls already selected; it will still come on
right away and assist you during this step.
- Inspect the pasted static-text control. Change its name
to :b-text and its value to "~B:".
- Inspect the newly pasted editable-text control. Change the name
to :b-coefficient-text.
- Inspect the newly pasted up-down-control. Change the name
to :b-coefficient-control. Verify that the buddy-widget is
:b-coefficient-text.
- Click on the Save All button to save your changes.
- Set focus on the Coefficients form and choose the Run | Run Form
command.
- Verify that the up-down-controls are working for both the A and B
coefficients.
- Stop the running Coefficients dialog using the Stop button or choosing Run
| Stop.
- Repeat the previous pasting and editing process to create the controls for the C
coefficient. See the illustration in Step 2 for reference.
- Sketch a group-box enclosing all the controls on the Coefficients form.

- Inspect the new group-box and change its name to
:coefficient-box and clear its title.
- Click on the Save All button to save your changes.
- Set focus to the Coefficients form and click Run | Run Form.
- Verify that all the up-down-controls are working, then stop the running dialog.
If the controls aren't changing numbers in the editable-text boxes, confirm that each
has its partnering editable-text control name showing as the buddy-widget
value in the Inspect window.
Add Button Controls to the Coefficients Dialog
- In the Coefficients form, sketch a default-button in the lower-left
corner.
- Inspect the new button and change its name to :ok-button and title
to ~OK.
- Sketch in a cancel-button on the right side of the OK button. Align the
top edge with the OK button.
- Inspect the cancel-button and change its name to
:cancel-button and its title to ~Cancel (its title starts as Cancel,
without the leading tilde).
- Sketch a button on the right side of the Cancel Button. Align the top
edge with the other two buttons.
- Inspect the new button and change its name to
:test-button and its title to ~Test.
- Click on the Save All button to save your changes.
Activate the Test Button
The Test button allows users to test-draw a curve and make adjustments without leaving
the Coefficients dialog.
- In the inspector of the test-button, click on the Events tab.
- In the test-button inspector, click on the on-change event and then,
click on the Extended Editor button (the one with the three dots).
- In the coefficient-dialog buffer (which should be visible), edit the skeleton code for
the on-change function coefficients-dialog-test-button-on-change to match
the following:
(defun coefficient-dialog-test-button-on-change
(widget new-value old-value)
(declare
(ignore-if-unused widget new-value old-value))
(when new-value
(test-curve (parent widget)))
(not new-value))
- Evaluate the coefficient-dialog-test-button-on-change function.
- Add the test-curve method to the same buffer.
(defmethod test-curve
((dialog coefficient-dialog))
(let* ((curve
(make-instance 'cycloidal-curve
:a-coefficient
(value
(find-component
:a-coefficient-control
dialog))
:b-coefficient
(value
(find-component
:b-coefficient-control
dialog))
:c-coefficient
(value
(find-component
:c-coefficient-control
dialog))))
(curve-dialog (owner dialog))
(doodler (owner curve-dialog)))
(draw-curve (frame-child doodler) curve)))
- Evaluate the test-curve method.
- Save the coefficient-dialog buffer.
- In the coefficient-dialog buffer, click inside the cycloidal-curve
text. Then, click Tools | Browse Class
- You should see the class browser dialog displayed with the information about the class cycloidal-curve.
- In the Class Browser dialog, click on the Direct Slots icon in the toolbar (the one with three horizonatl lines) and display
the information.

We are following the convention of naming the accessor the same as the slot; slots
shown here have the same names as their accessor functions.
Using the Class Browser
Use the Class Browser to quickly look up slots and methods of a class.
Click on the Methods tab now and youll see a list of the methods
(including the accessors) for cycloidal-curve.
Displaying the Coefficients Dialog from the Curves Dialog
- In the General tab of the Project Manager dialog,
select curve-dialog and click on the View Selected Code button.
- In the curve-dialog buffer, modify the curve-dialog class to add a slot
to store the coefficient-dialog. It should match the following:
(defclass curve-dialog (dialog)
((curve-coefficient-dialog
:initform nil
:accessor curve-coefficient-dialog)))
- Now add the following close :before method to the same buffer.
(defmethod close :before ((dialog curve-dialog) &key)
(let ((coefficient-dialog
(curve-coefficient-dialog dialog)))
(when (and (windowp coefficient-dialog)
coefficient-dialog)
(close coefficient-dialog))
(setf (curve-coefficient-dialog dialog) nil)))
Since the curve-dialog creates the coefficient-dialog, it must also close it. The
dialog must be explicitly closed since it is a pop-up window.
- Click on the Save All button on the standard toolbar to save your
changes.
- Click Tools | Compile Project to compile your changes.
- In the Project Manager dialog, select doodler and click on the View
Selected Code button.
- In the doodler buffer, add the user-close method.
(defmethod user-close ((window doodler))
(let ((modal-dialog (modal-window)))
(if* modal-dialog then
(beep window)
(pop-up-message-dialog window "Doodler"
(format nil "~
Close the ~a modal dialog before closing ~
the Doodler."
(title modal-dialog))
warning-icon
"~OK")
else
(call-next-method))))
Since the Coefficients dialog is displayed modally, you cannot close the Doodler when
the coefficient-dialog is displayed. Therefore, you must customize the user-close
method for doodlers to prevent your users from closing the Doodler while the Coefficients
dialog is displayed.
Activating the Add Button
- In the Project Manager, select curve-dialog and click on the View Selected Form
button.
- In the curve-dialog form, inspect the Add button.
- In the Add button inspector on the Events tab, select the on-change
event. Click on the Extended Editor button (the one with the three dots).
- In the curve-dialog buffer, change the on-change function (curve-dialog-add-button-on-change)
to match the following:
(defun curve-dialog-add-button-on-change
(widget new-value old-value)
(declare
(ignore-if-unused widget new-value old-value))
(when new-value
(add-curve (parent widget)))
(not new-value))
- Now add the following add-curve, get-coefficient-dialog,
and show-coefficient-dialog methods to the same buffer.
(defmethod add-curve ((dialog curve-dialog))
(let* ((curve-list
(find-component :curve-list dialog))
(default-curve (value curve-list))
(curve (show-coefficient-dialog dialog
(if default-curve
(copy-object default-curve)
;; else
(make-instance
'cycloidal-curve)))))
(when curve
(setf (range curve-list)
(append (range curve-list)
(list curve))))))
(defmethod get-coefficient-dialog
((dialog curve-dialog))
(let ((coefficient-dialog
(curve-coefficient-dialog dialog)))
(when (or (not coefficient-dialog)
(not (windowp coefficient-dialog)))
(setq coefficient-dialog
(make-coefficient-dialog :owner dialog))
(setf (curve-coefficient-dialog dialog)
coefficient-dialog))
coefficient-dialog))
(defmethod show-coefficient-dialog
((dialog curve-dialog)
&optional (curve
(make-instance 'cycloidal-curve)))
(let* ((coefficient-dialog
(get-coefficient-dialog dialog))
(a-widget
(find-component :a-coefficient-control
coefficient-dialog))
(b-widget
(find-component :b-coefficient-control
coefficient-dialog))
(c-widget
(find-component :c-coefficient-control
coefficient-dialog)))
(move-window coefficient-dialog
(window-to-screen-units
dialog (make-position 10 10)))
;; initialize the value of the widgets
(setf (value a-widget) (a-coefficient curve))
(setf (value b-widget) (b-coefficient curve))
(setf (value c-widget) (c-coefficient curve))
;; display the dialog as modal
(when (pop-up-modal-dialog coefficient-dialog
:stream (owner dialog))
;; if the user clicks on OK, change
;; the new curve to
;; reflect the values shown in the dialog
(setf (a-coefficient curve) (value a-widget))
(setf (b-coefficient curve) (value b-widget))
(setf (c-coefficient curve) (value c-widget))
curve)))
add-curve initializes a new curve to the same values as the selected
curve.
show-coefficient-dialog uses the pop-up-modal-dialog
function to display the Coefficients dialog modally.
- In the curve-dialog buffer, select everything (Edit | Select All) and
evaluate the selection (Tools | Incremental Evaluation).
- Click on the Save All button to save everything.
- Click the Run Project button to run the Doodler. Display the Curves
dialog by clicking on the blue Curve button displaying a cycloid
graph. In the Curves dialog, click on the Add button. Make sure that the
Coefficients dialog is modal with respect all the other Doodler windows (meaning you
cannot select another Doodler window until the Coefficients dialog is closed).
- When you are satisfied, click the Stop button or Run | Stop
to stop running.
Activating the Edit Button
- In the Project Manager, select the curve-dialog and click on the View
Selected Form button.
- Inspect the Edit button on the curve-dialog form. Switch to the Events
tab if necessary.
- Select the on-change property. Click on the Editor button (the one with
three dots). There is a default function -- return-t-from-pop-up-dialog
-- already provided but it is not suitable for our purposes.)
- In the curve-dialog buffer, edit the on-change function (curve-dialog-edit-button-on-change)
to match the following.
(defun curve-dialog-edit-button-on-change
(widget new-value old-value)
(declare
(ignore-if-unused widget new-value old-value))
(when new-value
(edit-curve (parent widget)))
(not new-value))
- In the curve-dialog buffer, add the edit-curve method:
(defmethod edit-curve ((dialog curve-dialog))
(let* ((curve-list (find-component :curve-list dialog))
(curve (value curve-list))
(range (range curve-list)))
(when curve
(when (show-coefficient-dialog dialog curve)
;; reset the range to force
;; the scrolling list
;; to redisplay its curve information
(setf (range curve-list) nil)
(setf (range curve-list) range)))))
- Click on the Save All button on the standard toolbar to save your
changes.
- Run the Doodler using the Run button or the Run | Run Project
command.
- In the Doodler, click on the Curve button. In the Curves dialog, click
on the Edit button. Notice that nothing happens.
Select the curve in the list box and click Edit again. This time the coefficients
dialog will appear since you have selected a curve. When satisfied, click the Stop
button to stop running the Doodler.
- In the curve-dialog buffer, enter the select-curve-warning method.
(defmethod select-curve-warning
((dialog curve-dialog))
(pop-up-message-dialog dialog "Doodler"
"Select a curve first"
warning-icon "~OK"))
- In the curve-dialog buffer, modify the edit-curve method to match the
following.
(defmethod edit-curve ((dialog curve-dialog))
(let* ((curve-list
(find-component :curve-list dialog))
(curve (value curve-list))
(range (range curve-list)))
(if curve
(when (show-coefficient-dialog dialog curve)
;; reset the range to force the
;; scrolling list to redisplay
;; its curve information
(setf (range curve-list) nil)
(setf (range curve-list) range))
;; else
(select-curve-warning dialog))))
- Select the whole curve-dialog buffer (Edit | Select All) and evaluate
it (Tools | Incremental Evaluation). Then click on the Save All
button to save your changes.
- Run the doodler using the Run button or Run | Run Project.
In the Doodler window, click on the Curve button and then click on the Edit
button. Youll see a warning saying that you need to select a curve first. Click OK
to accept the warning. Select a curve and try editing a curve.
- Your application will look something like this after adding, editing, and drawing the
curves.

When satisfied, click Run | Stop command to stop running the doodler.
Making the Delete Button Work
- In the Project Manager dialog, select curve-dialog and click on the View
Selected Form button.
- Inspect the Delete button and select the Events tab.
- In the delete-button inspector, select the on-change
event and click on the Extended Editor button (the one with three dots).
The curve-dialog buffer will appear with some skeleton code in it.
- In the curve-dialog buffer, edit the on-change function (curve-dialog-delete-button-on-change)
to match the following.
(defun curve-dialog-delete-button-on-change
(widget new-value old-value)
(declare
(ignore-if-unused widget new-value old-value))
(when new-value
(delete-curve (parent widget)))
(not new-value))
- Now add the delete-curve method to the same buffer. Notice that the draw-all
and select-curve-warning functions are reused here.
(defmethod delete-curve ((dialog curve-dialog))
(let* ((curve-list
(find-component :curve-list dialog))
(curve (value curve-list)))
(if* curve then
(setf (range curve-list)
(remove curve (range curve-list)))
(setf (value curve-list) nil)
(erase-window (owner dialog))
(draw-all dialog)
else
(select-curve-warning dialog))))
- Click on the Save All button on the Standard toolbar to save your
changes.
- Click the Run button to run the Doodler. Add a few curves to the dialog
using the Add button. Try using the Delete button to see
how it works.
- When you are satisfied, click the Stop button to stop running the
Doodler.
Handling a Double-Click
- In the Project Manager dialog, select the curve-dialog and click on the
View Selected Form button.
- In the Curves form, inspect the curve-list, which is a single-item-list control.
- In the curve-list inspector, select the Events tab. Select the on-double-click
event and click on the Extended Editor button (the one with the three
dots).
- 98. In the curve-dialog buffer, change the on-double-click
function (curve-dialog-curve-list-on-double-click) to match the
following:
(defun curve-dialog-curve-list-on-double-click
(dialog widget)
(declare (ignore-if-unused dialog widget))
(curve-list-double-click dialog widget)
t) ;; Return t to accept the new value
- Now add the curve-list-double-click method to the same buffer:
(defmethod curve-list-double-click
((dialog curve-dialog) widget)
(declare (ignore widget))
(edit-curve dialog))
100. Click on the Save All button to save your
changes.
101. Run the Doodler using the Run button. Try
double-clicking on a curve to edit it.
102. When you are satisfied, click the Stop button to
stop running the Doodler.
103. Go on to Chapter 6. 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.