Linking User Interface and Database Objects

In the first installment of this two-part article, Eng-Kee and Chris discuss the object-oriented UI and database architecture of the notebook UI they implemented for a pen-based computer.


December 01, 1991
URL:http://www.drdobbs.com/architecture-and-design/linking-user-interface-and-database-obje/184408669

Figure 1


Copyright © 1991, Dr. Dobb's Journal

Figure 2


Copyright © 1991, Dr. Dobb's Journal

Figure 3


Copyright © 1991, Dr. Dobb's Journal

Figure 4


Copyright © 1991, Dr. Dobb's Journal

Figure 4


Copyright © 1991, Dr. Dobb's Journal

Figure 5


Copyright © 1991, Dr. Dobb's Journal

Figure 5


Copyright © 1991, Dr. Dobb's Journal

Figure 6


Copyright © 1991, Dr. Dobb's Journal

DEC91: LINKING USER INTERFACE AND DATABASE OBJECTS

LINKING USER INTERFACE AND DATABASE OBJECTS

Designing an application environment for a pen-based machine

Eng-Kee Kwang and Christopher Rosebrugh

Eng-Kee Kwang and Christopher Rosebrugh are cofounders of PI Systems Corporation. Eng-Kee is vice president of software development, and Chris is vice president of engineering. They can be reached at 10300 SW Greenburg Rd., Suite 500, Portland, OR 97223.


It's no great revelation that different types of computers beget--or require--different user interfaces. Witness the rapidly emerging class of computers that use a pen or stylus as an input device. While many of these systems are desk-oriented and use the pen primarily as a pointing device to complement the keyboard, the system we describe in this article is designed for mobile users in the field of collecting and analyzing data and use the pen as its primary input device. The familiar "desktop" UI metaphor is inappropriate for an "armtop" computer that's capable of being cradled in the crook of your arm like a common clipboard or notebook. For this tool an alternative to the traditional desktop is more fitting.

In this first installment of a two-part article, we describe the software architecture of the notebook UI we implemented for the Infolio, a pen-based computer our company PI (Portable Information) Systems recently introduced. The system is built around object-based user interface and database software. It uses a notebook metaphor, with applications and other categories of software accessed as "tab sections," and user data objects accessible as icons in a "table of contents" section. Because of the high degree of software and hardware integration, we'll begin with an overview of the complete system to put into perspective the intricacies of how the UI and database objects are linked and how they communicate with each other.

In our next installment, we'll describe the Infolio hardware architecture and our hardware/software development and integration methodology. Although the design we describe is unique to the Infolio, the concepts behind the design do have broader applications.

System Overview

The Infolio computer (see Figure 1) is completely pen-based--it has no keyboard--and uses handwriting recognition to accept alphanumeric characters and command gestures "written" directly on its bit-mapped LCD display. The character recognition is stroke-based and includes a training utility that lets users map their own handprinting to characters and their preferred gestures to commands. The device itself weighs less than three pounds and measures 1.2X9X10 inches. Based on Motorola's 68331 small systems processor ( a variant of the 68020), it operates for up to 12 hours on a charge and can also use standard AA batteries.

Rather than using floppies or hard disk, the Infolio executes code and accesses data stored on PCMCIA memory cards inserted in any one of the three available slots. One slot is dedicated to system memory, holding a mixed-memory card which contains the system software in 1 Mbyte of ROM and the system stack and heap in 1 Mbyte of SRAM. (PCMCIA, short for "Personal Computer Memory Card International Association," is an industry-supported open standard that defines solid-state, credit card-size IC cards. The recently announced 2.0 spec supports functions for modems, fax, and networking in addition to memory and application storage.) The other two slots can hold ROM or SRAM cards of sizes ranging from 64 Kbytes to 8 Mbytes each. These cards hold third-party applications and user data. Because the system memory card also provides user data storage space, additional memory cards are not always needed. Because the Infolio supports execute-in-place, read-in-place, and write-in-place, the storage cards are used as continuous flat memory rather than as a disk-like subsystem.

Design Goals and Requirements

From a hardware point of view, the system design goals included use of lowcost, off-the-shelf components, minimum power dissipation and platform weight, maximum database and graphics performance, and true portability.

From the human interaction point of view, the critical design requirement of this system was that it be simple to use in field environments--as close as possible to using pen and paper, but also taking advantage of computing resources to streamline data collection tasks, minimize user errors, and maximize data integrity.

As we conceptualized the software design, we established several goals:

The result is that building applications on our platform is straightforward. Programming the machine consists primarily of connecting standard or customized UI objects to database objects for viewing and editing. A typical application consists of one or more forms definitions (which embody database records), user-defined constraints between the fields in these records, and a graphical representation of the records for both viewing and editing.

Another early decision was that, in order to meet our market window, the software and hardware would have to be designed and implemented concurrently. To make this possible, we defined and created a layer in the system above which all software would (theoretically) be absolutely portable. This allowed us to develop most of the software on SPARCStations while the hardware was being prototyped. Of the megabyte of code we wrote, only 50 Kbytes (less than five percent) is specific to the particular platform (Infolio, SPARCStation, or PC).

User Interaction Paradigm

There are a number of features that support Infolio's use as a field data acquisition and analysis tool.

First, information is input solely with a pen. The system converts the user's hand-printing and command gestures into ASCII data and system commands. The character recognition system is designed to learn individual users' hand-printing idiosyncrasies; this feature also allows the system to be adapted to process non-Roman languages.

Secondly, information in the system is presented to the user for manipulation via a clipboard or notebook-style user interface. This user interface was chosen because it is a familiar paradigm--most people are somewhat familiar with a physical clipboard or a notebook, while only computer users are comfortable with a windowing environment consisting of multiple overlapped windows. The notebook interface simplifies interaction by presenting in the forefront only information in which the user is interested. All other pieces of information are easily accessible via tabs, but remain hidden from view and do not clutter the screen. With the notebook interface, the user does not have to juggle and manage the organization of multiple, overlapping windows.

Because the computer skills of users range from novice to expert, however, we also implemented an easily accessible environment that supports multiple overlapping windows. This mechanism allows overlapping windows to sit on top of the basic clipboard view. Any application can be "torn-off" the clipboard and become a floating window, which allows the user to look at more than one piece of information at a time. There can be as many torn-off windows as the user wishes. Figure 2 shows an example of a floating window.

Database Facilities

The software provides the foundation for a massively-linked database machine. Some of the concepts present are an evolution of the Zog system, a hypertext program that came out of research at Carnegie-Mellon in the early '80s.

Infolio allows both conventional searches of the system's database contents, as well as hyper-linking capabilities. Using the hyper-linking mechanism, a database object can point to any other database object without the need to understand context. For example, an icon can be embedded within an application to link to another application--perhaps a note with text recorded in it. By embedding a link icon to the note in an appointment entry, the user can access background information about that appointment simply by tapping the pen on the link icon.

Links also serve another, more fundamental function: The database architecture makes use of the linking mechanism to build hierarchical objects. For example, an address card object can be built by simply tying together a set of more primitive database objects. This is shown in Figure 3. Each child object retains its original behavior without the need for any additional code. In effect, database linking provides the glue by which the entire software system is constructed on top of the Infolio's kernel.

A Layered Architecture

We decided early in the design process to create a layered software architecture which presents both a simple procedural interface to kernel services, as well as an object-oriented interface to the database and user-interface functions. The rationale behind this decision was:

Layering is more than simply a design philosophy. We strive to maintain the integrity of layer boundaries, to foster a strongly modular system with well-defined dependencies. References are almost always from a higher to a lower layer. Interaction between adjacent layers dominates, with bottom-up and multilayer references intentionally kept to a minimum. By minimizing random references between any two modules, modules affected by changes to external interfaces are more easily identified.

Layering in the system also serves to create a disciplined approach to software design typically found only in hardware design. The layered structure reflects the top-down approach used in designing large hardware systems. The idea is to present to the developer (whether of hardware or software) a view of the world that contains a limited number of discrete, easily managed pieces of information to work with at any one time. This makes the system more understandable. For example, if a developer is working on the Core Object Framework layer (as shown in Figure 4), over 90 percent of the time that developer need be concerned about services in the Kernel Services layer only; only occasionally must he or she deal with other layers' contents.

An additional benefit of layering is that we can port the entire software system to a different operating system, if so desired, with minimal code changes. In most instances, only code in the kernel will need to be changed to support a different platform and operating system.

Object Orientation

One of our software design goals was to create an object-based environment in which the task of creating an application means simply instantiating and connecting UI editing or viewing objects, and then attaching these UI objects to appropriate database objects. The application only needs to provide code that actually deals with its specific purpose rather than with handling information flow in the system. All of the data manipulation and bookkeeping mechanisms are already part of the objects' default behavior.

This object orientation also extends to how the system interacts with applications themselves. From Infolio's point of view, applications are objects. This enables a standard way for the system to interact with applications. It also allows application objects to instantiate and embed other applications within them without explicitly knowing implementation details of the embedded application.

While much of the system design has an object-oriented flavor, we chose not to use an object-oriented development language. Instead, we chose C as the implementation language because it is flexible and widely-known, and because it is well supported with respect to cross-compilers and debuggers. Other considerations were code space limitations and the desire to minimize the execution overhead inherent in object-oriented languages such as C++. Our intent was to provide an object-oriented interface to the database, user interface, and applications--not to provide a generally object-oriented programming system. We call modules having procedural interfaces "toolkits," and those having object-oriented interfaces "toolboxes."

The object or class hierarchy mechanism in Infolio allows complex objects to be built using simpler objects without duplicating the code associated with the simpler objects. We can thus build complex applications incrementally without incurring the cost of duplicated code.

Encapsulation of data and behavior protect the integrity of the object. Changes to the data contained within an object can only be made through a standard predefined message interface.

Event Handling

The interaction between the system and the user is based on events, which act as catalysts for activity in the system.

Events in the Infolio include both physical and logical events. Physical events include, for example, pen tip down, pen tip up, side switch down, side switch up, card door open, low battery, failing battery, wake up, and time-out alarms. Logical events are generated by the system to trigger a response without actually targeting the responder. Examples of logical events include inserting characters, deleting characters, selecting a region, closing a window, moving a window, and refreshing windows.

The system uses the hierarchical organization of the user-interface objects to determine the appropriate response to an event that occurs in a specific area of the screen. Events that are not position-specific are handled by whatever handler exists at the time the event is to be processed. If no handler exists, the event is simply ignored and discarded.

As shown in Figure 5, the system event manager passes an event to the window manager, which in turn passes it to the root UI object via the user-interface framework. The event is then passed down the object hierarchy until it reaches a "leaf" UI object (one that has no children). This UI object can then choose to handle the event or bounce it back up the hierarchy. This mechanism gives the lowest-level object (the most specific object) the first shot at handling the event. If the event remains unhandled, it becomes a null event and is discarded.

Because locality is the basis for handling events and passing messages to UI objects, new objects can be installed without affecting any existing objects. This also allows applications to change the way a UI object handles an event. To illustrate how an application can change event handling, here's an example using a text input object. The text object's normal behavior when passed an Insert event is to take the data (in this case a string) and append it to its internal storage. To make it a Read-Only text object, all the application has to do is disable the handler for that message. When the object receives an Insert event, it will then ignore the event and pass it back up the hierarchy, as shown in Figure 5.

Behavior Encapsulation

Objects are wholly responsible for implementing their own behavior, while conforming to a minimal fixed external interface. The definition of an object includes not only its appearance and its data storage, but also how it interacts with events and with other objects.

For example, a number input object will only respond positively to an Insert event that contains numeric characters, namely, 0-9. Any other characters will be ignored. This object always exhibits the same behavior, regardless of where it is instantiated. Because behavior is an integral part of the object, any application that instantiates the object does not have to provide any code to filter the input data.

Objects with container ability have a specific interaction style with the objects they contain. For example, three container objects are currently defined: Bag, Scaffold, and OneOf. All three can contain zero or more objects of any type, including other Bags, Scaffolds, or OneOfs. However, each organizes its children differently, so that changes imposed on the container objects will be reflected differently by their children.

A Bag provides for a visual organization of objects that is unconstrained or freeform--its component objects can sit anywhere. When a Bag is resized, the size and position of all its children with respect to the origin of the Bag's space are unchanged. Objects sitting outside the visible portions of the Bag's space are simply invisible to the user.

A Scaffold provides a structured row/ column organization for the objects it contains. Objects in a Scaffold are organized either in a row or in a column structure. When a Scaffold is resized, it will attempt to distribute the change in dimension to all its children that are set up to change. So, if there are four objects in a row Scaffold, and two of the four objects are set up to change, and if the row shrinks in the horizontal dimension by two inches, each of the two resizable children will be made to shrink in proportion to the new horizontal dimension.

A OneOf provides an overlapping organization of objects. All objects contained in a OneOf occupy overlapping visual space, and only one child object is visible at any one time. When a OneOf is resized, all its children are resized to the same new size.

Message Handling

All objects support a common set of messages, and can send these common messages to any other objects. Common messages are akin to a base class definition. Common messages can be passed around without any explicit knowledge of the objects required. New objects can thus be defined, created, and installed without having to recompile the system.

The message handling mechanism is implemented using function tables. All object classes provide function tables in which a predetermined number of slots in the table represent the common messages. The common messages which all UI objects support are shown in Table 1.

Table 1: Common messages supported by all UI objects

  UI_NEW_M           Creates a new instance of the object class
  UI_DELETE_M        Deletes an object instance
  UI_DRAW_M          Causes a redraw of the object instance
  UI_MOVETO_M        Changes the location of the object
  UI_RESIZE_M        Changes the dimension of the object
  UI_1CLICK_M        Passes a pen tap event to the object for processing
  UI_PEN_DOWN_M      Passes a pen down event to the object for processing
  UI_PEN_UP_M        Passes a pen up event to the object for processing
  UI_GESTURE_M       Passes a gesture event to the object for processing
  UI_GET_INFO_M      Inquires about attribute information of the object

Sending Messages To Objects

Every object instantiated in the system has a unique identifier that also contains its object type.

For example, to pass a message do_something to the object named object_x, the following will suffice: ui_do_something (object_x,...).

If object_x chooses not to handle the message do_something, the call will simply fail without serious consequence. This allows the caller to not have to worry about whether an object actually understands a particular message.

Examples 1 and 2 present pseudocode fragments that demonstrate how a new message, Do_Something, is created by the developer with the system's help. Example 1(a) shows how to define the new message and map it to a handler by using a standard template. Example 1(b) shows how this template-based definition is automatically expanded into implementation code by the PI "file compiler." Example 2(a) shows the message-handler code written by the developer, and Example 2(b) shows the system code that resolves the new message and passes it to the object's new message-handling function.


Example 1: (a) Starting with common message template definition, the developer defines the message and maps it to its handler function; (b) the system implementation code that is automatically generated by the PI file compiler from the definition in Example 1(a).

(a)
  /* message template description */
  %func_template bool UI_DO_SOMETHING_M (
      obj_id                             /* IN: object pointer *
  );
  /* Object class message description mapping.  It is NOT necessary to
     declare
  * parameters to message since they are already defined in template.  */
  %function [UI_DO_SOMETHING_M] ui_Bag_do_something;

  _________________________________________________________________________

(b)
  /* These macros are used by the UI framework to pass messages to
     particular
  * objects without requiring explicit knowledge of the object classes.
  * The typedef and macros are AUTOMATICALLY generated from the message
  * template description.  These macros, etc. are only used byi
    framework.  */
  #define UI_DO_SOMETHING_M_ID 1
  typedef void (*UI_DO_SOMETHING_M_fn_t) ( obj_id );
  #define UI_DO_SOMETHING_M_(_ftbl)
 (*(UI_DO_SOMETHING_M_fn_t)_ftbl[UI_DO_SOMETHING_M_ID])

  /* Messages are implemented as re-directed MACRO'ed functions through
function

  * table.  This typedef and define is AUTOMATICALLY generated from a
high-level
  * message description.  */
  typedef void (*ui_Bag_do_something_fn_t) ( obj_id );
  #define ui_Bag_do_something (*(ui_Bag_do_something_fn_t)bag_ftbl [1])

  /* Message function table for object class Bag.  This table is
     AUTOMATICALLY
  * generated from the high-level message description.  */
  void *bag_ftbl [19] = {          (void *)...,
  (void *) _ui_Bag_do_something.

  ...

  };

Example 2: (a) Developer's message handler code for the object; (b) the system framework code that resolves the message and passes it to its

handler

  (a)

      void _ui_Bag_do_something(
           ui_Bag_t *bag                  /* corresponds to an obj_id */
           )
      {
           ...
      }
  (b)

  /* Implementation of messaging mechanism for sending message
      DO_SOMETHING */
      bool ui_do_something(
          obj_id    id,
          ...
          )
      {
          void  **ftbl;

          /* look for message function table associated with the object
             ID. */
          ftbl = __find_object_ftbl (id);
          if (ftbl && &UI_DO_SOMETHING_M (ftbl)) {
             /* If function table exists for the object -> known object
                type
              * and message DO_SOMETHING is defined, pass the message to
                the
              * object (call the function!!) */
              return UI_DO_SOMETHING_M (ftbl) (id, ...);
          }
          return FALSE;
      }


Data/Viewer Binding

The relationship between a data object and a viewer/editor object is loosely constrained. This means that just because a data object contains an integer value, it is not constrained to be viewed only as a number. Different viewers can be attached to the same data object at the same time. For example, an integer data object can be viewed as a number using a simple text or number object, or graphically, as a gauge, by using a gauge object as the viewer.

In addition to being able to view the database information differently, viewers can also be constructed to view distinct portions--or hide certain pieces--of a complex database object.

For example, to create two views into an integer object, you would link user interface objects to a database object as shown in Example 3. The graphical result of these links is shown in Figure 6.


Example 3: Creating two views into an integer object by linking a UI object to a database object

  db_handle = db_Int16_new(123);
  viewer_1 = ui_Num_new(...);
  viewer_2 = ui_Gauge_new(...);
  ui_attach_data(viewer_1, db_handle);
  ui_attach_data(viewer_2, db_handle);

Conclusion

The layered software architecture and object-oriented implementation of Infolio have enabled us to build a simple but powerful software system for our portable pen-based computer. Next month, we'll examine the system's hardware architecture.


Copyright © 1991, Dr. Dobb's Journal

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.