Next: , Previous: , 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: , Previous: , Up: Part V Overview of Main Functions   [Contents][Index]