Valuator Objects
****************

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.

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.

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.

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 moving the slider.

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.

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

Slider Attributes
-----------------

Never use FL_NO_BOX as the boxtype for a slider. For FL_VERT_NICE_SLIDERs and FL_HOR_NICE_SLIDERs 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.

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.

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

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.

Scrollbar Object
================

Scrollbars are similar to sliders (as a matter of fact, scrollbars are made with sliders and scrollbuttons), and useful in letting 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 press the scroll buttons. Whenever the value changes, it is reported to the application program via the callback function.

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.

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.

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 is changed by moving the mouse inside the scrollbar area or. For fine control hold down the left or right <Shift> key while moving the slider.

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.

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

Scrollbar Attributes
--------------------

Never use FL_NO_BOX as the boxtype for a scrollbar. For FL_VERT_NICE_SCROLLBARs and FL_HOR_NICE_SCROLLBARs 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.

Remarks
-------

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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 (i.e.{ drawn in in XOR mode).

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

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.

Other Positioner Routines
-------------------------

To set the value of the positioner and the boundary values use the routines:

     void fl_set_positioner_xvalue(FL_OBJECT *obj, double val);
     void fl_set_positioner_xbounds(FL_OBJECT *obj, double min, double max);
     void fl_set_positioner_yvalue(FL_OBJECT *obj, double val);
     void fl_set_positioner_ybounds(FL_OBJECT *obj, double min, double max);

By default the minimum values are 0.0, the maximum values are 1.0 and the actual values are 0.5. 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.

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

     double fl_get_positioner_xvalue(FL_OBJECT *obj);
     void fl_get_positioner_xbounds(FL_OBJECT *obj,
                                    double *min, double *max);
     double fl_get_positioner_yvalue(FL_OBJECT *obj);
     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.0 for step to switch off rounding.

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.

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.

Remarks
-------

A demo can be found in positioner.c.

Counter Object
==============

A counter provides a different mechanism for the user to indicate a value. In consists of a box displaying a value and two or four buttons, two at the left and two at the right side. The user can press these buttons to change the value. If the counter has four buttons, the left-most and right-most button make the value change in large steps, the other buttons make it change in small steps. As long as the user keeps the mouse pressed, the value changes.

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.

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.

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.

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 the value changing 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);

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.

Remarks
-------

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

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.

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.

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

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 (Part III 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.

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_SPINNERs and -DBL_MAX and DBL_MAX for FL_FLOAT_SPINNERs.

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.

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_lcol(), 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 and those then can be used to set or query the way the individual components are drawn. The addresses of these sub-objects shouldn't be used for any other purposes, especially their callback function may never be changed!

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.

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.

Thumbwheel Types
----------------

The following types of thumbwheels are available:

FL_VERT_THUMBWHEEL
     A vertical thumbwheel.

FL_HOR_THUMBWHEEL
     A horizontal thumbwheel.

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.

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.

Thumbwheel Attributes
---------------------

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

Remarks
-------

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