1.1 Structure of an application using XForms
1.2 Initialization (fl_initialize)
1.3 Defining forms (fl_bgn_form, fl_end_form)
1.4 Adding objects to a form (fl_add_XXXX)
1.5 Showing forms (fl_show_form)
1.5.1 Controlling the position and size of forms,
1.5.2 Hiding a form (fl_hide_form)
1.6 Doing interaction
1.6.1 Blocking interaction (fl_do_forms),
1.6.2 Non-blocking interaction (fl_check_forms),
1.6.3 Using callback functions (fl_set_object_callback)
2 MORE ON FORMS AND OBJECTS
2.1 Modifying an existing form by adding/deleting objects
2.2 Grouping objects in a form
2.3 Hiding and showing objects
2.4 Activating, deactivating and triggering objects
2.5 Activating and deactivating forms
2.6 Generic object attributes
2.6.1 Color, 2.6.2 Bounding box, 2.6.3 Label, 2.6.4 Symbols
2.7 Forcing or preventing redrawing
2.7.1 Redrawing objects and forms,
2.7.1 Freezing forms
2.8 Object shortcuts
2.9 Goodies (predefined objects)
2.9.1 Messages and questions, 2.9.2 File selector
3 OVERVIEW OF ALL OBJECT CLASSES
3.1 Static objects
3.1.1 Box, 3.1.2 Frame, 3.1.3 Text, 3.1.4 Bitmap, 3.1.5 Pixmap,
3.1.6 Clock, 3.1.7 Chart
3.2 Button-like objects
3.2.1 Button
3.3 Valuator objects
3.3.1 Slider, 3.3.2 Dial, 3.3.3 Positioner, 3.3.4 Counter
3.4 Input objects
3.4.1 Input field
3.5 Choice objects
3.5.1 Menu, 3.5.2 Choice, 3.5.3 Browser, 3.5.4 Pop-ups
3.6 Other objects
3.6.1 Timer, 3.6.2 XYPlot
3.7 Canvas
3.7.1 OpenGl canvas
Display *fl_initialize(int *argc, char *argv[], const char *appclass, XrmOptionDescList app_opt, int n_app_opt)argc,argv are the command line parameters. appclass is the application class name. app_opt, n_app_opt are an option list and the number of its entries (usually 0, 0).
The following routine starts a form definition:
FL_FORM *fl_bgn_form(int type,FL_Coord w,FL_Coord h)type indicates the type of the background drawn in the form. The background is a box. w and h indicate the width and height of the form in pixels.
The following routine ends a form definition:
void fl_end_form()Many different forms can be defined and displayed when required. It is a good habit to first define all your forms before starting the actual work.
FL_OBJECT *fl_add_NAME(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)NAME is the class name. type is the type of the object in its class. Most classes have many different types. x,y,w,h give the left bottom corner and the width and height of the bounding box of the object. label is the label that is placed inside or next to the object.
After an object has been created, it is possible to set up its attributes. Object attributes can be divided into generic and object specific ones. For generic attributes (e.g., the object label size) the routines that change them always start with:
fl_set_object_xxx()xxx is the name of the attribute.
Here is a list of XForms object classes and a short description of each class:
Window fl_show_form(FL_FORM *form,int place,int border, const char *name)It opens a (top-level) window on the screen in which the form is shown. The routine returns the window resource ID of the form. You normally never need this. Immediately after the form becomes visible, a full draw of all objects on the form is performed.
The location and size of the window are determined by place:
The argument border indicates whether or not to request window manager's decoration. Border should take one of the following values:
For some dialogs, such as demanding an answer etc., you probably do not want
window manager's full decoration. Use FL_TRANSIENT for this.
A window border is useful to let the user iconify a form or move it around.
If a form is transient or has no border, it is normally more difficult (or
even impossible) to move the form. A transient form typically should have
less decoration, but not necessarily so. It depends on window mangers as
well as their options.
FL_NOBORDER is guaranteed to have no border and is immune to iconification
request. Because of this, borderless forms can be hostile to other
applications, so use this only if absolutely necessary.
For almost all situations where the application must demand
an action from the user, FL_TRANSIENT is preferred.
Also note you can't iconify a form that has no border and under
most window managers, FL_TRANSIENT form can't be iconified either.
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)x,y,w,h indicate the position of the form on the screen and its size. The position is measured from the top-left corner of the screen.
If interactive resizing is to be allowed, it can be useful to limit the range the size of a form can take:
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.
void fl_hide_form(FL_FORM *form)A hidden form continues to exist and can be shown again.
FL_OBJECT *fl_do_forms()It controls the interaction until some object in one of the forms changes state. In this case a pointer to the changed object is returned.
When the object is returned by fl_do_forms() the application
program can check what the change is and take action accordingly.
Normally, after the action is taken by the application program
fl_do_forms() is called again to continue the interaction.
Hence, most programs have the following global form:
/* define the forms */ /* display the forms */ while (! ready) { obj = fl_do_forms() /* handle the change in obj */ }
FL_OBJECT *fl_check_forms()In this case control is returned to the application program immediately. When a change has occurred in some object the object is returned as with fl_do_forms(). But when no change has occurred control is also returned but this time a NULL object is returned. Programs working in this way have the following as the basic structure:
/* define the forms */ /* display the forms */ while (! ready) { obj = fl_check_forms(); if (obj != NULL) /* handle the change in obj */ /* update other things */ }Note that the use of a loop like this will eat up most computer time. Hence, only use it when the application program actually has to do something all the time. Otherwise use fl_do_forms() instead.
To bind a callback routine to an object, use:
FL_CALLBACKPTR fl_set_object_callback(FL_OBJECT *obj, FL_CALLBACKPTR callback, long argument)obj is the object. callback is the callback function. argument is an argument that is passed to the callback routine so that it can take different actions for different objects. The function returns the old callback routine already bound to the object. You can change the callback routine any time using this function.
The callback routine should have the form:
void callback(FL_OBJECT *obj,long argument)The first argument to every callback function is the object to which the callback is bound. The second parameter is the argument specified by the application program in the call to fl_set_object_callback().
By defaults, callbacks are invoked automatically by the system when an object changes its state. To invoke the callback manually (as opposed to invocation by the main loop) you can use the following function:
void fl_call_object_callback(FL_OBJECT *obj)When dealing with multiple forms, the application program can also bind a callback routine to an entire form. To this end it should use the routine:
void fl_set_form_callback(FL_FORM *form, void (*callback)(FL_OBJECT *, void *), void *data)Whenever fl_do_forms() or fl_check_forms() would return an object in form they call the routine callback instead, with the object as an argument. Such callback should have the form:
void callback(FL_OBJECT *obj, void *data)
void fl_addto_form(FL_FORM *form)After this call you can start adding objects to the form. To stop adding objects to the form use fl_end_form() as before. The following routine deletes an object from the form it is in:
void fl_delete_object(FL_OBJECT *obj)The following routine frees the memory for an object (the object should be deleted first):
void fl_free_object(FL_OBJECT *obj)An object after being freed should not be referenced.
The following routine frees the memory for a form, together with all its objects:
void fl_free_form(FL_FORM *form)The form should not be visible.
FL_OBJECT *fl_bgn_group(void)It returns a pointer to the group.
The following routine ends the definition of a group:
FL_OBJECT * fl_end_group(void)Between these two calls, various objects are added to the group. Groups should never be nested.
Groups are useful for two reasons. First of all, it is possible to show/hide or activate/deactivate groups of objects, and to change some of their attributes with a single instruction. The second reason for using groups is for radio buttons. Pushing a radio button makes the currently pushed radio button released. In fact, this happens only with radio buttons in the particular group. Radio buttons are considered related only if they belong to the same group. Using groups is the only way to place unrelated groups of radio buttons on a single form without interference from each other.
It is possible to add objects to an existing group. The following routine reopens a group for adding more objects to it:
void fl_addto_group(FL_OBJECT *group)group is the object returned by fl_bgn_group().
void fl_hide_object(FL_OBJECT *obj)obj is the object to hide or the group of objects to hide. Hidden objects don't play any role anymore. All routines on the form act as if the object does not exist.
To make the object or group of objects visible again use:
void fl_show_object(FL_OBJECT *obj)Hiding and showing (groups of) objects are useful to change the appearance of a form depending on particular information provided by the user. You can also make overlapping groups in the form and take care that only one of them is visible.
void fl_deactivate_object(FL_OBJECT *obj)obj is the object to be deactivated. When obj is a group the whole group is deactivated.
To reactivate the group or button use the routine:
void fl_activate_object(FL_OBJECT *obj)It is possible to simulate the action of an object being triggered from within the program by using the following routine:
void fl_trigger_object(FL_OBJECT *)Calling this routine on an object results in the object returned to the application program or its callback called if it exists. Note however, there is no visual feedback, i.e., fl_trigger_object(button) will not make the button appear pushed.
In certain situations, you might not want to have interaction with all of them. For example, when the user presses a quit button in a form you might want to ask a confirmation using another form. You don't want to hide the main form because of that but you also don't want the user to be able to press buttons, etc. in this form. The user first has to give the confirmation. So you want to temporarily deactivate the main form. This can be done using the call:
void fl_deactivate_form(FL_FORM *form)To reactivate the form later again use:
void fl_activate_form(FL_FORM *form)The following routines activate or deactivate all forms:
void fl_deactivate_all_forms(void) void fl_activate_all_forms(void)
void fl_set_object_color(FL_OBJECT *obj,FL_COLOR col1,FL_COLOR col2)col1 and col2 are indices into a colormap.
The following predefined color symbols can be used in all color change requests: FL_BLACK, FL_RED, FL_GREEN, FL_YELLOW, FL_BLUE, FL_CYAN, FL_MAGENTA, FL_WHITE.
The actual color is handled by an internal colormap of FL_MAX_COLS entries
(default 1024).
To change or query the values of this internal colormap use the call:
void fl_set_icm_color(FL_COLOR index, int r, int g, int b) void fl_get_icm_color(FL_COLOR index, int *r, int *g, int *b)
The shape of the box can be changed using the routine:
void fl_set_object_boxtype(FL_OBJECT *obj,int boxtype)boxtype should be one of the following: FL_UP_BOX, FL_DOWN_BOX, FL_FLAT_BOX, FL_BORDER_BOX, FL_SHADOW_BOX, FL_ROUNDED_BOX, FL_RFLAT_BOX, FL_RSHADOW_BOX, FL_NO_BOX, with the same meaning as the type for object class box (see Section 3.1.1).
The following routines act on the position and size of the box:
void fl_set_object_position(FL_OBJECT *ob, FL_Coord x, FL_Cood y) void fl_set_object_size(FL_OBJECT *ob, FL_Coord w, FL_Coord h) void fl_set_object_geometry(FL_OBJECT *ob, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h)
void fl_set_object_lcol(FL_OBJECT *obj, FL_COLOR lcol) void fl_set_object_lsize(FL_OBJECT *obj,int lsize) void fl_set_object_lstyle(FL_OBJECT *obj,int lstyle)lsize gives the size in points. The available styles for lstyle are:
You can change the alignment of the label with respect to the bounding box of the object:
void fl_set_object_lalign(FL_OBJECT *obj,int align)The following possibilities exist:
Finally, the routine:
void fl_set_object_label(FL_OBJECT *obj, const char *label)changes the label of a given object. The passed parameter label is copied internally.
A number of predefined symbols are available:
The application program can also add symbols to the system which it can then use to display symbols on objects that are not provided by the Forms Library (topic not covered here).
void fl_redraw_object(FL_OBJECT *obj)When the object is a group it redraws the complete group. Normally you should never need this routine because all library routines take care of redrawing but there might be situations in which a redraw is required.
To redraw an entire form, use:
void fl_redraw_form(FL_FORM *form)Use of these routines is normally not necessary and should be kept to an absolute minimum.
void fl_freeze_form(FL_FORM *form) void fl_unfreeze_form(FL_FORM *form)
The following routine binds a series of keys to an object:
void fl_set_object_shortcut(FL_OBJECT *obj, const char *str, int showit)Any character in string str is considered as a shortcut, except for ^ and #, which stand for combinations with the CONTROL, and ALT key. The symbol ^ itself can be obtained using ^^. The symbol # can be obtained using ^#. The ESCAPE key can be given as ^[. Additional syntax exists to indicate function and arrow keys (topic not covered here).
Parameter showit indicates whether the shortcut letter in the object label should be underlined if a match exists. Although the entire object label is searched for matches, only the first alphanumerical character in the shortcut string is used.
void fl_show_message(const char *s1, const char *s2, const char * s3)It shows a simple form with a message and a button with OK on it. s1,s2,s3 are the three lines of the message. Use empty strings if you don' t need all the lines. The routine returns when the user presses the OK button or presses the RETURN key.
int fl_show_question(const char *s1, const char *s2, const char *s3)Again shows a three line message but this time with a Yes and a No button. It returns whether the user pushed the Yes button. The user can also press the
int fl_show_choice(const char *s1,const char *s2,const char *s3, int numb, const char *b1,const char *b2,const char *b3)Shows a three line message with one, two or three buttons.
To obtain some text from the user, use the following routine:
const char *fl_show_input(const char *str1,const char *defstr)This shows a box with one line of message (indicated by str1) and an input field in which the user can enter a string. defstr is the default string placed in the input box.
const char * fl_show_fselector(const char *message,const char *directory, const char *pattern,const char *default)A form will be shown in which listed are all files in directory directory that satisfy the pattern.
pattern can be any kind of regular expression, e.g. [a-f]*.c gives all files starting with a letter between a and f and ending with .c. default is the default file name. message is the message string placed at the top of the form.
Now the user can choose a file from the list given. Function returns a pointer to a static buffer that contains the filename selected or null if the Cancel button is pressed. The user can also walk through the directory structure, either by changing the directory string by pressing the mouse on it or by pressing his mouse on a directory name to enter this directory. All directory entries read are cached internally (up to 10 directories) and if there is any change in directory entries, click on ReScan button to force an update.
To add a box to a form you use the routine:
FL_OBJECT *fl_add_box(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is default placed centered in the box. The following types are available:
To add an frame to a form you use the routine:
FL_OBJECT *fl_add_frame(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The frame is drawn outside of the bounding box, so a flat box of the same size just fills the inside of the frame without any gaps. The label is by default placed centered inside the frame. The following types are available:
To add a text to a form you use the routine:
FL_OBJECT *fl_add_text(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed flushed left in the bounding box. Only one type of text exists: FL_NORMAL_TEXT.
No interaction takes place with text objects. Attribute Color1 controls the color of the box. The color of the text is controlled by lcol as usual.
To add a bitmap to a form you use the routine:
FL_OBJECT *fl_add_bitmap(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label )The label is by default placed below the bitmap. The bitmap will be empty. Only the type FL_NORMAL_BITMAP is available.
No interaction takes place with a bitmap.
To set the actual bitmap being displayed use:
void fl_set_bitmap_data(FL_OBJECT *ob, int width,int height,char *bits) void fl_set_bitmap_file(FL_OBJECT *ob,const char *file)bits contains the bitmap data as a character string. file is the name of the file that contains bitmap data.
A number of bitmaps can be found in /usr/include/X11/bitmaps or similar places. The X program bitmap can be used to create bitmaps.
Label color controls the foreground color of the bitmap. Color1 controls the background color of the bitmap (and the color of the box) Color2 is not used.
To add a bitmap to a form you use the routine:
FL_OBJECT *fl_add_pixmap(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed below the pixmap. Only the type FL_NORMAL_PIXMAP is available.
No interaction takes place with a pixmap.
To set the actual pixmap being displayed use:
void fl_set_pixmap_data(FL_OBJECT *ob, char **data) void fl_set_pixmap_file(FL_OBJECT *ob, const char *file)data contains the pixmap data as an array of char pointers and file is the name of the file that contains the pixmap data.
Note that both of these functions do not free the old pixmaps associated with the object. There is more on pixmaps which is not covered here.
To add a clock to a form you use the routine:
FL_OBJECT *fl_add_clock(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, char label[])The label is default placed below the clock. The following types are available:
To get the current time use the routine:
void fl_get_clock(FL_OBJECT *obj, int *h, int *m, int *s)Attribute Color1 controls the color of the background, color2 the color of the hands.
To add a chart object to a form use the routine:
FL_OBJECT *fl_add_chart(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)It shows an empty box on the screen with the label below it. The following types are available:
No interaction takes place with charts.
To clear a chart use the routine:
void fl_clear_chart(FL_OBJECT *obj)To add an item to a chart use:
void fl_add_chart_value(FL_OBJECT *obj, double val, const char *text, int col)val is the value of the item, text is the label to be associated with the item (can be empty) and col is an index in the colormap that is the color of this item.
The chart will be redrawn each time you add an item. This might not be appropriate if you are filling a chart with values. In this case put the calls between fl_freeze_form() and fl_unfreeze_form().
You can also insert a new value at a particular place using:
void fl_insert_chart_value(FL_OBJECT *obj, int index, double val, const char *text, int col)index is the index before which the new item should be inserted. The first item is number 1.
To replace the value of a particular item use the routine:
void fl_replace_chart_value(FL_OBJECT *obj, int index, double val, const char *text, int col)index is the index of the value to be replaced. The first value has an index of 1, etc.
Normally, bar-charts and line-charts are automatically scaled in the vertical direction such that all values can be displayed. This is often not wanted when new values are added from time to time. To set the minimal and maximal value displayed use the routine:
void fl_set_chart_bounds(FL_OBJECT *obj, double min, double max)To return to automatic scaling choose min = max = 0.
Also the width of the bars and distance between the points in a line-chart are normally scaled. To change this use:
void fl_set_chart_autosize(FL_OBJECT *obj, int autosize)with autosize = 0.
In this case the width of the bars will be such that the maximal number of items fits in the box. This maximal number (default FL_CHART_MAX which is 256) can be changed using:
void fl_set_chart_maxnumb(FL_OBJECT *obj, int maxnumb)
Attribute Color1 controls the color of the box.
FL_OBJECT *fl_add_button(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label) FL_OBJECT *fl_add_lightbutton(int type, FL_Coord x, FL_Coord y, FL_Coord w,FL_Coord h, const char *label) FL_OBJECT *fl_add_roundbutton(int type, FL_Coord x, FL_Coord y, FL_Coord w,FL_Coord h, const char *label) FL_OBJECT *fl_add_checkbutton(int type, FL_Coord x, FL_Coord y, FL_Coord w,FL_Coord h, const char *label)The label is by default placed inside the button for button and lightbutton. For roundbutton, bitmapbutton and pixmapbutton, it is placed to the right of the circle and to the bottom of the bitmap/pixmap respectively.
Different types of buttons correspond to different behaviors of the button. The following types of buttons are available:
FL_NORMAL_BUTTONs, FL_PUSH_BUTTONs, FL_RADIO_BUTTONs, FL_RETURN_BUTTONs and FL_HIDDEN_BUTTONs are returned at the moment the user releases the mouse after having pressed it on the button. An FL_INOUT_BUTTON is returned both when the user presses it and when the user releases it. A FL_TOUCH_BUTTON is returned all the time as long as the user keeps it pressed. A FL_RETURN_BUTTON and a FL_HIDDEN_RET_BUTTON are also returned when the user presses the RETURN key.
The application program can also set a button to be pushed or not itself without a user action. To this end use the routine:
void fl_set_button(FL_OBJECT *obj, int pushed)pushed indicates whether the button should be pushed (1) or released (0).
Note that when setting a FL_RADIO_BUTTON to be pushed this does not automatically set the currently pushed button to be released. The application program will have to do that itself. Further, this routine only simulates the visual appearance and perhaps some internal states, it does not affect the program flow in anyway, i.e., setting a button being pushed does not invoke its callback or results in the button returned to the program. For that, fl_trigger_object() is needed.
To figure out whether a button is pushed or not use:
int fl_get_button(FL_OBJECT *obj)To find out which mouse button was used at the last push (or release) use the routine:
int fl_get_button_numb(FL_OBJECT *obj)It returns the number of the mouse button (1 = left, 2 = middle, 3 = right). If the last push is triggered by a shortcut the function returns the keysym (ascii value if ASCII) of the key plus FL_SHORTCUT.
In a number of situations it is useful to define a keyboard equivalent to a button. E.g., you might want to define that ^Q (CNTRL Q) has the same meaning as pressing the Quit button. This can be achieved using the following call:
void fl_set_button_shortcut(FL_OBJECT *obj, const char *str, int showUL)Note that str is a string, not a character. This string should contain all the characters that correspond to this button. If you use string "^QQq" the button will react on the keys q, Q and CNTRL Q. As you see you should use the symbol ^ to indicate the control key. Similarly you can use the symbol # to indicate the ALT key.
To set the bitmap to use for the bitmap button, the following routines can be used:
void fl_set_bitmapbutton_data(FL_OBJECT *ob, int w, int h, unsigned char *bits) void fl_set_bitmapbutton_file(FL_OBJECT *ob, const char *filename)Similarly, to set the pixmap to use for the pixmap button, the following routines can be used:
void fl_set_pixmapbutton_data(FL_OBJECT *ob, unsigned char **bits) void fl_set_pixmapbutton_file(FL_OBJECT *ob, const char *filename) void fl_set_pixmapbutton_pixmap(FL_OBJECT *ob, Pixmap id, Pixmap mask)Note that these routines do not free the pixmaps already associated with the button. To free the pixmaps, use the following routine:
void fl_free_pixmapbutton_pixmap(FL_OBJECT *ob)To get the pixmap that is currently being displayed, use the following routine:
Pixmap fl_get_pixmapbutton_pixmap(FL_OBJECT *ob, Pixmap &pixmap, Pixmap &mask)Pixmaps are by default displayed centered inside the bounding box. However, this can be changed using the following routine:
void fl_set_pixmapbutton_align(FL_OBJECT *ob, int align, int xmargin, int ymargin)align is the same as that used for labels. xmargin and ymargin are extra margins to leave in additional to the object border width.
For normal buttons color1 controls the normal color and color2 the color when pushed. For lightbuttons color1 is the color of the light when off and color2 the color when on. For round buttons, color1 is the color of the circle and color2 the color of the circle that is placed inside it when pushed. For bitmapbuttons, color1 is the normal box color (or bitmap background if nobox) and color2 is used to indicate the focus color. The fore ground color of the bitmap is controlled by label color.
To add a slider to a form use:
FL_OBJECT *fl_add_slider(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label) FL_OBJECT *fl_add_valslider(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed below the slider. The second class of slider displays its value above or to the left of the slider. The following types of sliders are available:
In some applications you might not want the slider to be returned all the time. To change the default, call the following routine:
void fl_set_slider_return(FL_OBJECT *obj, int when)Parameter when can be one of the four values:
void fl_set_slider_value(FL_OBJECT *obj,double val)
void fl_set_slider_bounds(FL_OBJECT *obj, double min, double max)The program can read the slider value using the call:
double fl_get_slider_value(FL_OBJECT *obj)Attribute Color1 controls the color of the background of the slider, color2 the color of the slider itself.
You can control the size of the slider inside the box using the routine:
void fl_set_slider_size(FL_OBJECT *obj, double size)size should be a float between 0.0 and 1.0. With size=1.0, the slider covers the box completely and can no longer be moved. The default is FL_SLIDER_WIDTH = 0.08.
To add a dial to a form use:
FL_OBJECT *fl_add_dial(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed below the dial. The following types of dials are available:
void fl_set_dial_return(FL_OBJECT *obj, int always)Set always to FALSE to achieve this goal.
To change the value of the dial use:
void fl_set_dial_value(FL_OBJECT *obj, double val) void fl_set_dial_bounds(FL_OBJECT *obj, double min, double max)By default, the minimum value is 0.0, the maximum is 1.0 and the value is 0.5.
To obtain the current values of the dial use:
double fl_get_dial_value(FL_OBJECT *obj) void fl_get_dial_bounds(FL_OBJECT *obj, double *min, double *max)Sometimes, it might be desirable to limit the angular range a dial can take or choose an angle other than 0 to represent the minimum value. For this purpose, use the following routine:
void fl_set_dial_angles(FL_OBJECT *ob, double thetai, double thetaf)thetai maps to the minimum value of the dial and thetaf maps to the maximum value of the dial.
By default, crossing from 359.9 to 0 or from 0 to 359.9 is not allowed. To allowing crossing, use the following routine:
void fl_set_dial_cross(FL_OBJECT *ob, int flag)The following routine makes dial values to be rounded to some values, e.g. to integer values:
void fl_set_dial_step(FL_OBJECT *obj, double step)After this call dial values will be rounded to multiples of step. Use the value 0.0 to stop rounding.
The default box for dials is FL_NO_BOX.
Color1 controls the color of the background of the dial, color2 the color of
the knob or the line.
A positioner can be added to a form using the call:
FL_OBJECT *fl_add_positioner(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is placed below the box by default. Only one type of positioner exists at the moment: FL_NORMAL_POSITIONER.
The user changes the setting of the positioner using the mouse inside the box. Whenever the values change, the object is returned by the interaction routines.
In some applications you only want the positioner to be returned to the application program when the user releases the mouse, i.e., not all the time. To achieve this call the routine:
void fl_set_positioner_return(FL_OBJECT *obj, int always)Set always to 0 to achieve this goal.
To set the value of the positioner and the boundary values use the routines:
void fl_set_positioner_xvalue(FL_OBJECT *obj, double val) void fl_set_positioner_xbounds(FL_OBJECT *obj, double min, double max) void fl_set_positioner_yvalue(FL_OBJECT *obj, double val) void fl_set_positioner_ybounds(FL_OBJECT *obj, double min, double max)By default the minimum values are 0.0, the maximum values are 1.0 and the values are 0.5. For ybounds, min and max should be taken to mean the value at the bottom and value at the top of the positioner.
To obtain the current values of the positioner use:
double fl_get_positioner_xvalue(FL_OBJECT *obj) void fl_get_positioner_xbounds(FL_OBJECT *obj, double *min, double *max) double fl_get_positioner_yvalue(FL_OBJECT *obj) void fl_get_positioner_ybounds(FL_OBJECT *obj, double *min, double *max)The following routines allows rounding positioner values to some values, e.g. to integer values:
void fl_set_positioner_xstep(FL_OBJECT *obj, double step) void fl_set_positioner_ystep(FL_OBJECT *obj, double step)After these calls positioner values will be rounded to multiples of step. Use the value 0.0 to stop rounding.
Attribute Color1 controls the color of the box, color2 the color of the cross-hair.
To add a counter to a form use:
FL_OBJECT *fl_add_counter(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed below the counter. The following types of counters are available:
In some applications you might want the counter to be returned to the application program whenever the value changes. To achieve this call the routine:
void fl_set_counter_return(FL_OBJECT *obj, int always)Set always to TRUE to achieve this.
To change the value of the counter use the routines:
void fl_set_counter_value(FL_OBJECT *obj, double val) void fl_set_counter_bounds(FL_OBJECT *obj, double min, double max) void fl_set_counter_step(FL_OBJECT *obj, double small, double large)The first routine sets the value (default 0), the second routine sets the minimum and maximum values that the counter will take (default -1000000 and 1000000) and the third routine sets the sizes of the small and large steps (default 0.1 and 1). For simple counters only the small step is used.
To obtain the current value of the counter use:
double fl_get_counter_value(FL_OBJECT *obj)Attribute Color1 controls the color of the background of the counter, color2 the color of the arrows in the counter.
To add an input field to a form you use the routine:
FL_OBJECT *fl_add_input(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is by default placed in front of the input field. The following types of input fields exist:
Whenever the user presses the mouse inside an input field a cursor will appear in it (and it will change color). Further input will appear inside this field. When the user presses the TAB key the input field is returned to the application program and the input focus is directed to the next input field. This also happens when the user presses the RETURN key but only if the form does not contain a return button. This does not work for multi-line input fields where return key is used to separate lines. Also when the user picks a new input field with the mouse, the current input object is returned.
To set the contents of the input field use the routine:
void fl_set_input(FL_OBJECT *obj, char str[])To obtain the string in the field (when the user has changed it) use:
[const] char *fl_get_input(FL_OBJECT *obj)
To add a menu to a form use the routine:
FL_OBJECT *fl_add_menu(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)It shows a box on the screen with the label centered in it. The following types are available:
When the menu appears the user can make a selection using the right mouse button or make no selection by clicking outside the menu. When he makes a selection the menu object is returned by the interaction routines.
To set the actual menu for a menu object, use the routine:
void fl_set_menu(FL_OBJECT *obj, const char *menustr)menustr describes the menu in the form used by XPopups. It should contain the menu items, separated by a bar, e.g., "First|Second|Third". Special tags can be used to indicate special attributes (not covered here, but see fl_set_menu_item_mode).
Whenever the user selects some menu item, the menu object is returned to the application program. To find the actual menu item selected by the user use:
int fl_get_menu(FL_OBJECT *obj)When the first item is selected 1 is returned, for the second item 2, etc. If no item was selected -1 is returned.
You can also obtain the text of the item selected:
const char *fl_get_menu_text(FL_OBJECT *obj)To obtain the text of any item, use the following routine:
const char *fl_get_menu_item_text(FL_OBJECT *obj, int n)To obtain the total number of menu items, use:
int fl_get_menu_maxitems(FL_OBJECT *obj)It is possible to add menu items to an existing menu using the call:
void fl_addto_menu(FL_OBJECT *obj, const char *menustr)Also routines exist to change a particular menu item or delete it:
void fl_replace_menu_item(FL_OBJECT *obj,int numb,const char *menustr) void fl_delete_menu_item(FL_OBJECT *obj, int numb)To clear the whole menu use the routine:
void fl_clear_menu(FL_OBJECT *obj)One can change the appearance of different menu items. In particular, it is possible to sometimes make them grey and unselectable and to put boxes with and without checkmarks in front of them. This can be done using the routine:
void fl_set_menu_item_mode(FL_OBJECT *obj, int numb, unsigned mode)mode is the display characteristics you want to apply to the chosen entry. For this parameter, the following symbolic constants exist:
unsigned int fl_get_menu_item_mode(FL_OBJECT *ob, int numb)It is possible to define keyboard shortcuts for particular menu items (not covered here).
Attribute Color1 controls the color of the box when not selected and color2 is the color when the menu is shown.
To change the font used in the popup menu (not the menu label) use the following routines:
void fl_setpup_fontsize(int size) void fl_setpup_fontstyle(int style)Currently there is not direct support for cascade menus in menu class. You can, however, get a cascade menu by using a popup and then attach the popup ID to a menu object via the following routine:
void fl_set_menu_popup(FL_OBJECT *ob, int pupID)For a menu so created, only fl_get_menu and fl_get_menu_text work as expected. Other services such as mode query etc. should be obtained via popup routines. You can use FL_MENU_BUTTON to initiate a callback and use XPopup directly within the callback.
To add a choice object to a form use the routine:
FL_OBJECT *fl_add_choice(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)It shows a box on the screen with the label to the left of it and the current choice (empty in the beginning) centered in the box. The object label is also used as the title of the popup if not empty.
The following types are available:
The other way is to use the left mouse button. In this case a menu appears from which the user can select the proper choice. In both cases, whenever a choice is selected (even when it is the original one) the object is returned to the application program.
The items in the list are numbered in the order in which they are inserted. The first item has number 1, etc.
To clear the list of choices, use the routine:
void fl_clear_choice(FL_OBJECT *obj)To add/delete a line to/from a choice object use:
void fl_addto_choice(FL_OBJECT *obj, const char *text) void fl_delete_choice(FL_OBJECT *obj, int line)One can also replace a line using:
void fl_replace_choice(FL_OBJECT *obj, int line, const char *text)To obtain the current choice in the choice object use the call:
int fl_get_choice(FL_OBJECT *obj)It returns the number of the current choice (0 if there is no choice).
You can also obtain the actual choice text using the call:
const char *fl_get_choice_text(FL_OBJECT *obj)NULL is returned when there is no current choice.
To obtain the text of a choice item, use the routine:
const char *fl_get_choice_item_text(FL_OBJECT *obj, int n)To obtain the total number of choices (items) use:
int fl_get_choice_maxitems(FL_OBJECT *obj)One can set various attributes of an item using the routine:
void fl_set_choice_item_mode(FL_OBJECT *ob, int numb, unsigned mode)mode is the same as that used in menu objects.
Finally, the application program can set the currently selected item in the choice by using one of:
void fl_set_choice(FL_OBJECT *obj, int line) void fl_set_choice_text(FL_OBJECT *obj, const char *txt)line is the number of the item to be selected. txt must be exactly the same string used in fl_addto_choice to add the item.
Attribute Color1 controls the color of the box and color2 is the color of the text in the box.
The current choice by default is shown centered in the box. To change the alignment of the choice text in the box, use:
void fl_set_choice_align(FL_OBJECT *ob, int align)To set the font size and style used inside the choice object use:
void fl_set_choice_fontsize(FL_OBJECT *obj, int size) void fl_set_choice_fontstyle(FL_OBJECT *obj, int style)Note that the above functions only change the font inside the choice object, not the font used in the popup. To change the font used in the popup, use:
void fl_setpup_fontsize(int size) void fl_setpup_fontstyle(int style)
It is possible to create a browser from which the user can select lines. In this way the user can make its selections from (possible) long lists of choices. Both single lines and multiple lines can be selected, depending on the type of the browser.
To add a browser to a form use the routine:
FL_OBJECT *fl_add_browser(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is placed below the box by default. The following types of browsers exist:
For FL_SELECT_BROWSER's, as long as the user keeps the mouse pressed,
the current line under the mouse is highlighted.
Whenever he releases the mouse the highlighting disappears and the browser
is returned to the application program.
The application program can now figure out which line was selected using the
call fl_get_browser().
An FL_HOLD_BROWSER works exactly the same except that, when the mouse
is released, the selection remains highlighted.
An FL_MULTI_BROWSER allows the user to select and de-select multiple lines.
Whenever he selects or de-selects a line the browser is returned to the
application program that can next figure out (using fl_get_browser())
which line was selected or de-selected.
When the user presses the mouse on a non-selected line,
he will select all lines he touches with his mouse until he releases it.
All these lines will become highlighted.
When the user starts pressing the mouse on an already selected line he
de-selects lines rather than selecting them.
To make a browser empty use:
void fl_clear_browser(FL_OBJECT *obj)To add a line to a browser use one of:
void fl_add_browser_line(FL_OBJECT *obj, const char *text) void fl_addto_browser(FL_OBJECT *obj, const char *text)The difference is that with the second call the browser will be shifted such that the newly added line is visible.
You can also insert a line in front of a given line. All lines after it will be shifted. Note that the top line is numbered 1 (not 0).
void fl_insert_browser_line(FL_OBJECT *obj, int line, const char *text)To delete a line (shifting the following lines) use:
void fl_delete_browser_line(FL_OBJECT *obj, int line)One can also replace a line using:
void fl_replace_browser_line(FL_OBJECT *obj, int line, const char *tex)Making many changes to a visible browser at the same moment, is very slow because the browser is redrawn after each change. The Forms Library has a mechanism for avoiding this using the calls fl_freeze_form() and fl_unfreeze_form().
To obtain the contents of a particular line in the browser, use:
const char *fl_get_browser_line(FL_OBJECT *obj, int line)It returns a pointer to the particular line of text.
It is also possible to load an entire file into a browser using:
int fl_load_browser(FL_OBJECT *obj, const char *filename)The routine returns whether or not the file name was successfully loaded. If the file name is an empty string the box is simply cleared. There is currently a limit of maximum 1024 bytes per line for fl_load_browser().
The application program can select or de-select lines in the browser. To this end the following calls exist:
void fl_select_browser_line(FL_OBJECT *obj, int line) void fl_deselect_browser_line(FL_OBJECT *obj, int line) void fl_deselect_browser(FL_OBJECT *ob)The last call de-selects all lines.
To check whether a line is selected, use the routine:
int fl_isselected_browser_line(FL_OBJECT *obj, int line)The following routine returns the number of lines in the browser:
int fl_get_browser_maxline(FL_OBJECT *obj)
The following routine tells how many lines are visible in the browser:
int fl_get_browser_screenlines(FL_OBJECT *ob)
To obtain the last selection made by the user, e.g. when the browser is returned, the application program can use the routine:
int fl_get_browser(FL_OBJECT *obj)It returns the line number of the last selection being made (0 if no selection was made). Top line is line 1. When the last action was a de-selection (only for FL_MULTI_BROWSER's) the negation of the line number is returned.
There are also calls to influence and query top line shown in the box (i.e., influence the position of the slider):
void fl_set_browser_topline(FL_OBJECT *obj, int line) int fl_get_browser_topline(FL_OBJECT *obj)It is possible to register a callback function that gets called when a line is double-clicked. To this end, the following function can be used:
void fl_set_browser_dblclick_callback(FL_OBJECT *ob, void (*cb)(FL_OBJECT *,long), long data)Of course, double-click callback makes most sense for FL_HOLD_BROWSER.
Finally the following routine can be used to scroll the text horizontally:
void fl_set_browser_xoffset(FL_OBJECT *ob, FL_Coord xoff)xoff is the offset in pixels.
Attribute Color1 controls the color of the box, color2 the color of the selection. The text color is the same as the label color.
To set the font size and style used inside the browser use:
void fl_set_browser_fontsize(FL_OBJECT *obj, int size) void fl_set_browser_fontstyle(FL_OBJECT *obj, int style)To align different text fields on a line, tabs can be embedded in the text.
The following routine turns the (vertical) scrollbar on and off:
void fl_set_browser_vscrollbar(FL_OBJECT *ob, int on)
void fl_get_browser_dimension(FL_OBJECT *ob, FL_Coord *x, FL_Coord *y, FL_COORD *w, FL_COORD *h)x and y are measured from the top-left corner of the form.
XPopups (XPups) are simple transient windows that show a number of choices the user can click on to select the desired options.
To define a new popup, use the following routines:
int fl_newpup(Window parent) int fl_defpup(Window parent, const char *str [, args...])Both functions allocate and initialize a new popup menu and return the menu identifier (-1 if error).
fl_defpup() in addition accepts a pointer to the text you want to add as a menu item. More than one item can be specified by using a vertical bar between the items, e.g., "foo|bar" adds two menu items.
The parent parameter specifies the window to which the pup belongs. In a situation where pup is used inside an object callback (e.g., FL_MENU_BUTTON) FL_ObjWin(ob) would suffice.
It is possible to pair an "item type" flag with each menu item to specify particular attributes of the item, such as shortcuts and callbacks, etc. (not covered here, but see also fl_setpup_mode).
You can add more menu items to an existing popup menu using the following routine:
void fl_addtopup(int menuID, const char *str [, args, ...])To display a popup, use the following routine:
int fl_dopup(int menuID)This function displays the specified popup menu until the user makes a selection. The value returned is the value of the item selected. However, if there are callback functions bound to the menu or menu item, the function is invoked and the value returned by fl_dopup is the executed function value. If no selection is made, function returns -1. To select an item, drag the mouse into the item and release the mouse.
It is also possible to bind keyboard keys to menu items (not covered here).
It is possible to modify the display characteristics of a given popup menu entry after its creation using the following routine:
void fl_setpup_mode(int menuID, int item_num, unsigned mode)The following modes (and bitwise ORing thereof) are available:
To obtain the mode of a particular menu item, use the following routine:
unsigned int fl_getpup_mode(int menuID, int item_num)menuId is the ID returned by fl_newpup or fl_defpup. item_num is the value of the item (it can be an item in one of the submenus of menuID).
The following routine can be used to obtain the menu item text:
const char *fl_getpup_text(int menuID, int item_num)In some situations, especially when the popup is activated by non-pointer events (e.g., as a result of an object shortcut) the default placement of popups based on mouse location might not be adequate or appropriate, thus XPup provides the following routine to override the default placement:
void fl_setpup_position(int x, int y)pair x,y specifies the location where the top-left corner of the popup should be.
This routine should be used immediately before invoking fl_dopup() and the position is not remembered afterwards.
A radio group can be reset programmatically using the following routine:
void fl_setpup_selection(int menuID, int item_val)Use the following routines to modify the default popup font style and size:
void fl_setpup_fontsize(int size) void fl_setpup_fontstyle(int style)The background color and text color of a popup can be changed using the following routine:
void fl_setpup_color(FL_COLOR bkcolor, FL_COLOR textcolor)By default, bkcolor is FL_COL1 and textcolor is FL_BLACK.
For item that has check box assocaited with it, the checked color (the default is blue) can be changed with the following routine:
void fl_setpup_checkcolor(FL_COLOR checkcolor)
To add a timer to a form you use the routine:
FL_OBJECT *fl_add_timer(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)There are at the moment three types of timers:
To set the timer to a particular value use:
void fl_set_timer(FL_OBJECT *obj, double delay)delay gives the number of seconds the timer should run. Use 0.0 to reset the timer.
To obtain the current delay left in the timer use:
double fl_get_timer(FL_OBJECT *obj)Attribute Color1 controls the color of the timer. Color2 is the blinking color.
To add an xyplot object to a form use the routine:
FL_OBJECT *fl_add_xyplot(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)It shows an empty box on the screen with the label below it. The following types are available:
Only FL_ACTIVE_XYPLOT takes mouse events by default. Clicking and dragging the data points (marked with little squares) will change the data and result in the object returned to the program. By default, the reporting happens only when the mouse is released.
In some situations, reporting changes as soon as they happen might be desirable. Use the following to force this behavior:
void fl_set_xyplot_return(FL_OBJECT *ob, int when)To obtain the current value of the point that has changed, use the following routine:
void fl_get_xyplot(FL_OBJECT *ob, float *x, float *y, int *i)where i is returned as the data index (starting from 0) and x,y is the actual data point. If no point is changed, i is set to -1.
To set or replace the data for an xyplot, use:
void fl_set_xyplot_data(FL_OBJECT *obj, float *x, float *y, int n, const char *title, const char *xlabel, const char *ylabel)x,y is the tabulated function, and n is the number of data points.
To load a tabulated function from a file use the following routine:
void fl_set_xyplot_file(FL_OBJECT *obj, const char *filename, const char *title, const char *xlabel, const char *ylabel)The data file should be an ASCII file consisting of data lines. Each data line must have two columns indicating the (x,y) pair with space, tab or comma separating the two columns. Lines that start with ! ; # are considered to be comments and are ignored.
To get a copy of the current FL_XYPLOT data, use:
void fl_get_xyplot_data(FL_OBJECT *ob, float x[], float y[], int *n)The caller must supply the space for the data.
All xyplot objects can be made aware of mouse clicks by using the following routine:
void fl_set_xyplot_inspect(FL_OBJECT *ob, int yes)Once an xyplot is in inspect mode, whenever the mouse is clicked and the mouse position is on one of the data point, the object is returned to the caller or whose callback is called. You can use fl_get_xyplot() to find out which point the mouse is clicked on.
There are several routines to change the appearance of an xyplot, but are not covered here.
Color1 controls the color of the box and Color2 controls the actual xyplot color.
To add a canvas to a form you use the routine:
FL_OBJECT *fl_add_canvas(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)The label is not drawn but used as the window name for possible resource and playback purposes. The following types of canvases exist:
By default, the only event a canvas will receive is Expose. To receive other events, the application program has to select them. One way to do this is by adding an event handler.
To register an event handler, use:
void fl_add_canvas_handler(FL_OBJECT *ob, int event, FL_HANDLE_CANVAS handler, void *user_data)event is the XEvent type, e.g., Expose etc.
To remove a registered handler, use the following routine:
void fl_remove_canvas_handler(FL_OBJECT *ob, int event, FL_CANVAS_HANDLER handler)To obtain the window ID of a canvas, use the following routine:
Window fl_get_canvas_id(FL_OBJECT *ob)or use the macro FL_ObjWin(canvas_object)
Of course, window ID has meaning only after the form is shown.
To add an OpenGL canvas to a form, use the following routine:
FL_OBJECT *fl_add_glcanvas(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label)where type is the same as the generic canvas.
A glcanvas so created will have the following attributes by default: GLX_RGBA, GLX_DEPTH_SIZE,1, GLX_RED_SIZE,1, GLX_GREEN_SIZE,1, GLX_BLUE_SIZE,1, GLX_DOUBLEBUFFER.
The application program can modify these defaults using the following routine (before the creation of glcanvases):
void fl_set_glcanvas_defaults(const int *attributes)See glXChooseVisual for a list of valid attributes.
To get the current defaults, use the following routine:
void fl_get_glcanvas_defaults(int *attributes)