Application Development |
When developing a screen, you need to keep in mind a number of issues relating to the visual appearance of the screen, the type of data being displayed or manipulated, and what your users will do with the data.
These issues can include whether more than one screen can be open at a time. This is a main factor in deciding if you open the screen as a form or as a window.
This chapter discusses the underlying sequence of client screens and how Panther manipulates them.
Forms and Windows |
User interaction with a Panther application typically begins with a startup screen, or base form. The base form is often the gateway to other screens, which can be opened in one of two ways:
Panther maintains a form stack which lists forms previously opened by the application. The application's startup screen is the base form—that is, the first screen to be pushed onto the form stack. Panther pushes onto the stack each screen that is subsequently opened as a form in the application. The top screen is the only form that is open and whose data is accessible.
The form stack retains the names of the screens saved to it and some information about each one's save state—for example, the cursor's last position. However, the stack does not save screen data. Consequently, changes entered earlier on a form might not reappear when the form is reactivated. You can save form data changes through the local data block (LDB). All changes in fields with corresponding LDB entries are written to the LDB when a new form is opened, and can be restored when the earlier form is reactivated. You can also send screen data to a named location in memory, or bundle, for later retrieval; bundles are created and accessed through Panther's send and receive commands and library functions. For more information on LDB processing and send/receive facility, refer to Chapter 25, "Moving Data Between Screens."
Panther stacks forms in last-in/first-out ( For example, an application might consist of three screens,
screen3 has a menu item that allows users to open screen1 as a form through the control string screen1. On selection of that menu item, Panther finds screen1 already exists in the form stack and returns to that instance. All intervening screens in the form stack—in this case, The top form always has its own window stack, in which it serves as the base window. Only the top form maintains a window stack. The window stack remains in memory until Panther gets a request to open another form. It then closes all windows and purges that window stack from memory. Finally, it opens the form and creates a new window stack.
Panther stacks windows in last-in/first-out ( For example, given the form stack shown earlier, the top form
In this example, Panther uses the window stack to maintain information about all open windows—which one is active, the order in which they were opened, whether they have a sibling or stacked relationship, and the data of inactive windows. Because the window stack saves inactive window data, Panther can reactivate a window in its previous state, and thus avoids the overhead and processing otherwise incurred by reopening and redisplaying the screen.
The window stack can hold as many windows as system memory allows. You can get the number of windows in the window stack through sm_wcount.
In contrast with the form stack, the window stack can contain multiple instances of the same screen. Be careful to avoid recursive designs that might use large amounts of memory.
You can open a screen as a sibling of the current window. Unlike stacked windows, users can bring focus to any window that is a sibling of the active window.
A window cannot directly open any screen as a sibling that is already a sibling. To open multiple instances of the same screen as sibling windows, call sm_setsibling to force sibling status onto the next screen opened as a window. You can also reset an existing window's sibling property ( Panther provides these library functions to manipulate the window stack:
Forms and the Form Stack
LIFO
) order. All screens in the form stack must be unique. If a form is opened and its name is already in the stack, Panther assumes that you want to return to that form; it pops off the stack all screens above the specified form and discards them.
screen1
, screen2
, and screen3
, which open each other as forms. This creates a form stack in which screen1 is the application's base form and screen3 is the top form:
screen3
and screen2
—are destroyed. If the user now exits from screen1, the form stack is empty. If the setup variable CLOSELAST_OPT
is set to NO_CLOSELAST
, the application terminates; otherwise, the application continues to run without an open screen.
Windows and the Window Stack
Window Stack Organization
LIFO
) order. The top screen in the window stack is the active window and is the only window to have focus. When the application issues a request to close the active window—through EXIT
or an explicit function call—Panther pops the active window off the window stack. The top window in the stack now becomes the active window with its saved data restored.
screen3
can open screen1 as a window; screen1 can in turn open another window, and so on, yielding a window stack as shown in the following illustration:
screenY
is the top window in the window stack and therefore the active window; only it has focus. If the user closes screenY
, for example, through the EXIT
key, screenX
becomes the active window.
Sibling Windows
PV_YES
to define the window as a sibling, PV_NO
to reinstate its stacked window state).
Window Stack Manipulation
sm_wselect
to its former position in the window stack. Panther only saves information about the screen last-selected by sm_wselect
call; consequently, you can restore a screen to its previous place in the window stack only if no other windows have subsequently been selected by sm_wselect
.
sm_setsibling
.
You can also programmatically rotate sibling windows in order to change the active one.
sm_wrotate rotates sibling windows according to the supplied step value. For example, the following illustration shows sibling windows A, B, and C, where C is the active window:
The following function call rotates the top sibling window C to the bottom of the sibling stack and leaves screen B on top as the active window:
sib_windows = sm_wrotate (1);