Reorganize EditorNode menu options

This commit is contained in:
kobewi 2025-01-03 21:30:25 +01:00
parent 76c8e76560
commit 24eadaa6a4
6 changed files with 192 additions and 204 deletions

View file

@ -313,10 +313,10 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto
void EditorNode::_version_control_menu_option(int p_idx) {
switch (vcs_actions_menu->get_item_id(p_idx)) {
case RUN_VCS_METADATA: {
case VCS_METADATA: {
VersionControlEditorPlugin::get_singleton()->popup_vcs_metadata_dialog();
} break;
case RUN_VCS_SETTINGS: {
case VCS_SETTINGS: {
VersionControlEditorPlugin::get_singleton()->popup_vcs_set_up_dialog(gui_base);
} break;
}
@ -751,7 +751,7 @@ void EditorNode::_notification(int p_what) {
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
// Save on focus loss before applying the FPS limit to avoid slowing down the saving process.
if (EDITOR_GET("interface/editor/save_on_focus_loss")) {
_menu_option_confirm(FILE_SAVE_SCENE_SILENTLY, false);
_save_scene_silently();
}
// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused.
@ -844,8 +844,8 @@ void EditorNode::_update_update_spinner() {
const bool update_continuously = EDITOR_GET("interface/editor/update_continuously");
PopupMenu *update_popup = update_spinner->get_popup();
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_CONTINUOUSLY), update_continuously);
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_WHEN_CHANGED), !update_continuously);
update_popup->set_item_checked(update_popup->get_item_index(SPINNER_UPDATE_CONTINUOUSLY), update_continuously);
update_popup->set_item_checked(update_popup->get_item_index(SPINNER_UPDATE_WHEN_CHANGED), !update_continuously);
if (update_continuously) {
update_spinner->set_tooltip_text(TTR("Spins when the editor window redraws.\nUpdate Continuously is enabled, which can increase power usage. Click to disable it."));
@ -1277,8 +1277,8 @@ void EditorNode::_titlebar_resized() {
void EditorNode::_update_undo_redo_allowed() {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_UNDO), !undo_redo->has_undo());
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_REDO), !undo_redo->has_redo());
file_menu->set_item_disabled(file_menu->get_item_index(FILE_UNDO), !undo_redo->has_undo());
file_menu->set_item_disabled(file_menu->get_item_index(FILE_REDO), !undo_redo->has_redo());
}
void EditorNode::_node_renamed() {
@ -1860,6 +1860,17 @@ int EditorNode::_save_external_resources(bool p_also_save_external_data) {
return saved;
}
void EditorNode::_save_scene_silently() {
// Save scene without displaying progress dialog. Used to work around
// errors about parent node being busy setting up children
// when Save on Focus Loss kicks in.
Node *scene = editor_data.get_edited_scene_root();
if (scene && !scene->get_scene_file_path().is_empty() && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) {
_save_scene(scene->get_scene_file_path());
save_editor_layout_delayed();
}
}
static void _reset_animation_mixers(Node *p_node, List<Pair<AnimationMixer *, Ref<AnimatedValuesBackup>>> *r_anim_backups) {
for (int i = 0; i < p_node->get_child_count(); i++) {
AnimationMixer *mixer = Object::cast_to<AnimationMixer>(p_node->get_child(i));
@ -2209,7 +2220,7 @@ void EditorNode::_dialog_action(String p_file) {
ERR_FAIL_NULL(current_obj);
current_obj->notify_property_list_changed();
} break;
case SETTINGS_LAYOUT_SAVE: {
case LAYOUT_SAVE: {
if (p_file.is_empty()) {
return;
}
@ -2237,7 +2248,7 @@ void EditorNode::_dialog_action(String p_file) {
}
} break;
case SETTINGS_LAYOUT_DELETE: {
case LAYOUT_DELETE: {
Ref<ConfigFile> config;
config.instantiate();
Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
@ -2687,6 +2698,15 @@ void EditorNode::_android_export_preset_selected(int p_index) {
install_android_build_template_message->set_text(vformat(TTR(INSTALL_ANDROID_BUILD_TEMPLATE_MESSAGE), export_template_manager->get_android_build_directory(android_export_preset)));
}
void EditorNode::_android_install_build_template() {
gradle_build_manage_templates->hide();
file_android_build_source->popup_centered_ratio();
}
void EditorNode::_android_explore_build_templates() {
OS::get_singleton()->shell_show_in_file_manager(ProjectSettings::get_singleton()->globalize_path(export_template_manager->get_android_build_directory(android_export_preset).get_base_dir()), true);
}
void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!p_confirmed) { // FIXME: this may be a hack.
current_menu_option = (MenuOptions)p_option;
@ -2733,7 +2753,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
previous_scenes.pop_back();
} break;
case FILE_CLOSE_OTHERS: {
case EditorSceneTabs::SCENE_CLOSE_OTHERS: {
tab_closing_menu_option = -1;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
if (i == editor_data.get_edited_scene()) {
@ -2743,14 +2763,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
_proceed_closing_scene_tabs();
} break;
case FILE_CLOSE_RIGHT: {
case EditorSceneTabs::SCENE_CLOSE_RIGHT: {
tab_closing_menu_option = -1;
for (int i = editor_data.get_edited_scene() + 1; i < editor_data.get_edited_scene_count(); i++) {
tabs_to_close.push_back(editor_data.get_scene_path(i));
}
_proceed_closing_scene_tabs();
} break;
case FILE_CLOSE_ALL: {
case EditorSceneTabs::SCENE_CLOSE_ALL: {
tab_closing_menu_option = -1;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
tabs_to_close.push_back(editor_data.get_scene_path(i));
@ -2760,16 +2780,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_CLOSE: {
_scene_tab_closed(editor_data.get_edited_scene());
} break;
case FILE_SAVE_SCENE_SILENTLY: {
// Save scene without displaying progress dialog. Used to work around
// errors about parent node being busy setting up children
// when Save on Focus Loss kicks in.
Node *scene = editor_data.get_edited_scene_root();
if (scene && !scene->get_scene_file_path().is_empty() && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) {
_save_scene(scene->get_scene_file_path());
save_editor_layout_delayed();
}
} break;
case SCENE_TAB_CLOSE:
case FILE_SAVE_SCENE: {
int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing_idx;
@ -2851,32 +2861,15 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
_save_all_scenes();
} break;
case FILE_RUN_SCENE: {
case EditorSceneTabs::SCENE_RUN: {
project_run_bar->play_current_scene();
} break;
case FILE_EXPORT_PROJECT: {
case PROJECT_EXPORT: {
project_export->popup_export();
} break;
case FILE_EXTERNAL_OPEN_SCENE: {
if (unsaved_cache && !p_confirmed) {
confirmation->set_ok_button_text(TTR("Open"));
confirmation->set_text(TTR("Current scene not saved. Open anyway?"));
confirmation->popup_centered();
break;
}
bool oprev = opening_prev;
Error err = load_scene(external_file);
if (err == OK && oprev) {
previous_scenes.pop_back();
opening_prev = false;
}
} break;
case EDIT_UNDO: {
case FILE_UNDO: {
if ((int)Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message(TTR("Can't undo while mouse buttons are pressed."), EditorLog::MSG_TYPE_EDITOR);
} else {
@ -2899,7 +2892,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
} break;
case EDIT_REDO: {
case FILE_REDO: {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
if ((int)Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message(TTR("Can't redo while mouse buttons are pressed."), EditorLog::MSG_TYPE_EDITOR);
@ -2926,7 +2919,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
} break;
case EDIT_RELOAD_SAVED_SCENE: {
case FILE_RELOAD_SAVED_SCENE: {
Node *scene = get_edited_scene();
if (!scene) {
@ -2960,17 +2953,18 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_SHOW_IN_FILESYSTEM: {
case EditorSceneTabs::SCENE_SHOW_IN_FILESYSTEM: {
String path = editor_data.get_scene_path(editor_data.get_edited_scene());
if (!path.is_empty()) {
FileSystemDock::get_singleton()->navigate_to_path(path);
}
} break;
case RUN_SETTINGS: {
case PROJECT_OPEN_SETTINGS: {
project_settings_editor->popup_project_settings();
} break;
case FILE_INSTALL_ANDROID_SOURCE: {
case PROJECT_INSTALL_ANDROID_SOURCE: {
if (p_confirmed) {
if (export_template_manager->is_android_template_installed(android_export_preset)) {
remove_android_build_template->set_text(vformat(TTR(REMOVE_ANDROID_BUILD_TEMPLATE_MESSAGE), export_template_manager->get_android_build_directory(android_export_preset)));
@ -3014,17 +3008,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
} break;
case RUN_USER_DATA_FOLDER: {
case PROJECT_OPEN_USER_DATA_FOLDER: {
// Ensure_user_data_dir() to prevent the edge case: "Open User Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved.
OS::get_singleton()->ensure_user_data_dir();
OS::get_singleton()->shell_show_in_file_manager(OS::get_singleton()->get_user_data_dir(), true);
} break;
case FILE_EXPLORE_ANDROID_BUILD_TEMPLATES: {
OS::get_singleton()->shell_show_in_file_manager(ProjectSettings::get_singleton()->globalize_path(export_template_manager->get_android_build_directory(android_export_preset).get_base_dir()), true);
} break;
case FILE_QUIT:
case RUN_PROJECT_MANAGER:
case RELOAD_CURRENT_PROJECT: {
case PROJECT_QUIT_TO_PROJECT_MANAGER:
case PROJECT_RELOAD_CURRENT_PROJECT: {
if (p_confirmed && plugin_to_save) {
plugin_to_save->save_external_data();
p_confirmed = false;
@ -3034,7 +3025,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
if (_next_unsaved_scene(!save_each) == -1) {
if (EditorUndoRedoManager::get_singleton()->is_history_unsaved(EditorUndoRedoManager::GLOBAL_HISTORY)) {
if (p_option == RELOAD_CURRENT_PROJECT) {
if (p_option == PROJECT_RELOAD_CURRENT_PROJECT) {
save_confirmation->set_ok_button_text(TTR("Save & Reload"));
save_confirmation->set_text(TTR("Save modified resources before reloading?"));
} else {
@ -3050,7 +3041,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
for (int i = 0; i < editor_data.get_editor_plugin_count(); i++) {
const String unsaved_status = editor_data.get_editor_plugin(i)->get_unsaved_status();
if (!unsaved_status.is_empty()) {
if (p_option == RELOAD_CURRENT_PROJECT) {
if (p_option == PROJECT_RELOAD_CURRENT_PROJECT) {
save_confirmation->set_ok_button_text(TTR("Save & Reload"));
save_confirmation->set_text(unsaved_status);
} else {
@ -3085,7 +3076,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_scene_file_path();
i = _next_unsaved_scene(true, ++i);
}
if (p_option == RELOAD_CURRENT_PROJECT) {
if (p_option == PROJECT_RELOAD_CURRENT_PROJECT) {
save_confirmation->set_ok_button_text(TTR("Save & Reload"));
save_confirmation->set_text(TTR("Save changes to the following scene(s) before reloading?") + unsaved_scenes);
} else {
@ -3102,44 +3093,40 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
_save_external_resources();
_discard_changes();
} break;
case SETTINGS_UPDATE_CONTINUOUSLY: {
case SPINNER_UPDATE_CONTINUOUSLY: {
EditorSettings::get_singleton()->set("interface/editor/update_continuously", true);
_update_update_spinner();
show_accept(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."), TTR("OK"));
} break;
case SETTINGS_UPDATE_WHEN_CHANGED: {
case SPINNER_UPDATE_WHEN_CHANGED: {
EditorSettings::get_singleton()->set("interface/editor/update_continuously", false);
_update_update_spinner();
} break;
case SETTINGS_UPDATE_SPINNER_HIDE: {
case SPINNER_UPDATE_SPINNER_HIDE: {
EditorSettings::get_singleton()->set("interface/editor/show_update_spinner", 2); // Disabled
_update_update_spinner();
} break;
case SETTINGS_PREFERENCES: {
case EDITOR_OPEN_SETTINGS: {
editor_settings_dialog->popup_edit_settings();
} break;
case SETTINGS_EDITOR_DATA_FOLDER: {
case EDITOR_OPEN_DATA_FOLDER: {
OS::get_singleton()->shell_show_in_file_manager(EditorPaths::get_singleton()->get_data_dir(), true);
} break;
case SETTINGS_EDITOR_CONFIG_FOLDER: {
case EDITOR_OPEN_CONFIG_FOLDER: {
OS::get_singleton()->shell_show_in_file_manager(EditorPaths::get_singleton()->get_config_dir(), true);
} break;
case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
case EDITOR_MANAGE_EXPORT_TEMPLATES: {
export_template_manager->popup_manager();
} break;
case SETTINGS_MANAGE_FBX_IMPORTER: {
case EDITOR_CONFIGURE_FBX_IMPORTER: {
#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
fbx_importer_manager->show_dialog();
#endif
} break;
case SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE: {
gradle_build_manage_templates->hide();
file_android_build_source->popup_centered_ratio();
} break;
case SETTINGS_MANAGE_FEATURE_PROFILES: {
case EDITOR_MANAGE_FEATURE_PROFILES: {
feature_profile_manager->popup_centered_clamped(Size2(900, 800) * EDSCALE, 0.8);
} break;
case SETTINGS_TOGGLE_FULLSCREEN: {
case EDITOR_TOGGLE_FULLSCREEN: {
DisplayServer::WindowMode mode = DisplayServer::get_singleton()->window_get_mode();
if (mode == DisplayServer::WINDOW_MODE_FULLSCREEN || mode == DisplayServer::WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
DisplayServer::get_singleton()->window_set_mode(prev_mode);
@ -3148,7 +3135,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_FULLSCREEN);
}
} break;
case EDITOR_SCREENSHOT: {
case EDITOR_TAKE_SCREENSHOT: {
screenshot_timer->start();
} break;
case SETTINGS_PICK_MAIN_SCENE: {
@ -3171,7 +3158,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case HELP_SEARCH: {
emit_signal(SNAME("request_help_search"), "");
} break;
case HELP_COMMAND_PALETTE: {
case EDITOR_COMMAND_PALETTE: {
command_palette->open_popup();
} break;
case HELP_DOCS: {
@ -3202,23 +3189,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case HELP_SUPPORT_GODOT_DEVELOPMENT: {
OS::get_singleton()->shell_open("https://godotengine.org/donate");
} break;
case SET_RENDERER_NAME_SAVE_AND_RESTART: {
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method", renderer_request);
if (renderer_request == "mobile" || renderer_request == "gl_compatibility") {
// Also change the mobile override if changing to a compatible rendering method.
// This prevents visual discrepancies between desktop and mobile platforms.
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", renderer_request);
} else if (renderer_request == "forward_plus") {
// Use the equivalent mobile rendering method. This prevents the rendering method from staying
// on its old choice if moving from `gl_compatibility` to `forward_plus`.
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", "mobile");
}
ProjectSettings::get_singleton()->save();
save_all_scenes();
restart_editor();
} break;
}
}
@ -3447,10 +3417,10 @@ void EditorNode::_discard_changes(const String &p_str) {
_exit_editor(EXIT_SUCCESS);
} break;
case RUN_PROJECT_MANAGER: {
case PROJECT_QUIT_TO_PROJECT_MANAGER: {
restart_editor(true);
} break;
case RELOAD_CURRENT_PROJECT: {
case PROJECT_RELOAD_CURRENT_PROJECT: {
restart_editor();
} break;
}
@ -5474,11 +5444,11 @@ bool EditorNode::has_scenes_in_session() {
}
void EditorNode::undo() {
trigger_menu_option(EDIT_UNDO, true);
trigger_menu_option(FILE_UNDO, true);
}
void EditorNode::redo() {
trigger_menu_option(EDIT_REDO, true);
trigger_menu_option(FILE_REDO, true);
}
bool EditorNode::ensure_main_scene(bool p_from_native) {
@ -5556,10 +5526,10 @@ void EditorNode::_update_layouts_menu() {
overridden_default_layout = -1;
editor_layouts->reset_size();
editor_layouts->add_shortcut(ED_SHORTCUT("layout/save", TTRC("Save Layout...")), SETTINGS_LAYOUT_SAVE);
editor_layouts->add_shortcut(ED_SHORTCUT("layout/delete", TTRC("Delete Layout...")), SETTINGS_LAYOUT_DELETE);
editor_layouts->add_shortcut(ED_SHORTCUT("layout/save", TTRC("Save Layout...")), LAYOUT_SAVE);
editor_layouts->add_shortcut(ED_SHORTCUT("layout/delete", TTRC("Delete Layout...")), LAYOUT_DELETE);
editor_layouts->add_separator();
editor_layouts->add_shortcut(ED_SHORTCUT("layout/default", TTRC("Default")), SETTINGS_LAYOUT_DEFAULT);
editor_layouts->add_shortcut(ED_SHORTCUT("layout/default", TTRC("Default")), LAYOUT_DEFAULT);
Ref<ConfigFile> config;
config.instantiate();
@ -5573,7 +5543,7 @@ void EditorNode::_update_layouts_menu() {
for (const String &layout : layouts) {
if (layout == TTR("Default")) {
editor_layouts->remove_item(editor_layouts->get_item_index(SETTINGS_LAYOUT_DEFAULT));
editor_layouts->remove_item(editor_layouts->get_item_index(LAYOUT_DEFAULT));
overridden_default_layout = editor_layouts->get_item_count();
}
@ -5583,21 +5553,21 @@ void EditorNode::_update_layouts_menu() {
void EditorNode::_layout_menu_option(int p_id) {
switch (p_id) {
case SETTINGS_LAYOUT_SAVE: {
case LAYOUT_SAVE: {
current_menu_option = p_id;
layout_dialog->set_title(TTR("Save Layout"));
layout_dialog->set_ok_button_text(TTR("Save"));
layout_dialog->set_name_line_enabled(true);
layout_dialog->popup_centered();
} break;
case SETTINGS_LAYOUT_DELETE: {
case LAYOUT_DELETE: {
current_menu_option = p_id;
layout_dialog->set_title(TTR("Delete Layout"));
layout_dialog->set_ok_button_text(TTR("Delete"));
layout_dialog->set_name_line_enabled(false);
layout_dialog->popup_centered();
} break;
case SETTINGS_LAYOUT_DEFAULT: {
case LAYOUT_DEFAULT: {
editor_dock_manager->load_docks_from_config(default_layout, "docks");
_save_editor_layout();
} break;
@ -5643,7 +5613,7 @@ void EditorNode::_proceed_closing_scene_tabs() {
}
bool EditorNode::_is_closing_editor() const {
return tab_closing_menu_option == FILE_QUIT || tab_closing_menu_option == RUN_PROJECT_MANAGER || tab_closing_menu_option == RELOAD_CURRENT_PROJECT;
return tab_closing_menu_option == FILE_QUIT || tab_closing_menu_option == PROJECT_QUIT_TO_PROJECT_MANAGER || tab_closing_menu_option == PROJECT_RELOAD_CURRENT_PROJECT;
}
void EditorNode::_scene_tab_closed(int p_tab) {
@ -6625,6 +6595,24 @@ void EditorNode::_add_renderer_entry(const String &p_renderer_name, bool p_mark_
renderer->add_item(item_text);
}
void EditorNode::_set_renderer_name_save_and_restart() {
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method", renderer_request);
if (renderer_request == "mobile" || renderer_request == "gl_compatibility") {
// Also change the mobile override if changing to a compatible rendering method.
// This prevents visual discrepancies between desktop and mobile platforms.
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", renderer_request);
} else if (renderer_request == "forward_plus") {
// Use the equivalent mobile rendering method. This prevents the rendering method from staying
// on its old choice if moving from `gl_compatibility` to `forward_plus`.
ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", "mobile");
}
ProjectSettings::get_singleton()->save();
save_all_scenes();
restart_editor();
}
void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) {
if (singleton->saving_resources_in_path.has(p_resource)) {
// This is going to be handled by save_resource_in_path when the time is right.
@ -7339,11 +7327,11 @@ EditorNode::EditorNode() {
export_as_menu->connect("index_pressed", callable_mp(this, &EditorNode::_export_as_menu_option));
file_menu->add_separator();
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO, false, true);
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO, false, true);
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), FILE_UNDO, false, true);
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), FILE_REDO, false, true);
file_menu->add_separator();
file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTRC("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE);
file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTRC("Reload Saved Scene")), FILE_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), FILE_CLOSE);
ED_SHORTCUT_OVERRIDE("editor/close_scene", "macos", KeyModifierMask::CMD_OR_CTRL + Key::W);
@ -7361,7 +7349,7 @@ EditorNode::EditorNode() {
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);
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));
}
@ -7371,17 +7359,17 @@ EditorNode::EditorNode() {
project_menu->set_name(TTR("Project"));
main_menu->add_child(project_menu);
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/project_settings", TTRC("Project Settings..."), Key::NONE, TTRC("Project Settings")), RUN_SETTINGS);
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));
project_menu->add_separator();
project_menu->add_item(TTR("Version Control"), VCS_MENU);
project_menu->add_item(TTR("Version Control"), PROJECT_VERSION_CONTROL);
project_menu->add_separator();
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTRC("Export..."), Key::NONE, TTRC("Export")), FILE_EXPORT_PROJECT);
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTRC("Export..."), Key::NONE, TTRC("Export")), PROJECT_EXPORT);
#ifndef ANDROID_ENABLED
project_menu->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
project_menu->add_item(TTR("Open User Data Folder"), RUN_USER_DATA_FOLDER);
project_menu->add_item(TTR("Install Android Build Template..."), PROJECT_INSTALL_ANDROID_SOURCE);
project_menu->add_item(TTR("Open User Data Folder"), PROJECT_OPEN_USER_DATA_FOLDER);
#endif
project_menu->add_separator();
@ -7394,10 +7382,10 @@ EditorNode::EditorNode() {
tool_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/upgrade_mesh_surfaces", TTRC("Upgrade Mesh Surfaces...")), TOOLS_SURFACE_UPGRADE);
project_menu->add_separator();
project_menu->add_shortcut(ED_SHORTCUT("editor/reload_current_project", TTRC("Reload Current Project")), RELOAD_CURRENT_PROJECT);
project_menu->add_shortcut(ED_SHORTCUT("editor/reload_current_project", TTRC("Reload Current Project")), PROJECT_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"), RUN_PROJECT_MANAGER, true);
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.
HBoxContainer *left_spacer = memnew(HBoxContainer);
@ -7433,12 +7421,12 @@ EditorNode::EditorNode() {
#ifdef MACOS_ENABLED
if (!global_menu) {
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), SETTINGS_PREFERENCES);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS);
}
#else
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), SETTINGS_PREFERENCES);
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), HELP_COMMAND_PALETTE);
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(TTR("Editor Docks"), editor_dock_manager->get_docks_menu());
@ -7451,31 +7439,31 @@ EditorNode::EditorNode() {
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_SCREENSHOT);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_TAKE_SCREENSHOT);
settings_menu->set_item_tooltip(-1, TTR("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"), SETTINGS_TOGGLE_FULLSCREEN);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), EDITOR_TOGGLE_FULLSCREEN);
settings_menu->add_separator();
#ifndef ANDROID_ENABLED
if (OS::get_singleton()->get_data_path() == OS::get_singleton()->get_config_path()) {
// Configuration and data folders are located in the same place (Windows/macOS).
settings_menu->add_item(TTR("Open Editor Data/Settings Folder"), SETTINGS_EDITOR_DATA_FOLDER);
settings_menu->add_item(TTR("Open Editor Data/Settings Folder"), EDITOR_OPEN_DATA_FOLDER);
} else {
// Separate configuration and data folders (Linux).
settings_menu->add_item(TTR("Open Editor Data Folder"), SETTINGS_EDITOR_DATA_FOLDER);
settings_menu->add_item(TTR("Open Editor Settings Folder"), SETTINGS_EDITOR_CONFIG_FOLDER);
settings_menu->add_item(TTR("Open Editor Data Folder"), EDITOR_OPEN_DATA_FOLDER);
settings_menu->add_item(TTR("Open Editor Settings Folder"), EDITOR_OPEN_CONFIG_FOLDER);
}
settings_menu->add_separator();
#endif
settings_menu->add_item(TTR("Manage Editor Features..."), SETTINGS_MANAGE_FEATURE_PROFILES);
settings_menu->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
settings_menu->add_item(TTR("Manage Editor Features..."), EDITOR_MANAGE_FEATURE_PROFILES);
settings_menu->add_item(TTR("Manage Export Templates..."), EDITOR_MANAGE_EXPORT_TEMPLATES);
#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
settings_menu->add_item(TTR("Configure FBX Importer..."), SETTINGS_MANAGE_FBX_IMPORTER);
settings_menu->add_item(TTR("Configure FBX Importer..."), EDITOR_CONFIGURE_FBX_IMPORTER);
#endif
help_menu = memnew(PopupMenu);
@ -7572,7 +7560,7 @@ EditorNode::EditorNode() {
video_restart_dialog = memnew(ConfirmationDialog);
video_restart_dialog->set_ok_button_text(TTR("Save & Restart"));
video_restart_dialog->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_option).bind(SET_RENDERER_NAME_SAVE_AND_RESTART));
video_restart_dialog->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_set_renderer_name_save_and_restart));
gui_base->add_child(video_restart_dialog);
progress_hb = memnew(BackgroundProgress);
@ -7588,10 +7576,10 @@ EditorNode::EditorNode() {
update_spinner->set_button_icon(theme->get_icon(SNAME("Progress1"), EditorStringName(EditorIcons)));
update_spinner->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option));
PopupMenu *p = update_spinner->get_popup();
p->add_radio_check_item(TTR("Update Continuously"), SETTINGS_UPDATE_CONTINUOUSLY);
p->add_radio_check_item(TTR("Update When Changed"), SETTINGS_UPDATE_WHEN_CHANGED);
p->add_radio_check_item(TTR("Update Continuously"), SPINNER_UPDATE_CONTINUOUSLY);
p->add_radio_check_item(TTR("Update When Changed"), SPINNER_UPDATE_WHEN_CHANGED);
p->add_separator();
p->add_item(TTR("Hide Update Spinner"), SETTINGS_UPDATE_SPINNER_HIDE);
p->add_item(TTR("Hide Update Spinner"), SPINNER_UPDATE_SPINNER_HIDE);
_update_update_spinner();
// Instantiate and place editor docks.
@ -7687,8 +7675,8 @@ EditorNode::EditorNode() {
gradle_build_manage_templates = memnew(ConfirmationDialog);
gradle_build_manage_templates->set_text(TTR("Android build template is missing, please install relevant templates."));
gradle_build_manage_templates->set_ok_button_text(TTR("Manage Templates"));
gradle_build_manage_templates->add_button(TTR("Install from file"))->connect(SceneStringName(pressed), callable_mp(this, &EditorNode::_menu_option).bind(SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE));
gradle_build_manage_templates->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_option).bind(SETTINGS_MANAGE_EXPORT_TEMPLATES));
gradle_build_manage_templates->add_button(TTR("Install from file"))->connect(SceneStringName(pressed), callable_mp(this, &EditorNode::_android_install_build_template));
gradle_build_manage_templates->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_option).bind(EDITOR_MANAGE_EXPORT_TEMPLATES));
gui_base->add_child(gradle_build_manage_templates);
file_android_build_source = memnew(EditorFileDialog);
@ -7720,7 +7708,7 @@ EditorNode::EditorNode() {
remove_android_build_template = memnew(ConfirmationDialog);
remove_android_build_template->set_ok_button_text(TTR("Show in File Manager"));
remove_android_build_template->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_option).bind(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
remove_android_build_template->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_android_explore_build_templates));
gui_base->add_child(remove_android_build_template);
file_templates = memnew(EditorFileDialog);
@ -7829,9 +7817,9 @@ EditorNode::EditorNode() {
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(TTR("Create/Override Version Control Metadata..."), RUN_VCS_METADATA);
vcs_actions_menu->add_item(TTR("Version Control Settings..."), RUN_VCS_SETTINGS);
project_menu->set_item_submenu_node(project_menu->get_item_index(VCS_MENU), vcs_actions_menu);
vcs_actions_menu->add_item(TTR("Create/Override Version Control Metadata..."), VCS_METADATA);
vcs_actions_menu->add_item(TTR("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)));

View file

@ -133,92 +133,82 @@ public:
};
enum MenuOptions {
// Scene menu.
FILE_NEW_SCENE,
FILE_NEW_INHERITED_SCENE,
FILE_OPEN_SCENE,
FILE_OPEN_PREV,
FILE_OPEN_RECENT,
FILE_SAVE_SCENE,
FILE_SAVE_SCENE_SILENTLY,
FILE_SAVE_AS_SCENE,
FILE_SAVE_ALL_SCENES,
FILE_SAVE_AND_RUN,
FILE_SAVE_AND_RUN_MAIN_SCENE,
FILE_RUN_SCENE,
FILE_SHOW_IN_FILESYSTEM,
FILE_EXPORT_PROJECT,
FILE_EXPORT_MESH_LIBRARY,
FILE_INSTALL_ANDROID_SOURCE,
FILE_EXPLORE_ANDROID_BUILD_TEMPLATES,
FILE_SAVE_OPTIMIZED,
FILE_OPEN_RECENT,
FILE_OPEN_OLD_SCENE,
FILE_QUICK_OPEN,
FILE_QUICK_OPEN_SCENE,
FILE_QUICK_OPEN_SCRIPT,
FILE_OPEN_PREV,
FILE_UNDO,
FILE_REDO,
FILE_RELOAD_SAVED_SCENE,
FILE_CLOSE,
FILE_CLOSE_OTHERS,
FILE_CLOSE_RIGHT,
FILE_CLOSE_ALL,
FILE_QUIT,
FILE_EXTERNAL_OPEN_SCENE,
EDIT_UNDO,
EDIT_REDO,
EDIT_RELOAD_SAVED_SCENE,
FILE_EXPORT_MESH_LIBRARY,
// Project menu.
PROJECT_OPEN_SETTINGS,
PROJECT_VERSION_CONTROL,
PROJECT_EXPORT,
PROJECT_INSTALL_ANDROID_SOURCE,
PROJECT_OPEN_USER_DATA_FOLDER,
PROJECT_RELOAD_CURRENT_PROJECT,
PROJECT_QUIT_TO_PROJECT_MANAGER,
TOOLS_ORPHAN_RESOURCES,
TOOLS_BUILD_PROFILE_MANAGER,
TOOLS_SURFACE_UPGRADE,
TOOLS_CUSTOM,
RESOURCE_SAVE,
RESOURCE_SAVE_AS,
RUN_SETTINGS,
RUN_USER_DATA_FOLDER,
RELOAD_CURRENT_PROJECT,
RUN_PROJECT_MANAGER,
VCS_MENU,
RUN_VCS_METADATA,
RUN_VCS_SETTINGS,
SETTINGS_UPDATE_CONTINUOUSLY,
SETTINGS_UPDATE_WHEN_CHANGED,
SETTINGS_UPDATE_ALWAYS,
SETTINGS_UPDATE_CHANGES,
SETTINGS_UPDATE_SPINNER_HIDE,
SETTINGS_PREFERENCES,
SETTINGS_LAYOUT_SAVE,
SETTINGS_LAYOUT_DELETE,
SETTINGS_LAYOUT_DEFAULT,
SETTINGS_EDITOR_DATA_FOLDER,
SETTINGS_EDITOR_CONFIG_FOLDER,
SETTINGS_MANAGE_EXPORT_TEMPLATES,
SETTINGS_MANAGE_FBX_IMPORTER,
SETTINGS_MANAGE_FEATURE_PROFILES,
SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE,
SETTINGS_PICK_MAIN_SCENE,
SETTINGS_TOGGLE_FULLSCREEN,
SETTINGS_HELP,
VCS_METADATA,
VCS_SETTINGS,
SCENE_TAB_CLOSE,
// Editor menu.
EDITOR_OPEN_SETTINGS,
EDITOR_COMMAND_PALETTE,
EDITOR_TAKE_SCREENSHOT,
EDITOR_TOGGLE_FULLSCREEN,
EDITOR_OPEN_DATA_FOLDER,
EDITOR_OPEN_CONFIG_FOLDER,
EDITOR_MANAGE_FEATURE_PROFILES,
EDITOR_MANAGE_EXPORT_TEMPLATES,
EDITOR_CONFIGURE_FBX_IMPORTER,
EDITOR_SCREENSHOT,
EDITOR_OPEN_SCREENSHOT,
LAYOUT_SAVE,
LAYOUT_DELETE,
LAYOUT_DEFAULT,
// Help menu.
HELP_SEARCH,
HELP_COMMAND_PALETTE,
HELP_DOCS,
HELP_FORUM,
HELP_REPORT_A_BUG,
HELP_COMMUNITY,
HELP_COPY_SYSTEM_INFO,
HELP_REPORT_A_BUG,
HELP_SUGGEST_A_FEATURE,
HELP_SEND_DOCS_FEEDBACK,
HELP_COMMUNITY,
HELP_ABOUT,
HELP_SUPPORT_GODOT_DEVELOPMENT,
SET_RENDERER_NAME_SAVE_AND_RESTART,
// Update spinner menu.
SPINNER_UPDATE_CONTINUOUSLY,
SPINNER_UPDATE_WHEN_CHANGED,
SPINNER_UPDATE_SPINNER_HIDE,
IMPORT_PLUGIN_BASE = 100,
TOOL_MENU_BASE = 1000
// Non-menu options.
SCENE_TAB_CLOSE,
FILE_SAVE_AND_RUN,
FILE_SAVE_AND_RUN_MAIN_SCENE,
RESOURCE_SAVE,
RESOURCE_SAVE_AS,
SETTINGS_PICK_MAIN_SCENE,
};
struct ExecuteThreadArgs {
@ -237,7 +227,7 @@ private:
enum {
MAX_INIT_CALLBACKS = 128,
MAX_BUILD_CALLBACKS = 128
MAX_BUILD_CALLBACKS = 128,
};
struct ExportDefer {
@ -448,9 +438,6 @@ private:
uint64_t update_spinner_step_frame = 0;
int update_spinner_step = 0;
String _tmp_import_path;
String external_file;
String open_navigate;
String saving_scene;
EditorProgress *save_scene_progress = nullptr;
@ -527,6 +514,8 @@ private:
void _android_build_source_selected(const String &p_file);
void _android_export_preset_selected(int p_index);
void _android_install_build_template();
void _android_explore_build_templates();
void _request_screenshot();
void _screenshot(bool p_use_utc = false);
@ -564,6 +553,7 @@ private:
void _update_undo_redo_allowed();
int _save_external_resources(bool p_also_save_external_data = false);
void _save_scene_silently();
void _set_current_scene(int p_idx);
void _set_current_scene_nocheck(int p_idx);
@ -597,6 +587,7 @@ private:
void _renderer_selected(int);
void _update_renderer_color();
void _add_renderer_entry(const String &p_renderer_name, bool p_mark_overridden);
void _set_renderer_name_save_and_restart();
void _exit_editor(int p_exit_code);

View file

@ -321,7 +321,7 @@ void EditorRunBar::recovery_mode_show_dialog() {
}
void EditorRunBar::recovery_mode_reload_project() {
EditorNode::get_singleton()->trigger_menu_option(EditorNode::RELOAD_CURRENT_PROJECT, false);
EditorNode::get_singleton()->trigger_menu_option(EditorNode::PROJECT_RELOAD_CURRENT_PROJECT, false);
}
void EditorRunBar::play_main_scene(bool p_from_native) {

View file

@ -48,8 +48,6 @@
#include "scene/gui/tab_bar.h"
#include "scene/gui/texture_rect.h"
EditorSceneTabs *EditorSceneTabs::singleton = nullptr;
void EditorSceneTabs::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
@ -195,9 +193,9 @@ void EditorSceneTabs::_update_context_menu() {
if (tab_id >= 0) {
scene_tabs_context_menu->add_separator();
scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), EditorNode::FILE_SHOW_IN_FILESYSTEM);
scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), SCENE_SHOW_IN_FILESYSTEM);
DISABLE_LAST_OPTION_IF(!ResourceLoader::exists(EditorNode::get_editor_data().get_scene_path(tab_id)));
scene_tabs_context_menu->add_item(TTR("Play This Scene"), EditorNode::FILE_RUN_SCENE);
scene_tabs_context_menu->add_item(TTR("Play This Scene"), SCENE_RUN);
DISABLE_LAST_OPTION_IF(no_root_node);
scene_tabs_context_menu->add_separator();
@ -206,11 +204,11 @@ void EditorSceneTabs::_update_context_menu() {
scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/reopen_closed_scene"), EditorNode::FILE_OPEN_PREV);
scene_tabs_context_menu->set_item_text(-1, TTR("Undo Close Tab"));
DISABLE_LAST_OPTION_IF(!EditorNode::get_singleton()->has_previous_scenes());
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), EditorNode::FILE_CLOSE_OTHERS);
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), SCENE_CLOSE_OTHERS);
DISABLE_LAST_OPTION_IF(EditorNode::get_editor_data().get_edited_scene_count() <= 1);
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), EditorNode::FILE_CLOSE_RIGHT);
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), SCENE_CLOSE_RIGHT);
DISABLE_LAST_OPTION_IF(EditorNode::get_editor_data().get_edited_scene_count() == tab_id + 1);
scene_tabs_context_menu->add_item(TTR("Close All Tabs"), EditorNode::FILE_CLOSE_ALL);
scene_tabs_context_menu->add_item(TTR("Close All Tabs"), SCENE_CLOSE_ALL);
const PackedStringArray paths = { EditorNode::get_editor_data().get_scene_path(tab_id) };
EditorContextMenuPluginManager::get_singleton()->add_options_from_plugins(scene_tabs_context_menu, EditorContextMenuPlugin::CONTEXT_SLOT_SCENE_TABS, paths);

View file

@ -44,8 +44,18 @@ class TextureRect;
class EditorSceneTabs : public MarginContainer {
GDCLASS(EditorSceneTabs, MarginContainer);
static EditorSceneTabs *singleton;
inline static EditorSceneTabs *singleton = nullptr;
public:
enum {
SCENE_SHOW_IN_FILESYSTEM = 3000, // Prevents conflicts with EditorNode options.
SCENE_RUN,
SCENE_CLOSE_OTHERS,
SCENE_CLOSE_RIGHT,
SCENE_CLOSE_ALL,
};
private:
PanelContainer *tabbar_panel = nullptr;
HBoxContainer *tabbar_container = nullptr;

View file

@ -34,6 +34,7 @@
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/gui/editor_scene_tabs.h"
#include "editor/gui/editor_toaster.h"
#include "editor/themes/editor_scale.h"
#include "servers/rendering_server.h"
@ -118,7 +119,7 @@ void SurfaceUpgradeTool::begin_upgrade() {
}
void SurfaceUpgradeTool::finish_upgrade() {
EditorNode::get_singleton()->trigger_menu_option(EditorNode::FILE_CLOSE_ALL, true);
EditorNode::get_singleton()->trigger_menu_option(EditorSceneTabs::SCENE_CLOSE_ALL, true);
// Update all meshes here.
Vector<String> resave_paths = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "resave_paths", Vector<String>());