Monday, July 10, 2006

input requested: adding a Lisp listener

I'm thinking about adding a Lisp listener to Graphic-Forms, and was
hoping to get some input. Do you think it is:

a) a "must have" feature if GF is to be taken seriously

b) a "nice-to-have" feature that you could live without
(note -- thinking of the availability of SLIME or
commercial IDEs as I write this)

c) more important to make sure apps built with GF have
the right building blocks for a listener, rather than
bundling one directly with the library proper

d) a complete waste of time


a lesson in CLOS-based interface fine-tuning

I recently made a fine-tuning pass through the argument lists for event-handling functions in Graphic-Forms and had an interesting experience.

First a bit of background. In Graphic-Forms, applications handle each event type by implementing the associated generic function. E.g., one implements EVENT-SELECT to handle a button press or menu item click. Prior to this past weekend, every event function included a time argument, which was a system-generated timestamp for the event. Other UI libraries have included that information (such as SWT's TypedEvent, which has a time instance variable) so I had figured it would be a good idea to include it in my library. Going ahead with this design choice without thinking harder was my first mistake: events in SWT are objects that are passed to interface methods, thus they can carry any amount of ancillary information with little added cost (from the standpoint of an application implementing those interface methods).

Instead of realizing the design error, I made the narrower observation that an event timestamp is needed in only a few special circumstances -- and in all of the test code I have written so far, I was writing a (declare (ignore time)) form everywhere. That gave me some empirical evidence to justify changing the API. I wanted to alleviate the need for application code to worry about that argument, yet still have access to it in the rare cases where it is needed.

So, my first inclination was to make the time argument &optional. oops! In CLOS, optional arguments in methods have to be congruent in their number just like required arguments, so event method implementors are not saved any work this way.

Then I considered making time a keyword argument, so method implementors could specify &allow-other-keys when they don't need the timestamp. But that adds more clutter than it saves; in other words, a symptom of this being the wrong reason to use keyword arguments.

Finally, the light bulb above my head flickered on, and I decided to remove the time argument completely. As a substitute, I decided to provide a separate access function. Problem solved.

I took away a couple conclusions from this. First, CLOS not only has powerful features, but there are easy-to-see signs that you're misusing them if you just pay attention. And more importantly, it's a mistake to copy a feature without thinking hard.

Monday, July 3, 2006

Graphic-Forms version 0.4.0 released

Release 0.4.0 of Graphic-Forms, a Common Lisp library for Windows GUI
programming, is now available. This is an alpha release, meaning that
the feature set and API have not yet stabilized.

Here is what's new in this release:

. CFFI snapshot 060606 or later is required in order to benefit from a
bugfix for a problem when running on LispWorks where foreign structure
contents could be corrupted; the most obvious symptom of this was a
Win32 error encountered when attempting to create a window.

. A new layout manager called `heap-layout' has been implemented. Its
purpose is to align all the children of a container in a single
Z-orderwise stack and allow the application to select which of the
children are top-most at any given time. This is useful when
implemnenting windows with panels containing related functionality,
where only one such panel should be visible at a time (e.g., property
sheets or wizard dialogs).

. This release provides access to the standard font dialog, and
integrates with the previously-defined font and font-data classes.

. Application-defined modal and modeless dialogs are now fully
supported, including keyboard navigation (tab traversal, default
button invocation via the ENTER key, and cancel button invocation via
the ESC key).

. In this release, the flow-layout manager gets a new style called
:normalize which instructs the manager to size children equally using
the maximum dimension of the children's preferred sizes opposite to
the dimension in which the layout is oriented.

. Applications may set minimum size and/or maximum size constraints
for top-level windows. Setting both constraints to the same size
implicitly disables resizing by the user.

. It is also possible to explicitly disable resizabilty, which not
only results in a fixed window size but also causes window decorations
to be updated appropriately (no maximize box and no resize handles in
the window frame).

. The button class has been expanded to support checkboxes, radio
buttons, toggle buttons, and tri-state button controls.

. There is now basic support for instantiating single-line and
multi-line edit controls. Edit controls participate in the focus gain
/ focus loss protocol; they also provide notification when contents
change via the event-modify generic function.

. Implemented event-focus-gain and event-focus-loss to allow applications
to response to changes in focus.

. It is now possible to customize the background color, foreground
color, and font of label controls. Infrastructure to support similar
customizations for other controls is in place.

. Functions capture-mouse and release-mouse are available to implement
mouse capturing behavior.

. Added a function to programmatically append separators to menus;
this was already possible via DEFMENU but not yet supported for
dynamic menu management.

. Rewrote timer event processing such that the library no longer uses
the TimerProc callback technique, but instead each call to the Win32
SetTimer function is made with the handle to a hidden utility window
managed by the library code.

. Changed the rectangle type to be a structure; it was a class before.

. Started work on infrastructure required to support a new layout
manager called `group-layout' which will appear in a subsequent
release. The infrastructure developed this time includes definition of
a text-baseline method that widgets implement to help layout managers
align text appropriately.

. Also started work on infrastructure needed to enable WinXP-themed

. Continued work on the UnBlocked demo game.

The above list is in addition to documentation enhancements and
bug fixes. The README.txt file in the release zip file also has
additional important information about this release.

Download the release zip file here:

The project website is: