Types of Window
In Chapter 17, we concentrated on the drawing-related interactions between CCoeControl and RWindow(and, occasionally, RBackedUp-Window). In this chapter, we've introduced key-event processing, which brings in RWindowGroup and CCoeAppUi. The window server classes involved here are part of a small window class hierarchy, defined in w32std.h (illustrated in Figure 18.7 and described in Table 18.1).
- Figure 18.7 Window class hierarchy
For much of the time you can call the functions of these classes through the control environment. Nevertheless, it is useful to understand them because the control environment is not designed to encapsulate the window server. Rather, the control environment provides a convenience layer for lodger controls and compound controls, and for the window
|
Class Name |
Description |
|
RWindowTreeNode |
Base class for all windows: a node in the tree that |
|
defines z-order | |
|
RWindowGroup |
Unit of keyboard focus and top-level owner of |
|
displayable windows | |
|
RWindowBase |
Base class for all displayable windows |
|
RBlankWindow |
Entirely blank window |
|
RDrawableWindow |
Base class that defines windows which support |
|
drawing | |
|
Backed-up window: window server redraws invalid | |
|
areas | |
|
RWindow |
Standard window: application redraws invalid areas |
server's major functions such as drawing and pointer- and key-event handling.
We do not provide detailed information on these facilities: but we give enough of an overview that you can understand what is available and find the information you need in the SDK.
For most application programming, the most important concrete classes are RWindow and RWindowGroup. Because all displayable windows are ultimately owned by a window group, a window group is the toplevel node in the tree that defines z-order. This means that all windows belonging to an application move back and forth in the z-order as a group. We can therefore use the terms 'foreground application' and 'application whose window group has focus' interchangeably.
The window server allows applications to have more than one window group but the control environment supports only a single window group per application. This assumption is built into other Symbian OS components as well.
The window server provides other features that aren't supported by the control environment, such as blank windows and non-rectangular windows whose shape is defined by a region.
Standard Windows
A standard window has functionality inherited from the chain right up to RWindowTreeNode. However, the interesting functionality starts with RWindowBase, the base class for all displayable windows, which includes:
• the Activate() function
• position- and size-setting functions
• pointer control functions
• shadow control functions
• backed-up behind functions.
You can use the Activate() function asthefinal step in athree-phase construction:
1. Use the constructor to create an RWindow with an RWsSession object. It is then just an empty client-side handle.
2. Use Construct() to connect the RWindow to the window server using the RWsSession object it already has.
3. After you have set all the window parameters, use Activate() to display the window and enable it to receive events. In the case of an RWindow, the whole window is normally invalid immediately after you activate it, so (unless you proceed immediately to redraw it) you get a redraw event. If you are using redraw storing, you could draw it before it is activated and the window server will draw it as soon as it becomes visible.
These functions can only be associated with a window that has a visible extent on the screen, so that is why they are introduced with RWindowBase. RWindowBase serves as a base class for blank windows and also for RDrawableWindow objects. If you can draw a window, you can also scroll its contents, so scrolling functions are introduced here.
We have already seen that the most important functions are introduced in RWindow: Invalidate(), BeginRedraw() and EndRedraw(). However, there are a few other interesting functions too:
• Constructs requires you to pass an RWindowTreeNode, to serve as this window's parent, and a 32-bit handle; the parent can be another displayable window or a window group; all events relating to the window include the handle; the control environment passes the address of the control that owns this window; when the control environment fields an event, it simply casts the handle to the address in order to associate it with the correct control
• easier-to-use variants of SetSize() and SetExtent() than those provided by RWindowBase
• two variants of SetBackgroundColor()
• GetInvalidRegion() allows you to get the exact region that is invalid.
The only type of window for which a client doesn't need to specify a parent is a window group. All window groups from all applications sit at the same level in the window tree. The window server holds them in a linked list which gives them order, their z-order. The order is dynamic - it changes as applications are moved to the foreground or background. For each application, its window group serves as its top-level window.
In the past, it would have been possible to use the invalid region to highly optimize the drawing code of an application, so it would only draw the exact set of pixels that contained the wrong content. If the window is using redraw storing, such optimization works against the benefits that redraw storing provides. Thus from Symbian OS v8 onward is it best not to do this.
Fading is used in Symbian OS to change a window's colors so that other windows stand out. It is implemented by re-mapping color values to a more limited range and, optionally, making them lighter or darker. For example, in UIQ, when a dialog is displayed, the window that was previously in the foreground is redrawn faded and darkened; in S60 windows that are drawn faded are lighter.
In UIQ, the default fading values are set to zero for black and 190 for white (unfaded windows have values of 0 and 255), although you can override these defaults through the window itself (the functions to do this are defined in RWindowTreeNode) or through the graphics context used to draw it.
Window Groups
The primary role of the RWindowGroup class is to handle focus and key handling. Window groups handle focus because they are the top-level nodes in the z-order. The only window group that can reasonably grant focus is the foreground group.
Focus-related functions enable you to say that a window group can't take focus or that it should automatically get focus (and foreground) when a pointer event occurs. The window server supports a flashing text cursor, whose window, position, shape, etc. can be controlled through the window group. This is clearly the right place to do it, since the cursor is associated with focus.
One implication of this is that there can only be one text cursor per application. An application such as the UIQ agenda displays a flashing cursor in its detail view when the view has focus. But when a dialog is displayed, the view loses focus and it must stop the cursor flashing. The same is true when adding a meeting in the S60 Calendar and the menu is brought up. Moreover, the view should relinquish control of the cursor, so that it can be used for editing any text fields that might appear in the dialog.
RWindowGroup also allows you to configure the way in which key events are generated when a key is held down for a certain length of time. For instance, on some phone keypads, holding down an alphanumeric key rather than releasing it immediately can cause the generated key event to switch between alphabetic and numeric; it may also be sent to a different application from the one currently in the foreground.
The default behavior is for a standard key event to occur on key down; after the key has been held down for a short time interval (usually a fraction of a second), it repeats automatically. You can override this using the CaptureLongKey() function of the RWindowGroup. You can customize several things. First, when the user presses the key but releases it before the required time interval, the standard key event can occur when the key is pressed or when it is released. Secondly, if the key is held down long enough, a different key event can be generated from the one that was captured, and this may or may not repeat automatically.
The event can also be sent to a different window group from the one with focus. For instance, if the key event was changed from numeric to alphabetic, you might want to send it to the address book, rather than the phone number display.
Post a comment