[prev] [up] [next]

GUI Coding Guidelines

Contents

Introduction & Motivation

This document describes mandatory rules for UI coding. These are obligatory for new code.

In order to provide a consistent look & feel to ST/X users, it is mandatory that UI components (widgets, windows, tools) follow common guidelines. Especially for new users, it is very inconvenient, if the layout and/or position of common controls or the naming of operations is non consistent.

In the past, a lot of code (especially from third parties) has appeared, in which the personal preferences of the programmer affected the graphical appearance, and it takes a lot of work to fix such issues later. This document shall prevent this as much as possible in the future.

Old Code

There may be old code in the system which does not in part or fully follow those rules. This is not an excuse for new code to not follow those rules. If you come along old code which does not follow this guideline, it should be changed, if it can be done with reasonable effort and you have nothing else to do.

Typing

Please care for proper english typing both in UI widget texts (labels, buttons, etc.) AND in the program. Typing errors in the program (especially in message names) make it *very* hard to find senders/implementors unless the searching programmer knows the typo.

For example: method names like "removeContaines" (instead of "removeContainers") makes it almost impossible for someone to find all manipulations of "containers" by searching for "*container*".

Performance / User Response

Awoid the following:

Ensure that your algorithms scale

Not only test your app with a small number of data elements; also test it with bigger amounts of data.

For example, a list of MP3 files may be shown fast if it contains 100 music files, but how does it behave if there are 100000?

This error seems to be very common - even in many TV sets and Satelite receivers with network support, users have to wait minutes to get their lists shown

As a concrete real-world example of a very bad UI:
I have to wait minutes on my brand new Samsung TV's builtin mp3 player, which gets its playlists from a networked storage device because I do have 100000 mp3's there. The builtin software is just plain stupidly programmed: when ever I navigate back from a subfolder to its parent, it scrolls back to the beginning, closes all open subfolders and starts to read the list from the network drive again. Whenever I stop playing a song, to navigate back to the playlist, it rereads the whole list (from the nework), closes the folders, ...

The whole Samsung's builtin MP3 player is therefore completely useless (and was obviously written by a total beginner)

Cache the data!


If the user has to switch between lists, make sure that you cache the previous one, so he does not have to wait again, when returning back to a previous view/list/directory. A bad example is again my Samsung TV, which reloads the complete 10000 title list from the cloud server, after I look at the details of a song. This can easily take up to 15seconds!

Remember where the User came from


Wheb navigating in a tree, and the user returns back from a sub-application, dialog, play program or editor, scroll to the previous position in a long list, and reopen folders to the state they were before. Do not return to the top of a list, if the list can get longer than 20 items. Again, the Samsung TV shows how not to program a UI.

Ensure that your UI scales

Again the TV set: clicking on a remote control through a list of 50 items in a list of music titles may be ok, but who wants to scroll through 10000 items? And because it does not remember the previous scroll position, I have to start over at the top of the list, after a title's details have been shown! Think of quick navigation, search functions, remember previous entered search strings etc.

Looking at how bad some UIs are, makes me believe that the programmers (or the product managers) actually never ever tried their product before deploying.

Give feedback

Always show at least a busy cursor, if the app is busy. If possible and useful, show a progress bar. Never ever remember mouse- or keyboard clicks, during a long running operation: the user might think that the previous click was not working and may try again instead of waiting. If the new click is already recorded, it may later be associated to a function (button) which was not anticipated.

Again, one of my TV apps is a good example: the maxdome UI does not give any feedback, and some clicks take tens of seconds for the UI to react. If during that time I click on the remote again, that click may (after 20 seconds) be associated to a back buctton, which appears after that long pause. And I am back, and have to start again.

Layout

General

The layout of widgets within an application or dialog should be logical and estetically pleasant. Elements must be grouped logically and consistent with the way the rest of the system is organized.

OK - Cancel Buttons in a Dialog

All dialogs must have at least a cancel button. Buttons must be in a horizontal panel at the bottom. All such panels MUST have the following attributes:

Button Order

(in the UI spec): OK button(s) at right, Cancel at left. Set the "reverse order if OK is at left" flag.

If there are multiple OK-like or Cancel-like buttons (like "OK for all", "Cancel for all"), the "most-positive" OK-Button is at the far right, the most negative "Cancel" at the far left". I.e. a "CancelAll" is leftmost, then a "Cancel", then "OK", then "OK for All".

Reason: This, together with the "reverse order if OK is at left" flag ensures that the buttons will appear in the windowing system's natural order. (i.e. it cares for differences between windows, linux and OSX, by reversing the order if and only if the underlying window system requires this). The "reverse order if OK is at left" flag is interpreted by the panel widget, and it will do exactly what it says.

Without this setup, you application will look wrong on at least one of the above mentioned operating systems.

Height & Position

30 pixels at the bottom of the dialog

Reason: have a common look and enough height for larger fonts (Xft).

Layout

Use the new #okCancel layout. This will dynamically be mapped to either #fitSpace or #rightMax, depending on the native window systems natural look.

Reason: have a common look which looks "natural" on each window system platform. If future or other systems use any special layout, we can easily change the horizontal panel class to whatever is needed. (for example, to maxCenter or similar).

Flags

OSX-resizeH (leaves space for any window manager resize handle)

Reason: some window systems (OSX) place a resize handle over the lower right edge area of EVERY top window. The OSX-resizeH flag changes the layout so that this area is unused by the widget, by giving the widget (in this case: panel) a -16 right offset. The flag is ignored if running on windows or linux. Thus, we get a good looking box on all systems. No other solution is allowed here, as it will always look bad on either system.

You MAY NOT

Non-Standard (explicit) Colors

You MAY NOT:

Non-Standard (explicit) Fonts

You MAY NOT:

3D-Level and Borders

You SHALL AVOID:

Tooltips

You MUST: You MAY NOT:

Prepare for OSX

As already mentioned above, OSX needs a 16x16 pisel area at the lower right of every top window. It will unconditionally draw its resize handle over that area. So we better make sure, that nothing useful is located there.

This affects mostly three situations:

The first two of the above MUST set the "OSX-resizeH" flag (in the UI-painter's layout). So the panel will get a right inset of 16 pixels.

The other should set the "OSX-resizeV" flag of its scrollable view, which passes this flag down to its vertical scrollbar. So the scrollbar will get a vertical inset of 16 pixels. This scheme currently only works if the vertical scrollbar is at least 16 pixels wide.

Notice: do NOT hardcode an inset at the lower right - if you do so, you UI will look ugly on non-OSX systems. The above mentioned flag will dynamically use an inset of either 16 pixels (on OSX) or zero, if on non-OSX.

Sizes of Labels (and Buttons)

Be prepared for longer labels in other languages

Always add some 25-30% in size to the english text. Other languages (German and more so French) usually are a bit more redundant and therefore require more space than english.

Be prepared for font size differences

The windows fonts are a bit denser than the corresponding Linux fonts. Add another 20% when designing the UI in windows.

Let the layout be computed dynamically

If possible, place buttons in a large enough Panel, let the buttons compute their size and the panel arrange them. In many cases, a *Max* layout looks better. This lets the panel compute the size of the widest button and resize the others to that size.

Put multiple, vertical arranged elements into a VPanel

This allows for each element to become larger, in case the user chooses a bigger font.

Test it!

There is no automatic unit test for "Has a pleasing look". So try your UI under windows and linux. Also, change the font settings to a (say 20pt) font and see if it looks ok.

Initial Size of Dialogs

Avoid Fixed Extents or Small MaxSize Limits

Many real world dialogs have a fixed size (or way too small max size). Especially the native Windows UI (from Microsoft) often presents boxes - even list selection boxes - with a too small extent. Small listboxes are especially inconvenient - why would any end-user like a 4-line list, on a 30 inch display?

Reflect your own use of the UI

Watch your own behavior - if a dialogs regularily comes up too small and the first thing you do is to resize it, make it a bit larger right from the start.

This applies especially to selection-in-list views inside a dialog. There is no reason to make the list only (say 4) lines high, if the overall dialog is only taking up 1/5 of the screen height. Unless the list is actually only showing a very small number of items.

Remember the last size

Many apps and dialogs remember their size-on-close in a class variable. And come up with this default size the next time. That is a very convenient behavior and you should also implement it. (it is now done on the AppModel-level automatically for you, if the user has checked so in his preferences). But for some hand-crafted ad-hoq dialogs, you have to do it manually.

Variable Panels

If there are multiple lists and/or a list and text-editor in a dialog/app, always put them into variable panel. Think what a good initial fraction might be. The UI painter saves the fraction at construction time as default to be used when the app is opened - so always go into the test-geometry mode, adjust for a nice initial fraction and save it.


Copyright © 2014 Claus Gittinger, all rights reserved

<cg at exept.de>

Doc $Revision: 1.16 $ $Date: 2021/03/13 18:24:51 $