Desktop UX - How I Escaped Cluttered TabControls
This week's Desktop First UX Summit, hosted by Embarcadero, is a great collection of presentations by leading software development and design professionals sharing the theory and practice of creating great desktop experiences. I really appreciate the focus on desktop app design--not everything is mobile or web. One of my favorite speakers every year is Ray Konopka and he gave another great talk, this year on How Tab Controls Can Ruin Desktop UX. It reminded me of an application I wrote many years ago that turned into the exact same ugly point of confusion and frustration he showed--and how I changed the design in my app for better usability.
A lot of desktop apps I have written were for a company that built back-end file and database integrations for point-of-sale applications, either importing orders from a website, exporting shipping information, looking up customer membership in a web service, or synchronizing inventory between two different systems. Some of the first few projects were simple or the ideas were new, so many things were hard-coded. File paths and FTP locations were configurable but many other aspects of the projects were simply built to spec. The few options I surfaced were put in configuration screens and, like many other developers, the TabControl made grouping options while saving screen space a natural choice. When these option groups were few in number, it worked really well.
Over time as I saw patterns emerge from project to project, the specs got more complex, and I built more flexibility into a library of integration routines to save myself from rewriting so much code, the number of configuration options grew as well. With increasing workload we tried to make things efficient but never really had time to stop and redesign everything (it's always like that, isn't it?). Then on one project, I hit the point where there were too many tabs and the tab rows started jumping around when I clicked on one that wasn't on the "front" row--that's when I decided the interface had to change.
By this time, the company had seen so many custom integrations and there were so many similar requests, we decided to write one big program with lots of options that would cover all situations and save ourselves from writing all these custom projects. License codes would turn certain features on or off and hide irrelevant options. It was good in theory but resulted in configuration nightmare--and we still ended up with custom requests beyond that so I'm not sure how useful it really was in the long run. But it did give us a chance to rethink the design a bit.
The interface I switched to got rid of the typical "File" menu and used CategoryButtons on the left side that I prevented from collapsing (I didn't want to use the "ribbon" or "outlook bar" styles for menu options). Instead of pulling up a dialog box for configuration options, I simply hid the main CategoryButtons menu and showed a smaller one with just Save and Cancel. And instead of a TabControl for grouped configuration options, I found a couple of visual components in the JVCL that worked pretty well together. These were the TJvPageListTreeView and TJvPageList. The JvPageListTreeView has a visual designer for items in its tree view and then allows you to link pages from an associated JvPageList. That was pretty slick in that I didn't have to do any coding for selecting different configuration screens when the user selected a different group but any change to the list meant re-mapping all the page links (most of the time) which was a pain.
Eventually, I came up with a better plan. I ditched the JVCL components and now simply use a ListBox and a PageControl where the pages are in the same order as the items in the ListBox (which makes switching pages very simple). Also, instead of putting all functionality and all options in one big program, I put the various integration pieces along with their options in separate DLLs and load them at runtime as plugins. That way, every program I distribute is custom but put together with a bunch of pre-built plugins, keeping all functionality separate but allowing me to put as much or as little functionality in the program as needed for a customer by simply adding a few plugins in the InnoSetup script (well, it's a little more complicated than that). Each set of configuration options conforms to a standard interface, is tested separately and adds it's own screens to new pages in the PageControl seamlessly.
No more jumping tab rows!