Fltk Menus

All widgets that have a menu in fltk are subclassed off of the virtual base class Fl_Menu_. Currently Fltk provides you with Fl_Menu_Button, Fl_Menu_Bar, and Fl_Choice.

The Fl_Menu_ contains a pointer to an array of structures of type Fl_Menu_Item. These describe the contents of the menu. Usually the array is a large initialization constant, but there are methods to build it dynamically.

struct Fl_Menu_Item

This structure is defined in <FL/Fl_Menu_Item.H>
struct Fl_Menu_Item {
  const char*	text; // label()
  ulong		shortcut_;
  Fl_Callback*	callback_;
  void*		user_data_;
  int		flags;
  uchar		labeltype_;
  uchar		labelfont_;
  uchar		labelsize_;
  uchar		labelcolor_;
};

enum { // values for flags:
  FL_MENU_INACTIVE	= 1,
  FL_MENU_TOGGLE	= 2,
  FL_MENU_VALUE		= 4,
  FL_MENU_RADIO		= 8,
  FL_MENU_INVISIBLE	= 0x10,
  FL_SUBMENU_POINTER	= 0x20,
  FL_SUBMENU		= 0x40,
  FL_MENU_DIVIDER	= 0x80,
  FL_MENU_HORIZONTAL	= 0x100
};

A sample menu defined by a C initialization constant:
Fl_Menu_Item popup[] = {
  {"&alpha",   FL_ALT+'a', the_cb, (void*)1},
  {"&beta",    FL_ALT+'b', the_cb, (void*)2},
  {"gamma",    FL_ALT+'c', the_cb, (void*)3, FL_MENU_DIVIDER},
  {"&strange",  0,   strange_cb},
  {"&charm",    0,   charm_cb},
  {"&truth",    0,   truth_cb},
  {"b&eauty",   0,   beauty_cb},
  {"sub&menu",	0,   0, 0, FL_SUBMENU},
    {"one"},
    {"two"},
    {"three"},
  {0},
  {"inactive", FL_ALT+'i', 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER},
  {"invisible",FL_ALT+'i', 0, 0, FL_MENU_INVISIBLE},
  {"check",    FL_ALT+'i', 0, 0, FL_MENU_TOGGLE|FL_MENU_VALUE},
  {"box",      FL_ALT+'i', 0, 0, FL_MENU_TOGGLE},
{0}};
A submenu title is identified by the bit FL_SUBMENU in the flags field, and ends with a label() that is null. You can nest menus to any depth. A pointer to the first item in the submenu can be treated as an Fl_Menu array itself. It is also possible to make seperate submenu arrays with FL_SUBMENU_POINTER flags.

You should not use the member names to refer to the Fl_Menu_Item, instead use these methods:

const char* Fl_Menu_Item::label() const;
void Fl_Menu_Item::label(const char*);

void Fl_Menu_Item::label(Fl_Labeltype, const char*);
Fl_Labeltype Fl_Menu_Item::labeltype() const;
void Fl_Menu_Item::labeltype(Fl_Labeltype);

Fl_Color Fl_Menu_Item::labelcolor() const;
void Fl_Menu_Item::labelcolor(Fl_Color);

Fl_Font Fl_Menu_Item::labelfont() const;
void Fl_Menu_Item::labelfont(Fl_Font);

uchar Fl_Menu_Item::labelsize() const;
void Fl_Menu_Item::labelsize(uchar);

typedef void (Fl_Callback)(Fl_Widget*, void*);
Fl_Callback* Fl_Menu_Item::callback() const;
void Fl_Menu_Item::callback(Fl_Callback*, void* = 0);

void* Fl_Menu_Item::user_data() const;
void Fl_Menu_Item::user_data(void*);

void Fl_Menu_Item::callback(void (*)(Fl_Widget*, long), long = 0);
long Fl_Menu_Item::argument() const;
void Fl_Menu_Item::argument(long);

void Fl_Menu_Item::callback(void (*)(Fl_Widget*));

void Fl_Menu_Item::do_callback(Fl_Widget*);
void Fl_Menu_Item::do_callback(Fl_Widget*, void*);
void Fl_Menu_Item::do_callback(Fl_Widget*, long);

ulong Fl_Menu_Item::shortcut() const;
void Fl_Menu_Item::shortcut(ulong);

int Fl_Menu_Item::submenu() const;

int Fl_Menu_Item::checkbox() const;

int Fl_Menu_Item::radio() const;

int Fl_Menu_Item::value() const;
void Fl_Menu_Item::set();
void Fl_Menu_Item::setonly();
void Fl_Menu_Item::clear();

int Fl_Menu_Item::visible() const;
void Fl_Menu_Item::show();
void Fl_Menu_Item::hide();

int Fl_Menu_Item::active() const;
void Fl_Menu_Item::activate();
void Fl_Menu_Item::deactivate();

const Fl_Menu_Item* Fl_Menu_Item::popup(
  int X, int Y,
  const char* title = 0,
  const Fl_Menu_Item* picked = 0,
  const Fl_Menu_* button = 0) const;

const Fl_Menu_Item* Fl_Menu_Item::pulldown(
  int X, int Y, int W, int H,
  const Fl_Menu_Item* picked = 0,
  const Fl_Menu_* button = 0,
  const Fl_Menu_Item* title = 0,
  int menubar=0) const;

const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const;

int Fl_Menu_Item::size();

const Fl_Menu_Item* Fl_Menu_Item::next(int=1) const;
Fl_Menu_Item* Fl_Menu_Item::next(int=1);


class Fl_Menu_ : public Fl_Widget

This is the base class for all widgets that contain a menu, including Fl_Menu_Button, Fl_Choice, and Fl_Menu_Bar. This base class provides the methods for setting or modifying the menu.

const Fl_Menu_Item* Fl_Menu_::menu() const ;
void Fl_Menu_::menu(const Fl_Menu_Item*);

int Fl_Menu_::value() const ;
const Fl_Menu_Item* Fl_Menu_::mvalue() const;
int Fl_Menu_::value(int);
int Fl_Menu_::value(const Fl_Menu_Item*);

int Fl_Widget::changed() const;
void Fl_Widget::set_changed();
void Fl_Widget::clear_changed();

Fl_When Fl_Widget::when() const;
void Fl_Widget::when(Fl_When);

const Fl_Menu_Item* Fl_Menu_::test_shortcut();

void Fl_Menu_::global();

const char* Fl_Menu_::text() const ;
const char* Fl_Menu_::text(int i) const ;

int Fl_Menu_::size() const ;

int Fl_Menu_::add(const char *,const char *,Fl_Callback *,void *v=0,int f=0);

int Fl_Menu_::add(const char *);

void Fl_Menu_::clear();

void Fl_Menu_::replace(int,const char *);

void Fl_Menu_::remove(int);

void Fl_Menu_::shortcut(int i, int n);

void Fl_Menu_::mode(int i,int x);

Fl_Font Fl_Menu_::textfont() const;
void Fl_Menu_::textfont(Fl_Font);
uchar Fl_Menu_::textsize() const;
void Fl_Menu_::textsize(uchar);
Fl_Color Fl_Menu_::textcolor() const;
void Fl_Menu_::textcolor(Fl_Color);

Fl_Boxtype Fl_Menu_::down_box() const;
void Fl_Menu_::down_box(Fl_Boxtype);


class Fl_Menu_Button : public Fl_Menu_

This is a button that when pushed pops up a menu (or hierarchy of menus) defined by an array of Fl_Menu_Item objects.

Normally any mouse button will pop up a menu and it is lined up below the button as shown in the picture. However an Fl_Menu_Button may also control a pop-up menu. This is done by setting the type(), see below.

The menu will also pop up in response to shortcuts indicated by putting a '&' character in the label(). See Fl_Button for a description of this.

Typing the shortcut() of any of the menu items will cause callbacks exactly the same as when you pick the item with the mouse. The '&' character in menu item names are only looked at when the menu is popped up, however.

When the user picks an item off the menu, the item's callback is done with the menu_button as the Fl_Widget* argument. If the item does not have a callback the menu_button's callback is done instead.

Fl_Menu_Button::Fl_Menu_Button(int,int,int,int,const char * = 0);

void Fl_Widget::type(uchar);

const Fl_Menu* Fl_Menu_Button::popup();


class Fl_Menu_Bar : public Fl_Menu_

This widget provides a standard menubar interface. Usually you will put this widget along the top edge of your window. The height of the widget should be 30 for the menu titles to draw correctly.

The items on the bar and the menus they bring up are defined by a single Fl_Menu_Item array. Because a Fl_Menu_Item array defines a hierarchy, the top level menu defines the items in the menubar, while the submenus define the pull-down menus. Sub-sub menus and lower pop up to the right of the submenus.

If there is an item in the top menu that is not a title of a submenu, then it acts like a "button" in the menubar. Clicking on it will pick it.

When the user picks an item off the menu, the item's callback is done with the menubar as the Fl_Widget* argument. If the item does not have a callback the menubar's callback is done instead.

Submenus will also pop up in response to shortcuts indicated by putting a '&' character in the name field of the menu item. See Fl_Button for a description of this. If you put a '&' character in a top-level "button" then the shortcut picks it. The '&' character in submenus is ignored until the menu is popped up, to match Micro$oft behavior.

Typing the shortcut() of any of the menu items will cause callbacks exactly the same as when you pick the item with the mouse.

Currently the menu bar does not display as many attributes as a pop-up menu. Invisible and inactive items draw correctly. Checkboxes, divider lines, display of shortcuts, and perhaps other things are not drawn in the current version.

Fl_Menu_Bar::Fl_Menu_Bar(int, int, int, int, const char * = 0);

The constructor sets menu() to null. See Fl_Menu_ for the methods to set or change the menu.

labelsize() and labelfont() and labelcolor() are used to control how the menubar items are drawn. They are initialized from the Fl_Menu static variables, but you can change them if desired.

label() is ignored unless you change the align() to put it outside the menubar.


class Fl_Choice : public Fl_Menu_

This is a button that when pushed pops up a menu (or hierarchy of menus) defined by an array of Fl_Menu_Item objects. Motif calls this an OptionButton.

The only difference between this and a Fl_Menu_Button is that the name of the most recent chosen menu item is displayed inside the box, while the label is displayed outside the box. However, since the use of this is most often to control a single variable rather than do individual callbacks, some of the Fl_Menu_Button methods are redescribed here in those terms.

When the user picks an item off the menu the value() is set to that item and then the callback is done.

All three mouse buttons pop up the menu. The Forms behavior of the first two buttons to increment/decrement the choice is not implemented. This could be added with a subclass, however.

The menu will also pop up in response to shortcuts indicated by putting a '&' character in the label(). See Fl_Button for a description of this.

Typing the shortcut() of any of the items will do exactly the same as when you pick the item with the mouse. The '&' character in item names are only looked at when the menu is popped up, however.

Fl_Choice::Fl_Choice(int,int,int,int,const char * =0);

The constructor sets menu() to null. See Fl_Menu_ for the methods to set or change the menu!

int Fl_Choice::value() const ;
int Fl_Choice::value(int);
int Fl_Choice::value(const Fl_Menu *);

The value is the index into the Fl_Menu_Item array of the last item chosen by the user. It is zero initially. You can set it as an integer, or set it with a pointer to a menu item. The set routines return non-zero if the new value is different than the old one. Changing it causes a redraw().

int Fl_Widget::changed() const;
void Fl_Widget::set_changed();
void Fl_Widget::clear_changed();

This value is true if the user picks a different value. It is turned off by value(x) and just before doing a callback (the callback can turn it back on if desired).

Fl_When Fl_Widget::when() const;
void Fl_Widget::when(Fl_When);

Controls when callbacks are done. The following values are useful, the default value is FL_WHEN_RELEASE:

(back to contents)