1@node Part III Choice Objects
2@chapter Choice Objects
3
4@ifnottex
5
6@menu
7* Select Object:   Select Object
8* Nmenu Object:    Nmenu Object
9* Browser Object:  Browser Object
10@end menu
11
12@end ifnottex
13
14
15@node Select Object
16@section Select Object
17
18A select object is a rather simple object that allows the user to
19pick alternatives from a linear list that pops up when he clicks on
20the object. It remembers the last selected item, which is also
21shown on top of the select object.
22
23The select object internally uses a popup (@pxref{Part III Popups})
24and thus it can be helpful to understand at lest some aspects of how
25popups work to fully grasp the functionality of select objects.
26
27
28@ifnottex
29
30@menu
31* Adding Select Objects:   Adding Select Objects
32* Select Interaction:      Select Interaction
33* Other Select Routines:   Other Select Routines
34* Select Attributes:       Select Attributes
35* Remarks:                 Select Remarks
36@end menu
37
38@end ifnottex
39
40
41@node Adding Select Objects
42@subsection Adding Select Objects
43
44To add a select object to a form use
45@findex fl_add_select()
46@anchor{fl_add_select()}
47@example
48FL_OBJECT *fl_add_select(int type, FL_Coord x, FL_Coord y,
49                         FL_Coord w, FL_Coord h, const char *label)
50@end example
51@noindent
52There are currently three types which just differ by the way they
53look:
54@table @code
55@tindex FL_NORMAL_SELECT
56@anchor{FL_NORMAL_SELECT}
57@item FL_NORMAL_SELECT
58Per default this type is drawn as a rounded, flat box (but you can
59change that by setting a different boxtype for the object) with the
60text of the currently selected item in its center.
61
62@tindex FL_MENU_SELECT
63@anchor{FL_MENU_SELECT}
64@item FL_MENU_SELECT
65This select object looks like a button with a little extra box at its
66right side (just like a @code{FL_MENU_BUTTON}) and the text of the
67currently selected item is drawn on the button-like object.
68
69@tindex FL_DROPLIST_SELECT
70@anchor{FL_DROPLIST_SELECT}
71@item FL_DROPLIST_SELECT
72This type looks like a button with the text of the currently selected
73item on top of it and a second square button directly beside it with
74an downward pointing arrow on it.
75@end table
76
77Per default @code{label} is drawn outside and to the left of the
78object.
79
80Once a new select object has been created items have to be added to
81it. For this the following function exists:
82@findex fl_add_select_items()
83@anchor{fl_add_select_items()}
84@example
85FL_POPUP_ENTRY *fl_add_select_items(FL_OBJECT *obj,
86                                    const char items,...);
87@end example
88@noindent
89@code{items} is a string with the items to add, separated by the
90@code{|} character. In the simplest case you would just use something
91like @code{"Item 1|Item 2|Item 3"} to add three items to the list. If
92there weren't any items before the first item will be automatically
93shown as the selected one.
94
95As also described in the documentation for the similar function
96@code{@ref{fl_popup_add_entries()}} (@pxref{Adding Popups}) the text
97for an item may contain "special sequences" that start with the
98character @code{%} and the may require an additional argument passed
99to the function after the @code{items} argument:
100@table @code
101@item %x
102Set a value of type @code{long int} that's passed to all callback
103routines for the item. The value must be given in the arguments
104following the @code{items} string.
105
106@item %u
107Set a @code{user_void} pointer that's passed to all callbacks of the
108item. The pointer must be specified in the arguments following the
109@code{items} string.
110
111@item %f
112Set a callback function that gets called when the item is selected.
113The function is of type
114@example
115int callback(FL_POPUP_RETURN *r);
116@end example
117@noindent
118Information about the item etc.@: gets passed to the callback function
119via the @code{@ref{FL_POPUP_RETURN}} structure and the return value of
120the function can be used to keep the selection from becoming reported
121back to the user made by returning a value of @code{FL_IGNORE} (-1).
122The function's address must be given in the arguments following the
123@code{items} string.
124
125@item %E
126Set a callback routine that gets called each time the mouse enters the
127item (as long as the item isn't disabled or hidden). The type of the
128function is the same as that of the callback function for the
129selection of the item but it's return value is never used. The
130functions address must be given in the arguments following the
131@code{items} string.
132
133@item %L
134Set a callback routine that gets called each time the mouse leaves the
135item. The type of the function is the same that as of the callback
136function for the selection of the item but it's return value is never
137used. The functions address must be given in the arguments following
138the @code{items} string.
139
140@item %d
141Marks the item as disabled, i.e., it can't be selected and its text
142is per default drawn in a different color
143
144@item %h
145Marks the item as hidden, i.e., it is not shown while in this state.
146
147@item %S
148For items with shortcut keys it's quite common to have them shown on
149the right hand side. Using @code{"%S"} you can split the items text
150into two parts, the first one (before @code{"%S"}) being drawn flushed
151left and the second part flushed right. Note that using this special
152sequence doesn't automatically sets a shortcut key, this still has to
153be done using @code{"%s"}.
154
155@item %s
156Sets one or more shortcut keys for an item. Requires a string with the
157shortcuts in the arguments following the @code{items} string.
158@xref{Shortcuts}, for details on how to define shortcuts. Please note
159that the character in the label identical to the shortcut character is
160only shown as underlined if @code{"%S"} isn't used.
161
162@item %%
163Use this to get a @code{'%'} within the text of an item.
164@end table
165@noindent
166If you compare this list of "special sequences" with those listed for
167the @code{@ref{fl_popup_add_entries()}} function you will find that
168aome are missing. This is because a select object is a simple linear
169list of items that uses only parts of the popups functionalities.
170
171Another way to set up the popup of a select object is to use the
172function
173@findex fl_set_select_items()
174@anchor{fl_set_select_items()}
175@example
176long fl_set_select_items(FL_OBJECT *obj, FL_POPUP_ITEM *item);
177@end example
178@noindent
179Here @code{item} is an array of structures of type
180@code{@ref{FL_POPUP_ITEM}} with the @code{text} member of the very
181last element of the array being set to @code{NULL}, indicating the end
182of the array.
183
184The @code{text} member is the text of the item. It may only contain
185one "special sequence", @code{"%S"} to indicate that the string is to
186be split at that position into the part of the item label to be drawn
187to the left and on the right side (also prepending the string with
188@code{'_'} or @code{'/'} has no effect). @code{callback} is a callback
189function to be invoked on selection of the item. @code{shortcut} is a
190string for setting keybord shortcuts for the item. @code{type} has no
191function at all here (there can be only items of type
192@code{@ref{FL_POPUP_NORMAL}} in a select objects popup) and
193@code{state} can be set to @code{@ref{FL_POPUP_DISABLED}} and/or
194@code{@ref{FL_POPUP_HIDDEN}}.
195
196Please note: when the select object already had items before the call
197of @code{@ref{fl_set_select_items()}} then they are removed before the
198new ones are set. The values assigned to the items start at 0.
199
200A third way to "populate" a select object is to create a popup
201directly and then associate it with the select object using
202@findex fl_set_select_popup()
203@anchor{fl_set_select_popup()}
204@example
205int fl_set_select_popup(FL_OBJECT *obj, FL_POPUP *popup);
206@end example
207@noindent
208If the select object already had a popup before this will be deleted
209and replaced by the new popup passed as the second argument. Please
210note that the popup the argument @code{popup} points to may not
211contain any entries other than those of type
212@code{@ref{FL_POPUP_NORMAL}} (and, of course, the popup can't be a
213sub-popup of another popup).
214
215
216@node Select Interaction
217@subsection Select Interaction
218
219The simplest interaction with a select object consists of clicking
220onto the object and then selecting an item in the popup that gets
221shown directly beside the mouse position.
222
223If you click with the left or right mouse button onto the select
224object previous or next item, respectively, will be selected. If
225youl keep the left or mouse button pressed down for a longer time
226slowly all alternatives are selected, one after each other.
227
228You finally can also use the scroll wheel of your mouse to select
229the next or previous item (scrolling down selects the next, scrolling
230up the previous item).
231
232On every selection of an item (also if the already selected item is
233re-selected) a callback that may have been associated with the item is
234executed. The callback receives as its argument a pointer to a
235structure of type @code{@ref{FL_POPUP_RETURN}}.
236
237Its @code{val} member is a integer value associated with the entry. It
238can be set explicitely on creation of the item using the @code{"%x"}
239"special sequence". If not given then first item gets the value 0, the
240next 1 etc. @code{user_data} is a pointer to some user data, which can
241be set on creation of the item using @code{"%u"}. @code{text} is the
242string used in creating the item, including all "special sequences",
243while @code{label} is the string shown in the popup for the item. If
244there was a special sequence of @code{"%S"} in the string that was
245used to create the item @code{accel} is the text that appears
246right-flushed in the popup for the item. @code{entry} is a pointer to
247the popup entry that represents the item in the select object and,
248finally, @code{popup} is the popup associated with the select object.
249
250Normally, when a new item is selected this is reported back to the
251caller either by calling the select objects callback (if one exists)
252or by returning the object as the result of a call of e.g.,
253@code{@ref{fl_do_forms()}}. But if the callback for the item itself
254returns @code{FL_IGNORE} then the latter doesn't happen. This can be
255useful for cases where all work for a change of the selection can
256already be done within the items callback and the "main loop"
257shouldn't get involved anymore.
258
259As for all other normal objects the condition under which a
260@code{FL_SELECT} object gets returned to the application (or an
261associate callback is called) can be influenced by calling the
262function
263@example
264int fl_set_object_return(FL_OBJECT *obj, unsigned int when)
265@end example
266where @code{when} can have the following values
267@table @code
268@item @ref{FL_RETURN_NONE}
269Never return or invoke a callback.
270
271@item @ref{FL_RETURN_END_CHANGED}
272Return or invoke callback if end of interaction and selection of an
273item coincide.
274
275@item @ref{FL_RETURN_CHANGED}
276Return or invoke callback whenever an item is selected (this is the
277default).
278
279@item @ref{FL_RETURN_END}
280Return or invoke callback on end of an interaction.
281
282@item @ref{FL_RETURN_ALWAYS}
283Return (or invoke callback) whenever the interaction ends and/or
284an item is selected.
285@end table
286
287
288Per default the popup of a select objects remains shown when the user
289releases the mouse somewhere outside the popup window (or on its title
290area). The alternative is to close the popup immediately when the user
291releases the mouse, independent of where it is. Using the function
292@findex fl_set_select_policy()
293@anchor{fl_set_select_policy()}
294@example
295int fl_set_select_policy(FL_OBJECT *obj, int policy);
296@end example
297@noindent
298the program can switch between these two modes of operation,
299where @code{policy} can be on of two values:
300@table @code
301@tindex FL_POPUP_NORMAL_SELECT
302@item FL_POPUP_NORMAL_SELECT
303Keeps the popup opened when the mouse isn't released on one of the
304selectable items.
305
306@tindex FL_POPUP_DRAG_SELECT
307@item FL_POPUP_DRAG_SELECT
308Close the popup immediately when the mouse button is released.
309@end table
310@noindent
311The function returns on success the previous setting of the "policy"
312and -1 on error.
313
314
315@node Other Select Routines
316@subsection Other Select Routines
317
318To find out which item is currently selected use
319@findex fl_get_select_item()
320@anchor{fl_get_select_item()}
321@example
322FL_POPUP_RETURN *fl_get_select_item(FL_OBJECT *obj);
323@end example
324@noindent
325It returns a pointer to a structure of type
326@code{@ref{FL_POPUP_RETURN}} as already described above, containing
327all needed information about the selected item.
328
329For some actions, e.g., deletion of an item etc., it is necessary to
330know the popup entry that represents it. Therefore it's possible to
331search the list of items according to several criteria:
332@findex fl_get_select_item_by_value()
333@anchor{fl_get_select_item_by_value()}
334@findex fl_get_select_item_by_label()
335@anchor{fl_get_select_item_by_label()}
336@findex fl_get_select_item_by_label_f()
337@anchor{fl_get_select_item_by_label_f()}
338@findex fl_get_select_item_by_text()
339@anchor{fl_get_select_item_by_text()}
340@findex fl_get_select_item_by_text_f()
341@anchor{fl_get_select_item_by_text_f()}
342@example
343FL_POPUP_ENTRY *fl_get_select_item_by_value(FL_OBJECT *obj, long val);
344FL_POPUP_ENTRY *fl_get_select_item_by_label(FL_OBJECT *obj,
345                                            const char *label);
346FL_POPUP_ENTRY *fl_get_select_item_by_label_f(FL_OBJECT *obj,
347                                              const char *fmt, ...);
348FL_POPUP_ENTRY *fl_get_select_item_by_text(FL_OBJECT *obj,
349                                           const char *text);
350FL_POPUP_ENTRY *fl_get_select_item_by_text_f(FL_OBJECT *obj,
351                                             const char *fmt, ...);
352@end example
353The first function, @code{@ref{fl_get_select_item_by_value()}},
354searches through the list of items and returns the first one with the
355@code{val} associated with the item (or @code{NULL} if none is found).
356The second and third, @code{@ref{fl_get_select_item_by_label()}} and
357@code{@ref{fl_get_select_item_by_label_f()}} searches for a certain
358label as displayed for the item in the popup. The last two,
359@code{@ref{fl_get_select_item_by_text()}} and
360@code{@ref{fl_get_select_item_by_text_f()}} searches for the text the
361item was created by (that might be the same as the label text in
362simple cases). The difference between the second and third and the
363forth and the last is the way the text is passed to the functions,
364it's either a simple string or the result of the expansion of a format
365string as used for @code{printf()} etc. using the following
366unspecified arguments.
367
368Please note that all these functions return a structure of type
369@code{@ref{FL_POPUP_ENTRY}} (and not @code{@ref{FL_POPUP_RETURN}},
370which gives you direct access to the entry in the popup for the item.
371
372Using e.g., the result of one of the functions above you can also set
373the currently selected item via your program using
374@findex fl_set_select_item()
375@anchor{fl_set_select_item()}
376@example
377FL_POPUP_RETURN *fl_set_select_item(FL_OBJECT *obj,
378                                    FL_POPUP_ENTRY *entry);
379@end example
380
381Or you could use the result to delete an item:
382@findex fl_delete_select_item()
383@anchor{fl_delete_select_item()}
384@example
385int fl_delete_select_item(FL_OBJECT *obj, FL_POPUP_ENTRY *entry);
386@end example
387@noindent
388Please note that the values associated with items won't change due to
389removing an item.
390
391Alternatively, you can replace an item by one or more new ones.
392To do that use
393@findex fl_replace_select_item()
394@anchor{fl_replace_select_item()}
395@example
396FL_POPUP_ENTRY *fl_replace_select_item(FL_OBJECT *obj,
397                                       FL_POPUP_ENTRY *old,
398                                       const char *new_items, ...);
399@end example
400@noindent
401@code{old} designates the item to be removed and @code{new_items} is a
402string exactly like it would be used in
403@code{@ref{fl_add_select_items()}} for the @code{items} argument, that
404defines the item(s) to replace the existing item. Please note that,
405unless values to be associated with the items (see the @code{val}
406member of the @code{@ref{FL_POPUP_RETURN}} structure) there's a twist
407here. When items get created they per default receive increasing
408values, starting at 0. This also holds for items that get created in
409the process of replacement. The result is that the ordering of those
410values in that case wont represent the order in which they appear in
411the select objects popup.
412
413Another sometimes useful function allows insertion of new items somewhere
414in the middle of a list of already existing items:
415@findex fl_insert_select_items()
416@anchor{fl_insert_select_items()}
417@example
418FL_POPUP_ENTRY *fl_insert_select_items(FL_OBJECT *obj,
419                                       FL_POPUP_ENTRY *after,
420                                       const char *new_items, ...);
421@end example
422@noindent
423@code{after} is the entry after which the new item(s) are to be
424inserted (if it's @code{NULL} the new items are inserted at the very
425start). The rest of the arguments are the same as for
426@code{@ref{fl_replace_select_item()}} and the same caveats about the
427values associated automatically with the new items holds.
428
429It's possible to remove all items from a select object by calling
430@findex fl_clear_select()
431@anchor{fl_clear_select()}
432@example
433int fl_clear_select(FL_OBJECT *obj);
434@end example
435@noindent
436Afterwards you have to call again e.g.,
437@code{@ref{fl_add_select_items()}} to set new entries. Note that if
438you used @code{@ref{fl_set_select_popup()}} to set a popup for the
439select object then that popup gets deleted automatically on calling
440@code{@ref{fl_clear_select()}}! The values automatically associated
441with items when calling @code{@ref{fl_add_select_items()}} will start
442at 0 again.
443
444
445@node Select Attributes
446@subsection Select Attributes
447
448The two color arguments, @code{clo1} and @code{col2}, of the function
449@code{@ref{fl_set_object_color()}} set the background color of the
450object normally and when the mouse is hovering over it, respectively.
451
452With the functions
453@findex fl_set_select_text_color()
454@anchor{fl_set_select_text_color()}
455@findex fl_get_select_text_color()
456@anchor{fl_get_select_text_color()}
457@example
458FL_COLOR fl_set_selection_text_color(FL_OBJECT *obj, FL_COLOR color);
459FL_COLOR fl_get_selection_text_color(FL_OBJECT *obj);
460@end example
461@noindent
462the color of the text of the currently selected item on top of the
463object can be set or queried.
464
465To control (or determine) the alignment of the text with the currently
466selected item on top of the select object use
467@findex fl_set_select_text_align()
468@anchor{fl_set_select_text_align()}
469@findex fl_get_select_text_align()
470@anchor{fl_get_select_text_align()}
471@example
472int fl_set_select_text_align(FLOBJECT *obj, int align);
473int fl_get_select_text_align(FLOBJECT *obj);
474@end example
475@noindent
476Please note that the @code{@ref{FL_ALIGN_INSIDE}} flag should be set
477with @code{align} since the text always will be drawn within the
478boundaries of the object. On success the function return the old
479setting for the alignment or -1 on error.
480
481Finally, the font style and size of the text can be set or obtained
482using
483@findex fl_set_select_text_font()
484@anchor{fl_set_select_text_font()}
485@findex fl_get_select_text_font()
486@anchor{fl_get_select_text_font()}
487@example
488int fl_set_select_text_font(FL_OBJECT *obj, int style, int size);
489int fl_get_select_text_font(FL_OBJECT *obj, int *style, int *size);
490@end example
491@noindent
492
493The rest of the appearance of a select object concerns the popup that
494is used. To avoid bloating the API unnecessarily no functions for
495select objects were added that would just call popup functions. The
496popup belonging to a select object can be easily found from either a
497@code{@ref{FL_POPUP_ENTRY}} structure as returned by the functions for
498searching for items or the @code{@ref{FL_POPUP_RETURN}} structure
499passed to all callbacks and also returned by
500@code{@ref{fl_get_select_item()}}. Both structures have a member
501called @code{popup} that is a pointer to the popup associated with the
502select object. For popup functions operation on indiviual items just
503use the pointer to the @code{@ref{FL_POPUP_ENTRY}} structure itself or
504the @code{entry} member of the @code{@ref{FL_POPUP_RETURN}} structure.
505
506There's also a convenience function for finding out the popup used
507for a select object:
508@findex fl_get_select_popup()
509@anchor{fl_get_select_popup()}
510@example
511FL_POPUP *fl_get_select_popup(FL_OBJECT *obj);
512@end example
513@noindent
514During the lifetime of a select object the popup never changes as long
515as @code{@ref{fl_set_select_popup()}} isn't called.
516
517Per default the popup of a select object does not have a title drawn
518on top of it. To change that use @code{@ref{fl_popup_set_title()}}.
519
520To change the various colors and fonts used when drawing the popup use
521the functions @code{@ref{fl_popup_set_color()}} and
522@code{@ref{fl_popup_entry_set_font()}} (and
523@code{@ref{fl_popup_set_title_font()}}).
524
525To change the border width or minimum width of the popup use
526@code{@ref{fl_popup_set_bw()}} and
527@code{@ref{fl_popup_set_min_width()}}.
528
529To disable or hide (or do the reverse) an item use the functions
530@code{@ref{fl_popup_entry_set_state()}} and
531@code{@ref{fl_popup_entry_get_state()}}.
532
533The keyboard shortcut for an entry can be set via
534@code{@ref{fl_popup_entry_set_shortcut()}}.
535
536The callback functions (selection, enter and leave callback) for
537individual items can be set via
538@code{@ref{fl_popup_entry_set_callback()}},
539@code{@ref{fl_popup_entry_set_enter_callback()}} and
540@code{@ref{fl_popup_entry_set_leave_callback()}}, a callback for the
541whole popup with @code{@ref{fl_popup_set_callback()}}.
542
543Finally, to assign a different (long) value to an item or set a
544pointer to user data use @code{@ref{fl_popup_entry_set_value()}}
545and @code{@ref{fl_popup_entry_set_user_data()}}.
546
547
548@node Select Remarks
549@subsection Remarks
550
551See the demo program @file{select.c} for an example of the use of
552select objects.
553
554
555@node Nmenu Object
556@section Nmenu Object
557
558Another object type that heavily depends on popups is the "nmenu"
559object type. It is meant to be used for menus and the "n" in front of
560the name stands for "new" since this is a re-implementation of the
561old menu object type (which is now deprecated since it is based on
562@ref{XPopup}).
563
564
565@ifnottex
566
567@menu
568* Adding Nmenu Objects:   Adding Nmenu Objects
569* Nmenu Interaction:      Nmenu Interaction
570* Other Nmenu Routines:   Other Nmenu Routines
571* Nmenu Attributes:       Nmenu Attributes
572* Remarks:                Nmenu Remarks
573@end menu
574
575@end ifnottex
576
577
578@node Adding Nmenu Objects
579@subsection Adding Nmenu Objects
580
581To add a nmenu object use
582@findex fl_add_nmenu()
583@anchor{fl_add_nmenu()}
584@example
585FL_OBJECT *fl_add_nmenu(int type, FL_Coord x, FL_Coord y,
586                        FL_Coord w, FL_Coord h, const char *label);
587@end example
588@noindent
589There are currently three types:
590@table @code
591@tindex FL_NORMAL_NMENU
592@anchor{FL_NORMAL_NMENU}
593@item FL_NORMAL_NMENU
594Probably the most often used type: shown as text on a borderless
595background, popup gets opened when clicked on.
596
597@tindex FL_NORMAL_TOUCH_NMENU
598@anchor{FL_NORMAL_TOUCH_NMENU}
599@item FL_NORMAL_TOUCH_NMENU
600Also shown as text on a borderless background, but popup gets opened
601when the mouse is moved on top of it without any further user action
602required.
603
604@tindex FL_BUTTON_NMENU
605@anchor{FL_BUTTON_NMENU}
606@item FL_BUTTON_NMENU
607When not active shown as text on borderless background, when clicked
608on popup is shown and the object itself being displayed as a button.
609
610@tindex FL_BUTTON_TOUCH_NMENU
611@anchor{FL_BUTTON_TOUCH_NMENU}
612@item FL_BUTTON_TOUCH_NMENU
613When not active shown as text on borderless background, when mouse is
614moved onto it the popup is shown and the object itself is displayed as
615a button.
616@end table
617
618Once a new nmenu object has been created items have to be added to
619it. For this the following function exists:
620@findex fl_add_nmenu_items()
621@anchor{fl_add_nmenu_items()}
622@example
623FL_POPUP_ENTRY *fl_add_nmenu_items(FL_OBJECT *obj,
624                                   const char items, ...);
625@end example
626@noindent
627(The function can also be used to append new items to a nmenu object
628that already has items.)
629
630The function returns a pointer to the first menu entry added on
631success and @code{NULL} on failure. @code{items} is a string with the
632items to add, separated by the @code{'|'} character. In the simplest
633case you would just use something like @code{"Item 1|Item 2|Item 3"}
634to add three items to the list.
635
636As also described in the documentation for the similar function
637@code{@ref{fl_popup_add_entries()}} the text for an item may contain
638"special sequences" that start with the character @code{'%'} and then
639may require an additional argument passed to the function after the
640@code{items} argument. All of those described in detail in the
641documentation for the @code{@ref{fl_popup_add_entries()}} function can
642also be used for nmenus.
643
644Another way to set up the popup of a select object, using an array of
645@ref{FL_POPUP_ITEM} structures, is via the function
646@findex fl_set_nmenu_items()
647@anchor{fl_set_nmenu_items()}
648@example
649FL_POPUP_ENTRY *fl_set_nmenu_items(FL_OBJECT *obj, FL_POPUP_ITEM *item);
650@end example
651@noindent
652The function returns a pointer to the first menu item on success and
653@code{NULL} on failure. The function expects as arguments a pointer to
654the nmenu object and an array of @code{@ref{FL_POPUP_ITEM}}
655structuress, with the very last element having @code{NULL} as the
656@code{text} member to mark the end of the array.
657
658The @code{text} member of the structure may contain the character
659sequence @code{"%S"} to have the text drawn for the item split up at
660that position and with everything before @code{"%S"} drawn
661left-flushed and the rest right-flushed. Moreover, @code{text} may
662start with the character @code{'/'} and/or @code{'_'}. For an
663underline character a line is drawn above the item. And if there's a
664slash this item marks the begin of a sub-menu with all further items
665belonging to the sub-menu until a structure with member @code{text}
666being set to @code{NULL} is found in the array. (The @code{'/'} and
667@code{'_'} characters are, of course, not drawn.)
668
669@code{type} indicates the type of the item. It can be
670@table @code
671@tindex FL_POPUP_NORMAL
672@item FL_POPUP_NORMAL
673A normal, plain item.
674
675@tindex FL_POPUP_TOGGLE
676@item FL_POPUP_TOGGLE
677An item that represents one of two states and is drawn with a
678check-marker when in "on" state.
679
680@tindex FL_POPUP_RADIO
681@item FL_POPUP_RADIO
682A radio item, i.e., it belongs to a group of items of which only one
683can be in "on" state at a time. They are drawn with a circle to the
684left with the circle for the "selected" item being filled with a
685color.
686@end table
687@noindent
688Please note that if @code{text} starts with a @code{'/'} the type
689@strong{must} be @code{FL_POPUP_NORMAL}.
690
691The @code{state} member per default is @code{@ref{FL_POPUP_NONE}}. It
692can be set to
693@table @code
694@tindex FL_POPUP_NONE
695@item FL_POPUP_NONE
696No special flags are set for the state of the item.
697
698@tindex FL_POPUP_DSABLED
699@item FL_POPUP_DSABLED
700The item is disabled and can't be selected.
701
702@tindex FL_POPUP_HIDDEN
703@item FL_POPUP_HIDDEN
704The item is hidden, i.e., does not get shown (and thus can't be
705selected).
706
707@tindex FL_POPUP_CHECKED
708@item FL_POPUP_CHECKED
709Only relevant for toggle or radio items, marks it as in "on" state.
710@end table
711
712@code{callback} is a function that will be called if the item is
713selected. The callback function has the following type:
714@example
715typedef int (*FL_POPUP_CB)(FL_POPUP_RETURN *);
716@end example
717@noindent
718It receives a pointer to a structure that contains all information
719about the entry selected by the user:
720@example
721typedef struct @{
722    long int              val;       /* value assigned to entry */
723    void                 *user_data; /* pointer to user data */
724    const char           *text;      /* text of selected popup entry */
725    const char           *label;     /* text drawn on left side */
726    const char           *accel;     /* text drawn on right side */
727    const FL_POPUP_ENTRY *entry;     /* selected popup entry */
728    const FL_POPUP       *popup;     /* (sub-)popup it belongs to */
729@} FL_POPUP_RETURN;
730@end example
731@noindent
732@code{val} is a value that has been associated with the entry and
733@code{user_data} is a pointer that can be used to store the location
734of further information. @code{text} is the text that was used to
735create the entry (including all "special" characters), while
736@code{label} and @code{accel} are the texts shown for the entry on the
737left and right. @code{entry} is the pointer to the structure for the
738entry selected and @code{popup} to the (sub-) popup the entry belongs
739to (@pxref{Part III Popups} for more details on these structures).
740
741If the callback function already does all the work required on
742selection of the item have it return the value @code{FL_IGNORE} to
743keep the selection from being reported back to the main loop of the
744program.
745
746Finally, @code{shortcut} is a string encoding the keybord shortcut to
747be used for the item.
748
749
750There's also a third method to "populate" a menu. If you already
751created a popup than you can set it as the menu's popup via a call of
752@findex fl_set_nmenu_popup()
753@anchor{fl_set_nmenu_popup()}
754@example
755int fl_set_nmenu_popup(FL_POPUP *popup);
756@end example
757@noindent
758Of course, the popup you associate with the nmenu object in this way
759can't be a sub-popup.
760
761
762@node Nmenu Interaction
763@subsection Nmenu Interaction
764
765There are, if seen interaction-wise, two types of nmenu objects,
766normal ones and touch nmenus. For normal nmenus a popup is opened when
767the user clicks on the area of the nmenu object while for touch nmenus
768the popup already is shown when the user moves the mouse unto the
769area. In other respects they behave identical: the user just selects
770one of the items in the popup (or one of the sub-popups) and then the
771popup is closed again. The selection can now be handled within a
772callback function and/or reported back to the main loop of the
773program.
774
775The popup is always shown directly below the nmenu object (except
776for the case that the popup is that long that it wouldn't fit on the
777screen, in which case the popup is drawn above the nmenu's area.
778
779The most natural way to deal with a selection by the user is probably
780via a callback for the item that was selected. But also a callback for
781the popup as a whole or the object itself can be used. Item and popup
782callback functions are of type @code{@ref{FL_POPUP_CB}} described
783above (and in even more detail in @ref{Part III Popups}), while object
784callbacks are "normal" XForms callback functions.
785
786The condition under which a @code{FL_NMENU} object gets returned to
787the application (or an associate callback is invoked) can be
788influenced by calling the function
789@example
790int fl_set_object_return(FL_OBJECT *obj, unsigned int when)
791@end example
792where @code{when} can have the following values
793@table @code
794@item @ref{FL_RETURN_NONE}
795Never return or invoke a callback.
796
797@item @ref{FL_RETURN_END_CHANGED}
798Return or invoke callback if end of interaction and selection of an
799item coincide.
800
801@item @ref{FL_RETURN_CHANGED}
802Return or invoke callback whenever an item is selected (this is the
803default).
804
805@item @ref{FL_RETURN_END}
806Return or invoke callback on end of an interaction.
807
808@item @ref{FL_RETURN_ALWAYS}
809Return (or invoke callback) whenever the interaction ends and/or
810an item is selected.
811@end table
812
813
814One detail of the interaction that can be adjusted is under which
815conditions the nmenu's popup gets closed. Per default the popup is
816closed when an item is selected or (without a selection) when the user
817clicks somehwere outside of the popups area. This can be changed so
818that the popup also gets closed (without a selection) when the mouse
819button is clicked or released on a non-selectable item (giving the
820impression of a "pull-down" menu). For this purpose there's the
821@findex fl_set_nmenu_policy()
822@anchor{fl_set_nmenu_policy()}
823@example
824int fl_set_nmenu_policy(FL_OBJECT *obj, int policy);
825@end example
826@noindent
827function where @code{policy} can be one of two values:
828@table @code
829@tindex FL_POPUP_NORMAL_SELECT
830@item FL_POPUP_NORMAL_SELECT
831Default, popup stays open until mouse button is released on a
832selectable entry or button is clicked outside the popups area.
833
834@tindex FL_POPUP_DRAG_SELECT
835@item FL_POPUP_DRAG_SELECT
836Popup is closed when the mouse button is released.
837@end table
838@noindent
839The function returns on success the previous setting of the "policy"
840and -1 on error.
841
842
843@node Other Nmenu Routines
844@subsection Other Nmenu Routines
845
846To find out which item of a nmenu object was selected last use
847@findex fl_get_nmenu_item()
848@anchor{fl_get_nmenu_item()}
849@example
850FL_POPUP_RETURN *fl_get_nmenu_item(FL_OBJECT *obj);
851@end example
852@noindent
853The function returns either a pointer to a @code{@ref{FL_POPUP_RETURN}}
854structure with informations about the selected item (as already
855discussed above when talking about callbacks) or @code{NULL} if
856no selection was made the last time the nmenu object was used.
857
858For some actions, e.g., deletion of an item etc., it is necessary to
859know the popup entry that represents it. Therefore it's possible to
860search the list of items according to several criteria:
861@findex fl_get_nmenu_item_by_value()
862@anchor{fl_get_nmenu_item_by_value()}
863@findex fl_get_nmenu_item_by_label()
864@anchor{fl_get_nmenu_item_by_label()}
865@findex fl_get_nmenu_item_by_text()
866@anchor{fl_get_nmenu_item_by_text()}
867@example
868FL_POPUP_ENTRY *fl_get_nmenu_item_by_value(FL_OBJECT *obj, long val);
869FL_POPUP_ENTRY *fl_get_nmenu_item_by_label(FL_OBJECT *obj,
870                                           const char *label);
871FL_POPUP_ENTRY *fl_get_nmenu_item_by_label(FL_OBJECT *obj,
872                                           const char *text);
873@end example
874The first function, @code{@ref{fl_get_nmenu_item_by_value()}},
875searches through the list of all items (including items in sub-popups)
876and returns the first one with the @code{val} associated with the item
877(or @code{NULL} if none is found). The second,
878@code{@ref{fl_get_nmenu_item_by_label()}} searches for a certain label
879as displayed for the item in the popup. The third,
880@code{@ref{fl_get_nmenu_item_by_text()}} searches for the text the
881item was created by (that might be the same as the label text in
882simple cases). Please note that all functions return a structure of
883type @code{@ref{FL_POPUP_ENTRY}} (and not
884@code{@ref{FL_POPUP_RETURN}}, which gives you direct access to the
885entry in the popup for the item.
886
887
888Using e.g., the results of the above searches a nmenu item can be
889deleted:
890@findex fl_delete_nmenu_item()
891@anchor{fl_delete_nmenu_item()}
892@example
893int fl_delete_nmenu_item(FL_OBJECT *obj, FL_POPUP_ENTRY *item);
894@end example
895
896Alternatively, an item can be replaced by one or more items:
897@findex fl_replace_nmenu_item()
898@anchor{fl_replace_nmenu_item()}
899@example
900FL_POPUP_ENTRY *fl_replace_nmenu_item(FL_OBJECT *obj,
901                                      FL_POPUP_ENTRY *old,
902                                      const char *new_items, ...);
903@end example
904where @code{old} is the item to replace and @code{new_items} is a
905string exactly as used for @code{@ref{fl_add_nmenu_items()}} with
906informations about the new item(s).
907
908One also may insert additional items using
909@findex fl_insert_nmenu_items()
910@anchor{fl_insert_nmenu_items()}
911@example
912FL_POPUP_ENTRY *fl_insert_nmenu_items(FL_OBJECT *obj,
913                                      FL_POPUP_ENTRY *after,
914                                      const char *new_items, ...);
915@end example
916@noindent
917where @code{after} is the item after which the new items are to be
918inserted (use @code{NULL} to insert at the very start) and
919@code{new_items} is a string just like used with
920@code{@ref{fl_add_nmenu_items()}} with informations about the
921additional item(s).
922
923
924As you may remember, there are two different ways to "populate" a
925nmenu object. In one case you pass a kind of format string plus
926a variable number of arguments and in the other case an array of
927@code{@ref{FL_POPUP_ITEM}} structures. The previously listed
928functions for inserting and replacing used the first "interface".
929But there are also three functions for using the alternative
930interface:
931@anchor{fl_add_nmenu_items2()}
932@findex fl_add_nmenu_items2()
933@anchor{fl_insert_nmenu_items2()}
934@findex fl_insert_nmenu_items2()
935@anchor{fl_replace_nmenu_items2()}
936@findex fl_replace_nmenu_items2()
937@example
938FL_POPUP_ENTRY *fl_add_nmenu_items2(FL_OBJECT *obj,
939                                    FL_POPUP_ITEM *items);
940FL_POPUP_ENTRY *fl_insert_nmenu_items2(FL_OBJECT *obj,
941                                       FL_POPUP_ENTRY *after,
942                                       FL_POPUP_ITEM *items);
943FL_POPUP_ENTRY *fl_replace_nmenu_items2(FL_OBJECT *obj,
944                                        FL_POPUP_ENTRY *old_item,
945                                        FL_POPUP_ITEM *items);
946@end example
947@noindent
948All three functions return a pointer to the first new entry in the
949nmenu's popup on success and @code{NULL} on failure. The all take
950a pointer to the nmenu object as their first argument.
951
952@code{@ref{fl_add_nmenu_items2()}} appends the items given by the list
953specified via the second argument to the nmenu's popup.
954@code{@ref{fl_insert_nmenu_items2()}} inserts one or more new items
955(as given by the last argument) after the entry specified by
956@code{after} (if @code{after} is @code{NULL} the new items are
957inserted before all existing items). Finally,
958@code{@ref{fl_replace_nmenu_items2()}} replaces the existing entry
959@code{old_item} with a new (or a list of new items specified by
960@code{items}.
961
962Finally, there's a function to remove all items from a nmenu object
963at once:
964@findex fl_clear_nmenu()
965@anchor{fl_clear_nmenu()}
966@example
967in fl_clear_nmenu(FL_OBJECT *obj);
968@end example
969
970
971@node Nmenu Attributes
972@subsection Nmenu Attributes
973
974
975While not "active" the background of the nmenu object is drawn in the
976color that can be controlled via the first color argument,
977@code{col1}, of @code{@ref{fl_set_object_color()}}. When "active"
978(i.e., while the popup is shown) its background is drawn in the color
979of second color argument, @code{col2}, of the same function. The color
980of the label when "inactive" is controlled via
981@code{@ref{fl_set_object_lcolor()}}. When in "active" state the color
982use for the label can be set via the function
983@findex fl_set_nmenu_hl_text_color()
984@anchor{fl_set_nmenu_hl_text_color()}
985@example
986FL_COLOR fl_set_nmenu_hl_text_color(FL_OBJECT *obj, FL_COLOR color);
987@end example
988@noindent
989The function returns the old color on success or
990@code{@ref{FL_MAX_COLORS}} on failure. Per default this color is
991@code{FL_BLACK} for nmenus that are shown as a button while being
992"active" while for normal nmenus it's the same color that is used
993items in the popup when the mouse is hovering over them.
994
995The size and style of the font used for the label of the nmenu object
996can be set via @code{@ref{fl_set_object_lsize()}} and
997@code{@ref{fl_set_object_lstyle()}}.
998
999The rest of the appearance of a nmenu object is given by the
1000appearance of the popup. These can be directly set via the functions
1001for setting the popup appearance as described in @ref{Popup
1002Attributes}. To find out which popup is associated with the nmenu
1003object use the function
1004@findex fl_get_nmenu_popup()
1005@anchor{fl_get_nmenu_popup()}
1006@example
1007FL_POPUP *fl_get_nmenu_popup(FL_OBJECT *obj);
1008@end example
1009@noindent
1010and then use the popup specific functions to set the appearance. The
1011same also holds for the appearance etc.@: of the items of the popup, a
1012lot of functions exist that allow to set the attributes of entries of
1013a popup, @pxref{Popup Attributes}.
1014
1015
1016@node Nmenu Remarks
1017@subsection Remarks
1018
1019See the demo program @file{menu.c}.
1020
1021
1022@node Browser Object
1023@section Browser Object
1024
1025The browser object class is probably the most powerful that currently
1026exists in the Forms Library. A browser is a box that contains a number
1027of lines of text. If the text does not fit inside the box, a scrollbar
1028is automatically added so that the user can scroll through it. A
1029browser can be used for building up a help facility or to give
1030messages to the user.
1031
1032It is possible to create a browser from which the user can select
1033lines. In this way the user can make its selections from a (possible)
1034long list of choices. Both single lines and multiple lines can be
1035selected, depending on the type of the browser.
1036
1037@ifnottex
1038
1039@menu
1040* Adding Browser Objects:   Adding Browser Objects
1041* Browser Types:            Browser Types
1042* Browser Interaction:      Browser Interaction
1043* Other Browser Routines:   Other Browser Routines
1044* Browser Attributes:       Browser Attributes
1045* Remarks:                  Browser Remarks
1046@end menu
1047
1048@end ifnottex
1049
1050
1051@node Adding Browser Objects
1052@subsection Adding Browser Objects
1053
1054To add a browser to a form use the routine
1055@findex fl_add_browser()
1056@anchor{fl_add_browser()}
1057@example
1058FL_OBJECT *fl_add_browser(int type, FL_Coord x, FL_Coord y,
1059                          FL_Coord w, FL_Coord h, const char *label);
1060@end example
1061@noindent
1062The meaning of the parameters is as usual. The label is placed below
1063the box by default.
1064
1065
1066@node Browser Types
1067@subsection Browser Types
1068
1069The following types of browsers exist (see below for more information
1070about them):
1071@table @code
1072@tindex FL_NORMAL_BROWSER
1073@anchor{FL_NORMAL_BROWSER}
1074@item FL_NORMAL_BROWSER
1075A browser in which no selections can be made.
1076
1077@tindex FL_SELECT_BROWSER
1078@anchor{FL_SELECT_BROWSER}
1079@item FL_SELECT_BROWSER
1080In this type of browser the user can make single line selections which
1081get reset immediately when the mouse button is released.
1082
1083@tindex FL_HOLD_BROWSER
1084@anchor{FL_HOLD_BROWSER}
1085@item FL_HOLD_BROWSER
1086Same as @code{FL_SELECT_BROSER} but the selection remains visible till
1087the next selection.
1088
1089@tindex FL_DESELECTABLE_HOLD_BROWSER
1090@anchor{FL_DESELECTABLE_HOLD_BROWSER}
1091@item FL_DESELECTABLE_HOLD_BROWSER
1092Same as the @code{FL_HOLD_BROWSER} but the user can deselect the
1093selected line.
1094
1095@tindex FL_MULTI_BROWSER
1096@anchor{FL_MULTI_BROWSER}
1097@item FL_MULTI_BROWSER
1098Multiple selections can be made and remain visible till de-selected.
1099@end table
1100
1101Hence, the differences only lie in how the selection process works.
1102
1103
1104@node Browser Interaction
1105@subsection Browser Interaction
1106
1107The user can change the position of the slider or use keyboard cursor
1108keys (including @code{<Home>}, @code{<PageDown>}, etc.) to scroll
1109through the text. When he/she presses the left mouse below or above
1110the slider, the browser scrolls one page up or down. Any other mouse
1111button scrolls one line at a time (except wheel mouse buttons). When
1112not using an @code{@ref{FL_NORMAL_BROWSER}} the user can also make
1113selections with the mouse by pointing to a line or by using the cursor
1114keys.
1115
1116For @code{@ref{FL_SELECT_BROWSER}}'s, as long as the user keeps the
1117left mouse button pressed, the current line under the mouse is
1118highlighted. Whenever she releases the left mouse button the
1119highlighting disappears and the browser is returned to the application
1120program. The application program can now figure out which line was
1121selected using a call of @code{@ref{fl_get_browser()}} to be described
1122below. It returns the number of the last selected line (with the
1123topmost line being line 1).
1124
1125A @code{@ref{FL_HOLD_BROWSER}} works exactly the same except that,
1126when the left mouse button is released, the selection remains
1127highlighted. A @code{@ref{FL_DESELECTABLE_HOLD_BROWSER}} additionally
1128allows the user to undo a selection (by clicking on it again).
1129
1130An @code{@ref{FL_MULTI_BROWSER}} allows the user to select and
1131de-select multiple lines. Whenever he selects or de-selects a line the
1132browser object is returned to the application program (or a callback
1133is executed when installed) that then can figure out which line was
1134selected using @code{@ref{fl_get_browser()}} (described in more detail
1135below). That function returns the number of the last line to be
1136selected or de-selected. When a line was de-selected the negation of
1137the line number gets returned. I.e., if line 10 was selected the
1138routine returns 10 and if line 10 was de-selected -10. When the user
1139presses the left mouse button on a non-selected line and then moves it
1140with the mouse button still pressed down, he will select all lines he
1141touches with his mouse until he releases it. All these lines will
1142become highlighted. When the user starts pressing the mouse on an
1143already selected line he de-selects lines rather than selecting them.
1144
1145
1146Per default a browser only gets returned (or a possibly associated
1147callback gets invoked) on selection of a line (and, in the case of
1148@code{@ref{FL_MULTI_BROWSER}}, on deselections). This behaviour can be
1149changed by using the function
1150@example
1151int fl_set_object_return(FL_OBJECT *obj, unsigned int when)
1152@end example
1153where @code{when} can have the following values
1154@table @code
1155@item @ref{FL_RETURN_NONE}
1156Never return or invoke callback.
1157
1158@item @ref{FL_RETURN_SELECTION}
1159Return or invoke callback on selection of a line. Please note that for
1160@code{@ref{FL_MULTI_BROWSER}} the browser may be returned just once
1161for a number of lines having been selected.
1162
1163@item @ref{FL_RETURN_DESELECTION}
1164Return or invoke a callback on deselection of a line. This only
1165happens for @code{@ref{FL_DESELECTABLE_HOLD_BROWSER}} and
1166@code{@ref{FL_MULTI_BROWSER}} objects and, for the latter, the browser
1167may get returned (or the callback invoked) just once for a number of
1168lines having been deselected.
1169
1170@item @ref{FL_RETURN_END_CHANGED}
1171Return or invoke callback at end (mouse release) if the text in the
1172browser has been scrolled.
1173
1174@item @ref{FL_RETURN_CHANGED}
1175Return or invoke callback whenever the text in the browser has been scrolled.
1176
1177@item @ref{FL_RETURN_END}
1178Return or invoke callback on end of an interaction for scrolling the
1179text in the browser regardless if the text was scrolled or not.
1180
1181@item @ref{FL_RETURN_ALWAYS}
1182Return or invoke callback on selection, deselection or scrolling of
1183text or end of scrolling.
1184@end table
1185
1186The default setting for @code{when} for a browser object is
1187@code{@ref{FL_RETURN_SELECTION}|@ref{FL_RETURN_DESELECTION}} (unless
1188during the built of XForms you set the configuration flag
1189@code{--enable-bwc-bs-hack} in which case the default is
1190@code{@ref{FL_RETURN_NONE}} to keep backward compatibility with
1191earlier releases of the library).
1192
1193
1194@node Other Browser Routines
1195@subsection Other Browser Routines
1196
1197There are a large number of routines to change the contents of a
1198browser, select and de-select lines, etc.
1199
1200To remove all lnes from a browser use
1201@findex fl_clear_browser()
1202@anchor{fl_clear_browser()}
1203@example
1204void fl_clear_browser(FL_OBJECT *obj);
1205@end example
1206
1207To add a line to a browser use one of
1208@findex fl_add_browser_line()
1209@anchor{fl_add_browser_line()}
1210@findex fl_add_browser_line_f()
1211@anchor{fl_add_browser_line_f()}
1212@example
1213void fl_add_browser_line(FL_OBJECT *obj, const char *text);
1214void fl_add_browser_line_f(FL_OBJECT *obj, const char *fmt, ...);
1215@end example
1216The first function receives a simple string as the argument, the
1217second one expects a format string just like for @code{printf()} etc.
1218and followed by the appropriate number of arguments of the correct
1219types. The line to be added may contain embedded newline characters
1220(@code{'\n'}). These will result in the text being split up into
1221several lines, separated at the newline characters.
1222
1223A second way of adding a line to the browser is to use calls of
1224@findex fl_addto_browser()
1225@anchor{fl_addto_browser()}
1226@findex fl_addto_browser_f()
1227@anchor{fl_addto_browser_f()}
1228@example
1229void fl_addto_browser(FL_OBJECT *obj, const char *text);
1230@end example
1231@noindent
1232The difference to @code{@ref{fl_add_browser_line()}} and
1233@code{@ref{fl_add_browser_line_f()}} is that with these
1234calls the browser will be shifted such that the newly appended line is
1235visible. This is useful when e.g., using the browser to display
1236messages.
1237
1238Sometimes it may be more convenient to add characters to a browser
1239without starting of a new line. To this end, the following routines
1240exists
1241@findex fl_addto_browser_chars()
1242@anchor{fl_addto_browser_chars()}
1243@findex fl_addto_browser_chars_f()
1244@anchor{fl_addto_browser_chars_f()}
1245@example
1246void fl_addto_browser_chars(FL_OBJECT *obj, const char *text);
1247void fl_addto_browser_chars_f(FL_OBJECT *obj, const char *fmt, ...);
1248@end example
1249@noindent
1250These functions appends text to the last line in the browser without
1251advancing the line counter. The to functions differ in that the first
1252one takes a simple string argument while the second expects a format
1253string just as for @code{printf()} etc., followed by a corresponding
1254number of arguments. Again the text may contain embedded newline
1255characters (@code{'\n'}). In that case, the text before the first
1256embedded newline is appended to the last line, and everything
1257afterwards is put onto new lines. As in the case of
1258@code{@ref{fl_addto_browser()}} the last added line will be visible in
1259the browser.
1260
1261You can also insert a line in front of a given line. All lines after
1262it will be shifted. Note that the top line is numbered 1 (not 0).
1263@findex fl_insert_browser_line()
1264@anchor{fl_insert_browser_line()}
1265@findex fl_insert_browser_line_f()
1266@anchor{fl_insert_browser_line_f()}
1267@example
1268void fl_insert_browser_line(FL_OBJECT *obj, int line,
1269                            const char *text);
1270void fl_insert_browser_line_f(FL_OBJECT *obj, int line,
1271                              const char *fmt, ...);
1272@end example
1273@noindent
1274The first function takes a simple string argument while the second one
1275expects a format string as used for @code{printf()} etc. and the
1276appropriate number of arguments (of the types specified in the format
1277string).
1278
1279Please note that on insertion (as well as replacements, see below)
1280embedded newline characters don't result in the line being split up as
1281it's done in the previous functions. Instead they will rather likely
1282appear as strange looking characters in the text shown. The only
1283exception is when inserting into an empty browser or after the last
1284line, then this function works exactly as if you had called
1285@code{@ref{fl_add_browser_line()}} or
1286@code{@ref{fl_add_browser_line_f()}}.
1287
1288To delete a line (shifting the following lines) use:
1289@findex fl_delete_browser_line()
1290@anchor{fl_delete_browser_line()}
1291@example
1292void fl_delete_browser_line(FL_OBJECT *obj, int line);
1293
1294@end example
1295
1296One can also replace a line using one of
1297@findex fl_replace_browser_line()
1298@anchor{fl_replace_browser_line()}
1299@findex fl_replace_browser_line_f()
1300@anchor{fl_replace_browser_line_f()}
1301@example
1302void fl_replace_browser_line(FL_OBJECT *obj, int line,
1303                             const char *text);
1304void fl_replace_browser_line_f(FL_OBJECT *obj, int line,
1305                               const char *fmt, ...);
1306@end example
1307The first one takes a simple string for the replacement text while for
1308the second it is to be specified by a format string exactly as used in
1309@code{printf()} etc. and the appropriate number of arguments of the
1310types specifed in the format string.
1311\
1312As in the case of @code{@ref{fl_insert_browser_line()}} and
1313@code{@ref{fl_insert_browser_line_f()}} newline characters embedded
1314into the replacement text don't have any special meaning, i.e., they
1315don't result in replacement of more than a single line.
1316
1317Making many changes to a visible browser after another, e.g.,
1318clearing it and then adding a number of new lines, is slow because the
1319browser is redrawn on each and every change. This can be avoided by
1320using calls of @code{@ref{fl_freeze_form()}} and
1321@code{@ref{fl_unfreeze_form()}}. So a piece of code that fills in a
1322visible browser should preferably look like the following
1323@example
1324fl_freeze_form(browser->form);
1325fl_clear_browser(browser);
1326fl_add_browser_line(browser, "line 1");
1327fl_add_browser_line(browser, "line 2");
1328...
1329fl_unfreeze_form(brow->form);
1330@end example
1331@noindent
1332where @code{browser->form} is the form that contains the browser
1333object named @code{browser}.
1334
1335To obtain the contents of a particular line in the browser, use
1336@findex fl_get_browser_line()
1337@anchor{fl_get_browser_line()}
1338@example
1339const char *fl_get_browser_line(FL_OBJECT *obj, int line);
1340@end example
1341@noindent
1342It returns a pointer to the text of that line, exactly as it were
1343passed to the function that created the line.
1344
1345It is possible to load an entire file into a browser using
1346@findex fl_load_browser()
1347@anchor{fl_load_browser()}
1348@example
1349int fl_load_browser(FL_OBJECT *obj, const char *filename);
1350@end example
1351@noindent
1352The routine returns @code{1} when file could be successfully loaded,
1353otherwise @code{0}. If the file name is an empty string (or the file
1354could not be opened for reading) the browser is just cleared. This
1355routine is particularly useful when using the browser for a help
1356facility. You can create different help files and load the needed one
1357depending on context.
1358
1359The application program can select or de-select lines in the browser.
1360To this end the following calls exist with the obvious meaning:
1361@findex fl_select_browser_line()
1362@anchor{fl_select_browser_line()}
1363@findex fl_deselect_browser()
1364@anchor{fl_deselect_browser()}
1365@findex fl_deselect_browser_line()
1366@anchor{fl_deselect_browser_line()}
1367@example
1368void fl_select_browser_line(FL_OBJECT *obj, int line);
1369void fl_deselect_browser_line(FL_OBJECT *obj, int line);
1370void fl_deselect_browser(FL_OBJECT *obj);
1371@end example
1372@noindent
1373The last call de-selects all lines.
1374
1375To check whether a line is selected, use the routine
1376@findex fl_isselected_browser_line()
1377@anchor{fl_isselected_browser_line()}
1378@example
1379int fl_isselected_browser_line(FL_OBJECT *obj, int line);
1380@end example
1381
1382The routine
1383@findex fl_get_browser_maxline()
1384@anchor{fl_get_browser_maxline()}
1385@example
1386int fl_get_browser_maxline(FL_OBJECT *obj);
1387@end example
1388@noindent
1389returns the number of lines in the browser. For example, when the
1390application program wants to figure out which lines in a
1391@code{@ref{FL_MULTI_BROWSER}} are selected code similar to the
1392following can be used:
1393@example
1394int total_lines = fl_get_browser_maxline(browser);
1395for (i = 1; i <= total_lines; i++)
1396    if (fl_isselected_browser_line(browser, i))
1397        /* Handle the selected line */
1398@end example
1399
1400Sometimes it is useful to know how many lines are visible in the
1401browser. To this end, the following call can be used
1402@findex fl_get_browser_screenlines()
1403@anchor{fl_get_browser_screenlines()}
1404@example
1405int fl_get_browser_screenlines(FL_OBJECT *obj);
1406@end example
1407Please note that this count only includes lines that are shown
1408completely in the browser, lines that are partially obscured aren't
1409counted in.
1410
1411To obtain the last selection made by the user, e.g., when the browser
1412is returned, the application program can use the routine
1413@findex fl_get_browser()
1414@anchor{fl_get_browser()}
1415@example
1416int fl_get_browser(FL_OBJECT *obj);
1417@end example
1418@noindent
1419It returns the line number of the last selection being made (0 if no
1420selection was made). When the last action was a de-selection (only for
1421@code{@ref{FL_MULTI_BROWSER}}) the negative of the de-selected line
1422number is returned.
1423
1424The following function allows to find out the (unobscured) line that
1425is currently shown at the top of the browser:
1426@findex fl_get_browser_topline()
1427@anchor{fl_get_browser_topline()}
1428@example
1429int fl_get_browser_topline(FL_OBJECT *obj);
1430@end example
1431@noindent
1432Note that the index of the top line is @code{1}, not @code{0}. A
1433value of @code{0} is returned if the browser doesn't contain any
1434lines.
1435
1436Finally, the function
1437@findex fl_show_browser_line()
1438@anchor{fl_show_browser_line()}
1439@example void fl_show_browser_line(FL_OBJECT *obj, int ln);
1440@end example
1441@noindent
1442shifts the browsers content so that (as far as possible) the line
1443indexed by @code{ln} is shown at the center of the browser.
1444
1445It is possible to register a callback function that gets called when a
1446line is double-clicked on. To do so, the following function is
1447available:
1448@findex fl_set_browser_dblclick_callback()
1449@anchor{fl_set_browser_dblclick_callback()}
1450@example
1451void fl_set_browser_dblclick_callback(FL_OBJECT *obj,
1452                                      void (*cb)(FL_OBJECT *, long),
1453`                                     long data);
1454@end example
1455@noindent
1456Of course, double-click callbacks make most sense for
1457@code{@ref{FL_HOLD_BROWSER}}s.
1458
1459The part if the text visible within the browser can be set
1460programmatically in a number of ways. With the functions
1461@findex fl_set_browser_topline()
1462@anchor{fl_set_browser_topline()}
1463@findex fl_set_browser_bottomline()
1464@anchor{fl_set_browser_bottomline()}
1465@example
1466void fl_set_browser_topline(FL_OBJECT *obj, int line);
1467void fl_set_browser_bottomline(FL_OBJECT *obj, int line);
1468@end example
1469@noindent
1470the line shown at the top or the bottom can be set (note again
1471that line numbers start with 1).
1472
1473Instead of by line number also the amount the text is scrolled in
1474horizontal and vertical direction can be set with the functions
1475@findex fl_set_browser_xoffset()
1476@anchor{fl_set_browser_xoffset()}
1477@findex fl_set_browser_rel_xoffset()
1478@anchor{fl_set_browser_rel_xoffset()}
1479@findex fl_set_browser_yoffset()
1480@anchor{fl_set_browser_yoffset()}
1481@findex fl_set_browser_rel_yoffset()
1482@anchor{fl_set_browser_rel_yoffset()}
1483@example
1484void fl_set_browser_xoffset(FL_OBJECT *obj, FL_Coord xoff);
1485void fl_set_browser_rel_xoffset(FL_OBJECT *obj, double xval);
1486void fl_set_browser_yoffset(FL_OBJECT *obj, FL_Coord yoff);
1487void fl_set_browser_rel_yoffset(FL_OBJECT *obj, double yval);
1488@end example
1489@noindent
1490where @code{xoff} and @code{yoff} indicate how many pixels to scroll
1491horizontally (relative to the left margin) or vertically (relative to
1492the top of the text), while @code{xval} and @code{yval} stand for
1493positions relative to the total width or height of all of the text and
1494thus have to be numbers between @code{0.0} and @code{1.0}.
1495
1496There are also a number of functions that can be used to obtain the
1497current amount of scrolling:
1498@findex fl_get_browser_xoffset()
1499@anchor{fl_get_browser_xoffset()}
1500@findex fl_get_browser_rel_xoffset()
1501@anchor{fl_get_browser_rel_xoffset()}
1502@findex fl_get_browser_yoffset()
1503@anchor{fl_get_browser_yoffset()}
1504@findex fl_get_browser_rel_yoffset()
1505@anchor{fl_get_browser_rel_yoffset()}
1506@example
1507FL_Coord fl_get_browser_xoffset(FL_OBJECT *obj);
1508FL_Coord fl_get_browser_rel_xoffset(FL_OBJECT *obj);
1509FL_Coord fl_get_browser_yoffset(FL_OBJECT *obj);
1510FL_Coord fl_get_browser_rel_yoffset(FL_OBJECT *obj);
1511@end example
1512
1513Finally, there's a function that tells you the vertical position of a
1514line in pixels:
1515@findex fl_get_browser_line_yoffset()
1516@anchor{fl_get_browser_line_yoffset()}
1517@example
1518int fl_get_browser_line_yoffset(FL_OBJECT *obj, imt line);
1519@end example
1520@noindent
1521The return value is just the value that would have to be passed to
1522@code{@ref{fl_set_browser_yoffset()}} to make the line appear at the
1523top of the browser. If the line does not exist it returns @code{-1}
1524instead.
1525
1526
1527@node Browser Attributes
1528@subsection Browser Attributes
1529
1530Never use the boxtype @code{@ref{FL_NO_BOX}} for browsers.
1531
1532The first color argument (@code{col1}) to
1533@code{@ref{fl_set_object_color()}} controls the color of the browser's
1534box, the second (@code{col2}) the color of the selection. The text
1535color is the same as the label color, @code{obj->lcol}.
1536
1537To set the font size used inside the browser use
1538@findex fl_set_browser_fontsize()
1539@anchor{fl_set_browser_fontsize()}
1540@example
1541void fl_set_browser_fontsize(FL_OBJECT *obj, int size);
1542@end example
1543
1544To set the font style used inside the browser use
1545@findex fl_set_browser_fontstyle()
1546@anchor{fl_set_browser_fontstyle()}
1547@example
1548void fl_set_browser_fontstyle(FL_OBJECT *obj, int style);
1549@end example
1550@noindent
1551@xref{Label Attributes and Fonts}, for details on font sizes and
1552styles.
1553
1554It is possible to change the appearance of individual lines in the
1555browser. Whenever a line starts with the symbol @code{'@@'} the next
1556letter indicates the special characteristics associated with this line.
1557The following possibilities exist at the moment:
1558@table @code
1559@item f
1560Fixed width font.
1561
1562@item n
1563Normal (Helvetica) font.
1564
1565@item t
1566Times-Roman like font.
1567
1568@item b
1569Boldface modifier.
1570
1571@item i
1572Italics modifier.
1573
1574@item l
1575Large (new size is @code{@ref{FL_LARGE_SIZE}}).
1576
1577@item m
1578Medium (new size is @code{@ref{FL_MEDIUM_SIZE}}).
1579
1580@item s
1581Small (new size is @code{@ref{FL_SMALL_SIZE}}).
1582
1583@item L
1584Large (new size = current size + 6)
1585
1586@item M
1587Medium (new size = current size + 4)
1588
1589@item S
1590Small (new size = current size - 2).
1591
1592@item c
1593Centered.
1594
1595@item r
1596Right aligned.
1597
1598@item _
1599Draw underlined text.
1600
1601@item -
1602An engraved separator. Text following @code{'-'} is ignored.
1603
1604@item C
1605The next number indicates the color index for this line.
1606
1607@item N
1608Non-selectable line (in selectable browsers).
1609
1610@item ' '
1611(a space character) Does nothing, can be used to separate between the
1612digits specifying a color (following @code{"@@C"}, see above) and the
1613text of a line starting with a digit.
1614
1615@item @@@@
1616Regular @code{'@@'} character.
1617@end table
1618
1619The modifiers (bold and itatic) work by adding
1620@code{@ref{FL_BOLD_STYLE}} and @code{@ref{FL_ITALIC_STYLE}} to the
1621current active font index to look up the font in the font table (you
1622can modify the table using @code{@ref{fl_set_font_name()}} or
1623@code{@ref{fl_set_font_name_f()}}).
1624
1625More than one option can be used by putting them next to each other.
1626For example, @code{"@@C1@@l@@f@@b@@cTitle"} will give you the red,
1627large, bold fixed font, centered word @code{"Title"}. As you can see
1628the font change requests accumulate and the order is important, i.e.,
1629@code{"@@f@@b@@i"} gives you a fixed bold italic font while
1630@code{"@@b@@i@@f"} gives you a (plain) fixed font.
1631
1632Depending on the font size and style lines may have different heights.
1633
1634In some cases the character @code{'@@'} might need to be placed at the
1635beginning of the lines without introducing the special meaning
1636mentioned above. In this case you can use @code{"@@@@"} or change the
1637special character to something other than @code{'@@'} using the
1638following routine
1639@findex fl_set_browser_specialkey()
1640@anchor{fl_set_browser_specialkey()}
1641@example
1642void fl_set_browser_specialkey(FL_OBJECT *obj, int key);
1643@end example
1644
1645To align different text fields on a line, tab characters (@code{'\t'})
1646can be embedded in the text. See @code{@ref{fl_set_tabstop()}} on how
1647to set tabstops.
1648
1649There are two functions to turn the scrollbars on and off:
1650@findex fl_set_browser_hscrollbar()
1651@anchor{fl_set_browser_hscrollbar()}
1652@findex fl_set_browser_vscrollbar()
1653@anchor{fl_set_browser_vscrollbar()}
1654@example
1655void fl_set_browser_hscrollbar(FL_OBJECT *obj, int how);
1656void fl_set_browser_vscrollbar(FL_OBJECT *obj, int how);
1657@end example
1658@noindent
1659@code{how} can be set to the following values:
1660@table @code
1661@tindex FL_ON
1662@item FL_ON
1663Always on.
1664@tindex FL_OFF
1665@item FL_OFF
1666Always off.
1667@tindex FL_AUTO
1668@item FL_AUTO
1669On only when needed (i.e., there are more lines/chars than could be
1670shown at once in the browser).
1671@end table
1672@noindent
1673@code{FL_AUTO} is the default.
1674
1675Please note that when you switch the scrollbars off the text can't be
1676scrolled by the user anymore at all (i.e., also not using methods
1677that don't use scrollbars, e.g., using the cursor keys).
1678
1679Sometimes, it may be desirable for the application to obtain the
1680scrollbar positions when they change (e.g., to use the scrollbars of
1681one browser to control other browsers). There are two ways to achieve
1682this. You can use these functions:
1683@tindex FL_BROWSER_SCROLL_CALLBACK
1684@findex fl_set_browser_hscroll_callback()
1685@anchor{fl_set_browser_hscroll_callback()}
1686@findex fl_set_browser_vscroll_callback()
1687@anchor{fl_set_browser_vscroll_callback()}
1688@example
1689typedef void (*FL_BROWSER_SCROLL_CALLBACK)(FL_OBJECT *, int, void *);
1690void fl_set_browser_hscroll_callback(FL_OBJECT *obj,
1691                                     FL_BROWSER_SCROLL_CALLBACK cb,
1692                                     void *cb_data);
1693void fl_set_browser_vscroll_callback(FL_OBJECT *obj,
1694                                     FL_BROWSER_SCROLL_CALLBACK cb,
1695                                     void *cb_data);
1696@end example
1697@noindent
1698After scroll callbacks are set whenever the scrollbar changes position
1699the callback function is called as
1700@example
1701cb(ob, offset, cb_data);
1702@end example
1703@noindent
1704The first argument to the callback function @code{cb} is the browser
1705object, the second argument is the new xoffset for the horizontal
1706scrollbar or the new top line for the vertical scrollbar. The third
1707argument is the callback data specified as the third argument in the
1708function calls to install the callback.
1709
1710To uninstall a scroll callback, use a @code{NULL} pointer as the
1711callback function.
1712
1713As an alternative you could request that the browser object gets
1714returned (or a callback invoked) when the the scrollbar positions are
1715changed. This can be done e.g., by passing
1716@code{@ref{FL_RETURN_CHANGED}} (if necessary @code{OR}'ed with flags
1717for also returning on selection/deselections). Within the code for
1718dealing with the event you could check if this is a change event by
1719using the function
1720@findex fl_get_object_return_state()
1721@example
1722int fl_get_object_return_state(FL_OBJECT *obj);
1723@end example
1724and test if @code{@ref{FL_RETURN_CHANGED}} is set in the return
1725value (by just logically @code{AND}'ing both) and then handle
1726the change.
1727
1728By default, the scrollbar size is based on the relation between the
1729size of the browser and the size of the text. To change the default,
1730use the following routine
1731@findex fl_set_browser_scrollbarsize()
1732@anchor{fl_set_browser_scrollbarsize()}
1733@example
1734void fl_set_browser_scrollbarsize(FL_OBJECT *obj, int hh, int vw);
1735@end example
1736@noindent
1737where @code{hh} is the horizontal scrollbar height and @code{vw} is
1738the vertical scrollbar width. Use 0 to indicate the default.
1739
1740The default scrollbar type is @code{FL_THIN_SCROLLBAR}. There are two
1741ways you can change the default. One way is to use
1742@code{@ref{fl_set_defaults()}} or @code{@ref{fl_set_scrollbar_type()}}
1743to set the application wide default, another way is to use
1744@code{@ref{fl_get_object_component()}} to get the object handle to the
1745scrollbars and change the the object type forcibly. The first method
1746is preferable because the user can override the setting via resources.
1747Although the second method of changing the scrollbar type is not
1748recommended, the object handle obtained can be useful in changing the
1749scrollbar colors etc.
1750
1751Finally there is a routine that can be used to obtain the browser size
1752in pixels for the text area
1753@findex fl_get_browser_dimension()
1754@anchor{fl_get_browser_dimension()}
1755@example
1756void fl_get_browser_dimension(FL_OBJECT *obj, FL_Coord *x, FL_Coord *y,
1757                              FL_COORD *w, FL_COORD *h);
1758@end example
1759@noindent
1760where @code{x} and @code{y} are measured from the top-left corner of
1761the form (or the smallest enclosing window). To establish the
1762relationship between the text area (a function of scrollbar size,
1763border with and text margin), you can compare the browser size and
1764text area size.
1765
1766
1767Finally, the functions
1768@findex fl_get_browser_scrollbar_repeat()
1769@anchor{fl_get_browser_scrollbar_repeat()}
1770@findex fl_set_browser_scrollbar_repeat()
1771@anchor{fl_set_browser_scrollbar_repeat()}
1772@example
1773int fl_get_browser_scrollbar_repeat(FL_OBJECT *obj);
1774void fl_set_browser_scrollbar_repeat(FL_OBJECT *obj, int millisec);
1775@end example
1776@noindent
1777allows to determine and control the time delay (in milliseconds)
1778between jumps of the scrollbar knob when the mouse button is kept
1779pressed down on the scrollbar outside of the knobs area. The default
1780value is @w{100 ms}. The delay for the very first jump is twice
1781that long in order to avoid jumping to start too soon when only a
1782single click was intended but the user is a bit slow in releasing
1783the mouse button.
1784
1785
1786
1787
1788@node Browser Remarks
1789@subsection Remarks
1790
1791Since version 1.0.92 there isn't a limit on the maximum length of
1792lines in a browser anymore. (The macro @code{FL_BROWSER_LINELENGTH}
1793still exists and is set to 2048 for backward compatibility but has no
1794function anymore).
1795
1796See @file{fbrowse1.c} for an example program using a
1797@code{@ref{FL_NORMAL_BROWSER}} to view files. @file{browserall.c}
1798shows all different browsers. @file{browserop.c} shows the insertion
1799and deletion of lines in a @code{@ref{FL_HOLD_BROWSER}}.
1800
1801For the browser class, especially multi browsers, interaction via
1802callbacks is strongly recommended.
1803