[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
19.1 Select Object | ||
19.2 Nmenu Object | ||
19.3 Browser Object |
A select object is a rather simple object that allows the user to pick alternatives from a linear list that pops up when he clicks on the object. It remembers the last selected item, which is also shown on top of the select object.
The select object internally uses a popup (see section Popups) and thus it can be helpful to understand at lest some aspects of how popups work to fully grasp the functionality of select objects.
19.1.1 Adding Select Objects | ||
19.1.2 Select Interaction | ||
19.1.3 Other Select Routines | ||
19.1.4 Select Attributes | ||
19.1.5 Remarks |
To add a select object to a form use
FL_OBJECT *fl_add_select(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label) |
There are currently three types which just differ by the way they look:
FL_NORMAL_SELECT
Per default this type is drawn as a rounded, flat box (but you can change that by setting a different boxtype for the object) with the text of the currently selected item in its center.
FL_MENU_SELECT
This select object looks like a button with a little extra box at its
right side (just like a FL_MENU_BUTTON
) and the text of the
currently selected item drawn on the button-like object.
FL_DROPLIST_SELECT
This type looks like a button with the text of the currently selected item on top of it and a second square button directly beside it with an downward pointing arrow on it.
Per default label
is drawn outside and to the left of the
object.
Once a new select object has been created items have to be added to it. For this the following function exists:
FL_POPUP_ENTRY *fl_add_select_items(FL_OBJECT *obj, const char items, ...); |
items
is a string with the items to add, separated by the
|
character. In the simplest case you would just use something
like "Item 1|Item 2|Item 3"
to add three items to the list. If
there weren't any items before the first item will be automatically
shown as the selected one.
As also described in the documentation for the similar function
fl_popup_add_entries()
(see section Adding Popups) the text
for an item may contain "special sequences" that start with the
character %
and the may require an additional argument passed
to the function after the items
argument:
%x
Set a value of type long int
that's passed to all callback
routines for the item. The value must be given in the arguments
following the items
string.
%u
Set a user_void
pointer that's passed to all callbacks of the
item. The pointer must be specified in the arguments following the
items
string.
%f
Set a callback function that gets called when the item is selected. The function is of type
int callback(FL_POPUP_RETURN *r); |
Informaton about the item etc. gets passed to the callback function
via the FL_POPUP_RETURN structure and the return value of the
function can be used to keep the selection being made form becoming
reported back to the user made by returning a value of
FL_IGNORE
(-1). The functions address must be given in the
arguments following the items
string.
%E
Set a callback routine that gets called each time the mouse enters the
item (as long as the item isn't disabled or hidden). The type of the
function is the same as that of the callback function for the
selection of the item but it's return value is never used. The
functions address must be given in the arguments following the
items
string.
%L
Set a callback routine that gets called each time the mouse leaves the
item. The type of the function is the same that as of the callback
function for the selection of the item but it's return value is never
used. The functions address must be given in the arguments following
the items
string.
%d
Marks the item as disabled, i.e. it can't be selected and its text is per default drawn in a different color
%h
Marks the item as hidden, i.e. it is not shown while in this state.
%S
For items with shortcut keys it's quite common to have them shown on
the right hand side. Using %S
you can split the items text
into two parts, the first one (before %S
) being drawn flushed
left and the second part flushed right. Note that using this special
sequence doesn't automatically sets a shortcut key, this still has to
be done using %s
.
%s
Sets one or more shortcut keys for an item. Requires a string with the
shortcuts in the arguments following the items
string.
See section Shortcuts, for details on how to define shortcuts. Please note
that the character in the label idenical to the shortcut character is
only shown as underlined if %S
isn't used.
%%
Use this to get a %
within the text of an item.
If you compare this list of "special sequences" with those listed for
the fl_popup_add_entries()
function you will find that
aome are missing. This is because a select object is a simple linear
list of items that uses only parts of the popups functionalities.
Another way to set up the popup of a select object is to use the function
long fl_set_select_items(FL_OBJECT *obj, FL_POPUP_ITEM *item); |
Here item
is an array of structures of type FL_POPUP_ITEM
with the text
member of the very last element of the array
being set to NULL
, indicating the end of the array.
The text
member is the text of the item. It may only contain
one "special sequence", %S
to indicate that the string is to be
split at that position into the part of the item label to be drawn to
the left and on the right side (also prepending the string with
_
or /
has no effect). callback
is a callback
function to be invoked on selection of the item. shortcut
is a
string for setting keybord shortcuts for the item. type
has no
function at all here (there can be only items of type
FL_POPUP_NORMAL
in a select objects popup) and state
can
be set to FL_POPUP_DISABLED
and/or Fl_POPUP_HIDDEN
.
Please note: when the select object already had items before the call
of fl_set_select_items()
then they are removed before the
new ones are set. The values assigned to the items start at 0.
A third way to "populate" a select object is to create a popup directly and then associate it with the selecy object using
int fl_set_select_popup(FL_OBJECT *obj, FL_POPUP *popup); |
If the select object lready had a popup before this will be deleted
and replaced by the new popup passed as the second argument. Please
note that the popup the argument popup
points to may not
contain any entries other than those of type FL_POPUP_NORMAL
(and, of course, the popup can't be a sub-popup of another popup).
The simplest interaction with a select object consists of clicking onto the object and then selecting an item in the popup that gets shown directly beside the mouse position.
If you click with the left or right mouse button onto the select object previous or next item, respectively, will be selected. If youl keep the left or mouse button pressed down for a longer time slowly all alternatives are selected, one after each other.
You finally can also use the scroll wheel of your mouse to select the next or previous item (scrolling down selects the next, scrolling up the previous item).
On every selection of an item (also if the already selected item is re-selected) a callback that may have been associated with the item is executed. The callback receives as its argument a pointer to a structure of type FL_POPUP_RETURN.
Its val
member is a integer value associated with the entry.
It can be set explicitely on creationg of the item using the %x
"special sequence". If not given then first item gets the value 0,
the next 1 etc. user_data
is a pointer to some user data, which
can be set on creation of the item using %u
. text
is the
string used in creating the item, including all "special sequences",
while label
is the string shown in the popup for the item. If
there was a special sequence of %S
in the string that was used
to create the item accel
is the text that appears right-flushed
in the popup for the item. entry
is a pointer to the popup
entry that represents the item in the select object and, finally,
popup
is the popup associated with the select object.
Normally, when a new item is selected this is reported back to the
caller either by calling the select objects callback (if one exists)
or by returning the onject as the result of a call of e.g.
fl_do_forms()
. But if the callback for the item itself
returns FL_IGNORE
then the latter doesn't happen. This can be
useful for cases where all work for a change of the selection can
already be done within the items callback and the "main loop"
shouldn't get involved anymore.
As for all other normal objects the condition under which a
FL_SELECT
object gets returned to the application (or an
associate callback is called) can be influenced by calling the
function
int fl_set_object_return(FL_OBJECT *obj, int when) |
where when
can have the following values
FL_RETURN_NONE
Never return or invoke a callback.
FL_RETURN_END_CHANGED
Return or invoke callback if end of interaction and selection of an item coincide.
FL_RETURN_CHANGED
Return or invoke callback whenever an item is selected (this is the default).
FL_RETURN_END
Return or invoke callback on end of an interaction.
FL_RETURN_ALWAYS
Return (or invoke callback) whenever the interaction ends and/or an item is selected.
Per default the popup of a select objects remains shown when the user releases the mouse somewhere outside the popup window (or on its title area). The alternative is to close the popup immediately when the user releases the mouse, independent of where it is. Using the function
int fl_set_select_policy(FL_OBJECT *obj, int policy); |
the program can switch between these two modes of operation,
where policy
can be on of two values:
FL_POPUP_NORMAL_SELECT
Keeps the popup opened when the mouse isn't released on one of the selectable items.
FL_POPUP_DRAG_SELECT
Close the popup immediately when the mouse button is released.
The function returns on success the previous setting of the "policy" and -1 on error.
To find out which item is currently selected use
FL_POPUP_RETURN *fl_get_select_item(FL_OBJECT *obj); |
It returns a pointer to a structure of type FL_POPUP_RETURN as already described above, containing all needed information about the selected item.
For some actions, e.g. deletion of an item etc., it is necessary to know the popup entry that represents it. Therefore it's possible to search the list of items accoring to several criteria:
FL_POPUP_ENTRY *fl_get_select_item_by_value(FL_OBJECT *obj, long val); FL_POPUP_ENTRY *fl_get_select_item_by_label(FL_OBJECT *obj, const char *label); FL_POPUP_ENTRY *fl_get_select_item_by_label(FL_OBJECT *obj, const char *text); |
The first function, fl_get_select_item_by_value()
,
searches through the list of items and returns the first one with the
val
associated with the item (or NULL
if none is found).
The second, fl_get_select_item_by_label()
searches for a
certain label as displayed for the iten in the popup. The third,
fl_get_select_item_by_text()
searches for the text the
item was created by (that might be the same as the label text in
simple cases). Please note that all functions return a structure of
type FL_POPUP_ENTRY (and not FL_POPUP_RETURN, which
gives you direct access to the entry in the popup for the item.
Using e.g. the result of one of the functions above you can also set the currently selected item via your program using
FL_POPUP_RETURN *fl_set_select_item(FL_OBJECT *obj, FL_POPUP_ENTRY *entry); |
Or you could use the result to delete an item:
int fl_delete_select_item(FL_OBJECT *obj, FL_POPUP_ENTRY *entry); |
Please note that the values associated with items won't change due to removing an item.
Alternatively, you can replace an item by one or more new ones. To do that use
FL_POPUP_ENTRY *fl_replace_select_item(FL_OBJECT *obj, FL_POPUP_ENTRY *old, const char *new_items, ...); |
old
designates the item to be removed and new_items
is a
string exactly like it would be used in fl_add_select_items()
for the items
argument, that defines the item(s) to replace the
existing item. Please note that, unless values to be associated with
the items (see the val
member of the FL_POPUP_RETURN
structure) there's a twist here. When items get created they per
default reeive increasing values, starting at 0. This also holds for
items that get created in the process of replacement. The result is
that the ordering of those values in that case won;t represent the
order in whch they appear in the select objects popup.
Another sometimes useful function allows to insert new items somewhere in the middle of a list of already existing items:
FL_POPUP_ENTRY *fl_insert_select_item(FL_OBJECT *obj, FL_POPUP_ENTRY *after, const char *new_items, ...); |
after
is the entry after which the new item(s) are to be
inserted (if it's NULL
the new items are inserted at the very
start). The rest of the argumnts are the same as for
fl_replace_select_item()
and the same caveats about the
values associated autimatically with the new items holds.
It's possible to remove all items from a select object by calling
int fl_clear_select(FL_OBJECT *obj); |
Afterwards you have to call again e.g.
fl_add_select_items()
to set new entries. Note that if
you used fl_set_select_popup()
to set a popup for the
select object then that popup gets deleted automatically on calling
fl_clear_select()
! The values automatically associated
with items when calling fl_add_select_items()
will start
at 0 again.
The two color arguments, clo1
and col2
, of the function
fl_set_object_color()
set the background color of the
obect normally and when the mouse is hovering over it, respectively.
FL_COLOR fl_set_selection_text_color(FL_OBJECT *obj, FL_COLOR color); FL_COLOR fl_get_selection_text_color(FL_OBJECT *obj); |
the color of the text of the currenty selected item on top of the object can be set or queried.
To control (or determine) the alignment of the text with the currently selected item on top of the select object use
int fl_set_select_text_align(FLOBJECT *obj, int align); int fl_get_select_text_align(FLOBJECT *obj); |
Please note that the FL_ALIGN_INSIDE
flag must be set with
align
since the text always will be drawn withing the
boundaries of the object. On success the function return the old
setting for the alignemnt or -1 on error.
Finally, the font style and size of the text can be set or obtained using
int fl_set_select_font(FL_OBJECT *obj, int style, int size); int fl_get_select_font(FL_OBJECT *obj, int *style, int *size); |
The rest of the appearance of a select object concerns the popup that
is used. To avoid bloating the API unnecessarily no functions for
select objects were added that would just call popup functions. The
popup belonging to a select object can be easily ound from either
a FL_POPUP_ENTRY structure as returned by the functions for
searching for items or the L_POPUP_RETURN
structure passed
to all callbacks and also returned by
fl_get_select_item()
. Both structures have a member
called popup
that is a pointer to the popup associated with the
select object. For popup functions operation on indiviual items just
use the poiner to the FL_POPUP_ENTRY structure itself or the
entry
member of the FL_POPUP_RETURN structure.
There's also a convenience function for finding out the popup used for a select object:
FL_POPUP *fl_get_select_popup(FL_OBJECT *obj); |
During the lifetime of a select object the popup never changes as long
as fl_set_select_popup()
isn't called.
Per default the popup of a select object does not have a title drawn
on top of it. To change that use fl_popup_set_title()
.
To change the various colors and fonts used when drawing the popup use
the functions fl_popup_set_color()
and
fl_popup_entry_set_font()
(and
fl_popup_set_title_font()
).
To change the border width or minimum width of the popup use
fl_popup_set_bw()
and
fl_popup_set_min_width()
.
To disable or hide (or do the reverse) an item use the functions
fl_popup_entry_set_state()
and
fl_popup_entry_get_state()
.
The keyboard shortcut for an entry can be set via
fl_popup_entry_set_shortcut()
.
The callback functions (selection, enter and leave callback) for
individual items can be set via
fl_popup_entry_set_callback()
,
fl_popup_entry_set_enter_callback()
and
fl_popup_entry_set_leave_callback()
, a callback for the
whole popup with fl_popup_set_callback()
.
Finally, to assign a different (long) value to an item or set a
pointer to user data use fl_popup_entry_set_value()
and fl_popup_entry_set_user_data()
.
See the demo program `select.c' for an example of the use of select objects.
Another object type that heavily depends on popups is the "nmenu" object type. It is meant to be used for menus and the "n" in front of the name stands for "new" since this is a re-implementation of the old menu object type (which is now deprecated since it is based on XPopup).
19.2.1 Adding Nmenu Objects | ||
19.2.2 Nmenu Interaction | ||
19.2.3 Other Nmenu Routines | ||
19.2.4 Nmenu Attributes | ||
19.2.5 Remarks |
FL_OBJECT *fl_add_nmenu(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label); |
There are currently three types:
FL_NORMAL_NMENU
Probably the most often used type: shown as text on a borderless background, popup gets opened when clicked on.
FL_NORMAL_TOUCH_NMENU
Also shown as text on a borderless background, but popup gets opened when the mouse is moved on top of it without any further user action required.
FL_BUTTON_NMENU
When not active shown as text on borderless background, when clicked on popup is shown and the object itself being dispayed as a button.
FL_BUTTON_TOUCH_NMENU
When not active shown as text on borderless background, when mouse is moved onto it the popup is shown and the object itself is dispayed as a button.
Once a new nmenu object has been created items have to be added to it. For this the following function exists:
FL_POPUP_ENTRY *fl_add_nmenu_items(FL_OBJECT *obj, const char items, ...); |
items
is a string with the items to add, separated by the
|
character. In the simplest case you would just use something
like "Item 1|Item 2|Item 3"
to add three items to the list.
As also described in the documentation for the similar function
fl_popup_add_entries()
the text for an item may contain
"special sequences" that start with the character %
and the may
require an additional argument passed to the function after the
items
argument. All of those described in detail in the
documentation for the fl_popup_add_entries()
function can
also be used for nmenus.
Another way to set up the popup of a select object, using an array of FL_POPUP_ITEM structures, is via the function
long fl_set_nmenu_items(FL_OBJECT *obj, FL_POPUP_ITEM *item); |
The function expects an array of FL_POPUP_ITEM structuress, with
the very last element having NULL
as the text
member to
mark the end of the array.
The text
member of the structure may contain the character
sequence %S
to have the text drawn for the item split up at
that position and with everything before %S
drawn left-flushed
and the rest right-flushed. Moreover, text
may start with the
character /
and/or _
. If there's an underline a line is
drawn above the item. And if there's a slash this item marks the begin
of s sub-menu with all further items belonging to the sub-menu until a
structure with text
set to NULL
is found in the array.
(The /
and _
characters are, of course, not drawn.)
type
indicates the type of the item. It can be
FL_POPUP_NORMAL
Just a noral, plain item.
FL_POPUP_TOGGLE
An item that represents one of tow states and is drawn with a check-marker when in "on" state.
FL_POPUP_RADIO
A radio item, i.e. it belongs to a group of items of which only one can be in "on" state at a time. The are drawn with a circle to the left with circle for the "selected" item being filed with a color.
Please note that if text
starts with a /
the type
must be FL_POPUP_NORMAL
.
The state
member per default is FL_POPUP_NONE
. It can be
set to
FL_POPUP_NONE
No special flags are set for the state of the item.
FL_POPUP_DSABLED
The item is disabled and can't be selected.
FL_POPUP_HIDDEN
The popup is hidden, i.e. does not get shown (and thus can't be selected).
FL_POPUP_CHECKED
Only relevant for toggle or radio items, marks it as in "on" state.
callback
is a function that will be called if the item is
selected. The callback function has the following type:
typedef int (*FL_POPUP_CB)(FL_POPUP_RETURN *); |
It receives a pointer to a structure that contains all information about the item selected by the user:
typedef struct { long int val; /* value assigned to entry */ void *user_data; /* pointer to user data */ const char *text; /* text of selected popup entry */ const char *label; /* left-flished text */ const char *accel; /* right-flushed text */ const FL_POPUP_ENTRY *entry; /* selected popup entry */ const FL_POPUP *popup; /* popup we're called for */ } FL_POPUP_RETURN; |
val
is a value that has been associated with the item and
user_data
is a pointer that can be used to store the location
of further information. text
is the text that was used to
create the item (including all "special" characters), while
label
and accel
are the texts shown for the item on the
left and right. entry
is the pointer to the structure for the
item selected and popup
to the (sub-) popup the item belongs to
((see section Popups, for more details on these structures).
If the callback function already does all the work required on
seletion of the item have it return the value FL_IGNORE
to
keep the selection from being reported back to the main loop of the
program.
Finally, shortcut
is a string encoding the keybord shortcut to
be used for the item.
There'e also a third method to "populate" a menu. If you already created a popup than you can set it as the menu's popup via a call of
int fl_set_nmenu_popup(FL_POPUP *popup); |
Of course, the popup you associate with the nmenu object this way can't be a sub-popup.
There are, if seen interaction-wise, two types of nmenu objects, normal ones and touch nmenus. For normal nmenus a popup is opened when the user clicks on the area of the nmenu object while for touch nmenus the popup already is shown when the user moves the mouse unto the area. In other respects they behave identical: the user just selects one of the items in the popup (or one of the sub-popups) and then the popup is closed again. The selection can now be handled within a callback function and/or reported back to the main loop of the program.
The popup is always shown directly below the nmenu object (except for the case that the popup is that long that it wouldn't fit on the screen, in that case the popup is drawn above the nmenu's area0>
The most natural way to deal with a selection by the user is probably
via a callback for the item that was selected. But also a callback for
the popup as a whole or the object itself can be used. Item and popup
callback functions are of type FL_POPUP_CB
described above (and
in even more detail in Popups), while object callbacks
are "normal" XForms callback functions.
The condition under which a FL_NMENU
object gets returned to
the application (or an associate callback is called) can be influenced
by calling the function
int fl_set_object_return(FL_OBJECT *obj, int when) |
where when
can have the following values
FL_RETURN_NONE
Never return or invoke a callback.
FL_RETURN_END_CHANGED
Return or invoke callback if end of interaction and selection of an item coincide.
FL_RETURN_CHANGED
Return or invoke callback whenever an item is selected (this is the default).
FL_RETURN_END
Return or invoke callback on end of an interaction.
FL_RETURN_ALWAYS
Return (or invoke callback) whenever the interaction ends and/or an item is selected.
One detail about the interaction that can be adjusted is when the nmenu's popup gets closed. Per default, the popup is closed when an item is selected or (without a selection) when the user clicks somehwere outside of the popups area. This can be changed so that the popup also gets closed (without a selection) when the mouse button was clicked or released on a non-selectable item (giving the impression of a "pull-down" menu). For this purpose there's the
int fl_set_nmenu_policy(FL_OBJECT *obj, int policy); |
function where policy
can be one of two values:
FL_POPUP_NORMAL_SELECT
Default, popup stays open until mouse button is released on a selectable entry or button is clicked outside the popups area.
FL_POPUP_DRAG_SELECT
Popup is closed when the mouse button is released anywhere.
The function returns on success the previous setting of the "policy" and -1 on error.
To find out which item of a nmenu object was selected last use
FL_POPUP_RETURN *fl_get_nmenu_item(FL_OBJECT *obj); |
The functon returns either a pointer to a FL_POPUP_RETURN
structure with informations about the selected item (as already
discussed above when talking about callbacks) or NULL
if
no selection was made the last time the nmenu object was used.
For some actions, e.g. deletion of an item etc., it is necessary to know the popup entry that represents it. Therefore it's possible to search the list of items accoring to several criteria:
FL_POPUP_ENTRY *fl_get_nmenu_item_by_value(FL_OBJECT *obj, long val); FL_POPUP_ENTRY *fl_get_nmenu_item_by_label(FL_OBJECT *obj, const char *label); FL_POPUP_ENTRY *fl_get_nmneu_item_by_label(FL_OBJECT *obj, const char *text); |
The first function, fl_get_nmenu_item_by_value()
,
searches through the list of all items (including items in sub-popups)
and returns the first one with the val
associated with the item
(or NULL
if none is found). The second,
fl_get_nmenu_item_by_label()
searches for a certain label
as displayed for the iten in the popup. The third,
fl_get_nmenu_item_by_text()
searches for the text the
item was created by (that might be the same as the label text in
simple cases). Please note that all functions return a structure of
type FL_POPUP_ENTRY (and not FL_POPUP_RETURN, which
gives you direct access to the entry in the popup for the item.
Using e.g. the results of the above searches a nmenu item can be deleted:
int fl_delete_nmneu_item(FL_OBJECT *obj, FL_POPUP_ENTRY *item); |
Alternatively, an item can be replaced by one or more items:
FL_POPUP_ENTRY *fl_replace_nmenu_item(FL_OBJECT *obj, FL_POPUP_ENTRY *old, const char *new_items, ...); |
where old
is the item to replace and new_items
is a
string exactly as used for fl_add_nmenu_items()
with
informations about the new item(s).
One also may insert additional items using
FL_POPUP_ENTRY *fl_insert_nmenu_items(FL_OBJECT *obj, FL_POPUP_ENTRY *after, const char *new_items, ...); |
where after
is the item after which the new items are to be
inserted (use NULL
to insert at the very start) and
new_items
is a strung just like used with
fl_add_nmenu_items()
with informations about the
additional item(s).
Finally, there's a function to remove all items from a nmenu object at once:
in fl_clear_nmenu(FL_OBJECT *obj); |
While not "active" the background of the nmenu object is drawn in the
color that can be controlled via the first color argument,
col1
, of fl_set_object_color()
. When "active"
(i.e. while the popup is shown) its background is drawn in the color
of second color argument, col2
, of the same function. The color
of the label when "inactive" is controlled via
fl_set_object_lcol()
. When in "active" state the color
use for the label can be set via the function
FL_COLOR fl_set_nmenu_hl_text_color(FL_OBJECT *obj, FL_COLOR color); |
The function returns the old color on success or FL_MAX_COLORS
on failure. Per default this color is FL_BLACK
for nmenus that
are shown as a button while being "active" while for normal nmenus
it's the same color that is used items in the popup when the mouse is
hovering over them.
The size and style of the font used for the label of the nmenu object
can be set via fl_set_object_lsize()
and
fl_set_object_lstyle()
.
The rest of the appearance of a nmenu object is given by the appearance of the popup. These can be directly set via the functions for setting the popup appearance as described in Popup Attributes. To find out which popup is associated with the nmenu object use the function
FL_POPUP *fl_get_nmenu_popup(FL_OBJECT *obj); |
and then use the popup specific functions to set the appearance. The same also holds for the appearance etc. of the items of the popup, a lot of functions exist that allow to set the attributes of entries of a popup, see section Popup Attributes.
See the demo program `menu.c'.
The browser object class is probably the most powerful that currently exists in the Forms Library. A browser is a box that contains a number of lines of text. If the text does not fit inside the box, a scrollbar is automatically added so that the user can scroll through it. A browser can be used for building up a help facility or to give messages to the user.
It is possible to create a browser from which the user can select lines. In this way the user can make its selections from a (possible) long list of choices. Both single lines and multiple lines can be selected, depending on the type of the browser.
19.3.1 Adding Browser Objects | ||
19.3.2 Browser Types | ||
19.3.3 Browser Interaction | ||
19.3.4 Other Browser Routines | ||
19.3.5 Browser Attributes | ||
19.3.6 Remarks |
To add a browser to a form use the routine
FL_OBJECT *fl_add_browser(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.
The following types of browsers exist (see below for more information about them):
FL_NORMAL_BROWSER
A browser in which no selections can be made.
FL_SELECT_BROWSER
In this case the user can make single line selections.
FL_HOLD_BROWSER
Same but the selection remains visible till the next selection.
FL_MULTI_BROWSER
Multiple selections can be made and remain visible till de-selected.
Hence, the differences only lie in how the selection process works.
The user can change the position of the slider or use keyboard cursor
keys (including <Home>
, <PageDown>
, etc.) to scroll
through the text. When he/she presses the left mouse below or above
the slider, the browser scrolls one page up or down. Any other mouse
button scrolls one line at a time (except wheel mouse buttons). When
not using an FL_NORMAL_BROWSER
, the user can also make
selections with the mouse by pointing to a line or by using the cursor
keys.
For FL_SELECT_BROWSER
's, as long as the user keeps the mouse
pressed, the current line under the mouse is highlighted. Whenever he
releases the mouse the highlighting disappears and the browser is
returned to the application program. The application program can now
figure out which line was selected using a call of
fl_get_browser()
to be described below. It returns the
number of the last selected line (with the topmoset line being line
1.)
An FL_HOLD_BROWSER
works exactly the same except that, when the
mouse is released, the selection remains highlighted.
An FL_MULTI_BROWSER
allows the user to select and de-select
multiple lines. Whenever he selects or de-selects a line the browser
is returned to the application program that can next figure out (using
fl_get_browser()
described below) which line was
selected. It returns the number of the last selected line. When the
last line was de-selected it returns the negation of the line number.
I.e., if line 10 was selected last the routine returns 10 and if line
10 was de-selected last, it returns -10. When the user presses the
mouse on a non-selected line and then moves it with the mouse button
still pressed down, he will select all lines he touches with his mouse
until he releases it. All these lines will become highlighted. When
the user starts pressing the mouse on an already selected line he
de-selects lines rather than selecting them.
Per default a browser gets only returned or the associated callback
invoked on selection of a line (and, in the case of
FL_MULTI_BROWSER
, on deselections). This behaviour can be
changed by using the function
int fl_set_object_return(FL_OBJECT *obj, int when) |
where when
can have the following values
FL_RETURN_NONE
Never return or invoke callback.
FL_RETURN_SELECTION
Return or invoke callback on selection of a line. Please note that for
FL_MULTI_BROWSER
the browser may be returned just once
for a number of lines having been selected.
FL_RETURN_DESELECTION
Return or invoke callback on deselection of a line. This only works
for FL_MULTI_BROWSER
browsers and the browser may be
returned just once for a number of lines having been deselected.
FL_RETURN_END_CHANGED
Return or invoke callback at end (mouse release) if the text in the browser has been scrolled.
FL_RETURN_CHANGED
Return or invoke callback whenever the text in the browser has been scrolled.
FL_RETURN_END
Return or invoke callback on end of an interaction for scrolling the text in the browser regardless if the text was scrolled or not.
FL_RETURN_ALWAYS
Return or invoke callback on selection, deselection or scrolling of text or end of scrolling.
The default settting for when
for a browser object is
FL_RETURN_SELECTION|FL_RETURN_DESELECTION
(unless during the
built of XForms you set the configurationb flag
--enable-bwc-bs-hack
in which case the default is
FL_RETURN_NONE
to keep backward compatibility with earlier
releases of the library).
There are a large number of routines to change the contents of a browser, select and de-select lines, etc.
To remove all lnes from a browser use
void fl_clear_browser(FL_OBJECT *obj); |
To add a line to a browser use
void fl_add_browser_line(FL_OBJECT *obj, const char *text); |
The line may contain embedded newline characters ('\n'
).
These will result in the text being split up into several lines,
separated at the newline characters.
A second way of adding a line to the browser is to use the call
void fl_addto_browser(FL_OBJECT *obj, const char *text); |
The difference to fl_add_browser_line()
is that with this
call the browser will be shifted such that the newly appended line is
visible. This is useful when e.g. using the browser to display
messages.
Sometimes it may be more convenient to add characters to a browser without starting of a new line. To this end, the following routine exists
void fl_addto_browser_chars(FL_OBJECT *obj, const char *text); |
This function appends text to the last line in the browser without
advancing the line counter. Again the text may contain embedded
newline characters ('\n'
). In that case, the text before the
first embedded newline is appended to the last line, and everything
aferwards is put onto new lines. As in the case of
fl_addto_browser()
the last added line will be visible in
the browser.
You can also insert a line in front of a given line. All lines after it will be shifted. Note that the top line is numbered 1 (not 0).
void fl_insert_browser_line(FL_OBJECT *obj, int line, const char *text); |
Please note that on insertion (as well as replacements, see below)
embedded newline characters don't result in the line being split up as
it's done in the previous functions. Instead they will rather likely
appear as strange looking characters in the text shown. The only
exception is when inserting into an empty browser or after the last
line, then this function works exactly as if you had called
fl_add_browser_line()
.
To delete a line (shifting the following lines) use:
void fl_delete_browser_line(FL_OBJECT *obj, int line); |
One can also replace a line using
void fl_replace_browser_line(FL_OBJECT *obj, int line, const char *text); |
As in the case of fl_insert_browser_line()
newline
characters embedded into the replacement text don't have any special
meaning, i.e. they don't result in replacement of more than a single
line.
Making many changes to a visible browser after another, e.g.
clearing it and then adding a number of new lines, is slow because the
browser is redrawn on each and every change. This can be avoided by
using calls of fl_freeze_form()
and
fl_unfreeze_form()
. So a piece of code that fills in a
visible browser should preferably look like the following
fl_freeze_form(browser->form); fl_clear_browser(browser); fl_add_browser_line(browser, "line 1"); fl_add_browser_line(browser, "line 2"); ... fl_unfreeze_form(brow->form); |
where browser->form
is the form that contains the browser
object named browser
.
To obtain the contents of a particular line in the browser, use
const char *fl_get_browser_line(FL_OBJECT *obj, int line); |
It returns a pointer to the text of that line, exactly as it were passed to the function that created the line.
It is possible to load an entire file into a browser using
int fl_load_browser(FL_OBJECT *obj, const char *filename); |
The routine returns 1
when file could be successfully loaded,
otherwise 0
. If the file name is an empty string (or the file
could bot be opened for reading) the browser is just cleared. This
routine is particularly useful when using the browser for a help
facility. You can create different help files and load the needed one
depending on context.
The application program can select or de-select lines in the browser. To this end the following calls exist with the obvious meaning:
void fl_select_browser_line(FL_OBJECT *obj, int line); void fl_deselect_browser_line(FL_OBJECT *obj, int line); void fl_deselect_browser(FL_OBJECT *obj); |
The last call de-selects all lines.
To check whether a line is selected, use the routine
int fl_isselected_browser_line(FL_OBJECT *obj, int line); |
int fl_get_browser_maxline(FL_OBJECT *obj); |
returns the number of lines in the browser. For example, when the
application program wants to figure out which lines in a
FL_MULTI_BROWSER
are selected code similar to the following can
be used:
int total_lines = fl_get_browser_maxline(browser); for (i = 1; i <= total_lines; i++) if (fl_isselected_browser_line(browser, i)) /* Handle the selected line */ |
Sometimes it is useful to know how many lines are visible in the browser. To this end, the following call can be used
int fl_get_browser_screenlines(FL_OBJECT *obj); |
Please note that this count only includes lines that are shown completely in the browser, lines that are partially obscured aren't counted in.
To obtain the last selection made by the user, e.g. when the browser is returned, the application program can use the routine
int fl_get_browser(FL_OBJECT *obj); |
It returns the line number of the last selection being made (0 if no
selection was made). When the last action was a de-selection (only for
FL_MULTI_BROWSER
) the negative of the de-selected line number
is returned.
The following function allows to find out the (unobscured) line that is currently shown at the top of the browser:
int fl_get_browser_topline(FL_OBJECT *obj); |
Note that the index of the top line is 1, not 0.
It is possible to register a callback function that gets called when a line is double-clicked on. To do so, the following function is available:
void fl_set_browser_dblclick_callback(FL_OBJECT *obj, void (*cb)(FL_OBJECT *, long), ` long data); |
Of course, double-click callbacks make most sense for
FL_HOLD_BROWSER
s.
The part if the text visible within the browser can be set programmatically in a number of ways. With the functions
void fl_set_browser_topline(FL_OBJECT *obj, int line); void fl_set_browser_bottomline(FL_OBJECT *obj, int line); |
the line shown at the top or the bottom can be set (note again that line numbers start with 1).
Instead of by line number also the amount the text is scrolled in horizontal and vertical direction can be set with the functions
void fl_set_browser_xoffset(FL_OBJECT *obj, FL_Coord xoff); void fl_set_browser_rel_xoffset(FL_OBJECT *obj, double xval); void fl_set_browser_yoffset(FL_OBJECT *obj, FL_Coord yoff); void fl_set_browser_rel_yoffset(FL_OBJECT *obj, double yval); |
where xoff
and yoff
indicate how many pixels to scroll
horizontally (relativ to the left margin) or vertically (relative to
the top of the text), while xval
and yval
stand for
positions relative to the total width or height of all of the text and
thus have to be numbers between 0.0
and 1.0
.
There are also a number of functions that can be used to obtain the current amount of scrolling:
FL_Coord fl_get_browser_xoffset(FL_OBJECT *obj); FL_Coord fl_get_browser_rel_xoffset(FL_OBJECT *obj); FL_Coord fl_get_browser_yoffset(FL_OBJECT *obj); FL_Coord fl_get_browser_rel_yoffset(FL_OBJECT *obj); |
Finally, there's a function that tells you the vertical position of a line in pixels:
int fl_get_browser_line_yoffset(FL_OBJECT *obj, imt line); |
The return value is just the value that would have to be passed to
fl_set_browser_yoffset()
to make the line appear at the
top of the browser. If the line does not exist it returns -1
instead.
Never use the boxtype FL_NO_BOX
for browsers.
The first color argument (col1
) to
fl_set_object_color()
controls the color of the browser's
box, the second (col2
) the color of the selection. The text
color is the same as the label color, obj->lcol
.
To set the font size used inside the browser use
void fl_set_browser_fontsize(FL_OBJECT *obj, int size); |
To set the font style used inside the browser use
void fl_set_browser_fontstyle(FL_OBJECT *obj, int style); |
See section Label Attributes and Fonts, for details on font sizes and styles.
It is possible to change the appearance of individual lines in the
browser. Whenever a line starts with the symbol @
the next
letter indicates the special characteristics associated with this line.
The following possibilities exist at the moment:
f
Fixed width font.
n
Normal (Helvetica) font.
t
Times-Roman like font.
b
Boldface modifier.
i
Italics modifier.
l
Large (new size is FL LARGE SIZE
).
m
Medium (new size is FL MEDIUM SIZE
).
s
Small (new size is FL SMALL SIZE
).
L
Large (new size = current size + 6)
M
Medium (new size = current size + 4)
S
Small (new size = current size - 2).
c
Centered.
r
Right aligned.
_
Draw underlined text.
-
An engraved separator. Text following -
is ignored.
C
The next number indicates the color index for this line.
N
Non-selectable line (in selectable browsers).
@
Regular @
character.
The modifiers (bold and itatic) work by adding FL_BOLD_STYLE
and FL_ITALIC_STYLE
to the current active font index to look up
the font in the font table (you can modify the table using
fl_set_font_name()
).
More than one option can be used by putting them next to each other.
For example, "@C1@l@f@b@cTitle"
will give you the red,
large, bold fixed font, centered word "Title"
. As you can see
the font change requests accumulate and the order is important, i.e.,
"@f@b@i"
gives you a fixed bold italic font while
"@b@i@f"
gives you a (plain) fixed font.
Depending on the font size and style lines may have different heights.
In some cases the character @
might need to be placed at the
beginning of the lines without introducing the special meaning
mentioned above. In this case you can use @@
or change the
special character to something other than @
using the
following routine
void fl_set_browser_specialkey(FL_OBJECT *obj, int key); |
To align different text fields on a line, tab characters ('\t'
)
can be embedded in the text. See fl_set_tabstop()
on how
to set tabstops.
There are two functions to turn the scrollbars on and off:
void fl_set_browser_hscrollbar(FL_OBJECT *obj, int how); void fl_set_browser_vscrollbar(FL_OBJECT *obj, int how); |
how
can be set to the following values:
FL_ON
FL_OFF
FL_AUTO
On only when needed (i.e. there are more lines/chars than could be shown at once in the browser).
FL_AUTO
is the default.
Please note that when you switch the scrollbars off the text can't be scrolled by the user anymore at all (i.e. also not using methods that don't use scrollbars, e.g. using the cursor keys).
Sometimes, it may be desirable for the application to obtain the scrollbar positions when they change (e.g., to use the scrollbars of one browser to control other browsers). There are two ways to achieve this. You can use these functions:
typedef void (*FL_BROWSER_SCROLL_CALLBACK)(FL_OBJECT *, int, void *); void fl_set_browser_hscroll_callback(FL_OBJECT *obj, FL_BROWSER_SCROLL_CALLBACK cb, void *cb_data); void fl_set_browser_vscroll_callback(FL_OBJECT *obj, FL_BROWSER_SCROLL_CALLBACK cb, void *cb_data); |
After scroll callbacks are set whenever the scrollbar changes position the callback function is called as
cb(ob, offset, cb_data); |
The first argument to the callback function cb
is the browser
object, the second argument is the new xoffset for the horizontal
scrollbar or the new top line for the vertical scrollbar. The third
argument is the callback data specified as the third argument in the
function calls to install the callback.
To uninstall a scroll callback, use a NULL
pointer as the
callback function.
As an alternative you cound request that the browser object gets
returned (or a callback invoked) when the the scrollbar positions are
changed. This can be done e.g. by passing FL_RETURN_CHANGED
(if necessary OR
'ed with flags for also returning on
selection/deselections). Within the code for dealing with the
event you could check if this is a change event by using the
function
int fl_get_object_return_state(FL_OBJECT *obj); |
and test if FL_RETURN_CHANGED
is set in the return
value (by just logically AND
'ing both) and then handle
the change.
By default, the scrollbar size is based on the relation between the size of the browser and the size of the text. To change the default, use the following routine
void fl_set_browser_scrollbarsize(FL_OBJECT *obj, int hh, int vw); |
where hh
is the horizontal scrollbar height and vw
is
the vertical scrollbar width. Use 0 to indicate the default.
The default scrollbar type is FL_THIN_SCROLLBAR
. There are two
ways you can change the default. One way is to use
fl_set_defaults()
or fl_set_scrollbar_type()
to set the application wide default, another way is to use
fl_get_object_component()
to get the object handle to the
scrollbars and change the the object type forcibly. The first method
is preferable because the user can override the setting via resources.
Although the second method of changing the scrollbar type is not
recommended, the object handle obtained can be useful in changing the
scrollbar colors etc.
Finally there is a routine that can be used to obtain the browser size in pixels for the text area
void fl_get_browser_dimension(FL_OBJECT *obj, FL_Coord *x, FL_Coord *y, FL_COORD *w, FL_COORD *h); |
where x
and y
are measured from the top-left corner of
the form (or the smallest enclosing window). To establish the
relationship between the text area (a function of scrollbar size,
border with and text margin), you can compare the browser size and
text area size.
Since version 1.0.92 there isn't a limit on the maximum length of
lines in a browser anymore. (The macro FL_BROWSER_LINELENGTH
still exists for backward compatibility but has now function anymore).
See `fbrowse1.c' for an example program using a
FL_NORMAL_BROWSER
to view files. `browserall.c' shows all
different browsers. `browserop.c' shows the insertion and
deletion of lines in a FL_HOLD_BROWSER
.
For the browser class, especially multi browsers, interaction via callbacks is strongly recommended.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Build Daemon user on November 7, 2009 using texi2html 1.82.