|
|
commit 8ca1e0ca034d083c7ba5a67c7a947093c52dc44e
Author: Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Wed Apr 17 19:14:59 2024 +0200
Commit: Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Wed Apr 17 19:14:59 2024 +0200
Fix 'int Fl_Menu_::value()' if item is in a submenu (STR 3241)
More precise: ... if the last picked item is in a "detached submenu",
i.e. in one addressed by another menu item with the FL_SUBMENU_POINTER
flag set.
Also: document *why* this is the case, and what the result value is.
FL/Fl_Menu_.H | 64 +++++++++++++++++++++++++++++++++++-----------
src/Fl_Menu_.cxx | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 118 insertions(+), 23 deletions(-)
diff --git FL/Fl_Menu_.H FL/Fl_Menu_.H
index acab1a3..96e1356 100644
--- FL/Fl_Menu_.H
+++ FL/Fl_Menu_.H
@@ -1,7 +1,7 @@
//
// Menu base class header file for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2019 by Bill Spitzak and others.
+// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -151,29 +151,63 @@ public:
int clear_submenu(int index);
void replace(int,const char *);
void remove(int);
- /** Changes the shortcut of item \p i to \p s. */
+ /** Change the shortcut of item \p i to \p s. */
void shortcut(int i, int s) {menu_[i].shortcut(s);}
- /** Sets the flags of item i. For a list of the flags, see Fl_Menu_Item. */
+ /** Set the flags of item i. For a list of the flags, see Fl_Menu_Item. */
void mode(int i,int fl) {menu_[i].flags = fl;}
- /** Gets the flags of item i. For a list of the flags, see Fl_Menu_Item. */
+ /** Get the flags of item i. For a list of the flags, see Fl_Menu_Item. */
int mode(int i) const {return menu_[i].flags;}
- /** Returns a pointer to the last menu item that was picked. */
+ /** Return a pointer to the last menu item that was picked. */
const Fl_Menu_Item *mvalue() const {return value_;}
- /** Returns a pointer to the menu item that was picked before the current one was picked.
- This call gives devs additional details how a user changed a choice in the Fl_Choice widget.
- */
+
+ /** Return a pointer to the menu item that was picked before the current one was picked.
+ This call gives developers additional details how a user changed a choice in the Fl_Choice widget.
+ */
const Fl_Menu_Item *prev_mvalue() const {return prev_value_;}
- /** Returns the index into menu() of the last item chosen by the user. It is zero initially. */
- int value() const {return value_ ? (int)(value_-menu_) : -1;}
+ // Return the index into the menu() of the last item chosen by the user or -1.
+ int value() const;
+ // Set the internal value_ of the menu to the given Fl_Menu_Item.
int value(const Fl_Menu_Item*);
/**
- The value is the index into menu() 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.
+ Set the value of the menu to index \c i.
+
+ The \e value of the menu is the index into the menu() of the last
+ item chosen by the user or -1.
+
+ It is \c -1 initially (if no item has been chosen) or if the chosen
+ menu item is part of a submenu addressed by an FL_SUBMENU_POINTER.
+
+ \note All menu items are located in a contiguous array of Fl_Menu_Item's
+ unless an item has the FL_SUBMENU_POINTER flag which redirects the
+ submenu to an independent submenu array. This submenu array is not
+ counted in the size() of the menu, and menu items in this submenu can't
+ return a valid index into the \b main menu. Therefore menu items that
+ are located in such a submenu return -1 when value() is called.
+ This may be changed in a future version.
+
+ You can set the value as an integer or with a pointer to a menu item.
+ The integer value is restricted to the main menu array (0..size()-1)
+ whereas the menu item can be any menu item, even one in a detached
+ submenu (see note about FL_SUBMENU_POINTER above).
+
+ \param[in] i Index of the menu item in the main menu array.\n
+ Values outside 0..size()-1 are ignored (return 0).
+
+ \return Whether the new value is different than the old one.
+ \retval 0 The value didn't change.
+ \retval 1 The value was changed.
+
+ \see int value(const Fl_Menu_Item*)
+ \see int value()
+ \see const Fl_Menu_Item *mvalue()
*/
- int value(int i) {return value(menu_+i);}
+ int value(int i) {
+ if (!menu_ || i < 0 || i >= size())
+ return 0;
+ return value(menu_ + i);
+ }
+
/** Returns the title of the last item chosen. */
const char *text() const {return value_ ? value_->text : 0;}
/** Returns the title of item i. */
diff --git src/Fl_Menu_.cxx src/Fl_Menu_.cxx
index 73998ba..b935fb3 100644
--- src/Fl_Menu_.cxx
+++ src/Fl_Menu_.cxx
@@ -1,7 +1,7 @@
//
// Common menu code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2016 by Bill Spitzak and others.
+// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -301,10 +301,34 @@ const Fl_Menu_Item* Fl_Menu_::find_item_with_argument(long v) {
}
/**
- The value is the index into menu() 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.
+ Set the value of a menu to the menu item \c m.
+
+ The \e value of the menu is the index into the menu() of the last
+ item chosen by the user or -1.
+
+ It is \c -1 initially (if no item has been chosen) or if the chosen
+ menu item is part of a submenu addressed by an FL_SUBMENU_POINTER.
+
+ \note All menu items are located in a contiguous array of Fl_Menu_Item's
+ unless an item has the FL_SUBMENU_POINTER flag which redirects the
+ submenu to an independent submenu array. This submenu array is not
+ counted in the size() of the menu, and menu items in this submenu can't
+ return a valid index into the \b main menu. Therefore menu items that
+ are located in such a submenu return -1 when value() is called.
+ This may be changed in a future version.
+
+ The menu item can be any menu item, even one in a detached submenu
+ (see note about FL_SUBMENU_POINTER above).
+
+ \param[in] m Pointer to any menu item.
+
+ \return Whether the new value is different than the old one.
+ \retval 0 The value didn't change.
+ \retval 1 The value was changed.
+
+ \see int value(int)
+ \see int value()
+ \see const Fl_Menu_Item *mvalue()
*/
int Fl_Menu_::value(const Fl_Menu_Item* m) {
clear_changed();
@@ -316,10 +340,47 @@ int Fl_Menu_::value(const Fl_Menu_Item* m) {
return 0;
}
+/** Return the index into the menu() of the last item chosen by the user.
+
+ The \e value of the menu is the index into the menu() of the last
+ item chosen by the user or -1.
+
+ It is \c -1 initially (if no item has been chosen) or if the chosen
+ menu item is part of a submenu addressed by an FL_SUBMENU_POINTER.
+
+ \note All menu items are located in a contiguous array of Fl_Menu_Item's
+ unless an item has the FL_SUBMENU_POINTER flag which redirects the
+ submenu to an independent submenu array. This submenu array is not
+ counted in the size() of the menu, and menu items in this submenu can't
+ return a valid index into the \b main menu. Therefore menu items that
+ are located in such a submenu return -1 when value() is called.
+ This may be changed in a future version.
+
+ You can use mvalue() instead to retrieve the last picked menu item directly.
+
+ \returns Index of the last chosen menu item or -1 (see description).
+
+ \see const Fl_Menu_Item *mvalue()
+*/
+int Fl_Menu_::value() const {
+ if (!value_)
+ return -1;
+ if (menu() && value_ >= menu() && value_ < menu() + size())
+ return (int)(value_ - menu_);
+ return -1;
+}
+
/**
- When user picks a menu item, call this. It will do the callback.
- Unfortunately this also casts away const for the checkboxes, but this
- was necessary so non-checkbox menus can really be declared const...
+ When user picks a menu item, call this.
+
+ It will do the callback.
+
+ Unfortunately this also casts away const for the checkboxes, but this
+ was necessary so non-checkbox menus can really be declared 'const'.
+
+ \param[in] v The menu item that was picked by the user.
+
+ \returns The same Fl_Menu_Item* that was set (\c v).
*/
const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
if (v) {
[ Direct Link to Message ] | |
|
| |