diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2019-06-27 16:04:30 +0200 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2019-06-27 16:04:03 +0200 |
| commit | 42b8cb7bb8211117d2e4c0b64632458c6815e56b (patch) | |
| tree | 1defbe64677b90296e7468244c313885dae86403 /src | |
| parent | 44b2b7126c121d425d0856a4528db8ae5721bbbf (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')
| -rw-r--r-- | src/Fl_Menu_Button.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_Menu_add.cxx | 50 |
2 files changed, 48 insertions, 10 deletions
diff --git a/src/Fl_Menu_Button.cxx b/src/Fl_Menu_Button.cxx index 74bf62430..0a5099b2c 100644 --- a/src/Fl_Menu_Button.cxx +++ b/src/Fl_Menu_Button.cxx @@ -3,7 +3,7 @@ // // Menu button widget for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 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 @@ -46,8 +46,14 @@ void Fl_Menu_Button::draw() { and if they pick one it sets value() and does the callback or sets changed() as described above. The menu item is returned or NULL if the user dismisses the menu. + + \note Since FLTK 1.4.0 Fl_Menu_::menu_end() is called before the menu + pops up to make sure the menu array is located in private storage. + + \see Fl_Menu_::menu_end() */ const Fl_Menu_Item* Fl_Menu_Button::popup() { + menu_end(); const Fl_Menu_Item* m; pressed_menu_button_ = this; redraw(); 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$". // |
