[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 17. Valuator Objects

## 17.1 Slider Object

Sliders are useful for letting the user indicate a value between some fixed bounds. Both horizontal and vertical sliders exist. They have a minimum, a maximum and a current value (all floating point values). The user can change the current value by shifting the slider with the mouse. Whenever the value changes, this is reported to the application program.

### 17.1.1 Adding Slider Objects

Adding an object To add a slider to a form use

    FL_OBJECT *fl_add_slider(int type, FL_Coord x, FL_Coord y,
                             FL_Coord w, FL_Coord h, const char *label);

or

    FL_OBJECT *fl_add_valslider(int type, FL_Coord x, FL_Coord y,
                                FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is by default placed below the slider. The difference between a normal slider and a valslider is that for the second type its value is displayed above or to the left of the slider.

### 17.1.2 Slider Types

The following types of sliders are available:

`FL_VERT_SLIDER`

  A vertical slider.

`FL_HOR_SLIDER`

  A horizontal slider.

`FL_VERT_FILL_SLIDER`

  A vertical slider, filled from the bottom.

`FL_HOR_FILL_SLIDER`

  A horizontal slider, filled from the left.

`FL_VERT_NICE_SLIDER`

  A nice looking vertical slider.

`FL_HOR_NICE_SLIDER`

  A nice looking horizontal slider.

`FL_VERT_BROWSER_SLIDER`

  A different looking vertical slider.

`FL_HOR_BROWSER_SLIDER`

  A different looking horizontal slider.

`FL_VERT_PROGRESS_BAR`

  A vertical progress bar

`FL_HOR_PROGRESS_BAR`

  A horizontal progress bar

Please note that except for `FL_VERT_PROGRESS_BAR` and `FL_HOR_PROGRESS_BAR` the label will always drawn on the outside of the slider (even if you attempt to set an inside alignment).

### 17.1.3 Slider Interaction

Whenever the user changes the value of the slider using the mouse, the slider is returned (unless there's callback function associated with the object) by the interaction routines. The slider position is changed by moving the mouse inside the slider area. For fine control, hold down the `<Shift>` key while usinf the slider, in that case the slider doesn't follow the mouse directly but at a lower speed.

Please note: the `FL_VERT_PROGRESS_BAR` and `FL_HOR_PROGRESS_BAR` aren't actually valuator objects (they don't react to any user interaction) but are vor visualization only (i.e., showing a progress bar that is changed by the program only), they appear here because they are directly derived from the `FL_VERT_FILL_SLIDER` and `FL_VERT_FILL_SLIDER` slider. Thus the only way to change the value of objects of these types is by calling `fl_set_slider_value()`! To obtain the correct "progress bar" behaviour you should also update the label accordingly.

In some cases you might not want the slider to be returned or its callback called each time its value changes. To change the default, call the following routine:

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when)

where the parameter `when` can be one of the four values:

`FL_RETURN_NONE`

  Never return or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) if value is changed since last return.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the slider value is changed. This is the default.

`FL_RETURN_END`

  Return or invoke callback at end (mouse release) regardless if the value is changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback when the value changed or at end (mouse release).

See the demo program ``objreturn.c`' for an example use of this.

### 17.1.4 Other Slider Routines

To change the value and bounds of a slider use the following routines

    void fl_set_slider_value(FL_OBJECT *obj, double val);
    void fl_set_slider_bounds(FL_OBJECT *obj, double min, double max);

By default, the minimum value for a slider is 0.0, the maximum is 1.0 and the value is 0.5. For vertical sliders the slider position for the minimum value is at the left, for horizontal sliders at the top of the slider. By setting `nin` to a larger value than `max` in a call of `fl_set_slider_bounds()` this can be reversed.

If in a call of `fl_set_slider_bounds()` the actual value of a slider isn't within the range of the new bounds, its value gets adjusted to the nearest limit. When the requested new slider value in a call of `fl_set_slider_value()` is outside the range of bounds it gets adjusted to the nearest boundary value.

To obtain the current value or bounds of a slider use

    double fl_get_slider_value(FL_OBJECT *obj);
    void fl_get_slider_bounds(FL_OBJECT *obj, double *min, double *max);

Per default a slider only reacts to the left mouse button. But sometimes it can be useful to modify this. To set this call

    void fl_set_slider_mouse_buttons(FL_OBJECT *obj,
                                     int mbuttons);

`mbuttons` is the bitwise OR of the numbers 1 for the left mouse button, 2 for the middle and 4 for the right mouse button.

To determine which mouse buttons a slider reacts to use

    void fl_get_slider_mouse_buttons(FL_OBJECT *obj,
                                     unsigned int *mbuttons);

The value returned via `mbuttons` is the same value as would be used in `fl_set_slider_mouse_buttons()`.

### 17.1.5 Slider Attributes

Never use `FL_NO_BOX` as the boxtype for a slider. For `FL_VERT_NICE_SLIDER`s and `FL_HOR_NICE_SLIDER`s it's best to use a `FL_FLAT_BOX` in the color of the background to get the nicest effect.

The first color argument (`col1`) to `fl_set_object_color()` controls the color of the background of the slider, the second (`col2`) the color of the slider itself.

You can control the size of the slider inside the box using the routine

    void fl_set_slider_size(FL_OBJECT *obj, double size);

`size` should be a floating point value between 0.0 and 1.0. The default is `FL_SLIDER_WIDTH`, which is 0.1 for regular sliders and 0.15 for browser sliders. With a value for `size` of 1.0, the slider covers the box completely and can no longer be moved. This function does nothing if applied to sliders of type `NICE_SLIDER` and `FILL_SLIDER`.

To obtain the current setting of the slider size use

    double fl_get_slider_size(FL_OBJECT *obj);

The routine

    void fl_set_slider_precision(FL_OBJECT *obj, int prec);

sets the precision with which the value of the slider is shown. This only applies to sliders showing their value, i.e., valsliders. The argument must be between 0 and `FL_SLIDER_MAX_PREC` (currently set to 10).

By default, the value shown by a valslider is the slider value in floating point format. You can override the default by registering a filter function using the following routine

    void fl_set_slider_filter(FL_OBJECT *obj,
                              const char *(*filter)(FL_OBJECT *,
                                                    double value,
                                                    int prec));

where `value` and `prec` are the slider value and precision respectively. The filter function `filter` should return a string that is to be shown. The default filter is equivalent to the following

    const char *filter(FL_OBJECT *obj, double value, int prec) {
        static char buf[32];

         sprintf(buf, "%.*f", prec, value);
         return buf;
    }

### 17.1.6 Remarks

See the demo program ``demo05.c`' for an example of the use of sliders. See demo programs ``sldsize.c`' and ``sliderall.c`' for the effect of setting slider sizes and the different types of sliders.

## 17.2 Scrollbar Object

Scrollbars are similar to sliders (as a matter of fact, scrollbars are made with sliders and scrollbuttons) and alse let the user indicate a value between some fixed bounds. Both horizontal and vertical scrollbars exist. They have a minimum, maximum and current value (all floating point values). The user can change this value by dragging the sliding bar with the mouse or by pressing the scroll buttons. Per default whenever the value changes, it is reported to the application program via the callback function.

### 17.2.1 Adding Scrollbar Objects

To add a scrollbar to a form use

    FL_OBJECT *fl_add_scrollbar(int type, FL_Coord x, FL_Coord y,
                                FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is by default placed below the scrollbar.

### 17.2.2 Scrollbar Types

The following types of scrollbar are available:

`FL_VERT_SCROLLBAR`

  A vertical scrollbar.

`FL_HOR_SCROLLBAR`

  A horizontal scrollbar.

`FL_VERT_THIN_SCROLLBAR`

  A different looking vertical scrollbar.

`FL_HOR_THIN_SCROLLBAR`

  A different looking horizontal scrollbar.

`FL_VERT_NICE_SCROLLBAR`

  A vertical scrollbar using `FL_NICE_SLIDER`.

`FL_HOR_NICE_SCROLLBAR`

  A horizontal scrollbar using `FL_NICE_SLIDER`.

`FL_VERT_PLAIN_SCROLLBAR`

  Similar to `FL_THIN_SCROLLBAR`.

`FL_HOR_PLAIN_SCROLLBAR`

  Similar to `FL_HOR_THIN_SCROLLBAR`.

### 17.2.3 Scrollbar Interaction

Whenever the user changes the value of the scrollbar, the scrollbar's callback is called (if one is associated with the scrollbar). The scrollbar position can be changed in several ways. The most simple one is to left-click on the knob of the scrollbar and move the know while the left mouse button is kept pressed down. Left-clicking beside the know will move the knob in large steps toward the current position of the mouse, clicking with the middle or right mouse button in smaller steps. Small shifts can also be obtained by clicking on one of the buttons at the side of the scrollbar or by using the scroll-wheel somehwere over the scrollbar.

You can control under which conditions the scrollbar gets returned to your application or its callback invoked. To change the default, call

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where the parameter `when` can be one of the following four values:

`FL_RETURN_NONE`

  Never return or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) if value is changed (since last return).

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the scrollbar value is changed. This is the default.

`FL_RETURN_END`

  Return or invoke callback at end (mouse release) regardless if the value is changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback whenever value changed or mouse button was released.

The default setting for `when` for a scrollbar object is `FL_RETURN_CHANGED` (unless during the build of XForms you set the configuration flag `--enable-bwc-bs-hack` in which case the default is `FL_RETURN_NONE` to keep backward compatibility with earlier releases of the library).

See demo program ``objreturn.c`' for an example use of this.

### 17.2.4 Other Scrollbar Routines

To change the value and bounds of a scrollbar use the following routines:

    void fl_set_scrollbar_value(FL_OBJECT *obj, double val);
    void fl_set_scrollbar_bounds(FL_OBJECT *obj, double min, double max);

By default, the minimum value for a slider is 0.0, the maximum is 1.0 and the value is 0.5. For vertical sliders the slider position for the minimum value is at the left, for horizontal sliders at the top of the slider. By setting `min` to a larger value than `max` in a call of `fl_set_scrollbar_bounds()` this can be reversed.

If in a call of `fl_set_scrollbar_bounds()` the actual value of a scrollbar isn't within the range of the new bounds, its value gets adjusted to the nearest limit. When the requested new scrollbar value in a call of `fl_set_scrollbar_value()` is outside the range of bounds it gets adjusted to the nearest boundary value.

To obtain the current value and bounds of a scrollbar use

    double fl_get_scrollbar_value(FL_OBJECT *obj);
    void fl_get_scrollbar_bounds(FL_OBJECT *obj, double *min, double *max);

By default, if the mouse is pressed beside the the sliding bar, the bar starts to jumps in the direction of the mouse position. You can use the following routine to change this size of the steps being made :

    void fl_set_scrollbar_increment(FL_OBJECT *obj, double lj, double rj);

where `lj` indicates how much to increment if the left mouse button is pressed and `rj` indicates how much to jump if the middle mouse button pressed. For example, for the scrollbar in the browser class, the left mouse jump is made to be one page and middle mouse jump is made to be one line. The increment (decrement) value when the scrollbuttons are pressed is set to the value of the right jump. The default values for `lj` and `rj` are `0.1` and `0.02`.

To obtain the current increment settings, use the following routine

    void fl_get_scrollbar_increment(FL_OBJECT *obj, double *lj, double *sj);

With the function

    int fl_get_scrollbar_repeat(FL_OBJECT *obj);
    void fl_set_scrollbar_repeat(FL_OBJECT *obj, int millisec);

you can determine and control the time delay (in milliseconds) between jumps of the knob when the mouse button is kept pressed down outside of the knobs area. The default value is 100 ms. The delay for the very first jump is twice that long in order to avoid jumping to start too soon when only a single click was intended but the user is a bit slow in releasing the mouse button.

### 17.2.5 Scrollbar Attributes

Never use `FL_NO_BOX` as the boxtype for a scrollbar. For `FL_VERT_NICE_SCROLLBAR`s and `FL_HOR_NICE_SCROLLBAR`s it's best to use a `FL_FLAT_BOX` boxtype in the color of the background to get the nicest effect.

The first color argument (`col1` to `fl_set_object_color()` controls the color of the background of the scrollbar, the second (`col2`) the color of the sliding bar itself.

You can control the size of the sliding bar inside the box using the routine

    void fl_set_scrollbar_size(FL_OBJECT *obj, double size);

`size` should be a value between 0.0 and 1.0. The default is `FL_SLIDER_WIDTH`, which is 0.15 for all scrollbars With `size` set to 1.0, the scrollbar covers the box completely and can no longer be moved. This function does nothing if applied to scrollbars of type `FL_NICE_SCROLLBAR`.

The function

    double fl_get_scrollbar_size(FL_OBJECT *obj);

returns the current setting of the scrollbar size.

### 17.2.6 Remarks

See the demo program ``scrollbar.c`' for an example of the use of scrollbars.

## 17.3 Dial Object

Dial objects are dials that the user can put in a particular position using the mouse. They have a minimum, maximum and current value (all floating point values). The user can change this value by turning the dial with the mouse. Whenever the value changes, this is reported to the application program.

### 17.3.1 Adding Dial Objects

To add a dial to a form use

    FL_OBJECT *fl_add_dial(int type, FL_Coord x, FL_Coord y,
                           FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is by default placed below the dial.

### 17.3.2 Dial Types

The following types of dials are available:

`FL_NORMAL_DIAL`

  A dial with a knob indicating the position.

`FL_LINE_DIAL`

  A dial with a line indicating the position.

`FL_FILL_DIAL`

  The area between initial and current is filled.

### 17.3.3 Dial Interaction

By default, the dial value is returned to the application when the user releases the mouse. It is possible to change this behavior using the following routine

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where `when` can be one of the following

`FL_RETURN_NONE`

  Never report or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) and only if the dial value is changed. This is the default setting.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the dial value is changed.

`FL_RETURN_END`

  Return or invoke callback at the end regardless if the dial value is changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback when value has changed or mouse button has been released.

### 17.3.4 Other Dial Routines

To change the value of the dial and its bounds use

    void fl_set_dial_value(FL_OBJECT *obj, double val);
    void fl_set_dial_bounds(FL_OBJECT *obj, double min, double max);

By default, the minimum value is 0.0, the maximum is 1.0 and the value is 0.5.

To obtain the current values of the dial and its bounds use

    double fl_get_dial_value(FL_OBJECT *obj);
    void fl_get_dial_bounds(FL_OBJECT *obj, double *min, double *max);

Sometimes, it might be desirable to limit the angular range a dial can take or choose an angle other than 0 to represent the minimum value. For this purpose, use the following routine

    void fl_set_dial_angles(FL_OBJECT *obj, double thetai, double thetaf)

where `thetai` maps to the minimum value of the dial and `thetaf` to its maximum value. The angles are relative to the origin of the dial, which is by default at 6 o'clock and rotates clock-wise. By default, the minimum angle is 0 and the maximum angle is 360.

To obtain the start and end angles use

    void fl_get_dial_angles(FL_OBJECT *obj, double *thetai, double *thetaf)

By default, crossing from 359.9 to 0 or from 0 to 359.9 is not allowed. To allowing crossing over, use the following routine

    void fl_set_dial_crossover(FL_OBJECT *obj, int yes_no);

where a true value for `yes_no` indicates that cross-over is allowed.

In a number of situations you might want dial values to be rounded to some values, e.g., to integer values. To this end use the routine

    void fl_set_dial_step(FL_OBJECT *obj, double step);

After this call dial values will be rounded to multiples of `step`. Use a value of 0.0 for `step` to switch off rounding.

To get the current setting for the rounding steps use

    double fl_get_dial_step(FL_OBJECT *obj);

By default, clock-wise rotation increases the dial value. To change, use the following routine

    void fl_set_dial_direction(FL_OBJECT *obj, int dir);

where `dir` can be either `FL_DIAL_CCW` or `FL_DIAL_CW`.

To obtain the direction use

    int fl_get_dial_direction(FL_OBJECT *obj);

### 17.3.5 Dial Attributes

You can use any boxtype you like, but the final dial face always appears to be circular although certain correlation between the requested boxtype and actual boxtype exists (for example, `FL_FRAME_BOX` is translated into a circular frame box.)

The first color argument (`col1` to `fl_set_object_color()` controls the color of the background of the dial, the second `col2`) the color of the knob or the line or the fill color.

### 17.3.6 Remarks

The resolution of a dial is about 0.2 degrees, i.e., there are only about 2000 steps per 360 degrees and, depending on the size of the dial, it is typically less.

The dial is always drawn with a circular box. If you specify a `FL_UP_BOX`, a `FL_OVAL3D_UPBOX` will be used.

See the demo programs ``ldial.c`', ``ndial.c`' and ``fdial.c`' for examples of the use of dials.

## 17.4 Positioner Object

A positioner is an object in which the user can indicate a position with an x- and a y-coordinate. It displays a box with a cross-hair cursor in it (except an invisble positioner, of course). Clicking the mouse inside the box changes the position of the cross-hair cursor and, hence, the x- and y-values.

### 17.4.1 Adding Positioner Objects

A positioner can be added to a form using the call

    FL_OBJECT *fl_add_positioner(int type, FL_Coord x, FL_Coord y,
                                 FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is placed below the box by default.

### 17.4.2 Positioner Types

The following types of positioner exist:

`FL_NORMAL_POSITIONER`

  Cross-hair inside a box.

`FL_OVERLAY_POSITIONER`

  Cross-hair inside a transparent box.

`FL_INVISIBLE_POSITIONER`

  Completely invisible positioner, to be used just for the side effect of obtaining a position (typically an object is below below it that otherwise would receive user events).

Note that for exatly positioning a `FL_OVERLAY_POSITIONER` or `FL_INVISIBLE_POSITIONER` over another object you have to take account of the (absolute value of the) border widths of both the underlying obkject and the positioner.

### 17.4.3 Positioner Interaction

The user changes the setting of the positioner using the mouse inside the box. Per default whenever the values changes, the object is returned by the interaction routines or its callback invoked (if one exists.

To change the default use the function

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where `when` can be one of the following

`FL_RETURN_NONE`

  Never report or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) and only when the positioner ended in a different position than the one it started from.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the positioners value is changed, default setting.

`FL_RETURN_END`

  Return or invoke callback at the end only but regardless if the positioners value changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback when value has changed or mouse button has been released.

Per default a positioner only reacts to the left mouse button. But sometimes it can be useful to modify which mouse buttons it will reacts to. To set this use

    void fl_set_positioner_mouse_buttons(FL_OBJECT *obj,
                                         int mbuttons);

`mbuttons` is the bitwise OR of the numbers 1 for the left mouse button, 2 for the middle, 4 for the right mouse button, 8 for moving the scroll wheel up "button" and 16 for scrolling down "button".

To determine which mouse buttons a positioner reacts to use

    void fl_get_positioner_mouse_buttons(FL_OBJECT *obj,
                                         unsigned int *mbuttons);

The value returned via `mbuttons` is the same value as would be used in `fl_set_positioner_mouse_buttons()`.

Sometimes you may want to assign different meanings to the mouse buttons used to interact with the positioner. To find out which one has been used there's the function

    int fl_get_positioner_numb(FL_OBJECT *obj);

It returns one of the constants `FL_LEFT_MOUSE`, `FL_MIDDLE_MOUSE`, `FL_RIGHT_MOUSE`, `FL_SCROLLUP_MOUSE` or `FL_SCROLLDOWN_MOUSE` (the latter two are from the scroll wheel of the mouse).

### 17.4.4 Other Positioner Routines

Usually, a positioner of type `FL_OVERLAY_POSITIONER` is used on top if another object, e.g., a pixmap object. If the object below the positioner is changed, e.g., by setting a new pixmap for the pixmap object, tis may lead to visual artefacts since the postioner isn't aware of the changes of the underlying object. To avoid this call the function

    void fl_reset_positioner(FL_OBJECT *obj);

before each change to an object below it.

Per defauly the range that the `x` and `y` values of a positioner can assume are controlled via minimum and maximum values for both directions. These boundary values can be set by using the functions the routines:

    void fl_set_positioner_xbounds(FL_OBJECT *obj, double min, double max);
    int fl_set_positioner_ybounds(FL_OBJECT *obj, double min, double max);

When a new positioner object is created the minimum values are 0.0 and the maximum values are 1.0. For boundaries in x-direction `min` and `max` should be taken to mean the left- and right-most position, respectively, and for the y-boundaries `min` and `max` should be taken to mean the value at the bottom and value at the top of the positioner, respectively.

Note that the posituoners value may be changed automatically when setting new boundaries to make them satisfy the new conditions.

For more complicated situations, i.e., when only a subset of the positioners value range may be used, a validation function can be installed (see the ``positioner_overlay`' demo program for an example):

    typedef int (*FL_POSITIONER_VALIDATOR (FL_OBJECT * obj,
    									   double x, double y,
    									   double *x_repl, double *y_repl);

    FL_POSITIONER_VALIDATOR
    fl_set_positioner_validator(FL_OBJECT               * obj,
    							FL_POSITIONER_VALIDATOR   validator);

If a non-`NULL` pointer is passed to the function each time a new position is set the validation function is invoked. It can return either `FL_POSITIONER_INVALID` to indicate that the new valuea aren't acceptable, in which case the position remains unchanged. It may also return `FL_POSITIONER_VALID` if the values are acceptable. Finally, the function may also return modified values via the `x_repl` and `y_repl` pointers and return `FL_POSITIONER_REPLACED`. In this case the values returned are used. It's the responsibility of the validation function to make sure that the `x` and `y` values satisfy the boundary restrictions etc. If it doesn't the results are unpredictable.

To switch off validation pass the function a `NULL` pointer. The function returns a pointer to the previously active validation function (or `NULL` if non had been set). Note that if a new validation function is set it is immediately called to check that the current position is still compatible with the new requirements. If the validation function returns `FL_POSITIONER_INVALID` in this case the position can't be corrected to fit the new conditions. Thus if you write your validation function in a way that it may return this value it is advisable to set compilant values for the positions before installing the validation function.

To programatically change the `x` and `y` position use

    int fl_set_positioner_values(FL_OBJECT *obj, double xval, double yval);
    int fl_set_positioner_xvalue(FL_OBJECT *obj, double val);
    int fl_set_positioner_yvalue(FL_OBJECT *obj, double val);

These functions return either `FL_POSITIONER_VALID` if the new position was acceptable or `FL_POSITIONER_REPLACED` if the value passed to the function had to be modified due to constraints imposed by the boundaries the step sizes or a validation routine. If a validation routine is set the functions also may return `FL_POSITIONER_INVALID` if that routine returned this value.

To obtain the current values of the positioner and the bounds use

    double fl_get_positioner_xvalue(FL_OBJECT *obj);
    double fl_get_positioner_yvalue(FL_OBJECT *obj);
    void fl_get_positioner_xbounds(FL_OBJECT *obj, double *min, double *max);
    void fl_get_positioner_ybounds(FL_OBJECT *obj, double *min, double *max);

In a number of situations you might like positioner values to be rounded to some values, e.g., to integer values. To this end use the routines

    void fl_set_positioner_xstep(FL_OBJECT *obj, double step);
    void fl_set_positioner_ystep(FL_OBJECT *obj, double step);

After these calls positioner values will be rounded to multiples of `step`. Use a value of 0 for `step` to switch off rounding.

The functions

    void fl_get_positioner_xstep(FL_OBJECT *obj);
    void fl_get_positioner_ystep(FL_OBJECT *obj);

return the current settings for the `x` and `y` step size.

Sometimes, it makes more sense for a positioner to have an icon/pixmap as the background that represents a minified version of the area where the positioner's values apply. Type `FL_OVERLAY_POSITIONER` is specifically designed for this by drawing the moving cross-hair in XOR mode as not to erase the background. A typical creation procedure might look something like the following

    obj = fl_add_pixmap(FL_NORMAL_PIXMAP, x, y, w, h, label);
    fl_set_pixmap_file(obj, iconfile);
    pos = fl_add_positioner(FL_OVERLAY_POSITIONER, x, y, w, h, label);

Of course, you can overlay this type of positioner on objects other than a pixmap. See the demo program ``positionerXOR.c`' for an example.

### 17.4.5 Positioner Attributes

Never use `FL_NO_BOX` as the boxtype for a positioner of type. `FL_NORMAL_POSITIONER` (but the other two types will have a box type of `FL_NO_BOX` per default).

The first color argument (`col1`) to `fl_set_object_color()` controls the color of the box, the second (`col2`) the color of the cross-hair.

### 17.4.6 Remarks

A demo can be found in ``positioner.c`'.

## 17.5 Counter Object

A counter provides a different mechanism for the user to select a value. In consists of a box displaying a value with one or two buttons on each side. The user can press these buttons to change the value (and while the mouse button is kept pressed down the value will continue to change, slow at first and faster after some time). If the counter has four buttons, the left- and right-most button make the value change in large steps, the other buttons make it change in small steps.

### 17.5.1 Adding Counter Objects

To add a counter to a form use

    FL_OBJECT *fl_add_counter(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w, FL_Coord h, const char *label)

The meaning of the parameters is as usual. The label is by default placed below the counter.

### 17.5.2 Counter Types

The following types of counters are available:

`FL_NORMAL_COUNTER`

  A counter with two buttons on each side.

`FL_SIMPLE_COUNTER`

  A counter with one button on each side.

### 17.5.3 Counter Interaction

The user changes the value of the counter by keeping his mouse pressed on one of the buttons. Per default whenever the mouse is released and the counter value is changed the counter is returned to the application program or its callback is invoked.

In some applications you might want the counter to be returned to the application program (or the callback invoked) e.g., whenever the value changes and not only when the mouse is released. To this end use

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where `when` can be either

`FL_RETURN_NONE`

  Never report or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) and only if the counter value is changed.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the counter value is changed. This is the default setting.

`FL_RETURN_END`

  Return or invoke callback at the end regardless if the counter value is changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback when the counter value has changed or mouse button has been released.

### 17.5.4 Other Counter Routines

To change the value of the counter, it's bounds and stp size use the routines

    void fl_set_counter_value(FL_OBJECT *obj, double val);
    void fl_set_counter_bounds(FL_OBJECT *obj, double min, double max);
    void fl_set_counter_step(FL_OBJECT *obj, double small, double large);

The first routine sets the value (default is 0) of the counter, the second routine sets the minimum and maximum values that the counter will take (default are -1000000 and 1000000, respectively) and the third routine sets the sizes of the small and large steps (defaults to 0.1 and 1). (For simple counters only the small step is used.)

For conflicting settings, bounds take precedence over value, i.e., if setting a value that is outside of the current bounds, it is clamped. Also changing the bounds in a way that the current counter value isn't within the new bounds range anymore will result in its value being adjusted to the nearest of the new limits.

To obtain the current value of the counter use

    double fl_get_counter_value(FL_OBJECT *obj);

To obtain the current bounds and steps, use the following functions

    void fl_get_counter_bounds(FL_OBJECT *obj, double *min, double *max);
    void fl_get_counter_step(FL_OBJECT *obj, double *small, double *large);

To set the precision (number of digits after the dot) with which the counter value is displayed use the routine

    void fl_set_counter_precision(FL_OBJECT *obj, int prec);

To determine the current value of the precision use

    int fl_get_counter_precision(FL_OBJECT *obj);

By default, the value shown is the counter value in floating point format. You can override the default by registering a filter function using the following routine

    void fl_set_counter_filter(FL_OBJECT *obj,
                               const char *(*filter)(FL_OBJECT *,
                                                     double value,
                                                     int prec));

where `value` and `prec` are the counter value and precision respectively. The filter function `filter` should return a string that is to be shown. Note that the default filter is equivalent to the following

    const char *filter(FL_OBJECT *obj, double value, int prec) {
        static char buf[32];

         sprintf(buf, "%.*f",prec,value);
         return buf;
    }

By default the counter value changes first slowly and the rate of change then accelerates until a final speed is reached. The default delay between value changes is 600 ms at the start and the final delay is 50 ms. You can change the initial delay by a call of the function

    void fl_set_counter_repeat(FL_OBJECT *obj, int millisec);

and the final delay by using

    void fl_set_counter_min_repeat(FL_OBJECT *obj, int millisec);

where in both cases the argument `millisec` is the delay in milli-seconds. The current settings for the initial and final delay can be obtained by calling the functions

    int fl_get_counter_repeat(FL_OBJECT *obj);
    int fl_get_counter_min_repeat(FL_OBJECT *obj);

Until version 1.0.91 of the library the delay between changes of a counter was constant (with a default value of 100 ms). To obtain this traditional behaviour simple set the initial and final delay to the same value.

As a third alternative you can also request that only the first change of the counter has a different delay from all the following ones. To achieve this call

    void fl_set_counter_speedjump(FL_OBJECT *obj, int yes_no);

with a true value for `yes_no`. The delay for the first change of the counter value will then be the one set by `fl_set_counter_repeat()` and the following delays last as long as set by `fl_set_counter_min_repeat()`.

To determine the setting for "speedjumping" call

    int fl_get_counter_speedjump(FL_OBJECT *obj);

### 17.5.5 Counter Attributes

Never use `FL_NO_BOX` as the boxtype for a counter.

The first color argument (`col1`) t `fl_set_object_color()` controls the color of the background of the counter, the second (`col2`) sets the color of the arrow buttons of the counter.

### 17.5.6 Remarks

See demo program ``counter.c`' for an example of the use of counters.

## 17.6 Spinner Object

A spinner object is a combination of a (numerical) input field with two (touch) buttons that allow to increment or decrement the value in the (editable) input field. I.e., the user can change the spinners value by either editing the value of the input field or by using the up/down buttons shown beside the input field.

There are two types of spinner objects, one for integer and one for floating point values. You can set limits on the values that can be input and you can also set the amount of increment/decrement achieved when clicking on its buttons.

### 17.6.1 Adding Spinner Objects

To add a spinner to a form use

    FL_OBJECT *fl_add_spinner(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is by default placed on the left of the spinner object.

### 17.6.2 Spinner Types

There are two types of spinners, one for input of integer and one for floating point values:

`FL_INT_SPINNER`

  A spinner that allows input of integer values.

`FL_FLOAT_SPINNER`

  A spinner that allows input of floating point values.

The way a spinner looks like depends on its dimensions. If it's at least as wide as it's high the two buttons are drawn above each other to the right of the input field (and are marked with and up and down pointing triangle), while when the object is higher than it's wide they are drawn beside each other and below the input field (and the markers are then left and right pointing arrows).

### 17.6.3 Spinner Interaction

The user can change the value of a spinner in two ways. She can either edit the value in the spinner directly (exactly the same as for an integer or floating point input object (Input Objects) or by clicking on one of the buttons that will increment or decrement the value.

Per default the spinner object gets returned to the application (or the associated callback is called) whenever the value changed and the interaction seems to have ended. If you want it returned under different circumstances use the function

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where the parameter `when` can be one of the four values

`FL_RETURN_NONE`

  Never return or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end of interaction (when either the input field loses the focus or one of the buttons was released) and the spinner's value changed during the interaction.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the spinner's value changed. This is the default.

`FL_RETURN_END`

  Return or invoke callback at end of interaction regardless of the spinner's value having changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback whenever the value changed or the interaction ended.

### 17.6.4 Other Spinner Routines

Probably the most often used spinner functions are

    double fl_get_spinner_value(FL_OBJECT *obj );
    double fl_set_spinner_value(FL_OBJECT *obj, double val);

The first one returns the value of a spinner. The type of the return value is a double for both integer and floating point spinners, so you have to convert it for integer spinners appropriately, e.g: using the `FL_nint()` macro, that converts a double to the nearest integer value.

You can set or retrieve the upper and lower limit the value a spinner can be set to using the functions

    void fl_set_spinner_bounds(FL_OBJECT *obj, double min, double max);
    void fl_get_spinner_bounds(FL_OBJECT *obj, double *min, double *max);

Since this function is to be used for integer as well as floating point spinner objects the `double` type values must be converted as necessary for `FL_INT_SPINNER`.

The default limits are `-10000` and `10000`, but can be set to up to `INT_MIN` and `INT_MIN` for `FL_INT_SPINNER`s and `-DBL_MAX` and `DBL_MAX` for `FL_FLOAT_SPINNER`s.

To set or determine the step size by which a spinner will be incremented or decremented when one of the buttons is clicked on use

    void fl_set_spinner_step(FL_OBJECT *obj, double step);
    double fl_get_spinner_step(FL_OBJECT *obj);

The default step size is `1` for both `FL_INT_SPINNER` and `FL_FLOAT_SPINNER` objects.

For `FL_FLOAT_SPINNER` objects you can set (or determine) how many digits after the decimal point are shown by using

    void fl_set_spinner_precision(FL_OBJECT *obj, int prec);
    int fl_get_spinner_precision(FL_OBJECT *obj);

This is per default set to 6 digits after the decimal point. The function for setting the precision has no effect on `FL_INT_SPINNER` objects and the other one returns 0 for this type of spinners.

### 17.6.5 Spinner Attributes

Please don't change the boxtype from `FL_NO_BOX`.

The label color and font can be set using the normal `fl_set_object_lcolor()`, `fl_set_object_lsize()` and `fl_set_object_lstyle()` functions. The color of the input field of a spinner object can be set via using `fl_set_object_color()` where the first color argument (`col1`) controls the color of the input field when it is not selected and the second (`col2`) is the color when selected.

Instead of creating a plethora of functions to influence all the other aspects of how the spinner is drawn (colors, font types etc.) the user is given direct access to the sub-objects of a spinner. To this end three functions exist:

    FL_OBJECT *fl_get_spinner_input(FL_OBJECT *obj);
    FL_OBJECT *fl_get_spinner_up_button(FL_OBJECT *obj);
    FL_OBJECT *fl_get_spinner_down_button(FL_OBJECT *obj);

They return the addresses of the objects the spinner object is made up from, i.e., that of the input field and the buttons for increasing and decreasing the spinner's value. These then can be used to set or query the way the individual component objects are drawn. The addresses of these sub-objects shouldn't be used for any other purposes, especially their callback function may never be changed!

## 17.7 Thumbwheel Object

Thumbwheel is another valuator that can be useful for letting the user indicate a value between some fixed bounds. Both horizontal and vertical thumbwheels exist. They have a minimum, a maximum and a current value (all floating point values). The user can change the current value by rolling the wheel.

### 17.7.1 Adding Thumbwheel Objects

To add a thumbwheel to a form use

    FL_OBJECT *fl_add_thumbwheel(int type, FL_Coord x, FL_Coord y,
                                 FL_Coord w, FL_Coord h, const char *label);

The meaning of the parameters is as usual. The label is by default placed below the thumbwheel.

### 17.7.2 Thumbwheel Types

The following types of thumbwheels are available:

`FL_VERT_THUMBWHEEL`

  A vertical thumbwheel.

`FL_HOR_THUMBWHEEL`

  A horizontal thumbwheel.

### 17.7.3 Thumbwheel Interaction

Whenever the user changes the value of the thumbwheel using the mouse or keyboard, the thumbwheel is returned (or the callback called) by the interaction routines. You change the value of a thumbwheel by dragging the mouse inside the wheel area or, for vertical thumbwheels also by using the scroll wheel of the mouse. Each pixel of movement changes the value of the thumbwheel by 0.005, which you can change using the `fl_set_thumbwheel_step()` function.

The keyboard can be used to change the value of a thumbwheel. Specifically, the `<Up>` and `<Down>` cursor keys can be used to increment or decrement the value of a vertical thumbwheel and the `<Right>` and `<Left>` cursor keys can be used to increment or decrement the value of horizontal thumbwheel. Each pressing of the cursor key changes the thumbwheel value by the current step value. The `<Home>` key can be used to set the thumbwheel to a known value, which is the average of the minimum and the maximum value of the thumbwheel.

In some applications you might not want the thumbwheel to be returned all the time. To change the default, call the following routine:

    void fl_set_object_return(FL_OBJECT *obj, unsigned int when);

where the parameter `when` can be one of the four values

`FL_RETURN_NONE`

  Never return or invoke callback.

`FL_RETURN_END_CHANGED`

  Return or invoke callback at end (mouse release) if value is changed since last return.

`FL_RETURN_CHANGED`

  Return or invoke callback whenever the thumbwheel value is changed.

`FL_RETURN_END`

  Return or invoke callback at end (mouse release) regardless if the value is changed or not.

`FL_RETURN_ALWAYS`

  Return or invoke callback whenever the value changes or the mouse button is released.

See demo program ``thumbwheel.c`' for an example use of this.

### 17.7.4 Other Thumbwheel Routines

To change the value and bounds of a thumbwheel use the following routines

    double fl_set_thumbwheel_value(FL_OBJECT *obj, double val);
    void fl_set_thumbwheel_bounds(FL_OBJECT *obj, double min, double max);

By default, the minimum value is 0.0, the maximum is 1.0 and the value is 0.5.

To obtain the current value or bounds of a thumbwheel use

    double fl_get_thumbwheel_value(FL_OBJECT *obj);
    void fl_get_thumbwheel_bounds(FL_OBJECT *obj, double *min, double *max);

By default, the bounds are "hard", i.e., once you reach the minimum or maximum, the wheel would not turn further in this direction. However, if desired, you can make the bounds to turn over such that it crosses over from the minimum to the maximum value and vice versa. To this end, the following routine is available

    int fl_set_thumbwheel_crossover(FL_OBJECT *obj, int yes_no);

In a number of situations you might like thumbwheel values to be rounded to some values, e.g., to integer values. To this end use the routine

    void fl_set_thumbwheel_step(FL_OBJECT *obj, double step);

After this call thumbwheel values will be rounded to multiples of `step`. Use a value 0.0 for `step` to switch off rounding.

To get the current setting for this call

    double fl_set_thumbwheel_step(FL_OBJECT *obj);

### 17.7.5 Thumbwheel Attributes

Setting colors via `fl_set_object_color()` has no effect on thumbwheels.

### 17.7.6 Remarks

See the demo program ``thumbwheel.c`' for an example of the use of thumbwheels.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated on January 5, 2026 using texi2html 1.82.