Simple XForms examples

Here you find some very simple programs on how you can use the XForms library. This isn't meant as real world examples (or as a tutorial) but just should demonstrate "how it works" in principle.

A button in a window

The following short program opens up a window that contains a single button with the label "Hello world". If you click on the button the window gets closed again and the program ends (as I warned you, it's a very sinple program;-)

#include <forms.h>

int main(int argc, char **argv)
{
    FL_FORM *form;

    fl_initialize(&argc, argv, 0, 0, 0);

    form = fl_bgn_form(FL_UP_BOX, 230, 100);
    fl_add_button(FL_NORMAL_BUTTON, 20, 20, 190, 60, "Hello world");
    fl_end_form();
 
    fl_show_form(form, FL_PLACE_MOUSE, FL_FULLBORDER, "Hello, world!");

    fl_do_forms();

    fl_hide_form(form);
    fl_finish();
    return 0;
}

The first function called in the program, fl_initialize(), initializes the XForms library (and extracts command line arguments meant for XForms). That out of the way a "form" is defined (which ofter corresponds to a window to be shown) and populates it with a single button. Once the form is defined it gets drawn on the screen with a call of fl_show_form().

Window of first examples program

Now follows the main loop of the program in which we wait for something the user does. This happens in the function fl_do_forms(). Since this is a very simple program not much can happen - the only thing the user can do is to click on the button. If that happens the function returns and the program ends after closing the window.

(Please note: the borders around the window may look a bit different on your system from what's shown in the picture above - they aren't created by XForms but by the window manager, a program running in the background which, beside other things, puts "decorations" around the windows of other programs. How these decorations look like thus depends on the window manager being used.)

Two buttons

Because it gets a bit boring to have just a single button that doesn't do anything else than ending the program here's a slightly more complicated example, featuring two buttons:

#include <stdio.h>
#include <forms.h>

int main(int argc, char **argv)
{
    FL_FORM *form;
    FL_OBJECT *obj;

    fl_initialize(&argc, argv, 0, 0, 0);

    form = fl_bgn_form(FL_UP_BOX, 230, 180);
    obj = fl_add_button(FL_NORMAL_BUTTON, 20, 20, 190, 60, "Hello world");
    fl_add_button(FL_NORMAL_BUTTON, 70, 100, 90, 60, "Quit");
    fl_end_form();
 
    fl_show_form(form, FL_PLACE_MOUSE, FL_FULLBORDER, "Hello, world!");

    while (fl_do_forms() == obj)
        printf("Hello world\n");

    fl_finish();
    return 0;
}

As it's easy to see the main differences are that instead of one button two are generated and that the return value of fl_do_forms() is used. The program also demonstrates that the function for adding a button, fl_add_button(), does return something useful, a pointer to a structure of type FL_OBJECT. All objects in a GUI you create with XForms are of this type and uniquely identify the object.

Window of second examples program

This is now used in the main loop of the program. fl_do_forms() returns a pointer to the object that was clicked on by the user. If it was the button with the label "Hello word" now the string "Hello world\n" is printed to standard output and the loop is restarted. Only if the button labeled "Quit" is pressed the loop and thus the program ends.

While this program is still extremely simple, it demonstrates nicely the typical way programs with a graphical user interface are written: after creating the GUI they go into a loop in which they wait for user interactions, doing some specific work for each event initiated by the user.

Callbacks

If you have more than a very small number of objects comparing them to what fl_do_forms() returns each time becomes quite tedious (and your program would probably look rather horrible). Thus there's a more powerful mechanism to tell XForms to execute some code on an event for an object, callbacks. Lets rewrite the above program using a callback for the first button.

#include <stdio.h>
#include <forms.h>

static void button_cb(FL_OBJECT *obj, long data)
{
    printf("Hello world\n");
}

int main(int argc, char **argv)
{
    FL_FORM *form;
    FL_OBJECT *obj;

    fl_initialize(&argc, argv, 0, 0, 0);

    form = fl_bgn_form(FL_UP_BOX, 230, 180);
    obj = fl_add_button(FL_NORMAL_BUTTON, 20, 20, 190, 60, "Hello world");
    fl_set_object_callback(obj, button_cb, 0);
    fl_add_button(FL_NORMAL_BUTTON, 70, 100, 90, 60, "Quit");
    fl_end_form();
 
    fl_show_form(form, FL_PLACE_MOUSE, FL_FULLBORDER, "Hello, world!");

    fl_do_forms();

    fl_do_forms();
    return 0;
}

This program behaves exactly as the previous one (and its window looks the same, too). But instead of analyzing the return value of fl_do_forms() we now make sure that fl_do_forms() won't return when the first button is pressed. Instead we have created a function, button_cb(), to be called when this button is pressed and, by using fl_set_object_callback(), associated it with the object for the first button. This takes care of making XForms call our function button_cb() whenever this button is pressed. Thus fl_do_forms() will only return when the second button, labeled "Quit", gets pressed.

(When you look at the callback function you will notice that it has two arguments (which aren't used in this example). The first one is a pointer to the object the callback function is invoked for and the second one is additional data that can be set in fl_set_object_callback() (as its final argument). Thus a single callback function can be used for more than one object.)

Compiling the examples

The exact method for compiling these programs may depend a bit on the system you are using. Thus here we can only show how it's done one UNIX-like systems. If the XForms library has been installed all you should need is a single command like

      cc -o xftest xftest.c -lforms -lX11
	

This, of course, assumes that you have stored the code of the example program in a file called xftest.c.

Other object types

While we have only used buttons in the above examples (and then only a single type of button, but XForms comes with 9 different types of them) there are, of course, a lot more types of objects. The most simple ones are static objects like boxes, frames, text objects, bit- and pixmaps, (analog and digital) clocks and objects for displaying charts (like pie charts etc.), most of them coming with a number of sub-types.

Then there are objects that allow the user to adjust values, like sliders, scrollbars, dials, counters, thumbwheels and more. To be able to enter texts, numbers or dates there are several different input objects. If you want the user to select one out of several alternatives you can use select, menu and popup objects. Then there are also browser objects in which you can display text or whole files (scrollable if necessary) and the user can select single or multiple lines. Further, there are also so-called "container" objects, e.g. tab folders, into which you can put several forms and the user can select which form (s)he wants to work with by selecting it via tab riders at the top. And, of course, there's also a canvas object, i.e. an object into which you draw freely whatever you want. And if that's still not enough there's support writing your own objects to do something which isn't implemented yet.

And, of course, for very common tasks there are the so-called "goodies". They include file selectors, boxes for messages or selections between up to three alternatives.

Further reading

Got curious? Go straight to the documentation of the XForms library.


Last modified: January 6, 2014 by Jens Thoms Törring Valid CSS! Valid XHTML 1.0 Strict