Next: Part IV Drawing Objects, Previous: Part IV Events, Up: Top [Contents][Index]

## 27 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 objects14. 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.

#### Footnotes

### (14)

The only exception is the canvas class where the window ID is guaranteed to be non-shared.

Next: Part IV Drawing Objects, Previous: Part IV Events, Up: Top [Contents][Index]