From 89324bc6d2724d8db9c18c2c11bdd02f3e8520b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:07:23 +0200 Subject: [PATCH] Reorganize editor menu setup, allow switching global menu without restart. --- editor/editor_node.cpp | 605 ++++++++++++++++------------ editor/editor_node.h | 14 + editor/settings/editor_settings.cpp | 2 +- 3 files changed, 364 insertions(+), 257 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9e6e1658b33..b389e44fa90 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -669,7 +669,6 @@ void EditorNode::_update_theme(bool p_skip_creation) { // Update styles. { - bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU); bool dark_mode = DisplayServer::get_singleton()->is_dark_mode_supported() && DisplayServer::get_singleton()->is_dark_mode(); gui_base->add_theme_style_override(SceneStringName(panel), theme->get_stylebox(SNAME("Background"), EditorStringName(EditorStyles))); @@ -685,10 +684,10 @@ void EditorNode::_update_theme(bool p_skip_creation) { distraction_free->set_button_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons))); update_distraction_free_button_theme(); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), get_editor_theme_native_menu_icon(SNAME("HelpSearch"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), get_editor_theme_native_menu_icon(SNAME("ActionCopy"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), get_editor_theme_native_menu_icon(SNAME("Godot"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), get_editor_theme_native_menu_icon(SNAME("Heart"), global_menu, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), get_editor_theme_native_menu_icon(SNAME("HelpSearch"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), get_editor_theme_native_menu_icon(SNAME("ActionCopy"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), get_editor_theme_native_menu_icon(SNAME("Godot"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), get_editor_theme_native_menu_icon(SNAME("Heart"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); _update_renderer_color(); } @@ -3895,7 +3894,6 @@ void EditorNode::_save_screenshot(const String &p_path) { void EditorNode::_check_system_theme_changed() { DisplayServer *display_server = DisplayServer::get_singleton(); - bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU); bool system_theme_changed = false; if (follow_system_theme) { @@ -3919,16 +3917,16 @@ void EditorNode::_check_system_theme_changed() { if (system_theme_changed) { _update_theme(); - } else if (global_menu && display_server->is_dark_mode_supported() && display_server->is_dark_mode() != last_dark_mode_state) { + } else if (menu_type == MENU_TYPE_GLOBAL && display_server->is_dark_mode_supported() && display_server->is_dark_mode() != last_dark_mode_state) { last_dark_mode_state = display_server->is_dark_mode(); // Update system menus. bool dark_mode = DisplayServer::get_singleton()->is_dark_mode(); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), get_editor_theme_native_menu_icon(SNAME("HelpSearch"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), get_editor_theme_native_menu_icon(SNAME("ActionCopy"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), get_editor_theme_native_menu_icon(SNAME("Godot"), global_menu, dark_mode)); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), get_editor_theme_native_menu_icon(SNAME("Heart"), global_menu, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), get_editor_theme_native_menu_icon(SNAME("HelpSearch"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), get_editor_theme_native_menu_icon(SNAME("ActionCopy"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), get_editor_theme_native_menu_icon(SNAME("Godot"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); + help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), get_editor_theme_native_menu_icon(SNAME("Heart"), menu_type == MENU_TYPE_GLOBAL, dark_mode)); editor_dock_manager->update_docks_menu(); } } @@ -7737,17 +7735,239 @@ void EditorNode::set_unfocused_low_processor_usage_mode_enabled(bool p_enabled) unfocused_low_processor_usage_mode_enabled = p_enabled; } +void EditorNode::_build_file_menu() { + if (!file_menu) { + return; + } + file_menu->clear(false); + + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_scene"), SCENE_NEW_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_inherited_scene"), SCENE_NEW_INHERITED_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/open_scene"), SCENE_OPEN_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/reopen_closed_scene"), SCENE_OPEN_PREV); + if (!recent_scenes) { + recent_scenes = memnew(PopupMenu); + recent_scenes->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + recent_scenes->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_open_recent_scene)); + } + file_menu->add_submenu_node_item(TTRC("Open Recent"), recent_scenes, SCENE_OPEN_RECENT); + file_menu->add_separator(); + + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene"), SCENE_SAVE_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene_as"), SCENE_SAVE_AS_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), SCENE_SAVE_ALL_SCENES); + file_menu->add_separator(); + + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/quick_open"), SCENE_QUICK_OPEN); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/quick_open_scene"), SCENE_QUICK_OPEN_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/quick_open_script"), SCENE_QUICK_OPEN_SCRIPT); + file_menu->add_separator(); + + if (!export_as_menu) { + export_as_menu = memnew(PopupMenu); + export_as_menu->add_shortcut(ED_GET_SHORTCUT("editor/export_as_mesh_library"), FILE_EXPORT_MESH_LIBRARY); + export_as_menu->connect("index_pressed", callable_mp(this, &EditorNode::_export_as_menu_option)); + } + file_menu->add_submenu_node_item(TTRC("Export As..."), export_as_menu, SCENE_EXPORT_AS); + file_menu->add_separator(); + + file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), SCENE_UNDO, false, true); + file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), SCENE_REDO, false, true); + file_menu->add_separator(); + + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/reload_saved_scene"), SCENE_RELOAD_SAVED_SCENE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/close_scene"), SCENE_CLOSE); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/close_all_scenes"), SCENE_CLOSE_ALL); +#ifdef MACOS_ENABLED + if (menu_type != MENU_TYPE_GLOBAL) { + // On macOS "Quit" option is in the "app" menu. + file_menu->add_separator(); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/file_quit"), SCENE_QUIT, true); + } +#else + file_menu->add_separator(); + file_menu->add_shortcut(ED_GET_SHORTCUT("editor/file_quit"), SCENE_QUIT, true); +#endif +} + +void EditorNode::_build_project_menu() { + if (!project_menu) { + return; + } + project_menu->clear(false); + + project_menu->add_shortcut(ED_GET_SHORTCUT("editor/project_settings"), PROJECT_OPEN_SETTINGS); + project_menu->add_shortcut(ED_GET_SHORTCUT("editor/find_in_files"), PROJECT_FIND_IN_FILES); + project_menu->add_separator(); + + project_menu->add_item(TTRC("Version Control"), PROJECT_VERSION_CONTROL); + if (!vcs_actions_menu) { + vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel(); + vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option)); + vcs_actions_menu->add_item(TTRC("Create/Override Version Control Metadata..."), VCS_METADATA); + vcs_actions_menu->add_item(TTRC("Version Control Settings..."), VCS_SETTINGS); + } + project_menu->set_item_submenu_node(project_menu->get_item_index(PROJECT_VERSION_CONTROL), vcs_actions_menu); + + project_menu->add_separator(); + project_menu->add_shortcut(ED_GET_SHORTCUT("editor/export"), PROJECT_EXPORT); + project_menu->add_item(TTRC("Pack Project as ZIP..."), PROJECT_PACK_AS_ZIP); + project_menu->add_item(TTRC("Install Android Build Template..."), PROJECT_INSTALL_ANDROID_SOURCE); +#ifndef ANDROID_ENABLED + project_menu->add_item(TTRC("Open User Data Folder"), PROJECT_OPEN_USER_DATA_FOLDER); +#endif + project_menu->add_separator(); + + if (!tool_menu) { + tool_menu = memnew(PopupMenu); + tool_menu->connect("index_pressed", callable_mp(this, &EditorNode::_tool_menu_option)); + tool_menu->add_shortcut(ED_GET_SHORTCUT("editor/orphan_resource_explorer"), TOOLS_ORPHAN_RESOURCES); + tool_menu->add_shortcut(ED_GET_SHORTCUT("editor/engine_compilation_configuration_editor"), TOOLS_BUILD_PROFILE_MANAGER); + tool_menu->add_shortcut(ED_GET_SHORTCUT("editor/upgrade_project"), TOOLS_PROJECT_UPGRADE); + } + project_menu->add_submenu_node_item(TTRC("Tools"), tool_menu); + + project_menu->add_separator(); + project_menu->add_shortcut(ED_GET_SHORTCUT("editor/reload_current_project"), PROJECT_RELOAD_CURRENT_PROJECT); + project_menu->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), PROJECT_QUIT_TO_PROJECT_MANAGER, true); +} + +void EditorNode::_build_settings_menu() { + if (!settings_menu) { + return; + } + settings_menu->clear(false); + +#ifdef MACOS_ENABLED + if (menu_type != MENU_TYPE_GLOBAL) { + // On macOS "Settings" option is in the "app" menu. + settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); + } +#else + settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); +#endif + settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/command_palette"), EDITOR_COMMAND_PALETTE); + settings_menu->add_separator(); + + settings_menu->add_submenu_node_item(TTRC("Editor Docks"), editor_dock_manager->get_docks_menu()); + + if (!editor_layouts) { + editor_layouts = memnew(PopupMenu); + editor_layouts->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_layout_menu_option)); + } + settings_menu->add_submenu_node_item(TTRC("Editor Layout"), editor_layouts); + settings_menu->add_separator(); + + settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_TAKE_SCREENSHOT); + settings_menu->set_item_tooltip(-1, TTRC("Screenshots are stored in the user data folder (\"user://\").")); + + settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), EDITOR_TOGGLE_FULLSCREEN); + settings_menu->add_separator(); + +#ifndef ANDROID_ENABLED + if (EditorPaths::get_singleton()->get_data_dir() == EditorPaths::get_singleton()->get_config_dir()) { + // Configuration and data folders are located in the same place. + settings_menu->add_item(TTRC("Open Editor Data/Settings Folder"), EDITOR_OPEN_DATA_FOLDER); + } else { + // Separate configuration and data folders. + settings_menu->add_item(TTRC("Open Editor Data Folder"), EDITOR_OPEN_DATA_FOLDER); + settings_menu->add_item(TTRC("Open Editor Settings Folder"), EDITOR_OPEN_CONFIG_FOLDER); + } + settings_menu->add_separator(); +#endif + + settings_menu->add_item(TTRC("Manage Editor Features..."), EDITOR_MANAGE_FEATURE_PROFILES); + settings_menu->add_item(TTRC("Manage Export Templates..."), EDITOR_MANAGE_EXPORT_TEMPLATES); +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + settings_menu->add_item(TTRC("Configure FBX Importer..."), EDITOR_CONFIGURE_FBX_IMPORTER); +#endif +} + +void EditorNode::_build_help_menu() { + if (!help_menu) { + return; + } + help_menu->clear(false); + + if (menu_type == MENU_TYPE_GLOBAL && NativeMenu::get_singleton()->has_system_menu(NativeMenu::HELP_MENU_ID)) { + help_menu->set_system_menu(NativeMenu::HELP_MENU_ID); + } else { + help_menu->set_system_menu(NativeMenu::INVALID_MENU_ID); + } + bool dark_mode = DisplayServer::get_singleton()->is_dark_mode_supported() && DisplayServer::get_singleton()->is_dark_mode(); + help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("HelpSearch"), menu_type == MENU_TYPE_GLOBAL, dark_mode), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH); + help_menu->add_separator(); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/online_docs"), HELP_DOCS); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/forum"), HELP_FORUM); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/community"), HELP_COMMUNITY); + help_menu->add_separator(); + help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("ActionCopy"), menu_type == MENU_TYPE_GLOBAL, dark_mode), ED_GET_SHORTCUT("editor/copy_system_info"), HELP_COPY_SYSTEM_INFO); + help_menu->set_item_tooltip(-1, TTRC("Copies the system info as a single-line text into the clipboard.")); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/report_a_bug"), HELP_REPORT_A_BUG); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/suggest_a_feature"), HELP_SUGGEST_A_FEATURE); + help_menu->add_shortcut(ED_GET_SHORTCUT("editor/send_docs_feedback"), HELP_SEND_DOCS_FEEDBACK); + help_menu->add_separator(); +#ifdef MACOS_ENABLED + if (menu_type != MENU_TYPE_GLOBAL) { + // On macOS "About" option is in the "app" menu. + help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("Godot"), menu_type == MENU_TYPE_GLOBAL, dark_mode), ED_GET_SHORTCUT("editor/about"), HELP_ABOUT); + } +#else + help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("Godot"), menu_type == MENU_TYPE_GLOBAL, dark_mode), ED_GET_SHORTCUT("editor/about"), HELP_ABOUT); +#endif + help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("Heart"), menu_type == MENU_TYPE_GLOBAL, dark_mode), ED_GET_SHORTCUT("editor/support_development"), HELP_SUPPORT_GODOT_DEVELOPMENT); +} + +void EditorNode::_add_to_main_menu(const String &p_name, PopupMenu *p_menu) { + p_menu->set_name(p_name); + main_menu_items.push_back(p_menu); +} + void EditorNode::_update_main_menu_type() { + bool can_expand = bool(EDITOR_GET("interface/editor/expand_to_title")) && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_EXTEND_TO_TITLE); bool use_menu_button = EDITOR_GET("interface/editor/collapse_main_menu"); bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU); - - bool already_using_button = main_menu_button != nullptr; - bool already_using_bar = main_menu_bar != nullptr; - if ((use_menu_button && already_using_button) || (!use_menu_button && already_using_bar)) { - return; // Already correctly configured. + MenuType new_menu_type; + if (global_menu) { + new_menu_type = MENU_TYPE_GLOBAL; + } else if (use_menu_button) { + new_menu_type = MENU_TYPE_COMPACT; + } else { + new_menu_type = MENU_TYPE_FULL; } - if (use_menu_button && !global_menu) { + if (new_menu_type == menu_type) { + return; // Nothing to do. + } + menu_type = new_menu_type; + + // Update menu items. + _build_file_menu(); + _build_project_menu(); + _build_settings_menu(); + _build_help_menu(); + + // Delete all menu. + if (main_menu_bar) { + for (PopupMenu *menu : main_menu_items) { + main_menu_bar->remove_child(menu); + } + memdelete(main_menu_bar); + main_menu_bar = nullptr; + } + if (main_menu_button) { + main_menu_button->get_popup()->clear(false); + for (PopupMenu *menu : main_menu_items) { + main_menu_button->get_popup()->remove_child(menu); + } + memdelete(main_menu_button); + main_menu_button = nullptr; + } + memdelete_notnull(menu_btn_spacer); + menu_btn_spacer = nullptr; + + // Create new menu. + if (new_menu_type == MENU_TYPE_COMPACT) { main_menu_button = memnew(MenuButton); main_menu_button->set_text(TTRC("Main Menu")); main_menu_button->set_theme_type_variation("MainScreenButton"); @@ -7757,18 +7977,8 @@ void EditorNode::_update_main_menu_type() { } main_menu_button->set_switch_on_hover(true); - if (main_menu_bar != nullptr) { - Vector menus_to_move; - for (int i = 0; i < main_menu_bar->get_child_count(); i++) { - PopupMenu *menu = Object::cast_to(main_menu_bar->get_child(i)); - if (menu != nullptr) { - menus_to_move.push_back(menu); - } - } - for (PopupMenu *menu : menus_to_move) { - main_menu_bar->remove_child(menu); - main_menu_button->get_popup()->add_submenu_node_item(menu->get_name(), menu); - } + for (PopupMenu *menu : main_menu_items) { + main_menu_button->get_popup()->add_submenu_node_item(menu->get_name(), menu); } #ifdef ANDROID_ENABLED @@ -7784,47 +7994,26 @@ void EditorNode::_update_main_menu_type() { } else { title_bar->move_child(main_menu_button, menu_btn_spacer->get_index() + 1); } - memdelete_notnull(main_menu_bar); - main_menu_bar = nullptr; } else { main_menu_bar = memnew(MenuBar); main_menu_bar->set_mouse_filter(Control::MOUSE_FILTER_STOP); main_menu_bar->set_v_size_flags(Control::SIZE_SHRINK_CENTER); main_menu_bar->set_theme_type_variation("MainMenuBar"); main_menu_bar->set_start_index(0); // Main menu, add to the start of global menu. - main_menu_bar->set_prefer_global_menu(global_menu); + main_menu_bar->set_prefer_global_menu(menu_type == MENU_TYPE_GLOBAL); main_menu_bar->set_switch_on_hover(true); - if (main_menu_button != nullptr) { - Vector menus_to_move; - for (int i = 0; i < main_menu_button->get_item_count(); i++) { - PopupMenu *menu = main_menu_button->get_popup()->get_item_submenu_node(i); - if (menu != nullptr) { - menus_to_move.push_back(menu); - } - } - for (PopupMenu *menu : menus_to_move) { - menu->get_parent()->remove_child(menu); - main_menu_bar->add_child(menu); - } + for (PopupMenu *menu : main_menu_items) { + main_menu_bar->add_child(menu); } title_bar->add_child(main_menu_bar); title_bar->move_child(main_menu_bar, left_menu_spacer ? left_menu_spacer->get_index() + 1 : 0); - - memdelete_notnull(menu_btn_spacer); - memdelete_notnull(main_menu_button); - menu_btn_spacer = nullptr; - main_menu_button = nullptr; } -} -void EditorNode::_add_to_main_menu(const String &p_name, PopupMenu *p_menu) { - p_menu->set_name(p_name); - if (main_menu_button != nullptr) { - main_menu_button->get_popup()->add_submenu_node_item(p_name, p_menu); - } else { - main_menu_bar->add_child(p_menu); + // Show/hide project title. + if (project_title) { + project_title->set_visible(can_expand && menu_type == MENU_TYPE_GLOBAL); } } @@ -8358,22 +8547,6 @@ EditorNode::EditorNode() { scene_root->set_disable_input(true); scene_root->set_as_audio_listener_2d(true); - bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU); - bool dark_mode = DisplayServer::get_singleton()->is_dark_mode_supported() && DisplayServer::get_singleton()->is_dark_mode(); - bool can_expand = bool(EDITOR_GET("interface/editor/expand_to_title")) && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_EXTEND_TO_TITLE); - - if (can_expand) { - // Add spacer to avoid other controls under window minimize/maximize/close buttons (left side). - left_menu_spacer = memnew(Control); - left_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - title_bar->add_child(left_menu_spacer); - } - - _update_main_menu_type(); - - file_menu = memnew(PopupMenu); - _add_to_main_menu(TTRC("Scene"), file_menu); - accept = memnew(AcceptDialog); accept->set_autowrap(true); accept->set_min_size(Vector2i(600, 0)); @@ -8428,211 +8601,74 @@ EditorNode::EditorNode() { warning->add_button(TTRC("Copy Text"), true, "copy"); warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning)); - ED_SHORTCUT("editor/next_tab", TTRC("Next Scene Tab"), KeyModifierMask::CTRL + Key::TAB); - ED_SHORTCUT("editor/prev_tab", TTRC("Previous Scene Tab"), KeyModifierMask::CTRL + KeyModifierMask::SHIFT + Key::TAB); - ED_SHORTCUT("editor/filter_files", TTRC("Focus FileSystem Filter"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::P); - + // Command palette and editor shortcuts. command_palette = EditorCommandPalette::get_singleton(); command_palette->set_title(TTR("Command Palette")); gui_base->add_child(command_palette); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_scene", TTRC("New Scene"), KeyModifierMask::CMD_OR_CTRL + Key::N), SCENE_NEW_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_inherited_scene", TTRC("New Inherited Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::N), SCENE_NEW_INHERITED_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/open_scene", TTRC("Open Scene..."), KeyModifierMask::CMD_OR_CTRL + Key::O), SCENE_OPEN_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reopen_closed_scene", TTRC("Reopen Closed Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::T), SCENE_OPEN_PREV); + ED_SHORTCUT("editor/next_tab", TTRC("Next Scene Tab"), KeyModifierMask::CTRL + Key::TAB); + ED_SHORTCUT("editor/prev_tab", TTRC("Previous Scene Tab"), KeyModifierMask::CTRL + KeyModifierMask::SHIFT + Key::TAB); + ED_SHORTCUT("editor/filter_files", TTRC("Focus FileSystem Filter"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::P); - recent_scenes = memnew(PopupMenu); - recent_scenes->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); - file_menu->add_submenu_node_item(TTRC("Open Recent"), recent_scenes, SCENE_OPEN_RECENT); - recent_scenes->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_open_recent_scene)); + ED_SHORTCUT_AND_COMMAND("editor/new_scene", TTRC("New Scene"), KeyModifierMask::CMD_OR_CTRL + Key::N); + ED_SHORTCUT_AND_COMMAND("editor/new_inherited_scene", TTRC("New Inherited Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::N); + ED_SHORTCUT_AND_COMMAND("editor/open_scene", TTRC("Open Scene..."), KeyModifierMask::CMD_OR_CTRL + Key::O); + ED_SHORTCUT_AND_COMMAND("editor/reopen_closed_scene", TTRC("Reopen Closed Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::T); - file_menu->add_separator(); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene", TTRC("Save Scene"), KeyModifierMask::CMD_OR_CTRL + Key::S), SCENE_SAVE_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene_as", TTRC("Save Scene As..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::S), SCENE_SAVE_AS_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_all_scenes", TTRC("Save All Scenes"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::S), SCENE_SAVE_ALL_SCENES); + ED_SHORTCUT_AND_COMMAND("editor/save_scene", TTRC("Save Scene"), KeyModifierMask::CMD_OR_CTRL + Key::S); + ED_SHORTCUT_AND_COMMAND("editor/save_scene_as", TTRC("Save Scene As..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::S); + ED_SHORTCUT_AND_COMMAND("editor/save_all_scenes", TTRC("Save All Scenes"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::S); - file_menu->add_separator(); - - file_menu->add_shortcut(ED_SHORTCUT_ARRAY_AND_COMMAND("editor/quick_open", TTRC("Quick Open..."), { int32_t(KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::O), int32_t(KeyModifierMask::CMD_OR_CTRL + Key::P) }), SCENE_QUICK_OPEN); + ED_SHORTCUT_ARRAY_AND_COMMAND("editor/quick_open", TTRC("Quick Open..."), { int32_t(KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::O), int32_t(KeyModifierMask::CMD_OR_CTRL + Key::P) }); ED_SHORTCUT_OVERRIDE_ARRAY("editor/quick_open", "macos", { int32_t(KeyModifierMask::META + KeyModifierMask::CTRL + Key::O), int32_t(KeyModifierMask::CMD_OR_CTRL + Key::P) }); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_scene", TTRC("Quick Open Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::O), SCENE_QUICK_OPEN_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_script", TTRC("Quick Open Script..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::O), SCENE_QUICK_OPEN_SCRIPT); + ED_SHORTCUT_AND_COMMAND("editor/quick_open_scene", TTRC("Quick Open Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::O); + ED_SHORTCUT_AND_COMMAND("editor/quick_open_script", TTRC("Quick Open Script..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::O); - file_menu->add_separator(); - export_as_menu = memnew(PopupMenu); - file_menu->add_submenu_node_item(TTRC("Export As..."), export_as_menu, SCENE_EXPORT_AS); - export_as_menu->add_shortcut(ED_SHORTCUT("editor/export_as_mesh_library", TTRC("MeshLibrary...")), FILE_EXPORT_MESH_LIBRARY); - export_as_menu->connect("index_pressed", callable_mp(this, &EditorNode::_export_as_menu_option)); + ED_SHORTCUT("editor/export_as_mesh_library", TTRC("MeshLibrary...")), - file_menu->add_separator(); - file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), SCENE_UNDO, false, true); - file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), SCENE_REDO, false, true); - - file_menu->add_separator(); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTRC("Reload Saved Scene")), SCENE_RELOAD_SAVED_SCENE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/close_scene", TTRC("Close Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::W), SCENE_CLOSE); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/close_all_scenes", TTRC("Close All Scenes")), SCENE_CLOSE_ALL); + ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTRC("Reload Saved Scene")); + ED_SHORTCUT_AND_COMMAND("editor/close_scene", TTRC("Close Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::W); + ED_SHORTCUT_AND_COMMAND("editor/close_all_scenes", TTRC("Close All Scenes")); ED_SHORTCUT_OVERRIDE("editor/close_scene", "macos", KeyModifierMask::CMD_OR_CTRL + Key::W); - if (!global_menu || !OS::get_singleton()->has_feature("macos")) { - // On macOS "Quit" and "About" options are in the "app" menu. - file_menu->add_separator(); - file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/file_quit", TTRC("Quit"), KeyModifierMask::CMD_OR_CTRL + Key::Q), SCENE_QUIT, true); - } - ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTRC("Editor Settings...")); ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KeyModifierMask::META + Key::COMMA); -#ifdef MACOS_ENABLED - if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::APPLICATION_MENU_ID)) { - apple_menu = memnew(PopupMenu); - apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID); - main_menu_bar->add_child(apple_menu); - apple_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); - apple_menu->add_separator(); - apple_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); - } -#endif - - project_menu = memnew(PopupMenu); - _add_to_main_menu(TTRC("Project"), project_menu); - - project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/project_settings", TTRC("Project Settings..."), Key::NONE, TTRC("Project Settings")), PROJECT_OPEN_SETTINGS); - project_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + ED_SHORTCUT_AND_COMMAND("editor/file_quit", TTRC("Quit"), KeyModifierMask::CMD_OR_CTRL + Key::Q); + ED_SHORTCUT_AND_COMMAND("editor/project_settings", TTRC("Project Settings..."), Key::NONE, TTRC("Project Settings")); ED_SHORTCUT_AND_COMMAND("editor/find_in_files", TTRC("Find in Files..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F); - project_menu->add_shortcut(ED_GET_SHORTCUT("editor/find_in_files"), PROJECT_FIND_IN_FILES); - project_menu->add_separator(); - project_menu->add_item(TTRC("Version Control"), PROJECT_VERSION_CONTROL); + ED_SHORTCUT_AND_COMMAND("editor/export", TTRC("Export..."), Key::NONE, TTRC("Export")); - project_menu->add_separator(); - project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTRC("Export..."), Key::NONE, TTRC("Export")), PROJECT_EXPORT); - project_menu->add_item(TTRC("Pack Project as ZIP..."), PROJECT_PACK_AS_ZIP); - project_menu->add_item(TTRC("Install Android Build Template..."), PROJECT_INSTALL_ANDROID_SOURCE); -#ifndef ANDROID_ENABLED - project_menu->add_item(TTRC("Open User Data Folder"), PROJECT_OPEN_USER_DATA_FOLDER); -#endif + ED_SHORTCUT_AND_COMMAND("editor/orphan_resource_explorer", TTRC("Orphan Resource Explorer...")); + ED_SHORTCUT_AND_COMMAND("editor/engine_compilation_configuration_editor", TTRC("Engine Compilation Configuration Editor...")); + ED_SHORTCUT_AND_COMMAND("editor/upgrade_project", TTRC("Upgrade Project Files...")); - project_menu->add_separator(); - - tool_menu = memnew(PopupMenu); - tool_menu->connect("index_pressed", callable_mp(this, &EditorNode::_tool_menu_option)); - project_menu->add_submenu_node_item(TTRC("Tools"), tool_menu); - tool_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/orphan_resource_explorer", TTRC("Orphan Resource Explorer...")), TOOLS_ORPHAN_RESOURCES); - tool_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/engine_compilation_configuration_editor", TTRC("Engine Compilation Configuration Editor...")), TOOLS_BUILD_PROFILE_MANAGER); - tool_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/upgrade_project", TTRC("Upgrade Project Files...")), TOOLS_PROJECT_UPGRADE); - - project_menu->add_separator(); - project_menu->add_shortcut(ED_SHORTCUT("editor/reload_current_project", TTRC("Reload Current Project")), PROJECT_RELOAD_CURRENT_PROJECT); + ED_SHORTCUT("editor/reload_current_project", TTRC("Reload Current Project")); ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTRC("Quit to Project List"), KeyModifierMask::CTRL + KeyModifierMask::SHIFT + Key::Q); ED_SHORTCUT_OVERRIDE("editor/quit_to_project_list", "macos", KeyModifierMask::META + KeyModifierMask::CTRL + KeyModifierMask::ALT + Key::Q); - project_menu->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), PROJECT_QUIT_TO_PROJECT_MANAGER, true); - // Spacer to center 2D / 3D / Script buttons. - left_spacer = memnew(HBoxContainer); - left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); - title_bar->add_child(left_spacer); - - if (can_expand && global_menu) { - project_title = memnew(Label); - project_title->add_theme_font_override(SceneStringName(font), theme->get_font(SNAME("bold"), EditorStringName(EditorFonts))); - project_title->add_theme_font_size_override(SceneStringName(font_size), theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); - project_title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); - project_title->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); - project_title->set_h_size_flags(Control::SIZE_EXPAND_FILL); - project_title->set_mouse_filter(Control::MOUSE_FILTER_PASS); - left_spacer->add_child(project_title); - } - - HBoxContainer *main_editor_button_hb = memnew(HBoxContainer); - main_editor_button_hb->set_mouse_filter(Control::MOUSE_FILTER_STOP); - main_editor_button_hb->set_name("EditorMainScreenButtons"); - editor_main_screen->set_button_container(main_editor_button_hb); - title_bar->add_child(main_editor_button_hb); - title_bar->set_center_control(main_editor_button_hb); - - // Options are added and handled by DebuggerEditorPlugin. - debug_menu = memnew(PopupMenu); - _add_to_main_menu(TTRC("Debug"), debug_menu); - - settings_menu = memnew(PopupMenu); - _add_to_main_menu(TTRC("Editor"), settings_menu); - -#ifdef MACOS_ENABLED - if (!global_menu) { - settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); - } -#else - settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); -#endif - settings_menu->add_shortcut(ED_SHORTCUT("editor/command_palette", TTRC("Command Palette..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::P), EDITOR_COMMAND_PALETTE); - settings_menu->add_separator(); - - settings_menu->add_submenu_node_item(TTRC("Editor Docks"), editor_dock_manager->get_docks_menu()); - - editor_layouts = memnew(PopupMenu); - settings_menu->add_submenu_node_item(TTRC("Editor Layout"), editor_layouts); - editor_layouts->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_layout_menu_option)); - settings_menu->add_separator(); + ED_SHORTCUT("editor/command_palette", TTRC("Command Palette..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::P); ED_SHORTCUT_AND_COMMAND("editor/take_screenshot", TTRC("Take Screenshot"), KeyModifierMask::CTRL | Key::F12); ED_SHORTCUT_OVERRIDE("editor/take_screenshot", "macos", KeyModifierMask::META | Key::F12); - settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_TAKE_SCREENSHOT); - - settings_menu->set_item_tooltip(-1, TTRC("Screenshots are stored in the user data folder (\"user://\").")); ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTRC("Toggle Fullscreen"), KeyModifierMask::SHIFT | Key::F11); ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::F); - settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), EDITOR_TOGGLE_FULLSCREEN); - settings_menu->add_separator(); - -#ifndef ANDROID_ENABLED - if (EditorPaths::get_singleton()->get_data_dir() == EditorPaths::get_singleton()->get_config_dir()) { - // Configuration and data folders are located in the same place. - settings_menu->add_item(TTRC("Open Editor Data/Settings Folder"), EDITOR_OPEN_DATA_FOLDER); - } else { - // Separate configuration and data folders. - settings_menu->add_item(TTRC("Open Editor Data Folder"), EDITOR_OPEN_DATA_FOLDER); - settings_menu->add_item(TTRC("Open Editor Settings Folder"), EDITOR_OPEN_CONFIG_FOLDER); - } - settings_menu->add_separator(); -#endif - - settings_menu->add_item(TTRC("Manage Editor Features..."), EDITOR_MANAGE_FEATURE_PROFILES); - settings_menu->add_item(TTRC("Manage Export Templates..."), EDITOR_MANAGE_EXPORT_TEMPLATES); -#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) - settings_menu->add_item(TTRC("Configure FBX Importer..."), EDITOR_CONFIGURE_FBX_IMPORTER); -#endif - - help_menu = memnew(PopupMenu); - if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::HELP_MENU_ID)) { - help_menu->set_system_menu(NativeMenu::HELP_MENU_ID); - } - _add_to_main_menu(TTRC("Help"), help_menu); - - help_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTRC("Search Help..."), Key::F1); ED_SHORTCUT_OVERRIDE("editor/editor_help", "macos", KeyModifierMask::ALT | Key::SPACE); - help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("HelpSearch"), global_menu, dark_mode), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH); - help_menu->add_separator(); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTRC("Online Documentation")), HELP_DOCS); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/forum", TTRC("Forum")), HELP_FORUM); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/community", TTRC("Community")), HELP_COMMUNITY); - help_menu->add_separator(); - help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("ActionCopy"), global_menu, dark_mode), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTRC("Copy System Info")), HELP_COPY_SYSTEM_INFO); - help_menu->set_item_tooltip(-1, TTR("Copies the system info as a single-line text into the clipboard.")); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTRC("Report a Bug")), HELP_REPORT_A_BUG); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTRC("Suggest a Feature")), HELP_SUGGEST_A_FEATURE); - help_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTRC("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK); - help_menu->add_separator(); - if (!global_menu || !OS::get_singleton()->has_feature("macos")) { - // On macOS "Quit" and "About" options are in the "app" menu. - help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("Godot"), global_menu, dark_mode), ED_SHORTCUT_AND_COMMAND("editor/about", TTRC("About Godot...")), HELP_ABOUT); - } - help_menu->add_icon_shortcut(get_editor_theme_native_menu_icon(SNAME("Heart"), global_menu, dark_mode), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTRC("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT); + ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTRC("Online Documentation")); + ED_SHORTCUT_AND_COMMAND("editor/forum", TTRC("Forum")); + ED_SHORTCUT_AND_COMMAND("editor/community", TTRC("Community")); + + ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTRC("Copy System Info")); + ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTRC("Report a Bug")); + ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTRC("Suggest a Feature")); + ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTRC("Send Docs Feedback")); + ED_SHORTCUT_AND_COMMAND("editor/about", TTRC("About Godot...")); + ED_SHORTCUT_AND_COMMAND("editor/support_development", TTRC("Support Godot Development")); // Use the Ctrl modifier so F2 can be used to rename nodes in the scene tree dock. ED_SHORTCUT_AND_COMMAND("editor/editor_2d", TTRC("Open 2D Workspace"), KeyModifierMask::CTRL | Key::F1); @@ -8650,6 +8686,74 @@ EditorNode::EditorNode() { ED_SHORTCUT_AND_COMMAND("editor/editor_next", TTRC("Open the next Editor")); ED_SHORTCUT_AND_COMMAND("editor/editor_prev", TTRC("Open the previous Editor")); + // Editor menu and toolbar. + bool can_expand = bool(EDITOR_GET("interface/editor/expand_to_title")) && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_EXTEND_TO_TITLE); + +#ifdef MACOS_ENABLED + if (NativeMenu::get_singleton()->has_system_menu(NativeMenu::APPLICATION_MENU_ID)) { + apple_menu = memnew(PopupMenu); + apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID); + add_child(apple_menu); + + apple_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS); + apple_menu->add_separator(); + apple_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + } +#endif + + if (can_expand) { + // Add spacer to avoid other controls under window minimize/maximize/close buttons (left side). + left_menu_spacer = memnew(Control); + left_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + title_bar->add_child(left_menu_spacer); + } + + file_menu = memnew(PopupMenu); + file_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + file_menu->connect("about_to_popup", callable_mp(this, &EditorNode::_update_file_menu_opened)); + _add_to_main_menu(TTRC("Scene"), file_menu); + + project_menu = memnew(PopupMenu); + project_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + _add_to_main_menu(TTRC("Project"), project_menu); + + debug_menu = memnew(PopupMenu); + // Options are added and handled by DebuggerEditorPlugin, do not rebuild. + _add_to_main_menu(TTRC("Debug"), debug_menu); + + settings_menu = memnew(PopupMenu); + settings_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + _add_to_main_menu(TTRC("Editor"), settings_menu); + + help_menu = memnew(PopupMenu); + help_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); + _add_to_main_menu(TTRC("Help"), help_menu); + + _update_main_menu_type(); + + // Spacer to center 2D / 3D / Script buttons. + left_spacer = memnew(HBoxContainer); + left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); + title_bar->add_child(left_spacer); + + project_title = memnew(Label); + project_title->add_theme_font_override(SceneStringName(font), theme->get_font(SNAME("bold"), EditorStringName(EditorFonts))); + project_title->add_theme_font_size_override(SceneStringName(font_size), theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); + project_title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); + project_title->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + project_title->set_h_size_flags(Control::SIZE_EXPAND_FILL); + project_title->set_mouse_filter(Control::MOUSE_FILTER_PASS); + project_title->set_visible(can_expand && menu_type == MENU_TYPE_GLOBAL); + left_spacer->add_child(project_title); + + HBoxContainer *main_editor_button_hb = memnew(HBoxContainer); + main_editor_button_hb->set_mouse_filter(Control::MOUSE_FILTER_STOP); + main_editor_button_hb->set_name("EditorMainScreenButtons"); + editor_main_screen->set_button_container(main_editor_button_hb); + title_bar->add_child(main_editor_button_hb); + title_bar->set_center_control(main_editor_button_hb); + // Spacer to center 2D / 3D / Script buttons. right_spacer = memnew(Control); right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); @@ -8897,11 +9001,6 @@ EditorNode::EditorNode() { file_pack_zip->set_title(TTR("Pack Project as ZIP...")); gui_base->add_child(file_pack_zip); - file_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); - file_menu->connect("about_to_popup", callable_mp(this, &EditorNode::_update_file_menu_opened)); - - settings_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option)); - file->connect("file_selected", callable_mp(this, &EditorNode::_dialog_action)); file_templates->connect("file_selected", callable_mp(this, &EditorNode::_dialog_action)); @@ -8973,12 +9072,6 @@ EditorNode::EditorNode() { add_editor_plugin(VersionControlEditorPlugin::get_singleton()); - vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel(); - vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option)); - vcs_actions_menu->add_item(TTRC("Create/Override Version Control Metadata..."), VCS_METADATA); - vcs_actions_menu->add_item(TTRC("Version Control Settings..."), VCS_SETTINGS); - project_menu->set_item_submenu_node(project_menu->get_item_index(PROJECT_VERSION_CONTROL), vcs_actions_menu); - add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { diff --git a/editor/editor_node.h b/editor/editor_node.h index 2eff6a047fd..21634f59f98 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -710,6 +710,20 @@ private: bool _is_project_data_missing(); + enum MenuType { + MENU_TYPE_NONE, + MENU_TYPE_GLOBAL, + MENU_TYPE_COMPACT, + MENU_TYPE_FULL, + }; + MenuType menu_type = MENU_TYPE_NONE; + Vector main_menu_items; + + void _build_file_menu(); + void _build_project_menu(); + void _build_settings_menu(); + void _build_help_menu(); + void _update_main_menu_type(); void _add_to_main_menu(const String &p_name, PopupMenu *p_menu); diff --git a/editor/settings/editor_settings.cpp b/editor/settings/editor_settings.cpp index 7dfe8226dde..b63322e7368 100644 --- a/editor/settings/editor_settings.cpp +++ b/editor/settings/editor_settings.cpp @@ -487,7 +487,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "network/connection/check_for_updates", int(default_update_mode), "Disable Update Checks,Check Newest Preview,Check Newest Stable,Check Newest Patch"); // Uses EngineUpdateLabel::UpdateMode. } - EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/use_embedded_menu", false, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED | PROPERTY_USAGE_EDITOR_BASIC_SETTING) + EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/use_embedded_menu", false, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_BASIC_SETTING) EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/use_native_file_dialogs", false, "", PROPERTY_USAGE_DEFAULT) EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/expand_to_title", true, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED | PROPERTY_USAGE_EDITOR_BASIC_SETTING)