Anatomy of a Window

team bbl


Naturally, you know what a window is, but for a full understanding of how to use the wxWidgets API, it's good to have a grasp of the window model that wxWidgets uses. This differs in small respects from the window model used on each individual platform. Figure 4-1 shows the basic elements of a window.

Figure 4-1. The elements of a window


The Concept of a Window

A window is any rectangular area with a common set of properties: it can be resized, it can paint itself, it can be shown and hidden, and so on. It may contain other windows (such as a frame with menu bar, toolbar, and status bar), or no child windows (such as a static text control). Normally, a window that you see on the screen in a wxWidgets application has a corresponding object of the wxWindow class or derived class, but this is not always the case: for example, the drop-down list in a native wxComboBox is not usually modeled with a separate wxWindow.

Client and Non-Client Areas

When we refer to the size of a window, we normally include the outer dimensions, including decorations such as the border and title bar. When we refer to the size of the client area of a window, we mean the area inside the window that can be drawn upon or into which child windows may be placed. A frame's client area excludes any space taken by the menu bar, status bar, and toolbar.

Scrollbars

Most windows are capable of showing scrollbars, managed by the window rather than added explicitly by the application. The client area is then reduced by the space used by the scrollbars. For optimization, only windows that have the wxHSCROLL and wxVSCROLL style are guaranteed to own their own scrollbars. More information on scrolling can be found later in this chapter when we discuss wxScrolledWindow.

Caret and Cursor

A window can have a wxCaret (for displaying the current text position) and a wxCursor (for displaying the current mouse position). When the mouse enters a window, wxWidgets automatically displays the cursor that has been set for the window. When a window receives the focus, the caret (if any) will be shown at its current position, or at the mouse position if the focus was a result of a mouse button click.

Top-Level Windows

Windows are broadly divided into top-level windows (wxFrame, wxDialog, wxPopup) and other windows. Only top-level windows may be created with a NULL parent, and only top-level windows have delayed destruction (they are not deleted until idle time, when all other events have been processed). Except for pop-up windows, top-level windows can have decorations such as title bars and close buttons and can normally be dragged around the screen and resized, if the application allows it.

Coordinate System

The coordinate system always has (0, 0) at the top-left corner, and window dimensions are in pixels. The origin and scale can be changed for a device context that is used to paint on the window. For more on device contexts, see Chapter 5, "Drawing and Printing."

Painting

When a window needs to be painted, it receives two events, wxEVT_ERASE_BACKGROUND to paint the background, and wxEVT_PAINT to paint the foreground. Ready-to-use classes such as wxButton paint themselves, but to create your own special window class, you will need to handle these events. You can optimize painting by getting the update region (the part that needs refreshing) from the window.

Color and Font

Every window has background and foreground color settings that can be used to determine the background color and (less commonly) foreground color. The default background erase handler uses the window's background color, or if none has been set, the appropriate color or texture for the current color scheme or theme. A window also has a font setting, which may or may not be used depending on the kind of window.

Window Variant

On Mac OS X, a window has the concept of window variant, whereby it can be shown in a selection of sizes: wxWINDOW_VARIANT_NORMAL (the default), wxWINDOW_ VARIANT_SMALL, wxWINDOW_VARIANT_MINI, or wxWINDOW_VARIANT_LARGE. Changing to a smaller variant is useful when you have a lot of information to convey and limited space, but it should be used in moderation. Some applications use the small variant throughout.

Sizing

When a window is resized, either by the application or by the user, it receives a wxEVT_SIZE event. If the window has children, they will need to be positioned and sized appropriately, and the recommended way is to use sizers, as discussed in Chapter 7, "Window Layout Using Sizers." Most stock windows have a notion of a default size and position if you pass them wxDefaultSize or wxDefaultPosition (or -1 as an individual size or position value). To this end, each control implements DoGetBestSize, which returns a reasonable default size based on the control content, current font, and other factors.

Input

Any window can receive input from the mouse at any time, unless another window has temporarily captured the mouse or the window is disabled. Only the window with the current focus can receive keyboard input. An application can set the window focus itself; wxWidgets also sets the focus to a window when the user clicks on it. The wxEVT_SET_FOCUS event is sent to a window that is receiving the focus; wxEVT_KILL_FOCUS is sent when the focus is moving to a different window. See Chapter 6, "Handling Input," for more details on handling input.

Idle Time Processing and UI Updates

All windows are (unless otherwise specified) recipients of idle events (wxEVT_IDLE), which are sent when all other events have been processed, specified with the EVT_IDLE(func) macro. For more information, see "Idle Time Processing" in Chapter 17, "Writing Multithreaded Applications."

A special kind of idle time processing is user interface updating, in which all windows can specify a function that updates the window's state. This function is called periodically in idle time. In the descriptions of events that follow, EVT_UPDATE_UI(id, func) is usually omitted for brevity. User interface updating is covered in Chapter 9, "Creating Custom Dialogs."

Window Creation and Deletion

In general, windows are created on the heap with new, but see Chapter 15, "Memory Management, Debugging, and Error Checking," for details and exceptions. Most window classes allow creation either in one or two steps. wxButton has typical constructor signatures:

 wxButton(); wxButton(wxWindow* parent,     wxWindowID id,     const wxString& label = wxEmptyString,     const wxPoint& pos = wxDefaultPosition,     const wxSize& size = wxDefaultSize,     long style = 0,     const wxValidator& validator = wxDefaultValidator,     const wxString& name = wxT("button")); 

The following example of one-step construction takes advantage of all the constructor's default values:

 wxButton* button  = new wxButton(parent, wxID_OK); 

Unless the window is a frame or dialog, you must pass a non-NULL parent window to the constructor. This will automatically add the child window to the parent, and when the parent is destroyed, the children will also be destroyed. As we've seen previously, you pass a standard or user-defined identifier to the window for the purposes of uniquely identifying it. You can also pass wxID_ANY, and wxWidgets will generate a suitable identifier (a negative value, to differentiate it from user-defined or standard identifiers). You can pass a position and size to the window, a validator, if appropriate (see Chapter 9), a style (see the following), and a string name. You can pass an arbitrary string to the name parameter, or ignore it; it is rarely used now but was introduced to allow window customization under Xt and Motif, which require controls to be identified by name.

With two-step construction, you use the default constructor and then call Create, which has the same signature as the full constructor. For example, to create a button in two steps:

 wxButton* button  = new wxButton; button->Create(parent, wxID_OK); 

Only when you call Create is the underlying window created, and a wxEVT_CREATE event sent to the window in case it needs to do further processing at this point.

Why would you want to use two-step construction? One reason is that you may want to delay full creation of the window until it's really required. Another is to set some properties of the window before Create is called, especially if those properties are used within the Create call. For example, you may want to set the wxWS_EX_VALIDATE_RECURSIVELY extra style (which must be set with SetExtraStyle). In the case of a dialog, this style is used from within its Create function when initial validation takes place, so if you need it, it's important to set it before the dialog is created.

When you create a wxWindow, or any non-top-level derived window class, it is always in a visible stateso if the parent is visible at the time of creation, the window will also be visible. You can then use Show(false) to hide it if required. This is different from wxDialog and wxFrame, which are initially created in a hidden state to enable the application to lay out the controls without initial flicker, before showing with Show or (for modal dialogs) ShowModal.

Windows are deleted by calling Destroy (for top-level windows) or delete (for child windows), and the wxEVT_DESTROY event is sent just before the actual window is destroyed. In fact, child windows are deleted automatically, so it is rare to delete them explicitly.

Window Styles

A window has a style and an extra style. Window styles are a concise way to specify alternative behavior and appearances for windows when they are created. The symbols are defined in such as way that they can be combined in a "bit-list" using the C++ bitwise-or operator. For example:

 wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxTHICK_FRAME 

The wxWindow class has a basic set of styles, such as border styles, and each derived class may add further styles. The "extra" style accommodates values that cannot fit into the style value.

    team bbl



    Cross-Platform GUI Programming with wxWidgets
    Cross-Platform GUI Programming with wxWidgets
    ISBN: 0131473816
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net