Tabbed Windows

Unless all of the screens in your application contain only a few fields or you are happy to have enormous forms all crammed full of fields, one of the first problems you're going to run into with your UI design is how to present the data to the user in small, clearly understandable chunks. Depending on the function of the screen involved, there are a number of standard ways of achieving this separation - wizards for task orientated screens, property sheets or Outlook style shortcut bars / tree views for data orientated screens.

We've been using the standard ADM2 folder.w smart object to implement all of our property sheet style forms on my current project, but recently I've been working on the design of a window which was going to stretch the folder smart object to it's limits, and it turns out that it doesn't stretch very well. The window in question will be the primary user window in the application and, as such, it pulls all of the data from various parts of the system together to be presented to the user in one place. In other words, it's going to be one busy window. We're already looking at somewhere between 20 and 30 different pages of data and this is where folder.w starts creaking. There's a hard coded limit of 32 pages to the default smart object, although this is easily modifiable - there a pre-processor definition, max-labels, in the definitions section of folder.w. No, the real problem is how the folder presents a large number of pages to the user. It makes pretty much no attempt to gracefully handle a folder instance which contains more tab labels than can fit in the current window. It simply re-sizes the instance to the required size in the process developing scrollbars, so what you end up with looks something like this -

Ignoring just how aesthetically unpleasing this is for the moment, with 20 pages it's also completely impractical as well. You'd have a virtual tab folder which is three or four times the size of the actual viewing pane, so if you wanted to switch from a tab at one end of the list to a tab at the other you'd be scrolling for a long time. It wouldn't be long before any user got frustrated with that. And scrolling forms are one of the easiest way to uglify any application quickly. So we started looking around for alternative approaches and examined how other applications handle this kind of problem. The first idea up for grabs was multiple rows of tabs. Something like this ( from MS Word ) -

There's a couple of things worth pointing out about the way that the MS Word dialog handles multiple rows of tabs. Firstly, notice how the top row of tabs in the screenshot have been justified to use the whole width of the dialog. This means that when the user clicks on any of the tabs in the top row, the two rows simply swap position as both rows are exactly the same width. I've seen some implementations of the multi-row tabbed window which had rows of varying width. What would happen was that when a specific tab was moved to the front row, the composition of the row would be re-calculated in order to ensure that the front row was always at least equal widest. In other words, the position of tabs would change both horizontally and vertically. Justifying the width of the rows removes the possibility of tabs being repositioned horizontally - "File Locations" will always be at the right hand side of the dialog- but they can still be repositioned vertically.

The second point is that although Microsoft have gone for a multi-row dialog, they have still resisted the temptation to throw too many pages into it. The designer conjured up separate dialogs, with their own menu items, for toolbar customisation, templates, add-ins, style sheets and auto-correct each of which could have arguably been classified as "Options". I believe that the reason that they held back on the number of tabs is that users just can't handle more than about ten tabs on the one screen. Although you may not realise it, as you're learning to use a piece of software, you're also subconsciously learning the locations of various buttons, menu items and tabs within the windows you are using. Think about it, where is the "Procedure Settings" button in the Appbuilder relative to the "Run" button - is it to the left of the right? If you use the Appbuilder every day, you would have known the answer to that question without having to check, even though you've never actively learned the position of the buttons. This kind of subconscious learning is critically important to the user's level of comfort with and acceptance of any application.

Which is where a large number of tabs becomes a real problem. Tabs have no inherent order to allow your subconscious to learn where to find them, the brain can maybe cope with up to ten but if you go much beyond that and you use multiple rows so that the tabs keep changing position, you'll never be able to "learn" the interface. Every time you want to change tab, you'll find yourself scanning through each of the labels in turn looking for the tab you're after. Even if you don't realise this is going on ( and most users won't ) you'll find yourself becoming frustrated with the layout of the application.

Given that we were talking between twenty and thirty pages in our window, we'd probably have been looking at three to four rows of tabs as long as we kept the descriptions terse. It would have been a pretty confusing screen, not to mention the fact that we'd lose about 80 pixels off the height of the screen, assuming approximately 20 pixels per row. Scratch multiple rows.

The next idea that, briefly, came up for consideration was from another Microsoft product. The Visual SourceSafe designers obviously ran into the same dilemma when they were working on the UI for the options dialog for their product. What they've done is a little nicer on the eye than the scrollbars in the first screenshot, but just as problematic.

The left and right icons / spinbox to the right of the screenshot above are effectively scrollbars. Click on the right arrow, brings the next tab into view, shuffles all the other tabs one place to the left and drops the left most tab. So, although it looks better than the scrollbars, if you want to go from the first tab to the twentieth, you're going to have to click that right arrow button a lot of times. Scratch that idea.

So it was starting to become apparent that we needed to do something more fundamental that finding a different way of arranging the tabs. The decision that we eventually came around to was to move away from tabs altogether. After all, in the ADM2 world, tabs are simply a user interface which allows the user to select which page is visible. Look at the code in folder.w. The code which gets executed when the user clicks on one of the tabs is held in the procedure label-trigger and it all boils down to something as simple as this -

RUN selectPage IN container-hdl (INPUT p-page#).

From a Progress perspective, it could just as easily be a fill-in which prompts the user for a page number, although this would be a poor interface. So we experimented with different ways of representing pages. A simple combo-box was the most compact option we came up with, but we eventually decided to go with something like this -

As you can see, we've used a selection list in place of the tabbed folder. Each page is represented by an entry in the selection list and clicking on the individual entries triggers a page change. There's a number of different things I like about the selection list approach -

  • It can handle a lot of page labels. Without any kind of scrollbars you will be easily able to fit thirty entries in the selection list all of which will be immediately visible to the user
  • It's learnable. We sort the tab labels alphabetically so the user can now subconsciously learn that the "User Information" page label is always towards the bottom of the selection list, irrespective of which page is currently being viewed.
  • It's compact and doesn't take up a lot of screen estate. Also, the space that it does use detracts from the width of the form rather than the height. The vast majority of monitors are wider than they are high, so if you're going to loose space to a page selection mechanism, it makes more sense to loose the space from the form width.
  • It can be used in combination with standard tab chooser to give you a whole extra dimension of pages. Pages within pages, so to speak. To implement the screen pictured below, I inserted a smart frame into a smart window which also had a selection list page chooser. Then within the smartframe I've used the standard chooser and inserted other smart frames onto separate pages. I'm not really sold on the result, I tend to think that it would be a better idea to simply add more pages to the original window in most instances, although I can see occasional uses for such a screen.

Having said that, nothing is perfect and there are definitely a few drawbacks to using a selection list -

  • It's inappropriate for a small number of pages. A selection list which runs the whole height of the window but only contains two page labels could probably be considered overkill. I would ( and do ) continue to use the standard page chooser for all but my busiest screens.
  • The standard methods available in folder.w allow you to enable / disable each of the page labels individually. It's not possible with a selection list to disable only certain of the items, so I've not been able to implement these methods in my new object.

So there it is. I'm pretty pleased with the result, it's certainly a lot better a design than using some form of tab representation, and of course we were able to wrap it all up into a single easily maintainable, re-usable smart object.

Build the Smart Object

...was a relatively straightforward affair. I simply copied the existing folder.w routine to a new file and then worked through each of the methods re-working them to use the selection list rather than the dynamically created images. A quick change to smart.cst and I had a new entry in my palette. To be honest, I removed a lot more code than I added. I'd like to share the source with you, but as I built this routine for my current client the source code isn't mine to share. Which is a great excuse for you to go and build one for yourself, it should only take a few hours. If you get stuck, drop me an e-mail and I'll be happy to help out.

Further Reading / Links

If you are interested in doing multiple rows of tabs within the ADM2 framework, Michael Caroll's SmartPak contains an excellent implementation of such an object. You can pretty much plug it into your existing development environment and start using it in place of the standard folder. You can download the SmartPak here.

 

 

What's New