Next: , Previous: , Up: Menu Object   [Contents][Index]


23.2.4 Other Menu Routines

There are two ways to populate a menu, i.e., add items. The first one is a bit more complex but allows for more flexibility, e.g., later adding and removing items, associating callbacks with individual items etc. For the more simple (and in many cases sufficient) method see the function fl_set_menu_entries().

To set the actual menu for a menu object, use the routine

void fl_set_menu(FL_OBJECT *obj, const char *menustr, ...);

menustr describes the menu in the form used by XPopups (see XPopup). In the simplest case it just contains the texts for the menu items, separated by a bar ('|'), e.g., "First|Second|Third". But it’s also possible to employ special tags (see Creating XPopups) that can be used to indicate special attributes (radio, toggle and greyed-out, for example). For this usage the unspecified arguments (the ... in the function call) can be used t add neceassary information. Whenever the user selects a menu item, a pointer to the menu object it belongs to is returned to the application program.

Please note that if you call fl_set_menu() on a menu that already contains items the existing items are replaced by the new ones - the function calls fl_clear_menu() internally before the new items are added.

If you explicitely assign a menu item ID to a menu, using the special tag %x, it is your responsibility to make sure that this ID isn’t already used by a different menu item in the same menu. Failure to do so may make it impossible to use the menu properly. All functions working on items expect the menu item ID as one of their arguments. Also note that only values that fit into a char can be used, so the range is restricted to the interval [-128, 127] on most machines with a signed char type and to [0, 255] on those with an unsigned char type. For portability reasons it’s thus to be recommended to restrict the range to [0, 127].

In case you don’t set menu item IDs they are assigned automatically with the first item obtaining the menu item ID 1, the next 2 etc., i.e., it directly reflects the position of the item in the menu.

It is also possible to add menu items to an existing menu using a call of

int fl_addto_menu(FL_OBJECT *obj, const char *menustr, ...);

where menustr is a string of the same form as used in fl_set_menu() (you can add one or more new menu items this way).

Also routines exist to delete a particular menu item or change it:

void fl_delete_menu_item(FL_OBJECT *obj, int miid);
void fl_replace_menu_item(FL_OBJECT *obj, int miid,
                           const char *menustr, ...);

miid is the menu item ID. menustr must be a string as used in fl_set_menu() with the only difference that only a single menu item can be specified.

Please note: when deleting a menu item all other items keep their menu item IDs. The menu item ID of the deleted menu item isn’t re-used when new items are added later. Instead for each menu an internal counter exists that gets incremented for each menu item added and which value is used for the menu item ID unless one is explicitely assigned to the menu item. The counter oly gets reset to 1 when the menu is cleared used fl_clear_menu().

The menu item ID of a menu item changed by using fl_replace_menu_item() does not change unless the library is explicitely asked to via %x in menustr.

For most applications, the following routine may be easier to use at the expense of somewhat restrictive value a menu item can have as well as a loss of the ability to delete menu items or associate callbacks with menu items.

int fl_set_menu_entries(FL_OBJECT *obj, FL_PUP_ENTRY *ent);

where ent is a pointer to an array of structure of the following type, terminated by an element, where at least the text member is a NULL pointer:

typedef struct {
    const char *text;
    FL_PUP_CB callback;
    const char *shortcut;
    int mode;
} FL_PUP_ENTRY;

The meaning of each member is explained in Section 21.3. For menus, item callback function can be NULL if the menu callback handles the interaction results. See demo program popup.c for an example use of fl_set_menu_entries().

The function fl_set_menu_entries() works by creating and associating a popup menu with the menu object. The popup ID is returned by the function. Whenever the function is called, the old popup associated with the object (if one exists) is freed and a new one is created. Although you can manipulate the menu either through the menu API (but adding and removing menu items is not supported for menus created this way ) or popup API, the application should not free the popup directly and use fl_clear_menu() instead.

To clear the whole menu use

void fl_clear_menu(FL_OBJECT *obj);

To find the menu item selected by the user use

int fl_get_menu(FL_OBJECT *obj);

The the function returns the menu item ID. In the simplest possible case this is just the position of the menu item (starting at 1). This stops to be true when either IDs have been explicitely assigned to items or items have been deleted. In that case the following rules apply:

  1. A menu item ID may have been assigned to a menu item using %xn in the string for the text of the menu item.
  2. Menu items can get associated with a callback function that is executed when the menu item is selected. The callback function is of type FL_PUP_CB and receives the menu item ID of the selected menu. If such a callback is set for a menu item the return value of fl_get_menu() is the return value of this function instead of the menu item ID that would have been returned otherwise.

To obtain the text of any item, use the following routine

const char *fl_get_menu_item_text(FL_OBJECT *obj, int miid);

where miid is the menu item ID. If n isn’t a valid menu iem ID item NULL is returned.

To obtain the text of the selected enu item use

const char *fl_get_menu_text(FL_OBJECT *obj);

To obtain the total number of menu items, use the function

int fl_get_menu_maxitems(FL_OBJECT *obj);

One can change the appearance of different menu items. In particular, it is sometimes desirable to make grey-out menu items and make them unselectable or to put boxes with and without checkmarks in front of them. This can be done using the routine:

void fl_set_menu_item_mode(FL_OBJECT *obj, int miid, unsigned mode);

miid is the menu index ID of the memu item you want to change. mode represents the special properties you want to apply to the chosen item. You can specify more than one at a time by adding or bitwise OR-ing these values together. For this parameter, the following symbolic constants exist:

FL_PUP_NONE

No special display characteristic, the default.

FL_PUP_BOX

"Binary" entry, i.e., an entry that stands for a choice that can be switched on and off. Displayed with an unchecked box to the left.

FL_PUP_RADIO

"Radio" item belonging to a group, so that gets automatically switched off when another item of the group is selected. Displayed with a diamoned-shaped box at the left.

FL_PUP_GREY

To be OR-ed with one of the above to make that item appear greyed-out and disable it (i.e., not selectable anymore).

FL_PUP_CHECK

To be OR-ed with one of FL_PUP_BOX and FL_PUP_RADIO to make the box to the left appear checked or pushed.

There is also a routine that can be used to obtain the current mode of an item after interaction, mostly useful for toggle or radio items:

unsigned int fl_get_menu_item_mode(FL_OBJECT *obj, int miid);

While a callback associated with a menu entry can be set when it is created it can also set later on or be changed. For this use the function

FL_PUP_CB fl_set_menu_item_callback(FL_OBJECT *ob,
                                    int numb, FL_PUP_CB cb);

where numb is the menu entries ID and cb is the callback function of type FL_PUP_CB (or NULL to disable a callback). The return value is a pointer to the previously used callback function (or NULL).

It is often useful to define keyboard shortcuts for particular menu items. For example, it would be nice to have <Alt>s behave like selecting "Save" from a menu. This can be done using the following routine:

void fl_set_menu_item_shortcut(FL_OBJECT *obj, int miid,
                               const char *str);

miid is the menu item ID of the menu item under consideration. str contains the shortcut for the item. (Actually, it can contain more shortcuts for the same item.) See Shortcuts, for more information about shortcuts.

Finally there is the routine:

void fl_show_menu_symbol(FL_OBJECT *obj, int yes_no);

With this routine you can indicate whether to show a menu symbol at the right of the menu label. By default no symbol is shown.


Next: , Previous: , Up: Menu Object   [Contents][Index]