@node Part III Button-like Objects
@chapter Button-like Objects

A very important class of objects are the buttons. Buttons are placed
on the form such that the user can push them with the mouse. Different
types of buttons exist: buttons that return to their normal position
when the user releases the mouse, buttons that stay pushed until the
user pushes them again and radio buttons that make other buttons be
released.

@ifhtml
@center @image{images/buttontypes}
@end ifhtml
@ifnothtml
@center @image{images/buttontypes,7cm}
@end ifnothtml


Also different shapes of buttons exist. Normal buttons are rectangles
that come out of the background. When the user pushes them they go
into the background (and possibly change color). Lightbuttons have a
small light inside them. Pushing the button switches the light on.
Round buttons are simple circles. When pushed, a colored circle
appears inside them. Bitmap and pixmap buttons are buttons whose
labels are graphics rather than text.

@ifnottex

@menu
* Adding Button Objects:   Adding Button Objects
* Button Types:            Button Types
* Button Interaction:      Button Interaction
* Other Button Routines:   Other Button Routines
* Button Attributes:       Button Attributes
* Remarks:                 Button Remarks
@end menu

@end ifnottex


@node Adding Button Objects
@section Adding Button Objects

Adding an object To add buttons use one of the following routines:
@findex fl_add_button()
@anchor{fl_add_button()}
@findex fl_add_lightbutton()
@anchor{fl_add_lightbutton()}
@findex fl_add_roundbutton()
@anchor{fl_add_roundbutton()}
@findex fl_add_round3dbutton()
@anchor{fl_add_round3dbutton()}
@findex fl_add_checkbutton()
@anchor{fl_add_checkbutton()}
@findex fl_add_bitmapbutton()
@anchor{fl_add_bitmapbutton()}
@findex fl_add_pixmapbutton()
@anchor{fl_add_pixmapbutton()}
@findex fl_add_labelbutton()
@anchor{fl_add_labelbutton()}
@findex fl_add_scrollbutton()
@anchor{fl_add_scrollbutton()}
@example
FL_OBJECT *fl_add_button(int type, FL_Coord x, FL_Coord y,
                         FL_Coord w, FL_Coord h,
                         const char *label);
FL_OBJECT *fl_add_lightbutton(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w,FL_Coord h,
                              const char *label);
FL_OBJECT *fl_add_roundbutton(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w,FL_Coord h,
                              const char *label);
FL_OBJECT *fl_add_round3dbutton(int type, FL_Coord x, FL_Coord y,
                                FL_Coord w,FL_Coord h,
                                const char *label);
FL_OBJECT *fl_add_checkbutton(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w,FL_Coord h,
                              const char *label);
FL_OBJECT *fl_add_bitmapbutton(int type, FL_Coord x, FL_Coord y,
                               FL_Coord w,FL_Coord h,
                               const char *label);
FL_OBJECT *fl_add_pixmapbutton(int type, FL_Coord x, FL_Coord y,
                               FL_Coord w,FL_Coord h,
                               const char *label);
FL_OBJECT *fl_add_labelbutton(int type, FL_Coord x, FL_Coord y,
                              FL_Coord w,FL_Coord h,
                              const char *label);
FL_OBJECT *fl_add_scrollbutton(int type, FL_Coord x, FL_Coord y,
                               FL_Coord w,FL_Coord h,
                               const char *label);
@end example

The meaning of the parameters is as usual. The label is by default
placed inside the button for button and lightbutton. For roundbutton,
round3dbutton, bitmapbutton and pixmapbutton, it is placed to the
right of the circle and to the bottom of the bitmap/pixmap
respectively. For scrollbutton, the label must be of some
pre-determined string that indicates the direction of the scroll
arrow.

@node Button Types
@section Button Types

The following types of buttons are available:
@table @code
@tindex FL_NORMAL_BUTTON
@anchor{FL_NORMAL_BUTTON}
@item FL_NORMAL_BUTTON
Returns value when released.

@tindex FL_PUSH_BUTTON
@anchor{FL_PUSH_BUTTON}
@item FL_PUSH_BUTTON
Stays pushed until user pushes it again.

@tindex FL_MENU_BUTTON
@anchor{FL_MENU_BUTTON}
@item FL_MENU_BUTTON
Returns value when pushed, useful e.g.@: for opening a popup when
pushed.

@tindex FL_TOUCH_BUTTON
@anchor{FL_TOUCH_BUTTON}
@item FL_TOUCH_BUTTON
Returns value as long as the user pushes it.

@tindex FL_RADIO_BUTTON
@anchor{FL_RADIO_BUTTON}
@item FL_RADIO_BUTTON
Push button that switches off other radio buttons.

@tindex FL_HIDDEN_BUTTON
@anchor{FL_HIDDEN_BUTTON}
@item FL_HIDDEN_BUTTON
Invisible normal button.

@tindex FL_INOUT_BUTTON
@anchor{FL_INOUT_BUTTON}
@item FL_INOUT_BUTTON
Returns value both when pushed and when released.

@tindex FL_RETURN_BUTTON
@anchor{FL_RETURN_BUTTON}
@item FL_RETURN_BUTTON
Like a normal button but reacts on the @code{<Return>} key.

@tindex FL_HIDDEN_RET_BUTTON
@anchor{FL_HIDDEN_RET_BUTTON}
@item FL_HIDDEN_RET_BUTTON
Invisible return button.
@end table

Except for the @code{@ref{FL_HIDDEN_BUTTON}} and
@code{@ref{FL_HIDDEN_RET_BUTTON}}, which are invisible, all types of
button look similar on the screen but their function is quite
different. Each of these buttons gets pushed down when the user
presses the mouse on top of it. What actually happens when the user
does so depends on the type of the button. An
@code{@ref{FL_NORMAL_BUTTON}}, @code{@ref{FL_TOUCH_BUTTON}} and
@code{@ref{FL_INOUT_BUTTON}} gets released when the user releases the
mouse button. Their difference lies in the moment at which the
interaction routines return them (see below). A
@code{@ref{FL_PUSH_BUTTON}} remains pushed and is only released when
the user pushes it again. A @code{@ref{FL_RADIO_BUTTON}} is a push
button with the following extra property: whenever the user pushes a
radio button, all other pushed radio buttons in the same form (or in
the same group) are released. In this way the user can make its choice
among several possibilities. A @code{@ref{FL_RETURN_BUTTON}} behaves
like a normal button, but it also reacts when the @code{<Return>} key
on the keyboard is pressed. When a form contains such a button (of
course there can only be one) the @code{<Return>} key can no longer be
used to move between input fields. For this the @code{<Tab>} key must
be used.

A @code{@ref{FL_HIDDEN_BUTTON}} behaves like a normal button but is
invisible. A @code{@ref{FL_HIDDEN_RET_BUTTON}} is like a hidden button
but also reacts to @code{<Return>} key presses.


@node Button Interaction
@section Button Interaction

@code{@ref{FL_NORMAL_BUTTON}}s, @code{@ref{FL_PUSH_BUTTON}}s,
@code{@ref{FL_RADIO_BUTTON}}s, @code{@ref{FL_RETURN_BUTTON}}s and
@code{@ref{FL_HIDDEN_BUTTON}}s are returned at the moment the user
releases the mouse after having pressed it on the button. A
@code{@ref{FL_MENU_BUTTON}}, in contrast, is returned already on a
mouse press. A @code{@ref{FL_INOUT_BUTTON}} is returned both when the
user presses it and when the user releases it. A
@code{@ref{FL_TOUCH_BUTTON}} is returned all the time as long as the
user keeps the mouse button pressed while the mouse is on top of it. A
@code{@ref{FL_RETURN_BUTTON}} and a @code{@ref{FL_HIDDEN_RET_BUTTON}}
are also returned when the user presses the @code{<Return>} key.

As for other ``active'' objects, you can control under which
conditions a button object gets returned or its callback invoked
by using the function
@example
int fl_set_object_return(FL_OBJECT *obj, unsigned int when);
@end example
where reasonable values for @code{when} are
@table @code
@item @ref{FL_RETURN_NONE}
Never return object or invoke callback.

@item @ref{FL_RETURN_END_CHANGED}
Return object or invoke callback when mouse button is released and at
the same moment the state of the button changed.

@item @ref{FL_RETURN_CHANGED}
Return object or invoke callback whenever the state of the button
changes.

@item @ref{FL_RETURN_END}
Return object or invoke callback when mouse button is released

@item @ref{FL_RETURN_ALWAYS}
Return object or invoke callback on all of the above condtions.
@end table

Most buttons will always return @code{@ref{FL_RETURN_END}} and
@code{@ref{FL_RETURN_CHANGED}} at the same time. Exceptions are
@code{@ref{FL_INOUT_BUTTON}}s and @code{@ref{FL_TOUCH_BUTTON}}s. The
former returns @code{@ref{FL_RETURN_CHANGED}} when pushed and both
@code{@ref{FL_RETURN_END}} and @code{@ref{FL_RETURN_CHANGED}} together
when released. @code{@ref{FL_TOUCH_BUTTON}}s return when pressed, then
@code{@ref{FL_RETURN_CHANGED}} at regular time intervals while being
pressed and finally @code{@ref{FL_RETURN_END}} when released.

See demo @file{butttypes.c} for a feel of the different button types.


@node Other Button Routines
@section Other Button Routines

The application program can also set a button to be pushed or not
itself without a user action. To this end use the routine
@findex fl_set_button()
@anchor{fl_set_button()}
@example
void fl_set_button(FL_OBJECT *obj, int pushed);
@end example
@noindent
@code{pushed} indicates whether the button should be pushed (1) or
released (0). When setting a @code{@ref{FL_RADIO_BUTTON}} to be pushed
this automatically releases the currently pushed radio button in the
same form (or group). Also note that, while this routine only
simulates the visual appearance and perhaps some internal states, it
does not affect the program flow in any way, i.e.@: setting a button
as being pushed does not invoke its callback or results in the button
becoming returned to the program. For that
@code{@ref{fl_trigger_object()}} is to be used or, more conveniently,
just follow up @code{@ref{fl_set_button()}} with a call of
@code{@ref{fl_call_object_callback()}}.

To figure out whether a button is pushed or not
use@footnote{@code{@ref{fl_mouse_button()}} can also be used.}
@findex fl_get_button()
@anchor{fl_get_button()}
@example
int fl_get_button(FL_OBJECT *obj);
@end example

Sometimes you want to give the button a different meaning depending on
which mouse button gets pressed on it. To find out which mouse button
was used at the last push (or release) use the routine
@findex fl_get_button_numb()
@anchor{fl_get_button_numb()}
@example
int fl_get_button_numb(FL_OBJECT *obj);
@end example
@noindent
It returns one of the constants @code{@ref{FL_LEFT_MOUSE}},
@code{@ref{FL_MIDDLE_MOUSE}}, @code{@ref{FL_RIGHT_MOUSE}},
@code{@ref{FL_SCROLLUP_MOUSE}} or @code{@ref{FL_SCROLLDOWN_MOUSE}}
(the latter two are from the scroll wheel of the mouse). If the last
push was triggered by a shortcut (see below), the function returns the
@code{keysym} (ASCII value if the key used is between 0 and 127)
of the key plus
@tindex FL_SHORTCUT
@code{@ref{FL_SHORTCUT}}. For example, if a button has @code{<Ctrl>C}
as its shortcut the button number returned upon activation of the
shortcut will be @code{FL_SHORTCUT + 3} (the ASCII value of
@code{<Ctrl>C} is 3).

It can also be controlled which mouse buttons a buttons reacts to at
all. To set which mouse buttons the button reacts to use
@findex fl_set_button_mouse_buttons()
@anchor{fl_set_button_mouse_buttons()}
@example
void fl_set_button_mouse_buttons(FL_OBJECT *obj, int mbuttons);
@end example
@noindent
@code{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". Unless set differently a button reacts to all mouse buttons.

To determine which mouse buttons a button is reacting to use
@findex fl_get_button_mouse_buttons()
@anchor{fl_get_button_mouse_buttons()}
@example
void fl_get_button_mouse_buttons(FL_OBJECT *obj,
                                 unsigned int *mbuttons);
@end example
@noindent
The value returned via @code{mbuttons} is the same value as would
be used in @code{@ref{fl_set_button_mouse_buttons()}}.

More information about the last event can be obtained by calling the
function
@code{@ref{fl_last_event()}}
@findex fl_last_event()
@example
const XEvent *fl_last_event(void);
@end example

In a number of situations it is useful to define a keyboard equivalent
for a button. You might e.g.@: want to define that @code{<Ctrl>Q} has
the same meaning as pressing the "Quit" button. This can be achieved
using the following call:
@findex fl_set_button_shortcut()
@anchor{fl_set_button_shortcut()}
@example
void fl_set_button_shortcut(FL_OBJECT *obj, const char *str,
                            int showUL);
@end example
@noindent
Note that @code{str} is a string, not a single character. This string
is a list of all the characters to become keyboard shortcuts for the
button. E.g.@: if you use string "^QQq" the button will react on the
keys @code{q}, @code{Q} and @code{<Ctrl>Q}. (As you see you can use
the symbol @code{^} to indicate the control key. Similarly you can use
the symbol @code{#} to indicate the @code{<Alt>} key.) Be careful with
your choices. When the form also contains input fields you probably
don't want to use the normal printable characters because they can no
longer be used for input in the input fields. Shortcuts are always
evaluated before input fields. Other special keys, such as @code{<F1>}
etc., can also be used as shortcuts. @xref{Shortcuts}, for details.
Finally, keep in mind that a button of type @code{FL_RETURN_BUTTON} is
in fact nothing more than a normal button, just with the
@code{<Return>} key set as the shortcut. So don't change the shortcuts
for such a button.

If the third parameter @code{showUL} is true and one of the letters in
the object label matches the shortcut the matching letter will be
underlined. This applies to non-printable characters (such as
@code{#A}) as well in the sense that if the label contains the letter
@code{a} or @code{A} it will be underlined (i.e.@: special characters
such as @code{#} and @code{^} are ignored when matching). A false
value (0) for @code{showUL} turns off underlining without affecting
the shortcut. Note that although the entire object label is searched
for matching character to underline of the shortcut string itself only
the first (non-special) character is considered, thus a shortcut
string of @code{"Yy"} for the label @code{"Yes"} will result in the
letter @code{Y} becoming underlined while for @code{"yY"} it won't.

To set the bitmap to use for a bitmap button the following functions
can be used:
@findex fl_set_bitmapbutton_data()
@anchor{fl_set_bitmapbutton_data()}
@findex fl_set_bitmapbutton_file()
@anchor{fl_set_bitmapbutton_file()}
@example
void fl_set_bitmapbutton_data(FL_OBJECT *obj, int w, int h,
                              unsigned char *bits);
void fl_set_bitmapbutton_file(FL_OBJECT *obj, const char *filename);
@end example

Similarly, to set the pixmap to use for a pixmap button the following
routines can be used:
@findex fl_set_pixmapbutton_data()
@anchor{fl_set_pixmapbutton_data()}
@findex fl_set_pixmapbutton_file()
@anchor{fl_set_pixmapbutton_file()}
@findex fl_set_pixmapbutton_pixmap()
@anchor{fl_set_pixmapbutton_pixmap()}
@example
void fl_set_pixmapbutton_data(FL_OBJECT *obj, unsigned char **bits);
void fl_set_pixmapbutton_file(FL_OBJECT *obj, const char *file);
void fl_set_pixmapbutton_pixmap(FL_OBJECT *obj, Pixmap id,
                                 Pixmap mask);
@end example
@noindent
To use the first routine, you @code{#include} the pixmap file into
your source code and use the pixmap definition data (an array of char
pointers) directly. For the second routine the filename @code{file}
that contains the pixmap definition is used to specify the pixmap. The
last routine assumes that you already have a X Pixmap resource ID for
the pixmap you want to use. Note that these routines do not free a
pixmap already associated with the button. To free the pixmaps use
the function
@findex fl_free_pixmapbutton_pixmap()
@anchor{fl_free_pixmapbutton_pixmap()}
@example
void fl_free_pixmapbutton_pixmap(FL_OBJECT *obj);
@end example
@noindent
This function frees the pixmap and mask together with all the colors
allocated for them.

To get the pixmap and mask that is currently being displayed, use the
following routine
@findex fl_get_pixmapbutton_pixmap()
@anchor{fl_get_pixmapbutton_pixmap()}
@example
Pixmap fl_get_pixmapbutton_pixmap(FL_OBJECT *obj,
                                  Pixmap &pixmap, Pixmap &mask);
@end example

Pixmaps are by default displayed centered inside the bounding box.
However, this can be changed using the following routine
@findex fl_set_pixmapbutton_align()
@anchor{fl_set_pixmapbutton_align()}
@example
void fl_set_pixmapbutton_align(FL_OBJECT *obj, int align,
                               int xmargin, int ymargin);
@end example
@noindent
where @code{align} is the same as that used for labels. @xref{Label
Attributes and Fonts}, for a list. @code{xmargin} and @code{ymargin}
are extra margins to leave in addition to the object border width.
Note that although you can place a pixmap outside of the bounding box,
it probably is not a good idea.

When the mouse enters a pixmap button an outline of the button is
shown. If required, a different pixmap (the focus pixmap) can also be
shown. To set such a focus pixmap the following functions are
available:
@findex fl_set_pixmapbutton_focus_data()
@anchor{fl_set_pixmapbutton_focus_data()}
@findex fl_set_pixmapbutton_focus_file()
@anchor{fl_set_pixmapbutton_focus_file()}
@findex fl_set_pixmapbutton_focus_pixmap()
@anchor{fl_set_pixmapbutton_focus_pixmap()}
@example
void fl_set_pixmapbutton_focus_data(FL_OBJECT *obj,
                                     unsigned char **bits);
void fl_set_pixmapbutton_focus_file(FL_OBJECT *obj,
                                    const char *file);
void fl_set_pixmapbutton_focus_pixmap(FL_OBJECT *obj, Pixmap id,
                                      Pixmap mask);
@end example
@noindent
The meanings of the parameters are the same as that in the regular
pixmap routines.

Finally, there's a function that can be used to enable or disable the
focus outline
@findex fl_set_pixmapbutton_focus_outline()
@anchor{fl_set_pixmapbutton_focus_outline()}
@example
void fl_set_pixmapbutton_focus_outline(FL_OBJECT *obj, int yes_no);
@end example
@noindent
See also @ref{Pixmap Object}, for pixmap color and transparency
handling.



@node Button Attributes
@section Button Attributes


For normal buttons the first color argument (@code{col1}) to
@code{@ref{fl_set_object_color()}} controls the normal color and the
second (@code{col2}) the color the button has when pushed. For
lightbuttons @code{col1} is the color of the light when off and
@code{col2} the color when on. For round buttons, @code{col1} is the
color of the circle and @code{col2} the color of the circle that is
placed inside it when pushed. For round3dbutton, @code{col1} is the
color of the inside of the circle and @code{col2} the color of the
embedded circle. For bitmapbuttons, @code{col1} is the normal box
color (or bitmap background if boxtype is not @code{FL_NO_BOX}) and
@code{col2} is used to indicate the focus color. The foreground color
of the bitmap is controlled by label color (as set via
@code{@ref{fl_set_object_lcol()}}. For scrollbutton, @code{col1} is
the overall boundbox color (if boxtype is not @code{FL_NO_BOX}),
@code{col2} is the arrow color. The label of a scrollbutton must be a
string with a number between 1 and 9 (except 5), indicating the arrow
direction like on the numerical key pad. The label can have an
optional prefix @code{#} to indicate uniform scaling. For example, the
label @code{"#9"} tells that the arrow should be pointing up-right and
the arrow has the identical width and height regardless the overall
bounding box size.

@node Button Remarks
@section Remarks

See all demo programs, in particular @file{pushbutton.c} and
@file{buttonall.c} for the use of buttons.
