Putting multiple table and page layouts to use to provide user flexibility, simplicity of operation, and task support.
Let’s review: For your latest UI design, you’ve settled on an object-centered UI structure, where each window presents the query result for data objects that fit some sort of user-specified query criteria. You’re using object controls to allow the user to carry out both object-level and attribute-level operations whether the data objects are represented in a page layout:
Or as a table:
The page layout and table layout each have strengths. How can you exploit each while keeping the app as simple, flexible, and consistent as possible?
In our example for today, let’s say you’re designing the UI for the corporate buck-passing system. You have to figure the personnel of any complex organization pass the buck every day. It’s high time we involve IT to rationalize the process. Our user group comprises the buck-passers, who receive the “bucks,” where a buck is responsibility for an issue as bestowed by another buck passer. There are four key business objects, the buck, personnel who pass the buck, an instance of a buck being passed (relating personnel to bucks), and the excuses the personnel use to pass the buck. The ER diagram is this:
There are two high-level tasks to concern ourselves with, one is passing incoming bucks to others, and the other task, for those users with supervisory responsibilities (in addition to the buck-passing responsibilities everyone has), is monitoring and evaluating the buck-passing behavior of one’s subordinates. The task hierarchy looks something like this
- Manage buck passing.
- Pass a buck to someone else.
- Prioritize the incoming flow of bucks, and select one to pass next.
- Review each bucks attributes to plan next pass.
- Review history of passes to plan the next pass.
- Assess the suitability of others to get the buck next.
- Select someone from the others to pass the buck to.
- Set the excuse(s) for passing the buck, along with other things.
- Evaluate buck passing of subordinates
- Evaluate general performance of one’s subordinates.
- Evaluate and analyze performance of a particular subordinate.
- Pass a buck to someone else.
There are other tasks too, someone has to initiate the buck in the first place and eventually the buck has to stop somewhere, but we won’t worry about them for this exercise.
Anyway, when designing a UI for a query result of data objects, such as bucks, you have the choice of displaying them to the user in either a page or table layout. Page layout allows for more and larger attributes to be neatly arranged before the user, so it’s best when the user’s task involves detailed analysis and manipulation of individual object attributes. Table layout allows for more data objects to be neatly arranged before the user, so it’s best when the user’s task requires a summary overview and comparisons of object attributes or the manipulation of attributes of multiple objects. Higher level tasks, such as passing a buck and subordinate evaluation, involve many classes of data objects, instances of data objects, and attributes for the data objects, due to the needs of the sub-tasks under the task. Because of differences among the sub-tasks and the data relevant to each, the whole task will often need both table and page layouts. For example, the first subtask for passing a buck is to select one to pass. The selection of a buck requires the user to compare many bucks, something best done in a table layout. However, the second subtask, reviewing a selected buck to plan the pass requires detailed study of a buck’s attributes, something best done in a page layout. The third subtask, looking at the history of passes, requires the summary view point of a table (of previous passes). How should one present such tables and pages? Should they each be in different windows, or the same window? How does one show the relations among classes and attributes when they’re using different layouts? There are several options.
- Isolated windows.
- Alternative views.
- Primary windows linked to dialog boxes.
- Primary windows (or web pages) linked to other primary windows (or web pages).
- Master-detail panes.
- Fish-eye views.
Isolated Windows and Views
Sometimes different tasks need to be performed on the same class of objects, where one task is best done with a table layout and the other is best done with a page layout. For example, when supervisors are not busy passing the buck, they need to review the performance of their respective subordinates. This may involve evaluating the global performance of the subordinates as a group, something good for a table, or focused evaluation on a single subordinate, something good for a page layout. These alternative layouts are illustrated at the beginning of this post.
In any case, the same data objects (personnel) need two layouts depending on the specific sub-task within the task of monitoring subordinates. This can be done two ways: isolated windows and alternative views.
When the same class has different tasks requiring different layouts, you may want to consider having two different windows for the same class, one with page layout and one with table layout. This is especially the case when the tasks are unrelated, not typically being done in close temporal proximity with each other on the same set of objects. Indeed, having separate windows allows other features of the windows, such as the querying capabilities (e.g., Open dialog box), to be optimized for their respective tasks.
To purists, an object-centered UI structure will only have one version of a window for a given class and group of users, rather than multiple windows depending on the task, but don’t let that stop you from making a design more efficient for the user. Separate windows with page and table layouts allow the user to select exactly what’s needed for the task at hand, all with a single click from a menu. It’s an efficient design.
On the other hand, having multiple task-centered windows for the same classes will still add complexity and reduce error tolerance for the user, which needs to be factored against any benefits in efficiency. Note that having alternative windows abrogates to the user the selection of the layout for the current task, and the selection must be made early in the process. If the user guesses wrong, she or he has to close the window and start over, redoing the query. With alternative views, you can maintain a strict object-centered structure while still supporting the tasks with different layouts.
In this design, a single window provides the user with the option to see the same data in either a table or page layout. Typically, the user can switch between the views through the View menu, toolbar controls, or with marginal view attributes.
This is a preferred design when closely related tasks for the same set of objects unpredictably favor either a page or table layout. For example, it would not be surprising if a supervisor wants to switch from global evaluation to individual evaluation (maybe a subordinate is not passing as many bucks as his or her colleagues, and the supervisor wants to figure out why). From doing an individual evaluation, the supervisor might revert to completing the global evaluation. Like isolated windows, alternative views require that users decide on the layout for the current task. The main difference is that the users can more easily switch to an alternative layout for the same set of objects at any time. With a single click, they can change the layout when the task changes or if they simply mis-selected the layout earlier.
You can effectively achieved the advantages of isolated windows with alternative views by providing the user the option to set the view when opening the window. This can be done with separate menu items to open the same window with each view, or, if the one view is preferred much more frequently than the other, a parameter on the Open dialog box can provide the option, with the default being the more frequent view. Users can thus select the layout best for the current task, but always have the option of changing the layout without re-opening the window. Flexibility and error tolerance are maximized, and the UI structure remains at least nominally object centered.
Alternative views are therefore usually preferred over isolated windows. However, they are probably not needed very often. In most cases a sufficiently detailed analysis of the tasks will show that the tasks have more predictability than it may seem at a first. While there may not be much predictability in task order, there may be some predictability in the content. Because of the added complexity alternative table-page views add to the UI, you should not support it unless analysis indicates no better alternative for the users’ known tasks. Generally, do not include it “just in case” sometimes users want a table view and sometimes want a page view. The decision is often one the user cannot make effectively, so providing the views can do more harm than good.
When dealing with database UIs, such as the buck-passing system we’ve here, the tasks often have a certain structure such that each low-level task uses only a certain attributes of the objects. For example with buck-passing, selecting the buck may require little other than the date and the basic issue. However, planning how to pass a buck may require knowing who initiated the buck in the first place. Often different tasks also involve different classes associated with the queried objects. For example, planning a pass of a Buck requires knowing the history of passes to date, so the user needs to see the Pass objects associated with a selected Buck. In such cases, you can cleave the content into page and table layouts, having certain attributes or associated objects have page layouts and others have tables contingent on the tasks they’re used for.
One way to implement this is to have multiple linked windows, each with a fixed layout as appropriate for the attributes or associated classes they display. After selecting an object in one window, the user can display the object’s attributes or associated objects in a subsequent window, which may be either a primary window or a dialog box.
Primary Window Linked to Dialog Box
When a dialog box is used to display the attributes or associated objects of a current object in a primary window, you have essentially a Properties dialog, such as seen in file managers such as Windows Explorer, where files are listed in a tabular layout but a menu command opens a dialog in a page layout for the current object (a file in this case). Because a dialog box is functionally and visually a secondary window to a primary window, using a dialog in this manner has the advantage of communicating a clear hierarchy in the data: whatever is in the dialog is dependent on, or otherwise subordinate to, whatever is in the primary window.
However, using a dialog box is usually a bad idea.
- It introduces an inconsistency and confusion in how changes are saved. Where changes to a primary window are saved with a Save menu command, changes in the associated dialog box are saved with an OK button (a rather uninformative label in this context -”OK” what?). If the Properties window is modeless, then you may also need an Apply button, further complicating things.
- A modeless Properties dialog also has certain ambiguities in the Z-order. Being merely a container of attributes or objects like its parent primary window, it arguably shouldn’t be always floating above the app’s primary window (like an ordinary action dialog does) because it will tend to get in the way. However, if it doesn’t float above the parent (as happens to be the case in Windows Explorer), it can get easily lost under a primary window -and it has no icon on the task bar or dock to allow the user to raise it back up.
- If a modal Properties dialog box is used, now the UI loses flexibility, forcing the user to work on either the objects in the primary window or dialog box, but not both at the same time.
- Dialog boxes need to be small to keep them recognizable as dialog boxes, which forces the otherwise unnecessary use of tab controls when they need to show many attributes, increasing the user’s navigation effort and decrease the self-documenting ability of the window.
- Dialogs lack access to a menu that allows for basic editing controls (in Windows or Linux anyway) such as undo, copy, and paste, which are frequently needed when changing objects or attributes, so users have to use shortcut keys, assuming they know them.
- Dialogs in Mac and Windows are generally not resizable, resulting in users sometimes working in absurdly small scrolling areas (e.g., for a table layout of associated objects).
You get the sense I’m a little unenthusiastic about Properties dialogs?
Dialog boxes, of course, are perfect for delivering commands which require some user-specified parameters, and sometimes those parameters are data objects or their attributes. For example, an Open dialog to specify the query criteria for a window may include a table of objects (e.g., Personnel, sorted by name) for the user to choose to display in the window. As another example, an association between two objects (e.g., between a buck and the initiator) can be set by a dialog box that lists candidate objects (e.g., personnel who may receive the buck next). This is okay as long as the dialog box executes a single atomic action based on the selected parameters. It should not be a place to view and update the object attributes it holds. If you find yourself adding such functionality to a command dialog, you’re probably making it too complicated for its original purpose.
The only reason I can think of to put certain objects and attributes on a dialog box for viewing and/or updating is when the data have so little value or use that it’s not worth even a single progressive disclosure control on the primary window. In such a case, you can tuck the data out of the way on a dialog, with user access buried in a pulldown menu. It’s a place for data an influential stakeholder insists must be available but have no purpose for any task you can uncover.
Primary Window Linked to Primary Window
In some cases, it’s best to present the attributes or associated objects of a current object in another primary window. This is also perhaps the most common solution for web apps, only substitute “page” (as in web page, not page layout) for “primary window,” with the not insignificant caveat that navigating among web pages tends to be slower and harder than navigating among opened primary windows on the desktop. Using linked primary windows may be the only choice when the amount of information to show in each window is simply too large to fit in a single reasonably sized window.
This method is also seen in window managers. Double-clicking a folder opens a new primary window showing the folder contents constituting the objects associated with the selected folder. For that matter, double-clicking an icon to open a document is much the same, showing in a new primary window the (content) attribute value of a selected object in the window manager. This is also what is essentially happening when a user using a browser clicks a link.
Using two primary windows works well when the user has separate but somewhat related tasks in each window. By “related” I mean that the user may transition from the tasks in one window to do the tasks in the other. The tasks however should be separate in that they aren’t tasks that require the user to use both windows at the same time. In general, you want to avoid making the user navigate back and forth between primary windows too much, especially if the primary windows and screen have sizes where the windows will overlap, making the user expend effort shuffling and managing the windows.
For example, while reviewing the pass history of a buck to decide how to pass it, a supervisor may notice something about the behavior of a subordinate (maybe the excuse wasn’t lame enough), and decide to pause from passing the buck to review this subordinates general buck-passing characteristics. To support this transition between two tasks, we allow the supervisor to open the Personnel window from the Buck window by double-clicking the subordinates object control. Navigation between windows is limited to switching to Personnel then later back to Buck window to finish passing the buck.
Primary linking to primary is also a good solution when you’re going to need separate windows for separate high-level tasks anyway. The Buck window serves the buck-passing task, but supervisors also have the separate personnel-monitoring task that needs it’s own primary window, a window they need to access and query for arbitrary personnel, not just those associated with the current bucks. However, by providing a means to link from the Bucks window to the Personnel window, we are re-using a piece of the UI, reducing complexity.
One problem with dividing objects and attributes into linked primary windows is what to do with windows left from a user navigating through a chain of them to get to desired objects or attributes in the final window. Such “drilling down” is common in database apps where classes often have hierarchical relations (e.g., each buck has multiple passes, and each pass may have multiple excuses). Leaving a trail of primary windows allows the user to easily navigate back to previous windows which may have unfinished work (like our supervisor above). However very often the previous windows were mere stepping stones to get to final destination, now left cluttering the screen, adding workload as the user must manually close each window.
One solution is to provide a means to automatically close each previous window as the user opens the next, perhaps through the user depressing a metakey as they open the next window. Another solution is to adopt the browser model and by default replace the current window’s contents with the next, keeping a history in case the user wants to backtrack (this is just the inverse of the first solution -now a metakey is used to force new content into a different window).
Both of these are acceptable solutions, but the real solution for database apps is to not have such drilling down at all. Navigating through a series of primary windows is too laborious for any task you expect the user to perform regularly. Instead, you should provide the user with a means to jump immediately to the proper objects at the proper level in the hierarchy. For example, your Open dialog box can include a sortable list box or (at worse) a tree control to allow fast selection of the ultimate destination without the intervening primary windows. Your user must know something about the destination, maybe its identifier, or the identifier of an associated object, or maybe only its status. Whatever it is, provide the user the ability to query on that attribute, and skip the mining. Drilling down through windows (or pages in a browser-based app) should only occur for exceptions to normal tasks.
Return of the Master-Detail
When the sets of attributes or associated objects are used in related and integrated tasks, they all should appear on the same window to minimize navigation. The obvious solution is dump all the attributes and associated objects sequentially into one big window, providing a scrollbar if necessary, much as would be done with a paper document or report.
While this design is practiced in some web apps, it is rarely satisfactory. Objects high in the hierarchy get spread far apart, even though they are same class and used for the same subtasks. For example, each buck is now separated by its passes and other details, making it difficult to scan for a buck to select to pass. Also, for database apps, a combinatorial explosion of hierarchically related objects can make the window unmanageably large, defying navigating by scrollbar. For example, showing every incoming buck and all its attributes, and all its passes in its history, and all the excuses for each pass could mean thousands of objects to show simultaneously in a single page.
The solution is to divide the window into separate scrollable regions, some using page layout and some using table.
These are your basic “master-detail” relations among the regions, a common design in the UIs of traditional DBMS and some database-like applications such as email and file managers. I’ve touched on master-detail relations before in Task-centered Versus Object-centered UI Structures, Documents and Databases, Object Control, Links and Other Wrong Controls, and Redundant Menus of Redundancy. The content of a subordinate “detail” region depends on the current data object in its superordinate “master” region. A detail region can show objects associated with the master object in a many-to-one relation (the classic master-detail). For example, for the current buck in a table of bucks, a separate region can show the buck’s previous passes, listing who the buck was passed to and when.
Alternatively, the detail region may show additional attributes of the current master object when those attributes are poorly suited for tabular display, an “overflow” detail, to use an Oracle Forms term. For example, details about a buck that a user needs to know to plan the next pass may be in an overflow detail region, leaving the table simplified to only include attributes needed to select a buck to pass next.
There are other possible configurations. You can have a page- or table-layout master with a page-layout associated object detail (rather than table layout), if the objects are usually few (less than four), and it’s more important for the user to work with individual detail objects than to compare them. You can even have a overflow detail with a table layout if it happens that the attributes are best laid out as a table (e.g., a table of summary statistics for the object for the previous four quarters). The same master object may have more than one detail, where each is for a different class of associated objects, or one is an overflow detail and the rest are associated object details.
Master-detail has been around just about as long as the form delivery style has been around. Old character-cell green-screen terminals used them. Somehow, however, this design has been nearly forgotten, perhaps in the move of database apps to the web, where “subforms” are not supported. They are only now being re-discovered, thanks to development techniques like AJAX. However, when you do see master-detail designs today, often they seem stuck in around 1983, not quite making the jump to GUI. Often the regions have a fixed size and presence. The user can’t make the table shorter if it has few items, or let it consume the entire window if it has many items. Resizing the window can result in attributes being cropped off.
It’s time the master-detail had a revival in apps on and off the web. But such a rival should take full advantage of the conventions that modern GUIs offer. To bring those old master-detail relations into modern windows, we need to use panes, where each region is separately sizeable, scrollable, and closeable.
This is how master-detail relations are implemented with consumer software, such as Microsoft Outlook and other email clients, and Windows Explorer. Windows Explorer for Vista, for example features a pane for listing the folder on a computer (in a tree control). The folder pane is the master to a detail object pane listing the contents of the current folder. This pane is in turn a master to a detail overflow pane that provides many attributes of the current file in the folder.
Panes are sizeable to allow the user to adjust for the content, useful for a table layout of objects where the number of objects can vary, or for displaying a single “heavy” attribute that won’t necessarily fit on a single line, such as a picture or a memo field. Panes are closeable for situations when the user needs more real estate for other panes. The ability to open and close can also be used to provide progressive disclosure. You can put low priority objects or attributes in a detail pane and open the window by default with that pane closed.
Given the flexibility panes provide users, you should almost always implement master-detail relations using panes. The only exception would be when the detail is so small and simple (e.g., 1 to 3 light attributes) that it can be integrated within a master pane almost as if it were an attribute of the master object. For example, let’s say that technically each pass can be associated with many excuses, but 90% of the time, there’s only one excuse. We could implement the Excuse detail as a “mini” page layout within the pass overflow detail pane.
Paging controls are provided (disabled here) for the rare case when there’s more than one excuse, but for the typical case, the excuses take little space, a nice proportional design.
Panes to Show Data Relations
Panes can represent the hierarchies of the content by their spatial position to each other, giving your user an quick way to recognize the relations among the objects and attributes. In any window, there will be at least one (usually exactly one) pane that has no master, its content being the query result the user specified through the Open dialog box. This pane should go in the upper left. Detail panes are then arranged down and to the right. For hierarchies with more than two levels, it usually works best to layout out the panes in the same order as an outline, like one would do with the content in a paper report, but applied to the panes, not the content. This means that as you move down the window you finish off each branch of the hierarchy before starting another in order to maximize the proximity of the detail panes to their masters. For example, to use outline notation to represent the hierarchy, order the panes as 1., 1.1, 1.1.1., 1.2., 1.2.1. rather than 1., 1.1, 1.2, 1.1.1, 1.2.1.
Unless the task specifies otherwise, an overflow detail pane should precede an associated object detail. Within the same level of the hierarchy, panes should be ordered to best fit the task or user concepts. For example, order may fit data entry order, chronological order, or perceptions of importance.
Laying out the panes as an outline gives users a sense of the data relations at a glance. However, given the limits of two-dimensional windows, there can still be some ambiguity on what a pane’s master is. For example, with three panes stacked on top of each other, the third pane may be the detail of either the first or the second. Perhaps some standard symbolic indications can be developed that will cue the user for these potential points of confusion, such as using bullets and/or indenting of the pane captions, capitalizing further on outline stereotypes.
Panes versus Link Windows
Panes in a master-detail relation have the following advantages over using multiple windows (or web pages).
- There’s no “window thrashing” effort spent navigating among possibly overlapping windows.
- The layout is stable, eliminating the mental reorientation necessary when switching windows.
- A single click shows new content in the detail panes, as opposed to some window designs that require a double click, or selection of a menu or toolbar item in addition to selection of the object.
- There is no need to close multiple windows when done, no trail of windows left after a task is completed. If the user is finished with an object, the user just picks another. If the user is finished with everything, one click closes the entire window.
- There’s no need to keep a navigation history because wherever the user wants to go (including back to previously visited object) is only one click away.
- While panes visually represent the hierarchical relation among the data, windows can be moved around destroying any visualization of relations, especially for hierarchies more than two layers deep. Windows make it too easy for the user to lose track of what object is related to what.
Overflow details also allow for more consistency across primary windows than a linked-windows design. The division of attributes between the table-layout master and page-layout detail depends on the tasks. For some cases there will be lots of attributes in the table and few in the overflow, and for other cases vice-versa. In an extreme case where all attributes belong in the table, there is no overflow pane. At the other extreme, where users donâ€™t compare items and donâ€™t find the item by scrolling, thereâ€™s no table pane –the master is a page-layout with all the attributes. Thereâ€™s incremental variability in between the extremes depending on the attributesâ€™ characteristics and purposes, but one basic design approach, blending table to page layout, covers nearly all cases with a consistent interface that the user can immediately interpret. Contrast that to using linked windows, where the user may or may not be able to get more attributes in another window, and that window may be a dialog or a primary window.
Overflows as Tabs
Overflow panes have another use than avoiding separate windows. Usually it makes sense to have only one overflow pane for a given master, but sometimes if there are a very large number of attributes, you may want two or more overflow panes for a single master. Assuming you provide a fast way to open and close the panes (e.g., a disclosure triangle or equivalent), this allows your user to better control the attributes to display. The user can display none, one, or several overflow panes. This is in contrast with the alternative for controlling the display of a large number of attributes, a tab control, which always shows exactly one set of attributes.
Alternatives to the Master-Detail
There are a couple other ways of combining page and table layouts in the same window. One approach is the “fish-eye” view. Objects are displayed in a table, but the current object, residing in the center of the table, is shown in an expanded region that includes a display of the associated objects and/or additional attributes. As the user scrolls and clicks through the list, the details for the current object come into view where they can be manipulated. A variation on the fish-eye is the Apple Macintosh Cover Flow, although in most database apps you usually want to use attributes that are more informative and interactive than cover art.
Fisheye views keep the details proximal to the master object, potentially making them easier to understand and learn than a master-detail design. It does, however, have some drawbacks.
- The expanded representation of the current object interrupts the table which can make it hard to match up the table headings with the attributes of objects below the current object.
- It only works well for hierarchies one level deep. Fisheyes within fisheyes would get confusing quick.
Another approach is to use a tree. Trees have enjoyed considerable success in showing hierarchically arranged objects, such as folders in a file management system, and they could be applied to database objects too. Conventional tree controls can show little more than the identifier of each object. To show multiple attributes for each object, you need to use a variation on the tree I call a “telescope” design. Here, the master objects are shown as a table but the user can selectively expand any row to also show details for a single object.
In essence, this is like a fish-eye view, except the user has full control over the expansion, expanding one, more than one, or no master objects. Like fish-eyes, the proximity between master object and its details is maintained, providing a strong and unambiguous visual representation of the hierarchy. However, it has the advantage that when all rows are unexpanded, no row’s attributes are isolated from the table headers. Also, it’s easier to make multi-level hierarchies work with a telescope design.
Master-detail panes have the following advantages over a telescope:
- Depending on the amount of detail and number of levels in the hierarchy, expanding on an object in a telescope may make the identifying attributes scroll out of view. In a master-detail, with separate scrollable panes for each step of the hierarchy, the user will not lose track of the identity of a master object.
- When studying the details of multiple master objects, a user may need to scroll and hunt for the master objects, whose positions change with each expansion. The master-detail has more stability and it’s easier to keep multiple master objects in view, and when the user clicks them, the differences in the detail pane appears as eye-catching animation (It should be said, however, that the telescope allows the user to see the details of two master objects simultaneously if they happen to be close to each other, and the window is big enough).
- In the event the user needs to find a master object with a particular detail (which should be an exception in a properly design window, but it can still happen), the user needs to explicitly expand each master object (e.g., with a double-click). For a master-detail, the user only needs to scroll down through the object controls with the cursor keys.
In most cases, the master-detail is the better solution. However, the telescope or other tree should be used when it is especially important for the user to see the hierarchy. It is also just about the only choice when the hierarchy structure varies by object. Adding or removing levels to a tree is easy. Adding panes to a window is difficult without confusing the user.
Of course, there’s no law saying you can’t use a tree with a detail pane: use the tree to show the relation of objects to each other; use the detail pane as an overflow. But now we’re getting close to the third kind of layout that’s neither page nor table, but that’s a topic for a later post.
Problem: Dividing content into table and page layouts among and between windows to best support the associated tasks.
- Use isolated primary windows to support unrelated high-level tasks.
- Use alternative views for related high-level tasks on the same class of objects.
- Use linked primary windows to support transition between high-level tasks involving different data.
- Use dialog boxes or “properties” windows for data of very low importance.
- Use master-detail regions in the same window for data objects and attributes used for the same high level tasks.
- Use resizable and closeable panes for each master and detail region, unless a detail region is only a few attributes.
- Arrange panes as an outline from top to bottom and left to right to indicate the hierarchical relations among the data.
- Consider breaking up large sets of overflow attributes into separate panes to provide the user greater flexibility.
- Use tree controls or telescope designs when the hierarchical relationships vary by object or are otherwise difficult for your users to recognize.
The title of this post is homage to / stolen from Pat Billingsley’s (1988) Taking panes: Issues in the design of windowing systems, in M. Helander (Ed.) The Handbook of Human-Computer Interaction. New York: North-Holland, p413-436. Billingsley introduced me to usability engineering in her course at the University of Massachusetts in 1993.