Creating Forms
**************

Creating and Changing Forms
===========================

To create a new form press the button labeled "New Form", indicate the enclosing box of the form and type in a (unique) name for the form. The form is shown in the main window and objects can be added to it.

There are two ways to change the size of a form at a later stage. The easiest way is to simply change the size of the main window and the form will resize itself to fit the new size. Or you can select the bottom box of the form, using the right mouse button. Next grab the box using the middle mouse at the lower-right corner and scale it. Note that objects lying outside the form will be invisible when the form is shown by the application program.

To change the name of the current visible form, press the button labeled "Rename Form" above the list of forms. You will be prompted for the new form name.

To delete a form, press the button labeled "Delete Form". The current form will be removed.

Adding Objects
==============

To add an object, choose the class of the object from the list of object classes in the middle of the control panel. Next drag the left mouse button within the form and an outline showing the current size of the object will appear. When the size is correct release the mouse button.

Note that 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. Any mouse button can be used for selecting objects. Simply single-click on the object you want to select. A red outline will appear, indicating that the object is selected. In some cases when the currently selected object is large and encloses some smaller objects in it, using the left mouse button might not allow selection of the enclosed small objects. In this case use the the right mouse button. Another way of selecting objects is to use the <Tab> key or the <F11> or the button labeled F11, which iterates over the object list and selects a new object upon each press.

It is also possible to select multiple objects. To this end, draw a box by dragging the mouse around all the objects you want to select. All objects that lie fully inside the box will be selected. Each selected object will get a red outline and a red bounding box is drawn around all of them.

To add objects to an already existing selection, hold down the <Shift> key and press the right mouse button inside the object. You can remove objects from the selection by doing the same on an already selected object.

It is possible to select all objects (except for the backface) at once using the function key <F4>. One note on the backface of the form: Although this is a normal object, it can not be treated in the same way as the other objects. It can be selected, but never in combination with other objects. Only two operations are allowed on it: changing its attributes and scaling it (which scales the size of the form).

Moving and Scaling
==================

Moving and scaling of objects is done using the middle mouse button. To move an object or a collection of objects to a new place, first select it (them) as described above. Next 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.

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 duplicating (cloning) objects on the form: First put one on the form, change the attributes as required and next copy it.

For precise object movement, the cursor keys can be used. Each press of the four directional cursors keys moves the object by 5 pixels. To change the step size, precede the cursor keys with 0-9 with 0 indicating 10 pixels. If <Shift> key is kept pressed 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, e.g. centered or all starting at the same left position, etc. To this end press the button labeled "Align". A special form will appear in the top right corner. You can leave this form visible as long as you want. You can hide it using the button labeled "Dismiss" on the form or by clicking the "Align" button again.

First select the objects you want to align. Next, press one of the alignment buttons in the form. The buttons in the top row have the following meaning: flush left, center horizontally, flush right, and make the objects have equal distances in horizontal direction (see below). The buttons in the bottom row mean: align to bottom, center vertically, align to top, and make all objects have the same vertical distance. Note that alignments are relative to the selection box, not to the form. Equal distance alignment means that between all the objects an equal sized gap is placed. 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 snapping is 10 pixels. Snapping helps in making objects of the same size and aligning them nicely.

The "Undo" button undoes the last alignment change. It is an undo with a depth of 1, i.e. you can only undo the last change and an undo after an undo will undo itself. Note however, that any modification to the selected objects invalidates the undo buffer.

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 invisible (if you put a framebox over a button, the button will be visible but appears to be inactive!). This is definitely not what you want. 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 e.g. a box to move it under some buttons. Raising or lowering objects is very simple. First select the objects using the right mouse button and next press the function key <F2> to lower the selection or <F3> to raise it.

Another use of raising and lowering is to change the order in which input field receive focus via the <Tab> key. Input fields focus order is the same as the order in which they are added to the form. This can become a problem if another input field is needed after the form is designed because this extra input field will always be the last among all input field on the form. Raising the objects becomes handy to solve this problem. What really happens when a object is raised is that the raised object becomes the last object added to the form. This means you can re-arrange the focus order by raising all input fields one by one in the exact order you want the focus order to be, and they will be added to the form in the order you raised them, thus the input focus order is what you intended.

Setting Attributes
==================

To set attributes like type, color, label, etc., of an object first select it (using the right mouse button) and next press the function key <F1> (or click on the button labeled "F1"). 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.

A form will appear in which you can indicate the different settings. Before we continue, the organization of the attributes form and classification of attributes need a little explanation. Attributes of an object are divided into two categories. The generic attributes are shared by all objects. These include type, color, label, callback function etc. The specific attributes are those that are specific to a particular object class, such as slider bounds, precision etc. When the attribute form is first shown, only the generic attributes are shown. Press on tab rider "Spec" to get to a form for the object class specific attributes (press the tab rider "Generic" to switch back to the generic attributes part).

Generic Attributes
==================

The form for setting generic attributes contains four fields for setting different groups of generic object properties, discussed in the following. Once you are satisfied with the settings, press the button labeled "Accept" and the form will disappear. If you don't want to change the attributes after all press the button labeled "Cancel". You may also reset the values to their initial settings by clicking on the "Restore" button.

Basic Attributes
----------------

The basic attributes include the type, boxtype, name, label string, the callback function with its arguments associated with the object and a shortcut.

For most object classes several different types exist. The type of the object under consideration can be selected via a choice object.

Most objects can also be drawn using different boxtypes. Normally, the default should do, but using the choice object labeled "BoxType" you can switch to a different box type (but note that not all choices may result in a different way the object is drawn).

Nearly all objects have a label that can be drawn at different positions within or outside of the object. The input field labeled "Label" lets you set this label string (it may also include return characters, i.e. \n, for line breaks).

An object may have a name by which it can be accessed within the program. This name must be a valid C (or simple C++) variable identifier and can be set via the input field labeled "Name". You need to make sure that there are no objects with the same name!

If instead of having e.g. the function fl_do_forms() return when an object is triggered a callback is to be called you can set the name of the callback function in the input field labeled "Callback". Obviously, this must be a valid C or C++ function name. When a callback function is set you must also specify the argument passed to the callback function together with the object's address via the input field labeled "Argument". This normally will be a (long) integer (defaulting to 0 if not specified). Using this value it is e.g. possible to distinguish between different objects, all using the same callback function.

Font
----

In the field labeled "Font" you can set properties of the font to be used for the label of the object. You can select between different types of fonts, the style the label is drawn in (normal, shadowed, engraved or embossed) and the size of the font to be used. All three types of properties can be selected via choice objects.

Misc. Attributes
----------------

The field labeled "Misc. Attributes" allows the setting of a number of attributes that don't fit into any other category.

First you can set the alignment of the object's label. It can be placed inside the object or outside of it and in 9 different positions. Use the choice objects labeled "Label/Align" and "In/Out" for this purpose.

Another important property of an object is how it reacts if the size of the form it belongs to is changed. It may keep its original size or may be resized in x- or y-direction or both. The details are controlled via its resize and gravity properties as described in chapter 4.

With the choice objects labeled "Resize" you can control if an object is to be resized in x- or y-direction or both or none. You may also specify if the object's upper left hand corner or its lower right hand corner is supposed to keep a fixed distance from the form's borders via the choice objects labeled "NW Gravity" and "SE Gravity". Please note that these properties aren't orthogonal, with the NWGravity and SEGravity overriding the resize property if necessary (also see the program grav in the demo directory that lets you experiment with these properties).

Colors
------

Within the "Color" field you can set three colors for the object. The colors of the object itself are controlled via the buttons labeled "Color 1" and "Color 2", while the button labeled "LabelColor" is for setting the color the label is drawn in.

Clicking on any of the three buttons will result in a new form being shown in which you can select one of the predefined colors from the internal colormap. You also can select one of the "free" colors but since these colors aren't set yet they will appear as black in the form for selecting the color.

While it's rather obvious what the label color is, the meaning of "Color 1" and "Color 2" is less well-defined and varies with the class and type of the object. E.g. for (normal buttons the first color is the normal color of the button while the second one is the color it's drawn with while the button is pressed while for a browser that allows selection the first color is the background color and the second color is the color selected lines are highlighted with. Since there are too many combinations of object classes and types to be discussed here comprehensively please refer to a following chapter where the exact properties of all objects are described in detail.

Object Specific Attributes
==========================

Many objects have attributes that are considered to be intrinsic to the objects, such as slider bounds, precision etc. You can access these attributes (if existent_ via the tab rider "Spec". In most cases the meaning of these attributes hopefully is self-explanatory (otherwise see the detailed description of the different object classes in Part III) and all changes made are shown immediately so you can see what effects the changes have on the object. Once satisfactory results have been achieved press button labeled "Accept" to accept the settings (clicking on the tab rider "Generic" has the same effect). Two additional buttons, "Cancel" and "Restore", are available to cancel the changes (and quit the attributes setting form) and restore the defaults, respectively.

One particular aspect of the pixmap/bitmap button initialization needs a little more explanation as the setting of button labeled "Use data" has no effect on the appearance of the button but nonetheless affects the generated code. By default, the "Use data" button is off, indicating the pixmap/bitmap file specified is to be loaded dynamically at run time via fl_set_pixmapbutton_file() (or the bitmap counterpart). If "Use data" is on, the specified file and its associated data will be #include'd at compile time so the data becomes part of the code. Depending on the application setup, you may choose one method over the other. In general, including the data in the code will make the code slightly larger, but it avoids problems with not finding the specified file at runtime. The button labeled "Full Path" only applies if "Use Data" is on. If "Full Path" is also on, the pixmap file will be #include'd using the full path, otherwise only the filename is used, presumably the compile process will take care of the path via -I flag in some system dependent way. In general, not using the full path is more flexible.

Cut, Copy and Paste
===================

You can remove objects from the form by first selecting them and next pressing function key <F12> or simply by 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>. Note that only the last collection of deleted objects is saved in the buffer.

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. This allows for a simple mechanism of making multiple copies of a set of objects and for moving information from one form to another.

To clone the currently selected object, hold down the <Shift> key and then drag the selected object to a new position. The cloned object will have exactly the same attributes as the original object except for object name and shortcut keys. Should these be cloned, the generated code would not be compilable (or cause runtime misbehavior).

Groups
======

As described in the tutorial about the Forms Library, 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. Hence, the Form Designer has some mechanism to deal with groups.

In the control panel there is a list of groups in the current form. As long as you don't have groups, this list will be empty. 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) or should be left empty. This name will be added to the list. In this way you can create many groups. Note that 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. This is unavoidable due to the structure of groups.)

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.

Note that there is no mechanism to add an object to a group directly. This can, however, 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.

Sometimes you may want to un-group the objects in an existing group, i.e. get them out of the group they are currently in. To this end simply select the group and press <F8>. (This only works if one group is selected.)

You can use the menu "Rename group" from the "Group" menu to change the name of a selected group. If multiple groups are selected only the name of the first group gets changed.

Hiding and Showing Objects
==========================

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 invisible it can no longer be selected. Fortunately, you can always use <F4> to select all objects, including the invisible 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 anf a panel appears at the top right corner of the screen. This panel shows you the objects as they are 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 also resize the form (if the backface of the form allows resizing) to test the gravity and resizing settings. You can play with the form as long as you want. When ready, press the "Stop Testing" button.

Note that any changes you made to the form while testing (including its size) 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's preset value.