The visual nature of AmigaOS has always encouraged the use of Graphical User Interfaces (GUIs) as primary means of interaction between the user and software. It did take some time to define and refine the direction in which the Amiga GUI-programming API was heading, including a complete false start (the 1.x Intuition) and a cul-de-sac called GadTools. Surely the programmer is now much better-off with BOOPSI/ReAction; yet the power, sophistication and comfort of the toolkit does not guarantee anything. The quality of the GUI is determined by the quality of its designer’s thinking – the toolkit itself is a secondary factor. You can make a lousy piece of GUI with ReAction, MUI or Zune just the same!
This article focuses on common GUI design problems because even the greatest features will come to nothing if the application behaves or speaks rubbish. I’ve picked fifteen particular problems in five problem areas; I may add some more in the future if there is interest. The article is based on a rather extensive research and distills material from many sources, of which the most helpful (and the least academic) is probably Jeff Johnson’s GUI Bloopers 2.0, a book which I can recommend as a perfect reference material for further study.
GUIs are designed for (and by) humans, so the quality of the user interface can be perceived in a subjective way. Rather than preaching what is good and what is bad (I have no authority to do that anyway), this article tries to explain why a particular solution may degrade user experience or hamper workflow. To illustrate my point, I use examples from real Amiga software wherever possible. This is not to criticize or deride the individual program authors, so don't get offended if you find your software being picked at here. The idea is to help you improve your software, much as reader feedback will help me improve this article.
PROBLEM AREA 1: Naming and text-related bloopers
1. Excess use of jargon
Despite all the modern efforts towards "user-friendliness", you cannot avoid using jargon in software: some kind of specialist knowledge will always be assumed. There are two types of jargon typically found in Amiga GUIs:
- technical jargon ("technicalese"), which refers to computing stuff in general, and
- Amiga jargon ("Amigalese"), which specifically describes AmigaOS internals and concepts.
Giving fancy names to things is an old Amiga tradition, and to an extent it is a healthy tradition, as it helps reinforce the identity of the platform: we would never call our Workbench a "desktop" because it is... well... our Workbench :-) However, remember that jargon only works as a successful communication device as long as its users share a similar level of knowledge and experience. From this viewpoint, using technicalese may be fairly safe because all AmigaOS users are computer users: they will know that an icon is not a religious painting, and that a menu is not to be looked for in a restaurant. Using Amigalese was fine while we all were on the same boat: we had the same computer with the same operating system of the same version, we bought the same magazines and read the same manuals. We lived and learnt as the platform developed. But this is not the case any more: the owners of present-day Amigas are seasoned users remembering the 1.x days as well as newcomers who dived into AmigaOS out of curiosity or in search for the geek factor.
So think about your use of Amigalese in your software. Try to imagine the user as someone who – unlike you – doesn’t have years of experience with AmigaOS. Adopt user thinking, not programmer thinking. Use more general terms and descriptions, say and name things clearly. Do not litter your GUI with confusing terms and abbreviations, do not refer to internal OS stuff unless you have to. Strive for information value.
Time for an example? The screenshot below on the left is from the old AmigaAMP Prefs editor (now superseded). As you can see, its menu makes an assumption that the user knows what ENV: and ENVARC: are, how they are used in the OS, and that they have something to do with program settings. Yet this is all rather specialist knowledge, far below the Workbench/UI level! The result? A less experienced user is left wondering why there are so many load/save options, what they actually do and which one is the appropriate to choose. — The other screenshot shows the AmigaOS4.1 Prefs drawer. See the number of abbreviations used there? Well, it can certainly be expected to find technical stuff in system settings, and we can possibly assume that a computer user may have heard of "GUI", "USB", "URL" or "DOS" – but do we really need to hide our audio system and our requesters under the cryptonyms "AHI" and "ASL"? (This one is even more absurd as it appears that very few Amigans know what ASL actually stands for.) Why not use more descriptive names?
Another example could be taken from the AmiUpdate preferences window. There is a setting that lets the user specify how the program shall be represented when iconified, the choices being "AppIcon", "AppMenu" and "AmiDock Docky". Not very clear and informative; I'd suggest not exposing the actual implementation (because that leads you to using Amigalese) and using more general descriptions, like "Icon on Workbench" or "Item in the Tools Menu".
2. Vagueness, redundancy, lack of point
Be clear and specific. Especially in requesters that require the user’s attention and/or confirmation it is helpful to provide more information about what’s going to happen. Save the user’s time and brain cells, do not just ask “Are you sure?” or “Continue?” – such vague questions may create confusion as to what the user is actually confirming. Resist the temptation to be funny in requester messages, it's a nerdy thing that only makes your software look unprofessional. Be instructive and informative, save your wit for the Friday night with the girl.
Redundancy (i.e. the repeating of information) can sometimes be useful as a mnemonic device but too much of it creates information overflow and can be distracting. There is really no need to keep repeating the word "settings" in a menu that is called Settings – this only makes the menu look crowded (the screenshot is from the VICE emulator):
3. Overuse of text styles
If you ever need to use text styles (bold, italics, underlined) in your GUI, use them sparsely. It's perfectly all right to display the requester headline in bold style because it makes sense and looks good, but generally there are other ways to present information and make things stand out. For example, a button for a dangerous function will provide a better (and safer) visual cue if you make it bigger and detach it from other gadgets.
Do not use italics for main or a longer text, it will be difficult to read. The software rendering of italics (as used in the Amiga font subsystem) does not always produce satisfactory results for certain fonts. And no, the italicized text for Workbench icon names in the default AmigaOS4 theme was really not a good idea.
PROBLEM AREA 2: Misused GUI controls
4. Wrongly used checkboxes
The checkbox – whether it is used in the form of a CheckBox Gadget, a checkable menu item, or a checkable ListBrowser node – seems to be a very simple and straightforward GUI element. Just don't let it fool you: you'd be surprised how many user interface bloopers are related to the use of checkboxes. In order to realize what you may be doing wrong you should first understand how the checkbox is supposed to work. The checkbox is a GUI control that indicates a state or an attribute within a binary relation of two opposite values. A switch whose checked state implies a value of yes, on, active, enabled or true, whereas the unchecked state implies no, off, inactive, disabled or false (the analogy is 1 and 0 in digital logic). In other words, the two states refer to clear and logical opposites.
It is, therefore, a blooper when the checkbox is used for other than on/off settings. For example, the menu of the text editor GoldEd features a typing-mode setting implemented as a checkable item labelled "Insert mode?" (see the screenshot below). What's wrong with that? Well it is quite clear what will happen if the item is checked (= the editor will work in the insert mode) but it's rather unclear when it comes to unchecking it: what on Earth is the opposite of “Insert mode”? You cannot expect the user to know that it is “Overwrite mode” because they are not clear, semantic or otherwise natural opposites: the only logic here is a certain convention used in text editors. Rather than opposites, the two typing modes should be seen as two mutually-exclusive options, so a more appropriate implementation of the setting would use two mutually-exclusive (radiobutton) menu items labelled "Insert mode" and "Overwrite mode", respectively.
As checkboxes establish a certain logic between their visual state and meaning, it is a blooper to use negative text labels with them. Why? The checkmark displayed in the checkbox is meant to visually indicate yes, while a negative text label (i.e. one containing the words "no", "not" or "don't") would swap the meaning and cause the checkmark to actually say no! This is confusing and should be avoided. In the screenshot below, the three marked CheckBox Gadgets are badly designed controls:
5. Wrongly used Chooser Gadgets
Choosers are popular GUI controls because they can display many options yet take up very little space. Being popular also makes them prone to being misused in user interface design.
A Chooser Gadget is a little less intuitive than a RadioButton Gadget: you need to pop up or cycle through the Chooser options whereas the RadioButton shows them all at once. The trade-off with the RadioButton Gadget is that it requires more room. So think in context of your particular GUI: unless you fight with space constraints, prefer RadioButtons for choices with up to three or four options. Use the Chooser for longer option lists.
Never, ever use a two-label Chooser Gadget for an on/off setting: use a CheckBox instead. The blooper example below shows Exchange, an AmigaOS component that controls commodities. It features a Chooser Gadget with two options, "Active" and "Inactive", which is a pair of logical opposites and, therefore, a clear binary relation. It's a two-state switch, so it should have been implemented as a CheckBox Gadget (or, alternatively, as a push button) but definitely not as a Chooser.
Don’t use choosers to flip layout pages in Page Gadgets. If you have a multi-page layout and cannot use a ClickTab (which is preferred and designed to work with pages), use a ListBrowser or, as your very last resort, a RadioButton Gadget. They are better, more intuitive solutions because they show all available “page links” whereas the Chooser would hide them and only show one. Generally, prefer using Choosers to set attributes, not to trigger actions.
PROBLEM AREA 3: Keyboard control
6. Lack of keyboard shortcuts (hotkeys)
Keyboard access to main program features and common functions speeds up workflow and makes power users happy. Use the menu system and/or BOOPSI’s GA_ActivationKey tag to help you set up the shortcuts – both methods are easy. Some shortcuts are standardized, even (also see below in section 8). Guess what is missing from the following program menu?
Hotkeys for requester buttons should also be provided. Requesters require user interaction: they “get in the way” and can slow down workflow (also see section 15). The user would therefore appreciate requester buttons having keyboard shortcuts (unless there’s a good reason not to provide them, such as safety of operation).
7. Waste of mnemonics
On the other hand, it’s not necessary to provide keyboard shortcuts for every single function in your program: the user wouldn’t be able to remember them anyway! Plus, keyboard shortcuts work best if they are mnemonic: “S” for “Save”, “P” for “Print”, etc. Therefore, save handy mnemonics for common and really important functions, don't waste them on secondary features. For example, many AmigaOS 4.x prefs editors implement shortcuts for on/off settings that rarely need changing: the user would use the shortcuts perhaps once or twice in life. This is a complete waste:
8. Non-standard hotkeys for standard functions
According to the Amiga User Interface Style Guide (now available and being updated through the AmigaOS Documentation Wiki), you should use the menu system to implement at least the following hotkeys (provided that your program implements the respective functions):
RightAmiga+A Save As...
However, some programs disregard this and implement different mnemonics. For example, the About requester is invoked through RightAmiga+V in Snoopy, RightAmiga+I in ADRipper and AppManager, RightAmiga+A in CodeAudio and ffmpegGUI; many programs don't implement a shortcut at all (DvPlayer, VICE, GoldEd, AmigaWriter...). Hotkeys for Undo make a similar story: I've seen RightAmiga+Z (the correct, reserved and cross-platform mnemonic) as well as RightAmiga+U (NotePad, CygnusEd), even RightAmiga+8 (GoldEd).
It is now also becoming apparent that a revision of the reserved shortcuts is necessary. Above all, there is no standardized hotkey for Iconify, a function now present in most applications: some programmers implement RightAmiga+I while others seem to prefer RightAmiga+H ("Hide"). Also, RightAmiga+A as a reserved shortcut for "Save As" is highly debatable – the mnemonic would be better suited for "Select All"-type operations, as it is usual on other operating systems.
PROBLEM AREA 4: Layouting
9. Crowded or messy layouts
Too many gadgets or gadget groups make GUI layouts crowded and difficult to find things in. Use the clicktab and put related things in separate pages. Gadgets that are related should be grouped together and some kind of visual correspondence – such as common alignment – should be established between them. The following two screenshots are from ClassMate, an old GUI builder for the ClassAct toolkit. It's an irony that a program that was supposed to help you build GUIs has one of the clumsiest user interfaces I've ever seen. The screenshot on the left shows a group of gadgets lacking alignment; the one on the right shows a selector window in an implementation that I still can't quite believe (also note the lack of distance/separator between the "Cancel" button and the other gadgets):
10. Unrelated grouping
Gadgets that bear no functional or logical relation should not be placed in one group. An obvious offender is the AmigaOS ASL requester. As you can see, it puts four buttons in one horizontal group despite their having different function and scope of operation: the "OK" and "Cancel" buttons control the entire requester whereas "Volumes" and "Parent" control the file list. Their grouping is illogical, and the "Volumes" and "Parent" buttons should be placed adjacent to the file list.
Window control buttons (the "Yes/No/Cancel"-type buttons typically found at the bottom of the window or requester) should always make an independent group, separated from the rest of the GUI by a space or a divider).
11. Localization blindness
Your program may get localized at some point (if not right from the start). When designing the GUI, take into account that localizable text labels can be of variable length (depending on language) and, therefore, gadgets can grow really wide. Be careful when putting gadgets next to other gadgets: prefer stacking them vertically. You can get away with a row of four buttons (see below left) because button labels tend to be short. However, other gadgets (checkboxes for example) may use longer, more descriptive labels so avoid placing them like in the screenshot on the right:
12. Too much scalability
ReAction GUIs are scalable: gadgets (can) change their size depending on current window sizing. However, when there’s no real benefit to be gained from resizing, limiting scalability is preferred. Look at the following screenshot below, which shows two individual pages in the Preferences window of Debug101, my favourite code debugging tool. The pages only contain RadioButton and CheckBox gadgets, that is, gadgets whose imagery never grows in size in a resizeable window. Therefore, vertically resizing the window makes no practical sense here because the gadgets would get scattered across the window and lose visual relation. Such a resized window would only waste valuable screen estate. So it would make a good sense to limit the vertical scalability by passing WINDOW_LockHeight, TRUE in the window definition.
PROBLEM AREA 5: Navigation / Interaction
13. Program doesn’t indicate it is busy
When your program goes into a busy state (i.e. executes an operation or function that blocks further user actions), display a busy pointer. Do not assume that the operation will be too quick for the busy pointer to be worth showing: the user's system can be slower than yours, or it might have become temporarily less responsive due to a CPU-consuming task running in the background. If you're afraid that the operation will execute so quickly that the pointer change will go unnoticed, use WA_PointerDelay, TRUE in your window definition to prevent extremely short flashes of the busy pointer.
It may not be so obvious but busy pointers also have a navigation function. How's that? If you click on a window and it shows you a busy pointer, it in fact says "You cannot use this window at the moment, there's some other window that needs your attention." This is an important navigation clue, so when opening a requester or a subwindow that requires user input before the program can continue, display a busy pointer for its parent window. That Amiga windows should always be non-blocking is a myth.
(ReAction programmers should take note that the busy pointer is supposed to be set through SetAttrs() on the window object, not by calling SetWindowPointer() or SetWindowAttrs() – the latter two functions are meant for non-BOOPSI windows.)
14. Annoying requesters
A confirmation requester is, surely, a safety measure but it gets in the way and slows down workflow. If you want your software to be hated, look no further and sprinkle it with requesters! Now seriously. Do not require confirmation for actions that pose no risk, or at least make the request configurable. If your program does not create any data (a calculator, a dictionary, a media player etc.), do not ask "Do you really want to quit?" before you... erm... quit. Should the user exit from such a program by mistake, he/she will start it again, no biggie. Just don't treat them as idiots who hit buttons randomly and do not know what they are doing.
And, there's a better way: the current trend in software design is a universal Undo function, i.e. one that does not apply to edit-type functions only. If there's a way to always take an operation back, who on Earth needs confirmation requesters? Food for thought maybe.