Object Layout with the SVL Interface Toolkit
Chemical Computing Group Inc.
One of the more mundane programming tasks when creating a Graphical User Interface (GUI), is the physical placement of the interface objects (buttons, labels, text fields etc) within the window. Many GUI Builders offer a simple point and click mechanism for placing the objects where the programmer desires. This method is easy, yet inadequate for many reasons including:
Other GUI Builders offer programmatic or algorithmic layout management. These services are either far too simplistic and confining, or so complicated that the code needed to layout a window encompasses half the program. Furthermore, complicated layout schemes often introduce non-standard and non-intuitive notions which require a level of mastery before becoming proficient. Most Motif programmers share this sentiment. The SVL Interface Toolkit, embedded within the Scientific Vector Language (SVL), provides programmatic layout of interface objects with a small set of intuitive and concise directives. The purpose of this article is to review the SVL Interface Toolkit, embedded within MOE.
SVL Interface Object Layout - The Basics
In SVL, the interface objects created in a window form a hierarchy. That is, a parent object may have one or more child objects, each of which may, in turn, parent one or more child objects of their own, and so on. Each parent object is responsible for laying out its children. For this reason, parent objects are referred to as "manager objects". The simplest type of manager object is a vertical layout manager (i.e. one which stacks its children vertically) as shown below:
This window layout was performed by creating a label, a button, and a text field as children of a vertical layout manager, called a "Vbox". The SVL code to create and display this window is listed below:
The other manager objects in the SVL Interface Toolkit are the horizontal layout manager, or "Hbox", which stacks its children horizontally, and the matrix layout manager, or "Mbox" which arranges its children in a matrix of specifyable dimensions. For all intents, a Vbox object is an Mbox with one column, while an Hbox object is an Mbox with an infinite number of columns. The Shell, the topmost interface object in the hierarchy of a standalone window, is actually a Vbox, thus child objects of a standalone shell will stack vertically by default. The specification of the Vbox object in the code fragment above is therefore redundant. One can easily imagine the power and flexibility of combining and nesting layout managers, and using creation order to create sophisticated layouts.
Each SVL Interface Toolkit layout manager creates a matrix, or grid, of cells, each containing one child object. The size of an individual cell depends upon the size of all other cells in its row and column. Layout managers have only two tasks to perform. The first is to size the cells of the matrix such that all children are contained within their respective cell. The second is to position the children (within their cells) such that they line up "nicely" with objects in neighboring cells. The latter of the two tasks is where most toolkits fall short. Each object needs a set of hints, or directives to position itself within its cell. Directives such as centering an object, and providing a margin around it are fairly trivial. The directive that is really needed is the "make-my-objects-line-up-so-that-they-look-nice" directive!
The SVL Interface Toolkit layout managers implement this directive implicitly. In fact, most interface specifications will layout "nicely" without any additional hints or directives at all. Objects simply "know" how they like to line up, even when surrounded by margins, extra spacing, and 3D shadows, or when accompanied by titles. Even changes to the textual contents of buttons and labels rarely require any intervention by the programmer to preserve a desired look. The menial task of repeatedly tweaking a window to get things to line up is greatly reduced.
A Rich Set of Directives
Obviously, the layout managers are not psychic. If they were, SVL would just provide the "window-that-I-need-for-my-SVL-program" object. For this reason, the SVL Interface Toolkit provides a small set of concise and intuitive layout directives, specifiable as object attributes. The following attributes are available to all interface objects:
For a more detailed list and description of these attributes, please see the SVL manual.
The following attributes are available to layout managers (Vbox, Hbox, Mbox) only:
An important point should be made about the resizeV and resizeH attributes. Unlike other toolkits, the SVL Interface Toolkit was designed to simplify the specification of resizable objects. A typical example would be creating a window containing a Listbox which resizes as the window is resized by the user. Eliciting this behavior in SVL is merely a matter of specifying the resize attributes on the Listbox object - that's it. The toolkit automatically knows to resize the rest of the object hierarchy accordingly.
Interface Layout In Action
The best way to see how interface object layout is trivial in SVL is to see it in action. The window, shown below, is the interface for a calculator. The window is resizable. That is, if the window is resized, the buttons in the calculator will grow/shink to match the window size.
The SVL code to create and layout this window is listed below. Notice how
virtually no extra directives and attributes, other than object hierarchy and
creation order, are required to specify the layout. The only layout directives
and attributes used are extend and resize. These are required to
allow the window to respond to resizing, and to extend objects to fit their
cell sizes. The rest of the layout is automatic. Recall that the topmost
window object in the hierarchy behaves as a Vbox.
As with most programmatic layout schemes, achieving an exact look is not always possible, especially when screen and font changes come into play, as described earlier. Instead, an acceptable layout which "looks nice" is generated. A positive side effect of this behavior is that a common style is preserved between application windows, with virtually no effort. As far as flexibility goes, one would be hard pressed to find a layout which is beyond the capabilities of the SVL Interface Toolkit. In fact, the entire MOE interface is written using the exact same layout methods, with just as little effort.