Understanding windows and forms

This is an introduction to Genero windows and forms.

Programs manipulate windows and forms, to define display and input areas controlled by interactive instructions such as the INPUT dialog. When a dialog is started, it uses the form associated with the current window. Forms are defined in .42f compiled form files and are loaded and displayed in windows.

Window objects

The windows are created from programs; they define a display context for sub-elements like forms, menus, message and error lines. A window can contain only one form at a time, but you can display different forms successively in the same window.

When using the text mode (FGLGUI=0), windows are displayed in the character terminal as fixed-size boxes, at a given line/column position, width and height. When using a graphical desktop front-end (FGLGUI=1), windows are displayed as independent resizable windows by default. Note that a GUI application can run in traditional mode (gui.uiMode="traditional" FGLPROFILE setting), displaying windows as simple static areas inside a real graphical parent window. When using a mobile device front-end, only one window is visible at the time, because of device platform GUI standards and the limited screen sizes (smartphones). Split views are the exception, as they allow for the display of two windows side by side in a typical list-detail display on tablets.

A program creates a new window with the OPEN WINDOW instruction, which also defines the window identifier. A window is destroyed with the CLOSE WINDOW instruction:
OPEN WINDOW mywindow WITH FORM "myform"
...
CLOSE WINDOW mywindow
If there is a current window, it is possible to display several forms successively in that same window. The previous form is removed automatically by the runtime system when displaying a new form to the window:
OPEN WINDOW mywindow WITH FORM "form1"
INPUT BY NAME ... -- uses form1 elements
...
OPEN FORM f1 FROM "form2"
DISPLAY FORM f1  -- removes "form1" from the window
INPUT BY NAME ... -- uses form2 elements
...
When a program starts, the runtime system creates a default window named SCREEN. This default window can be used as a regular window: it can hold a menu and a form. If needed, it can be closed with CLOSE WINDOW SCREEN. You typically display the main form of your program in the SCREEN window, by using OPEN FORM + DISPLAY FORM:
MAIN
    -- The SCREEN window exists by default
    ...
    OPEN FORM f_main FROM "customers"
    DISPLAY FORM f_main -- displays in SCREEN
    ...
END MAIN

Several windows can be created, but there can be only one current window when using modal dialogs (only one dialog is active at the time, thus only the current window can be active). By using parallel dialogs, several windows can be active concurrently. Parallel dialogs were introduced to implement split views, for mobile devices.

There is always a current window. The last created window becomes the current window. When the last created window is closed, the previous window in the window stack becomes the current window. Use the CURRENT WINDOW instruction to make a specific window current before executing the corresponding dialog that is controlling the window content:
OPEN WINDOW w_customers ...
OPEN WINDOW w_orders ...
...
CURRRENT WINDOW IS w_customers
...
CLOSE WINDOW w_customers
CURRRENT WINDOW IS w_orders
...
By default, a window has no particular type and displays as a modal window on the front-end, to be controlled by a modal dialog instruction. In some situations, you must specify the type of the window to get a specific rendering and behavior. This is achieved by defining the TYPE attribute in the ATTRIBUTES clause of the OPEN WINDOW instruction:
OPEN WINDOW w_cust WITH FORM "f_cust" ATTRIBUTES(TYPE=LEFT)
...
OPEN WINDOW w_pref WITH FORM "f_pref" ATTRIBUTES(TYPE=POPUP)
...
Specify decoration options with a presentation style for the window, identified the STYLE attribute of the ATTRIBUTES section of OPEN WINDOW. Window styles can also be specified at form level, with the WINDOWSTYLE form attribute in the LAYOUT of the form definition:
OPEN WINDOW w_cust WITH FORM "f_cust" ATTRIBUTES(STYLE="dialog2")

The ui.Window built-in class can be used to manipulate windows as objects. The common practice is to get the current form of the window and use it as ui.Form object to manipulate its content.

The windows can be displayed in an WCI container application, by using the ui.Interface methods to define parent / child relationship.

Form objects

Forms define the layout and presentation of areas used by the dialogs (INPUT), to display or input data. Forms are loaded by programs from external files with the .42f extension, the compiled version of .per form specification files.

Forms can be stamped with the VERSION attribute. The form version attribute is used to indicate that the form content has changed. The front-end is then able to distinguish different form versions and avoid saved settings being applied for new form versions.

Forms can be loaded with the OPEN FORM instruction followed by a DISPLAY FORM, to display the form into the current window, or forms can be used directly as window creation argument with the OPEN WINDOW ... WITH FORM instruction:
OPEN FORM f_cust FROM "f_cust"
DISPLAY FORM f_cust -- into current window
...
OPEN WINDOW w_cust WITH FORM "f_cust"

The form that is used by interactive instructions like INPUT is defined by the current window containing the form. Switching between existing windows (and thus, between forms associated with the windows) is done with the CURRENT WINDOW instruction.

Several forms can be successively displayed in the same (current) window. The last displayed form will be used by the next dialog, while the form displayed before will be automatically removed from the window:
OPEN WINDOW w_common WITH 20 ROWS, 60 COLUMNS
...
OPEN FORM f1 FROM "f_cust"
DISPLAY FORM f1 -- f_cust is shown
INPUT BY NAME rec_cust.* ...
...
OPEN FORM f2 FROM "f_ord"
DISPLAY FORM f2 -- f_ord is shown (f_cust is removed)
INPUT BY NAME rec_ord.* ...

The ui.Form built-in class is provided to handle form elements. You can, for example, hide some parts of a form with the setElementHidden() method. Get a ui.Form object with the ui.Window.getForm() method.