Merge pull request #59410 from bruvzg/mac_menu_features

This commit is contained in:
Rémi Verschelde 2022-03-22 12:58:29 +01:00 committed by GitHub
commit 7538ad81ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1038 additions and 53 deletions

View File

@ -136,7 +136,74 @@
<argument index="1" name="label" type="String" />
<argument index="2" name="callback" type="Callable" />
<argument index="3" name="tag" type="Variant" default="null" />
<argument index="4" name="accelerator" type="int" enum="Key" default="0" />
<argument index="5" name="index" type="int" default="-1" />
<description>
Adds a new checkable item with text [code]label[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_check_item">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="icon" type="Texture2D" />
<argument index="2" name="label" type="String" />
<argument index="3" name="callback" type="Callable" />
<argument index="4" name="tag" type="Variant" default="null" />
<argument index="5" name="accelerator" type="int" enum="Key" default="0" />
<argument index="6" name="index" type="int" default="-1" />
<description>
Adds a new checkable item with text [code]label[/code] and icon [code]icon[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_item">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="icon" type="Texture2D" />
<argument index="2" name="label" type="String" />
<argument index="3" name="callback" type="Callable" />
<argument index="4" name="tag" type="Variant" default="null" />
<argument index="5" name="accelerator" type="int" enum="Key" default="0" />
<argument index="6" name="index" type="int" default="-1" />
<description>
Adds a new item with text [code]label[/code] and icon [code]icon[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_radio_check_item">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="icon" type="Texture2D" />
<argument index="2" name="label" type="String" />
<argument index="3" name="callback" type="Callable" />
<argument index="4" name="tag" type="Variant" default="null" />
<argument index="5" name="accelerator" type="int" enum="Key" default="0" />
<argument index="6" name="index" type="int" default="-1" />
<description>
Adds a new radio-checkable item with text [code]label[/code] and icon [code]icon[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it.
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_item">
@ -145,13 +212,70 @@
<argument index="1" name="label" type="String" />
<argument index="2" name="callback" type="Callable" />
<argument index="3" name="tag" type="Variant" default="null" />
<argument index="4" name="accelerator" type="int" enum="Key" default="0" />
<argument index="5" name="index" type="int" default="-1" />
<description>
Adds a new item with text [code]label[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_multistate_item">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="labe" type="String" />
<argument index="2" name="max_states" type="int" />
<argument index="3" name="default_state" type="int" />
<argument index="4" name="callback" type="Callable" />
<argument index="5" name="tag" type="Variant" default="null" />
<argument index="6" name="accelerator" type="int" enum="Key" default="0" />
<argument index="7" name="index" type="int" default="-1" />
<description>
Adds a new item with text [code]label[/code] to the global menu with ID [code]menu_root[/code].
Contrarily to normal binary items, multistate items can have more than two states, as defined by [code]max_states[/code]. Each press or activate of the item will increase the state by one. The default value is defined by [code]default_state[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_radio_check_item">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="label" type="String" />
<argument index="2" name="callback" type="Callable" />
<argument index="3" name="tag" type="Variant" default="null" />
<argument index="4" name="accelerator" type="int" enum="Key" default="0" />
<argument index="5" name="index" type="int" default="-1" />
<description>
Adds a new radio-checkable item with text [code]label[/code] to the global menu with ID [code]menu_root[/code].
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it.
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_separator">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="index" type="int" default="-1" />
<description>
Adds a separator between items to the global menu with ID [code]menu_root[/code]. Separators also occupy an index.
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_add_submenu_item">
@ -159,41 +283,127 @@
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="label" type="String" />
<argument index="2" name="submenu" type="String" />
<argument index="3" name="index" type="int" default="-1" />
<description>
Adds an item that will act as a submenu of the global menu [code]menu_root[/code]. The [code]submenu[/code] argument is the ID of the global menu root that will be shown when the item is clicked.
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_clear">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<description>
Removes all items from the global menu with ID [code]menu_root[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"" - Main menu (macOS).
"_dock" - Dock popup menu (macOS).
[/codeblock]
</description>
</method>
<method name="global_menu_get_item_callback">
<method name="global_menu_get_item_accelerator" qualifiers="const">
<return type="int" enum="Key" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the accelerator of the item at index [code]idx[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_callback" qualifiers="const">
<return type="Callable" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the callback of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_submenu">
<method name="global_menu_get_item_icon" qualifiers="const">
<return type="Texture2D" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the icon of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_tag" qualifiers="const">
<return type="int" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="tag" type="Variant" />
<description>
Returns the index of the item with the specified [code]tag[/code]. Index is automatically assigned to each item by the engine. Index can not be set manually.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_text" qualifiers="const">
<return type="int" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="text" type="String" />
<description>
Returns the index of the item with the specified [code]text[/code]. Index is automatically assigned to each item by the engine. Index can not be set manually.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_max_states" qualifiers="const">
<return type="int" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns number of states of an multistate item. See [method global_menu_add_multistate_item] for details.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_state" qualifiers="const">
<return type="int" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the state of an multistate item. See [method global_menu_add_multistate_item] for details.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_submenu" qualifiers="const">
<return type="String" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the submenu ID of the item at index [code]idx[/code]. See [method global_menu_add_submenu_item] for more info on how to add a submenu.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_tag">
<method name="global_menu_get_item_tag" qualifiers="const">
<return type="Variant" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the metadata of the specified item, which might be of any type. You can set it with [method global_menu_set_item_tag], which provides a simple way of assigning context data to items.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_text">
<method name="global_menu_get_item_text" qualifiers="const">
<return type="String" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the text of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_get_item_tooltip" qualifiers="const">
<return type="String" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns the tooltip associated with the specified index index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_is_item_checkable" qualifiers="const">
@ -201,6 +411,8 @@
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [code]idx[/code] is checkable in some way, i.e. if it has a checkbox or radio button.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_is_item_checked" qualifiers="const">
@ -208,6 +420,28 @@
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [code]idx[/code] is checked.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_is_item_disabled" qualifiers="const">
<return type="bool" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [code]idx[/code] is disabled. When it is disabled it can't be selected, or its action invoked.
See [method global_menu_set_item_disabled] for more info on how to disable an item.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_is_item_radio_checkable" qualifiers="const">
<return type="bool" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [code]idx[/code] has radio button-style checkability.
[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/unchecking items in radio groups.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_remove_item">
@ -215,6 +449,19 @@
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<description>
Removes the item at index [code]idx[/code] from the global menu [code]menu_root[/code].
[b]Note:[/b] The indices of items after the removed item will be shifted by one.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_accelerator">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="keycode" type="int" enum="Key" />
<description>
Sets the accelerator of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_callback">
@ -223,6 +470,8 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="callback" type="Callable" />
<description>
Sets the callback of the item at index [code]idx[/code]. Callback is emitted when an item is pressed or its accelerator is activated.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_checkable">
@ -231,6 +480,8 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="checkable" type="bool" />
<description>
Sets whether the item at index [code]idx[/code] has a checkbox. If [code]false[/code], sets the type of the item to plain text.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_checked">
@ -239,6 +490,60 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="checked" type="bool" />
<description>
Sets the checkstate status of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_disabled">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="disabled" type="bool" />
<description>
Enables/disables the item at index [code]idx[/code]. When it is disabled, it can't be selected and its action can't be invoked.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_icon">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="icon" type="Texture2D" />
<description>
Replaces the [Texture2D] icon of the specified [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
[b]Note:[/b] This method is not supported by macOS "_dock" menu items.
</description>
</method>
<method name="global_menu_set_item_max_states">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="max_states" type="int" />
<description>
Sets number of state of an multistate item. See [method global_menu_add_multistate_item] for details.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_radio_checkable">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="checkable" type="bool" />
<description>
Sets the type of the item at the specified index [code]idx[/code] to radio button. If [code]false[/code], sets the type of the item to plain text
[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/unchecking items in radio groups.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_state">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="state" type="int" />
<description>
Sets the state of an multistate item. See [method global_menu_add_multistate_item] for details.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_submenu">
@ -247,6 +552,8 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="submenu" type="String" />
<description>
Sets the submenu of the item at index [code]idx[/code]. The submenu is the ID of a global menu root that would be shown when the item is clicked.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_tag">
@ -255,6 +562,8 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="tag" type="Variant" />
<description>
Sets the metadata of an item, which may be of any type. You can later get it with [method global_menu_get_item_tag], which provides a simple way of assigning context data to items.
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_text">
@ -263,6 +572,18 @@
<argument index="1" name="idx" type="int" />
<argument index="2" name="text" type="String" />
<description>
Sets the text of the item at index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_set_item_tooltip">
<return type="void" />
<argument index="0" name="menu_root" type="String" />
<argument index="1" name="idx" type="int" />
<argument index="2" name="tooltip" type="String" />
<description>
Sets the [String] tooltip of the item at the specified index [code]idx[/code].
[b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="has_feature" qualifiers="const">

View File

@ -186,6 +186,7 @@ private:
void _process_key_events();
void _update_keyboard_layouts();
static void _keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info);
NSImage *_convert_to_nsimg(Ref<Image> &p_image) const;
static NSCursor *_cursor_from_selector(SEL p_selector, SEL p_fallback = nil);
@ -217,24 +218,46 @@ public:
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
virtual void global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag = Variant()) override;
virtual void global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag = Variant()) override;
virtual void global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu) override;
virtual void global_menu_add_separator(const String &p_menu_root) override;
virtual void 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 void 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 void 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 void 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 void 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 void 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 void 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 void global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1) override;
virtual void 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;
virtual int global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const override;
virtual bool global_menu_is_item_checked(const String &p_menu_root, int p_idx) const override;
virtual bool global_menu_is_item_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) override;
virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx) override;
virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx) override;
virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx) 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 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;
virtual Key global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const override;
virtual bool global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const override;
virtual String global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const override;
virtual int global_menu_get_item_state(const String &p_menu_root, int p_idx) const override;
virtual int global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const override;
virtual Ref<Texture2D> global_menu_get_item_icon(const String &p_menu_root, int p_idx) const override;
virtual void global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) override;
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_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;
virtual void global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) override;
virtual void global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) override;
virtual void global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) override;
virtual void global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) override;
virtual void global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) override;
virtual void global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) override;
virtual int global_menu_get_item_count(const String &p_menu_root) const override;

View File

@ -91,6 +91,7 @@ NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) {
// Submenu.
if (!submenu.has(p_menu_root)) {
NSMenu *n_menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:p_menu_root.utf8().get_data()]];
[n_menu setAutoenablesItems:NO];
submenu[p_menu_root] = n_menu;
}
menu = submenu[p_menu_root];
@ -472,6 +473,40 @@ void DisplayServerOSX::_keyboard_layout_changed(CFNotificationCenterRef center,
}
}
NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const {
p_image->convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:p_image->get_width()
pixelsHigh:p_image->get_height()
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:int(p_image->get_width()) * 4
bitsPerPixel:32];
ERR_FAIL_COND_V(imgrep == nil, nil);
uint8_t *pixels = [imgrep bitmapData];
int len = p_image->get_width() * p_image->get_height();
const uint8_t *r = p_image->get_data().ptr();
/* Premultiply the alpha channel */
for (int i = 0; i < len; i++) {
uint8_t alpha = r[i * 4 + 3];
pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
pixels[i * 4 + 3] = alpha;
}
NSImage *nsimg = [[NSImage alloc] initWithSize:NSMakeSize(p_image->get_width(), p_image->get_height())];
ERR_FAIL_COND_V(nsimg == nil, nil);
[nsimg addRepresentation:imgrep];
return nsimg;
}
NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback) {
if ([NSCursor respondsToSelector:p_selector]) {
id object = [NSCursor performSelector:p_selector];
@ -498,7 +533,14 @@ void DisplayServerOSX::menu_callback(id p_sender) {
GodotMenuItem *value = [p_sender representedObject];
if (value) {
if (value->checkable) {
if (value->max_states > 0) {
value->state++;
if (value->state >= value->max_states) {
value->state = 0;
}
}
if (value->checkable_type == CHECKABLE_TYPE_CHECK_BOX) {
if ([p_sender state] == NSControlStateValueOff) {
[p_sender setState:NSControlStateValueOn];
} else {
@ -671,35 +713,195 @@ String DisplayServerOSX::get_name() const {
return "OSX";
}
void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) {
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""];
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable = false;
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = 0;
obj->state = 0;
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) {
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""];
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable = true;
obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX;
obj->max_states = 0;
obj->state = 0;
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu) {
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = 0;
obj->state = 0;
if (p_icon.is_valid()) {
obj->img = p_icon->get_image();
obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) {
obj->img->decompress();
}
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX;
obj->max_states = 0;
obj->state = 0;
if (p_icon.is_valid()) {
obj->img = p_icon->get_image();
obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) {
obj->img->decompress();
}
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON;
obj->max_states = 0;
obj->state = 0;
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON;
obj->max_states = 0;
obj->state = 0;
if (p_icon.is_valid()) {
obj->img = p_icon->get_image();
obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) {
obj->img->decompress();
}
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::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) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
GodotMenuItem *obj = [[GodotMenuItem alloc] init];
obj->callback = p_callback;
obj->meta = p_tag;
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = p_max_states;
obj->state = p_default_state;
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@ -713,20 +915,60 @@ void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, c
ERR_PRINT("Can't set submenu to menu that is already a submenu of some other menu!");
return;
}
NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:nil keyEquivalent:@""];
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:nil keyEquivalent:@"" atIndex:p_index];
} else {
menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:nil keyEquivalent:@""];
}
[sub_menu setTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()]];
[menu setSubmenu:sub_menu forItem:menu_item];
}
}
void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root) {
void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
[menu addItem:[NSMenuItem separatorItem]];
if (p_index != -1) {
[menu insertItem:[NSMenuItem separatorItem] atIndex:p_index];
} else {
[menu addItem:[NSMenuItem separatorItem]];
}
}
}
int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
return [menu indexOfItemWithTitle:[NSString stringWithUTF8String:p_text.utf8().get_data()]];
}
return -1;
}
int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
for (NSInteger i = 0; i < [menu numberOfItems]; i++) {
const NSMenuItem *menu_item = [menu itemAtIndex:i];
if (menu_item) {
const GodotMenuItem *obj = [menu_item representedObject];
if (obj && obj->meta == p_tag) {
return i;
}
}
}
}
return -1;
}
bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
@ -749,14 +991,30 @@ bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root,
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
return obj->checkable;
return obj->checkable_type == CHECKABLE_TYPE_CHECK_BOX;
}
}
}
return false;
}
Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_root, int p_idx) {
bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
return obj->checkable_type == CHECKABLE_TYPE_RADIO_BUTTON;
}
}
}
return false;
}
Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@ -772,7 +1030,7 @@ Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_ro
return Callable();
}
Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, int p_idx) {
Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@ -788,22 +1046,20 @@ Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, in
return Variant();
}
String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, int p_idx) {
String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
String ret;
ret.parse_utf8([[menu_item title] UTF8String]);
return ret;
return String::utf8([[menu_item title] UTF8String]);
}
}
return String();
}
String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) {
String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@ -823,6 +1079,116 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root,
return String();
}
Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
String ret = String::utf8([[menu_item keyEquivalent] UTF8String]);
Key keycode = find_keycode(ret);
NSUInteger mask = [menu_item keyEquivalentModifierMask];
if (mask & NSEventModifierFlagControl) {
keycode |= KeyModifierMask::CTRL;
}
if (mask & NSEventModifierFlagOption) {
keycode |= KeyModifierMask::ALT;
}
if (mask & NSEventModifierFlagShift) {
keycode |= KeyModifierMask::SHIFT;
}
if (mask & NSEventModifierFlagCommand) {
keycode |= KeyModifierMask::META;
}
if (mask & NSEventModifierFlagNumericPad) {
keycode |= KeyModifierMask::KPAD;
}
return keycode;
}
}
return Key::NONE;
}
bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
return ![menu_item isEnabled];
}
}
return false;
}
String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
return String::utf8([[menu_item toolTip] UTF8String]);
}
}
return String();
}
int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
return obj->state;
}
}
}
return 0;
}
int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
return obj->max_states;
}
}
}
return 0;
}
Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
const NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
if (obj->img.is_valid()) {
Ref<ImageTexture> txt;
txt.instantiate();
txt->create_from_image(obj->img);
return txt;
}
}
}
}
return Ref<Texture2D>();
}
void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
_THREAD_SAFE_METHOD_
@ -853,7 +1219,23 @@ void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root,
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
obj->checkable = p_checkable;
obj->checkable_type = (p_checkable) ? CHECKABLE_TYPE_CHECK_BOX : CHECKABLE_TYPE_NONE;
}
}
}
void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
obj->checkable_type = (p_checkable) ? CHECKABLE_TYPE_RADIO_BUTTON : CHECKABLE_TYPE_NONE;
}
}
}
@ -929,6 +1311,116 @@ void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, i
}
}
void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
[menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_keycode)];
String keycode = KeyMappingOSX::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK);
[menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
}
}
void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
[menu_item setEnabled:(!p_disabled)];
}
}
}
void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
[menu_item setToolTip:[NSString stringWithUTF8String:p_tooltip.utf8().get_data()]];
}
}
}
void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
obj->state = p_state;
}
}
}
}
void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
obj->max_states = p_max_states;
}
}
}
}
void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
if ((menu == [NSApp mainMenu]) && (p_idx == 0)) { // Do not edit Apple menu.
return;
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
GodotMenuItem *obj = [menu_item representedObject];
if (p_icon.is_valid()) {
obj->img = p_icon->get_image();
obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) {
obj->img->decompress();
}
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
} else {
obj->img = Ref<Image>();
[menu_item setImage:nil];
}
}
}
}
int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) const {
_THREAD_SAFE_METHOD_
@ -2628,11 +3120,13 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
// Setup Dock menu.
dock_menu = [[NSMenu alloc] initWithTitle:@"_dock"];
[dock_menu setAutoenablesItems:NO];
// Setup Apple menu.
apple_menu = [[NSMenu alloc] initWithTitle:@""];
title = [NSString stringWithFormat:NSLocalizedString(@"About %@", nil), nsappname];
[apple_menu addItemWithTitle:title action:@selector(showAbout:) keyEquivalent:@""];
[apple_menu setAutoenablesItems:NO];
[apple_menu addItem:[NSMenuItem separatorItem]];
@ -2660,6 +3154,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
NSMenu *main_menu = [NSApp mainMenu];
menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
[main_menu setSubmenu:apple_menu forItem:menu_item];
[main_menu setAutoenablesItems:NO];
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback

View File

@ -36,12 +36,21 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
enum GlobalMenuCheckType {
CHECKABLE_TYPE_NONE,
CHECKABLE_TYPE_CHECK_BOX,
CHECKABLE_TYPE_RADIO_BUTTON,
};
@interface GodotMenuItem : NSObject {
@public
Callable callback;
Variant meta;
int id;
bool checkable;
GlobalMenuCheckType checkable_type;
int max_states;
int state;
Ref<Image> img;
}
@end

View File

@ -44,22 +44,52 @@ DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[Displa
int DisplayServer::server_create_count = 1;
void DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) {
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) {
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu) {
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_add_separator(const String &p_menu_root) {
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void 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) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_add_separator(const String &p_menu_root, int p_index) {
WARN_PRINT("Global menus not supported by this display server.");
}
int DisplayServer::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
WARN_PRINT("Global menus not supported by this display server.");
return -1;
}
int DisplayServer::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
WARN_PRINT("Global menus not supported by this display server.");
return -1;
}
void DisplayServer::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) {
WARN_PRINT("Global menus not supported by this display server.");
}
@ -74,26 +104,61 @@ bool DisplayServer::global_menu_is_item_checkable(const String &p_menu_root, int
return false;
}
Callable DisplayServer::global_menu_get_item_callback(const String &p_menu_root, int p_idx) {
bool DisplayServer::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return false;
}
Callable DisplayServer::global_menu_get_item_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) {
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();
}
String DisplayServer::global_menu_get_item_text(const String &p_menu_root, int p_idx) {
String DisplayServer::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return String();
}
String DisplayServer::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) {
String DisplayServer::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return String();
}
Key DisplayServer::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return Key::NONE;
}
bool DisplayServer::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return false;
}
String DisplayServer::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return String();
}
int DisplayServer::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return -1;
}
int DisplayServer::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return -1;
}
Ref<Texture2D> DisplayServer::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return Ref<Texture2D>();
}
void DisplayServer::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
WARN_PRINT("Global menus not supported by this display server.");
}
@ -102,6 +167,10 @@ void DisplayServer::global_menu_set_item_checkable(const String &p_menu_root, in
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) {
WARN_PRINT("Global menus not supported by this display server.");
}
@ -114,6 +183,30 @@ void DisplayServer::global_menu_set_item_submenu(const String &p_menu_root, int
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
WARN_PRINT("Global menus not supported by this display server.");
}
void DisplayServer::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
WARN_PRINT("Global menus not supported by this display server.");
}
int DisplayServer::global_menu_get_item_count(const String &p_menu_root) const {
WARN_PRINT("Global menus not supported by this display server.");
return 0;
@ -341,24 +434,46 @@ 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"), &DisplayServer::global_menu_add_item, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("global_menu_add_check_item", "menu_root", "label", "callback", "tag"), &DisplayServer::global_menu_add_check_item, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("global_menu_add_submenu_item", "menu_root", "label", "submenu"), &DisplayServer::global_menu_add_submenu_item);
ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu_root"), &DisplayServer::global_menu_add_separator);
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_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);
ClassDB::bind_method(D_METHOD("global_menu_get_item_index_from_tag", "menu_root", "tag"), &DisplayServer::global_menu_get_item_index_from_tag);
ClassDB::bind_method(D_METHOD("global_menu_is_item_checked", "menu_root", "idx"), &DisplayServer::global_menu_is_item_checked);
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_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);
ClassDB::bind_method(D_METHOD("global_menu_get_item_accelerator", "menu_root", "idx"), &DisplayServer::global_menu_get_item_accelerator);
ClassDB::bind_method(D_METHOD("global_menu_is_item_disabled", "menu_root", "idx"), &DisplayServer::global_menu_is_item_disabled);
ClassDB::bind_method(D_METHOD("global_menu_get_item_tooltip", "menu_root", "idx"), &DisplayServer::global_menu_get_item_tooltip);
ClassDB::bind_method(D_METHOD("global_menu_get_item_state", "menu_root", "idx"), &DisplayServer::global_menu_get_item_state);
ClassDB::bind_method(D_METHOD("global_menu_get_item_max_states", "menu_root", "idx"), &DisplayServer::global_menu_get_item_max_states);
ClassDB::bind_method(D_METHOD("global_menu_get_item_icon", "menu_root", "idx"), &DisplayServer::global_menu_get_item_icon);
ClassDB::bind_method(D_METHOD("global_menu_set_item_checked", "menu_root", "idx", "checked"), &DisplayServer::global_menu_set_item_checked);
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_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);
ClassDB::bind_method(D_METHOD("global_menu_set_item_accelerator", "menu_root", "idx", "keycode"), &DisplayServer::global_menu_set_item_accelerator);
ClassDB::bind_method(D_METHOD("global_menu_set_item_disabled", "menu_root", "idx", "disabled"), &DisplayServer::global_menu_set_item_disabled);
ClassDB::bind_method(D_METHOD("global_menu_set_item_tooltip", "menu_root", "idx", "tooltip"), &DisplayServer::global_menu_set_item_tooltip);
ClassDB::bind_method(D_METHOD("global_menu_set_item_state", "menu_root", "idx", "state"), &DisplayServer::global_menu_set_item_state);
ClassDB::bind_method(D_METHOD("global_menu_set_item_max_states", "menu_root", "idx", "max_states"), &DisplayServer::global_menu_set_item_max_states);
ClassDB::bind_method(D_METHOD("global_menu_set_item_icon", "menu_root", "idx", "icon"), &DisplayServer::global_menu_set_item_icon);
ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu_root", "idx"), &DisplayServer::global_menu_remove_item);
ClassDB::bind_method(D_METHOD("global_menu_clear", "menu_root"), &DisplayServer::global_menu_clear);

View File

@ -126,24 +126,46 @@ public:
virtual bool has_feature(Feature p_feature) const = 0;
virtual String get_name() const = 0;
virtual void global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag = Variant());
virtual void global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag = Variant());
virtual void global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu);
virtual void global_menu_add_separator(const String &p_menu_root);
virtual void 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 void 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 void 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 void 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 void 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 void 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 void 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 void global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1);
virtual void 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;
virtual int global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const;
virtual bool global_menu_is_item_checked(const String &p_menu_root, int p_idx) const;
virtual bool global_menu_is_item_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);
virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx);
virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx);
virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx);
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 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;
virtual Key global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const;
virtual bool global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const;
virtual String global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const;
virtual int global_menu_get_item_state(const String &p_menu_root, int p_idx) const;
virtual int global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const;
virtual Ref<Texture2D> global_menu_get_item_icon(const String &p_menu_root, int p_idx) const;
virtual void global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked);
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_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);
virtual void global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode);
virtual void global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled);
virtual void global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip);
virtual void global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state);
virtual void global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states);
virtual void global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon);
virtual int global_menu_get_item_count(const String &p_menu_root) const;