@node Part IV The Type FL_OBJECT
@chapter The Type @code{FL_OBJECT}

Each object has a number of attributes. Some of them are used by the
main routine, some have a fixed meaning and should never be altered by
the class routines and some are free for the class routines to use.
Please always use accessor methods when available instead of using or
changing the object's properties directly. Below we consider some of
them that are likely to be used in new classes.
@table @code
@item int objclass
This indicates the class of the object (e.g., @code{FL_BUTTON},
@code{FL_SLIDER}, @code{FL_NEW} etc.) The user can query the class of
an object using the function @code{@ref{fl_get_object_objclass()}}.

@item int type
This indicates the type of the object within the class. Types are
integer constants that should be defined in a header file named after
the object class, e.g., @file{NEW.h}. Their use is completely free.
For example, in the slider class the type is used to distinguish
between horizontal and vertical sliders. At least one type should
exist and the user should always provide it (just for consistency).
They should be numbered from 0 upwards. The user can query the type
of an object using the function @code{@ref{fl_get_object_type()}}.

@item int boxtype
This is the type of the bounding box for the object. The handling
routine for the object, e.g., @code{handle_NEW()}, has to take care
that this is actually drawn. Note that there is a routine for drawing
boxes, see below. The user can change or query the boxtype of an
object with the functions @code{@ref{fl_set_object_boxtype()}} and
@code{@ref{fl_get_object_boxtype()}}.

@item FL_Coord x, y, w, h
These are the coordinates and sizes that indicate the bounding box of
the object. They always have to be provided when adding an object. The
system uses them e.g., to determine if the object is below the mouse.
The class routines should use them to draw the object in the correct
size, etc. Note that these values will change when the user resizes
the form window. So never assume anything about their values but
always recheck them when drawing the object. The routines
@code{@ref{fl_get_object_geometry()}},
@code{@ref{fl_get_object_position()}} and
@code{@ref{fl_get_object_size()}} should be used to determine position
and/or size. To change the position and/or size of an object never
change the elements of the structures directly (except in a function
like @code{fl_add_NEW()}) but always use
@code{@ref{fl_set_object_geometry()}},
@code{@ref{fl_set_object_position()}},
@code{@ref{fl_set_object_size()}} and
@code{@ref{fl_move_object()}}!

Also note that the @code{y}-member is always relative to the top of
the form the object belongs to, even if the user had called
@code{@ref{fl_flip_yorigin()}} - this only results in @code{y}-values
passed by and returned to the user when using functions like
@code{@ref{fl_set_object_position()}} or
@code{@ref{fl_get_object_position()}} getting "flipped", internally
always the normal coordinate system is used.

@item unsigned int resize
Controls if the object should be resized if the form it is on is
resized. The options are @code{FL_RESIZE_NONE}, @code{FL_RESIZE_X},
@code{FL_RESIZE_Y} and @code{FL_RESIZE_ALL}. The default is
@code{FL_RESIZE_ALL} which is the bitwise OR of @code{FL_RESIZE_X} and
@code{FL_RESIZE_Y}. Instead of accessing this element directly better
use the functions @code{@ref{fl_get_object_resize()}} and
@code{@ref{fl_set_object_resize()}}.

@item unsigned int nwgravity, segravity
These two variables control how the object is placed relative to its
position prior to resizing. Instead of accessing these elements
directly use @code{@ref{fl_get_object_gravity()}} and
@code{@ref{fl_set_object_gravity()}}.

@item FL_COLOR col1, col2
These are two color indices in the internal color lookup table. The
class routines are free to use them or not. The user can change them
using the routine @code{@ref{fl_set_object_color()}} or inspect the
colors with @code{@ref{fl_get_object_color()}}. The routine
@code{fl_add_NEW()} should fill in defaults.

@item char *label
This is a pointer to an allocated text string. This can be used by
class routines to provide a label for the object. The class routines
may not forget to allocate storage for it when it sets the pointer
itself, i.e., doesn't use @code{@ref{fl_set_object_label()}} - an
empty label should be the empty string and not just a @code{NULL}
pointer. The user can change it using the routines
@code{@ref{fl_set_object_label()}} and
@code{@ref{fl_set_object_label_f()}} or ask for it using
@code{@ref{fl_get_object_label()}}. The label must be drawn by the
routine handling the object when it receives a @code{FL_DRAWLABEL}
event (or it could be part of the code for @code{FL_DRAW} event). For
non-offsetted labels, i.e., the alignment is relative to the entire
bounding box, simply calling @code{@ref{fl_draw_object_label()}}
should be enough.

@item FL_COLOR lcol
The color of the label. The class routines can freely use this. The
user can set it with @code{@ref{fl_set_object_lcolor()}} and test it
with @code{@ref{fl_get_object_lcolor()}}.

@item int lsize
The size of the font used to draw the label. The class routines can
freely use this. The user can set it with @code{@ref{fl_set_object_lsize()}}.
and test it with @code{@ref{fl_get_object_lsize()}}.

@item int lstyle
The style of the font the label os drawn in, i.e., the number of the
font in which it should be drawn. The class routines can freely use
this. The user can set it with @code{@ref{fl_set_object_lstyle()}}
and test it with @code{@ref{fl_get_object_lstyle()}}.

@item int align
The alignment of the label with respect to the object. Again it is up
to the class routines to do something useful with this. The possible
values are @code{@ref{FL_ALIGN_LEFT}}, @code{@ref{FL_ALIGN_RIGHT}},
@code{@ref{FL_ALIGN_TOP}}, @code{@ref{FL_ALIGN_BOTTOM}},
@code{@ref{FL_ALIGN_CENTER}}, @code{@ref{FL_ALIGN_LEFT_TOP}},
@code{@ref{FL_ALIGN_RIGHT_TOP}}, @code{@ref{FL_ALIGN_LEFT_BOTTOM}} and
@code{@ref{FL_ALIGN_RIGHT_BOTTOM}}. The value should be bitwise ORed
with @code{@ref{FL_ALIGN_INSIDE}} if the label will be within the
bounding box of the object. The user can set this using the routine
@code{@ref{fl_set_object_lalign()}} and test it with
@code{@ref{fl_set_object_lalign()}}.

@item int bw
An integer indicating the border width of the object. Negative values
indicate the up box should look "softer" (in which case no black line
of 1 pixel width is drawn around the objects box). The user can set a
different border width using @code{@ref{fl_set_object_bw()}}.

@item long *shortcut
A pointer to long containing all shortcuts (as keysyms) defined for
the object (also see the previous chapter). You should never need them
because they are fully handled by the main routines.

@item void *spec
This is a pointer that points to any class specific information. For
example, for sliders it stores the minimum, maximum and current value
of the slider. Most classes (except the most simple ones like boxes
and texts) will need this. The function for adding a new object
(@code{fl_add_NEW()}) has to allocate storage for it. Whenever the
object receives the event @code{FL_FREEMEM} it should free this
memory.

@item int visible
Indicates whether the object is visible. The class routines don't have
to do anything with this variable. When the object is not visible the
main routine will never try to draw it or send events to it. By
default objects are visible. The visisbility of an object can be
tested using the @code{@ref{fl_object_is_visible()}} function. Note
that a this doesn't guarantee that the object is visible on the
screen, for this also the form the object belongs to needs to be
visible, in which case @code{@ref{fl_form_is_visible()}} returns true.

@item int active
Indicates whether the object is active, i.e., wants to receive events
other than @code{FL_DRAW}.

Static objects, such as text and boxes are inactive. This property
should be set in the @code{fl_add_NEW()} routine if required. By
default objects are active. This attribute can be changed by using the
functions @code{@ref{fl_deactivate_object()}} and
@code{@ref{fl_activate_object()}} and the current state can be
determined by calling @code{@ref{fl_object_is_active()}}.

@item int input
Indicates whether this object can receive keyboard input. If not,
events related to keyboard input are not sent to the object. The
default value of @code{input} is false. It should be set by
@code{fl_add_NEW()} if required. Note that not all keys are sent (see
member @code{wantkey} below).

@item int wantkey
An input object normally does not receive @code{<Tab>} or
@code{<Return>} keystrokes or any other keys except those that have
values between 0-255, the @code{<Left>} and @code{<Right>} arrow keys
and @code{<Home>} and @code{<End>} (@code{<Tab>} and @code{<Return>}
are normally used to switch between input objects). By setting this
field to @code{FL_KEY_TAB} enforces that the object receives also
these two keys as well as the @code{<Up>} and @code{<Down>} arrow keys
and @code{<PgUp>} and @code{<PgDn>} when it has the focus. To receive
other special keys (e.g., function keys) @code{FL_KEY_SPECIAL} must
be set in @code{wantkey}. By setting @code{wantkey} to
@code{FL_KEY_ALL} all keys are sent to the object.

@item unsigned int click_timeout
If non-zero this indicates the the maximum elapsed time (in msec)
between two mouse clicks to be considered a double click. A zero value
disables double/triple click detection. The user can set or query this
value using the functions @code{@ref{fl_set_object_dblclick()}} and
@code{@ref{fl_get_object_dblclick()}}.

@c The following is incorrect. The current implementation works only
@c for buttons since it explictely calls @code{@ref{fl_get_button()}},
@c so one can't create radio objects of any other sort.
@c
@c @item int radio This indicates whether this object is a radio
@c object. This means that, whenever it is pushed, other radio objects
@c in the same group in the form that are pushed are released (and
@c their pushed value is reset). Radio buttons use this. The default
@c is false. The @code{fl_add_NEW()} routine should set it if
@c required.

@item int automatic
An object is automatic if it automatically (without user actions) has
to change its contents. Automatic objects get a @code{FL_STEP} event
about every @w{50 msec}. For example the object class @code{FL_CLOCK}
is automatic. @code{automatic} by default is false. To set this
property use @code{@ref{fl_set_object_automatic()}} (don't set the
object member directly except from within a function like
@code{fl_add_NEW()}, in other contexts some extra work is required)
and to test the object for it use
@code{@ref{fl_object_is_automatic()}}.

@item int belowmouse
This indicates whether the mouse is on this object. It is set and
reset by the main routine. The class routines should never change it
but can use it to draw or handle the object differently.

@item int pushed
This indicates whether the mouse is pushed within the bounding box
of the object. It is set and reset by the main routine. Class
routines should never change it but can use it to draw or handle
objects differently.

@item int focus
Indicates whether keyboard input is sent to this object. It is set and
reset by the main routine. Never change it but you can use its value.

@item FL_HANDLEPTR handle
This is a pointer to the interaction handling routine for the object.
@code{fl_add_NEW()} sets this by providing the correct handling
routine. Normally it is never used (except by the main routine) or
changed although there might be situations in which you want to change
the interaction handling routine for an object, due to some user
action.

@item FL_OBJECT *next, *prev
@itemx FL_FORM *form
These are pointers to other objects in the form and to the form
itself. They are used by the main routines. The class routines should
not change them.

@item void *c_vdata
A void pointer for the class routine. The main module does not
reference or modify this field in any way. The object classes,
including the built-in ones, may use this field.

@item char *c_cdata
A char pointer for the class routine. The main module does not
reference or modify this field in any way. The object classes,
including the built-in ones, may use this field.

@item long c_ldata
A long variable for the class routine. The main module does not
reference or modify this field in any way. The object classes,
including the built-in ones, may use this field.

@item void *u_vdata
A void pointer for the application program. The main module does not
reference or modify this field in any way and neither should the class
routines.

@item char *u_cdata
A char pointer for the application program. The main module does not
reference or modify this field in any way and neither should the class
routines.

@item long u_ldata
A long variable provided for the application program.

@item FL_CALLBACKPTR object_callback
The callback routine that the application program assigned to the
object and that the system invokes when the user does something with
the object.

@item long argument
The argument to be passed to the callback routine when invoked.

@item int how_return
Determines under what circumstances the object is returned by e.g.,
@code{@ref{fl_do_forms()}} or the callback function for the object is
invoked. This can be either
@table @code
@item @ref{FL_RETURN_NONE}
Object gets never returned or its callback invoked

@item @ref{FL_RETURN_CHANGED}
Return object or invoke callback when state of object changed.

@item @ref{FL_RETURN_END}
Return object or invoke callback at end of interaction, normally when
the mouse key is released or, in the case of input objects, the object
has lost focus.

@item @ref{FL_RETURN_END_CHANGED}
Return object or invoke callback only when interaction has ended and
the state of the object has changed.

@item @ref{FL_RETURN_SELECTION}
Return object or invoke callback if e.g., in a browser a line
was selected.

@item @ref{FL_RETURN_SELECTION}
Return object or invoke callback if e.g., in a browser a line
was deselected.

@item @ref{FL_RETURN_ALWAYS}
Return object or invoke callback whenever interaction has ended or
the state of the object has changed.
@end table

Never change this element of the structure directly but use the
function @code{@ref{fl_set_object_return()}} instead! Especially in
the case of objects having child objects also the corresponding
settings for child objects may need changes and which automatically
get adjusted when the above function is used.

@item int returned
Set to what calling the object handling function did return (and
pruned to what the object is supposed to return according to the
@code{how_return} element). Can be either
@table @code
@item @ref{FL_RETURN_NONE}
Handling function did @code{FL_RETURN_NONE} (i.e., @code{0}).

@item @ref{FL_RETURN_CHANGED}
Handling function detected a change of the objects state.

@item @ref{FL_RETURN_END}
Handling function detected end of interaction with object.
@end table

@code{@ref{FL_RETURN_CHANGED}} and @code{@ref{FL_RETURN_END}} are bits
that can be bitwise ored. If both are set this indicates that the
objects state was changed and the interaction ended.
@end table

The generic object construction routine
@tindex FL_HANDLEPTR
@findex fl_make_object()
@anchor{fl_make_object()}
@example
typedef int (*FL_HANDLEPTR)(FL_OBJECT *obj, int event,
                            FL_Coord mx, FL_Coord my,
                            int key, void *raw_event);

FL_OBJECT *fl_make_object(int objclass, int type,
                          FL_Coord x, FL_Coord y,
                          FL_Coord w, FL_Coord h,
                          const char *label,
                          FL_HANDLEPTR handle);
@end example
@noindent
allocates a chunk of memory appropriate for all object classes and
initializes the newly allocated object to the following state:
@example
obj->resize     = FL_RESIZE_X | FL_RESIZE_Y;
obj->nwgravity  = obj->segravity = FL_NoGravity;
obj->boxtype    = FL_NO_BOX;
obj->align      = FL_ALIGN_CENTER | FL_ALIGN_INSIDE;
obj->lcol       = FL_BLACK;
obj->lsize      = FL_DEFAULT_SIZE;
obj->lstyle     = FL_NORMAL_STYLE;
obj->col1       = FL_COL1;
obj->col2       = FL_MCOL;
obj->wantkey    = FL_KEY_NORMAL;
obj->active     = 1;
obj->visible    = 1;
obj->bw         = borderWidth_resource_set ? resource_val : FL_BOUND_WIDTH;
obj->u_ldata    = 0;
obj->u_vdata    = 0;
obj->spec       = NULL;
obj->how_return = FL_RETURN_CHANGED
@end example

In some situations it can be also useful to make an object a child
of another object. An example is the scrollbar object. It has three
child objects, a slider and two buttons, which all three are children
of the scrollbar object. To make an object @code{child} a child
object of an object named @code{parent} use the function
@findex fl_add_child()
@anchor{fl_add_child()}
@example
void fl_add_child(FL_OBJECT *parent, FL_OBJECT *child);
@end example

When creating a composite object you will typically add callbacks
for the child object that handle what happens on events for these
child objects (e.g., for the scrollbar the buttons have callbacks
that update the internal state for the scrollbar object and result
in the slider getting shifted). Within these callback functions
the @code{returned} elements of the parent can be changed to
influence if and what gets reported to the application via
@code{@ref{fl_do_forms()}}.

There is rarely any need for the new object class to know how the
object is added to a form and how the Forms Library manages the
geometry, e.g., does an object have its own window etc. Nonetheless
if this information is required, use @code{@ref{FL_ObjWin()}} on the
object to obtain the window resource ID of the window the object
belongs to. Beware that an object window ID may be shared with other
objects@footnote{The only exception is the canvas class where the
window ID is guaranteed to be non-shared.}. Always remove an object
from the screen with @code{@ref{fl_hide_object()}}.

The class routine/application may reference the following members of
the @code{FL FORM} structure to obtain information on the status of
the form, but should not modify them directly:
@table @code
@item int visible
Indicates if the form is visible on the screen (mapped). Never change
it directly, use @code{@ref{fl_show_form()}} or
@code{@ref{fl_hide_form()}} instead.
@item int deactivated
Indicates if the form is deactivated. Never change it directly, use
@code{@ref{fl_activate_form()}} or @code{@ref{fl_deactivate_form()}}
instead.
@item FL OBJECT *focusobj
This pointer points to the object on the form that has the
input focus.
@item FL OBJECT *first
The first object on the form. Pointer to a linked list.
@item  Window window
The forms window.
@end table
