Browse Source

Adding the FL_MENU_CHATTY flag to Fl_Menu_Item.

If set, menu items will also call the callback when highlighting changes.
The reason is given with Fl::callback_reason(). #941
pull/1246/head
Matthias Melcher 2 months ago
parent
commit
f4978a0149
  1. 28
      FL/Fl_Menu_Item.H
  2. 2
      src/Fl_MacOS_Sys_Menu_Bar.mm
  3. 21
      src/Fl_Menu.cxx
  4. 7
      src/Fl_Menu_.cxx
  5. 16
      test/menubar.cxx

28
FL/Fl_Menu_Item.H

@ -34,7 +34,8 @@ enum { // values for flags: @@ -34,7 +34,8 @@ enum { // values for flags:
FL_SUBMENU_POINTER = 0x20, ///< Indicates user_data() is a pointer to another menu array
FL_SUBMENU = 0x40, ///< Item is a submenu to other items
FL_MENU_DIVIDER = 0x80, ///< Creates divider line below this item. Also ends a group of radio buttons
FL_MENU_HORIZONTAL = 0x100 ///< ??? -- reserved, internal (do not use)
FL_MENU_HORIZONTAL = 0x100, ///< reserved, do not use
FL_MENU_CHATTY = 0x200 ///< Menu Item receives additional callbacks
///< Note: \b ALL other bits in \p flags are reserved: do not use them for your own purposes!
};
@ -67,7 +68,8 @@ class Fl_Menu_; @@ -67,7 +68,8 @@ class Fl_Menu_;
FL_SUBMENU_POINTER = 0x20, // Indicates user_data() is a pointer to another menu array
FL_SUBMENU = 0x40, // This item is a submenu to other items
FL_MENU_DIVIDER = 0x80, // Creates divider line below this item. Also ends a group of radio buttons.
FL_MENU_HORIZONTAL = 0x100 // ??? -- reserved, internal (do not use)
FL_MENU_HORIZONTAL = 0x100 // reserved, do not use
FL_MENU_CHATTY = 0x200 ///< Menu Item receives additional callbacks
};
\endcode
@ -120,6 +122,16 @@ class Fl_Menu_; @@ -120,6 +122,16 @@ class Fl_Menu_;
variants copies the entire menu to internal storage. Using the
memory of a static menu array after that would access unused (but not
released) memory and thus have no effect.
When a menu item is selected by the user and a callback is set, the callback
will be called with FL_REASON_SELECTED. The Fl_Widget pointer is set to the
widget that opened the menu, a copy of the menu item's user data. If no menu
item callback is set, the callback of the managing widget is called instead.
If the FL_MENU_CHATTY flag is set, the menu item callback may be called for
additional reasons. When a menu item is highlighted, the callback is called
with FL_REASON_GOT_FOCUS. If it is no longer highlighted,
FL_REASON_LOST_FOCUS is sent.
*/
struct FL_EXPORT Fl_Menu_Item {
const char *text; ///< menu item text, returned by label()
@ -490,14 +502,18 @@ struct FL_EXPORT Fl_Menu_Item { @@ -490,14 +502,18 @@ struct FL_EXPORT Fl_Menu_Item {
The callback is called with the stored user_data() as its second argument.
You must first check that callback() is non-zero before calling this.
*/
void do_callback(Fl_Widget* o) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, user_data_);}
void do_callback(Fl_Widget* o, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const {
Fl::callback_reason_ = reason; callback_(o, user_data_);
}
/**
Calls the Fl_Menu_Item item's callback, and provides the Fl_Widget argument.
This call overrides the callback's second argument with the given value \p arg.
You must first check that callback() is non-zero before calling this.
*/
void do_callback(Fl_Widget* o,void* arg) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, arg);}
void do_callback(Fl_Widget* o, void* arg, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const {
Fl::callback_reason_ = reason; callback_(o, arg);
}
/**
Calls the Fl_Menu_Item item's callback, and provides the Fl_Widget argument.
@ -506,7 +522,9 @@ struct FL_EXPORT Fl_Menu_Item { @@ -506,7 +522,9 @@ struct FL_EXPORT Fl_Menu_Item {
the callback.
You must first check that callback() is non-zero before calling this.
*/
void do_callback(Fl_Widget* o,long arg) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, (void*)(fl_intptr_t)arg);}
void do_callback(Fl_Widget* o, long arg, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const {
Fl::callback_reason_ = FL_REASON_SELECTED; callback_(o, (void*)(fl_intptr_t)arg);
}
/** Back compatibility only.
\deprecated

2
src/Fl_MacOS_Sys_Menu_Bar.mm

@ -167,7 +167,7 @@ const char *Fl_Mac_App_Menu::quit = "Quit %@"; @@ -167,7 +167,7 @@ const char *Fl_Mac_App_Menu::quit = "Quit %@";
{
fl_lock_function();
Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes];
if ( item && item->callback() ) item->do_callback(NULL);
if ( item && item->callback() ) item->do_callback(NULL, FL_REASON_SELECTED);
fl_unlock_function();
}
- (void) setKeyEquivalentModifierMask:(int)value

21
src/Fl_Menu.cxx

@ -146,6 +146,7 @@ class menuwindow : public window_with_items { @@ -146,6 +146,7 @@ class menuwindow : public window_with_items {
public:
menutitle* title;
int handle(int) FL_OVERRIDE;
void hide() override;
int itemheight; // zero == menubar
int numitems;
int selected;
@ -480,6 +481,11 @@ menuwindow::~menuwindow() { @@ -480,6 +481,11 @@ menuwindow::~menuwindow() {
delete title;
}
void menuwindow::hide() {
set_selected(-1);
window_with_items::hide();
}
void menuwindow::position(int X, int Y) {
if (title) {title->position(X, title->y()+Y-y());}
Fl_Menu_Window::position(X, Y);
@ -592,7 +598,20 @@ void menuwindow::draw() { @@ -592,7 +598,20 @@ void menuwindow::draw() {
}
void menuwindow::set_selected(int n) {
if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);}
if (n != selected) {
if ((selected!=-1) && (menu)) {
const Fl_Menu_Item *mi = menu->next(selected);
if ((mi) && (mi->callback_) && (mi->flags & FL_MENU_CHATTY))
mi->do_callback(this, FL_REASON_LOST_FOCUS);
}
selected = n;
if ((selected!=-1) && (menu)) {
const Fl_Menu_Item *mi = menu->next(selected);
if ((mi) && (mi->callback_) && (mi->flags & FL_MENU_CHATTY))
mi->do_callback(this, FL_REASON_GOT_FOCUS);
}
damage(FL_DAMAGE_CHILD);
}
}
////////////////////////////////////////////////////////////////

7
src/Fl_Menu_.cxx

@ -401,8 +401,11 @@ const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) { @@ -401,8 +401,11 @@ const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
value_ = v;
if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) {
if (changed() || when()&FL_WHEN_NOT_CHANGED) {
if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this);
else do_callback();
if (value_ && value_->callback_) {
value_->do_callback((Fl_Widget*)this, value_->user_data(), FL_REASON_SELECTED);
} else {
do_callback(FL_REASON_SELECTED);
}
}
}
}

16
test/menubar.cxx

@ -61,7 +61,19 @@ void test_cb(Fl_Widget* w, void*) { @@ -61,7 +61,19 @@ void test_cb(Fl_Widget* w, void*) {
G_tty->printf("%s\n", m->label());
}
void quit_cb(Fl_Widget*, void*) {exit(0);}
void quit_cb(Fl_Widget*, void*) {
switch (Fl::callback_reason()) {
case FL_REASON_SELECTED:
exit(0);
case FL_REASON_GOT_FOCUS:
G_tty->printf("Selecting this menu item will quit this application!\n");
break;
case FL_REASON_LOST_FOCUS:
G_tty->printf("Risk of quitting averted.\n");
break;
default: break;
}
}
Fl_Menu_Item hugemenu[100];
@ -70,7 +82,7 @@ Fl_Menu_Item menutable[] = { @@ -70,7 +82,7 @@ Fl_Menu_Item menutable[] = {
{"&File",0,0,0,FL_SUBMENU},
{"&Open", FL_ALT+'o', 0, 0, FL_MENU_INACTIVE},
{"&Close", 0, 0},
{"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER},
{"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER|FL_MENU_CHATTY},
#if (OVERRIDE_SCALING_SHORTCUTS)
{"CTRL/0", FL_COMMAND+'0', 0},

Loading…
Cancel
Save