@node Part II Creating Forms
@chapter Creating Forms

@ifnottex

@menu
* Creating and Changing Forms::
* Adding Objects::
* Selecting Objects::
* Moving and Scaling::
* Aligning Objects::
* Raising and Lowering::
* Setting Attributes::
* Generic Attributes::
* Object Specific Attributes::
* Cut, Copy and Paste: Copy and Paste
* Groups::
* Hiding and Showing Objects::
* Testing Forms::
@end menu

@end ifnottex


@node Creating and Changing Forms
@section 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.


@node Adding Objects
@section 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.


@node Selecting Objects
@section 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
@code{<Tab>} key or the @code{<F11>} or the button labeled @code{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
@code{<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 @code{<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).


@node Moving and Scaling
@section 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 @code{<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 @code{<Shift>} key is kept pressed down,
instead of moving the object, the object size is increased or
decreased by the step size.


@node Aligning Objects
@section 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.

@ifhtml
@center @image{images/fd_align}
@end ifhtml
@ifnothtml
@center @image{images/fd_align,9cm}
@end ifnothtml

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.


@node Raising and Lowering
@section 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 @code{<F2>} to lower the
selection or @code{<F3>} to raise it.

Another use of raising and lowering is to change the order in which
input field receive focus via the @code{<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.


@node Setting Attributes
@section 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 @code{<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).


@node Generic Attributes
@section 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.

@ifnottex

@menu
* Basic Attributes::
* Font::
* Misc. Attributes::
* Colors::
@end menu

@end ifnottex

@node Basic Attributes
@subsection 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. @code{\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 @code{@ref{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.


@node Font
@subsection 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.


@node Misc. Attributes
@subsection 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 @file{grav} in the @file{demo} directory that lets you
experiment with these properties).


@node Colors
@subsection 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.


@node Object Specific Attributes
@section 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 @code{@ref{fl_set_pixmapbutton_file()}}
(or the bitmap counterpart). If "Use data" is on, the specified file
and its associated data will be @code{#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 @code{#include}'d using the full
path, otherwise only the filename is used, presumably the compile
process will take care of the path via @code{-I} flag in some system
dependent way. In general, not using the full path is more flexible.


@node Copy and Paste
@section Cut, Copy and Paste

You can remove objects from the form by first selecting them and next
pressing function key @code{<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 @code{<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
@code{<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 @code{<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).


@node Groups
@section 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 @code{<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 @code{<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 @code{<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.


@node Hiding and Showing Objects
@section 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 @code{<F6>}. The objects
(though still selected) are now invisible. To show them again press
@code{<F5>}. A problem might occur here. When you press @code{<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 @code{<F4>} to select all objects, including the invisible ones,
and press @code{<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.


@node Testing Forms
@section 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.
