summaryrefslogtreecommitdiff
path: root/src/Fl_Menu_add.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2019-06-27 16:04:30 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2019-06-27 16:04:03 +0200
commit42b8cb7bb8211117d2e4c0b64632458c6815e56b (patch)
tree1defbe64677b90296e7468244c313885dae86403 /src/Fl_Menu_add.cxx
parent44b2b7126c121d425d0856a4528db8ae5721bbbf (diff)
Add method Fl_Menu_::menu_end() (STR 3523)
This method can be called after all menu modifications to make sure the menu() array is relocated (copied from the internal working area) to a private place owned by the Fl_Menu_ instance. menu_end() is now called in Fl_Menu_Button::popup() to make sure the menu array is in private storage. This fixes STR 3523 w/o user code changes. Calling menu_end() is in most cases optional. Todo: call menu_end() where useful (or necessary), e.g. in Fl_Choice, Fl_Menu_Bar, etc. ?
Diffstat (limited to 'src/Fl_Menu_add.cxx')
-rw-r--r--src/Fl_Menu_add.cxx50
1 files changed, 41 insertions, 9 deletions
diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx
index 57534f4e3..d29d75a42 100644
--- a/src/Fl_Menu_add.cxx
+++ b/src/Fl_Menu_add.cxx
@@ -3,7 +3,7 @@
//
// Menu utilities for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2016 by Bill Spitzak and others.
+// Copyright 1998-2019 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,7 +44,6 @@ extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx
// widget, and if so it reallocates as necessary.
-
// Insert a single Fl_Menu_Item into an array of size at offset n,
// if this is local_array it will be reallocated if needed.
static Fl_Menu_Item* array_insert(
@@ -376,13 +375,7 @@ int Fl_Menu_::insert(
// make this widget own the local array:
if (this != fl_menu_array_owner) {
if (fl_menu_array_owner) {
- Fl_Menu_* o = fl_menu_array_owner;
- // the previous owner gets its own correctly-sized array:
- int value_offset = (int) (o->value_-local_array);
- int n = local_array_size;
- Fl_Menu_Item* newMenu = o->menu_ = new Fl_Menu_Item[n];
- memcpy(newMenu, local_array, n*sizeof(Fl_Menu_Item));
- if (o->value_) o->value_ = newMenu+value_offset;
+ fl_menu_array_owner->menu_end();
}
if (menu_) {
// this already has a menu array, use it as the local one:
@@ -495,6 +488,45 @@ void Fl_Menu_::remove(int i) {
memmove(item, next_item, (menu_+n-next_item)*sizeof(Fl_Menu_Item));
}
+/**
+ Finishes menu modifications and returns menu().
+
+ Call menu_end() after using add(), insert(), remove(), or any other
+ methods that may change the menu array if you want to access the
+ menu array anytime later with menu(). This should be called only
+ once after the \b last menu modification for performance reasons.
+
+ Does nothing if the menu array is already in a private location.
+
+ Some methods like Fl_Menu_Button::popup() call this method before
+ their menu is opened.
+
+ \note After menu changes like add(), insert(), etc. menu() would
+ return a pointer to a temporary internal menu array that may be
+ relocated at unexpected times. This is due to performance
+ considerations and may be changed w/o further notice.
+
+ \since 1.4.0
+
+ \returns New Fl_Menu_Item array pointer.
+
+ \see Fl_Menu_::menu()
+*/
+
+const Fl_Menu_Item *Fl_Menu_::menu_end() {
+ if (menu_ == local_array && fl_menu_array_owner == this) {
+ // copy the menu array to a private correctly-sized array:
+ int value_offset = (int)(value_ - local_array);
+ int n = local_array_size;
+ Fl_Menu_Item* newMenu = menu_ = new Fl_Menu_Item[n];
+ memcpy(newMenu, local_array, n * sizeof(Fl_Menu_Item));
+ if (value_)
+ value_ = newMenu + value_offset;
+ }
+ fl_menu_array_owner = 0;
+ return menu_;
+}
+
//
// End of "$Id$".
//