Designing an OK/Cancel button ContainerControl (Part Two)

| | Comments (0)

Last time we began to design a ContainerControl so that we can automatically handle the platform differences (between Mac and Windows/Linux) with an OK and Cancel button's placement on a window. If you haven't read the last article, you should go back now and read it before continuing on.

Today we're going to begin implementing our design specifications for the control. If you'll recall, we need to implement the following:

  • On Windows and Linux using KDE, OK should be on the left, Cancel should be on the right. On the Mac and Linux using Gnome, 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 let's dig right in and tackle these issues one at at time!

The first issue we need to solve is to get the OK and cancel buttons in the right location depending on the platform. To do that, we need to open up the code editor for the OKCancelButtonGroup class, and go to the Open event. We're going to use platform switches to move the buttons around. We do it this way (instead of renaming buttons) so that the user is working with the "proper" button based on the name. Remember, we named the one on the left OKButton, and the one on the right CancelButton -- so if we just swapped the captions, then the user would get an OKButton.Action event called if the user pressed the Cancel button depending on the platform! So your code should look something like this:
[rbcode]
#if TargetMacOS
dim oldLeft as Integer = OKButton.Left
OKButton.Left = CancelButton.Left
CancelButton.Left = oldLeft
#endif
[/rbcode]
If you run your application on Windows, you'll notice that nothing's changed -- OK is on the left and Cancel is on the right. This is exactly how we want it (which is why we don't have a #else clause in our code -- things are already setup correctly for Windows). However, if you run the application on the Mac (possibly via remote debugging, which is how I do all my platform testing), you'll notice that the OK button is now on the right instead of the left. Great! We still haven't solved the window manager issue, but we'll get back to that later.

We've already gotten the second design point done -- the OK button is the default and the Cancel button is cancelable. So we're just moving right along!

However, the third point is a problem. If you turn full keyboard access on while on the Mac, you'll notice that the OK button gets the focus first, even though it's on the right. Another thing you'll notice is a clipping issue with the cancel button due to the fact that the focus ring is outside the control's bounds on that platform. Let's quickly handle the redraw issue by going back to the Open event and adding two to the ContainerControl's height. So now your Open event should look like this:
[rbcode]
#if TargetMacOS
me.Height = me.Height + 2

dim oldLeft as Integer = OKButton.Left
OKButton.Left = CancelButton.Left
CancelButton.Left = oldLeft
#endif
[/rbcode]
However, this still leaves the problem how how to deal with the tab ordering on the Mac. Unfortunately, there's no easy way around the issue since you cannot set the tab ordering of controls on the fly. Tab ordering is hard-bound to the order in which the controls are created, so we're stuck -- or are we? Next time we'll see how to solve this issue in the most elegant way available to us.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.