Design tips

When designing your applications to be cross-platform, you should keep in mind the differences in user interface across the different platforms. An application that is well designed for Windows may look drastically out of place on Mac or Linux. And vice versa.

The Preferences menu item

Similarly, the Preferences menu is also located in the Application menu on Mac. On Windows and Linux, the Preferences menu is often located in the Edit menu and is instead called “Options”.

There is always a fixed Preferences menu in the Application menu on Mac, but is is disabled by default. To attach your Preferences menu to it, you set its Super property to DesktopPreferencesMenuItem. Only one menu in your project should be set to DesktopPreferencesMenuItem.

To change the name of the Preferences menu for Mac and Windows/Linux, you use a constant. By default there are several constants on the App class that control the text for Edit > Clear/Delete and File > Quit/Exit. You can add another to handle preferences.

To do so, add a new constant and call it kPreferences, setting its default value to "&Options...". In the Constant Editor, click the “+” to add a new entry and select “macOS” as the Platform. For the Value, enter "Preferences..."

This creates a constant that uses the value "&Options..." on Windows and Linux, but the value "Preferences..." on Mac.

Now that you have created the constant, you can use it as the text of the menu. Add a new MenuItem to the Edit menu and set its Text property to “#App.kPreferences”. This tells it to use the value of the constant. Also set its Super to “DesktopPreferencesMenuItem”.

You can use the preview buttons in the Menu Editor toolbar to see the text change between Mac, Windows and Linux. In addition, when you run the application on Mac, the Preferences menu appears in the Application menu instead of the Edit menu.

Dialog buttons

Perhaps you have never noticed it, but when you use a dialog box on Windows and Linux, the buttons are in a different order than they are on Mac. On Mac, the default OK/Cancel buttons display as Cancel followed by OK. On Windows and Linux they appear as OK followed by Cancel.

For your applications to look proper on each platform, the buttons should appear in the appropriate positions. The easiest way to do this is to us a DesktopContainer to swap the buttons for you at runtime. The example project OKCancelContainer in the Examples/Topics/User Interface/Desktop/Custom Controls folder demonstrates how to do this.

  • Examples/Platforms/Desktop/Custom Controls/OKCancelContainer

Fonts

Normally you will use the System font as the Font for your controls. This tells your application to use the default system font for each OS as the font for the control. As you might expect, the default system font varies by platform and sometimes even by updates within a platform.

This means that some controls may end up being too small on some platforms to fit the text you provided. It is important that you run your project on each platform and review the layout to make sure that everything is readable and fits as you expect.

You may find that you need to increase the size of some controls so that they display properly on all platforms. You can do this in the Layout Editor by increasing the size of a control. Or you can do it at runtime by increasing the size of the control in its Opening event depending on the platform being used (using Conditional Compilation). For example, this code in the Opening event handler of a DesktopButton increases its size when running on Linux:

#If TargetLinux Then
  Me.Height = Me.Height + 20
#Endif

Windows-specific tips

Linux and Mac use a technique called double-buffering for all window drawing. This means that updates to a window are done offscreen and then shown on the actual screen in one update. This results in stable, flicker-free windows and graphics updates.

Windows, however, does not use this technique. The Xojo desktop framework attempts to minimize this for you. Below are some general tips that will help your Windows apps look their best.

Do not overlap controls

The easiest thing you ensure a rock-solid UI is to not overlap any controls. Overlapped controls result in more requests to redraw the controls which will be slower and can sometimes result in flickering.

Use a Canvas

For best results, display any graphics using the Paint event of a DesktopCanvas control. Stay away from using the Window Backdrop property, the Window Paint event, the Canvas.Backdrop property or the DesktopImageViewer control. Although those techniques work fine in certain situations, in more complex window layouts a Canvas gives you more control.

You can have separate methods that update the graphics, but they need to be called from the Paint event with the graphics object supplied to the methods as a parameter. Another technique is to have a Picture property that you use to draw you graphics to and then in the Paint event handler you draw the Picture to the Canvas to display it.

When you want the Canvas to update itself, redrawing any changes to your graphics, you call the Refresh method:

Canvas1.Refresh

or

Canvas1.Refresh(True)

Passing True tells the Canvas to update itself immediately. Otherwise, the Canvas will update itself when it gets a redraw request from the operating system. Normally you want to use Refresh without the True parameter as it results in fewer draw requests, improving performance and reducing any flicker.

By using these techniques, you can create a stable UI and graphics in your Windows applications.