From 866c50a9260be4f92f6131384c9cfccabb8df7a7 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 21 Sep 2024 20:16:45 +0200 Subject: [PATCH] Add submenu support to EditorContextMenuPlugin --- doc/classes/EditorContextMenuPlugin.xml | 18 +++++++++++++++ editor/plugins/editor_context_menu_plugin.cpp | 22 ++++++++++++++++--- editor/plugins/editor_context_menu_plugin.h | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/doc/classes/EditorContextMenuPlugin.xml b/doc/classes/EditorContextMenuPlugin.xml index 71c4ca0f9b9..fb90a2a5cd6 100644 --- a/doc/classes/EditorContextMenuPlugin.xml +++ b/doc/classes/EditorContextMenuPlugin.xml @@ -47,6 +47,24 @@ [/codeblock] + + + + + + + Add a submenu to the context menu of the plugin's specified slot. The submenu is not automatically handled, you need to connect to its signals yourself. Also the submenu is freed on every popup, so provide a new [PopupMenu] every time. + [codeblock] + func _popup_menu(paths): + var popup_menu = PopupMenu.new() + popup_menu.add_item("Blue") + popup_menu.add_item("White") + popup_menu.id_pressed.connect(_on_color_submenu_option) + + add_context_menu_item("Set Node Color", popup_menu) + [/codeblock] + + diff --git a/editor/plugins/editor_context_menu_plugin.cpp b/editor/plugins/editor_context_menu_plugin.cpp index 0648327faba..b635816bd97 100644 --- a/editor/plugins/editor_context_menu_plugin.cpp +++ b/editor/plugins/editor_context_menu_plugin.cpp @@ -67,10 +67,21 @@ void EditorContextMenuPlugin::add_context_menu_item_from_shortcut(const String & context_menu_items.insert(p_name, item); } +void EditorContextMenuPlugin::add_context_submenu_item(const String &p_name, PopupMenu *p_menu, const Ref &p_texture) { + ERR_FAIL_NULL(p_menu); + + ContextMenuItem item; + item.item_name = p_name; + item.icon = p_texture; + item.submenu = p_menu; + context_menu_items.insert(p_name, item); +} + void EditorContextMenuPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("add_menu_shortcut", "shortcut", "callback"), &EditorContextMenuPlugin::add_menu_shortcut); ClassDB::bind_method(D_METHOD("add_context_menu_item", "name", "callback", "icon"), &EditorContextMenuPlugin::add_context_menu_item, DEFVAL(Ref())); ClassDB::bind_method(D_METHOD("add_context_menu_item_from_shortcut", "name", "shortcut", "icon"), &EditorContextMenuPlugin::add_context_menu_item_from_shortcut, DEFVAL(Ref())); + ClassDB::bind_method(D_METHOD("add_context_submenu_item", "name", "menu", "icon"), &EditorContextMenuPlugin::add_context_submenu_item, DEFVAL(Ref())); GDVIRTUAL_BIND(_popup_menu, "paths"); @@ -117,12 +128,17 @@ void EditorContextMenuPluginManager::add_options_from_plugins(PopupMenu *p_popup EditorContextMenuPlugin::ContextMenuItem &item = E.value; item.id = id; - if (item.icon.is_valid()) { - p_popup->add_icon_item(item.icon, item.item_name, id); - p_popup->set_item_icon_max_width(-1, icon_size); + if (item.submenu) { + p_popup->add_submenu_node_item(item.item_name, item.submenu, id); } else { p_popup->add_item(item.item_name, id); } + + if (item.icon.is_valid()) { + p_popup->set_item_icon(-1, item.icon); + p_popup->set_item_icon_max_width(-1, icon_size); + } + if (item.shortcut.is_valid()) { p_popup->set_item_shortcut(-1, item.shortcut, true); } diff --git a/editor/plugins/editor_context_menu_plugin.h b/editor/plugins/editor_context_menu_plugin.h index 0232d254ba5..86c67dedda1 100644 --- a/editor/plugins/editor_context_menu_plugin.h +++ b/editor/plugins/editor_context_menu_plugin.h @@ -65,6 +65,7 @@ public: Callable callable; Ref icon; Ref shortcut; + PopupMenu *submenu = nullptr; }; HashMap context_menu_items; HashMap, Callable> context_menu_shortcuts; @@ -80,6 +81,7 @@ public: void add_menu_shortcut(const Ref &p_shortcut, const Callable &p_callable); void add_context_menu_item(const String &p_name, const Callable &p_callable, const Ref &p_texture); void add_context_menu_item_from_shortcut(const String &p_name, const Ref &p_shortcut, const Ref &p_texture); + void add_context_submenu_item(const String &p_name, PopupMenu *p_menu, const Ref &p_texture); }; VARIANT_ENUM_CAST(EditorContextMenuPlugin::ContextMenuSlot);