FLTK logo

[master] 8ca1e0c - Fix 'int Fl_Menu_::value()' if item is in a submenu (STR 3241)

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 8ca1e0c - Fix 'int Fl_Menu_::value()' if item is in a submenu (STR 3241) "Albrecht Schlosser" 10:17 Apr 17  
 
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 ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.