Doing Interaction (XForms (Forms Library) - Version 1.2 (Rev. 4) A Graphical User Interface Toolkit for X)

Next: Signals, Previous: Object Attributes, Up: Part V Overview of Main Functions [Contents][Index]

### 32.5 Doing Interaction

To display the form `form` on the screen use one of

    Window fl_show_form(FL_FORM *form, int place, int border,
                        const char *title);
    Window fl_show_form(FL_FORM *form, int place, int border,
                        const char *fmt, ...);

`place` controls the position and size of the form. `border` indicates whether a border (window manager’s decoration) should be drawn around the form. If a border is to be drawn `title` is the name of the window (and its associated icon). The routine returns the window identifier of the form. For resource and identification purposes, the form name is taken to be the title with spaces removed and the first character lower-cased. E.g., if a form has a title `"Foo Bar` the forms name is derived as `"fooBar"`. The only difference between the two functions is that the first one accepts a simple string for the title while the second expects a format string like `printf()`, followed by the appropriate number of arguments.

For the the location and size of the window controlled by `place` the following possibilities exist:

`FL_PLACE_SIZE`

  The user can control the position but the size is fixed. Interactive resizing is not allowed once the form becomes visible.

`FL_PLACE_POSITION`

  Initial position used will be the one set via `fl_set_form_position()`. Interactive resizing is allowed.

`FL_PLACE GEOMETRY`

  Place at the latest position and size (see also below) or the geometry set via `fl_set_form_geometry()` etc. A form so shown will have a fixed size and interactive resizing is not allowed.

`FL_PLACE_ASPECT`

  Allows interactive resizing but any new size will have the aspect ratio as that of the initial size.

`FL_PLACE_MOUSE`

  The form is placed centered below the mouse. Interactive resizing will not be allowed unless this option is accompanied by `FL_FREE_SIZE` as in `FL_PLACE_MOUSE|FL_FREE_SIZE`.

`FL_PLACE_CENTER`

  The form is placed in the center of the screen. If `FL_FREE_SIZE` is also specified, interactive resizing will be allowed.

`FL_PLACE_FULLSCREEN`

  The form is scaled to cover the full screen. If `FL_FREE_SIZE` is also specified, interative resizing will be allowed.

`FL_PLACE_FREE`

  Both the position and size are completely free. The initial size used is the designed size. Initial position, if set via `fl_set_form_position()`, will be used, otherwise interactive positioning may be possible if the window manager allows it.

`FL_PLACE_HOTSPOT`

  The form is so placed that mouse is on the "hotspot". If `FL_FREE_SIZE` is also specified, interactive resizing will be allowed.

`FL_PLACE_CENTERFREE`

  Same as `FL_PLACE_CENTER|FL_FREE_SIZE`, i.e., place the form at the center of the screen and allow resizing.

`FL_PLACE ICONIC`

  The form is shown initially iconified. The size and location used are the window manager’s default.

If no size is specified, the designed (or later scaled) size will be used. Note that the initial position is dependent upon the window manager used. Some window managers will allow interactive placement of the windows and some will not.

There are three values that can be passed for `border`:

`FL_FULLBORDER`

  Draw full border with title

`FL_TRANSIENT`

  Draw borders with possibly less decoration (depends on the window managers behaviour)

`FL_NOBORDER`

  Draw no border at all

Since multiple forms can be displayed at the same time note that using `FL_NOBORDER` might have adverse effect on keyboard focus and is not very friendly to other applications (it is close to impossible to move a form that has no border). Thus use this feature with discretion. The only situation where `FL_NOBORDER` is appropriate is for automated demonstration suites or when the application program must obtain an input or a mouse click from the user, and even then all other forms should be deactivated while a borderless form is active. For almost all situations where the application must demand an action from the user `FL_TRANSIENT` is preferable. Also note that you can’t iconify a form that has no borders and under most window managers forms displayed with `FL_TRANSIENT` can’t be iconified either.

One additional property (under almost all window managers) of a transient window is that it will stay on top of the main form, which the application program can designate using

    void fl_set_app_mainform(FL_FORM *form);

By default, the main form is set automatically by the library to the first full-bordered form shown.

To obtain the current main form, use the following routine

    FL_FORM *fl_get_app_mainform(void);

In some situations, either because the concept of an application main form does not apply (for example, an application might have multiple full-bordered windows), or under some (buggy) window managers, the designation of a main form may cause stacking order problems. To workaround these, the following routine can be used to disable the designation of a main form (must be called before any full-bordered form is shown):

    void fl_set_app_nomainform(int yes_no);

with a true flag.

All visible forms will have the properties `WM_CLASS`, `WM_CLIENT_MACHINE` and `WM_NAME` set. In addition, the first full-bordered form will have the `WM_COMMAND` property set and is by default the applications main form.

Sometimes it is necessary to have access to the window resource ID before the window is mapped (shown). For this, the following routines can be used

    Window fl_prepare_form_window(FL_FORM *form, int place, int border,
                                  const char *name);
    Window fl_prepare_form_window_f(FL_FORM *form, int place, int border,
                                    const char *fmt, ...);

These routines create a window that obeys any and all constraints just as `fl_show_form()` does but remains unmapped. The only difference between the two functions is that the first one takes a simple string for the forms name while the second expects a format string like `printf()`, followed by the appropriate number of further arguments.

To map such a window, the following must be used

    Window fl_show_form_window(FL_FORM *form);

Between these two calls, the application program has full access to the window and can set all attributes, such as icon pixmaps etc., that are not set by `fl_show_form()`.

The application program can raise a form to the top of the screen so no other forms obscures it by calling

    void fl_raise_form(FL_FORM *form);

To instead lower a form to the bottom of the stack use

    void fl_lower_form(FL_FORM *form);

When placing a form on the screen using `FL_PLACE_GEOMETRY` for the `place` argument to `fl_show_form()` the position and size can be set before by using the routines

    void fl_set_form_position(FL_FORM *form, FL_Coord x, FL_Coord y);
    void fl_set_form_size(FL_FORM *form, FL_Coord w, FL_Coord h);
    void fl_set_form_geometry(FL_FORM form*, FL_Coord x, FL_Coord y,
                              FL_Coord w, FL_Coord h);
    void fl_scale_form(FL_FORM *form, double xsc, double ysc);

where `fl_set_form_geometry()` combines the functionality of `fl_set_form_position()` and `fl_set_form_size()` and the last routine, `fl_scale_form()`, scales the form in horizontal and vertical direction by the factors passed to the function. These routines can also be used when the form is visible.

Sometimes it is desirable to know how large the decoration are the window manager puts around a forms window. They can be obtained by a call of

    void fl_get_decoration_sizes(FL_FORM *form, int *top, int *right,
                                 int *bottom, int *left);

This is especially useful if it is necessary to open a window at some previously stored position since in that case one needs the position of of the window, which deviates from the position reported for the form by the window manager’s decorations. Obviously, the above function can’t be used for forms that are embedded into another form.

The function

    int fl_form_is_iconified(FL_FORM *form);

allows to test if the (visible) window of a form is in iconified state.

If interactive resizing is allowed (e.g., by showing the form with `FL_PLACE_POSITION`) it can be useful to limit the range of the size of a form can take. To this end, the following functions are available

    void fl_set_form_minsize(FL_FORM *form, FL_Coord minw, FL_Coord minh);
    void fl_set_form_maxsize(FL_FORM *form, FL_Coord maxw, FL_Coord maxh);

Although these two routines can be used before or after a form becomes visible, not all window managers honor such requests once the window is visible. Also note that the constraints only apply to the next call of `fl_show_form()` for the form.

To set or change the icon shown when a form is iconified use the following routine

    void fl_set_form_icon(FL_FORM *form, Pixmap icon, Pixmap mask);

where `icon` can be any valid pixmap ID. (see Pixmap Object for some of the routines that can be used to create pixmaps.) Note that a previously set icon if not freed or modified in anyway.

If, for any reason, you would like to change the form title after the form has been made visible, the following calls can be used (they will also change the icon title)

    void fl_set_form_title(FL_FORM *form, const char *name);
    void fl_set_form_title_f(FL_FORM *form, const char *fmt, ...);

(While the first function expects a simple string, the second has to be called with a format string as `printf()` etc., followed by the corresponding number of arguments.)

The routine

    void fl_hide_form(FL_FORM *form);

hides the particular form, i.e., closes its window and all subwindows.

To check if a form is visible or not, the following function can be used

    int fl_form_is_visible(FL_FORM *form)'

The function can return that the form is visible (`FL_VISIBLE`), is invisible (`FL_INVISIBLE`) or is in the processing of becoming invisible (`FL_BEING_HIDDEN`).

The most important function for doing the actual interaction with forms is

    FL_OBJECT *fl_do_forms(void);

It starts the main loop of the program and returns only when either the state of an object changes that has no callback bound to it or `fl_finish()` is called in a callback. In the first case the address of the object is returned, in the latter `NULL`.

A second way of doing interaction with the currently displayed forms is using

    FL_OBJECT *fl_check_forms(void);

This routine returns `NULL` immediately unless the state of one of the object (without a callback bound to it) changed. In that case a pointer to this object gets returned. `NULL` also gets returned after a call of `fl_finish()`.

Then there are two more functions:

    FL_OBJECT *fl_do_only_forms(void);
    FL_OBJECT *fl_check_only_forms(void);

Both functions do the same as `fl_do_forms()` and `fl_check_forms()` except that they do not handle user events generated by application windows opened via `fl_winopen()` or similar routines.

To activate or deactivate a form for user interaction you can use

    void fl_activate_form(FL_FORM *form);
    void fl_deactivate_form(FL_FORM *form);

The same can also be done for all forms at once using

    void fl_deactivate_all_forms(void)
    void fl_activate_all_forms(void)

To find out if a form is currently active call

    int fl_form_is_activated(FL_FORM *form);

A return value of 0 tells you that the form is currently deactivated.

You can also register callbacks for a form that are invoked whenever the activation status of the form is changed:

    typedef void (*FL_FORM_ATACTIVATE)(FL_FORM *, void *);
    FL_FORM_ACTIVATE fl_set_form_atactivate(FL_FORM *form,
                                            FL_FORM_ATACTIVATE callback,
                                            void *data);

    typedef void (*FL_FORM_ATDEACTIVATE)(FL_FORM *, void *);
    FL_FORM_ACTIVATE fl_set_form_atdeactivate(FL_FORM *form,
                                              FL_FORM_ATACTIVATE callback,
                                              void *data);

Also individual objects (or groups of objects if the argument of the function is an object returned by `fl_bgn_group()`) can be activated and deactivated to enable or disable user interaction:

    void fl_activate_object(FL_OBJECT *obj);
    void fl_deactivate_object(FL_OBJECT *obj);

It is normally useful to give the user a visual clue when an object gets deactivated, e.g., by graying out its label etc.

To find out if an object is active use

    int fl_object_is_active(FL_OBJECT *obj);

    void fl_redraw_object(FL_OBJECT *obj);

This routine redraws the particular object. If `obj` is a group it redraws the complete group. Normally you should never need this routine because all library routines take care of redrawing objects when necessary, but there might be situations in which an explicit redraw is required.

To redraw an entire form use

    void fl_redraw_form(FL_FORM *form);

For non-form windows, i.e., those created with `fl_winopen()` or similar routines by the application program, the following means of interaction are provided (note that these do not work on form windows, for which a different set of functions exist, see Windowing Support for details.)

You may set up a callback routine (of type `FL_APPEVENT_CB` for all user events using

    typedef int (*FL_APPEVENT_CB)(XEvent *, void *);
    FL_APPEVENT_CB fl_set_event_callback(FL_APPEVENT_CB callback, void *data);

The function returns the previously set callback (or `NULL`).

It is also possible to set up callback functions on a per window/event basis using the following routines:

    typedef int (*FL_APPEVENT_CB)(XEvent *xev, void *user_data);
    FL_APPEVENT_CB fl_add_event_callback(Window win, int xevent_type,
                                         FL_APPEVENT_CB callback,
                                         void *user_data);
    void fl_remove_event_callback(Window win, int xevent_type);

These functions manipulate the event callback functions for the window specified, which will be called when an event of type `xevent_type` is pending for the window. If `xevent_type` is 0 it signifies a callback for all event for window `win`. Note that the Forms Library does not solicit any event for the caller, i.e., the Forms Library assumes the caller opens the window and solicits all events before calling these routines.

To let the Forms Library handle event solicitation, the following function may be used

    void fl_activate_event_callbacks(Window win);

Next: Signals, Previous: Object Attributes, Up: Part V Overview of Main Functions [Contents][Index]