فهرست منبع

Free submenu children when clearing PopupMenu

kobewi 2 سال پیش
والد
کامیت
df24882f9a

+ 2 - 1
doc/classes/PopupMenu.xml

@@ -192,8 +192,9 @@
 		</method>
 		<method name="clear">
 			<return type="void" />
+			<param index="0" name="free_submenus" type="bool" default="false" />
 			<description>
-				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.
 			</description>
 		</method>
 		<method name="get_focused_item" qualifiers="const">

+ 7 - 0
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.

+ 7 - 2
scene/gui/popup_menu.compat.inc

@@ -31,16 +31,21 @@
 #ifndef DISABLE_DEPRECATED
 
 void PopupMenu::_add_shortcut_bind_compat_36493(const Ref<Shortcut> &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<Texture2D> &p_icon, const Ref<Shortcut> &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

+ 13 - 5
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);

+ 2 - 1
scene/gui/popup_menu.h

@@ -202,6 +202,7 @@ protected:
 #ifndef DISABLE_DEPRECATED
 	void _add_shortcut_bind_compat_36493(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
 	void _add_icon_shortcut_bind_compat_36493(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &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;