Lessons learned from SUIT, the simple user interface toolkit.
In recent years, the computer science community has realized the advantages of GUIs (Graphical User Interfaces). Because high-quality GUIs are difficult to build, support tools such as UIMSs, UI Toolkits, and Interface Builders have been developed. Although these tools are powerful, they typically make two assumptions: first, that the programmer has some familiarity with the GUI model, and second, that he is willing to invest several weeks becoming proficient with the tool. These tools typically operate only on specific platforms, such as DOS, the Macintosh, or UNIX/X-windows. The existing tools are beyond the reach of most undergraduate computer science majors, or professional programmers who wish to quickly build GUIs without investing the time to become specialists in  GUI design. For this class of users, we developed SUIT, the Simple User Iinterface Toolkit. SUIT is an attempt to distill the fundamental components of an interface builder and GUI toolkit, and to explain those concepts with the tool itself, all in a short period of time. We have measured that college juniors with no previous GUI programming experience can use SUIT productively after less than three hours. SUIT is a C subroutine library which provides an external control UIMS, an interactive layout editor, and a set of standard widgets, such as sliders, buttons, and check boxes. SUIT-based applications run transparently across the Macintosh, DOS, and UNIX/X platforms. SUIT has been exported  to hundreds of external sites on the internet. This paper describes SUIT's architecture, the design decisions we made during its development, and the lessons we learned from extensive observations of over 120 users.
Introduction
This is a practice and experience paper which describes our experience with SUIT, the Simple User
Interface Toolkit. In recent years, support tools for building GUIs, called UIMSs, UI toolkits, and interface
builders, have gained popularity, but they have been heavily skewed towards programmers who are willing
to invest a large amount of time in mastering them. While these tools are appropriate for many
professionals in the field, their extended learning curves make them prohibitive for undergraduate students
or other programmers who wish to build GUIs, but who do not wish to invest weeks in mastering the tool
base. GUI building tools can be very deceptive: providing an interactive builder that provides mouse-based
interface editing can obscure the fact that if the programmer is not familiar with the callback model for
GUIs, attempting to attach functionality to the screen components will be extremely confusing.
In academia, we should be exposing our students to good GUI-building tools, not as a speciality item
in a graduate level graphics course, but in mainstream courses, such as undergraduate software engineering
or "projects" courses. Unfortunately, these courses cannot sacrifice several weeks in order to teach the
concepts hidden inside the GUI model, nor can they afford the luxury of allowing the students several
weeks to master complicated GUI tools. Outside of academia, a similar situation exists, where many
professional programmers who do not specialize in GUI design often have need to quickly build "graphical
front ends" for various application software, but can never take the time to master complex GUI
development tools.
In SUIT, the Simple User Interface Toolkit, we have attempted to distill the essential components of
good GUI building tools and provided those essentials in a form that can be used by programmers who
come prepared with nothing but competency in the C programming language. Our goal is not to provide
new capabilities in the GUI-building realm, but to combine existing techniques in a clean design that can
be learned quickly. In this respect, we hope SUIT can provide the same contribution to the interface builder
community that Pascal[Wirth] did for the programming language community. We certainly have heard
many (older) GUI programmers comment that the current state of the art in GUI tools is similar to
programming languages in the 1960s and 1970s. The Motif Widget Set, for example, exhibits many of the
same "interference of features" problems as did PL/I.
SUIT succeeds not by providing a new "silver bullet" idea, but by making dozens of independent
design decisions which, when taken in combination, produce a system which is easy for novice GUI
programmers to learn. The design methodology was relatively straight-forward: be willing to rewrite the
implementation many times, perform stringent user testing of every phase in an iterative fashion, and be
willing to sacrifice "well known" design principles for ease of use in the face of evidence from user
observation. We have performed direct observations of over one hundred twenty separate users within a
two year time span during SUIT's development. The end result is a ten page tutorial which requires new
users to spend between 1.5 and 3 hours learning to use SUIT, at which time they can begin using SUIT for
programs of their own choice. This is a vast improvement over the four to six week learning curve we
observed for our students with systems like Xtk [McCormack], the Andrew Tool Kit [Palay], Interviews
[Calder], and the Motif Widget Set. SUIT also provides a one hundred-sixty page reference manual, much
of which is also available via on-line help.
Design Approach
Throughout SUIT's development, we applied the following principles:
. exploit knowledge and skills the user already has
. make the easy things easy and the hard things possible
. perform end-user testing early and often
Current UI toolkits and UIMSs tend to violate the first point by forcing their users to learn a new
programming language. For example, the NeXT Interface Builder [Mahoney] requires learning objective-
C, and Interviews requires learning C++. While these languages are required to support the model each
system provides, users who are focused on their task at hand often fail to use advanced tools because the
learning threshold of these languages is too high.
Our design strategy was to leverage off the only existing skill we could assume our users would have:
the ability to program in C. Therefore, anything that could not be specified with SUIT's interactive tools
would have to be done by having the user write C code. Also, we acknowledged early on that any new
concepts we needed our users to understand, such as inheritance of information in a class-based object-oriented
model, SUIT would have to teach to them via its interactive tools. As our final design goal, we
looked to the production of a ten page written tutorial which would walk the new user through the system.
We explicitly chose a written, rather than on-screen tutorial format for two reasons: First, our most limited
resource was screen real-estate, and putting the tutorial on paper reduced demand for screen space. The
second reason was that we wanted to avoid confusion between "tutorial areas" and "real areas" on the
screen. By using a paper-based tutorial, we could use the SUIT screen layouts without problem. While we
do not argue that on-screen tutorials are appropriate in many applications, we felt that for SUIT's target
audience, a paper-based tutorial would be superior. The last design constraint was in the type of users we
targeted during our testing of the software. Working with the very best students, or even average students
who were interested in GUIs, would have been a mistake. We wanted to target users for whom creating
GUIs was a means to their end, not an end in itself. Therefore, we used a captive audience: students in
undergraduate software engineering courses who had been assigned projects that required GUIs, but who
would be graded on the overall result of their effort, of which the GUI was a small fraction.
By constantly observing new users, we were able to maintain perspective on the difficulties new users
face when trying to understand the SUIT model. This sort of user testing is well understood in some
corporate cultures, most notably at Apple Computer. This technique was also used with great success in the
development of Trillium [Blomberg].
Architecture
This section gives a high-level description of SUIT's internal architecture and describes SUIT's basic
data model. We begin by discussing platform portability, then cover several popular UI builder models,
SUIT's definition of an object, SUIT's interactive tool set, and how SUIT composes and links objects
together.
A user interface toolkit requires three basic forms of support: an implementation language, operating
system support, and a graphics package. Our implementation language had to be either C or Pascal, since
they are the only languages most widely known by undergraduates. Although Pascal is more widely used
and is simpler than C, implementing SUIT in Pascal was not technologically feasible. Pascal exists on all
three platforms, but it varies widely [Welsh]. Also, standard Pascal is not powerful enough to support the
external control model: it lacks the ability to store function addresses as variables. Therefore, we chose
ANSI-C. Our operating system dependency was very small: we only needed to be able to read and write an
ASCII text file, and the standard C I/O libraries always support this.
For graphics, we needed a common, low-level graphics package which supported operations such as
DrawLine and DrawFilledCircle on each of the platforms. We were surprised to find few graphics
packages implemented for all three platforms. Most researchers we contacted said that they had always
ported between platforms by implementing small compatibility libraries for the specific graphics
commands they used in their applications. This made porting their systems unnecessarily time-consuming,
so we determined that we would use a well-defined common graphics layer from the beginning of the
project.
We chose to use SRGP, the Simple Raster Graphics Package, which was being distributed by the
Addison-Wesley publishing company with the second edition of Fundamentals of Interactive Computer
Graphics, by Foley, van Dam, Feiner, and Hughes [Foley90]. SRGP was already implemented for the
Macintosh and X windows; we ported it to Turbo C on DOS, on top of Borland's BGI graphics driver. Our
DOS version of SRGP is now distributed with the textbook. Figure 1 shows the software layering which
makes SUIT portable.
SRGP has several drawbacks. To overcome them and to provide a wider range of functionality, we
layered a thin graphic package called GP (for Graphics Package) on top of SRGP. GP allows widget
authors to avoid screen coordinates by providing arbitrary floating point coordinate systems and
performing standard window to viewport mapping. In addition, GP converts the mixed sample/event input
model of SRGP into a strict event model (mouse motion is treated as a discrete event). GP also provides a
color and font naming layer so that color and font table values can be properly set across different
platforms. Because GP was already providing support for fonts, we augmented its drawText primitive to
implement a small, extensible language for special characters and effects, including:
@i(text) Example Text
@b(text) Example Text
@u(text) Example Text
@+(text) Example Text
@-(text) Example Text
As long as SUIT-based applications are restrained in their choice of fonts and the number of colors
they use, the applications will port across Macintosh, DOS, and UNIX/X-windows platforms with
SUIT (Simple User Interface Toolkit)
SRGP (Simple Raster Graphics Package)
machine
Mac Toolbox
Macintosh
BGI driver

Figure

1: Layered Software for Portability
GP (Graphics Package)
identical look-and-feel. The only remaining point of potential inconsistency is the number of buttons on
the mouse: SUIT's interactive tools assume a one-button mouse, and we recommend that applications do
the same, although we provide access to whatever mouse buttons are provided by the current hardware.
One other feature of GP is its handling of colors. With most graphics packages, if an application is
developed for a color display, when it is ported to a monochrome display, various artifacts appear.
Consider Figure 2, where a red arrow is drawn on a green background. In most systems, when drawn on a
monochrome display, both (non-white) colors would map to black. GP's solution is to define the color of
each primitive as a pair [color, monochrome appearance], as in ["purple", "black"]. When SUIT's
interactive tools are used to set an object's color, a set of color chips appears when on a color screen, but a
toggle button appears on a monochrome screen.
A very different approach to portability is taken by XVT [Valdes, Rochkind], which provides a virtual
toolkit on top of the native toolkit layer on each platform. The advantage of the XVT approach is that on
each platform the application has the same look and feel as other applications built locally on that platform.
There are two major drawbacks to this approach. First, XVT is forced to provide only those functions
common to all platforms - the lowest common denominator solution. Second, the user must use different
support tools (e.g. layout editors) on each platform.
SUIT's Data Model
Most user interface toolkits for compiled languages use a "code dumping" model. The user runs a
builder application and interactively lays out what the screen interface should look like. When he exits this
builder program, it "dumps" the skeleton of a program and the user then edits the interior of the "callback"

Figure

2: Colors on Monochrome
Red
Green
routines, which are called when user interface actions, such as a button press, occur. The motivation for
code dumping programs is that the vast majority of the code to interact with screen widgets is ugly and can
be mechanically generated. The drawback to dumping code is that if the user ever wishes to go back and
change, say, the location or color of a button, the builder program must be able to "parse back" the code
that it had dumped. Of course, this requires preventing the user from editing the dumped code, although
that can usually be done by dumping the callback skeletons in separate files from other code regarding
things like object creation.
The code dumping model is also awkward: To make a change to the interface, the programmer must
fire up a separate builder application, drag a button to a new location, dump new code, and then re-compile,
re-link, and re-run the application.
SUIT uses a different model. In fact, it is fair to say that SUIT is best understood if thought of as a
subroutine library that provides a front end to a database. The SERPENT system uses a similar approach
[Bass]. The database maintains information about all screen objects, such as their location and color. When
an application exits, SUIT writes the database to permanent storage, and when the application is next
invoked, SUIT queries the database to see where objects should go and what color to make them. If we had
not been interested in platform portability, we would have used the .Xresources file as our permanent
storage, instead we write a separate file, called foo.sui, for an application named foo.
Applications programmers create objects by making calls such as
void Hi(SUIT_object obj)
{
printf("hello, world\n");
SUIT_createButton("hello", Hi);
which creates a screen button and attaches a callback function that is called when the button is pressed.
The first time this program runs, the button has no screen location, so it appears at some random location
on the screen. While the application is running, we provide the ability to interactively lay out widgets on
the screen (more on that later). If the user moves the button, SUIT records the location in the database and
upon exit, the database is written to disk. The next time this program runs, the SUIT_createButton
call will create the button, examine the database, and find the screen location that was stored during the
previous execution. Thus, interfaces can be modified at any time that a program is running.
SUIT provides a collection of screen objects, where each object is described by:
. its state, contained in a property list
. a C procedure which examines the object's state and displays it on the screen
. a C procedure which handles user input to the object and updates the object's state
The property list containing an object's state is a set of [name, type, value] triples, as in:
["label", "text", "pizza"]
["diameter", "floating point", 10.5]
["number of slices","integer", 6]
["has anchovies", "boolean", FALSE]
Once users understand that a SUIT-based application is a collection of objects, we introduce external
control by explaining that SUIT maintains a table of all on-screen objects (this is the database SUIT
maintains), and that SUIT multiplexes keyboard and mouse input based on the location of the cursor. Users
quickly understand that three different slider objects share code for their input handling and display
procedures, but have a distinct property lists in the state table. The contents of this table are written to
human-readable ASCII text file between executions of the program.
After users understand that SUIT maintains a table of objects, we explain that SUIT's interactive tools
are provided by accepting some of the user's input as commands to SUIT, rather than to a particular screen
object. When user input occurs, SUIT queries the state of the CONTROL and SHIFT keys: if they are both
down when mouse buttons are pressed, SUIT interprets the input as a command to move or resize a screen
object, and updates the object table accordingly. This use of keyboard modifiers allows us to avoid the "run
versus build" mode used by other interface builders, such as the NeXT Interface Builder. Avoiding this
mode switch is important for new users, and we have experienced almost no cases of users being confused
about when they are giving input to SUIT and when they are giving input to the application. The
combination of SHIFT and CONTROL was chosen for very pragmatic reasons: very few window
managers "grab" this combination by default, and they are two keys that most users can easily locate on the
The "main loop" of a SUIT-based application then looks like:
forever do
{
wait for an input event
are down
THEN handle as a SUIT-command
{
figure out widget we're over
call its input handler
paint any objects who've changed
SUIT maintains a "needs to be repainted" bit next to each object: if any properties of an object change,
then SUIT sets this bit. At the bottom of the loop, all "needs to be repainted" objects are repainted, and
their bits are reset. This provides two important sources of repaint optimization: First, if an object would
change several times in one pass of the loop, it will be painted only once; second, we can avoid some
repainting altogether by not repainting an object if its properties have not changed.
Having grasped how external control works, many users find it mildly unsettling, because they have
become accustomed to using the flow of control in programs to sequence actions. Users do not, however,
find external control to be nearly as difficult as their first introduction to either pointer variables or
recursion. Once users understand the basic mechanism which drives SUIT, we explain that a standard set
of screen objects has already been implemented and stored in a library. This motivates the question of how
screen objects can be made to invoke application procedures, or "callbacks." In the example of a slider,
users understand how the input handler and painting procedure will cause the slider to behave properly, but
are not sure how an application routine can be informed that a value contained in that slider has changed.
We then explain that a callback function can be added to the slider object's property list. If such a property
exists, the input handler calls the function after changing the state of the slider object. This attachment of
user-level callbacks is the most difficult intellectual leap for most users.
As a final comment on external control, we had originally implemented SUIT as strictly external
control: each application's main procedure looked something like:
{
Of course, one of the objects was usually a Done button which would call an exit function to
terminate the program. We added support for "internal control" applications by adding a routine that would
check to see if any mouse or keyboard input had occurred:
{
while (<application's test>)
{
<whatever the application wanted>
This was extremely important for some applications, especially those which needed to poll real-time I/
O devices, but it underscores the fact that internal versus external control is not necessarily a large
difference.
Objects as Abstract Data Types
Many students tend to confuse the notion of an object's state and the mechanisms which affect that
state. We have had good success combating this by treating objects as abstract data types which have
multiple mechanisms for displaying state. For example, SUIT supports a bounded value object with
properties:
["minimum value", "floating point", 0.0]
["current value", "floating point", 0.7]
["maximum value", "floating point", 1.0]
which can appear as any of the following display styles [Sibert, Foley86] shown in Figure 3. A
command (again, with keyboard modifiers down) cycles between the various display styles, and
this has been very effective in establishing the difference between an object's state and the mechanism for
displaying and altering that state. For many students, it is the most visceral experience they have had in
understanding the general concept of an abstract data type.
User Defined Property Types
Users may define their own types for use in property lists by registering subroutines with SUIT that
initialize, copy, destroy, convert the type to ASCII, and convert from ASCII to the type. The ASCII
conversion allows SUIT to write the interface file that is saved between executions, and to convert one
arbitrary type to another by going through an ASCII representation. Users may also register a custom
widget that interactively edits that type.
The Class Mechanism
Subclassing and inheritance are complex ideas. When we first show students SUIT, we explain that
SUIT provides a collection of screen objects, each of which belongs to one class, and can inherit some
portion of their state from that class. When motivating the class and inheritance mechanisms, we find it

Figure

3: Bounded Value Display Styles
scroll bar
speedometer
vertical
thermometer pie slice
horizontal thermometer
necessary to briefly lie to our students; they are not ready to appreciate the real reasons, which are of
course based on issues such as modularity and abstraction, upon which weaker undergraduates have a
tenuous grip. Students understand concrete explanations much better than abstract ones, and once they
understand the concept, one can revisit the motivation for it. Therefore, we explain that having each object
store values for each possible property is wasteful, especially when many widgets often have the value for
a property. Although the storage savings are not really of concern to us, they provide a motivation which
students readily accept. When a program requests the value of a property, SUIT looks first in the property
list containing that object's state. If SUIT does not find the requested property, it then looks in a property
list stored with the object's class. If the property is not found at that level, SUIT looks in a global property
list. If the property is not found in the global property list, SUIT creates it using the type's initialization
routine to establish a default value.
The Property Editor
Students do best with concrete, visible items. Screen objects are good for explaining object-oriented
programming, as shown by the early success in Smalltalk [Goldberg]. The problem with class and global
property lists is that they are no longer implicitly visible. The prototype-instance architecture [Myers90]
does not really solve this problem, because prototype objects are typically not visible on-screen. We
provide a direct manipulation [Schneiderman] property editor that allows users to interactively examine
and alter the state of objects. The SUIT property editor, which is shown in Figure 4, always displays the
object, class, and global property lists when allowing the user to edit the state of an object.
Users alter a property's value by clicking on that property with the mouse; boolean properties toggle
when clicked, and other properties either bring up a type-in box or a type-specific dialog box, such as the
dialog box for type font shown in Figure 5. If an object is currently inheriting a value from its class, the

Figure

4: Property Editor
(1) Object Properties: my poly
ACTIVE_DISPLAY: "standard" of {stan
FILLED: no
FOREGROUND_COLOR: green
VISIBLE: yes
(3) Global Properties
ANIMATED: no
BACKGROUND_COLOR: grey
BORDER_COLOR: grey
BORDER_RAISED: yes
BORDER_TYPE: "motif" of {"simple"
CLIP_TO_VIEWPORT: yes
DRAW_BORDER_ON_INSIDE: no
FOREGROUND_COLOR: black
(2) Class Properties: polygon
FILLED: yes
VISIBLE: yes
TRASH

Figure

5: Font Panel1218new century
charter
courier
helvetica
lucida
times
bold
italic
The quick brown fox jumped
user can take that property value and drag it from the class level to the object level, thereby copying it. If a
property is currently specified at the object level and the user wishes to have that property default to the
class' specification, the user drags the property from the object level to the trash can, deleting the object
level property. In the same way, properties can be manipulated at the global level. An exercise in the SUIT
tutorial asks the reader to make all labels in an application blue, and then have one particular label override
that default and be red.
Property sheets date back to (at least) the Xerox Star [Bewley]. Other systems use a spreadsheet model
for accessing attributes of objects [Myers91, Wilde]. Our contribution is to always expose the fixed three
levels on every invocation. This produces some screen clutter, but also avoids having the student learn the
mechanisms for accessing inherited state. The property editor has been tremendously successful; it allows
our students to understand and use state inheritance in less than five minutes. We believe this is due to the
combination of limiting the class hierarchy to a single level, exposing information at all three levels, and
using direct manipulation.
Other systems, such as Sun's DevGuide, use custom panels for each widget class, rather than a
scrollable list of properties, as in the SUIT property editor. The drawback to using a custom panel per
widget class is that it either requires the authors of new classes to create those panels by hand, or requires
the system provide an automatic layout tool for an arbitrary set of properties, a task beyond most current
systems' power. With SUIT, if a user defines a new widget class, the property editor will work
automatically with that class.
Linking Objects to Other Objects
By default, SUIT provides a very simple linkage mechanism. Application-level callbacks can be
registered with objects, and those callbacks are invoked by the input handlers for the screen objects. A
more complicated problem is how to provide a general linkage mechanism between screen components
and arbitrary user routines. The NeXT Interface Builder solves the problem by allowing the user to draw a
connection between two screen objects and then prompting the user to specify details about the linkage via
a sequence of dialog boxes. SUIT provides a simpler but more limited form of linkage that handles a large
number of common cases and avoids the novice's usual confusion about whether the first object is linked to
the second, or the second is linked to the first.
Many linkages between on-screen objects merely allow one object to control a particular aspect, or
property, of another. For example, in the polygon drawing program in Figure 6, the slider controls the
number of sides in the polygon. Rather than attempting to link two existing objects, a SUIT user would
start with only the polygon object and then invoke the property editor. The user would then drag the
"number of sides" property to the "EXPORT" icon (a picture of a moving van), which causes SUIT to
create a new object that controls that property. This also has the side effect of locking the property, which is
shown with a small "lock" icon in the property editor. This avoids the ambiguous situation of the user
modifying the polygon's ``number of sides'' in the property editor after exporting it.
In fact, the program shown in Figure 6 can be created with no programming, starting with a blank
screen. The user creates a "polygon object" via the menu of standard objects and then exports that polygon
object's ``number of sides'' and ``filled'' properties.
In a similar fashion to the EXPORT icon, the INFO icon can be used to gain information about a
property. Users can drag a property to this icon and get on-line help describing the data type of the property
and a textual description of what the property is used for.
Hierarchy
With most interface toolkits, novices confuse the logical tree of subclasses with the geometric tree that
visually nests objects. We avoid this problem in SUIT by limiting classes to one level, and by hiding the
geometric hierarchy from novice users. As an aside, the motivation for providing rich subclasses of objects
is somewhat weak; it may help the implementor of the toolkit, but most users of the toolkit do not want to

Figure

Application
A Polygon Drawing Program
Done
have to know that class "button" has been derived from class "label" in order to use it properly. In theory,
this should make it easier to create custom widgets by subclassing existing ones, but our discussions with
Motif users revealed that most find the process more frustrating than helpful.
Although some basic SUIT objects are actually hierarchical collections of other objects, we provide
procedural and interactive operations that treat these objects atomically. By providing interactive tools that
allow users to move and resize multiple objects at one time, we sidestep the only motivation most novices
have for wanting to compose basic objects into a hierarchy.
Once users are comfortable with the basic system, we introduce them to interactive manipulation of
hierarchy. SUIT allows users to create a composite object which geometrically contains other objects. One
type of composite object, the bulletin board, does no rearrangement of its children. Another, the stacker,
has vertical and horizontal tiling display styles (vboxes in Interviews/TeX terminology). A third, the pull
down menu, hides its children until it is pressed. Screen objects can be nested within a composite object by
dragging them inside it. Any object can be nested into any of the composite objects, and new users are
often delighted when they discover they can place clocks and sliders in pulldown menus.
When objects are inside a composite object, there is ambiguity as to which object should receive input.
For regular input, this is simple: the input handler for the outer object merely passes the input down to the
appropriate child. Input directed towards SUIT's interactive tools, such as an attempt to move an object, is
more problematic. This is resolved by allowing the user to open a composite widget. When an object is
open, SUIT draws a special border around it to indicate that its children, and not the outer object, will
receive SUIT commands. If a child is moved outside the boundaries of its geometric parent, it becomes
autonomous, moving up to be a sibling of its parent in the geometry tree.
Geometric hierarchy adds semantic complexity in several ways. First, property lookup is affected: if a
button is inside a pulldown menu, and does not specify its color, should it be the color of its class (all
buttons), or of its geometric parent (the pulldown menu)? There is no one, correct answer. One could
implement a flag per property in each object indicating "not specified, but look at parent, not class," which
provides all possible options at the cost of implementation and intellectual complexity. Instead, SUIT uses
a simple rule: if an object does not specify a property, we look first at its class's property list, and if we still
do not find the property, we walk up the parent chain until an answer is found. The class property lists of
the ancestors are not consulted; we concede this is an arbitrary decision, but so are all other solutions.
Employees
In SUIT each object represents an abstract data type, which can have multiple representations called
display styles. Each of these display styles may be simple or may be composed of other SUIT objects. If a
display style consists of other objects, these objects are known as the employees of that display style.

Figure

7 shows the display styles for a bounded value object. The speedometer and thermometer display
styles are simple because they have no employees, while the scrollbar display style has three employees:
two arrow buttons and an elevator.
The employees of a display style appear only while the object is in that display style. When one
"cycles" a bounded value object from the scrollbar to the thermometer, the scrollbar's three employees are
no longer needed. In SUIT this is implemented through visibility. Invisible objects in SUIT are neither
painted nor sent input. When one cycles an object from one display style to another, the employees of the
old display are made invisible and those of the new display are made visible. We chose to change the
employees' visibility rather than create and destroy them as necessary so that the employees' properties
would be retained when the user cycles away from the display style and back to it again.
In terms of geometrical composition, employees are very similar to children. Both children and
employees move and resize with their parents and may inherit their parent's properties. The only difference
between them is that a child exists for each of the parent's display styles while an employee exists for only
one. To make this distinction clear, consider a possible implementation of an object which allows the user

Figure

7: Employees in Display Styles
to scroll through a picture. One display style might use scrollbars along each axis to represent the portion
of the picture currently being viewed. Another might use a panner object (a rectangle within another
rectangle) to represent the same information. In the implementation, the picture object would be a child,
since it would necessarily be in every display style. The scrollbars would be the employees of the first
display style, and the panner would be the employee of the second.
In practice, employees are rarely used. The only object in SUIT's standard library which uses them is
the scrollbar mentioned above. There are two main reasons for this. The first is that, if an abstraction is
sufficiently complicated to merit breaking it down into several component objects, then there is often only
one good way to represent this abstraction; thus the object would have only one display style. An object
with only one display style has no need for employees. The second reason is that those who use SUIT to
build applications usually have a particular interface in mind and therefore only design one display style
for each of their objects. Again, having one display style makes employees unnecessary.
The last portion of the architecture supports semantic linking of state: many systems, such as Garnet,
support a constraint model where the programmer specifies a relationship that should remain true, and the
system ensures that it does. For example, the programmer can make one object stay "above" another on the
screen by establishing a constraint between their viewports.
SUIT's model is similar: we allow the programmer to register an interest in an object, by specifying a
procedure to call each time any property of that object changes. The procedure is called with parameters
indicating the object that is in question, the name of the property that changed, and the old and new values.
This interest routine will then set any properties for that (or any other) object. This is, in fact, how SUIT
makes sure that buttons are the same size as their text. It registers an interest in each button, and if the
"label" property of a button changes, SUIT recomputes a new "viewport" property based on the size of the
text. While this behavior could have been implemented in a specialized constraint language, we believe
that simply writing a subroutine in C is the most straightforward way to establish the relationship we wish
to maintain between the string in the button and the button's viewport.
Our Experience With Users
The next two sections are our most important contribution, both of which are based on our experiences
with our users and the changes in the system that they motivated. These two sections are delineated by
whether the change was to the programmer interface and the data model or to the set of interactive tools
that we provided in the interface builder. We begin with the lesson we learned from the programmer's
interface.
Our most important observation is that we were defeated on only one front: the general idea of
callback-based programming was something we were never able to have the tool teach as part of the
process. We were able to write a four-page addition, to be read before the tutorial, which makes it possible
for most students to understand external control. In hindsight, we should not have been surprised that
external control was the show-stopper for college juniors. Introductory programming courses stress writing
programs whose execution paths closely follow the order that the statements are read in the source code.
Callback functions are typically not covered, nor are subroutines which take functions as parameters. In
fact, in ANSI-Standard Pascal, external control is not even possible, because function pointers cannot be
stored into variables.
All but the very best undergraduates are accustomed to encoding state in the flow of their program, and
they have great difficulty adjusting to the model that they are writing small fragments that can be called in
any order, at any time. In fact, a common "coping strategy" we saw was for a single button's callback
procedure to encapsulate a huge chunk of program functionality. Students also tended towards moded
interfaces, where they attempted to force the user dialog at each step, trying to mimic a command-line
prompt interface within a GUI.
Custom Widget Authoring
Another major observation is that, although creating new widgets is relatively painless in SUIT and
early versions of the tutorial had students do so, we found that students went to great extremes to avoid
writing their own custom widgets. The end result of this is very positive. Whether motivated by fear,
laziness, or by good software engineering principles, students reuse existing code wherever possible.
When students did write custom widgets, we saw two major recurring problems. The first common
problem was in using coordinate systems. The abstract floating point "world" coordinate system is much
easier and more flexible, but is not what students expected. Concrete things are almost always easier to
grasp than abstract ones, and students uniformly expressed the desire to draw in screen pixels. However,
after students had written several custom widgets, they usually began to appreciate the abstract coordinate
system.
The second major problem with custom widget authors was a general lack of understanding of the
"database model," in which input procedures change properties in the database and paint procedures
may only examine the database. This division caused major problems: almost every student attempted to
paint within the input procedure. We considered mechanically disabling the graphics library routines
before calling a user's input handler and then re-enabling them after the call, so that any painting inside a
hit procedure would trigger a run-time error. We abandoned this because it probably wouldn't have helped
a student understand what they were doing wrong.
Students were able to write most programs without creating their own custom widgets. When they
attempted to create custom widgets, they often had difficulty. Based on these two facts, we removed the
section of the tutorial on creating custom widgets. Students who needed to create custom widgets were
eventually provided with an example program which created a simple widget. Students were much more
successful in modifying this program to meet their needs than they had been working from a clean slate.
Make Easy Things Easy
In several places, we were able to apply design principle of "make easy things easy, and hard things
possible." The first was with moded interaction techniques: dialog boxes that grabbed the input focus and
required an answer from the user before other screen objects would again accept input. We identified the
most commonly requested cases and provided simple functions for them:
SUIT_inform (char *message);
SUIT_askYesNo(char *question);
SUIT_askOKCancel(char *question);
SUIT_askYesNoCancel(char *question);
SUIT_ask(char *question,
char *answer1, char *answer2);
In addition to these, we provided one general-purpose moded dialog box. When passed an arbitrary
SUIT object as a parameter, it nests it in an OK/Cancel dialog box, and allows the user to interact with the
widget until the user presses either the OK or Cancel button. These routines seemed to meet all of our
users' needs for moded dialog boxes.
Another common case we found was the need users found for dynamic interaction techniques, such as
rubber banding lines or dragging objects around the screen. We provided a simple routine that XOR'd a
rectangle at the current mouse position as long as the button stayed down. The final screen coordinate
would then be functionally returned. This, combined with a utility function SUIT_ObjectAt(x,y), made it
easy for users to implement simple drag-and-drop techniques, such as dragging objects to a trash can. In
addition to the rectangle drag, we provided a text string drag routine and a general purpose drag routine
that called an application callback each time the mouse moved.
Most of the time, the rule of thumb is that anything one sees on the screen is part of the SUIT interface,
is stored in the database, and is restored, "as is" the next time the application is run. In some instances, this
is not desirable; for example, in some applications it makes more sense for scrollable lists to return to the
top of the list than retain their old location. To support this, we added calls to make particular properties
temporary. In a similar fashion, an entire object could be declared temporary, meaning none of its state
would be saved between application invocations.
Name Space Issues
Like other dynamic systems, we rapidly developed a problem due to the lack of static checking on our
name spaces. For example, property names in SUIT are just character strings, searched at run time using
string compares. Since users need not declare a property before using it, a common user error would be to
misspell a property's name, thus generating a new property with a default value. A classic story involved
one poor student who was trying to remove the border of an object and spent several hours trying to figure
out why the line of code:
SUIT_setBoolean(myObject,
"has boarder", FALSE);
had no effect. By misspelling the "has border" property, the student created a new boolean property,
never again examined. This is a common problem in most LISP-based systems, such as Garnet, where
accidental slot creation is a problem.
Users often need to create new properties. We kept this flexibility, but avoided misspelling problems
for the SUIT-provided properties by using the C preprocessor and including a lines such as:
#define HAS_BORDER "has border"
in the suit.h include file for each SUIT-provided property name in the standard set. This, combined
with the decision to make all string compares in SUIT be case-insensitive, effectively solved our dynamic
name space problems.
Other Programmer Issues
Under certain conditions, it became necessary to prohibit a user from altering a property via the
property editor. For example, uses tended to randomly play with various global level properties, which
often causes problems. Therefore, we locked some properties, so that the user could no longer change them
with the interactive property editor. The remaining semantic question was whether this would also prohibit
the application programmer from setting the property. (We rejected the idea of having two different lock
bits per property to specify both cases). Because the programmer also had the ability to query whether
properties were locked, and to lock and unlock them, we decided to make the lock only prohibit the
interactive user from changing the property, and this has worked well in practice.
From the beginning, we felt it was important to support animation in the toolkit. In our demonstration
programs, we provide bouncing balls that move at a constant twenty pixels per second, regardless of the
speed of the underlying hardware. (If the hardware is slow, the balls will appear at a lower number of
intermediate positions, and their motion will be choppier; if the hardware is fast, there motion will appear
smoother). In order to support this, we needed to provide a device-independent
SUIT_getCurrentTime function, which we added to GP since it was the most convenient layer. We
also found it useful to support a boolean animated property for all widgets; if true, SUIT would
automatically call the object's paint procedure, whether or not any of the object's properties had changed.
Interactive Tool Observations
We present here a variety of insights that we gained from watching people use SUIT's interactive tools.
Gathering Feedback
Gathering feedback from experts is relatively easy. We encouraged all our users to send electronic mail
to the SUIT account if they have questions or comments. From the mail we received, we were able to
deduce which parts of SUIT are causing programmers the most trouble and therefore, which parts needed
fixing, better documentation or both.
Gathering feedback from novices is, by comparison, much harder. The only real way to find out which
parts of SUIT are hardest for novices to learn is to give the SUIT tutorial to novices and watch them as they
work through it. Our standard observation protocol is to seat pairs of students at UNIX workstations with
an observer from the SUIT team sitting behind them, silently taking notes of the session.
Pairing the students off is a vital part of the observation. When two people are told to work together
they talk to each other, often saying what is going through their minds as they work through the tutorial.
This forces into the open a dialog that, with one person, would be entirely internal. By eavesdropping on a
pair of collaborating students, we can learn about which parts of SUIT (and the tutorial itself) that new
users find easy and which parts cause confusion. SUIT's design was changed innumerable times because of
difficulties we saw from these silent observation sessions.
Keeping the observers quiet during the observations is crucial. One reason user testing is hard is that
the observer can often influence the observed - a problem quite familiar to anyone who designs surveys.
This is especially true here, because often it was the SUIT implementors themselves who did the
observation. We maintained a strict policy of "sitting on our hands" during the observations; under no
circumstances were the observers allowed to get up from their chairs and help the users get out of a bind
that SUIT or its tutorial had put them into. If they did, we required the observers to deliver a standard
apology: "I'm sorry I wrote such bad software. Here, let me help you with that.'' Needless to say, the
observers remained seated.
We tested SUIT and its tutorial as often as possible and with as many people as we could. This often
meant living off the kindness of the professors in the department teaching software engineering. This gave
us a pool of approximately 45 students per semester from this one class alone. Other classes gave us more
opportunities to test the software on novices. Because of the large number of people that went through the
user testing process, video taping was never a practical alternative to real live observation.
We would like to note that everyone benefits from this massive user testing experience. The observers
benefit from the experience of learning how to take notes and to be observant; the observed benefit from a
kind of "cultural" lesson that computer scientists really field test as part of their craft; and the programmers
benefit from re-learning what parts of the software confuse new users.
The user testing and the electronic mail from our more advanced users yielded a great deal of practical
knowledge, which we can summarize under three categories: SUIT's basic feedback techniques, SUIT's
different interaction techniques, and SUIT's methods of creating and composing widgets.
Feedback Techniques
XOR is dangerous. As useful a technique as this is for moving graphics interactively, we found that
XOR was not nearly as portable as one might imagine. Some platforms define the bit representation of
"black" to be all zeros, which has no effect in XOR mode! The solution here is to always use a
representation that is all ones as the color to XOR with, not the "black" that is provided by the native
graphics environment.
On platforms with color displays, the XOR problem is even worse due to the fact that the result of an
XOR operation is ill-defined in color. XORing two colors results in a third color, the value of which
depends on the values loaded into the color table, which cannot be predicted. Often we found that we got
"lucky", but of course, anything can change the color table, so sometimes SUIT XOR's a faint blue line
onto a light grey background.
Take care when drawing handles. SUIT uses the standard feedback technique of drawing "handles" on
objects that are "selected" for the purposes of some direct manipulation operations (e.g. resize). As is the
convention, we drew these handles as small black squares in the corners and on the edges of whatever
objects were selected. Users complained that sometimes we would draw these squares on parts of widgets
that were already black, meaning that the handles were essentially invisible black on black.
Choosing some other color was clearly not the solution; doing so merely transferred the problem of
someday drawing red on red, or blue on blue. Eventually, we solved this problem by outlining each of the
black handles with a 1 pixel wide white border, producing a handle that is visible under all circumstances.
We learned that sometimes the best answer to an interface problem isn't with engineering, but with graphic
design.
Animation draws attention and raises expectations. We use animation in SUIT as a way of drawing the
user's attention to a particular part of the screen, especially when there is an abrupt change to the interface.
Animation has the effect of saying, "look here! this just changed!" For example, when the user creates a
new widget interactively, SUIT animates a rectangle that collapses from the edges of the window down
toward the center of the screen, where the new widget appears, much in the same way as the Macintosh
animates a rectangle when a new folder is opened. SUIT's export icon also animates when a property is
exported - a truck drives off the icon as feedback that the property was exported. This charmed most users
who saw it, but other users were disappointed because other icons and buttons didn't animate. Whether the
whimsical charm of the moving truck is too different as to warrant its removal is a matter of debate.
Interaction Techniques
Muscles as modes. SUIT is unlike some other interface builders that have separate "run" and "build"
modes. SUIT's interactive tools are present with the program as it runs, blurring the difference between
running and building. To distinguish between events that are meant for the application and those meant for
SUIT, we use a keyboard modifier. If the SHIFT and CONTROL keys are held down when the mouse is
clicked, we send the event to SUIT, otherwise the event is passed on to the application. Unlike a moded
interface, the chances of confusing run and build mode are zero; the user is holding down the SHIFT and
CONTROL keys, so there is a constant reminder of "who you're talking to.''
Direct manipulation beats menus. In the design of SUIT's property editor, we originally used a "cut
and paste" menu driven model, with dreadful results. Changing a property entailed clicking on a property,
then accessing a menu to choose the desired operation to perform: move a property up a level, move down
a level, delete, etc. The temptation to drag the property itself in order to move, copy and delete it was
overwhelming. The menus always seemed to put the properties "at arms length" from the user. We
eventually abandoned the menus in favor of a "direct manipulation" style of editing.
With direct manipulation, users could now simply click on the property to produce a widget that
allowed them to edit that property's value. For example, clicking on a color property produced a selection
of colors to choose from and clicking on a font produced a listing of available faces, sizes and styles. Text
properties are the only type that break this "click, get a dialog box, press OK to accept the change" model
of interaction. Clicking on a text property wraps a type in field around the currently displayed characters
for the value of that property. This is clearly an irregularity, but one that is seen as a benign exception to the
rule; rather than strict adherence to consistency, we opted for keeping the user's attention focused on the
string he is already looking at rather than producing a dialog box in some other part of the screen.
Moving a property from the class level to an object level was done by a familiar "drag and drop"
action. Users clearly liked this style better than the old menu "move up a level" command. Users also
showed in testing that they had no trouble understanding that dropping a property on the "info" widget
produced a dialog box with information about the property or that dropping it on the trash can deleted it.
As it turns out, the presence of the trash can implied power that SUIT didn't (at first) possess. We
observed that users extended the "drag and drop" metaphor in their own minds to apply to whole widgets
as well as properties; in many tutorial observation trials, users dragged widgets to the trash can and were
startled to discover that nothing happened. It seems that our users understood the concept of "regularity"
before we did.
We always saw the property editor as a place where properties were being dragged from place to place,
not widgets, but so many people tried delete widgets with the property trash can, we added the feature and
our users were happy. By extending this principle further, we also provided help strings for widgets that are
dropped on the info widget. Dropping a widget on the "export" button still does nothing, as the semantics
for this are not well defined.
By providing this harmless, but useful level functionality, we obeyed the "law of least astonishment" at
the expense of the "purity" of the model.
Creation And Composition
Users liked "export." If a user drops a property onto the property editor's ``export'' widget, SUIT
creates a widget corresponding to the type of the property. Color properties produce color chips, text
properties produce text entry widgets, etc. This widget then controls the value of the property that was
"exported". This provides a short cut to the full-blown property editor by giving the user a single widget in
the application interface that controls the value of a property. This ability was seen by many of our users as
a way of avoiding a fair bit of uninteresting code in their applications.
Interactive widget creation is only for demos and decoration. While always impressive in a demo, the
ability to create new buttons and sliders "on the fly," is really not very useful. Items that act merely as
decoration, such as labels, can be nicely added, but most items have attached functionality which must be
specified. Because SUIT is based on C, run time binding would be much harder than in a LISP based
system like Garnet; SUIT would need to compile and link code on the fly - something that a LISP based
system need not worry about. If the user creates a button interactively, how does he attach a callback
function to it? Usually, attaching the callback is done with the creation call, but here, the button has already
been created!
At present, the only way to do this is "by hand": the programmer opens up the C source code file and
makes a function call that attaches a function pointer to the button, referring to the button by its unique
string name that was provided when the widget was created interactively. Spelling the name incorrectly
results in a fatal run time error.
As a practical matter, SUIT's interactive creation of widgets is really only of use for widgets with no
functionality - labels and "place mats" (rectangles that exist purely for show).
Composition of Widgets
In the beginning, we saw the need for a composition widget - a widget whose only purpose was to
contain other widgets. In a fit of whimsy, we dubbed this new widget type tupperware. Tupperware was
seen as a general purpose container class that could be used for horizontal and vertical stacking geometry
managers, pulldown menus, dialog boxes and any other type of widget that might contain other widgets. In
our minds, the only distinction between these different screen objects was in the way they displayed their
subordinates (or "children" in SUIT parlance.) We therefore implemented a tupperware class with
display styles bulletin board, menu, vertical stacker, and horizontal stacker.
Our users saw things differently. To them, a menu and a bulletin board (dialog box) were two
different things and pretending that they were the same only served to confuse them. As it turned out, we
had difficulty in maintaining the code for this behemoth widget and so re-implemented it as several
different widgets. This removed bugs and cleared the waters considerably for our users. Again, cleanliness
of the model was sacrificed for the learning curve of our user base.
Conclusions
By using a reduced model for subclassing, hiding geometric hierarchy, and providing direct
manipulation tools for property setting and linkage, we have been able to radically reduce the learning time
and complexity for a user interface toolkit. By keeping the toolkit's implementation lightweight and
building it on top of an easily ported graphics package, we have been able to implement SUIT on a wide
variety of platforms.
College juniors who are not familiar with external control, and who have never seen another UI toolkit,
are able to use SUIT productively after roughly two and a half hours. Our undergraduate software
engineering class projects have been able to expand their scope significantly by using SUIT, and the
students are highly motivated by being able to easily produce professional looking interfaces for their
projects.
The best validation of a tool like SUIT is when it is used by external sites, which must rely on only our
printed documentation and limited correspondence via electronic mail. At the time of this writing, SUIT
has been FTP'd to over 100 external internet machines, and is being adopted for use in undergraduate
courses at a number of universities. Professional research laboratories are also finding SUIT attractive; as
is often the case, a powerful tool that is easy for novices to use is often attractive to experts as well.
Our original desire was merely to produce a tool which would introduce students to relatively difficult
concepts, specifically external control and inheritance. We had presumed that after spending a few weeks
with SUIT they would outgrow it and move on to other more mature and complex systems such as UIMX
[UIMX], based on Motif Widget set, or Interviews. Instead, we have observed the phenomenon that also
occurred with Pascal: Unless students discovered a specific need to move to a more advanced platform,
they continued to use SUIT for their own research projects.
Our major regret is that we implemented geometrically hierarchical widgets. This more than doubled
the complexity of the system, and we estimate its end value to most users at less than five percent.
In this paper, we have presented the final incarnation of SUIT; it is important to remember that SUIT's
development was a continuous, iterative process, with dozens of versions released and tested for feedback
with real students.

Acknowledgments

We would like to thank Roderic Collins, Jim Defay, Pramod Dwivedi, Brandon Furlich, Rich
Gossweiler, Drew Kessler, James Leatherby, Chris Long, William McClennan, Kim Passarella, Anne
Shackelford, and Hans-Martin Werner and Nathaniel Young, all of whom have contributed to SUIT's
development. We would also like all of our users, and especially Anita Jones and Marc Brown, who
allowed us to use their students as guinea pigs for early versions of SUIT. We would also like to
acknowledge the help of the anonymous referees, whose comments led to substantial improvements in the
paper.
SUIT should not be confused with SUITE [Dewan], a project at Purdue with a similar name.
Getting SUIT
SUIT is provided without charge to academic and non-profit organizations. Readers with access to the
internet can type finger suit@uvacs.cs.virginia.edu for directions on how to get and run the
software.


--R

Serpent: A User interface Environment
Human Factors Testing in the Design of Xerox's 8010
Reflections on Participatory Design: Lessons from the Trillium Experience
Composing User Interfaces with InterViews
A Guide to Suite
Computer Graphics and Applications 6:3
Computer Graphics: Principles and Practice (2nd Edition)

interface Builder and Object-Oriented Design in the NeXTstep Environment
An Overview of the X Toolkit.
Garnet: Comprehensive Support for Graphical
Graphical Techniques in a Spreadsheet for Specifying User Interfaces.
The Andrew Toolkit-An Overview
Technical Overview of the Extensible Virtual Toolkit
A Step Beyond Programming Languages
An Object-Oriented User interface Management System
User interface Management Toolkit for X
A Virtual Toolkit for Windows and the Mac
Ambiguities and Insecurities in Pascal
Graphics: from Prototype to Tool
The programming language Pascal
--TR
An object-oriented user interface management system
An overview of the X toolkit
Composing User Interfaces with InterViews
Computer graphics: principles and practice (2nd ed.)
Garnet
Spreadsheet-based interactive graphics: from prototype to tool
Reflections on participatory design: lessons from the trillium experience
Graphical techniques in a spreadsheet for specifying user interfaces
Human factors testing in the design of Xerox''s 8010 MYAMPERSANDldquo;StarMYAMPERSANDrdquo; office workstation

--CTR
Matthew Conway , Steve Audia , Tommy Burnette , Dennis Cosgrove , Kevin Christiansen, Alice: lessons learned from building a 3D system for novices, Proceedings of the SIGCHI conference on Human factors in computing systems, p.486-493, April 01-06, 2000, The Hague, The Netherlands
Saul Greenberg, Teaching human computer interaction to programmers, interactions, v.3 n.4, p.62-76, July/Aug. 1996
Jacob Eisenstein , Jean Vanderdonckt , Angel Puerta, Applying model-based techniques to the development of UIs for mobile computers, Proceedings of the 6th international conference on Intelligent user interfaces, p.69-76, January 14-17, 2001, Santa Fe, New Mexico, United States
Sven Ubik, Possibilities of using protocol converters for NIR system construction, ACM SIGCOMM Computer Communication Review, v.27 n.2, p.37-48, Apr. 1997
Caroline Appert , Michel Beaudouin-Lafon, SMCanvas: augmenter la bote  outils Java Swing pour prototyper des techniques d'interaction avances, Proceedings of the 18th international conference on Association Francophone d'Interaction Homme-Machine, p.99-106, April 18-21, 2006, Montreal, Canada
Brad Myers , Scott E. Hudson , Randy Pausch, Past, present, and future of user interface software tools, ACM Transactions on Computer-Human Interaction (TOCHI), v.7 n.1, p.3-28, March 2000
Brad A. Myers, User interface software tools, ACM Transactions on Computer-Human Interaction (TOCHI), v.2 n.1, p.64-103, March 1995
portability;software tools;graphical user interface;learnability;user interface toolkit;export;UIMS;pedagogy;rapid prototyping;GUI