From df24882f9a66d8400a05b6dbe26cad1328376e58 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 27 Jul 2023 19:50:31 +0200 Subject: [PATCH] Free submenu children when clearing PopupMenu --- doc/classes/PopupMenu.xml | 3 ++- .../4.1-stable.expected | 7 +++++++ scene/gui/popup_menu.compat.inc | 9 +++++++-- scene/gui/popup_menu.cpp | 18 +++++++++++++----- scene/gui/popup_menu.h | 3 ++- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index c31416b823..d1c1304509 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -192,8 +192,9 @@ + - Removes all items from the [PopupMenu]. + Removes all items from the [PopupMenu]. If [param free_submenus] is [code]true[/code], the submenu nodes are automatically freed. diff --git a/misc/extension_api_validation/4.1-stable.expected b/misc/extension_api_validation/4.1-stable.expected index 19c9a28c09..13f09436df 100644 --- a/misc/extension_api_validation/4.1-stable.expected +++ b/misc/extension_api_validation/4.1-stable.expected @@ -184,3 +184,10 @@ Validate extension JSON: Error: Field 'classes/PhysicsServer3DRenderingServerHan Validate extension JSON: Error: Field 'classes/PhysicsServer3DRenderingServerHandler/methods/_set_normal/arguments/1': type changed value in new API, from "const void*" to "Vector3". Intentional compatibility breakage to be consistent with the new non-virtual set_vertex/set_normal. + + +GH-79965 +-------- +Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/PopupMenu/methods/clear': arguments + +Added optional argument. Compatibility method registered. diff --git a/scene/gui/popup_menu.compat.inc b/scene/gui/popup_menu.compat.inc index ef74a17228..012d6a1334 100644 --- a/scene/gui/popup_menu.compat.inc +++ b/scene/gui/popup_menu.compat.inc @@ -31,16 +31,21 @@ #ifndef DISABLE_DEPRECATED void PopupMenu::_add_shortcut_bind_compat_36493(const Ref &p_shortcut, int p_id, bool p_global) { - return add_shortcut(p_shortcut, p_id, p_global, false); + add_shortcut(p_shortcut, p_id, p_global, false); } void PopupMenu::_add_icon_shortcut_bind_compat_36493(const Ref &p_icon, const Ref &p_shortcut, int p_id, bool p_global) { - return add_icon_shortcut(p_icon, p_shortcut, p_id, p_global, false); + add_icon_shortcut(p_icon, p_shortcut, p_id, p_global, false); +} + +void PopupMenu::_clear_bind_compat_79965() { + clear(false); } void PopupMenu::_bind_compatibility_methods() { ClassDB::bind_compatibility_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::_add_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_compatibility_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::_add_icon_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_compatibility_method(D_METHOD("clear"), &PopupMenu::_clear_bind_compat_79965); } #endif diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index d64136a682..54fd8b8745 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1908,10 +1908,18 @@ void PopupMenu::add_separator(const String &p_text, int p_id) { _menu_changed(); } -void PopupMenu::clear() { - for (int i = 0; i < items.size(); i++) { - if (items[i].shortcut.is_valid()) { - _unref_shortcut(items[i].shortcut); +void PopupMenu::clear(bool p_free_submenus) { + for (const Item &I : items) { + if (I.shortcut.is_valid()) { + _unref_shortcut(I.shortcut); + } + + if (p_free_submenus && !I.submenu.is_empty()) { + Node *submenu = get_node_or_null(I.submenu); + if (submenu) { + remove_child(submenu); + submenu->queue_free(); + } } } items.clear(); @@ -2236,7 +2244,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_item", "index"), &PopupMenu::remove_item); ClassDB::bind_method(D_METHOD("add_separator", "label", "id"), &PopupMenu::add_separator, DEFVAL(String()), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("clear"), &PopupMenu::clear); + ClassDB::bind_method(D_METHOD("clear", "free_submenus"), &PopupMenu::clear, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_hide_on_item_selection", "enable"), &PopupMenu::set_hide_on_item_selection); ClassDB::bind_method(D_METHOD("is_hide_on_item_selection"), &PopupMenu::is_hide_on_item_selection); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 72a579b90a..f123d08400 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -202,6 +202,7 @@ protected: #ifndef DISABLE_DEPRECATED void _add_shortcut_bind_compat_36493(const Ref &p_shortcut, int p_id = -1, bool p_global = false); void _add_icon_shortcut_bind_compat_36493(const Ref &p_icon, const Ref &p_shortcut, int p_id = -1, bool p_global = false); + void _clear_bind_compat_79965(); static void _bind_compatibility_methods(); #endif @@ -296,7 +297,7 @@ public: void add_separator(const String &p_text = String(), int p_id = -1); - void clear(); + void clear(bool p_free_submenus = true); virtual String get_tooltip(const Point2 &p_pos) const;