Most programs using traditional GUI libraries are structured
somewhat like this:
- Instances of different widgets with various options are created ;
- a geometry manager is used to lay them out ;
- events out bound to widgets ;
- an event loop is started.
But that structure is an unfortunate side-effect of the low level
of those traditional GUI libraries. By having to handle events, you no
longer have access to execution contexts such as the stack, and you
have to manage all kinds of contexts yourself, or else you end up with
applications that have a very rudimentary interaction policy.
CLIM turns the structure of traditional GUI libraries inside-out, and
makes it both possible and normal to use interaction methods that are
common in non-GUI based programs, i.e. where the program logic has the
initiative, and you use reads and writes to accomplish the
interaction.
CLIM has a "command loop" that is at a higher level than an event loop
and that:
- acquires a command. You might satisfy this demand by clicking on
a menu item, by typing the name of a command, by hitting some kind
of keystroke, by pressing a button, or by pressing some visible
object with a command associated with it ;
- acquires the arguments required by that command. These arguments
are often associated with a "presentation type", and visible
objects of the right presentation type can be clicked on to
satisfy this demand. You can also type a textual representation
of the argument, using completion, or you can use a context menu ;
- calls the command on its arguments, usually resulting in some
significant modification of the "model", i.e. the data structure
representing your application logic ;
- calls a redisplay routine (which might use incremental redisplay)
to update your views of the model.
Writing a CLIM application therefore consists of:
- writing CLIM commands that modify the model independently of how
those commands are invoked, and which may take application objects
as arguments ;
- writing display routines that turns the model (and possibly some
"view" object) into a collection of visible representations
(having presentation types) of application objects ;
- writing completion routines that allows you to type in application
objects (of a certain presentation type) using completions ;
- independently deciding how commands are to be invoked (menus,
buttons, presentations, textual commands, etc).
By using CLIM as a mediator of command invocation and argument
acquisition, you can obtain some very modular code indeed.
But there is more. CLIM is a well-documented and very rich collection
of internal protocols, and programmers can add, modify, or replace
components of CLIM by respecting those protocols, in particular the
programmer can:
- use CLOS :before, :after, and :around
methods on documented CLIM generic functions to modify the
behavior of standard CLIM in interesting ways ;
- add new types of panes and gadgets ;
- modify the way presentation types are displayed, or the way they
are sensitive to mouse gestures ;
- add specialized output records for particular application needs ;
- replace the standard command loop ;
- etc, etc, etc.