Browse Source

Adding `FL_BEFORE_MENU` event to classes derived from `Fl_Menu_`

pull/1240/head
Matthias Melcher 2 months ago
parent
commit
5dd1062df5
  1. 6
      FL/Enumerations.H
  2. 4
      FL/Fl_Choice.H
  3. 4
      FL/Fl_Menu_Bar.H
  4. 4
      FL/Fl_Menu_Button.H
  5. 2
      FL/Fl_Tooltip.H
  6. 7
      FL/names.h
  7. 2
      src/Fl_Choice.cxx
  8. 5
      src/Fl_Input_Choice.cxx
  9. 2
      src/Fl_Menu_Bar.cxx
  10. 1
      src/Fl_Menu_Button.cxx
  11. 14
      src/Fl_Tooltip.cxx
  12. 2
      test/color_chooser.cxx
  13. 29
      test/menubar.cxx

6
FL/Enumerations.H

@ -418,7 +418,11 @@ enum Fl_Event { // events @@ -418,7 +418,11 @@ enum Fl_Event { // events
/** A tooltip is about to pop up for this widget. The mouse coordinates are
available in Fl::event_x() and Fl::event_y(). Change the widget tooltip
as needed. */
FL_TOOLTIP_EVENT = 28
FL_BEFORE_TOOLTIP = 28,
/** Triggered just before a menu is displayed. Widgets derived from Fl_Menu_
receive this event right before the menu appears, providing an opportunity
to update menu item states and activation. */
FL_BEFORE_MENU = 29
// DEV NOTE: Keep this list in sync with FL/names.h
};

4
FL/Fl_Choice.H

@ -100,6 +100,10 @@ @@ -100,6 +100,10 @@
}
\endcode
FLTK triggers an `FL_BEFORE_MENU` event for this widget right before
displaying the menu. This event provides an opportunity to update menu
item states and activation. See `test/menubar.cxx`, class `Dynamic_Choice`
"Flip" and "Flop" for a usage example.
*/
class FL_EXPORT Fl_Choice : public Fl_Menu_ {
protected:

4
FL/Fl_Menu_Bar.H

@ -61,6 +61,10 @@ @@ -61,6 +61,10 @@
Typing the shortcut() of any of the menu items will cause
callbacks exactly the same as when you pick the item with the mouse.
FLTK triggers an `FL_BEFORE_MENU` event for this widget right before
displaying the menu. This event provides an opportunity to update menu
item states and activation.
*/
class FL_EXPORT Fl_Menu_Bar : public Fl_Menu_ {
friend class Fl_Sys_Menu_Bar_Driver;

4
FL/Fl_Menu_Button.H

@ -52,6 +52,10 @@ @@ -52,6 +52,10 @@
is done instead, along with any userdata configured for it.
The callback can determine which item was picked using
value(), mvalue(), item_pathname(), etc.
FLTK triggers an `FL_BEFORE_MENU` event for this widget right before
displaying the menu. This event provides an opportunity to update menu
item states and activation.
*/
class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ {
protected:

2
FL/Fl_Tooltip.H

@ -95,7 +95,7 @@ public: @@ -95,7 +95,7 @@ public:
static void wrap_width(int v) { wrap_width_ = v; }
/** Returns the window that is used for tooltips */
static Fl_Window* current_window(void);
/** \brief Temporarily Override Tooltip Text during an FL_TOOLTIP_EVENT. */
/** \brief Temporarily Override Tooltip Text during an FL_BEFORE_TOOLTIP event. */
static int override_text(const char *new_text);
// These should not be public, but Fl_Widget::tooltip() needs them...

7
FL/names.h

@ -73,10 +73,11 @@ const char * const fl_eventnames[] = @@ -73,10 +73,11 @@ const char * const fl_eventnames[] =
"FL_FULLSCREEN",
"FL_ZOOM_GESTURE",
"FL_ZOOM_EVENT",
"FL_TOOLTIP_EVENT",
"FL_EVENT_29", // not yet defined, just in case it /will/ be defined ...
"FL_BEFORE_TOOLTIP",
"FL_BEFORE_MENU",
"FL_EVENT_30", // not yet defined, just in case it /will/ be defined ...
"FL_EVENT_31" // not yet defined, just in case it /will/ be defined ...
"FL_EVENT_31", // not yet defined, just in case it /will/ be defined ...
"FL_EVENT_32" // not yet defined, just in case it /will/ be defined ...
};
/**

2
src/Fl_Choice.cxx

@ -195,6 +195,7 @@ int Fl_Choice::handle(int e) { @@ -195,6 +195,7 @@ int Fl_Choice::handle(int e) {
J1:
if (Fl::scheme()
|| fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) != textcolor()) {
handle(FL_BEFORE_MENU);
v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this);
if (wp.deleted()) return 1;
} else {
@ -202,6 +203,7 @@ int Fl_Choice::handle(int e) { @@ -202,6 +203,7 @@ int Fl_Choice::handle(int e) {
// temporarily override the color() of this widget...
Fl_Color c = color();
color(FL_BACKGROUND2_COLOR);
handle(FL_BEFORE_MENU);
v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this);
if (wp.deleted()) return 1;
color(c);

5
src/Fl_Input_Choice.cxx

@ -54,6 +54,10 @@ @@ -54,6 +54,10 @@
- 1: the user picked a different item in the choice menu
- 0: the user typed or pasted directly into the input field
FLTK triggers an `FL_BEFORE_MENU` event for this widget right before
displaying the menu. This event provides an opportunity to update menu
item states and activation.
\par Example Use of Fl_Input_Choice
\code
#include <stdio.h>
@ -152,6 +156,7 @@ void Fl_Input_Choice::InputMenuButton::draw() { @@ -152,6 +156,7 @@ void Fl_Input_Choice::InputMenuButton::draw() {
// Make pulldown menu appear under entire width of widget
const Fl_Menu_Item* Fl_Input_Choice::InputMenuButton::popup() {
handle(FL_BEFORE_MENU);
menu_end();
redraw();
Fl_Widget_Tracker mb(this);

2
src/Fl_Menu_Bar.cxx

@ -49,6 +49,7 @@ int Fl_Menu_Bar::handle(int event) { @@ -49,6 +49,7 @@ int Fl_Menu_Bar::handle(int event) {
case FL_PUSH:
v = 0;
J1:
handle(FL_BEFORE_MENU);
v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
picked(v);
return 1;
@ -71,6 +72,7 @@ Fl_Menu_Bar::Fl_Menu_Bar(int X, int Y, int W, int H,const char *l) @@ -71,6 +72,7 @@ Fl_Menu_Bar::Fl_Menu_Bar(int X, int Y, int W, int H,const char *l)
void Fl_Menu_Bar::play_menu(const Fl_Menu_Item *v) {
if (v) {
handle(FL_BEFORE_MENU);
v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
picked(v);
}

1
src/Fl_Menu_Button.cxx

@ -59,6 +59,7 @@ void Fl_Menu_Button::draw() { @@ -59,6 +59,7 @@ void Fl_Menu_Button::draw() {
\see Fl_Menu_::menu_end()
*/
const Fl_Menu_Item* Fl_Menu_Button::popup() {
handle(FL_BEFORE_MENU);
menu_end();
const Fl_Menu_Item* m;
pressed_menu_button_ = this;

14
src/Fl_Tooltip.cxx

@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
#include <stdio.h>
#define DEBUG
// #define DEBUG
float Fl_Tooltip::delay_ = 1.0f;
float Fl_Tooltip::hidedelay_ = 12.0f;
@ -161,16 +161,16 @@ static void tooltip_hide_timeout(void*) { @@ -161,16 +161,16 @@ static void tooltip_hide_timeout(void*) {
/**
Use this method to temporarily change the tooltip text before it is displayed.
When FLTK sends an FL_TOOLTIP_EVENT to the widget under the mouse pointer,
you can handle this event to modify the tooltip text dynamically. The
provided text will be copied into a local buffer. To apply the override,
When FLTK sends an FL_BEFORE_TOOLTIP event to the widget under the mouse
pointer, you can handle this event to modify the tooltip text dynamically.
The provided text will be copied into a local buffer. To apply the override,
the event handler must return 1.
To disable the tooltip for the current event, set the override text to nullptr
or an empty string ("") and return 1.
\param[in] new_text a C string that will be copied into a buffer
\return always 1, so this call can finish the FL_TOOLTIP_EVENT handling.
\return always 1, so this call can finish the FL_BEFORE_TOOLTIP event handling.
\see void Fl_Widget::tooltip(const char *text).
@ -198,7 +198,7 @@ void Fl_Tooltip::tooltip_timeout_(void*) { @@ -198,7 +198,7 @@ void Fl_Tooltip::tooltip_timeout_(void*) {
recursion = 1;
if (!top_win_iconified_()) { // no tooltip if top win iconified (STR #3157)
if (Fl_Tooltip::current()) {
if (Fl_Tooltip::current()->handle(FL_TOOLTIP_EVENT))
if (Fl_Tooltip::current()->handle(FL_BEFORE_TOOLTIP))
tip = Fl_Tooltip::override_text_;
}
if (!tip || !*tip) {
@ -394,7 +394,7 @@ void Fl_Tooltip::set_enter_exit_once_() { @@ -394,7 +394,7 @@ void Fl_Tooltip::set_enter_exit_once_() {
the childs tooltip to an empty string ("").
Tooltips can be updated dynamically before they are displayed. When a tooltip
is about to be shown, FLTK sends an `FL_TOOLTIP_EVENT` to the widgets
is about to be shown, FLTK sends an `FL_BEFORE_TOOLTIP` event to the widgets
`handle()` method. Developers can override the tooltip text temporarily
using `Fl_Tooltip::override_text(const char* new_text)` and returning 1 from
`handle()` to apply the change.

2
test/color_chooser.cxx

@ -90,7 +90,7 @@ public: @@ -90,7 +90,7 @@ public:
Image_Box(int x, int y, int w, int h, const char *label = nullptr)
: Fl_Box(x, y, w, h, label) { }
int handle(int event) {
if (event == FL_TOOLTIP_EVENT) {
if (event == FL_BEFORE_TOOLTIP) {
const char *color_name_lut[] = { "blue", "green", "black", "red" };
int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2);
char buf[80];

29
test/menubar.cxx

@ -236,6 +236,30 @@ void about_cb(Fl_Widget*, void*) { @@ -236,6 +236,30 @@ void about_cb(Fl_Widget*, void*) {
fl_message("The menubar test app.");
}
class Dynamic_Choice: public Fl_Choice {
public:
Dynamic_Choice(int x, int y, int w, int h, const char *label=nullptr)
: Fl_Choice(x, y, w, h, label) { }
int handle(int event) {
static int flip_flop = 0;
if (event == FL_BEFORE_MENU) {
// The following line is legal because we used `copy()` to create a
// writable copy of the menu array when creating this Choice.
Fl_Menu_Item *mi = const_cast<Fl_Menu_Item*>(menu());
if (flip_flop == 1) {
mi[7].flags |= FL_MENU_INACTIVE;
mi[8].flags &= ~FL_MENU_INACTIVE;
flip_flop = 0;
} else {
mi[7].flags &= ~FL_MENU_INACTIVE;
mi[8].flags |= FL_MENU_INACTIVE;
flip_flop = 1;
}
}
return Fl_Choice::handle(event);
}
};
int main(int argc, char **argv) {
for (int i=0; i<99; i++) {
char buf[100];
@ -256,7 +280,10 @@ int main(int argc, char **argv) { @@ -256,7 +280,10 @@ int main(int argc, char **argv) {
mb1.tooltip("this is a menu button");
mb1.callback(test_cb);
menus[1] = &mb1;
Fl_Choice ch(300,100,80,25,"&choice:"); ch.menu(pulldown);
Dynamic_Choice ch(300,100,80,25,"&choice:");
ch.copy(pulldown);
ch.add("Flip");
ch.add("Flop");
ch.tooltip("this is a choice menu");
ch.callback(test_cb);
menus[2] = &ch;

Loading…
Cancel
Save