Typically, most of a Desktop app’s user interface will be in its windows.
You create your user interface by adding interface controls such as Buttons and Check Boxes to windows. By default, a Desktop project has one window (Window1) that is displayed automatically when the app runs. Typically, you will begin designing your app’s interface by adding controls to this window and then by adding code to the events of the controls and perhaps the window itself.
To add additional windows to an app:
Add a new window to the project by clicking the Insert button on the toolbar or menu and selecting Window.
Set the window’s Type and other properties using the Inspector.
Add controls to the window from the Library.
Add code as needed.
Add code to display the window in the finished app.
Below is a list of commonly used Window events, properties and methods. Refer to DesktopWindow for the complete list.
CancelClosing - Called when the window is asked to close. Return True to prevent the window from closing. This can be a useful place to display an “Are you sure” message.
Closing - Called when the window is actually is closing. This is a good place for cleanup code.
Opening - Called when the window is opening. This is a good place for code that initializing the window.
MenuBar - The menu bar that is displayed when this window is front most. If no menu bar is specified then the menu bar specified in the App object is used.
Title - The text that appears in the title bar for the window.
Type - The type of the window. The different Window Types are described below.
Your Desktop apps can have several different types of windows. The window type is set by its Type property. Some types, however, are rarely used in modern apps and are retained only for historical reasons and backward compatibility. A few specialized windows are supported only on Mac.
The specifics of how a window looks on each OS tends to vary over time as OS vendors change themes and their overall look-and-feel. Be sure to test your apps on all platforms you ship with to verify you get the behavior you want.
The Document window is the most common type of window. When you add a new window to a project, this is the default window type. It is also the window type for the default window, Window1. Document windows are most often used when the window should stay open until the user dismisses it by clicking its close box (if it has one) or clicking a button programmed to close the window. The user can click on other windows to bring them to the foreground, moving the document window behind the others.
Document windows can have a close box, a minimize box, a maximize box, and can be user-resizable.
You can display document windows using the Show method:
On Windows and some versions of Linux, the default menu bar, MainMenuBar, appears within the window by default.
You can choose to display the window with no menubar by setting the MenuBar property of the window to None, although this is uncommon. If you have created additional menu bars, you can also choose a different menu bar to display for a specific window.
On Mac, the menu bar always displays at the top of the screen.
Movable Modal dialog
This type of window stays in front of the app’s other open windows until it is closed, preventing the user from being able to interact with the rest of the app. Use a Movable Modal window when you need to briefly communicate with the user without allowing the user to have access to the rest of the app. Because the window is movable, the user will be able to drag the window to another location in case they need to see information in other windows.
You will typically display a Movable Modal Dialog using the ShowModal method:
ResultWindow.ShowModal // Code stops until window is closed
On Windows, a Movable Modal dialog has minimize, maximize, and close buttons in the Title bar. In Windows MDI interfaces, the window opens in the center area of the screen rather than in the center area of the MDI window. Therefore, the Movable Modal dialog may open outside the MDI window.
On Linux, the window typically has minimize and close buttons in its Title bar, but this can vary by Linux distribution.
On Mac, Movable Modal windows do not have a close box, so you need to include a button that the user can click to dismiss the window unless the window will dismiss itself after the app finishes a particular task. This code in a button’s Pressed event handler closes the window:
To have a Movable Modal window automatically dismiss itself, you can use a Timer that calls Self.Close when its Period is reached.
These windows are very similar to Movable Modal Dialogs. The only difference is that Modal Dialogs have no Title bar, so they cannot be moved. On Windows, a Modal Dialog has no minimize, maximize, or close buttons. In Windows MDI applications, a Modal Dialog opens in the center area of the screen rather than the center area of the MDI window. Therefore, a Modal Dialog may open outside of the app’s MDI window. On Linux, Modal Dialogs are modal but have a Title bar and close and minimize buttons, so work the same as Movable Modal Dialogs.
Like Movable Modal and Modal Dialog windows, a Floating window stays in front of all other windows in your app. The difference is that the user can still interact with other windows in the app. If you have more than one Floating window open, clicking on another Floating window will bring that window to the front, but all open Floating windows will still be in front of all non-floating windows. Because they are always in front of other types of windows, their size should be kept to a minimum or they will quickly get in the user’s way. This type of window is most commonly used to provide tools the user frequently needs or to display information.
Use the Show method to display a Floating Window:
These windows function as Modal Dialog windows. The only real difference is their appearance. Plain Box windows are sometimes used for splash screens and for apps that need to hide the desktop.
On Windows MDI apps, a Plain Box window opens in the center area of the screen rather than the center area of the MDI window so it may open outside the MDI window.
Like Plain Box windows, Shadowed Box windows function as Modal Dialog windows. The only difference is their appearance. Shadowed Box windows are not commonly used. On Mac, a Shadowed Box window works like a Modal Dialog box with a minimize button.
Retained for compatibility purposes. This type is the same as a document window.
Global floating Window
A Global Floating window looks like a Floating window, except that it is able to appear in front of another app’s windows, even when you bring another app window to the front. A “regular” Floating window appears only in front of its own app’s windows.
On Windows MDI apps, a Global Floating window can appear outside of the MDI window. By default, it opens in the top-left area of the screen.
Sheet Window (macOS)
A Sheet Window is a special type of Mac dialog box that drops down from the window title bar. A Sheet Window behaves like a Modal Dialog window, except that an animation makes it appear to drop down from the parent window’s Title bar. It can ‘t be moved from that position and it puts the user interface in a modal state for the window. The user must respond to the choices presented in the Sheet window before they can interact with the window. They can interact with other windows in the app, however, so they are often a better choice than a Modal Dialog.
You display a Sheet Window using the ShowModal method, supplying a reference to the parent window:
PromptWindow.ShowModal(Self) // Displays the Sheet within the current window
On Windows and Linux, Sheet windows behave like Movable Modal Dialogs. This means if you are creating a cross-platform app you can design your dialogs as Sheets and they will works as Movable Modal Dialogs on Windows and Linux without you having to do anything specific.
A Metal window uses a darker, solid background on Mac.
This window type is a relic of older versions of macOS, is deprecated by Apple and is no longer commonly used.
On Windows and Linux, a Metal window looks like a regular Document window.
The Modeless Dialog window is similar to the Modal Dialog, except that it is paired with a parent window (usually a Document window). Unlike a Modal Dialog, it allows you to access the parent window while it is displayed. If you hide the parent window, the Modeless dialog hides as well. If you show the parent window, the dialog reappears.
The Modeless Dialog is supported on Windows and Linux. On Mac, it behaves as a Document window.
Windows are a special construct in Xojo. The class representing a window is a DesktopWindow. You can create a subclass of DesktopWindow that contains methods and properties, but you cannot subclass a DesktopWindow to share the user interface.
To create a DesktopWindow subclass for containing shared code, create a new class (called MyBaseWindow) and set its Super property to DesktopWindow. Add a new DesktopWindow to the project and change its Super to MyBaseWindow. You will now be able to access the Public and Protected members of MyBaseWindow on this new DesktopWindow.
Implicit window instances
Unlike other classes you can use windows directly by their name without having to first create an instance. For example this code displays Window2:
This syntax is allowed because an “implicit instance” of the window is automatically created for you if its Implicit Instance property in the Inspector is ON (which is the default for all Windows).
Although an implicit instance is convenient at times, there are side effects to keep in mind.
A window can be displayed inadvertently
Accessing properties or methods of a window using its implicit instance can show the window, which might not be what you expect. For example, this code looks like it is just changing the title:
Window2.Title = "Test"
But if Window2 is not displayed, the act of setting its title will cause it to be displayed. 1. When using an Implicit Instance, it is not possible to have multiple copies of the same window displayed on screen at one time.
Accessing enumeration values of a window when Implicit Instance is ON does not work.
To avoid these limitations, you can disable implicit window instances for a window by turning the Implicit Instance property to OFF in the Inspector for the window. As this behavior is preferred, Implicit Instance will default to OFF in a future version of Xojo.
To access a window when ImplicitInstance is OFF you create an instance using “New” just like you would for a class:
Var w As New Window2 w.Show
If you need to access this reference elsewhere then you will want to store it in a property, such as a public property on the App object. In that case your code would look like this:
App.SalesWindow = New Window2 App.SalesWindow.Show
Keyboard access on macOS
Macs includes a system-wide feature called Full Keyboard Access. This feature enables a user to do work with only the keyboard that ordinarily is done using both the keyboard and the mouse. For example, the standard Mac interface calls for mouse gestures to operate the menu system and the Dock. With full keyboard access, when the menu bar has the focus, menu items can be highlighted by the up and down arrow keys and an item is selected by pressing Spacebar. Full Keyboard Access is enabled in the Keyboard Shortcuts panel of the Keyboard System Preference. Click the All Controls radio button to enable Full Keyboard Access.
When full keyboard access is on, you can select and set values for controls via the keyboard (such as when using tab and tab order) that normally do not have the focus. When a control accepts keystrokes via full keyboard access, it has a halo around it. For example, when full keyboard access is on, the user can select radio buttons via the keyboard only.
To learn more about Full Keyboard Access, refer to Apple’s Mac accessibility shortcuts docs.
Full Keyboard Access is a Mac system-wide option that the end-user must select using System Preferences. The Mac version of Xojo supports full keyboard access if the user chooses to turn it on. However, you cannot turn it on for them, so you cannot assume that all (or any) of your users will be using full keyboard access.
User interface guidelines
The quality of your app interface determines how useful and usable it is. An intuitive interface is one of the most critical things in a successful app. Studies have shown that if a user can ‘t accomplish something within the first 15 minutes of using an app, they will give up in frustration. Beyond being intuitive, the more polished an app’s interface is, the more professional it will appear to the user. Remember that without realizing it, your users will be comparing your app’s interface to all of the other apps they have used.
The alignment guides in the Layout Editor help you make sure all your controls are aligned and positioned properly. But there is more to a professional, polished interface than aligning controls.
Each supported platform has its own conventions. User interface guidelines are available from the following sources:
KDE and Gnome are the most popular Linux desktops and are used by default in several major Linux distributions, however there are others. Linux also supports a greater degree of desktop customization than Windows and Mac.
Me vs Self topic