[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
20.1 Folder Object | ||
20.2 FormBrowser Object |
A tabbed folder is a special container class that is capable of holding multiple groups of objects (folders) to maximize the utilization of the screen real estate. Each folder has its own tab the user can click on to call up a specific folder from which option can be selected.
20.1.1 Adding Folder Objects | ||
20.1.2 Folder Types | ||
20.1.3 Folder Interaction | ||
20.1.4 Other Folder Routines | ||
20.1.5 Remarks |
To add a tabbed folder to a form use the routine
FL_OBJECT *fl_add_tabfolder(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label); |
The geometry indicated by x
, y
, w
, and h
is the total area of the tabbed folders, including the area used for
the tab riders.
The following types are available:
The folders displayed by the tabbed folder class are simply regular
forms (of type FL_FORM
), which in turn contain objects. Each
folder is associated with a name (shown on the tab rider). The folder
interacts with the user just like any other form. Different from other
top-level forms is that only one folder is active at any time. The
user selects different folders by clicking on the tab rider associated
with a folder.
To set up when the application is notified about events of the tabfolder or the tabfolders callback is invoked (if installed) use
void fl_set_object_return(FL_OBJECT *obj, unsigned int when); |
where the when
argument can be one of
FL_RETURN_NONE
Never report or invoke callback even if the selected folder has been changed.
FL_RETURN_CHANGED
FL_RETURN_END_CHANGED
Result in a notification when a folder other that the currently active one has been selected (this is the default).
FL_RETURN_END
FL_RETURN_ALWAYS
Notify when either a new or the already active folder has been selected.
In the releases before version 1.0.92 of the library only a callback
for the folder was executed (if one was installed) on change of the
selected folder bur not via e.g., fl_do_forms()
etc.
This has changed with version 1.0.92. To get the old behaviour you
have to build XForms with the --enable-bwc-bs-hack
being set.
To find out which folder is currently active the following routines the tab riders are available
FL_FORM *fl_get_active_folder(FL_OBJECT *obj); int fl_get_active_folder_number(FL_OBJECT *obj); const char *fl_get_active_folder_name(FL_OBJECT *obj); |
All three functions essentially perform the same task, i.e., return a handle of the active folder, but the kind of handle returned is different. The first function returns the form associated with the folder, the second function the folder sequence number starting from 1 on the left, and the third the folder name. Depending on the application setup, one routine might be more convenient than the other two.
To find out what the previous active folder was (which may be of similar interest as the currently active one) the following functions can be used:
FL_FORM *fl_get_folder(FL_OBJECT *obj) int fl_get_folder_number(FL_OBJECT *obj) const char *fl_get_folder_name(FL_OBJECT *obj) |
Again, depending on the application, one might prefer one routine to the other two.
To populate a tabbed folder, use the following routine
FL_OBJECT *fl_addto_tabfolder(FL_OBJECT *obj, const char *tab_name, FL_FORM *folder) |
where tab_name
is a string (with possible embedded newlines in
it) indicating the text of the tab rider and folder
is a
regular form created between calls of fl_bgn_form()
and
fl_end_form()
. Only the pointer to the form is required.
This means that the application program should not destroy a form that
has been added to a tabbed folder. The function returns the folder tab
object, which is an object of class FL_BUTTON
. The initial
object color, label color, and other attributes (gravities, for
example) of the tab button are inherited from the tabbed folder object
obj
and the location and size of the tab are determined
automatically. You can change the attributes of the returned object
just like any other objects, but not all possibilities result in a
pleasing appearance. Note that although there is no specific
requirement of what the backface of the folder/form should be, a
boxtype other than FL_FLAT_BOX
or FL_NO_BOX
may not look
nice. If the backface of the form is of FL_FLAT_BOX
the
associated tab will take on the color of the backface when activated.
One thing to note is that each tab must have its own form, i.e., you should not associate the same form with two different tabs. However, you can create copies of a form and use these copies.
To access the individual forms on the tabfolder, e.g., in order to modify something on it, use the following routines
FL_FORM *fl_get_tabfolder_folder_bynumber(FL_OBJECT *obj, int num); FL_FORM *fl_get_tabfolder_folder_byname(FL_OBJECT *obj, const char *name); FL_FORM *fl_get_tabfolder_folder_byname_f(FL_OBJECT *obj, const char *fnt, ...); |
The functions take either the sequence number (the first tab on the
left has a sequence number 1, the second 2 etc) or the tab name, which
can either be passed directly as a string or via a format string like
for printf()
etc. and the corresponding (unspecified)
arguments. The functions return the form associated with the number or
the name. If the requested number or name is invalid, NULL
is
returned.
If there are more tabs than that can be shown, the right-most tab will be shown as "broken". Clicking on the "broken" tab scrolls the tab to the right one per each click. To scroll to the left (if there are tabs scrolled-off screen from the left), clicking on the first tab scrolls right. How many tabs are "hidden" on the left can be determined and also set using the functions
int fl_get_tabfolder_offset(FL_OBJECT *ojb); int gl_set_tabfolder_offset(FL_OBJECT *obj, int offset); |
where offset
is the number of tabs hidden on the left.
Although a regular form (top-level) and a form used as a folder behave
almost identically, there are some differences. In a top-level form,
objects that do not have callbacks bound to them will be returned,
when their states change, to the application program via
fl_do_forms()
or fl_check_forms()
. When a
form is used as a folder, objects that do not have a callback are
ignored even when their states changes. The reason for this behavior
is that presumably the application does not care while the changes take
place and they only become relevant when the the folder is switched
off and at that time the application program can decide what to do
with these objects' states (apply or ignore for example). If immediate
reaction is desired, just use callback functions for these objects.
To obtain the number of folders in the tabfolder, the following routine can be used
int fl_get_tabfolder_numfolders(FL_OBJECT *obj); |
To remove a folder, the following routine is available
void fl_delete_folder(FL_OBJECT *obj, FL_FORM *folder); void fl_delete_folder_bynumber(FL_OBJECT *obj, int num); void fl_delete_folder_byname(FL_OBJECT *obj, const char *name); void fl_delete_folder_byname_f(FL_OBJECT *obj, const char *fmt, ...); |
(the last two function differ in the way the tab names gets passed,
the first is to be called with a simple string while the second
expects a format string as used for printf()
etc. and the
appropriate number of arguments, from which the tab name gets
constructed). wNote that after deletion, the number of folders in the
tabfolder as well as the sequence numbers are updated. This means if
you want to delete all folders after the second folder, you can do
that by deleting the third folder repeatedly.
The application program can select which folder to show by using the following routines
void fl_set_folder(FL_OBJECT *obj, FL_FORM *folder); void fl_set_folder_bynumber(FL_OBJECT *obj, int num); void fl_set_folder_byname(FL_OBJECT *obj, const char *name); void fl_set_folder_byname_f(FL_OBJECT *obj, const char *fmt, ...); |
(The latter two functions only differ in the way the tab name gets
passed top them, the first accepts a simple string while the second
expects a format string as used for printf()
etc. and the
appropriate number of (unspecified arguments, from which the tab name
is constructed.)
Since the area occupied by the tabbed folder contains the space for tabs, the following routine is available to obtain the actual folder size
void fl_get_folder_area(FL_OBJECT *obj, FL_Coord *x, FL_Coord *y, FL_OBJECT *w, FL_OBJECT *h) |
where x
and y
are relative to the (top-level) form the
tabbed folder belongs to. The size information may be useful for
resizing the individual forms that has to go into the tabbed folder.
Note that the folder area may not be constant depending on the current
tabs (For example, adding a multi-line tab will reduce the area for
the folders).
Since tab size can vary depending on monitor/font resolutions, it is in general not possible to design the forms (folders) so they fit exactly into the folder area. To dynamically adjust the sizes of the folders so they fit, the following routine is available
int fl_set_tabfolder_autofit(FL_OBJECT *obj, int how); |
where how
can be one of the following constants:
FL_NO
FL_FIT
FL_ENLARGE_ONLY
Scale the form only if it is smaller than the folder area.
The function returns the old setting.
By default, the tab for each folder is drawn with a corner of 3 pixels so it appears to be a trapezoid rather than a square. To change the appearance of the tabs, you can adjust the corner pixels using the following routine
int fl_set_default_tabfolder_corner(int n); |
where n
is the number of corner pixels. A value of 1 or 0 makes
the tabs appear to be squarish. The function returns the old value.
A tabbed folder is a composite object consisting of a canvas and several foldertab buttons. Each individual form is shown inside the canvas. Folder switching is accomplished by some internal callbacks bound to the foldertab button. Should the application change the callback functions of the foldertab buttons, these new callback functions must take the responsibility of switching the active folder.
Some visual effects like colors and label font of the tab rider
buttons can be set all at once by calling the corresponding functions
(i.e., fl_set_object_color()
,
fl_set_object_lstyle()
etc.) with the tabbed folder
object as the first argument. Individual tab rider buttons can also be
modified by calling those function with the corresponding return value
of fl_addto_tabfolder()
as the first argument.
fl_free_object(tabfolder)
does not free the individual forms
that make up the tabfolder.
See the demo program `folder.c' for an example use of tabbed folder class.
A nested tabfolder might not work correctly at the moment.
A form browser is another container class that is capable of holding multiple forms, the height of which in aggregate may exceed the screen height. The form browser also works obviously for a single form that has a height that is larger than the screen height.
This object class was developed with contributed code from Steve Lamont of UCSD and the National Center for Microscopy and Imaging Research (spl@ucsd.edu).
20.2.1 Adding FormBrowser Objects | ||
20.2.2 FormBrowser Types | ||
20.2.3 FormBrowser Interaction | ||
20.2.4 Other FormBrowser Routines | ||
20.2.5 Remarks |
Adding an object To add a formbrowser object to a form use the routine
FL_OBJECT *fl_add_formbrowser(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label); |
The geometry indicated by x
, y
, w
and h
is
the total area of the formbrowser, including scrollbars.
There's only a single type of formbrowser available, the
FL_NORMAL_FORMBROWSER
.
Once a formbrowser is populated with forms, you can scroll the forms
with the scrollbars and interact with any of the forms. All objects on
the forms act, for the most part, the same way as they would if they
were on separate forms, i.e., if there are callback functions bound to
the objects, they will be invoked by the main loop when the states of
the objects change. However, objects on the form that do not have
callbacks bound to them will not be returned by
fl_do_forms()
or fl_check_forms()
.
Your application can be notified about changes of the scrollbars of the formbrowser. To set up under which conditions the application is notified or the formbrowsers callback is invoked (if installed) use
void fl_set_object_return(FL_OBJECT *obj, unsigned int when); |
where the when
argument can be one of
FL_RETURN_NONE
Never report or invoke callback (this is the default for the formbrowser object)
FL_RETURN_CHANGED
Result in a notification whenever the position of one of the scrollbars has changed.
FL_RETURN_END_CHANGED
Notification is sent if the position of a scrollbar has changed and the mouse button has been released.
FL_RETURN_END
Notification on release of the mouse button.
FL_RETURN_ALWAYS
Notify if the position of a scrollbar has changed or the mouse button has been released.
To populate a formbrowser, use the following routine
int fl_addto_formbrowser(FL_OBJECT *obj, FL_FORM *form); |
where form
is a pointer to a regular form created between calls
of fl_bgn_form()
and fl_end_form()
. Only the
form pointer is passed to the function, which means that the form
should be valid for the duration of the formbrowser and the
application program should not destroy a form that is added to a
formbrowser before deleting the form from the formbrowser first. The
function returns the total number of forms in the formbrowser. Note
that although there is no specific requirement on what the backface of
the form should be, not all boxtypes look nice.
The form so added is appended to the list of forms that are already in the formbrowser. You can also use the following routine to obtain the total number of forms in a formbrowser
int fl_get_formbrowser_numforms(FL_OBJECT *formbrowser); |
Although a regular form (top-level) and a form used inside a
formbrowser behave almost identically, there are some differences. In
a top-level form, objects that do not have callbacks bound to them
will be returned to the application program when their states change
via fl_do_forms()
or fl_check_forms()
. When
a form is used as member of a formbrowser those objects that do not
have callbacks are ignored even when their states change.
To remove a form from the formbrowser, the following routine is available
int fl_delete_formbrowser(FL_OBJECT *obj, FL_FORM *form); FL_FORM* fl_delete_formbrowser_bynumber(FL_OBJECT *obj, int num); |
In the first function you specify the form to be removed from the formbrowser by a pointer to the form. If the form was removed successfully the function returns the remaining number of forms in the formbrowser, otherwise -1.
In the second function, you indicate the form to be removed with a
sequence number, an integer between 1 and the number of forms in the
browser. The sequence number is basically the order in which forms
were added to the formbrowser. After a form is removed, the sequence
numbers are re-adjusted so they are always consecutive. The function
returns NULL
if num
was invalid, otherwise it returns
address of the form that was removed.
To replace a form in formbrowser, the following routine is available
FL_FORM *fl_replace_formbrowser(FL_OBJECT *obj, int num, FL_FORM *form); |
where num
is the sequence number of the form that is to be
replaced by form
. For example, to replace the first form in the
browser with a different form, you should use 1 for num
. The
function returns the form that has been replaced on success, otherwise
NULL
is returned.
You can also insert a form into a formbrowser at arbitrary locations using the following routine
int fl_insert_formbrowser(FL_OBJECT *obj, int num, FL_FORM *form); |
where num
is the sequence number before which the new form form
is to be inserted into the formbrowser. If successful the function
returns the number of forms in the formbrowser, otherwise -1.
To find out the sequence number of a particular form, the following routine is available
int fl_find_formbrowser_form_number(FL_OBJECT *obj, FL_FORM *form); |
The function returns a number between 1 and the number of forms in the formbrowser on success, otherwise 0.
To obtain the form handle from the sequence number, use the following routine
int fl_get_formbrowser_form(FL_OBJECT *obj, int num); |
By default, if the size of the forms exceeds the size of the formbrowser, scrollbars are added automatically. You can use the following routines to control the scrollbars
void fl_set_formbrowser_hscrollbar(FL_OBJECT *obj, int how); void fl_set_formbrowser_vscrollbar(FL_OBJECT *obj, int how); |
where how
can be one of the following
The vertical scrollbar by default scrolls a fixed number of pixels. To change it so each action of the scrollbar scrolls to the next forms, the following routine is available
void fl_set_formbrowser_scroll(FL_OBJECT *obj, int how) |
where how
can be one of the following
To obtain the form that is currently the first form in the formbrowser visible to the user, the following can be used
FL_FORM *fl_get_formbrowser_topform(FL_OBJECT *obj); |
You can also set which form to show by setting the top form using the following routine
int fl_set_formbrowser_topform(FL_OBJECT *obj, FL_FORM *form); FL_FORM* fl_set_formbrowser_topform_bynumber(FL_OBJECT *obj, int num); |
The first function returns the sequence number of the form and
the second function returns the form with sequence number num
.
Since the area occupied by the formbrowser contains the space for the scrollbars, the following routine is available to obtain the actual size of the forms area
void fl_get_formbrowser_area(FL_OBJECT *obj, int *x, int *y, int *w, int *h); |
where x
and y
are relative to the (top-level) form the
formbrowser belongs to.
To programatically scroll within a formbrowser in horizontal and vertical direction, the following routines are available
int fl_set_formbrowser_xoffset(FL_OBJECT *obj, int offset); int fl_set_formbrowser_yoffset(FL_OBJECT *obj, int offset); |
where offset
is a positive number, measuring in pixels the
offset from the the natural position from the left and the top,
respectively. In other words, 0 indicates the natural position of the
content within the formbrowser. An x-offset of 10 means the content is
scrolled 10 pixels to the left. Similarly an y-offset of 10 means
the content is scrolled by 10 pixels upwards.
To obtain the current offsets, use the following routines
int fl_get_formbrowser_xoffset(FL_OBJECT *obj); int fl_get_formbrowser_yoffset(FL_OBJECT *obj); |
A call of fl_free_object(formbrowser)
does not free the
individual forms, it only frees the formbrowser object itself.
See the demo program `formbrowser.c' for an example use of formbrowser class. A nested formbrowser might not work correctly at the moment.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Build Daemon on October 16, 2020 using texi2html 1.82.