diff options
Diffstat (limited to 'scene/gui/popup_menu.cpp')
-rw-r--r-- | scene/gui/popup_menu.cpp | 378 |
1 files changed, 192 insertions, 186 deletions
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 42100bf9fa..dfe0649d0f 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -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(); } |