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