From 53b40f4138e70e443cbaf706cca98786208014ec Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Mon, 7 Mar 2022 18:23:53 +0100 Subject: [PATCH] Improve documentation on Fl_Menu_Item's and related methods (#332) See discussion on GitHub Issue #332. Summary: don't change FLTK code but document what to do and not to do. --- FL/Fl_Menu_Button.H | 16 ++++++++-------- FL/Fl_Menu_Item.H | 46 +++++++++++++++++++++++++-------------------- src/Fl_Menu_add.cxx | 29 +++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/FL/Fl_Menu_Button.H b/FL/Fl_Menu_Button.H index b592dbb19..947f849bb 100644 --- a/FL/Fl_Menu_Button.H +++ b/FL/Fl_Menu_Button.H @@ -1,7 +1,7 @@ // // Menu button header file for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2022 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 @@ -44,14 +44,14 @@ When the user clicks a menu item, value() is set to that item and then: - - The item's callback is done if one has been set; the - Fl_Menu_Button is passed as the Fl_Widget* argument, - along with any userdata configured for the callback. + - The item's callback is done if one has been set; the + Fl_Menu_Button is passed as the Fl_Widget* argument, + along with any userdata configured for the callback. - - If the item does not have a callback, the Fl_Menu_Button's callback - is done instead, along with any userdata configured for it. - The callback can determine which item was picked using - value(), mvalue(), item_pathname(), etc. + - If the item does not have a callback, the Fl_Menu_Button's callback + is done instead, along with any userdata configured for it. + The callback can determine which item was picked using + value(), mvalue(), item_pathname(), etc. */ class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ { protected: diff --git a/FL/Fl_Menu_Item.H b/FL/Fl_Menu_Item.H index d67d4ed3f..23441aae5 100644 --- a/FL/Fl_Menu_Item.H +++ b/FL/Fl_Menu_Item.H @@ -1,7 +1,7 @@ // // Menu item header file for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2020 by Bill Spitzak and others. +// Copyright 1998-2022 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 @@ -25,15 +25,16 @@ /// @file enum { // values for flags: - FL_MENU_INACTIVE = 1, ///< Deactivate menu item (gray out) - FL_MENU_TOGGLE = 2, ///< Item is a checkbox toggle (shows checkbox for on/off state) - FL_MENU_VALUE = 4, ///< The on/off state for checkbox/radio buttons (if set, state is 'on') - FL_MENU_RADIO = 8, ///< Item is a radio button (one checkbox of many can be on) - FL_MENU_INVISIBLE = 0x10, ///< Item will not show up (shortcut will work) - 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 + FL_MENU_INACTIVE = 1, ///< Deactivate menu item (gray out) + FL_MENU_TOGGLE = 2, ///< Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, ///< The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, ///< Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, ///< Item will not show up (shortcut will work) + 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_RESERVED = 0xffffff00 ///< These bits are reserved for internal or future usage (do not use) }; extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); @@ -57,15 +58,16 @@ class Fl_Menu_; }; enum { // values for flags: - FL_MENU_INACTIVE = 1, // Deactivate menu item (gray out) - FL_MENU_TOGGLE = 2, // Item is a checkbox toggle (shows checkbox for on/off state) - FL_MENU_VALUE = 4, // The on/off state for checkbox/radio buttons (if set, state is 'on') - FL_MENU_RADIO = 8, // Item is a radio button (one checkbox of many can be on) - FL_MENU_INVISIBLE = 0x10, // Item will not show up (shortcut will work) - 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 + FL_MENU_INACTIVE = 1, // Deactivate menu item (gray out) + FL_MENU_TOGGLE = 2, // Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, // The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, // Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, // Item will not show up (shortcut will work) + 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_RESERVED = 0xffffff00 // These bits are reserved for internal or future usage (do not use) }; \endcode Typically menu items are statically defined; for example: @@ -103,6 +105,11 @@ class Fl_Menu_; You should use the method functions to access structure members and not access them directly to avoid compatibility problems with future releases of FLTK. + + \note Adding menu items with insert(), add(), or any of its overloaded + 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. */ struct FL_EXPORT Fl_Menu_Item { const char *text; ///< menu item text, returned by label() @@ -233,7 +240,6 @@ struct FL_EXPORT Fl_Menu_Item { /** Sets the menu item's callback function and userdata() argument. - This method does not set the userdata() argument. The argument \p is cast to void* and stored as the userdata() for the menu item's callback function. \see Fl_Callback_p Fl_MenuItem::callback() const diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx index cd6bde434..803e40f49 100644 --- a/src/Fl_Menu_add.cxx +++ b/src/Fl_Menu_add.cxx @@ -1,7 +1,7 @@ // // Menu utilities for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2019 by Bill Spitzak and others. +// Copyright 1998-2022 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 @@ -235,6 +235,21 @@ int Fl_Menu_Item::insert( \par A menu item's callback must not add() items to its parent menu during the callback. + Due to backwards compatibility and historical restrictions we recommend to use + either + - static menu arrays that are not extended during runtime or + - dynamic, extendable menu item arrays that are entirely created by using + add() or insert(). + + This ensures that all menu arrays and strings are copied to internal storage + and released when required. + + \note If you create menus from static Fl_Menu_Item arrays and add() or insert() + more menu items later, then the menu array is copied to local storage but + some local (static) strings may appear to "leak memory". This is a known + issue and discouraged usage (see description above) but the impact on + memory usage should typically be small. + Detailed Description of Parameters \par label The menu item's label. This argument is required and must not be NULL. @@ -316,12 +331,16 @@ int Fl_Menu_Item::insert( FL_SUBMENU // This item is a submenu to other items FL_MENU_DIVIDER // Creates divider line below this item. Also ends a group of radio buttons. \endcode + \par + All other bits in \p 'flags' are reserved and must not be used. If FL_SUBMENU is set in an item's flags, then actually two items are added: - the first item is the menu item (submenu title), as expected, and the second - item is the submenu terminating item with the label and all other members - set to 0. If you add submenus with the 'path' technique, then the - corresponding submenu terminators (maybe more than one) are added as well. + - the first item is the menu item (submenu title), as expected, and + - the second item is the submenu terminating item with the label and all + other members set to 0. + + If you add submenus with the 'path' technique, then the corresponding submenu + terminators (maybe more than one) are added as well. \todo Raw integer shortcut needs examples. Dependent on responses to https://www.fltk.org/newsgroups.php?gfltk.coredev+v:10086 and results of STR#2344