Last time, I started to get into why ContainerControls are useful and hinted at designing a class from scratch that you can drop into your own projects. Today we'll begin to design this class. Before we begin, let's talk about what sort of functionality we expect from the project.
The problem is that OK/Cancel button orders are different on Mac than they are on Windows and Linux. So we want to design a class that abstracts this information so you can focus on the purpose of the interface, not the esoteric platform-specific details. The things our class should automatically do for us is:
- On Windows and Linux, OK should be on the left, Cancel should be on the right. On the Mac, OK should be on the right, Cancel should be on the left.
- The OK button should be the default button. The Cancel button should be the cancel button.
- The tab ordering should be correct no matter which platform the UI is running on.
- Automatically position the OK/Cancel buttons in the proper location on the window. This feature should be optional so that we can override it if we want to control the position of the group manually.
- The user should only have to deal with four events -- Open, Close, the OK button is pressed, and the Cancel button is pressed.
- The user should optionally be able to rename the buttons, but their captions should be correct by default.
So now that we have our list of design requirements, let's get started!
First, in the Project Items editor, we're going to add a new ContainerControl (via the toolbar item, or the Project->Add menu) and name it OKCancelButtonGroup. Then, double click the newly created ContainerControl to go into the window editor.
The first thing you'll notice is that there's no frame, even though we're in the "window" editor. That's perfectly normal -- this is a ContainerControl after all, not a window. But the terminology and UI can be slightly confusing if you're not expecting it.
Our first task is to put a pair of buttons onto the window. So drag a PushButton onto the upper-left corner of the window, at position 0,0. Then duplicate the PushButton, and position the second one directly to the right of the first one, at position 92, 0. Then resize the window so that it's 172 pixels wide, and 20 pixels tall. If you've followed along correctly, the window should exactly encompass the two buttons.
Now, let's make sure the buttons are in the proper state. So name the first button OKButton, and set the Default property to true and set the Caption to "OK".. Then name the second one CancelButton, and set Cancel to true, and set the Caption to "Cancel".
Congradulations! You've just made your first ContainerControl!
You can test it out by opening up Window1 in the project, and changing the controls palette list to be "Project Controls." In that list, you should see "OKCancelButtonGroup" -- drag it to the window and run the application. You'll see both the buttons from the container control.
Next time, we'll begin to implement some of our design specifications so that our control is useful.
"On Windows and Linux, OK should be on the left, Cancel should be on the right."
I'm not sure about that. In Gnome, I see OK on the right quite a bit. Hmmm... I'll have to look in the Gnome UI guidelines when I get a chance.
Sure enough:
http://developer.gnome.org/projects/gup/hig/2.0/windows-alert.html#alert-button-order
Hmm... make that Windows only, then?
You're right, I found it here as well: http://developer.gnome.org/projects/gup/hig/2.0/windows-utility.html#windows-explicit-apply
So I think it'd be Windows-only at that point. Interestingly enough, KDE is not explicit about it, but seems to follow the Windows guidelines.
Sure enough, KDE does follow the Windows-style button ordering. A good topic for Part Two or Three... how to detect if you're on Gnome and adjust accordingly!
Crazy Windows!! At least Gnome got it right...
"Crazy Windows!! At least Gnome got it right…"
No kidding.
@Adam -- interesting idea. To be honest, I've never looked into how to determine which window manager is running.