A CLIM-based Editor for Building
Gadget-oriented Graphical User Interfaces.

Nichael Lynn Cramer
BBN Systems and Technologies

Paper Presented at the Association of Lisp Users Meeting and Workshop,Conference, Cambridge, 1995.

Mirage is a system for building gadget-oriented Graphical User Interfaces [GUIs] in CLIM. The core of the system is a WYSIWYG/drag-and-drop editor that allows rapid specification of "Panels" (CLIM panes containing gadgets).

A Panel communicates with and is controlled by an associated application program through an abstraction of the CLIM Client protocol. Specifications for the Panels and their component gadgets can be stored either as raw CLIM code or more abstractly as first class Template objects which can be manipulated by the application program or used to generate additional, non-standard views of the interface.

Care has been taken to ensure that the run- time footprint of the associated Mirage-generated code is as small as possible (often as small as the inclusion of a single additional file). Several custom gadget and utilities are described. Finally future work and proposed extensions and modifications to CLIM are discussed.

1. Introduction
As part of several Lisp and CLIM-based projects at BBN a need arose for a tool to build displays for use in simulation systems modeling the behavior and appearance of various hardware systems. As work on this tool progressed it became clear that it could easily be made to fill another, much more important, need: i.e. a system that would support the rapid generation of more general interfaces.

During this process several goals were identified.

1] An easy-to-use WYSIWYG editor for interface development. In particular the editor must be usable by a non-programmer (at least at the level of interface-design). Likewise such an editor would free the actual developer from the endless cycles of display-code "tweaking" often needed to achieve the desired interface.

(Such a feature is useful in dialogs and other common "system" windows, but it is especially important in programs emulating "real-world" systems where a high degree of display "fidelity" is essential.)

In response to this goal the Appearance Editor was developed (see Figs. 1, 2, and 3, and Appendix A, and B for discussion of the Appearance Editor).

2] The resulting display code should be separable from the surrounding application thereby allowing a well-defined protocol between these two. In this way the display portions of the program could be "plugged into" the associated application code and development of the appearance of the interface can proceed independently.

Mirage has adhered to an abstraction of the "Client" protocol used in CLIM (and other standard interface systems such as Motif). In Mirage the basic unit of functionality is the "Panel" i.e. a CLIM-pane containing one or more gadgets.

Specifically, the application is notified of changes in the state of the interface (e.g. pointer- gestures) through "callback" functions, which contain information identifying which gadgets were involved. In turn the application controls the details of the interface through function calls in the which the gadgets are addressed by a unique identifier.

It is the communication between this Panel and its associated Client that define the interaction between the application and the interface. In this way the Panel serves as a "meta- gadget", whose components are accessed by unique identifiers. The details of this protocol are discussed below. (See especially Table 1.)

3] To be useful across a range of applications, the system must quickly and easily incorporate new gadget-types. Furthermore the details of the top-level mode of interaction of the editor should be customizable to meet the needs of the application.

Aside from being used in a variety of applications, Mirage is also used in systems in which two different but complementary versions of Mirage were used side by side. First, Mirage was used as an embedded GUI-builder with which the user/analyst could build mockups of the panels of a real-world hardware systems. Second, Mirage was used by the developers of the simulation system as a tool for building dialogs and other windows used in the application itself. In each role the functionality expected of Mirage and its required set of component gadgets were significantly different. These features and the inclusion of different gadget-sets is discussed below.

Figure 1 (Full-sized version)

The Appearance Editor, editing a Panel. (The
features of the editor are described in the

Figure 2 (Full-sized version)

The Gadget Editor Used for editing the
parameters of a specific gadget type (in this
example a "radio-box" grid of (custom) toggle

4] The Panels should be usable in a broad variety of functions and contexts.

To achieve this goal, the internal description of the Panel --i.e. the "recipe" from which the Panel and its features are created-- is stored as a first-class object and as such can be directly manipulated by the surrounding application.

Furthermore, the final form of the Panel is independent of this Panel-Definition. As a result the details of the final appearance and function of the Panel is left up to the application. (See the discussion of "Views" below.)

5] While the Appearance Editor and other "development time" features of Mirage should be as powerful as possible, the run-time impact of Mirage should be as small as possible.

Mirage is implemented in layers that enable the editing features of the system to be disconnected from those features necessary at run- time.

Furthermore, a Panel can be saved as raw CLIM code which can be used directly by the application. In this case the run-time "footprint" of the supporting Mirage code can be as small as one additional file.

6] Care should be taken to allow forward compatibility with new Gadget and Panel features, and to make the storage of the descriptions of the Panels as platform- independent as possible.

The internal structure of the descriptions of the gadget and Panels is stored as plist-based pseudo classes that are highly amenable to future, dynamic modification.

Finally a sizable library of custom gadgets and utilities was accumulated during the development of Mirage

2. Definitions
Some definitions of terms used in this paper:

PANEL: A single CLIM pane containing some number of individual gadgets. This is the basic functional unit in a Mirage-based display.

MIRAGE-CLIENT: A user-defined object through which the Panel communicates with and is controlled by the associated application program.

PANEL-ID/GADGET-ID: Each Panel and Gadget is assigned an ID, by which the object can be uniquely identified and accessed by the MIRAGE-CLIENT or the application program.

CALLBACK: A Callback is a method which notifies the Client object that a gadget's state has changed, specifically as the result of an interaction by the user (for example pressing a push-button or dragging a slider).

WIDGET: The term "Widget" is used in Mirage to mean user- (or Mirage-) defined CLIM- gadgets that are intended to mimic the behavior of genuine Motif-like gadgets. These gadgets in CLIM, typically at a low-level: For example by using LEAF-PANE and other *-GADGET mixins; directly handling event; adhering to the standard callback protocols. (Some of the custom widgets and other utilities used in Mirage are described in Appendix C. )

PANEL-ACCESSOR: A Panel-Accessor is a method called on the Panel by the application program in order to examine or alter the state of its component gadgets. (The target gadget is specified by its Gadget-ID.)

PANEL-DEFINITION: An object containing the description of the contents of the Panel. This behaves primarily as a "recipe" from which the Panel is defined. Note that the Panel-Definition is independent of the form in which the Panel is realized (see "View").

GADGET-TEMPLATE: An object, used by the Panel-Definition, which contains the definition of a single gadget. VIEW: A Panel's "View" is the form in which the surrounding program chooses to realize the Panel, based on the description contained in the Panel-Definition. In the standard view the Panel is instantiated as a collection of gadgets on a pane, but the system is free to display the Panel in other ways (see the examples below).

APPEARANCE EDITOR: The portion of Mirage for interactively laying out the component gadgets and other attributes of the Panel.

APPEARANCE-OBJECT: Corresponding to each type of Gadget-Template is a class which is responsible for the editing of the features of that type of gadget inside the Appearance Editor. The object responsible for editing a gadget of a particular type is call an Appearance-Object.

DECORATION: A decoration is a simple graphic display drawn on a panel --rectangle, circles, lines, etc. In the Appearance Editor these Decorations are manipulated in a manner similar to the gadgets, but they otherwise have no active functionality of their own and are used only for display purposes.

3. The Appearance Editor
The Appearance Editor is used to specify and edit a Panel and its component gadgets.

In the main editor window (shown in Fig. 1, ) the features of the overall Panel (size, shape, color) are specified along with the layout of the component gadgets. Also available are a small set of commands that can be used to edit some of the high-level feature (color and text style) common to all of the component gadgets-types.

A complete description of the available commands is beyond the scope of this paper, but brief descriptions are included in Appendix A .

Fig. 2 shows the Gadget Editor, which is used to edit the parameters of a single gadget. (In this example, the gadget is a radio-box filled with a grid of custom toggle boxes).

The controls used in the Gadget Editor fall into two classes:

First, those control parameters that are common to most types of gadgets, such as foreground or background color, size, or outlining. Controls for this set of parameters occur in virtually all Gadget Editors. (When editing a gadget type for which a specific control happens not to be appropriate, the control is disabled or "grayed-out").

Second, controls for those features that are unique (or nearly so) to a specific gadget type are handled in a standardized way (such as the "Toggle Type" or Item List table in Fig. 2, discussed below).

In this way uniformity and familiarity can be maintained across the editors for a broad spectrum of gadget types. (A brief overview of the commands/controls available in the Gadget Editor are given in Appendix B.)

4. Panels
The primary functional unit in a display is the "Panel". A Panel consists of a single pane into which one or more gadgets have been drawn. The Panel is assigned a unique ID (by the application program) and a "Mirage-Client" object through which the panel reports state-changes (e.g. gestures) to the associated application program.

4.1 Callbacks in CLIM
In CLIM (as for example also in Motif) the primary mechanism for notifying the program of state changes is through callbacks on a "Client" object. Each gadget is assigned a Client object. (More than one gadget can be assigned to a single Client.) Likewise each gadget is assigned a Gadget-ID which uniquely identify the specific gadget to the client. When the user interacts with a gadget through a gesture a "callback" function of a type appropriate to the event is called on the Client with arguments describing the events. [1]

For example, suppose the user changes the value on a slider-gadget with the pointer. After the slider-gadget's value is changed internally the following method is called by CLIM


GADGET: The Slider-gadget object.
CLIENT: The user-defined Client object.
GADGET-ID: The user-specified ID of the slider-gadget.
NEW-VALUE: The new value for the slider-gadget.

In the other direction, the program controls those features of the gadgets under its control (settable gadget-values, specifying the item-lists of menus, etc.) through direct function calls on the gadget. For example, setting the value of a dial gadget would be done by:


4.2 Mirage-Client Protocol
In Mirage a similar callback mechanism is followed, but is handled at a more abstract level. It is the Panel itself that is assigned a Client (called the Mirage-Client) through which the program receives notification of user-interaction. In addition to the gadget being assigned a GADGET-ID, the Panel is assigned a PANEL-ID (thereby allowing the program or Mirage-Client to control more than one Panel).

Just as in the CLIM Client protocol, the application program is notified of changes in the gadget's state through a callback. However, in Mirage, the arguments to the callback contain information about both the affected gadget and the parent Panel.

For example, a user-initiated value-change would result in callback of the following form being signaled:


Likewise the program controls the features of the individual gadgets by means of method- calls on the Panel object. These calls --called PANEL-ACCESSORS-- identify the gadget to be affected by specifying the GADGET-ID.

For example the value of a gadget in a Panel would be set by:


In this way the application program is protected from the need to directly manipulate the embedded gadget.

A list of the callbacks sent from the Panel to the Mirage Client and the Panel-Accessor called on the Panel are listed below in Table 1 .

5. Data and Representation
Once the form of a Panel has been specified with the Appearance Editor, Mirage allows for the Panel to be stored and used by the application program in two quite different ways. First, a description of the Panel can be stored and used in the form of a Panel-Definition. Alternatively, the description of the Panel can be written to a file as CLIM code which can be directly incorporated into the application.

5.1 Templates and Panel-Definitions
A "Panel Definition" is an object containing a description of the contents of the Panel, such as the height and width of the panel, the default fore/background colors and a description of each gadget. In short, it is a "recipe" from which a Panel object can be built.

The description for an individual gadget is its Template. Analogous to the Panel Definition, the gadget's Template contains a description of the parameters and features of the gadget (position, foreground and background color, label, size, etc.). Internally a Template consists of a plist containing a keyword/value pairs corresponding to each of the gadget's attributes. Each attributes is associated with a pseudo-class "mixin" which is responsible for maintaining the value and any functionality associated with the definition of the parameter.

Finally the complete Template is built up from an appropriate set of "mixins" and a pseudo- class for each Template is defined (that is, one corresponding to each gadget type). Associated with the pseudo-class are methods which are responsible for behavior appropriate to the particular type of Template (e.g. knowledge how to instantiate a gadget of this type from the corresponding parameters; knowledge about how to write the Template to file; etc.)

The reasons behind the decision to use plists and a pseudo-class structure to store the gadget's parameters were two-fold: 1] to easily support backward compatibility if additional features or parameters are added to the gadget's specification. 2] To support a more generic way of storing of the template --for example in a file or database where it is often difficult to store the objects in the standard CLOS object form.

It is these Panel Definitions and Gadget Templates that the Appearance Editor manipulates directly. Textual representations of these objects can be saved to files and reloaded for further editing.

Note in particular that the Definition of a Panel is completely independent of any particular instantiation of a Panel. In a simulation application a panel-definition describing, say, a portion of a cockpit could be passed around and displayed in an arbitrary number of Panels. Since the Panel Definitions are first class objects, they can be directly manipulated as program objects and are completely under program control (for example they can be saved directly as objects in a Object Oriented database).

5.2 Panel Views
A particularly useful feature of the Panel Definition is its role as a "recipe" for the panel. Since it contains only the description for a Panel and its component gadgets it is up to the enclosing application to specify how and in what way those gadget are displayed or are in other ways made manifest. In this way the application program (or the Panel itself) can support multiple "Views" of the Panel and its gadgets.

The most obvious and straightforward View of a Panel is the "Gadget View" in which each of the components of the Panel are created as a fully operable gadget (typically by "drawing" the gadget with MAKE-PANE ).

Two other Views are used in the Appearance Editor itself. As described above, in the standard editing View [Fig. 1] each individual gadget is presented (used here in the CLIM sense) in the main editor window, not as the gadget itself but as an image of the gadget. A second View is shown in [Fig. 3] . In this "Name View" each gadget is drawn as a plain rectangular box with its gadget-id printed in the upper-left corner.

Two other, more sophisticated Views are shown in [Fig. 4] and [Fig. 5] . These figures come from a simulation application in which Mirage was used to build simulated workstation panels.

The surface of the workstation shown before the mannequin in [Fig. 5] was built using Mirage and is here drawn in a wireframe View, projected into the 3-D workspace. (An accompanying, more detailed view of the same panel is shown in [Fig. 6] .)

[Fig. 4] shows another window from the same simulator application in which the values of specific gadgets in a Mirage Panel are tied to slots in simulation objects. In the upper left corner of this window is a view of the Pane being added, drawn in a somewhat schematic,reduced view from which the individual gadget can be selected.

Figure 3 (Full-sized version)

The main field of the Appearance Editor in
Name View (cf Fig. 1 ).

Figure 4 (Full-sized version)

Here Mirage is used in a window in a simulator
application to associate the value of gadgets in
the Panel with the slots of simulator objects.
The upper left portion of the window shows a
reduced, schematic view of the Panel.

In a separate application Mirage was used in an application whose interfaces were used both "on site" and via the Web. In this case Mirage was used to build standard CLIM interfaces. Once those interfaces were built the Panel- Definitions and gadget Templates were used to generate GIF bitmaps and define hot-spots to be incorporated HTML displays. In this ways consistency maintained between the two types of interface.

6. CLIM-Code Save Format
In addition to the Panel Definition mechanism, Mirage also allows the user to save the form of the Panel directly as files of raw CLIM code. These files can then be loaded into the application program directly.

Code for creating a Panels is saved in one of two ways: First, the panel can be written as part of a self-contained pop-up frame. This frame contains a single pane (the Panel) which has as its "display function" a method to draw the gadgets on a pane. In this case the frame itself supports the Mirage callback and Panel-accessor methods described above. The frame itself is assigned a Mirage Client and behaves as the Panel.

Second, the description of the panel can be saved simply as the display function for the pane. This Display Function can be incorporate directly into the application program.

Note that files in this format --i.e. raw CLIM code-- can not be read back into the Appearance Editor. The standard technique is to load, edit and save the Panel Definition as a ".panel" file and then, once the panel is in the required form, saved out as code into a ".lisp" file. The ".panel" preserved in the event that future modifications are required.

7. The Structure of the Mirage System
Mirage has been carefully structured so that "development time" features can be removed and the resulting "run-time footprint" can be minimized. Specifically Mirage consists of three layers, plus an independent supporting layer of CLIM utilities.

Mirage Layer 1:
This layer consists of a single file which contains the definition for the classes and mixins that support the Mirage-Client calling and message passing protocols. (This file is written in the CLIM-USER package to ensure portability.) If an application uses Mirage-defined Panels stored by the CLIM code-dump procedure described above, this file is the only portion of the Mirage system that needs to be loaded at run time.

Mirage Layer 2:
The intermediate, or Full run-time layer of the Mirage system consists of those features which are required to support the full Panel-Definition protocol for use by a Mirage Panel. This layer also includes the full set of gadget Template files defined by the Mirage System.

This layer comprises only about 30% of the complete Mirage system and, as such, represents a substantial reduction of the run-time footprint when compared to the complete system.

Figure 5 (Full-sized version)

A window, from a simulation application, which
shows a non-standard View of a Panel. The panel
shown on the dashboard of the mannequin's
workstation is a wire-frame version of the panel
shown in Fig. 6 . Both displays are drawn from a
single Panel Definition.

Figure 6 (Full-sized version)

The complete display of the Panel shown on the
workstation in Fig. 5 .

Mirage Layer 3:
This layer consists of the features supporting the Appearance Editor. Also included in this layer are the files defining the various Appearance Objectsassociated with editing features for each gadget type.

Finally it should be noted that the topmost layer of the Appearance Editor (the definition of the application frame, the command tables, etc.) are themselves completely separable from the rest of the system. In this way application-specific versions of Mirage can be easily and quickly specified.

Taken together, these layer compose the complete Mirage system.

Layer 0 (CLIM Utilities):
Strictly speaking this is not a portion of Mirage. Rather this portion of the code consists of a number of "CLIM Extensions": specific custom widgets and other utilities. Some of the custom gadgets and other utilities have been described below. Most of these features have been found to be quite handy and as such can be useful outside the Mirage system.

(Some of the custom widgets and utilities used in Mirage are described in Appendix C.)

While the full Mirage system (i.e. the Appearance Editor) uses many of these extensions, they are not necessary to run the core system.

In particular if none of the Mirage-provided custom widgets are used and the application chooses not to use any of the other included utilities, this extension system need not be loaded. (Alternately, most of the gadgets and utilities can used independently and so can be loaded on an as-needed basis.)

8. Including New Gadget is Mirage
As discussed above a major design goal of Mirage was to allow the easy inclusion of new gadget. In the simplest case the inclusion of a new gadget involves the definition of a new gadget Template pseudo-class (with one associated method controlling the instantiation of a gadget of this type) and the defintion of an associated Appearance object class (with two new methods, one governing the “image” of the object in the Appearance Editor and a second method specifiying which specific editior tools are to be invoked when the gadget is edited). As most of the necessary editing tools are already in place and given that there are over two dozen gadgets included in the basic Mirage set --and so can serve as working examples-- this process is typically quite short.

In addition most of these editor methods have "sensible" defaults: for example a gadget for which the editor-image method has not been defined appears in the editor as a blank rectangle. Similarly, a gadget for which the editing-method has not been defined is editing using a default editing facility which supports the editing of its individual field in a text-like way (based on the mixins included in the Appearance Object definition).

9. Future Work and Proposed Extensions to CLIM
Other File Formats and Cross-Platform GUI Specification
The usefulness and value of Mirage would be greatly enhanced if it could support other types of file formats (e.g. standard CAD/CAM formats). In this case the issue would be one of writing translators between the Mirage file-format and the target format. Given the implementation- independent style of the panel and gadget specification and the textual format of the output in Mirage such translations should be fairly easy to perform.

(In point of fact, many of the features need to support this translation have been designed into Mirage. However the only "type-translator" currently defined is that supporting the standard Mirage file format.)

Similarly if Mirage, running as the Appearance Editor on a given platform, could be used to specify an interface which would then be loaded into or used by an application on another, possibly completely different type of platform.

This case is somewhat more complicated than the previous example because two additional pieces of code would have to be written: 1] a "gadget translator" on the target machine that converted the Panel and Gadget specifications into actual Panels and Gadgets on the host machine and 2] --depending on the level of veracity required in the editor-- an additional View would have to added to the Appearance Editor (and the associated Appearance Objects) which supported the appearance of the respective gadgets on the target system.

As above, much of the work to support such a translation is in place in Mirage, but no such examples have been explored.

Proposed Modifications to CLIM
Note that while much of this following discussion is motivated by the specific needs of the Mirage system, the issues raised have a broader scope than that. More generally, these are issues that seem to crop up repeated in a broad range of systems and programs in which CLIM has been used.

Inclusion of third-party Motif gadgets
CLIM comes with a specific set of embedded Motif gadgets. One of the most severe limitations for a system designer using CLIM is the inability to import other, specifically third- party COTS Motif gadgets. If this restriction were relaxed, this would greatly improve the flexibility, usefulness and end-user satisfaction with CLIM-based systems.

In Mirage an attempt has been made to work around this restriction by the inclusion of a large number of custom-built "widgets"; that is gadgets that are intended to mimic the behavior and appearance of genuine Motif gadgets but that are built using low-level CLIM facilities. Below we discuss some the issues that arose during this work and make suggestions concerning features of CLIM that we would like to changed or extended.

Support for Gadget and Event Protocols existing Gadgets
Among the Motif gadgets that are included in the CLIM system, the various low-level protocols are difficult to discern or, in some case, incomplete. Documentation for these protocols is very limited, making it difficult for developers to design their own gadgets-like widgets with the intent of adhering to these protocols. [2]

Many of the "standard" callbacks are missing
For example, double-click events seem to never be called (for example on list-panes) and only the basic value-change callback is made on the scrollbar gadget (i.e. no differentiation is made between gestures on the elevator, the up/down arrows, etc.)

Similarly support for selection and gadget "focus" seems to be limited (or at least poorly documented) and, in some cases, non-standard. For example directing keyboard-input to a particular gadget is often difficult. Likewise a selected push-button is triggered by hitting the space-bar but not by hitting return.

Probably the most restricting of these limitations --certainly from the point of view of Mirage, or any other imaginable GUI-builder based on CLIM-- has to do with the menubars. Specifically, menubars are not accessible as true gadgets. For example the only way to specify the items of the individual menus and their interactions is to specify commands, add them to a command-table and assign the command-table to be the command-table for the menubar. This is cumbersome and makes it difficult to create new menubars dynamically [3] . It would be useful if menubars were handled as standard gadgets: for example items could be specified as item-list and user-selection of menu-items could reported through a standard callback protocol

Additional specific examples:
In text-editors it is not possible for the program specify the selected text. (It is often desirable for a text gadget to "come up" with its default text selected, allowing the user to immediately start typing any required new text.)

In a given pane it is difficult to control which gadget is selected or "focused" on. Very little documentation exist on those features that do exist.

10. References
OSF/MOTIF Style Guide, Prentice Hall, 1993.
CLIM 2 Users Guide, Franz Inc., 1994.

Thanks to Jeff Morrill who started the earliest version of Mirage, to Bill Ferguson, Clint Hyde and Ken Anderson for input during the development of Mirage (and this paper) and to Phil Chu and Andrew Wilson for feedback as actual users. Finally special thanks to the Big Three: Colin Meldrun, Scott McKay and John Aspinall for speedy, insightful --and patient-- responses to a seemingly endless series of questions about the guts of CLIM.

Appendix A
Editing a Panel
Following is a brief overview of the commands available on the top-level Panel window in the Appearance Editor (see Fig. 1 ).

At the top is a menu-bar for the Appearance Editor. Under the "Panel" menu are various file- manipulation commands ("Save", "Save As", "Open", etc.) and a Parameters menu allowing specification for the entire panel (such as size or Panel-ID) and for user preferences for customizing editing ("Placement After Duplication", etc.) Also under the "Panel" menu are commands for performing a CLIM-code dump of the Panel specification.

Under the "Edit" menu are standard editing commands (such as "Duplicate", "Delete" and "Select All")

Under the "Alignment" menu are commands governing the Autogrid feature, the grouping of gadgets and the alignment of sets of gadgets. Under the "View" menu are a set of choices of Views of the Panel and gadgets. For example, aside from the "standard" view, the gadgets can also be shown in views that display only their names (see Fig. 3 ) or their initial values (see the discussion on Views in Mirage below).

Below the menubar is a banner containing the ID of the current Panel (this ID can be edited by clicking on this banner).

Under the ID banner is the palette of available gadgets and Decorations that can be added to the Panel. (At the right end of the second row of the palette is a "Custom" button which can be used by the application in which Mirage is embedded to bring up a menu of custom gadgets specific to the current application.)

Along the left edge of the Appearance Editor is a toolbar containing color palettes and text- style information for the Panel and selected Gadgets. At the top are two palettes for specifying the background and foreground colors for the Panel ("Default" in this case means "use the underlying system defaults as appropriate").

Below this are Text Style and Color palettes for the gadgets. If these values are changed while a gadget is selected the corresponding parameters of the selected gadget are changed appropriately. These values of these controls specify the corresponding parameters of subsequently created gadgets.

Finally, individual gadgets can be manipulated by the pointer in standard "drag-and- drop" fashion --selecting, moving, resizing, lassoing, etc.

Appendix B
Editing an Individual Gadget
A brief overview of the commands/controls available in the Gadget Editor (see Fig. 2 ).

At the top of the window is a banner containing the GADGET-ID. This ID can be edited by clicking on the banner.

Directly below this banner is a menubar containing commands for editing various features of the Gadget.

Below and slightly to the right of this menubar is a text-field for entering the Label of the gadget (this is disabled for the gadget type in Fig. 2 ).

Below the menubar, along the left edge of the window is a toolbar containing controls for other parameters of the gadget:

An "Outlining" toggle, governing whether the gadget is drawn with an outline box.

Height and Width rocker controls.

"AutoScale": When pressed this causes the gadget to be scaled to a "sensible" size (for example a Push Button would be resized to fit its label).

Background and Foreground color palettes.

Note that, as was mentioned previously, the commands/controls described above are common to all types of gadgets. The following controls specify parameters that are specific to this type of gadget.

The remainder of the left-edge toolbar pane is used by the system to specify those features that are specific to this type of gadget. Here the user can specify the type of option box used in the radio box (such "Check Box", "Bullet" or "Y or N".)

The portion of the window near the bottom is filled with a grid to specify the labels of the individual toggle buttons included in the radio- box. (This grid is used to specify the "item-list" in other menu-like gadgets, e.g. list-panes and menubars.)

Finally at the bottom of the window are two buttons used to exit the Gadget Editor after either saving or aborting all changes.

Appendix C
Custom Widgets and Utilities

Below are the descriptions of a number of custom widgets and other utilities used in (or defined by) the Mirage system.

Custom Toggle-Box Pane
The widgets are similar to the standard CLIM Toggle-Box, but also accept a Toggle-Kind argument that governs the appearance of the "toggle" field (i.e. check-box, bullet, etc.) Adding a new Toggle-Kind requires only that a single method written which dispatches on the Toggle-Kind argument and is responsible of drawing the toggle field.

Custom Radio-Box Pane
This is a radio-box pane which supports a grid of the custom Toggle-Box panes described above.

Custom Push-Button Pane
A widget, similar to the standard CLIM Push- Button that supports different modes of display (e.g. different shapes, multi-lined labels, etc.) As with the custom Toggle-Box pane, specifying a new type of button involves writing a single method that dispatches on the button's Kind.

Lamp Pane
A boolean/binary toggle display which displays its on/off state either with text or by drawing itself as filled/empty. As with the custom Toggle-Box pane, specifying a new type of lamp involves writing a single method that dispatches on the lamp's Kind.

Grid-Gadget Pane
This widget is used for drawing array-like grids or clusters. (An example of this widget appears near the bottom of Fig. 2 .)

Rocker-Gadget Panel
A small numeric-text field accompanied by an up- and a down-button. (An example of this gadget appears in the Width and Height fields in Fig. 2 .)

Custom File-Chooser
A menu-based file chooser similar to those used in standard GUI-based interface systems.

Mirage uses a system of color-caching in which inks are identified by keyword names. A standard Color-Cache is provided, but more than one Color-Cache can be used in a system and Color- Caches can be specified for individual frames. Among other advantages, such a scheme allows color specifications to be saved out in a standardized, transportable format and by allowing the system to re-use colors previously defined the system can minimize the problems caused by running on platforms with limited color-palette sizes.

Color-Key Chooser
In support of the Color-Cache described above, Mirage defines a Color-Key Chooser widget, which allows mouse-selection from a palette of colors. (Examples of this widget can be seen in Fig. 1 and Fig. 2 .)

Digit-Meter Pane
Thermo-Dial Pane
Semi-Circular-Dial Pane
Circular-Dial Pane
A number of standard displays, implemented as low-level widgets.

Custom Menu-Pane
A gadget that whose appearance and behavior is similar to the standard "list-pane" in CLIM, but which allows additional mouse actions, customizable appearance of items, double-clicks, etc.

Panel-Holder Pane
This is a pane type that accepts Mirage Panel-Definition objects as its value. These widgets can then be used to recursively embed Mirage Panels inside other Mirage Panels.

Table 1
Callbacks and controlling functions used by the Panel.

Callbacks sent from the Panel to the Mirage-Client include:

Report a user-initiated value-change on GADGET contained in PANEL .

Report a user-initiated activation event (e.g. a button press) on GADGET contained in PANEL .

Report a user-selection of an item on a pulldown menubar. (Note that the menubar gadget itself is not passed. For more on this, see the discussion above on menubars in CLIM and Mirage.)

Report that Mirage is preparing to draw the gadgets onto the panel.

Report that Mirage has finished drawing the gadgets onto the panel. Note that this method is called only after all the gadgets are available and drawn on the screen, thereby avoiding any possible platform specific race conditions.

The application program controls the Panel by calling the following Panel-Accessors on the Panel:

Set the value of the Gadget with GADGET-ID to NEW-VALUE . An error is called if the Gadget is not found and if IF-NOT-FOUND? is :ERROR .

Set the label of the Gadget with GADGET-ID to NEW-LABEL .

Used to call an arbitrary method on the Gadget with GADGET-ID . The call is of the form:

Returns the Gadget in the PANEL with GADGET-ID .

Set the Panel-Definition in the Panel to NEW-PANEL-DEFINITION . If DISPLAY? is non-nil, redisplay the PANEL .

Refresh the current Panel-Definition.

Tell the Panel-Handler to load a new Panel-Definition from the file PATHNAME . The Panel is redisplayed if DISPLAY? is non-nil. CALLING-FRAME is used if warning or other notification is required.

[1] CLIM supports a second callback mechanism. Under this mechanism the gadget is assigned a specific callback-function which is then called as appropriate. (The set of arguments to this callback function is slightly different from the arguments passed to the callback method discussed above --for details see the CLIM documentation.) We might also note in passing that in standard presentation-based CLIM the user/programmer is typically shielded from the details of the client-gadget interaction. In Mirage we will only be concerned with the client-object, method-calling mechanism for callbacks.

[2] As a specific suggestion perhaps a session of "Low-level gadget hacking in CLIM" would be a useful topic for a tutorial at a future LUV meeting.

[3] For example in Mirage if a menubar is specified in a Panel, it is necessary to create a new command table, and the associated set of commands each time an instance of the menubar is created.

Copyright © 1995 Nichael Lynn Cramer

Return to Nichael Cramer's HomePage-- Publications
work: ncramer@bbn.com
home: nichael@sover.net