Merge pull request #87452 from bruvzg/native_menu

Move `global_menu_*` methods to a separate `NativeMenu` class.
This commit is contained in:
Rémi Verschelde 2024-03-06 13:16:52 +01:00
commit 13954fc33e
No known key found for this signature in database
GPG Key ID: C3336907360768E1
36 changed files with 3500 additions and 1738 deletions

View File

@ -266,7 +266,7 @@
[b]Note:[/b] Native dialogs are not included in this list.
</description>
</method>
<method name="global_menu_add_check_item">
<method name="global_menu_add_check_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="label" type="String" />
@ -291,7 +291,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_check_item">
<method name="global_menu_add_icon_check_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="icon" type="Texture2D" />
@ -317,7 +317,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_item">
<method name="global_menu_add_icon_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="icon" type="Texture2D" />
@ -343,7 +343,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_icon_radio_check_item">
<method name="global_menu_add_icon_radio_check_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="icon" type="Texture2D" />
@ -370,7 +370,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_item">
<method name="global_menu_add_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="label" type="String" />
@ -395,7 +395,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_multistate_item">
<method name="global_menu_add_multistate_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="label" type="String" />
@ -424,7 +424,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_radio_check_item">
<method name="global_menu_add_radio_check_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="label" type="String" />
@ -450,7 +450,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_separator">
<method name="global_menu_add_separator" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="index" type="int" default="-1" />
@ -468,7 +468,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_add_submenu_item">
<method name="global_menu_add_submenu_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="label" type="String" />
@ -488,7 +488,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_clear">
<method name="global_menu_clear" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<description>
@ -504,7 +504,7 @@
[/codeblock]
</description>
</method>
<method name="global_menu_get_item_accelerator" qualifiers="const">
<method name="global_menu_get_item_accelerator" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" enum="Key" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -513,7 +513,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_callback" qualifiers="const">
<method name="global_menu_get_item_callback" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="Callable" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -522,7 +522,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_count" qualifiers="const">
<method name="global_menu_get_item_count" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<description>
@ -530,7 +530,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_icon" qualifiers="const">
<method name="global_menu_get_item_icon" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="Texture2D" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -539,7 +539,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_indentation_level" qualifiers="const">
<method name="global_menu_get_item_indentation_level" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -548,7 +548,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_tag" qualifiers="const">
<method name="global_menu_get_item_index_from_tag" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="tag" type="Variant" />
@ -557,7 +557,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_text" qualifiers="const">
<method name="global_menu_get_item_index_from_text" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="text" type="String" />
@ -566,7 +566,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_key_callback" qualifiers="const">
<method name="global_menu_get_item_key_callback" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="Callable" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -575,7 +575,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_max_states" qualifiers="const">
<method name="global_menu_get_item_max_states" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -584,7 +584,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_state" qualifiers="const">
<method name="global_menu_get_item_state" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="int" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -593,7 +593,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_submenu" qualifiers="const">
<method name="global_menu_get_item_submenu" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="String" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -602,7 +602,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_tag" qualifiers="const">
<method name="global_menu_get_item_tag" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="Variant" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -611,7 +611,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_text" qualifiers="const">
<method name="global_menu_get_item_text" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="String" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -620,7 +620,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_tooltip" qualifiers="const">
<method name="global_menu_get_item_tooltip" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="String" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -629,14 +629,14 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_system_menu_roots" qualifiers="const">
<method name="global_menu_get_system_menu_roots" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="Dictionary" />
<description>
Returns Dictionary of supported system menu IDs and names.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_checkable" qualifiers="const">
<method name="global_menu_is_item_checkable" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="bool" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -645,7 +645,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_checked" qualifiers="const">
<method name="global_menu_is_item_checked" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="bool" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -654,7 +654,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_disabled" qualifiers="const">
<method name="global_menu_is_item_disabled" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="bool" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -664,7 +664,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_hidden" qualifiers="const">
<method name="global_menu_is_item_hidden" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="bool" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -674,7 +674,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_radio_checkable" qualifiers="const">
<method name="global_menu_is_item_radio_checkable" qualifiers="const" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="bool" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -684,7 +684,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_remove_item">
<method name="global_menu_remove_item" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -694,7 +694,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_accelerator">
<method name="global_menu_set_item_accelerator" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -704,7 +704,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_callback">
<method name="global_menu_set_item_callback" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -715,7 +715,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_checkable">
<method name="global_menu_set_item_checkable" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -725,7 +725,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_checked">
<method name="global_menu_set_item_checked" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -735,7 +735,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_disabled">
<method name="global_menu_set_item_disabled" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -745,7 +745,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_hidden">
<method name="global_menu_set_item_hidden" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -755,7 +755,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_hover_callbacks">
<method name="global_menu_set_item_hover_callbacks" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -766,7 +766,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_icon">
<method name="global_menu_set_item_icon" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -777,7 +777,7 @@
[b]Note:[/b] This method is not supported by macOS "_dock" menu items.
</description>
</method>
<method name="global_menu_set_item_indentation_level">
<method name="global_menu_set_item_indentation_level" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -787,7 +787,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_key_callback">
<method name="global_menu_set_item_key_callback" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -798,7 +798,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_max_states">
<method name="global_menu_set_item_max_states" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -808,7 +808,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_radio_checkable">
<method name="global_menu_set_item_radio_checkable" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -819,7 +819,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_state">
<method name="global_menu_set_item_state" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -829,7 +829,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_submenu">
<method name="global_menu_set_item_submenu" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -839,7 +839,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_tag">
<method name="global_menu_set_item_tag" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -849,7 +849,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_text">
<method name="global_menu_set_item_text" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -859,7 +859,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_tooltip">
<method name="global_menu_set_item_tooltip" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="idx" type="int" />
@ -869,7 +869,7 @@
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_popup_callbacks">
<method name="global_menu_set_popup_callbacks" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
<return type="void" />
<param index="0" name="menu_root" type="String" />
<param index="1" name="open_callback" type="Callable" />
@ -1756,7 +1756,7 @@
</method>
</methods>
<constants>
<constant name="FEATURE_GLOBAL_MENU" value="0" enum="Feature">
<constant name="FEATURE_GLOBAL_MENU" value="0" enum="Feature" deprecated="Use [NativeMenu] or [PopupMenu] instead.">
Display server supports global menu. This allows the application to display its menu items in the operating system's top bar. [b]macOS[/b]
</constant>
<constant name="FEATURE_SUBWINDOWS" value="1" enum="Feature">

685
doc/classes/NativeMenu.xml Normal file
View File

@ -0,0 +1,685 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NativeMenu" inherits="Object" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A server interface for OS native menus.
</brief_description>
<description>
[NativeMenu] handles low-level access to the OS native global menu bar and popup menus.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_check_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="label" type="String" />
<param index="2" name="callback" type="Callable" default="Callable()" />
<param index="3" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_icon_check_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="icon" type="Texture2D" />
<param index="2" name="label" type="String" />
<param index="3" name="callback" type="Callable" default="Callable()" />
<param index="4" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_icon_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="icon" type="Texture2D" />
<param index="2" name="label" type="String" />
<param index="3" name="callback" type="Callable" default="Callable()" />
<param index="4" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_icon_radio_check_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="icon" type="Texture2D" />
<param index="2" name="label" type="String" />
<param index="3" name="callback" type="Callable" default="Callable()" />
<param index="4" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[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 set_item_checked] for more info on how to control it.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="label" type="String" />
<param index="2" name="callback" type="Callable" default="Callable()" />
<param index="3" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_multistate_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="label" type="String" />
<param index="2" name="max_states" type="int" />
<param index="3" name="default_state" type="int" />
<param index="4" name="callback" type="Callable" default="Callable()" />
<param index="5" name="key_callback" type="Callable" default="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 label] to the global menu [param rid].
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].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] By default, there's no indication of the current item state, it should be changed manually.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_radio_check_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="label" type="String" />
<param index="2" name="callback" type="Callable" default="Callable()" />
<param index="3" name="key_callback" type="Callable" default="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 [param rid].
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[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 set_item_checked] for more info on how to control it.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_separator">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="index" type="int" default="-1" />
<description>
Adds a separator between items to the global menu [param rid]. Separators also occupy an index.
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="add_submenu_item">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="label" type="String" />
<param index="2" name="submenu_rid" type="RID" />
<param index="3" name="tag" type="Variant" default="null" />
<param index="4" name="index" type="int" default="-1" />
<description>
Adds an item that will act as a submenu of the global menu [param rid]. The [param submenu_rid] argument is the RID of the global menu that will be shown when the item is clicked.
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="clear">
<return type="void" />
<param index="0" name="rid" type="RID" />
<description>
Removes all items from the global menu [param rid].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="create_menu">
<return type="RID" />
<description>
Creates a new global menu object.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="find_item_index_with_tag" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="tag" type="Variant" />
<description>
Returns the index of the item with the specified [param tag]. Index is automatically assigned to each item by the engine. Index can not be set manually.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="find_item_index_with_text" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="text" type="String" />
<description>
Returns the index of the item with the specified [param text]. Index is automatically assigned to each item by the engine. Index can not be set manually.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="free_menu">
<return type="void" />
<param index="0" name="rid" type="RID" />
<description>
Frees a global menu object created by this [NativeMenu].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_accelerator" qualifiers="const">
<return type="int" enum="Key" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the accelerator of the item at index [param idx]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_callback" qualifiers="const">
<return type="Callable" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the callback of the item at index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_count" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<description>
Returns number of items in the global menu [param rid].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_icon" qualifiers="const">
<return type="Texture2D" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the icon of the item at index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_indentation_level" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the horizontal offset of the item at the given [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_key_callback" qualifiers="const">
<return type="Callable" />
<param index="0" name="rid" type="RID" />
<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 only on macOS.
</description>
</method>
<method name="get_item_max_states" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns number of states of a multistate item. See [method add_multistate_item] for details.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_state" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the state of a multistate item. See [method add_multistate_item] for details.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_submenu" qualifiers="const">
<return type="RID" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the submenu ID of the item at index [param idx]. See [method add_submenu_item] for more info on how to add a submenu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_tag" qualifiers="const">
<return type="Variant" />
<param index="0" name="rid" type="RID" />
<param 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 set_item_tag], which provides a simple way of assigning context data to items.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_text" qualifiers="const">
<return type="String" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the text of the item at index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_item_tooltip" qualifiers="const">
<return type="String" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns the tooltip associated with the specified index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_minimum_width" qualifiers="const">
<return type="float" />
<param index="0" name="rid" type="RID" />
<description>
Returns global menu minimum width.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_popup_close_callback" qualifiers="const">
<return type="Callable" />
<param index="0" name="rid" type="RID" />
<description>
Returns global menu close callback.
b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_popup_open_callback" qualifiers="const">
<return type="Callable" />
<param index="0" name="rid" type="RID" />
<description>
Returns global menu open callback.
b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_size" qualifiers="const">
<return type="Vector2" />
<param index="0" name="rid" type="RID" />
<description>
Returns global menu size.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_system_menu" qualifiers="const">
<return type="RID" />
<param index="0" name="menu_id" type="int" enum="NativeMenu.SystemMenus" />
<description>
Returns RID of a special system menu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="get_system_menu_name" qualifiers="const">
<return type="String" />
<param index="0" name="menu_id" type="int" enum="NativeMenu.SystemMenus" />
<description>
Returns readable name of a special system menu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="has_feature" qualifiers="const">
<return type="bool" />
<param index="0" name="feature" type="int" enum="NativeMenu.Feature" />
<description>
Returns [code]true[/code] if the specified [param feature] is supported by the current [NativeMenu], [code]false[/code] otherwise.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="has_menu" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<description>
Returns [code]true[/code] if [param rid] is valid global menu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="has_system_menu" qualifiers="const">
<return type="bool" />
<param index="0" name="menu_id" type="int" enum="NativeMenu.SystemMenus" />
<description>
Returns [code]true[/code] if a special system menu is supported.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_item_checkable" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is checkable in some way, i.e. if it has a checkbox or radio button.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_item_checked" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is checked.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_item_disabled" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is disabled. When it is disabled it can't be selected, or its action invoked.
See [method set_item_disabled] for more info on how to disable an item.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_item_hidden" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is hidden.
See [method set_item_hidden] for more info on how to hide an item.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_item_radio_checkable" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] 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 only on macOS.
</description>
</method>
<method name="is_system_menu" qualifiers="const">
<return type="bool" />
<param index="0" name="rid" type="RID" />
<description>
Return [code]true[/code] is global menu is a special system menu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="popup">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="position" type="Vector2i" />
<description>
Shows the global menu at [param position] in the screen coordinates.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="remove_item">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<description>
Removes the item at index [param idx] from the global menu [param rid].
[b]Note:[/b] The indices of items after the removed item will be shifted by one.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_accelerator">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="keycode" type="int" enum="Key" />
<description>
Sets the accelerator of the item at index [param idx]. [param keycode] can be a single [enum Key], or a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_callback">
<return type="void" />
<param index="0" name="rid" type="RID" />
<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.
[b]Note:[/b] The [param callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_checkable">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="checkable" type="bool" />
<description>
Sets whether the item at index [param idx] has a checkbox. If [code]false[/code], sets the type of the item to plain text.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_checked">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="checked" type="bool" />
<description>
Sets the checkstate status of the item at index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_disabled">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="disabled" type="bool" />
<description>
Enables/disables the item at index [param idx]. When it is disabled, it can't be selected and its action can't be invoked.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_hidden">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="hidden" type="bool" />
<description>
Hides/shows the item at index [param idx]. When it is hidden, an item does not appear in a menu and its action cannot be invoked.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_hover_callbacks">
<return type="void" />
<param index="0" name="rid" type="RID" />
<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]. The callback is emitted when an item is hovered.
[b]Note:[/b] The [param callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_icon">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="icon" type="Texture2D" />
<description>
Replaces the [Texture2D] icon of the specified [param idx].
[b]Note:[/b] This method is implemented only on macOS.
[b]Note:[/b] This method is not supported by macOS "_dock" menu items.
</description>
</method>
<method name="set_item_indentation_level">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="level" type="int" />
<description>
Sets the horizontal offset of the item at the given [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_key_callback">
<return type="void" />
<param index="0" name="rid" type="RID" />
<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] The [param key_callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_max_states">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="max_states" type="int" />
<description>
Sets number of state of a multistate item. See [method add_multistate_item] for details.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_radio_checkable">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="checkable" type="bool" />
<description>
Sets the type of the item at the specified index [param idx] 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 only on macOS.
</description>
</method>
<method name="set_item_state">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="state" type="int" />
<description>
Sets the state of a multistate item. See [method add_multistate_item] for details.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_submenu">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="submenu_rid" type="RID" />
<description>
Sets the submenu RID of the item at index [param idx]. The submenu is a global menu that would be shown when the item is clicked.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_tag">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param 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 get_item_tag], which provides a simple way of assigning context data to items.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_text">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="text" type="String" />
<description>
Sets the text of the item at index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_item_tooltip">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="idx" type="int" />
<param index="2" name="tooltip" type="String" />
<description>
Sets the [String] tooltip of the item at the specified index [param idx].
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_minimum_width">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="width" type="float" />
<description>
Sets the minimum width of the global menu.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="set_popup_close_callback">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="callback" type="Callable" />
<description>
Registers callable to emit when the menu is about to show.
</description>
</method>
<method name="set_popup_open_callback">
<return type="void" />
<param index="0" name="rid" type="RID" />
<param index="1" name="callback" type="Callable" />
<description>
Registers callable to emit when the menu is about to closed.
</description>
</method>
</methods>
<constants>
<constant name="FEATURE_GLOBAL_MENU" value="0" enum="Feature">
[NativeMenu] supports native global main menu.
</constant>
<constant name="FEATURE_POPUP_MENU" value="1" enum="Feature">
[NativeMenu] supports native popup menus.
</constant>
<constant name="INVALID_MENU_ID" value="0" enum="SystemMenus">
Invalid special system menu ID.
</constant>
<constant name="MAIN_MENU_ID" value="1" enum="SystemMenus">
Global main menu ID.
</constant>
<constant name="APPLICATION_MENU_ID" value="2" enum="SystemMenus">
Application (first menu after "Apple" menu on macOS) menu ID.
</constant>
<constant name="WINDOW_MENU_ID" value="3" enum="SystemMenus">
"Window" menu ID (on macOS this menu includes standard window control items and a list of open windows).
</constant>
<constant name="HELP_MENU_ID" value="4" enum="SystemMenus">
"Help" menu ID (on macOS this menu includes help search bar).
</constant>
<constant name="DOCK_MENU_ID" value="5" enum="SystemMenus">
Dock icon right-click menu ID (on macOS this menu include standard application control items and a list of open windows).
</constant>
</constants>
</class>

View File

@ -637,8 +637,8 @@
<member name="submenu_popup_delay" type="float" setter="set_submenu_popup_delay" getter="get_submenu_popup_delay" default="0.3">
Sets the delay time in seconds for the submenu item to popup on mouse hovering. If the popup menu is added as a child of another (acting as a submenu), it will inherit the delay time of the parent menu item.
</member>
<member name="system_menu_root" type="String" setter="set_system_menu_root" getter="get_system_menu_root" default="&quot;&quot;">
If set to one of the values returned by [method DisplayServer.global_menu_get_system_menu_roots], this [PopupMenu] is bound to the special system menu. Only one [PopupMenu] can be bound to each special menu at a time.
<member name="system_menu_id" type="int" setter="set_system_menu" getter="get_system_menu" enum="NativeMenu.SystemMenus" default="0">
If set to one of the values of [enum NativeMenu.SystemMenus], this [PopupMenu] is bound to the special system menu. Only one [PopupMenu] can be bound to each special menu at a time.
</member>
</members>
<signals>

View File

@ -6610,7 +6610,7 @@ EditorNode::EditorNode() {
main_screen_vbox->add_theme_constant_override("separation", 0);
scene_root_parent->add_child(main_screen_vbox);
bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU);
bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU);
bool can_expand = bool(EDITOR_GET("interface/editor/expand_to_title")) && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_EXTEND_TO_TITLE);
if (can_expand) {
@ -6741,7 +6741,7 @@ EditorNode::EditorNode() {
#ifdef MACOS_ENABLED
if (global_menu) {
apple_menu = memnew(PopupMenu);
apple_menu->set_system_menu_root("_apple");
apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID);
main_menu->add_child(apple_menu);
apple_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), SETTINGS_PREFERENCES);
@ -6864,7 +6864,7 @@ EditorNode::EditorNode() {
help_menu = memnew(PopupMenu);
help_menu->set_name(TTR("Help"));
help_menu->set_system_menu_root("_help");
help_menu->set_system_menu(NativeMenu::HELP_MENU_ID);
main_menu->add_child(help_menu);
help_menu->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));

View File

@ -202,22 +202,23 @@ void EditorSceneTabs::update_scene_tabs() {
}
menu_initialized = true;
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
DisplayServer::get_singleton()->global_menu_clear("_dock");
if (NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
RID dock_rid = NativeMenu::get_singleton()->get_system_menu(NativeMenu::DOCK_MENU_ID);
NativeMenu::get_singleton()->clear(dock_rid);
}
scene_tabs->set_block_signals(true);
scene_tabs->set_tab_count(EditorNode::get_editor_data().get_edited_scene_count());
scene_tabs->set_block_signals(false);
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
if (NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
RID dock_rid = NativeMenu::get_singleton()->get_system_menu(NativeMenu::DOCK_MENU_ID);
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
int global_menu_index = DisplayServer::get_singleton()->global_menu_add_item("_dock", EditorNode::get_editor_data().get_scene_title(i), callable_mp(this, &EditorSceneTabs::_global_menu_scene), Callable(), i);
int global_menu_index = NativeMenu::get_singleton()->add_item(dock_rid, EditorNode::get_editor_data().get_scene_title(i), callable_mp(this, &EditorSceneTabs::_global_menu_scene), Callable(), i);
scene_tabs->set_tab_metadata(i, global_menu_index);
}
DisplayServer::get_singleton()->global_menu_add_separator("_dock");
DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), callable_mp(this, &EditorSceneTabs::_global_menu_new_window));
NativeMenu::get_singleton()->add_separator(dock_rid);
NativeMenu::get_singleton()->add_item(dock_rid, TTR("New Window"), callable_mp(this, &EditorSceneTabs::_global_menu_new_window));
}
_update_tab_titles();
@ -247,10 +248,11 @@ void EditorSceneTabs::_update_tab_titles() {
bool unsaved = EditorUndoRedoManager::get_singleton()->is_history_unsaved(EditorNode::get_editor_data().get_scene_history_id(i));
scene_tabs->set_tab_title(i, disambiguated_scene_names[i] + (unsaved ? "(*)" : ""));
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
if (NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
RID dock_rid = NativeMenu::get_singleton()->get_system_menu(NativeMenu::DOCK_MENU_ID);
int global_menu_index = scene_tabs->get_tab_metadata(i);
DisplayServer::get_singleton()->global_menu_set_item_text("_dock", global_menu_index, EditorNode::get_editor_data().get_scene_title(i) + (unsaved ? "(*)" : ""));
DisplayServer::get_singleton()->global_menu_set_item_tag("_dock", global_menu_index, i);
NativeMenu::get_singleton()->set_item_text(dock_rid, global_menu_index, EditorNode::get_editor_data().get_scene_title(i) + (unsaved ? "(*)" : ""));
NativeMenu::get_singleton()->set_item_tag(dock_rid, global_menu_index, i);
}
if (show_rb && EditorNode::get_editor_data().get_scene_root_script(i).is_valid()) {

View File

@ -1012,10 +1012,11 @@ void ProjectList::set_order_option(int p_option) {
// Global menu integration.
void ProjectList::update_dock_menu() {
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
if (!NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
return;
}
DisplayServer::get_singleton()->global_menu_clear("_dock");
RID dock_rid = NativeMenu::get_singleton()->get_system_menu(NativeMenu::DOCK_MENU_ID);
NativeMenu::get_singleton()->clear(dock_rid);
int favs_added = 0;
int total_added = 0;
@ -1025,18 +1026,18 @@ void ProjectList::update_dock_menu() {
favs_added++;
} else {
if (favs_added != 0) {
DisplayServer::get_singleton()->global_menu_add_separator("_dock");
NativeMenu::get_singleton()->add_separator(dock_rid);
}
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), Callable(), i);
NativeMenu::get_singleton()->add_item(dock_rid, _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), Callable(), i);
total_added++;
}
}
if (total_added != 0) {
DisplayServer::get_singleton()->global_menu_add_separator("_dock");
NativeMenu::get_singleton()->add_separator(dock_rid);
}
DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), callable_mp(this, &ProjectList::_global_menu_new_window));
NativeMenu::get_singleton()->add_item(dock_rid, TTR("New Window"), callable_mp(this, &ProjectList::_global_menu_new_window));
}
void ProjectList::_global_menu_new_window(const Variant &p_tag) {

View File

@ -58,9 +58,13 @@ DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
bool DisplayServerAndroid::has_feature(Feature p_feature) const {
switch (p_feature) {
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
case FEATURE_CURSOR_SHAPE:
//case FEATURE_CUSTOM_CURSOR_SHAPE:
//case FEATURE_GLOBAL_MENU:
//case FEATURE_HIDPI:
//case FEATURE_ICON:
//case FEATURE_IME:
@ -578,6 +582,8 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
native_menu = memnew(NativeMenu);
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
RasterizerGLES3::make_current(false);
@ -641,6 +647,11 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
DisplayServerAndroid::~DisplayServerAndroid() {
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
#if defined(RD_ENABLED)
if (rendering_device) {
memdelete(rendering_device);

View File

@ -76,6 +76,7 @@ class DisplayServerAndroid : public DisplayServer {
RenderingContextDriver *rendering_context = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
NativeMenu *native_menu = nullptr;
ObjectID window_attached_instance_id;

View File

@ -65,6 +65,7 @@ class DisplayServerIOS : public DisplayServer {
RenderingContextDriver *rendering_context = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
NativeMenu *native_menu = nullptr;
id tts = nullptr;

View File

@ -61,6 +61,7 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
if (tts_enabled) {
tts = [[TTS_IOS alloc] init];
}
native_menu = memnew(NativeMenu);
#if defined(RD_ENABLED)
rendering_context = nullptr;
@ -134,6 +135,11 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
}
DisplayServerIOS::~DisplayServerIOS() {
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
#if defined(RD_ENABLED)
if (rendering_device) {
rendering_device->screen_free(MAIN_WINDOW_ID);
@ -309,9 +315,13 @@ void DisplayServerIOS::update_gyroscope(float p_x, float p_y, float p_z) {
bool DisplayServerIOS::has_feature(Feature p_feature) const {
switch (p_feature) {
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
// case FEATURE_CURSOR_SHAPE:
// case FEATURE_CUSTOM_CURSOR_SHAPE:
// case FEATURE_GLOBAL_MENU:
// case FEATURE_HIDPI:
// case FEATURE_ICON:
// case FEATURE_IME:

View File

@ -192,6 +192,11 @@ void DisplayServerWayland::_show_window() {
bool DisplayServerWayland::has_feature(Feature p_feature) const {
switch (p_feature) {
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
case FEATURE_MOUSE:
case FEATURE_MOUSE_WARP:
case FEATURE_CLIPBOARD:
@ -1242,6 +1247,8 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
// Input.
Input::get_singleton()->set_event_dispatch_function(dispatch_input_events);
native_menu = memnew(NativeMenu);
#ifdef SPEECHD_ENABLED
// Init TTS
tts = memnew(TTS_Linux);
@ -1366,6 +1373,12 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
DisplayServerWayland::~DisplayServerWayland() {
// TODO: Multiwindow support.
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
if (main_window.visible) {
#ifdef VULKAN_ENABLED
if (rendering_device) {

View File

@ -132,6 +132,7 @@ class DisplayServerWayland : public DisplayServer {
#ifdef SPEECHD_ENABLED
TTS_Linux *tts = nullptr;
#endif
NativeMenu *native_menu = nullptr;
#if DBUS_ENABLED
FreeDesktopPortalDesktop *portal_desktop = nullptr;

View File

@ -109,6 +109,11 @@ static String get_atom_name(Display *p_disp, Atom p_atom) {
bool DisplayServerX11::has_feature(Feature p_feature) const {
switch (p_feature) {
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
case FEATURE_SUBWINDOWS:
#ifdef TOUCH_ENABLED
case FEATURE_TOUCHSCREEN:
@ -5765,6 +5770,8 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt
DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
KeyMappingX11::initialize();
native_menu = memnew(NativeMenu);
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
@ -6357,6 +6364,11 @@ DisplayServerX11::~DisplayServerX11() {
events_thread_done.set();
events_thread.wait_to_finish();
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
//destroy all windows
for (KeyValue<WindowID, WindowData> &E : windows) {
#if defined(RD_ENABLED)

View File

@ -156,6 +156,7 @@ class DisplayServerX11 : public DisplayServer {
#ifdef SPEECHD_ENABLED
TTS_Linux *tts = nullptr;
#endif
NativeMenu *native_menu = nullptr;
#if defined(DBUS_ENABLED)
FreeDesktopPortalDesktop *portal_desktop = nullptr;

View File

@ -113,6 +113,7 @@ files = [
"godot_menu_delegate.mm",
"godot_menu_item.mm",
"godot_open_save_delegate.mm",
"native_menu_macos.mm",
"dir_access_macos.mm",
"tts_macos.mm",
"joypad_macos.mm",

View File

@ -39,6 +39,8 @@
#include "gl_manager_macos_legacy.h"
#endif // GLES3_ENABLED
#include "native_menu_macos.h"
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
@ -142,19 +144,6 @@ private:
#endif
String rendering_driver;
NSMenu *apple_menu = nullptr;
NSMenu *window_menu = nullptr;
NSMenu *help_menu = nullptr;
NSMenu *dock_menu = nullptr;
struct MenuData {
Callable open;
Callable close;
NSMenu *menu = nullptr;
bool is_open = false;
};
HashMap<String, MenuData> submenu;
HashMap<NSMenu *, String> submenu_inv;
struct WarpEvent {
NSTimeInterval timestamp;
NSPoint delta;
@ -168,6 +157,7 @@ private:
id tts = nullptr;
id menu_delegate = nullptr;
NativeMenuMacOS *native_menu = nullptr;
Point2i im_selection;
String im_text;
@ -222,15 +212,10 @@ private:
Callable system_theme_changed;
const NSMenu *_get_menu_root(const String &p_menu_root) const;
NSMenu *_get_menu_root(const String &p_menu_root);
bool _is_menu_opened(NSMenu *p_menu) const;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
void _update_window_style(WindowData p_wd);
void _update_displays_arrangement();
Point2i _get_screens_origin() const;
Point2i _get_native_screen_position(int p_screen) const;
static void _displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info);
@ -240,27 +225,22 @@ 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);
int _get_system_menu_start(const NSMenu *p_menu) const;
int _get_system_menu_count(const NSMenu *p_menu) const;
NSMenuItem *_menu_add_item(const String &p_menu_root, const String &p_label, Key p_accel, int p_index, int *r_out);
Error _file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb);
public:
NSMenu *get_dock_menu() const;
void menu_callback(id p_sender);
void menu_open(NSMenu *p_menu);
void menu_close(NSMenu *p_menu);
void emit_system_theme_changed();
bool has_window(WindowID p_window) const;
WindowData &get_window(WindowID p_window);
NSImage *_convert_to_nsimg(Ref<Image> &p_image) const;
Point2i _get_screens_origin() const;
void send_event(NSEvent *p_event);
void send_window_event(const WindowData &p_wd, WindowEvent p_event);
void release_pressed_events();
@ -293,63 +273,6 @@ public:
Callable _help_get_search_callback() const;
Callable _help_get_action_callback() const;
virtual void global_menu_set_popup_callbacks(const String &p_menu_root, const Callable &p_open_callback = Callable(), const Callable &p_close_callback = Callable()) 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;
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 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;
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 bool global_menu_is_item_hidden(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 int global_menu_get_item_indentation_level(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_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) override;
virtual void global_menu_set_item_hover_callbacks(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_hidden(const String &p_menu_root, int p_idx, bool p_hidden) 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 void global_menu_set_item_indentation_level(const String &p_menu_root, int p_idx, int p_level) override;
virtual int global_menu_get_item_count(const String &p_menu_root) const override;
virtual void global_menu_remove_item(const String &p_menu_root, int p_idx) override;
virtual void global_menu_clear(const String &p_menu_root) override;
virtual Dictionary global_menu_get_system_menu_roots() const override;
virtual bool tts_is_speaking() const override;
virtual bool tts_is_paused() const override;
virtual TypedArray<Dictionary> tts_get_voices() const override;

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
#include "godot_application_delegate.h"
#include "display_server_macos.h"
#include "native_menu_macos.h"
#include "os_macos.h"
@implementation GodotApplicationDelegate
@ -211,9 +212,9 @@
}
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
return ds->get_dock_menu();
if (NativeMenu::get_singleton()) {
NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
return nmenu->_get_dock_menu();
} else {
return nullptr;
}

View File

@ -33,6 +33,7 @@
#include "display_server_macos.h"
#include "godot_menu_item.h"
#include "key_mapping_macos.h"
#include "native_menu_macos.h"
@implementation GodotMenuDelegate
@ -40,16 +41,16 @@
}
- (void)menuNeedsUpdate:(NSMenu *)menu {
if (DisplayServer::get_singleton()) {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
ds->menu_open(menu);
if (NativeMenu::get_singleton()) {
NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
nmenu->_menu_open(menu);
}
}
- (void)menuDidClose:(NSMenu *)menu {
if (DisplayServer::get_singleton()) {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
ds->menu_close(menu);
if (NativeMenu::get_singleton()) {
NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
nmenu->_menu_close(menu);
}
}

View File

@ -36,6 +36,9 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#define MENU_TAG_START 0x00004447
#define MENU_TAG_END 0xFFFF4447
enum GlobalMenuCheckType {
CHECKABLE_TYPE_NONE,
CHECKABLE_TYPE_CHECK_BOX,

View File

@ -0,0 +1,156 @@
/**************************************************************************/
/* native_menu_macos.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 NATIVE_MENU_MACOS_H
#define NATIVE_MENU_MACOS_H
#include "core/templates/hash_map.h"
#include "core/templates/rid_owner.h"
#include "servers/native_menu.h"
#import <AppKit/AppKit.h>
#import <ApplicationServices/ApplicationServices.h>
class NativeMenuMacOS : public NativeMenu {
GDCLASS(NativeMenuMacOS, NativeMenu)
struct MenuData {
NSMenu *menu = nullptr;
Callable open_cb;
Callable close_cb;
bool is_open = false;
bool is_system = false;
};
mutable RID_PtrOwner<MenuData> menus;
HashMap<NSMenu *, RID> menu_lookup;
NSMenu *main_menu_ns = nullptr;
NSMenu *application_menu_ns = nullptr;
NSMenu *window_menu_ns = nullptr;
NSMenu *help_menu_ns = nullptr;
NSMenu *dock_menu_ns = nullptr;
RID main_menu;
RID application_menu;
RID window_menu;
RID help_menu;
RID dock_menu;
int _get_system_menu_start(const NSMenu *p_menu) const;
int _get_system_menu_count(const NSMenu *p_menu) const;
bool _is_menu_opened(NSMenu *p_menu) const;
NSMenuItem *_menu_add_item(NSMenu *p_menu, const String &p_label, Key p_accel, int p_index, int *r_out);
public:
void _register_system_menus(NSMenu *p_main_menu, NSMenu *p_application_menu, NSMenu *p_window_menu, NSMenu *p_help_menu, NSMenu *p_dock_menu);
NSMenu *_get_dock_menu();
void _menu_open(NSMenu *p_menu);
void _menu_close(NSMenu *p_menu);
virtual bool has_feature(Feature p_feature) const override;
virtual bool has_system_menu(SystemMenus p_menu_id) const override;
virtual RID get_system_menu(SystemMenus p_menu_id) const override;
virtual RID create_menu() override;
virtual bool has_menu(const RID &p_rid) const override;
virtual void free_menu(const RID &p_rid) override;
virtual Size2 get_size(const RID &p_rid) const override;
virtual void popup(const RID &p_rid, const Vector2i &p_position) override;
virtual void set_popup_open_callback(const RID &p_rid, const Callable &p_callback) override;
virtual Callable get_popup_open_callback(const RID &p_rid) const override;
virtual void set_popup_close_callback(const RID &p_rid, const Callable &p_callback) override;
virtual Callable get_popup_close_callback(const RID &p_rid) const override;
virtual void set_minimum_width(const RID &p_rid, float p_width) override;
virtual float get_minimum_width(const RID &p_rid) const override;
virtual int add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag = Variant(), int p_index = -1) override;
virtual int add_item(const RID &p_rid, 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 add_check_item(const RID &p_rid, 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 add_icon_item(const RID &p_rid, 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 add_icon_check_item(const RID &p_rid, 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 add_radio_check_item(const RID &p_rid, 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 add_icon_radio_check_item(const RID &p_rid, 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 add_multistate_item(const RID &p_rid, 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 add_separator(const RID &p_rid, int p_index = -1) override;
virtual int find_item_index_with_text(const RID &p_rid, const String &p_text) const override;
virtual int find_item_index_with_tag(const RID &p_rid, const Variant &p_tag) const override;
virtual bool is_item_checked(const RID &p_rid, int p_idx) const override;
virtual bool is_item_checkable(const RID &p_rid, int p_idx) const override;
virtual bool is_item_radio_checkable(const RID &p_rid, int p_idx) const override;
virtual Callable get_item_callback(const RID &p_rid, int p_idx) const override;
virtual Callable get_item_key_callback(const RID &p_rid, int p_idx) const override;
virtual Variant get_item_tag(const RID &p_rid, int p_idx) const override;
virtual String get_item_text(const RID &p_rid, int p_idx) const override;
virtual RID get_item_submenu(const RID &p_rid, int p_idx) const override;
virtual Key get_item_accelerator(const RID &p_rid, int p_idx) const override;
virtual bool is_item_disabled(const RID &p_rid, int p_idx) const override;
virtual bool is_item_hidden(const RID &p_rid, int p_idx) const override;
virtual String get_item_tooltip(const RID &p_rid, int p_idx) const override;
virtual int get_item_state(const RID &p_rid, int p_idx) const override;
virtual int get_item_max_states(const RID &p_rid, int p_idx) const override;
virtual Ref<Texture2D> get_item_icon(const RID &p_rid, int p_idx) const override;
virtual int get_item_indentation_level(const RID &p_rid, int p_idx) const override;
virtual void set_item_checked(const RID &p_rid, int p_idx, bool p_checked) override;
virtual void set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable) override;
virtual void set_item_radio_checkable(const RID &p_rid, int p_idx, bool p_checkable) override;
virtual void set_item_callback(const RID &p_rid, int p_idx, const Callable &p_callback) override;
virtual void set_item_key_callback(const RID &p_rid, int p_idx, const Callable &p_key_callback) override;
virtual void set_item_hover_callbacks(const RID &p_rid, int p_idx, const Callable &p_callback) override;
virtual void set_item_tag(const RID &p_rid, int p_idx, const Variant &p_tag) override;
virtual void set_item_text(const RID &p_rid, int p_idx, const String &p_text) override;
virtual void set_item_submenu(const RID &p_rid, int p_idx, const RID &p_submenu_rid) override;
virtual void set_item_accelerator(const RID &p_rid, int p_idx, Key p_keycode) override;
virtual void set_item_disabled(const RID &p_rid, int p_idx, bool p_disabled) override;
virtual void set_item_hidden(const RID &p_rid, int p_idx, bool p_hidden) override;
virtual void set_item_tooltip(const RID &p_rid, int p_idx, const String &p_tooltip) override;
virtual void set_item_state(const RID &p_rid, int p_idx, int p_state) override;
virtual void set_item_max_states(const RID &p_rid, int p_idx, int p_max_states) override;
virtual void set_item_icon(const RID &p_rid, int p_idx, const Ref<Texture2D> &p_icon) override;
virtual void set_item_indentation_level(const RID &p_rid, int p_idx, int p_level) override;
virtual int get_item_count(const RID &p_rid) const override;
virtual bool is_system_menu(const RID &p_rid) const override;
virtual void remove_item(const RID &p_rid, int p_idx) override;
virtual void clear(const RID &p_rid) override;
NativeMenuMacOS();
~NativeMenuMacOS();
};
#endif // NATIVE_MENU_MACOS_H

File diff suppressed because it is too large Load Diff

View File

@ -1030,6 +1030,7 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
r_error = OK; // Always succeeds for now.
tts = GLOBAL_GET("audio/general/text_to_speech");
native_menu = memnew(NativeMenu); // Dummy native menu.
// Ensure the canvas ID.
godot_js_config_canvas_id_get(canvas_id, 256);
@ -1098,6 +1099,10 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
}
DisplayServerWeb::~DisplayServerWeb() {
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
#ifdef GLES3_ENABLED
if (webgl_ctx) {
emscripten_webgl_commit_frame();
@ -1108,7 +1113,11 @@ DisplayServerWeb::~DisplayServerWeb() {
bool DisplayServerWeb::has_feature(Feature p_feature) const {
switch (p_feature) {
//case FEATURE_GLOBAL_MENU:
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
//case FEATURE_HIDPI:
case FEATURE_ICON:
case FEATURE_CLIPBOARD:

View File

@ -104,6 +104,7 @@ private:
bool swap_cancel_ok = false;
bool tts = false;
NativeMenu *native_menu = nullptr;
// utilities
static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode);

View File

@ -96,6 +96,11 @@ static void track_mouse_leave_event(HWND hWnd) {
bool DisplayServerWindows::has_feature(Feature p_feature) const {
switch (p_feature) {
#ifndef DISABLE_DEPRECATED
case FEATURE_GLOBAL_MENU: {
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
} break;
#endif
case FEATURE_SUBWINDOWS:
case FEATURE_TOUCHSCREEN:
case FEATURE_MOUSE:
@ -5465,6 +5470,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
if (tts_enabled) {
tts = memnew(TTS_Windows);
}
native_menu = memnew(NativeMenu);
// Enforce default keep screen on value.
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
@ -5841,6 +5847,11 @@ DisplayServerWindows::~DisplayServerWindows() {
// Close power request handle.
screen_set_keep_on(false);
if (native_menu) {
memdelete(native_menu);
native_menu = nullptr;
}
#ifdef GLES3_ENABLED
// destroy windows .. NYI?
// FIXME wglDeleteContext is never called

View File

@ -358,6 +358,7 @@ class DisplayServerWindows : public DisplayServer {
HANDLE power_request;
TTS_Windows *tts = nullptr;
NativeMenu *native_menu = nullptr;
struct WindowData {
HWND hWnd;

View File

@ -192,31 +192,33 @@ bool MenuBar::is_native_menu() const {
}
#endif
return (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU) && is_native);
return (NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU) && is_native);
}
String MenuBar::bind_global_menu() {
void MenuBar::bind_global_menu() {
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
return String();
return;
}
#endif
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
return String();
if (!NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
return;
}
if (!global_menu_name.is_empty()) {
return global_menu_name; // Already bound.
if (!global_menu_tag.is_empty()) {
return; // Already bound.
}
DisplayServer *ds = DisplayServer::get_singleton();
global_menu_name = "__MenuBar#" + itos(get_instance_id());
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
global_menu_tag = "__MenuBar#" + itos(get_instance_id());
int global_start_idx = -1;
int count = ds->global_menu_get_item_count("_main");
int count = nmenu->get_item_count(main_menu);
String prev_tag;
for (int i = 0; i < count; i++) {
String tag = ds->global_menu_get_item_tag("_main", i).operator String().get_slice("#", 1);
String tag = nmenu->get_item_tag(main_menu, i).operator String().get_slice("#", 1);
if (!tag.is_empty() && tag != prev_tag) {
if (i >= start_index) {
global_start_idx = i;
@ -231,40 +233,39 @@ String MenuBar::bind_global_menu() {
Vector<PopupMenu *> popups = _get_popups();
for (int i = 0; i < menu_cache.size(); i++) {
String submenu_name = popups[i]->bind_global_menu();
RID submenu_rid = popups[i]->bind_global_menu();
if (!popups[i]->is_system_menu()) {
int index = ds->global_menu_add_submenu_item("_main", menu_cache[i].name, submenu_name, global_start_idx + i);
int index = nmenu->add_submenu_item(main_menu, menu_cache[i].name, submenu_rid, global_menu_tag + "#" + itos(i), global_start_idx + i);
menu_cache.write[i].global_index = index;
ds->global_menu_set_item_tag("_main", index, global_menu_name + "#" + itos(i));
ds->global_menu_set_item_hidden("_main", index, menu_cache[i].hidden);
ds->global_menu_set_item_disabled("_main", index, menu_cache[i].disabled);
ds->global_menu_set_item_tooltip("_main", index, menu_cache[i].tooltip);
nmenu->set_item_hidden(main_menu, index, menu_cache[i].hidden);
nmenu->set_item_disabled(main_menu, index, menu_cache[i].disabled);
nmenu->set_item_tooltip(main_menu, index, menu_cache[i].tooltip);
} else {
menu_cache.write[i].global_index = -1;
}
}
return global_menu_name;
}
void MenuBar::unbind_global_menu() {
if (global_menu_name.is_empty()) {
if (global_menu_tag.is_empty()) {
return;
}
DisplayServer *ds = DisplayServer::get_singleton();
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
Vector<PopupMenu *> popups = _get_popups();
for (int i = menu_cache.size() - 1; i >= 0; i--) {
if (!popups[i]->is_system_menu()) {
popups[i]->unbind_global_menu();
if (menu_cache[i].global_index >= 0) {
ds->global_menu_remove_item("_main", menu_cache[i].global_index);
nmenu->remove_item(main_menu, menu_cache[i].global_index);
}
menu_cache.write[i].global_index = -1;
}
}
global_menu_name = String();
global_menu_tag = String();
}
void MenuBar::_notification(int p_what) {
@ -286,12 +287,13 @@ void MenuBar::_notification(int p_what) {
queue_redraw();
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
DisplayServer *ds = DisplayServer::get_singleton();
bool is_global = !global_menu_name.is_empty();
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
bool is_global = !global_menu_tag.is_empty();
for (int i = 0; i < menu_cache.size(); i++) {
shape(menu_cache.write[i]);
if (is_global && menu_cache[i].global_index >= 0) {
ds->global_menu_set_item_text("_main", menu_cache[i].global_index, atr(menu_cache[i].name));
nmenu->set_item_text(main_menu, menu_cache[i].global_index, atr(menu_cache[i].name));
}
}
} break;
@ -489,8 +491,9 @@ void MenuBar::shape(Menu &p_menu) {
}
void MenuBar::_refresh_menu_names() {
DisplayServer *ds = DisplayServer::get_singleton();
bool is_global = !global_menu_name.is_empty();
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
bool is_global = !global_menu_tag.is_empty();
Vector<PopupMenu *> popups = _get_popups();
for (int i = 0; i < popups.size(); i++) {
@ -498,7 +501,7 @@ void MenuBar::_refresh_menu_names() {
menu_cache.write[i].name = popups[i]->get_name();
shape(menu_cache.write[i]);
if (is_global && menu_cache[i].global_index >= 0) {
ds->global_menu_set_item_text("_main", menu_cache[i].global_index, atr(menu_cache[i].name));
nmenu->set_item_text(main_menu, menu_cache[i].global_index, atr(menu_cache[i].name));
}
}
}
@ -545,12 +548,14 @@ void MenuBar::add_child_notify(Node *p_child) {
p_child->connect("about_to_popup", callable_mp(this, &MenuBar::_popup_visibility_changed).bind(true));
p_child->connect("popup_hide", callable_mp(this, &MenuBar::_popup_visibility_changed).bind(false));
if (!global_menu_name.is_empty()) {
String submenu_name = pm->bind_global_menu();
if (!global_menu_tag.is_empty()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
RID submenu_rid = pm->bind_global_menu();
if (!pm->is_system_menu()) {
int index = DisplayServer::get_singleton()->global_menu_add_submenu_item("_main", atr(menu.name), submenu_name, _find_global_start_index() + menu_cache.size() - 1);
int index = nmenu->add_submenu_item(main_menu, atr(menu.name), submenu_rid, global_menu_tag + "#" + itos(menu_cache.size() - 1), _find_global_start_index() + menu_cache.size() - 1);
menu_cache.write[menu_cache.size() - 1].global_index = index;
DisplayServer::get_singleton()->global_menu_set_item_tag("_main", index, global_menu_name + "#" + itos(menu_cache.size() - 1));
}
}
update_minimum_size();
@ -578,17 +583,19 @@ void MenuBar::move_child_notify(Node *p_child) {
int new_idx = get_menu_idx_from_control(pm);
menu_cache.insert(new_idx, menu);
if (!global_menu_name.is_empty()) {
if (!global_menu_tag.is_empty()) {
if (!pm->is_system_menu()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
int global_start = _find_global_start_index();
if (menu.global_index >= 0) {
DisplayServer::get_singleton()->global_menu_remove_item("_main", menu.global_index);
nmenu->remove_item(main_menu, menu.global_index);
}
if (new_idx != -1) {
String submenu_name = pm->bind_global_menu();
int index = DisplayServer::get_singleton()->global_menu_add_submenu_item("_main", atr(menu.name), submenu_name, global_start + new_idx);
RID submenu_rid = pm->bind_global_menu();
int index = nmenu->add_submenu_item(main_menu, atr(menu.name), submenu_rid, global_menu_tag + "#" + itos(new_idx), global_start + new_idx);
menu_cache.write[new_idx].global_index = index;
DisplayServer::get_singleton()->global_menu_set_item_tag("_main", index, global_menu_name + "#" + itos(new_idx));
}
}
}
@ -606,11 +613,13 @@ void MenuBar::remove_child_notify(Node *p_child) {
menu_cache.remove_at(idx);
if (!global_menu_name.is_empty()) {
if (!global_menu_tag.is_empty()) {
if (!pm->is_system_menu()) {
pm->unbind_global_menu();
if (menu_cache[idx].global_index >= 0) {
DisplayServer::get_singleton()->global_menu_remove_item("_main", menu_cache[idx].global_index);
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->remove_item(main_menu, menu_cache[idx].global_index);
menu_cache.write[idx].global_index = -1;
}
}
@ -746,7 +755,7 @@ bool MenuBar::is_flat() const {
void MenuBar::set_start_index(int p_index) {
if (start_index != p_index) {
start_index = p_index;
if (!global_menu_name.is_empty()) {
if (!global_menu_tag.is_empty()) {
unbind_global_menu();
bind_global_menu();
}
@ -808,8 +817,10 @@ void MenuBar::set_menu_title(int p_menu, const String &p_title) {
}
menu_cache.write[p_menu].name = p_title;
shape(menu_cache.write[p_menu]);
if (!global_menu_name.is_empty() && menu_cache[p_menu].global_index >= 0) {
DisplayServer::get_singleton()->global_menu_set_item_text("_main", menu_cache[p_menu].global_index, atr(menu_cache[p_menu].name));
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_text(main_menu, menu_cache[p_menu].global_index, atr(menu_cache[p_menu].name));
}
update_minimum_size();
}
@ -824,8 +835,10 @@ void MenuBar::set_menu_tooltip(int p_menu, const String &p_tooltip) {
PopupMenu *pm = get_menu_popup(p_menu);
pm->set_meta("_menu_tooltip", p_tooltip);
menu_cache.write[p_menu].tooltip = p_tooltip;
if (!global_menu_name.is_empty() && menu_cache[p_menu].global_index >= 0) {
DisplayServer::get_singleton()->global_menu_set_item_tooltip("_main", menu_cache[p_menu].global_index, p_tooltip);
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_tooltip(main_menu, menu_cache[p_menu].global_index, p_tooltip);
}
}
@ -837,8 +850,10 @@ String MenuBar::get_menu_tooltip(int p_menu) const {
void MenuBar::set_menu_disabled(int p_menu, bool p_disabled) {
ERR_FAIL_INDEX(p_menu, menu_cache.size());
menu_cache.write[p_menu].disabled = p_disabled;
if (!global_menu_name.is_empty() && menu_cache[p_menu].global_index >= 0) {
DisplayServer::get_singleton()->global_menu_set_item_disabled("_main", menu_cache[p_menu].global_index, p_disabled);
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_disabled(main_menu, menu_cache[p_menu].global_index, p_disabled);
}
}
@ -850,8 +865,10 @@ bool MenuBar::is_menu_disabled(int p_menu) const {
void MenuBar::set_menu_hidden(int p_menu, bool p_hidden) {
ERR_FAIL_INDEX(p_menu, menu_cache.size());
menu_cache.write[p_menu].hidden = p_hidden;
if (!global_menu_name.is_empty() && menu_cache[p_menu].global_index >= 0) {
DisplayServer::get_singleton()->global_menu_set_item_hidden("_main", menu_cache[p_menu].global_index, p_hidden);
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_hidden(main_menu, menu_cache[p_menu].global_index, p_hidden);
}
update_minimum_size();
}

View File

@ -114,23 +114,30 @@ class MenuBar : public Control {
void _open_popup(int p_index, bool p_focus_item = false);
void _popup_visibility_changed(bool p_visible);
String global_menu_name;
String global_menu_tag;
int _find_global_start_index() {
if (global_menu_name.is_empty()) {
if (global_menu_tag.is_empty()) {
return -1;
}
DisplayServer *ds = DisplayServer::get_singleton();
int count = ds->global_menu_get_item_count("_main");
NativeMenu *nmenu = NativeMenu::get_singleton();
if (!nmenu) {
return -1;
}
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
int count = nmenu->get_item_count(main_menu);
for (int i = 0; i < count; i++) {
if (ds->global_menu_get_item_tag("_main", i).operator String().begins_with(global_menu_name)) {
if (nmenu->get_item_tag(main_menu, i).operator String().begins_with(global_menu_tag)) {
return i;
}
}
return -1;
}
void bind_global_menu();
void unbind_global_menu();
protected:
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
@ -143,9 +150,6 @@ protected:
public:
virtual void gui_input(const Ref<InputEvent> &p_event) override;
String bind_global_menu();
void unbind_global_menu();
void set_switch_on_hover(bool p_enabled);
bool is_switch_on_hover();
void set_disable_shortcuts(bool p_disabled);

View File

@ -42,10 +42,40 @@ void PopupMenu::_clear_bind_compat_79965() {
clear(false);
}
void PopupMenu::_set_system_menu_root_compat_87452(const String &p_special) {
if (p_special == "_dock") {
set_system_menu(NativeMenu::DOCK_MENU_ID);
} else if (p_special == "_apple") {
set_system_menu(NativeMenu::APPLICATION_MENU_ID);
} else if (p_special == "_window") {
set_system_menu(NativeMenu::WINDOW_MENU_ID);
} else if (p_special == "_help") {
set_system_menu(NativeMenu::HELP_MENU_ID);
}
}
String PopupMenu::_get_system_menu_root_compat_87452() const {
switch (get_system_menu()) {
case NativeMenu::APPLICATION_MENU_ID:
return "_apple";
case NativeMenu::WINDOW_MENU_ID:
return "_window";
case NativeMenu::HELP_MENU_ID:
return "_help";
case NativeMenu::DOCK_MENU_ID:
return "_dock";
default:
return "";
}
}
void PopupMenu::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::_add_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_compatibility_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::_add_icon_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_compatibility_method(D_METHOD("clear"), &PopupMenu::_clear_bind_compat_79965);
ClassDB::bind_compatibility_method(D_METHOD("set_system_menu_root", "special"), &PopupMenu::_set_system_menu_root_compat_87452);
ClassDB::bind_compatibility_method(D_METHOD("get_system_menu_root"), &PopupMenu::_get_system_menu_root_compat_87452);
}
#endif

View File

@ -40,18 +40,18 @@
#include "scene/gui/menu_bar.h"
#include "scene/theme/theme_db.h"
HashMap<String, PopupMenu *> PopupMenu::system_menus;
HashMap<NativeMenu::SystemMenus, PopupMenu *> PopupMenu::system_menus;
bool PopupMenu::_set_item_accelerator(int p_index, const Ref<InputEventKey> &p_ie) {
DisplayServer *ds = DisplayServer::get_singleton();
NativeMenu *nmenu = NativeMenu::get_singleton();
if (p_ie->get_physical_keycode() == Key::NONE && p_ie->get_keycode() == Key::NONE && p_ie->get_key_label() != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, p_index, p_ie->get_key_label_with_modifiers());
nmenu->set_item_accelerator(global_menu, p_index, p_ie->get_key_label_with_modifiers());
return true;
} else if (p_ie->get_keycode() != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, p_index, p_ie->get_keycode_with_modifiers());
nmenu->set_item_accelerator(global_menu, p_index, p_ie->get_keycode_with_modifiers());
return true;
} else if (p_ie->get_physical_keycode() != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, p_index, ds->keyboard_get_keycode_from_physical(p_ie->get_physical_keycode_with_modifiers()));
nmenu->set_item_accelerator(global_menu, p_index, DisplayServer::get_singleton()->keyboard_get_keycode_from_physical(p_ie->get_physical_keycode_with_modifiers()));
return true;
}
return false;
@ -76,58 +76,60 @@ int PopupMenu::_get_item_checkable_type(int p_index) const {
return items[p_index].checkable_type;
}
String PopupMenu::bind_global_menu() {
RID PopupMenu::bind_global_menu() {
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
return String();
return RID();
}
#endif
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
return String();
if (!NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU)) {
return RID();
}
if (!global_menu_name.is_empty()) {
return global_menu_name; // Already bound;
if (global_menu.is_valid()) {
return global_menu; // Already bound;
}
global_menu_name = "__PopupMenu#" + itos(get_instance_id());
if (system_menu_name.length() > 0) {
if (system_menus.has(system_menu_name)) {
WARN_PRINT(vformat("Attempting to bind PopupMenu to the special menu %s, but another menu is already bound to it. This menu: %s, current menu: %s", system_menu_name, get_description(), system_menus[system_menu_name]->get_description()));
NativeMenu *nmenu = NativeMenu::get_singleton();
if (system_menu_id != NativeMenu::INVALID_MENU_ID) {
if (system_menus.has(system_menu_id)) {
WARN_PRINT(vformat("Attempting to bind PopupMenu to the system menu %s, but another menu is already bound to it. This menu: %s, current menu: %s", nmenu->get_system_menu_name(system_menu_id), get_description(), system_menus[system_menu_id]->get_description()));
global_menu = nmenu->create_menu();
} else {
const Dictionary &supported_special_names = DisplayServer::get_singleton()->global_menu_get_system_menu_roots();
if (supported_special_names.has(system_menu_name)) {
system_menus[system_menu_name] = this;
global_menu_name = system_menu_name;
}
system_menus[system_menu_id] = this;
system_menu = nmenu->get_system_menu(system_menu_id);
global_menu = system_menu;
}
} else {
global_menu = nmenu->create_menu();
}
DisplayServer *ds = DisplayServer::get_singleton();
ds->global_menu_set_popup_callbacks(global_menu_name, callable_mp(this, &PopupMenu::_about_to_popup), callable_mp(this, &PopupMenu::_about_to_close));
nmenu->set_popup_open_callback(global_menu, callable_mp(this, &PopupMenu::_about_to_popup));
nmenu->set_popup_close_callback(global_menu, callable_mp(this, &PopupMenu::_about_to_close));
for (int i = 0; i < items.size(); i++) {
Item &item = items.write[i];
if (item.separator) {
ds->global_menu_add_separator(global_menu_name);
nmenu->add_separator(global_menu);
} else {
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), item.shortcut_is_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), i);
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), item.shortcut_is_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), i);
if (item.submenu) {
String submenu_name = item.submenu->bind_global_menu();
ds->global_menu_set_item_submenu(global_menu_name, index, submenu_name);
RID submenu_rid = item.submenu->bind_global_menu();
nmenu->set_item_submenu(global_menu, index, submenu_rid);
item.submenu_bound = true;
}
if (item.checkable_type == Item::CHECKABLE_TYPE_CHECK_BOX) {
ds->global_menu_set_item_checkable(global_menu_name, index, true);
nmenu->set_item_checkable(global_menu, index, true);
} else if (item.checkable_type == Item::CHECKABLE_TYPE_RADIO_BUTTON) {
ds->global_menu_set_item_radio_checkable(global_menu_name, index, true);
nmenu->set_item_radio_checkable(global_menu, index, true);
}
ds->global_menu_set_item_checked(global_menu_name, index, item.checked);
ds->global_menu_set_item_disabled(global_menu_name, index, item.disabled);
ds->global_menu_set_item_max_states(global_menu_name, index, item.max_states);
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
ds->global_menu_set_item_state(global_menu_name, index, item.state);
ds->global_menu_set_item_indentation_level(global_menu_name, index, item.indent);
ds->global_menu_set_item_tooltip(global_menu_name, index, item.tooltip);
nmenu->set_item_checked(global_menu, index, item.checked);
nmenu->set_item_disabled(global_menu, index, item.disabled);
nmenu->set_item_max_states(global_menu, index, item.max_states);
nmenu->set_item_icon(global_menu, index, item.icon);
nmenu->set_item_state(global_menu, index, item.state);
nmenu->set_item_indentation_level(global_menu, index, item.indent);
nmenu->set_item_tooltip(global_menu, index, item.tooltip);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -137,20 +139,20 @@ String PopupMenu::bind_global_menu() {
}
}
} else if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
}
}
return global_menu_name;
return global_menu;
}
void PopupMenu::unbind_global_menu() {
if (global_menu_name.is_empty()) {
if (global_menu.is_null()) {
return;
}
if (global_menu_name == system_menu_name && system_menus[system_menu_name] == this) {
system_menus.erase(system_menu_name);
if (global_menu == system_menu && system_menus[system_menu_id] == this) {
system_menus.erase(system_menu_id);
}
for (int i = 0; i < items.size(); i++) {
@ -160,27 +162,32 @@ void PopupMenu::unbind_global_menu() {
item.submenu_bound = false;
}
}
DisplayServer::get_singleton()->global_menu_clear(global_menu_name);
if (system_menu != global_menu) {
NativeMenu::get_singleton()->free_menu(global_menu);
} else {
NativeMenu::get_singleton()->clear(global_menu);
}
global_menu_name = String();
system_menu = RID();
global_menu = RID();
}
bool PopupMenu::is_system_menu() const {
return (global_menu_name == system_menu_name) && (system_menu_name.length() > 0);
return (global_menu == system_menu) && (system_menu_id != NativeMenu::INVALID_MENU_ID);
}
void PopupMenu::set_system_menu_root(const String &p_special) {
if (is_inside_tree() && system_menu_name.length() > 0) {
void PopupMenu::set_system_menu(NativeMenu::SystemMenus p_system_menu_id) {
if (is_inside_tree() && system_menu_id != NativeMenu::INVALID_MENU_ID) {
unbind_global_menu();
}
system_menu_name = p_special;
if (is_inside_tree() && system_menu_name.length() > 0) {
system_menu_id = p_system_menu_id;
if (is_inside_tree() && system_menu_id != NativeMenu::INVALID_MENU_ID) {
bind_global_menu();
}
}
String PopupMenu::get_system_menu_root() const {
return system_menu_name;
NativeMenu::SystemMenus PopupMenu::get_system_menu() const {
return system_menu_id;
}
String PopupMenu::_get_accel_text(const Item &p_item) const {
@ -956,15 +963,12 @@ void PopupMenu::_menu_changed() {
void PopupMenu::add_child_notify(Node *p_child) {
Window::add_child_notify(p_child);
PopupMenu *pm = Object::cast_to<PopupMenu>(p_child);
if (!pm) {
return;
}
if (!global_menu_name.is_empty()) {
if (global_menu.is_valid()) {
PopupMenu *pm = Object::cast_to<PopupMenu>(p_child);
for (int i = 0; i < items.size(); i++) {
if (items[i].submenu == p_child) {
String submenu_name = pm->bind_global_menu();
DisplayServer::get_singleton()->global_menu_set_item_submenu(global_menu_name, i, submenu_name);
RID submenu_rid = pm->bind_global_menu();
NativeMenu::get_singleton()->set_item_submenu(global_menu, i, submenu_rid);
items.write[i].submenu_bound = true;
}
}
@ -979,10 +983,10 @@ void PopupMenu::remove_child_notify(Node *p_child) {
if (!pm) {
return;
}
if (Object::cast_to<PopupMenu>(p_child) && !global_menu_name.is_empty()) {
if (Object::cast_to<PopupMenu>(p_child) && global_menu.is_valid()) {
for (int i = 0; i < items.size(); i++) {
if (items[i].submenu == p_child) {
DisplayServer::get_singleton()->global_menu_set_item_submenu(global_menu_name, i, String());
NativeMenu::get_singleton()->set_item_submenu(global_menu, i, RID());
items.write[i].submenu_bound = false;
}
}
@ -1003,13 +1007,13 @@ void PopupMenu::_notification(int p_what) {
if (!is_embedded()) {
set_flag(FLAG_NO_FOCUS, true);
}
if (system_menu_name.length() > 0) {
if (system_menu_id != NativeMenu::INVALID_MENU_ID) {
bind_global_menu();
}
} break;
case NOTIFICATION_EXIT_TREE: {
if (system_menu_name.length() > 0) {
if (system_menu_id != NativeMenu::INVALID_MENU_ID) {
unbind_global_menu();
}
} break;
@ -1021,14 +1025,14 @@ void PopupMenu::_notification(int p_what) {
}
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
DisplayServer *ds = DisplayServer::get_singleton();
bool is_global = !global_menu_name.is_empty();
NativeMenu *nmenu = NativeMenu::get_singleton();
bool is_global = global_menu.is_valid();
for (int i = 0; i < items.size(); i++) {
Item &item = items.write[i];
item.xl_text = atr(item.text);
item.dirty = true;
if (is_global) {
ds->global_menu_set_item_text(global_menu_name, i, item.xl_text);
nmenu->set_item_text(global_menu, i, item.xl_text);
}
_shape_item(i);
}
@ -1184,11 +1188,11 @@ void PopupMenu::add_item(const String &p_label, int p_id, Key p_accel) {
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
}
@ -1206,13 +1210,13 @@ void PopupMenu::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_labe
item.icon = p_icon;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
nmenu->set_item_icon(global_menu, index, item.icon);
}
_shape_item(items.size() - 1);
@ -1229,13 +1233,13 @@ void PopupMenu::add_check_item(const String &p_label, int p_id, Key p_accel) {
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_checkable(global_menu_name, index, true);
nmenu->set_item_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1253,14 +1257,14 @@ void PopupMenu::add_icon_check_item(const Ref<Texture2D> &p_icon, const String &
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
ds->global_menu_set_item_checkable(global_menu_name, index, true);
nmenu->set_item_icon(global_menu, index, item.icon);
nmenu->set_item_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1277,13 +1281,13 @@ void PopupMenu::add_radio_check_item(const String &p_label, int p_id, Key p_acce
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_radio_checkable(global_menu_name, index, true);
nmenu->set_item_radio_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1301,14 +1305,14 @@ void PopupMenu::add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const St
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
ds->global_menu_set_item_radio_checkable(global_menu_name, index, true);
nmenu->set_item_icon(global_menu, index, item.icon);
nmenu->set_item_radio_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1326,14 +1330,14 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
item.state = p_default_state;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
if (item.accel != Key::NONE) {
ds->global_menu_set_item_accelerator(global_menu_name, index, item.accel);
nmenu->set_item_accelerator(global_menu, index, item.accel);
}
ds->global_menu_set_item_max_states(global_menu_name, index, item.max_states);
ds->global_menu_set_item_state(global_menu_name, index, item.state);
nmenu->set_item_max_states(global_menu, index, item.max_states);
nmenu->set_item_state(global_menu, index, item.state);
}
_shape_item(items.size() - 1);
@ -1359,9 +1363,9 @@ void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_g
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo);
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1387,9 +1391,9 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortc
item.icon = p_icon;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1399,7 +1403,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortc
}
}
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
nmenu->set_item_icon(global_menu, index, item.icon);
}
_shape_item(items.size() - 1);
@ -1416,9 +1420,9 @@ void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bo
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1428,7 +1432,7 @@ void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bo
}
}
}
ds->global_menu_set_item_checkable(global_menu_name, index, true);
nmenu->set_item_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1446,9 +1450,9 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1458,8 +1462,8 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
}
}
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
ds->global_menu_set_item_checkable(global_menu_name, index, true);
nmenu->set_item_icon(global_menu, index, item.icon);
nmenu->set_item_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1476,9 +1480,9 @@ void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1488,7 +1492,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_
}
}
}
ds->global_menu_set_item_radio_checkable(global_menu_name, index, true);
nmenu->set_item_radio_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1506,9 +1510,9 @@ void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, cons
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), p_global ? callable_mp(this, &PopupMenu::activate_item) : Callable(), items.size() - 1);
if (!item.shortcut_is_disabled && item.shortcut.is_valid() && item.shortcut->has_valid_event()) {
Array events = item.shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -1518,8 +1522,8 @@ void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, cons
}
}
}
ds->global_menu_set_item_icon(global_menu_name, index, item.icon);
ds->global_menu_set_item_radio_checkable(global_menu_name, index, true);
nmenu->set_item_icon(global_menu, index, item.icon);
nmenu->set_item_radio_checkable(global_menu, index, true);
}
_shape_item(items.size() - 1);
@ -1553,11 +1557,11 @@ void PopupMenu::add_submenu_node_item(const String &p_label, PopupMenu *p_submen
item.submenu_name = p_submenu->get_name();
items.push_back(item);
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
int index = ds->global_menu_add_item(global_menu_name, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
String submenu_name = p_submenu->bind_global_menu();
ds->global_menu_set_item_submenu(global_menu_name, index, submenu_name);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
int index = nmenu->add_item(global_menu, item.xl_text, callable_mp(this, &PopupMenu::activate_item), Callable(), items.size() - 1);
RID submenu_rid = p_submenu->bind_global_menu();
nmenu->set_item_submenu(global_menu, index, submenu_rid);
items.write[index].submenu_bound = true;
}
@ -1586,8 +1590,8 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
items.write[p_idx].xl_text = atr(p_text);
items.write[p_idx].dirty = true;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_text(global_menu_name, p_idx, items[p_idx].xl_text);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_text(global_menu, p_idx, items[p_idx].xl_text);
}
_shape_item(p_idx);
@ -1633,8 +1637,8 @@ void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
items.write[p_idx].icon = p_icon;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_icon(global_menu_name, p_idx, items[p_idx].icon);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_icon(global_menu, p_idx, items[p_idx].icon);
}
control->queue_redraw();
@ -1685,8 +1689,8 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
items.write[p_idx].checked = p_checked;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_checked(global_menu_name, p_idx, p_checked);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_checked(global_menu, p_idx, p_checked);
}
control->queue_redraw();
@ -1706,8 +1710,8 @@ void PopupMenu::set_item_id(int p_idx, int p_id) {
items.write[p_idx].id = p_id;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_tag(global_menu_name, p_idx, p_id);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_tag(global_menu, p_idx, p_id);
}
control->queue_redraw();
@ -1728,8 +1732,8 @@ void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) {
items.write[p_idx].accel = p_accel;
items.write[p_idx].dirty = true;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_accelerator(global_menu_name, p_idx, p_accel);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_accelerator(global_menu, p_idx, p_accel);
}
control->queue_redraw();
@ -1764,8 +1768,8 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
items.write[p_idx].disabled = p_disabled;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_disabled(global_menu_name, p_idx, p_disabled);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_disabled(global_menu, p_idx, p_disabled);
}
control->queue_redraw();
@ -1801,11 +1805,11 @@ void PopupMenu::set_item_submenu_node(int p_idx, PopupMenu *p_submenu) {
add_child(p_submenu);
}
if (!global_menu_name.is_empty()) {
if (global_menu.is_valid()) {
if (items[p_idx].submenu_bound) {
PopupMenu *pm = items[p_idx].submenu;
if (pm) {
DisplayServer::get_singleton()->global_menu_set_item_submenu(global_menu_name, p_idx, String());
NativeMenu::get_singleton()->set_item_submenu(global_menu, p_idx, RID());
pm->unbind_global_menu();
}
items.write[p_idx].submenu_bound = false;
@ -1814,10 +1818,11 @@ void PopupMenu::set_item_submenu_node(int p_idx, PopupMenu *p_submenu) {
items.write[p_idx].submenu = p_submenu;
if (!global_menu_name.is_empty()) {
if (items[p_idx].submenu) {
String submenu_name = p_submenu->bind_global_menu();
DisplayServer::get_singleton()->global_menu_set_item_submenu(global_menu_name, p_idx, submenu_name);
if (global_menu.is_valid()) {
PopupMenu *pm = items[p_idx].submenu;
if (pm) {
RID submenu_rid = pm->bind_global_menu();
NativeMenu::get_singleton()->set_item_submenu(global_menu, p_idx, submenu_rid);
items.write[p_idx].submenu_bound = true;
}
}
@ -1831,8 +1836,8 @@ void PopupMenu::toggle_item_checked(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checked = !items[p_idx].checked;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_checked(global_menu_name, p_idx, items[p_idx].checked);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_checked(global_menu, p_idx, items[p_idx].checked);
}
control->queue_redraw();
@ -1987,8 +1992,8 @@ void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) {
items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_checkable(global_menu_name, p_idx, p_checkable);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_checkable(global_menu, p_idx, p_checkable);
}
control->queue_redraw();
@ -2008,8 +2013,8 @@ void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) {
items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_radio_checkable(global_menu_name, p_idx, p_radio_checkable);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_radio_checkable(global_menu, p_idx, p_radio_checkable);
}
control->queue_redraw();
@ -2028,8 +2033,8 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
items.write[p_idx].tooltip = p_tooltip;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_tooltip(global_menu_name, p_idx, p_tooltip);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_tooltip(global_menu, p_idx, p_tooltip);
}
control->queue_redraw();
@ -2057,9 +2062,9 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo
_ref_shortcut(items[p_idx].shortcut);
}
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
ds->global_menu_set_item_accelerator(global_menu_name, p_idx, Key::NONE);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
nmenu->set_item_accelerator(global_menu, p_idx, Key::NONE);
if (!items[p_idx].shortcut_is_disabled && items[p_idx].shortcut.is_valid() && items[p_idx].shortcut->has_valid_event()) {
Array events = items[p_idx].shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -2069,9 +2074,9 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo
}
}
if (p_global) {
ds->global_menu_set_item_key_callback(global_menu_name, p_idx, callable_mp(this, &PopupMenu::activate_item));
nmenu->set_item_key_callback(global_menu, p_idx, callable_mp(this, &PopupMenu::activate_item));
} else {
ds->global_menu_set_item_key_callback(global_menu_name, p_idx, Callable());
nmenu->set_item_key_callback(global_menu, p_idx, Callable());
}
}
}
@ -2091,8 +2096,8 @@ void PopupMenu::set_item_indent(int p_idx, int p_indent) {
}
items.write[p_idx].indent = p_indent;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_indentation_level(global_menu_name, p_idx, p_indent);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_indentation_level(global_menu, p_idx, p_indent);
}
control->queue_redraw();
@ -2112,8 +2117,8 @@ void PopupMenu::set_item_max_states(int p_idx, int p_max_states) {
items.write[p_idx].max_states = p_max_states;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_max_states(global_menu_name, p_idx, p_max_states);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_max_states(global_menu, p_idx, p_max_states);
}
control->queue_redraw();
@ -2132,8 +2137,8 @@ void PopupMenu::set_item_multistate(int p_idx, int p_state) {
items.write[p_idx].state = p_state;
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_state(global_menu_name, p_idx, p_state);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_state(global_menu, p_idx, p_state);
}
control->queue_redraw();
@ -2152,9 +2157,9 @@ void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) {
items.write[p_idx].shortcut_is_disabled = p_disabled;
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
ds->global_menu_set_item_accelerator(global_menu_name, p_idx, Key::NONE);
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
nmenu->set_item_accelerator(global_menu, p_idx, Key::NONE);
if (!items[p_idx].shortcut_is_disabled && items[p_idx].shortcut.is_valid() && items[p_idx].shortcut->has_valid_event()) {
Array events = items[p_idx].shortcut->get_events();
for (int j = 0; j < events.size(); j++) {
@ -2181,8 +2186,8 @@ void PopupMenu::toggle_item_multistate(int p_idx) {
items.write[p_idx].state = 0;
}
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_set_item_state(global_menu_name, p_idx, items[p_idx].state);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->set_item_state(global_menu, p_idx, items[p_idx].state);
}
control->queue_redraw();
@ -2238,12 +2243,12 @@ void PopupMenu::set_item_count(int p_count) {
return;
}
DisplayServer *ds = DisplayServer::get_singleton();
bool is_global = !global_menu_name.is_empty();
NativeMenu *nmenu = NativeMenu::get_singleton();
bool is_global = global_menu.is_valid();
if (is_global && prev_size > p_count) {
for (int i = prev_size - 1; i >= p_count; i--) {
ds->global_menu_remove_item(global_menu_name, i);
nmenu->remove_item(global_menu, i);
}
}
@ -2253,7 +2258,7 @@ void PopupMenu::set_item_count(int p_count) {
for (int i = prev_size; i < p_count; i++) {
items.write[i].id = i;
if (is_global) {
ds->global_menu_add_item(global_menu_name, String(), callable_mp(this, &PopupMenu::activate_item), Callable(), i);
nmenu->add_item(global_menu, String(), callable_mp(this, &PopupMenu::activate_item), Callable(), i);
}
}
}
@ -2405,8 +2410,8 @@ void PopupMenu::remove_item(int p_idx) {
items.remove_at(p_idx);
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_remove_item(global_menu_name, p_idx);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->remove_item(global_menu, p_idx);
}
control->queue_redraw();
@ -2424,8 +2429,8 @@ void PopupMenu::add_separator(const String &p_text, int p_id) {
}
items.push_back(sep);
if (!global_menu_name.is_empty()) {
DisplayServer::get_singleton()->global_menu_add_separator(global_menu_name);
if (global_menu.is_valid()) {
NativeMenu::get_singleton()->add_separator(global_menu);
}
control->queue_redraw();
@ -2444,15 +2449,15 @@ void PopupMenu::clear(bool p_free_submenus) {
}
}
if (!global_menu_name.is_empty()) {
DisplayServer *ds = DisplayServer::get_singleton();
if (global_menu.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
for (int i = items.size() - 1; i >= 0; i--) {
Item &item = items.write[i];
if (item.submenu) {
item.submenu->unbind_global_menu();
item.submenu_bound = false;
}
ds->global_menu_remove_item(global_menu_name, i);
nmenu->remove_item(global_menu, i);
}
}
items.clear();
@ -2709,15 +2714,15 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_allow_search"), &PopupMenu::get_allow_search);
ClassDB::bind_method(D_METHOD("is_system_menu"), &PopupMenu::is_system_menu);
ClassDB::bind_method(D_METHOD("set_system_menu_root", "special"), &PopupMenu::set_system_menu_root);
ClassDB::bind_method(D_METHOD("get_system_menu_root"), &PopupMenu::get_system_menu_root);
ClassDB::bind_method(D_METHOD("set_system_menu", "system_menu_id"), &PopupMenu::set_system_menu);
ClassDB::bind_method(D_METHOD("get_system_menu"), &PopupMenu::get_system_menu);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_item_selection"), "set_hide_on_item_selection", "is_hide_on_item_selection");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_checkable_item_selection"), "set_hide_on_checkable_item_selection", "is_hide_on_checkable_item_selection");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "submenu_popup_delay", PROPERTY_HINT_NONE, "suffix:s"), "set_submenu_popup_delay", "get_submenu_popup_delay");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "system_menu_root", PROPERTY_HINT_ENUM, "Dock (macOS):_dock,Apple Menu(macOS):_apple,Window Menu(macOS):_window,Help Menu(macOS):_help"), "set_system_menu_root", "get_system_menu_root");
ADD_PROPERTY(PropertyInfo(Variant::INT, "system_menu_id", PROPERTY_HINT_ENUM, "Application Menu:2,Window Menu:3,Help Menu:4,Dock:5"), "set_system_menu", "get_system_menu");
ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_");
@ -2818,4 +2823,5 @@ PopupMenu::PopupMenu() {
}
PopupMenu::~PopupMenu() {
unbind_global_menu();
}

View File

@ -40,7 +40,7 @@
class PopupMenu : public Popup {
GDCLASS(PopupMenu, Popup);
static HashMap<String, PopupMenu *> system_menus;
static HashMap<NativeMenu::SystemMenus, PopupMenu *> system_menus;
struct Item {
Ref<Texture2D> icon;
@ -97,8 +97,9 @@ class PopupMenu : public Popup {
static inline PropertyListHelper base_property_helper;
PropertyListHelper property_helper;
String global_menu_name;
String system_menu_name;
RID global_menu;
RID system_menu;
NativeMenu::SystemMenus system_menu_id = NativeMenu::INVALID_MENU_ID;
bool close_allowed = false;
bool activated_by_keyboard = false;
@ -221,6 +222,10 @@ protected:
void _add_shortcut_bind_compat_36493(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void _add_icon_shortcut_bind_compat_36493(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void _clear_bind_compat_79965();
void _set_system_menu_root_compat_87452(const String &p_special);
String _get_system_menu_root_compat_87452() const;
static void _bind_compatibility_methods();
#endif
@ -231,11 +236,12 @@ public:
virtual void _parent_focused() override;
String bind_global_menu();
RID bind_global_menu();
void unbind_global_menu();
bool is_system_menu() const;
void set_system_menu_root(const String &p_special);
String get_system_menu_root() const;
void set_system_menu(NativeMenu::SystemMenus p_system_menu_id);
NativeMenu::SystemMenus get_system_menu() const;
void add_item(const String &p_label, int p_id = -1, Key p_accel = Key::NONE);
void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, Key p_accel = Key::NONE);

View File

@ -52,231 +52,352 @@ void DisplayServer::help_set_search_callbacks(const Callable &p_search_callback,
WARN_PRINT("Native help is not supported by this display server.");
}
#ifndef DISABLE_DEPRECATED
RID DisplayServer::_get_rid_from_name(NativeMenu *p_nmenu, const String &p_menu_root) const {
if (p_menu_root == "_main") {
return p_nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
} else if (p_menu_root == "_apple") {
return p_nmenu->get_system_menu(NativeMenu::APPLICATION_MENU_ID);
} else if (p_menu_root == "_dock") {
return p_nmenu->get_system_menu(NativeMenu::DOCK_MENU_ID);
} else if (p_menu_root == "_help") {
return p_nmenu->get_system_menu(NativeMenu::HELP_MENU_ID);
} else if (p_menu_root == "_window") {
return p_nmenu->get_system_menu(NativeMenu::WINDOW_MENU_ID);
} else if (menu_names.has(p_menu_root)) {
return menu_names[p_menu_root];
}
RID rid = p_nmenu->create_menu();
menu_names[p_menu_root] = rid;
return rid;
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_item(_get_rid_from_name(nmenu, p_menu_root), p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_check_item(_get_rid_from_name(nmenu, p_menu_root), p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_icon_item(_get_rid_from_name(nmenu, p_menu_root), p_icon, p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_icon_check_item(_get_rid_from_name(nmenu, p_menu_root), p_icon, p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_radio_check_item(_get_rid_from_name(nmenu, p_menu_root), p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_icon_radio_check_item(_get_rid_from_name(nmenu, p_menu_root), p_icon, p_label, p_callback, p_key_callback, p_tag, p_accel, 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_multistate_item(_get_rid_from_name(nmenu, p_menu_root), p_label, p_max_states, p_default_state, p_callback, p_key_callback, p_tag, p_accel, p_index);
}
void DisplayServer::global_menu_set_popup_callbacks(const String &p_menu_root, const Callable &p_open_callbacs, const Callable &p_close_callback) {
WARN_PRINT("Global menus not supported by this display server.");
void DisplayServer::global_menu_set_popup_callbacks(const String &p_menu_root, const Callable &p_open_callback, const Callable &p_close_callback) {
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_popup_open_callback(_get_rid_from_name(nmenu, p_menu_root), p_open_callback);
nmenu->set_popup_open_callback(_get_rid_from_name(nmenu, p_menu_root), p_close_callback);
}
int 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.");
return -1;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_submenu_item(_get_rid_from_name(nmenu, p_menu_root), p_label, _get_rid_from_name(nmenu, p_submenu), Variant(), p_index);
}
int DisplayServer::global_menu_add_separator(const String &p_menu_root, int p_index) {
WARN_PRINT("Global menus not supported by this display server.");
return -1;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->add_separator(_get_rid_from_name(nmenu, p_menu_root), p_index);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->find_item_index_with_text(_get_rid_from_name(nmenu, p_menu_root), p_text);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->find_item_index_with_tag(_get_rid_from_name(nmenu, p_menu_root), p_tag);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_callback(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_callback);
}
void DisplayServer::global_menu_set_item_hover_callbacks(const String &p_menu_root, int p_idx, const Callable &p_callback) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_hover_callbacks(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_callback);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_key_callback(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_key_callback);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, false);
return nmenu->is_item_checked(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
bool DisplayServer::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return false;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, false);
return nmenu->is_item_checkable(_get_rid_from_name(nmenu, p_menu_root), 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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, false);
return nmenu->is_item_radio_checkable(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Callable());
return nmenu->get_item_callback(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Callable());
return nmenu->get_item_key_callback(_get_rid_from_name(nmenu, p_menu_root), 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();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Variant());
return nmenu->get_item_tag(_get_rid_from_name(nmenu, p_menu_root), 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();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, String());
return nmenu->get_item_text(_get_rid_from_name(nmenu, p_menu_root), 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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, String());
RID rid = nmenu->get_item_submenu(_get_rid_from_name(nmenu, p_menu_root), p_idx);
if (!nmenu->is_system_menu(rid)) {
for (HashMap<String, RID>::Iterator E = menu_names.begin(); E;) {
if (E->value == rid) {
return E->key;
}
}
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Key::NONE);
return nmenu->get_item_accelerator(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, false);
return nmenu->is_item_disabled(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
bool DisplayServer::global_menu_is_item_hidden(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return false;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, false);
return nmenu->is_item_hidden(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, String());
return nmenu->get_item_tooltip(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->get_item_state(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, -1);
return nmenu->get_item_max_states(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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>();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Ref<Texture2D>());
return nmenu->get_item_icon(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
int DisplayServer::global_menu_get_item_indentation_level(const String &p_menu_root, int p_idx) const {
WARN_PRINT("Global menus not supported by this display server.");
return 0;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, 0);
return nmenu->get_item_indentation_level(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_checked(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_checked);
}
void DisplayServer::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_checkable(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_checkable);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_radio_checkable(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_checkable);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_tag(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_tag);
}
void DisplayServer::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_text(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_text);
}
void DisplayServer::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_submenu(_get_rid_from_name(nmenu, p_menu_root), p_idx, _get_rid_from_name(nmenu, p_submenu));
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_accelerator(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_keycode);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_disabled(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_disabled);
}
void DisplayServer::global_menu_set_item_hidden(const String &p_menu_root, int p_idx, bool p_hidden) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_hidden(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_hidden);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_tooltip(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_tooltip);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_state(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_state);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_max_states(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_max_states);
}
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.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_icon(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_icon);
}
void DisplayServer::global_menu_set_item_indentation_level(const String &p_menu_root, int p_idx, int p_level) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->set_item_indentation_level(_get_rid_from_name(nmenu, p_menu_root), p_idx, p_level);
}
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;
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, 0);
return nmenu->get_item_count(_get_rid_from_name(nmenu, p_menu_root));
}
void DisplayServer::global_menu_remove_item(const String &p_menu_root, int p_idx) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
nmenu->remove_item(_get_rid_from_name(nmenu, p_menu_root), p_idx);
}
void DisplayServer::global_menu_clear(const String &p_menu_root) {
WARN_PRINT("Global menus not supported by this display server.");
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL(nmenu);
RID rid = _get_rid_from_name(nmenu, p_menu_root);
nmenu->clear(rid);
if (!nmenu->is_system_menu(rid)) {
nmenu->free_menu(rid);
menu_names.erase(p_menu_root);
}
}
Dictionary DisplayServer::global_menu_get_system_menu_roots() const {
WARN_PRINT("Global menus not supported by this display server.");
return Dictionary();
NativeMenu *nmenu = NativeMenu::get_singleton();
ERR_FAIL_NULL_V(nmenu, Dictionary());
Dictionary out;
if (nmenu->has_system_menu(NativeMenu::DOCK_MENU_ID)) {
out["_dock"] = "@Dock";
}
if (nmenu->has_system_menu(NativeMenu::APPLICATION_MENU_ID)) {
out["_apple"] = "@Apple";
}
if (nmenu->has_system_menu(NativeMenu::WINDOW_MENU_ID)) {
out["_window"] = "Window";
}
if (nmenu->has_system_menu(NativeMenu::HELP_MENU_ID)) {
out["_help"] = "Help";
}
return out;
}
#endif
bool DisplayServer::tts_is_speaking() const {
WARN_PRINT("TTS is not supported by this display server.");
return false;
@ -640,6 +761,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("help_set_search_callbacks", "search_callback", "action_callback"), &DisplayServer::help_set_search_callbacks);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("global_menu_set_popup_callbacks", "menu_root", "open_callback", "close_callback"), &DisplayServer::global_menu_set_popup_callbacks);
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));
@ -695,6 +817,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("global_menu_clear", "menu_root"), &DisplayServer::global_menu_clear);
ClassDB::bind_method(D_METHOD("global_menu_get_system_menu_roots"), &DisplayServer::global_menu_get_system_menu_roots);
#endif
ClassDB::bind_method(D_METHOD("tts_is_speaking"), &DisplayServer::tts_is_speaking);
ClassDB::bind_method(D_METHOD("tts_is_paused"), &DisplayServer::tts_is_paused);
@ -866,7 +989,9 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("tablet_get_current_driver"), &DisplayServer::tablet_get_current_driver);
ClassDB::bind_method(D_METHOD("tablet_set_current_driver", "name"), &DisplayServer::tablet_set_current_driver);
#ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU);
#endif
BIND_ENUM_CONSTANT(FEATURE_SUBWINDOWS);
BIND_ENUM_CONSTANT(FEATURE_TOUCHSCREEN);
BIND_ENUM_CONSTANT(FEATURE_MOUSE);

View File

@ -36,6 +36,8 @@
#include "core/os/os.h"
#include "core/variant/callable.h"
#include "native_menu.h"
class Texture2D;
class Image;
@ -45,6 +47,12 @@ class DisplayServer : public Object {
static DisplayServer *singleton;
static bool hidpi_allowed;
#ifndef DISABLE_DEPRECATED
mutable HashMap<String, RID> menu_names;
RID _get_rid_from_name(NativeMenu *p_nmenu, const String &p_menu_root) const;
#endif
public:
_FORCE_INLINE_ static DisplayServer *get_singleton() {
return singleton;
@ -106,7 +114,9 @@ protected:
public:
enum Feature {
#ifndef DISABLE_DEPRECATED
FEATURE_GLOBAL_MENU,
#endif
FEATURE_SUBWINDOWS,
FEATURE_TOUCHSCREEN,
FEATURE_MOUSE,
@ -137,6 +147,7 @@ public:
virtual void help_set_search_callbacks(const Callable &p_search_callback = Callable(), const Callable &p_action_callback = Callable());
#ifndef DISABLE_DEPRECATED
virtual void global_menu_set_popup_callbacks(const String &p_menu_root, const Callable &p_open_callback = Callable(), const Callable &p_close_callback = Callable());
virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1);
@ -193,6 +204,7 @@ public:
virtual void global_menu_clear(const String &p_menu_root);
virtual Dictionary global_menu_get_system_menu_roots() const;
#endif
struct TTSUtterance {
String text;

422
servers/native_menu.cpp Normal file
View File

@ -0,0 +1,422 @@
/**************************************************************************/
/* native_menu.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "native_menu.h"
#include "scene/resources/image_texture.h"
NativeMenu *NativeMenu::singleton = nullptr;
void NativeMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_feature", "feature"), &NativeMenu::has_feature);
ClassDB::bind_method(D_METHOD("has_system_menu", "menu_id"), &NativeMenu::has_system_menu);
ClassDB::bind_method(D_METHOD("get_system_menu", "menu_id"), &NativeMenu::get_system_menu);
ClassDB::bind_method(D_METHOD("get_system_menu_name", "menu_id"), &NativeMenu::get_system_menu_name);
ClassDB::bind_method(D_METHOD("create_menu"), &NativeMenu::create_menu);
ClassDB::bind_method(D_METHOD("has_menu", "rid"), &NativeMenu::has_menu);
ClassDB::bind_method(D_METHOD("free_menu", "rid"), &NativeMenu::free_menu);
ClassDB::bind_method(D_METHOD("get_size", "rid"), &NativeMenu::get_size);
ClassDB::bind_method(D_METHOD("popup", "rid", "position"), &NativeMenu::popup);
ClassDB::bind_method(D_METHOD("set_popup_open_callback", "rid", "callback"), &NativeMenu::set_popup_open_callback);
ClassDB::bind_method(D_METHOD("get_popup_open_callback", "rid"), &NativeMenu::get_popup_open_callback);
ClassDB::bind_method(D_METHOD("set_popup_close_callback", "rid", "callback"), &NativeMenu::set_popup_close_callback);
ClassDB::bind_method(D_METHOD("get_popup_close_callback", "rid"), &NativeMenu::get_popup_close_callback);
ClassDB::bind_method(D_METHOD("set_minimum_width", "rid", "width"), &NativeMenu::set_minimum_width);
ClassDB::bind_method(D_METHOD("get_minimum_width", "rid"), &NativeMenu::get_minimum_width);
ClassDB::bind_method(D_METHOD("add_submenu_item", "rid", "label", "submenu_rid", "tag", "index"), &NativeMenu::add_submenu_item, DEFVAL(Variant()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_item", "rid", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_check_item", "rid", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_icon_item", "rid", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_icon_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_icon_check_item", "rid", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_icon_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_radio_check_item", "rid", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_icon_radio_check_item", "rid", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_multistate_item", "rid", "label", "max_states", "default_state", "callback", "key_callback", "tag", "accelerator", "index"), &NativeMenu::add_multistate_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_separator", "rid", "index"), &NativeMenu::add_separator, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("find_item_index_with_text", "rid", "text"), &NativeMenu::find_item_index_with_text);
ClassDB::bind_method(D_METHOD("find_item_index_with_tag", "rid", "tag"), &NativeMenu::find_item_index_with_tag);
ClassDB::bind_method(D_METHOD("is_item_checked", "rid", "idx"), &NativeMenu::is_item_checked);
ClassDB::bind_method(D_METHOD("is_item_checkable", "rid", "idx"), &NativeMenu::is_item_checkable);
ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "rid", "idx"), &NativeMenu::is_item_radio_checkable);
ClassDB::bind_method(D_METHOD("get_item_callback", "rid", "idx"), &NativeMenu::get_item_callback);
ClassDB::bind_method(D_METHOD("get_item_key_callback", "rid", "idx"), &NativeMenu::get_item_key_callback);
ClassDB::bind_method(D_METHOD("get_item_tag", "rid", "idx"), &NativeMenu::get_item_tag);
ClassDB::bind_method(D_METHOD("get_item_text", "rid", "idx"), &NativeMenu::get_item_text);
ClassDB::bind_method(D_METHOD("get_item_submenu", "rid", "idx"), &NativeMenu::get_item_submenu);
ClassDB::bind_method(D_METHOD("get_item_accelerator", "rid", "idx"), &NativeMenu::get_item_accelerator);
ClassDB::bind_method(D_METHOD("is_item_disabled", "rid", "idx"), &NativeMenu::is_item_disabled);
ClassDB::bind_method(D_METHOD("is_item_hidden", "rid", "idx"), &NativeMenu::is_item_hidden);
ClassDB::bind_method(D_METHOD("get_item_tooltip", "rid", "idx"), &NativeMenu::get_item_tooltip);
ClassDB::bind_method(D_METHOD("get_item_state", "rid", "idx"), &NativeMenu::get_item_state);
ClassDB::bind_method(D_METHOD("get_item_max_states", "rid", "idx"), &NativeMenu::get_item_max_states);
ClassDB::bind_method(D_METHOD("get_item_icon", "rid", "idx"), &NativeMenu::get_item_icon);
ClassDB::bind_method(D_METHOD("get_item_indentation_level", "rid", "idx"), &NativeMenu::get_item_indentation_level);
ClassDB::bind_method(D_METHOD("set_item_checked", "rid", "idx", "checked"), &NativeMenu::set_item_checked);
ClassDB::bind_method(D_METHOD("set_item_checkable", "rid", "idx", "checkable"), &NativeMenu::set_item_checkable);
ClassDB::bind_method(D_METHOD("set_item_radio_checkable", "rid", "idx", "checkable"), &NativeMenu::set_item_radio_checkable);
ClassDB::bind_method(D_METHOD("set_item_callback", "rid", "idx", "callback"), &NativeMenu::set_item_callback);
ClassDB::bind_method(D_METHOD("set_item_hover_callbacks", "rid", "idx", "callback"), &NativeMenu::set_item_hover_callbacks);
ClassDB::bind_method(D_METHOD("set_item_key_callback", "rid", "idx", "key_callback"), &NativeMenu::set_item_key_callback);
ClassDB::bind_method(D_METHOD("set_item_tag", "rid", "idx", "tag"), &NativeMenu::set_item_tag);
ClassDB::bind_method(D_METHOD("set_item_text", "rid", "idx", "text"), &NativeMenu::set_item_text);
ClassDB::bind_method(D_METHOD("set_item_submenu", "rid", "idx", "submenu_rid"), &NativeMenu::set_item_submenu);
ClassDB::bind_method(D_METHOD("set_item_accelerator", "rid", "idx", "keycode"), &NativeMenu::set_item_accelerator);
ClassDB::bind_method(D_METHOD("set_item_disabled", "rid", "idx", "disabled"), &NativeMenu::set_item_disabled);
ClassDB::bind_method(D_METHOD("set_item_hidden", "rid", "idx", "hidden"), &NativeMenu::set_item_hidden);
ClassDB::bind_method(D_METHOD("set_item_tooltip", "rid", "idx", "tooltip"), &NativeMenu::set_item_tooltip);
ClassDB::bind_method(D_METHOD("set_item_state", "rid", "idx", "state"), &NativeMenu::set_item_state);
ClassDB::bind_method(D_METHOD("set_item_max_states", "rid", "idx", "max_states"), &NativeMenu::set_item_max_states);
ClassDB::bind_method(D_METHOD("set_item_icon", "rid", "idx", "icon"), &NativeMenu::set_item_icon);
ClassDB::bind_method(D_METHOD("set_item_indentation_level", "rid", "idx", "level"), &NativeMenu::set_item_indentation_level);
ClassDB::bind_method(D_METHOD("get_item_count", "rid"), &NativeMenu::get_item_count);
ClassDB::bind_method(D_METHOD("is_system_menu", "rid"), &NativeMenu::is_system_menu);
ClassDB::bind_method(D_METHOD("remove_item", "rid", "idx"), &NativeMenu::remove_item);
ClassDB::bind_method(D_METHOD("clear", "rid"), &NativeMenu::clear);
BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU);
BIND_ENUM_CONSTANT(FEATURE_POPUP_MENU);
BIND_ENUM_CONSTANT(INVALID_MENU_ID);
BIND_ENUM_CONSTANT(MAIN_MENU_ID);
BIND_ENUM_CONSTANT(APPLICATION_MENU_ID);
BIND_ENUM_CONSTANT(WINDOW_MENU_ID);
BIND_ENUM_CONSTANT(HELP_MENU_ID);
BIND_ENUM_CONSTANT(DOCK_MENU_ID);
}
bool NativeMenu::has_feature(Feature p_feature) const {
return false;
}
bool NativeMenu::has_system_menu(SystemMenus p_menu_id) const {
return false;
}
RID NativeMenu::get_system_menu(SystemMenus p_menu_id) const {
WARN_PRINT("Global menus are not supported on this platform.");
return RID();
}
String NativeMenu::get_system_menu_name(SystemMenus p_menu_id) const {
switch (p_menu_id) {
case MAIN_MENU_ID:
return "Main menu";
case APPLICATION_MENU_ID:
return "Application menu";
case WINDOW_MENU_ID:
return "Window menu";
case HELP_MENU_ID:
return "Help menu";
case DOCK_MENU_ID:
return "Dock menu";
default:
return "Invalid";
}
}
RID NativeMenu::create_menu() {
WARN_PRINT("Global menus are not supported on this platform.");
return RID();
}
bool NativeMenu::has_menu(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
void NativeMenu::free_menu(const RID &p_rid) {
WARN_PRINT("Global menus are not supported on this platform.");
}
Size2 NativeMenu::get_size(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Size2();
}
void NativeMenu::popup(const RID &p_rid, const Vector2i &p_position) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_popup_open_callback(const RID &p_rid, const Callable &p_callback) {
WARN_PRINT("Global menus are not supported on this platform.");
}
Callable NativeMenu::get_popup_open_callback(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Callable();
}
void NativeMenu::set_popup_close_callback(const RID &p_rid, const Callable &p_callback) {
WARN_PRINT("Global menus are not supported on this platform.");
}
Callable NativeMenu::get_popup_close_callback(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Callable();
}
void NativeMenu::set_minimum_width(const RID &p_rid, float p_width) {
WARN_PRINT("Global menus are not supported on this platform.");
}
float NativeMenu::get_minimum_width(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return 0.f;
}
int NativeMenu::add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag, int p_index) {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
int NativeMenu::add_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_check_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_icon_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_icon_check_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_radio_check_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_icon_radio_check_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_multistate_item(const RID &p_rid, 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 are not supported on this platform.");
return -1;
}
int NativeMenu::add_separator(const RID &p_rid, int p_index) {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
int NativeMenu::find_item_index_with_text(const RID &p_rid, const String &p_text) const {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
int NativeMenu::find_item_index_with_tag(const RID &p_rid, const Variant &p_tag) const {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
bool NativeMenu::is_item_checked(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
bool NativeMenu::is_item_checkable(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
bool NativeMenu::is_item_radio_checkable(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
Callable NativeMenu::get_item_callback(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Callable();
}
Callable NativeMenu::get_item_key_callback(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Callable();
}
Variant NativeMenu::get_item_tag(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Variant();
}
String NativeMenu::get_item_text(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return String();
}
RID NativeMenu::get_item_submenu(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return RID();
}
Key NativeMenu::get_item_accelerator(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Key::NONE;
}
bool NativeMenu::is_item_disabled(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
bool NativeMenu::is_item_hidden(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
String NativeMenu::get_item_tooltip(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return String();
}
int NativeMenu::get_item_state(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
int NativeMenu::get_item_max_states(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return -1;
}
Ref<Texture2D> NativeMenu::get_item_icon(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return Ref<Texture2D>();
}
int NativeMenu::get_item_indentation_level(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return 0;
}
void NativeMenu::set_item_checked(const RID &p_rid, int p_idx, bool p_checked) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_radio_checkable(const RID &p_rid, int p_idx, bool p_checkable) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_callback(const RID &p_rid, int p_idx, const Callable &p_callback) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_key_callback(const RID &p_rid, int p_idx, const Callable &p_key_callback) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_hover_callbacks(const RID &p_rid, int p_idx, const Callable &p_callback) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_tag(const RID &p_rid, int p_idx, const Variant &p_tag) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_text(const RID &p_rid, int p_idx, const String &p_text) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_submenu(const RID &p_rid, int p_idx, const RID &p_submenu_rid) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_accelerator(const RID &p_rid, int p_idx, Key p_keycode) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_disabled(const RID &p_rid, int p_idx, bool p_disabled) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_hidden(const RID &p_rid, int p_idx, bool p_hidden) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_tooltip(const RID &p_rid, int p_idx, const String &p_tooltip) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_state(const RID &p_rid, int p_idx, int p_state) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_max_states(const RID &p_rid, int p_idx, int p_max_states) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_icon(const RID &p_rid, int p_idx, const Ref<Texture2D> &p_icon) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::set_item_indentation_level(const RID &p_rid, int p_idx, int p_level) {
WARN_PRINT("Global menus are not supported on this platform.");
}
int NativeMenu::get_item_count(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return 0;
}
bool NativeMenu::is_system_menu(const RID &p_rid) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
}
void NativeMenu::remove_item(const RID &p_rid, int p_idx) {
WARN_PRINT("Global menus are not supported on this platform.");
}
void NativeMenu::clear(const RID &p_rid) {
WARN_PRINT("Global menus are not supported on this platform.");
}

154
servers/native_menu.h Normal file
View File

@ -0,0 +1,154 @@
/**************************************************************************/
/* native_menu.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 NATIVE_MENU_H
#define NATIVE_MENU_H
#include "core/input/input.h"
#include "core/io/resource.h"
#include "core/os/os.h"
#include "core/variant/callable.h"
class Texture2D;
class NativeMenu : public Object {
GDCLASS(NativeMenu, Object)
static NativeMenu *singleton;
protected:
static void _bind_methods();
public:
_FORCE_INLINE_ static NativeMenu *get_singleton() {
return singleton;
}
enum Feature {
FEATURE_GLOBAL_MENU,
FEATURE_POPUP_MENU,
};
enum SystemMenus {
INVALID_MENU_ID,
MAIN_MENU_ID,
APPLICATION_MENU_ID,
WINDOW_MENU_ID,
HELP_MENU_ID,
DOCK_MENU_ID,
};
virtual bool has_feature(Feature p_feature) const;
virtual bool has_system_menu(SystemMenus p_menu_id) const;
virtual RID get_system_menu(SystemMenus p_menu_id) const;
virtual String get_system_menu_name(SystemMenus p_menu_id) const;
virtual RID create_menu();
virtual bool has_menu(const RID &p_rid) const;
virtual void free_menu(const RID &p_rid);
virtual Size2 get_size(const RID &p_rid) const;
virtual void popup(const RID &p_rid, const Vector2i &p_position);
virtual void set_popup_open_callback(const RID &p_rid, const Callable &p_callback);
virtual Callable get_popup_open_callback(const RID &p_rid) const;
virtual void set_popup_close_callback(const RID &p_rid, const Callable &p_callback);
virtual Callable get_popup_close_callback(const RID &p_rid) const;
virtual void set_minimum_width(const RID &p_rid, float p_width);
virtual float get_minimum_width(const RID &p_rid) const;
virtual int add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag = Variant(), int p_index = -1);
virtual int add_item(const RID &p_rid, 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 add_check_item(const RID &p_rid, 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 add_icon_item(const RID &p_rid, 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 add_icon_check_item(const RID &p_rid, 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 add_radio_check_item(const RID &p_rid, 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 add_icon_radio_check_item(const RID &p_rid, 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 add_multistate_item(const RID &p_rid, 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 add_separator(const RID &p_rid, int p_index = -1);
virtual int find_item_index_with_text(const RID &p_rid, const String &p_text) const;
virtual int find_item_index_with_tag(const RID &p_rid, const Variant &p_tag) const;
virtual bool is_item_checked(const RID &p_rid, int p_idx) const;
virtual bool is_item_checkable(const RID &p_rid, int p_idx) const;
virtual bool is_item_radio_checkable(const RID &p_rid, int p_idx) const;
virtual Callable get_item_callback(const RID &p_rid, int p_idx) const;
virtual Callable get_item_key_callback(const RID &p_rid, int p_idx) const;
virtual Variant get_item_tag(const RID &p_rid, int p_idx) const;
virtual String get_item_text(const RID &p_rid, int p_idx) const;
virtual RID get_item_submenu(const RID &p_rid, int p_idx) const;
virtual Key get_item_accelerator(const RID &p_rid, int p_idx) const;
virtual bool is_item_disabled(const RID &p_rid, int p_idx) const;
virtual bool is_item_hidden(const RID &p_rid, int p_idx) const;
virtual String get_item_tooltip(const RID &p_rid, int p_idx) const;
virtual int get_item_state(const RID &p_rid, int p_idx) const;
virtual int get_item_max_states(const RID &p_rid, int p_idx) const;
virtual Ref<Texture2D> get_item_icon(const RID &p_rid, int p_idx) const;
virtual int get_item_indentation_level(const RID &p_rid, int p_idx) const;
virtual void set_item_checked(const RID &p_rid, int p_idx, bool p_checked);
virtual void set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable);
virtual void set_item_radio_checkable(const RID &p_rid, int p_idx, bool p_checkable);
virtual void set_item_callback(const RID &p_rid, int p_idx, const Callable &p_callback);
virtual void set_item_key_callback(const RID &p_rid, int p_idx, const Callable &p_key_callback);
virtual void set_item_hover_callbacks(const RID &p_rid, int p_idx, const Callable &p_callback);
virtual void set_item_tag(const RID &p_rid, int p_idx, const Variant &p_tag);
virtual void set_item_text(const RID &p_rid, int p_idx, const String &p_text);
virtual void set_item_submenu(const RID &p_rid, int p_idx, const RID &p_submenu_rid);
virtual void set_item_accelerator(const RID &p_rid, int p_idx, Key p_keycode);
virtual void set_item_disabled(const RID &p_rid, int p_idx, bool p_disabled);
virtual void set_item_hidden(const RID &p_rid, int p_idx, bool p_hidden);
virtual void set_item_tooltip(const RID &p_rid, int p_idx, const String &p_tooltip);
virtual void set_item_state(const RID &p_rid, int p_idx, int p_state);
virtual void set_item_max_states(const RID &p_rid, int p_idx, int p_max_states);
virtual void set_item_icon(const RID &p_rid, int p_idx, const Ref<Texture2D> &p_icon);
virtual void set_item_indentation_level(const RID &p_rid, int p_idx, int p_level);
virtual int get_item_count(const RID &p_rid) const;
virtual bool is_system_menu(const RID &p_rid) const;
virtual void remove_item(const RID &p_rid, int p_idx);
virtual void clear(const RID &p_rid);
NativeMenu() {
singleton = this;
}
~NativeMenu() {
singleton = nullptr;
}
};
VARIANT_ENUM_CAST(NativeMenu::Feature);
VARIANT_ENUM_CAST(NativeMenu::SystemMenus);
#endif // NATIVE_MENU_H

View File

@ -60,6 +60,7 @@
#include "movie_writer/movie_writer.h"
#include "movie_writer/movie_writer_mjpeg.h"
#include "movie_writer/movie_writer_pngwav.h"
#include "native_menu.h"
#include "rendering/renderer_compositor.h"
#include "rendering/renderer_rd/framebuffer_cache_rd.h"
#include "rendering/renderer_rd/storage_rd/render_data_rd.h"
@ -162,6 +163,8 @@ void register_server_types() {
GDREGISTER_ABSTRACT_CLASS(RenderingServer);
GDREGISTER_CLASS(AudioServer);
GDREGISTER_CLASS(NativeMenu);
GDREGISTER_ABSTRACT_CLASS(NavigationServer2D);
GDREGISTER_ABSTRACT_CLASS(NavigationServer3D);
GDREGISTER_CLASS(NavigationPathQueryParameters2D);
@ -361,6 +364,7 @@ void register_server_singletons() {
#ifndef _3D_DISABLED
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton(), "PhysicsServer3D"));
#endif // _3D_DISABLED
Engine::get_singleton()->add_singleton(Engine::Singleton("NativeMenu", NativeMenu::get_singleton(), "NativeMenu"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton(), "NavigationServer2D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton(), "NavigationServer3D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton(), "XRServer"));