The Type 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.

int objclass
     This indicates the class of the object (e.g., FL_BUTTON, FL_SLIDER, FL_NEW etc.) The user can query the class of an object using the function fl_get_object_objclass().

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., 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 fl_get_object_type().

int boxtype
     This is the type of the bounding box for the object. The handling routine for the object, e.g., 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 fl_set_object_boxtype() and fl_get_object_boxtype().

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 fl_get_object_geometry(), fl_get_object_position() and 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 fl_add_NEW()) but always use fl_set_object_geometry(), fl_set_object_position(), fl_set_object_size() and fl_move_object()!

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

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

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 fl_get_object_gravity() and fl_set_object_gravity().

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 fl_set_object_color() or inspect the colors with fl_get_object_color(). The routine fl_add_NEW() should fill in defaults.

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 fl_set_object_label() - an empty label should be the empty string and not just a NULL pointer. The user can change it using the routines fl_set_object_label() and fl_set_object_label_f() or ask for it using fl_get_object_label(). The label must be drawn by the routine handling the object when it receives a FL_DRAWLABEL event (or it could be part of the code for FL_DRAW event). For non-offsetted labels, i.e., the alignment is relative to the entire bounding box, simply calling fl_draw_object_label() should be enough.

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

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 fl_set_object_lsize(). and test it with fl_get_object_lsize().

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 fl_set_object_lstyle() and test it with fl_get_object_lstyle().

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 FL_ALIGN_LEFT, FL_ALIGN_RIGHT, FL_ALIGN_TOP, FL_ALIGN_BOTTOM, FL_ALIGN_CENTER, FL_ALIGN_LEFT_TOP, FL_ALIGN_RIGHT_TOP, FL_ALIGN_LEFT_BOTTOM and FL_ALIGN_RIGHT_BOTTOM. The value should be bitwise ORed with FL_ALIGN_INSIDE if the label will be within the bounding box of the object. The user can set this using the routine fl_set_object_lalign() and test it with fl_set_object_lalign().

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 fl_set_object_bw().

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.

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 (fl_add_NEW()) has to allocate storage for it. Whenever the object receives the event FL_FREEMEM it should free this memory.

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 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 fl_form_is_visible() returns true.

int active
     Indicates whether the object is active, i.e., wants to receive events other than FL_DRAW.

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

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 input is false. It should be set by fl_add_NEW() if required. Note that not all keys are sent (see member wantkey below).

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

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 fl_set_object_dblclick() and fl_get_object_dblclick().

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

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.

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.

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.

FL_HANDLEPTR handle
     This is a pointer to the interaction handling routine for the object. 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.

FL_OBJECT *next, *prev
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.

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.

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.

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.

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.

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.

long u_ldata
     A long variable provided for the application program.

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.

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

int how_return
     Determines under what circumstances the object is returned by e.g., fl_do_forms() or the callback function for the object is invoked. This can be either

     FL_RETURN_NONE
          Object gets never returned or its callback invoked

     FL_RETURN_CHANGED
          Return object or invoke callback when state of object changed.

     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.

     FL_RETURN_END_CHANGED
          Return object or invoke callback only when interaction has ended and the state of the object has changed.

     FL_RETURN_SELECTION
          Return object or invoke callback if e.g., in a browser a line was selected.

     FL_RETURN_SELECTION
          Return object or invoke callback if e.g., in a browser a line was deselected.

     FL_RETURN_ALWAYS
          Return object or invoke callback whenever interaction has ended or the state of the object has changed.

     Never change this element of the structure directly but use the function 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.

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 how_return element). Can be either

     FL_RETURN_NONE
          Handling function did FL_RETURN_NONE (i.e., 0).

     FL_RETURN_CHANGED
          Handling function detected a change of the objects state.

     FL_RETURN_END
          Handling function detected end of interaction with object.

     FL_RETURN_CHANGED and 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.

The generic object construction routine

     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);

allocates a chunk of memory appropriate for all object classes and initializes the newly allocated object to the following state:

     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

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 child a child object of an object named parent use the function

     void fl_add_child(FL_OBJECT *parent, FL_OBJECT *child);

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 returned elements of the parent can be changed to influence if and what gets reported to the application via 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 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 (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 fl_hide_object().

The class routine/application may reference the following members of the FL FORM structure to obtain information on the status of the form, but should not modify them directly:

int visible
     Indicates if the form is visible on the screen (mapped). Never change it directly, use fl_show_form() or fl_hide_form() instead.

int deactivated
     Indicates if the form is deactivated. Never change it directly, use fl_activate_form() or fl_deactivate_form() instead.

FL OBJECT *focusobj
     This pointer points to the object on the form that has the input focus.

FL OBJECT *first
     The first object on the form. Pointer to a linked list.

Window window
     The forms window.