diff options
-rw-r--r-- | doc/classes/DisplayServer.xml | 70 | ||||
-rw-r--r-- | editor/editor_node.cpp | 2 | ||||
-rw-r--r-- | editor/project_manager.cpp | 2 | ||||
-rw-r--r-- | platform/macos/SCsub | 2 | ||||
-rw-r--r-- | platform/macos/display_server_macos.h | 17 | ||||
-rw-r--r-- | platform/macos/display_server_macos.mm | 85 | ||||
-rw-r--r-- | platform/macos/godot_menu_delegate.h | 44 | ||||
-rw-r--r-- | platform/macos/godot_menu_delegate.mm | 87 | ||||
-rw-r--r-- | platform/macos/godot_menu_item.h | 4 | ||||
-rw-r--r-- | platform/macos/godot_menu_item.mm | 34 | ||||
-rw-r--r-- | scene/gui/menu_bar.cpp | 15 | ||||
-rw-r--r-- | servers/display_server.cpp | 39 | ||||
-rw-r--r-- | servers/display_server.h | 16 |
13 files changed, 331 insertions, 86 deletions
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 35a2861c54..1d225aa06e 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -148,9 +148,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -168,9 +169,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -188,9 +190,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -208,9 +211,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new radio-checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -228,9 +232,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -249,9 +254,10 @@ <param index="2" name="max_states" type="int" /> <param index="3" name="default_state" type="int" /> <param index="4" name="callback" type="Callable" /> - <param index="5" name="tag" type="Variant" default="null" /> - <param index="6" name="accelerator" type="int" enum="Key" default="0" /> - <param index="7" name="index" type="int" default="-1" /> + <param index="5" name="key_callback" type="Callable" /> + <param index="6" name="tag" type="Variant" default="null" /> + <param index="7" name="accelerator" type="int" enum="Key" default="0" /> + <param index="8" name="index" type="int" default="-1" /> <description> Adds a new item with text [param labe] to the global menu with ID [param menu_root]. Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. Each press or activate of the item will increase the state by one. The default value is defined by [param default_state]. @@ -270,9 +276,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new radio-checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -384,6 +391,15 @@ [b]Note:[/b] This method is implemented on macOS. </description> </method> + <method name="global_menu_get_item_key_callback" qualifiers="const"> + <return type="Callable" /> + <param index="0" name="menu_root" type="String" /> + <param index="1" name="idx" type="int" /> + <description> + Returns the callback of the item accelerator at index [param idx]. + [b]Note:[/b] This method is implemented on macOS. + </description> + </method> <method name="global_menu_get_item_max_states" qualifiers="const"> <return type="int" /> <param index="0" name="menu_root" type="String" /> @@ -502,7 +518,7 @@ <param index="1" name="idx" type="int" /> <param index="2" name="callback" type="Callable" /> <description> - Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed or its accelerator is activated. + Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed. [b]Note:[/b] This method is implemented on macOS. </description> </method> @@ -557,6 +573,16 @@ [b]Note:[/b] This method is implemented on macOS. </description> </method> + <method name="global_menu_set_item_key_callback"> + <return type="void" /> + <param index="0" name="menu_root" type="String" /> + <param index="1" name="idx" type="int" /> + <param index="2" name="key_callback" type="Callable" /> + <description> + Sets the callback of the item at index [param idx]. Callback is emitted when its accelerator is activated. + [b]Note:[/b] This method is implemented on macOS. + </description> + </method> <method name="global_menu_set_item_max_states"> <return type="void" /> <param index="0" name="menu_root" type="String" /> diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 877581a93b..689a13ab5c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -366,7 +366,7 @@ void EditorNode::_update_scene_tabs() { scene_tabs->add_tab(disambiguated_scene_names[i] + (unsaved ? "(*)" : ""), icon); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) { - DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), Callable(), i); } if (show_rb && editor_data.get_scene_root_script(i).is_valid()) { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 9909ab378a..ed8c7b14c8 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1321,7 +1321,7 @@ void ProjectList::update_dock_menu() { } favs_added = 0; } - DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), Callable(), i); total_added++; } } diff --git a/platform/macos/SCsub b/platform/macos/SCsub index d0856c709a..bbd461fba9 100644 --- a/platform/macos/SCsub +++ b/platform/macos/SCsub @@ -17,6 +17,8 @@ files = [ "godot_window.mm", "key_mapping_macos.mm", "godot_main_macos.mm", + "godot_menu_delegate.mm", + "godot_menu_item.mm", "dir_access_macos.mm", "tts_macos.mm", "joypad_macos.cpp", diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index a08667a259..cd457836de 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -140,6 +140,7 @@ private: int key_event_pos = 0; id tts = nullptr; + id menu_delegate = nullptr; Point2i im_selection; String im_text; @@ -227,14 +228,14 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1) override; + virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; virtual int global_menu_add_separator(const String &p_menu_root, int p_index = -1) override; virtual int global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const override; @@ -244,6 +245,7 @@ public: virtual bool global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const override; virtual bool global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const override; virtual Callable global_menu_get_item_callback(const String &p_menu_root, int p_idx) const override; + virtual Callable global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const override; virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx) const override; virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx) const override; virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const override; @@ -259,6 +261,7 @@ public: virtual void global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) override; virtual void global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) override; virtual void global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) override; + virtual void global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) override; virtual void global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) override; virtual void global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) override; virtual void global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index b06ae9f27c..c117713c2b 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -31,6 +31,7 @@ #include "display_server_macos.h" #include "godot_content_view.h" +#include "godot_menu_delegate.h" #include "godot_menu_item.h" #include "godot_window.h" #include "godot_window_delegate.h" @@ -95,6 +96,7 @@ NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) { if (!submenu.has(p_menu_root)) { NSMenu *n_menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:p_menu_root.utf8().get_data()]]; [n_menu setAutoenablesItems:NO]; + [n_menu setDelegate:menu_delegate]; submenu[p_menu_root] = n_menu; } menu = submenu[p_menu_root]; @@ -754,7 +756,7 @@ NSMenuItem *DisplayServerMacOS::_menu_add_item(const String &p_menu_root, const return nullptr; } -int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -762,6 +764,7 @@ int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const St if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = 0; @@ -772,7 +775,7 @@ int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const St return out; } -int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -780,6 +783,7 @@ int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, co if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; obj->max_states = 0; @@ -790,7 +794,7 @@ int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, co return out; } -int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -798,6 +802,7 @@ int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, con if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = 0; @@ -817,7 +822,7 @@ int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, con return out; } -int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -825,6 +830,7 @@ int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_roo if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; obj->max_states = 0; @@ -844,7 +850,7 @@ int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_roo return out; } -int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -852,6 +858,7 @@ int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_ro if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; obj->max_states = 0; @@ -862,7 +869,7 @@ int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_ro return out; } -int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -870,6 +877,7 @@ int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_me if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; obj->max_states = 0; @@ -889,30 +897,15 @@ int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_me return out; } -int DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ - NSMenu *menu = _get_menu_root(p_menu_root); int out = -1; - if (menu) { - String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); - NSMenuItem *menu_item; - int item_count = ((menu == [NSApp mainMenu]) && _has_help_menu()) ? [menu numberOfItems] - 1 : [menu numberOfItems]; - if ((menu == [NSApp mainMenu]) && (p_label == "Help" || p_label == RTR("Help"))) { - p_index = [menu numberOfItems]; - } else if (p_index < 0) { - p_index = item_count; - } else { - if (menu == [NSApp mainMenu]) { // Skip Apple menu. - p_index++; - } - p_index = CLAMP(p_index, 0, item_count); - } - menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; - out = (menu == [NSApp mainMenu]) ? p_index - 1 : p_index; - + NSMenuItem *menu_item = _menu_add_item(p_menu_root, p_label, p_accel, p_index, &out); + if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = p_max_states; @@ -1104,6 +1097,27 @@ Callable DisplayServerMacOS::global_menu_get_item_callback(const String &p_menu_ return Callable(); } +Callable DisplayServerMacOS::global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const { + _THREAD_SAFE_METHOD_ + + const NSMenu *menu = _get_menu_root(p_menu_root); + if (menu) { + ERR_FAIL_COND_V(p_idx < 0, Callable()); + if (menu == [NSApp mainMenu]) { // Skip Apple menu. + p_idx++; + } + ERR_FAIL_COND_V(p_idx >= [menu numberOfItems], Callable()); + const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; + if (menu_item) { + GodotMenuItem *obj = [menu_item representedObject]; + if (obj) { + return obj->key_callback; + } + } + } + return Callable(); +} + Variant DisplayServerMacOS::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ @@ -1401,6 +1415,25 @@ void DisplayServerMacOS::global_menu_set_item_callback(const String &p_menu_root } } +void DisplayServerMacOS::global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) { + _THREAD_SAFE_METHOD_ + + NSMenu *menu = _get_menu_root(p_menu_root); + if (menu) { + ERR_FAIL_COND(p_idx < 0); + if (menu == [NSApp mainMenu]) { // Skip Apple menu. + p_idx++; + } + ERR_FAIL_COND(p_idx >= [menu numberOfItems]); + NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; + if (menu_item) { + GodotMenuItem *obj = [menu_item representedObject]; + ERR_FAIL_COND(!obj); + obj->key_callback = p_key_callback; + } + } +} + void DisplayServerMacOS::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) { _THREAD_SAFE_METHOD_ @@ -3477,6 +3510,8 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM [main_menu setSubmenu:apple_menu forItem:menu_item]; [main_menu setAutoenablesItems:NO]; + menu_delegate = [[GodotMenuDelegate alloc] init]; + //!!!!!!!!!!!!!!!!!!!!!!!!!! //TODO - do Vulkan and OpenGL support checks, driver selection and fallback rendering_driver = p_rendering_driver; diff --git a/platform/macos/godot_menu_delegate.h b/platform/macos/godot_menu_delegate.h new file mode 100644 index 0000000000..805ac0c4a3 --- /dev/null +++ b/platform/macos/godot_menu_delegate.h @@ -0,0 +1,44 @@ +/*************************************************************************/ +/* godot_menu_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_MENU_DELEGATE_H +#define GODOT_MENU_DELEGATE_H + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotMenuDelegate : NSObject <NSMenuDelegate> { +} + +- (void)doNothing:(id)sender; + +@end + +#endif // GODOT_MENU_DELEGATE_H diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm new file mode 100644 index 0000000000..bd394d8415 --- /dev/null +++ b/platform/macos/godot_menu_delegate.mm @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* godot_menu_delegate.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_menu_delegate.h" + +#include "display_server_macos.h" +#include "godot_menu_item.h" +#include "key_mapping_macos.h" + +@implementation GodotMenuDelegate + +- (void)doNothing:(id)sender { +} + +- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action { + NSString *ev_key = [[event charactersIgnoringModifiers] lowercaseString]; + NSUInteger ev_modifiers = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; + for (int i = 0; i < [menu numberOfItems]; i++) { + const NSMenuItem *menu_item = [menu itemAtIndex:i]; + if ([menu_item isEnabled] && [[menu_item keyEquivalent] compare:ev_key] == NSOrderedSame) { + NSUInteger item_modifiers = [menu_item keyEquivalentModifierMask]; + + if (ev_modifiers == item_modifiers) { + GodotMenuItem *value = [menu_item representedObject]; + if (value->key_callback != Callable()) { + // If custom callback is set, use it. + Variant tag = value->meta; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + value->key_callback.callp((const Variant **)&tagp, 1, ret, ce); + } else { + // Otherwise redirect event to the engine. + if (DisplayServer::get_singleton()) { + DisplayServerMacOS::KeyEvent ke; + + ke.window_id = DisplayServer::MAIN_WINDOW_ID; + ke.macos_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); + ke.raw = false; + ke.unicode = 0; + + reinterpret_cast<DisplayServerMacOS *>(DisplayServer::get_singleton())->push_to_key_event_buffer(ke); + } + } + + // Suppress default menu action. + *target = self; + *action = @selector(doNothing:); + return YES; + } + } + } + return NO; +} + +@end diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index e0b9f41632..e96f5dc1cf 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -45,6 +45,7 @@ enum GlobalMenuCheckType { @interface GodotMenuItem : NSObject { @public Callable callback; + Callable key_callback; Variant meta; GlobalMenuCheckType checkable_type; int max_states; @@ -54,7 +55,4 @@ enum GlobalMenuCheckType { @end -@implementation GodotMenuItem -@end - #endif // GODOT_MENU_ITEM_H diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm new file mode 100644 index 0000000000..ea35e35d19 --- /dev/null +++ b/platform/macos/godot_menu_item.mm @@ -0,0 +1,34 @@ +/*************************************************************************/ +/* godot_menu_item.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_menu_item.h" + +@implementation GodotMenuItem +@end diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index db06fca587..788b320b46 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -149,10 +149,6 @@ void MenuBar::_open_popup(int p_index, bool p_focus_item) { void MenuBar::shortcut_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (is_native_menu()) { - return; - } - if (!_is_focus_owner_in_shortcut_context()) { return; } @@ -253,7 +249,7 @@ void MenuBar::_update_submenu(const String &p_menu_name, PopupMenu *p_child) { DisplayServer::get_singleton()->global_menu_add_submenu_item(p_menu_name, p_child->get_item_text(i), p_menu_name + "/" + itos(i)); _update_submenu(p_menu_name + "/" + itos(i), pm); } else { - int index = DisplayServer::get_singleton()->global_menu_add_item(p_menu_name, p_child->get_item_text(i), callable_mp(p_child, &PopupMenu::activate_item), i); + int index = DisplayServer::get_singleton()->global_menu_add_item(p_menu_name, p_child->get_item_text(i), callable_mp(p_child, &PopupMenu::activate_item), Callable(), i); if (p_child->is_item_checkable(i)) { DisplayServer::get_singleton()->global_menu_set_item_checkable(p_menu_name, index, true); @@ -376,6 +372,11 @@ void MenuBar::_notification(int p_what) { case NOTIFICATION_INTERNAL_PROCESS: { MutexLock lock(mutex); + if (is_native_menu()) { + // Handled by OS. + return; + } + Vector2 pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted - get_global_position(); if (pos == old_mouse_pos) { return; @@ -386,7 +387,9 @@ void MenuBar::_notification(int p_what) { if (index >= 0 && index != active_menu) { selected_menu = index; focused_menu = selected_menu; - get_menu_popup(active_menu)->hide(); + if (active_menu >= 0) { + get_menu_popup(active_menu)->hide(); + } _open_popup(index); } } break; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 22f42ca343..6f14e73f34 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -44,37 +44,37 @@ DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[Displa int DisplayServer::server_create_count = 1; -int DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } @@ -103,6 +103,10 @@ void DisplayServer::global_menu_set_item_callback(const String &p_menu_root, int WARN_PRINT("Global menus not supported by this display server."); } +void DisplayServer::global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) { + WARN_PRINT("Global menus not supported by this display server."); +} + bool DisplayServer::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const { WARN_PRINT("Global menus not supported by this display server."); return false; @@ -123,6 +127,11 @@ Callable DisplayServer::global_menu_get_item_callback(const String &p_menu_root, return Callable(); } +Callable DisplayServer::global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const { + WARN_PRINT("Global menus not supported by this display server."); + return Callable(); +} + Variant DisplayServer::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { WARN_PRINT("Global menus not supported by this display server."); return Variant(); @@ -527,14 +536,14 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature); ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name); - ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_check_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_check_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_radio_check_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_radio_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_radio_check_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "labe", "max_states", "default_state", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_submenu_item", "menu_root", "label", "submenu", "index"), &DisplayServer::global_menu_add_submenu_item, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_check_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_radio_check_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_radio_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "labe", "max_states", "default_state", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu_root", "index"), &DisplayServer::global_menu_add_separator, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_get_item_index_from_text", "menu_root", "text"), &DisplayServer::global_menu_get_item_index_from_text); @@ -544,6 +553,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_is_item_checkable", "menu_root", "idx"), &DisplayServer::global_menu_is_item_checkable); ClassDB::bind_method(D_METHOD("global_menu_is_item_radio_checkable", "menu_root", "idx"), &DisplayServer::global_menu_is_item_radio_checkable); ClassDB::bind_method(D_METHOD("global_menu_get_item_callback", "menu_root", "idx"), &DisplayServer::global_menu_get_item_callback); + ClassDB::bind_method(D_METHOD("global_menu_get_item_key_callback", "menu_root", "idx"), &DisplayServer::global_menu_get_item_key_callback); ClassDB::bind_method(D_METHOD("global_menu_get_item_tag", "menu_root", "idx"), &DisplayServer::global_menu_get_item_tag); ClassDB::bind_method(D_METHOD("global_menu_get_item_text", "menu_root", "idx"), &DisplayServer::global_menu_get_item_text); ClassDB::bind_method(D_METHOD("global_menu_get_item_submenu", "menu_root", "idx"), &DisplayServer::global_menu_get_item_submenu); @@ -559,6 +569,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_set_item_checkable", "menu_root", "idx", "checkable"), &DisplayServer::global_menu_set_item_checkable); ClassDB::bind_method(D_METHOD("global_menu_set_item_radio_checkable", "menu_root", "idx", "checkable"), &DisplayServer::global_menu_set_item_radio_checkable); ClassDB::bind_method(D_METHOD("global_menu_set_item_callback", "menu_root", "idx", "callback"), &DisplayServer::global_menu_set_item_callback); + ClassDB::bind_method(D_METHOD("global_menu_set_item_key_callback", "menu_root", "idx", "key_callback"), &DisplayServer::global_menu_set_item_key_callback); ClassDB::bind_method(D_METHOD("global_menu_set_item_tag", "menu_root", "idx", "tag"), &DisplayServer::global_menu_set_item_tag); ClassDB::bind_method(D_METHOD("global_menu_set_item_text", "menu_root", "idx", "text"), &DisplayServer::global_menu_set_item_text); ClassDB::bind_method(D_METHOD("global_menu_set_item_submenu", "menu_root", "idx", "submenu"), &DisplayServer::global_menu_set_item_submenu); diff --git a/servers/display_server.h b/servers/display_server.h index 0b162fe491..7cb880cbcb 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -128,14 +128,14 @@ public: virtual bool has_feature(Feature p_feature) const = 0; virtual String get_name() const = 0; - virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1); + virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); virtual int global_menu_add_separator(const String &p_menu_root, int p_index = -1); virtual int global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const; @@ -145,6 +145,7 @@ public: virtual bool global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const; virtual bool global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const; virtual Callable global_menu_get_item_callback(const String &p_menu_root, int p_idx) const; + virtual Callable global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const; virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx) const; virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx) const; virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const; @@ -160,6 +161,7 @@ public: virtual void global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable); virtual void global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable); virtual void global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback); + virtual void global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback); virtual void global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag); virtual void global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text); virtual void global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu); |