The Form Designer (estratto dal manuale)

The Form Designer is an interactive GUI builder written to help you in designing the layout of your forms. The application program has to:

Getting started

To start up the Form Designer simply type fdesign without any argument (you can type fdesign -help for a list of possible command-line options).

A black window (the main window) will appear at the bottom-left corner of the screen. This is the window in which you can create your forms.

Next the control panel appears at the top-left corner of the screen. The control panel consists of five parts:

  1. The menu bar.
  2. A list of forms you are working on (initially empty). You can use this list to switch from form to form.
  3. A list of all groups in the form you are working on (initially empty).
  4. A list of all different types of objects that can be placed on the forms. You can use the mouse to select the type of object you want to add to the form.
  5. A number of buttons. Each of these buttons is bound to a function key . You can either press the buttons with the mouse or press the function keys on the keyboard.

Forms

Creating a form

To create a new form click with the mouse on the button labeled New Form.

You will have to provide a name (which must be a legal C variable name). Now the background of the form appears in the main window, and the form name is added in the list of forms in the control panel.

Resizing a form

There are two ways to change the size of a form: Note that objects lying outside the form will be invisible when the form is shown by the application program.

Renaming a form

To change the name of the current visible form, press the button labeled Rename Form under the list of forms.

Deleting a form

To delete the current form, press the button labeled Delete Form.

Objects

Adding an object

To add an object to the form, choose the type of object in the control panel by clicking in the list of object classes. Next move the mouse into the form you are creating and drag the mouse while pressing the left mouse button. Keep the mouse button pressed and create a box that has the required size. Release the button and the object will appear.

Note that a red outline appears around the new object. This means that the object is selected.

By default, the position and size of the object is rounded to multiples of 10 pixels (this can be changed, see below on alignments).

Selecting objects

To perform operations on objects that are already visible in the form, we first have to select them.

Press the right mouse button inside the object you want to select. A red outline will appear, indicating that the object is selected.

To select multiple objects, use the right mouse button to draw a box around all the objects you want to select. All objects that lie fully inside the box will be selected.

To add objects to an already existing selection, hold do wn the Shift key and press the right mouse button inside the objects.

You can remove objects from the selection by doing the same on an already selected object.

It is possible to select all objects at once using the function key F4.

The backface of the form can be selected, but never in combination with other objects. Only two operations are allowed on it: changing its attrib utes and scaling it (which scales the size of the form).

Moving and scaling objects

To move an object or a collection of objects to a new place, first select it, then press the middle mouse button inside the bounding box (not near one of the corners) and move the box to its new position. To scale the object or objects, pick up the bounding box near one of its corners (inside the red squares) and scale it, again using the middle mouse button.

When holding the SHIFT key while moving an object or group of objects, first a copy of the object(s) is made and the copy is moved. This allows for a very fast way of putting a number of equal objects on the form.

For precise object movement, the cursor keys can be used. Each pressing of the four directional cursors moves the object 10 pixels. To change the step size, precedes the cursor keys with 0-9 with 0 indicating 10 pixels. If SHIFT is down, instead of moving the object, the object size is increased or decreased by the step size.

Aligning objects

Sometimes you have a number of objects and you want to align them in some way. To this end press the button labeled Align. A special form will appear in the top right corner. Now select the objects you want to align. Next, press one of the alignment buttons in the form. The objects are kept in the same left to right or bottom to top order .

In the alignment form you can also indicate the snapping size using the counter at the bottom. Choose 0 if you don't want to snap positions. Default the snapping is 10 pixels. Snapping helps in making objects the same size and in making them nicely aligned.

Raising and lowering

The objects in a form are drawn in the order in which they are added. Sometimes this is undesirable. For example, you might decide at a later stage to put a box around some buttons. Because you add this box later, it will be drawn over the buttons thus making the buttons in visible.

The Form Designer makes it possible to raise objects (bring them to the top) or lower them (put them at the bottom). So you can lower the box to move it under the buttons.

First select the objects and next press the function key F2 to lower the selection or F3 to raise it.

Setting attributes

To set attributes like type, color, label, etc., of an object first select it and next press the function key F1. A form will appear in which you can indicate all the different attributes.

If only one object is selected you can change all its attributes, including its label, name, etc.

It is also possible to change the attributes of multiple objects as long as they all are of the same class. In this case you cannot change the label, name, etc. because you probably want them to remain different for the objects.

Object names and callback routines

Three more fields can be filled in in the attributes form: name, callback and argument.

Name indicates the name of the object. If you type in a name here the object will be known to the application program under this name. Names should be legal C variable names.

It is possible to use arrays of objects. E.g. if you define some objects as tt[0], tt[1] and tt[2] the piece of C-code produced by the Form Designer will contain a declaration of an array tt of size 3.

Callback indicates the callback routine. If you type in something here, this routine will be bound to the object. In this case you also have to provide an argument that must be an integer (or cast to integer). The application program will have to provide the callback routine.

Note that when copying objects these fields are also copied. So watch out for these after copying an object.

Cut, Copy and Paste

You can remove objects from the form by first selecting them and next pressing function key F12 or double-clicking the left mouse button.

The objects will disappear but are in fact saved in a buffer . You can put them back in the form, or in another form, by pasting them using F10. It is also possible to put a copy of the selection in the buffer using F9. This selection can now be put into the same form or into a different form.

Groups

Sets of radio buttons must be placed inside groups. Groups are also useful for other purposes. E.g. you can hide a group inside an application program with one command.

In the control panel there is a list of groups in the current form. To create a group, select the objects that should come in the group and press the function key F7. You will be prompted for the name of the group. This should be a legal C variable name (under which the group will be known to the application program).

Each object can be in only one group. So if you select it again and put it in a new group, it will be removed from its old group. Groups that become empty this way automatically disappear from the list. When putting objects in a group they will be raised.

In the list of groups it is always indicated which groups are part of the current selection. Only the groups that are fully contained in the selection are indicated, not those that are only partially contained in it. It is also possible to add or delete groups in the current selection by pushing the mouse on their name in the list.

There is no mechanism to add an object to a group directly. This can be achieved using the following procedure. Select the group and the new object and press F7 to group them. The old group will be discarded and a new group will be created. You only have to type in the group name again.

To un-group the objects in an existing group, select the group and press F8.

Hiding and showing

Sometimes it is useful to temporarily hide some objects in your form. In particular when you have sets of overlapping objects.

To this end, select the objects you want to hide and press F6. The objects (though still selected) are now invisible. To show them again press F5.

A problem might occur here. When you press F5 only the selected objects will be shown again. But once an object is in visible it can no longer be selected. Fortunately, you can always use F4 to select all objects, including the in visible ones, and press F5 after that. It is better, though, to first group the objects before hiding them. Now you can select them by pressing the mouse on the group name in the group browser.

Testing forms

To test the current form, press the button labeled Test.

The form will be displayed in the center of the screen. A panel will appear at the top right corner of the screen. This panel will show you the objects that will be returned and the callback routines called when working with the form.

In this way you can verify whether the form behaves correctly and whether all objects have either callback routines or names (or both) associated with them. You can play with the form as long as you want. When ready, press the button Stop Testing .

Note that any changes you make to the form while testing do not show up when saving the form. E.g. filling in an input field or setting a slider does not mean that in the saved code the input field will be filled in or the slider set.

Saving and loading forms

To save the set of forms created select the item Save from the File menu. You will be prompted for a file name. The file name should end with .fd. So for example, choose ttt.fd.

The Form Designer now creates three files:

  1. ttt.c contains a readable piece of C code that creates the forms you designed.
  2. ttt.h contains the corresponding header file for inclusion in your application program.
  3. ttt.fd contains a description of the forms in such a way that the Form Designer can read it back in later.
Depending on the options selected from the Options menu, two more files may be emitted. Namely the main program and callback function templates. They are named ttt_cb.c and ttt_main.c respectively.

Code files

There are two different kind of formats for the C-code generated.
  1. The default format allows more than one instances of the form created and uses no global variables.
  2. The other format, activated by altformat on the command line, or from the Options menu by selecting Alt Format, uses global variables and does not allow more than one instantiation of the designed forms. This format has a global routine that creates all the forms defined, which by default is named create_the_forms.
Depending on which format is output, the application program typically only needs to include the header file and call the form creation routine.

To illustrate the differences between the two output formats and the typical way an application program is setup, we look at the following hypothetical situation: We have two forms, foo and bar, each of which contains several objects, say fnobj1, fnobj2 etc. where n=1,2 .

Default format

The default output format will generate the following header file:
#ifndef FD_foobar_h_ 
#define FD_foobar_h_ 

/* call back routines if any */ 
extern void callback(FL_OBJECT *,long);

typedef struct 
{  FL_FORM *foo;
   FL_OBJECT *f1obj1; 
   FL_OBJECT *f1obj2;
   void *vdata; 
   long ldata;
} FD_foo; 

typedef struct
{  FL_FORM *bar;
   FL_OBJECT *f2obj1;
   FL_OBJECT *f2obj2;
   void *vdata; 
   long ldata;
} FD_bar; 

extern FD_foo *create_form_foo(void);
extern FD_bar *create_form_bar(void); 

#endif /* FD_foobar_h */ 
and the corresponding C file:
#include "forms.h" 
#include "foobar.h" 

FD_foo *create_form_foo (void)
{  ... create and return a form of type FD_foo ... }

FD_bar *create_form_bar (void)
{  ... create and return a form of type FD_bar ... }
The application program would look something like the following:
#include "forms.h"
#include "foobar.h" 

/* add call back routines here */ 

main (int argc, char *argv[]) 
{
  FD_foo *fd_foo;
  FD_bar *fd_bar; 

  fl_initialize(...);

  fd_foo = create_form_foo();
  init_fd_foo(fd_foo); /* application UI init routine */

  fd_bar = create_form_bar();
  init_fd_bar(fd_bar); /* application UI init routine */ 

  fl_show_form\(fd_foo->foo, ...);
  /* rest of the program */
}
Application program can create more than one instances of the form if needed.

Alternative format

The alternative format outputs something like the following:
/* callback routines */
extern void callback(FL_OBJECT *, long);

extern FL_FORM *foo, *bar; 
extern FL_OBJECT *f1obj1, f1obj2...:
extern FL_OBJECT *f2obj1, f2obj2...;

extern void create_form_foo(void);
extern void create_form_bar(void);

extern void create_the_forms(void); 
The C-routines:
FL_FORM *foo, *bar; 
FL_OBJECT *f1obj1, *f1obj2...;

void create_form_foo(void)
{  if (foo) return; 
   foo = fl_bgn_form(...);
   ...
}

void create_form_bar(void)
{  if (bar) return;
   bar = fl_bgn_form(...);
   ...
}

void create_the_forms(void)
{  create_form_foo();
   create_form_bar();
}
Normally the application program would look something like this:
#include "forms.h"
#include "foobar.h" 

/* The call back routines */ 

main(int argc, char *argv[])
{  fl_initialize(...);
   create_the_forms();
   /* rest of the program */
} 
Note that although the C-routine file in both cases is easily readable, editing it is strongly discouraged. If you were to do so, you will have to redo the changes whenever you call fdesign again to modify the layout.

Form file

The third file created, ttt.fd, is in a format that can be read in by the Form Designer. It is easy readable ASCII but you had better not change it because not much error checking is done when reading it in.

To load such a file select the Open from the File menu. You will be prompted for a file name. The current set of forms will be discarded, and replaced by the new set.

You can also merge the forms in a file with the current set. To this end select Merge from the File menu.