Re: UI subsystem interface design
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Tue, 7 Nov 2006 10:32:18 +0100
On Tue, 07 Nov 2006 04:20:16 GMT, Brendan Guild wrote:
I am trying to design an independent user-interface subsystem that
software can communicate with strictly by passing data by value.
Unfortunately, my first attempt feels rather awkward and I am filled
with an unspeakable dread that when I try to implement the design I
will discover that it is insufficient.
I don't think that by-value vs. by-reference is really THE issue here.
Because of this, I will now provide details of the design I have
created so that I might have hope of someone suggesting something
much better. At the very least I hope that someone will provide a
reference to a well designed UI-subsystem interface that I can borrow
I will call the user-interface subsystem which I am designing 'the
subsystem', while the rest of the software that interacts with the
subsystem will be called 'the application'. When I refer to 'the
interface', I mean the interface between the subsystem and the
application, not the user-interface.
My fundamental design principle is that the interface should define
classes of primitive drawing objects. The application constructs its
UI by composing the primitive drawing objects and then giving those
objects as data to the subsystem, which will be responsible for doing
the drawing based upon the data it is given.
The most primitive class of drawing objects is the Window. Each
window is a rectangle and contains coordinates for its position
represented as floating-point numbers between 0 and 1. Windows
contain other windows recursively, and the actual position of each
window is relative to the containing window. So a window between
coordinates (0,0) and (1,1) always exactly covers the containing
It must be rather a fixed-point type then. However the idea is not that
good. The problem is that windows get auto-scaled, which is in most cases
A fundamental helper class for windows is the Mapping class. A
mapping object in the context of this interface is a endomorphism on
objects within some class. Each window contains a mapping for Colors
and a mapping for Fonts.
A color object represents a color idea so that drawing can take place
with colors, and the mapping for a window defines the meaning of each
color used in terms of the colors of the containing window. Adjusting
the mappings of a window affects the way the UI looks for that window
and all contained windows.
Well, there are problems with that. Colors and fonts form a schema, you
need some inheritance mechanism for children to inherit the parent's style.
Aggregation is very not suitable here.
The application can create its own color objects and color mappings
to control the way each window appears, but the color mapping of the
outermost window must convert all color objects into color objects
that are supplied by the subsystem so that the subsystem is able to
interpret the colors. To make this possible, the subsystem is
required to supply a ColorScheme object which is an intricate
container for color objects that allows the application to get colors
from the subsystem at varying levels of abstraction.
Font objects are exactly like color objects, except that font objects
represent type-setting information, including more than what one
would normally call 'the font' of some displayed text.
I use the term ID-objects for Font and Color objects because they are
atomic identifiers for the idea that they represent. There is no way
for the application to examine an id-object supplied by the subsystem
just as there is no way for the subsystem to examine an id-object
supplied by the application. However, both the subsystem and the
application will likely be able to examine its own id-objects. Color
objects created by the subsystem to give to the application likely
contain red-green-blue information that only the subsystem has access
Unfortunately colors and fonts require some resources allocated, especially
fonts do. So you cannot use them by-value.
The Window class is abstract. The simplest subclass of Window is
called Drawing which represents something visible to the user. A
Drawing is restricted to only contain other Drawings, and contained
drawings hide part of the containing drawing by being painted over
the containing drawing.
There are three subclasses of Drawing: Text, Bitmap, Vector. They
correspond to the three major drawing modes that it would be nice to
support. 3D drawing would also be nice, but let's not get greedy.
[ OpenGL, huh? It is quite declarative, it would be quite difficult to
marry it with your stuff. Any 4GL stuff would be. ]
These subclasses are concrete and each object contains what one would
expect from the name. A Text object contains a string to be shown in
the window and type-setting information. Bitmap contains an array of
colors. Vector is a graph of lines and points with color and
thickness, as well as perhaps other geometric objects such as
That was quite sketchy. The primitives you describe don't work well on the
window abstraction level. Either you need some quarks lesser than a window,
or you should drop the concept of a rectangular opaque non-overlapping area
(window). It is not a simple decision, but you should make it early.
The other subclass of Window is called UIWindow and it represents an
area of the screen that reacts to the mouse. In addition to those
things which all windows have, a UIWindow has an Event object and an
Event mapping. When the user clicks on a UIWindow, the associated
event is given to the event mapping and the resulting even is given
to the event mapping of the containing UIWindow and so on until to
outermost UIWindow, then the final resulting Event is given to the
application as the notification that the user has clicked on
Event handling is a vast theme. The first question is how would you compose
event handlers. The second question is how would you prevent deadlocks and
circular notifications. The third question is how would you deal with modal
things (usually it leads to multi-threading and opens yet another can of
worms). The fourth question is how would you do synchronous notifications.
All in all, window is an active object. That means you have to compose not
only passive (messages/subprograms) but also active (event handling loop)
behavior. It is a very hard nut.
Event objects are the third sort of id-objects and the primary job of
the application is to create event objects to associate with each
place that the user might click and then to interpret the events when
the objects are given back to the application. Event objects can also
be associated with keyboard events through a completely separate part
of the interface. Naturally, the application is also given the
coordinates of the mouse-click relative to the UIWindow that was
The primary job of the subsystem it to take a single Window, render
it and report any events that the user generates upon seeing the
resulting display. When the rendering of the UI is to change, the
application must modify the Window object and then re-send it to the
That completes my brief description of what I have designed up until
now. I am concerned that when even a small part of the UI must change
the entire data for all of the UI must be sent to the subsystem. I
feel like I should have an interface for modifying the UI from the
application even after it has been sent to the subsystem, so that
small changes can be made efficiently with the cooperation of the
subsystem, however that would surely greatly complicate the interface
and I am not entirely certain how it should be done.
Are there any examples of a good data-passing UI subsystem interface
I saw no universal one. It is easy to criticize gtk, Qt, Windows API, MFC
etc. Too much depends on particular requirements. Both event and time frame
driven architectures have their place. And finally, no OOPL is suitable to
handle parallel types hierarchies required for "universal" case.
(I hope RM folks will jump in and teach us GUI design in SQL... (:-))
Dmitry A. Kazakov
- UI subsystem interface design
- From: Brendan Guild
- UI subsystem interface design
- Prev by Date: Re: Definition of Abstract Data Type
- Next by Date: Re: Definition of Abstract Data Type
- Previous by thread: Re: UI subsystem interface design
- Next by thread: Re: UI subsystem interface design