diff options
Diffstat (limited to 'editor/editor_node.cpp')
-rw-r--r-- | editor/editor_node.cpp | 279 |
1 files changed, 154 insertions, 125 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index d8f0367b33..8bc87b7f81 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -394,7 +394,7 @@ void EditorNode::_version_control_menu_option(int p_idx) { void EditorNode::_update_title() { const String appname = ProjectSettings::get_singleton()->get("application/config/name"); String title = (appname.is_empty() ? "Unnamed Project" : appname) + String(" - ") + VERSION_NAME; - const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String(); + const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_scene_file_path() : String(); if (!edited.is_empty()) { // Display the edited scene name before the program name so that it can be seen in the OS task bar. title = vformat("%s - %s", edited.get_file(), title); @@ -576,7 +576,7 @@ void EditorNode::_notification(int p_what) { // update the icon itself only when the spinner is visible if (EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")) { - update_spinner->set_icon(gui_base->get_theme_icon("Progress" + itos(update_spinner_step + 1), "EditorIcons")); + update_spinner->set_icon(gui_base->get_theme_icon("Progress" + itos(update_spinner_step + 1), SNAME("EditorIcons"))); } } @@ -741,6 +741,21 @@ void EditorNode::_notification(int p_what) { main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); } + Set<String> updated_textfile_extensions; + bool extensions_match = true; + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (const String &E : textfile_ext) { + updated_textfile_extensions.insert(E); + if (extensions_match && !textfile_extensions.has(E)) { + extensions_match = false; + } + } + + if (!extensions_match || updated_textfile_extensions.size() < textfile_extensions.size()) { + textfile_extensions = updated_textfile_extensions; + EditorFileSystem::get_singleton()->scan(); + } + _update_update_spinner(); } break; @@ -767,7 +782,7 @@ void EditorNode::_update_update_spinner() { // On a light theme, icons are dark, so we need to modulate them with an even brighter color. const bool dark_theme = EditorSettings::get_singleton()->is_dark_theme(); update_spinner->set_self_modulate( - gui_base->get_theme_color("error_color", "Editor") * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25))); + gui_base->get_theme_color(SNAME("error_color"), SNAME("Editor")) * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25))); } else { update_spinner->set_tooltip(TTR("Spins when the editor window redraws.")); update_spinner->set_self_modulate(Color(1, 1, 1)); @@ -1114,7 +1129,13 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d dependency_errors.clear(); Error err; - RES res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + + RES res; + if (ResourceLoader::exists(p_resource, "")) { + res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + } else if (textfile_extensions.has(p_resource.get_extension())) { + res = ScriptEditor::get_singleton()->open_file(p_resource); + } ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN); if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) { @@ -1175,7 +1196,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String int srpos = path.find("::"); if (srpos != -1) { String base = path.substr(0, srpos); - if (!get_edited_scene() || get_edited_scene()->get_filename() != base) { + if (!get_edited_scene() || get_edited_scene()->get_scene_file_path() != base) { show_warning(TTR("This resource can't be saved because it does not belong to the edited scene. Make it unique first.")); return; } @@ -1549,7 +1570,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_node) { for (int i = 0; i < p_node->get_child_count(); i++) { Node *child = p_node->get_child(i); - if (child->get_filename() == p_filename) { + if (child->get_scene_file_path() == p_filename) { return true; } @@ -1645,7 +1666,7 @@ void EditorNode::_save_scene(String p_file, int idx) { return; } - if (scene->get_filename() != String() && _validate_scene_recursive(scene->get_filename(), scene)) { + if (scene->get_scene_file_path() != String() && _validate_scene_recursive(scene->get_scene_file_path(), scene)) { show_accept(TTR("This scene can't be saved because there is a cyclic instancing inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK")); return; } @@ -1699,7 +1720,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } if (err == OK) { - scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file)); + scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(p_file)); if (idx < 0 || idx == editor_data.get_edited_scene()) { set_current_version(editor_data.get_undo_redo().get_version()); } else { @@ -1727,8 +1748,8 @@ void EditorNode::save_scene_list(Vector<String> p_scene_filenames) { for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { Node *scene = editor_data.get_edited_scene_root(i); - if (scene && (p_scene_filenames.find(scene->get_filename()) >= 0)) { - _save_scene(scene->get_filename(), i); + if (scene && (p_scene_filenames.find(scene->get_scene_file_path()) >= 0)) { + _save_scene(scene->get_scene_file_path(), i); } } } @@ -1738,7 +1759,7 @@ void EditorNode::restart_editor() { String to_reopen; if (get_tree()->get_edited_scene_root()) { - to_reopen = get_tree()->get_edited_scene_root()->get_filename(); + to_reopen = get_tree()->get_edited_scene_root()->get_scene_file_path(); } _exit_editor(); @@ -1757,13 +1778,15 @@ void EditorNode::restart_editor() { void EditorNode::_save_all_scenes() { for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { Node *scene = editor_data.get_edited_scene_root(i); - if (scene && scene->get_filename() != "") { + if (scene && scene->get_scene_file_path() != "" && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) { if (i != editor_data.get_edited_scene()) { - _save_scene(scene->get_filename(), i); + _save_scene(scene->get_scene_file_path(), i); } else { - _save_scene_with_preview(scene->get_filename()); + _save_scene_with_preview(scene->get_scene_file_path()); } - } // else: ignore new scenes + } else { + show_warning(TTR("Could not save one or more scenes!"), TTR("Save All Scenes")); + } } _save_default_environment(); @@ -1776,7 +1799,7 @@ void EditorNode::_mark_unsaved_scenes() { continue; } - String path = node->get_filename(); + String path = node->get_scene_file_path(); if (!(path == String() || FileAccess::exists(path))) { if (i == editor_data.get_edited_scene()) { set_current_version(-1); @@ -2128,7 +2151,7 @@ void EditorNode::_edit_current() { if (FileAccess::exists(base_path + ".import")) { editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } else { - if ((!get_edited_scene() || get_edited_scene()->get_filename() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") { + if ((!get_edited_scene() || get_edited_scene()->get_scene_file_path() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") { editable_warning = TTR("This resource belongs to a scene that was instantiated or inherited.\nChanges to it won't be kept when saving the current scene."); } } @@ -2152,8 +2175,8 @@ void EditorNode::_edit_current() { inspector_dock->update(nullptr); } - if (get_edited_scene() && get_edited_scene()->get_filename() != String()) { - String source_scene = get_edited_scene()->get_filename(); + if (get_edited_scene() && get_edited_scene()->get_scene_file_path() != String()) { + String source_scene = get_edited_scene()->get_scene_file_path(); if (FileAccess::exists(source_scene + ".import")) { editable_warning = TTR("This scene was imported, so changes to it won't be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } @@ -2276,7 +2299,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { String args; bool skip_breakpoints; - if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_filename())) { + if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) { Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -2284,7 +2307,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { return; } - if (scene->get_filename() == "") { + if (scene->get_scene_file_path() == "") { current_option = -1; _menu_option(FILE_SAVE_AS_SCENE); // Set the option to save and run so when the dialog is accepted, the scene runs. @@ -2293,7 +2316,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { return; } - run_filename = scene->get_filename(); + run_filename = scene->get_scene_file_path(); } else if (p_custom != "") { run_filename = p_custom; } @@ -2309,8 +2332,8 @@ void EditorNode::_run(bool p_current, const String &p_custom) { if (unsaved_cache) { Node *scene = editor_data.get_edited_scene_root(); - if (scene && scene->get_filename() != "") { // Only autosave if there is a scene and if it has a path. - _save_scene_with_preview(scene->get_filename()); + if (scene && scene->get_scene_file_path() != "") { // Only autosave if there is a scene and if it has a path. + _save_scene_with_preview(scene->get_scene_file_path()); } } _menu_option(FILE_SAVE_ALL_SCENES); @@ -2403,7 +2426,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { Node *scene = editor_data.get_edited_scene_root(); if (scene) { - file->set_current_path(scene->get_filename()); + file->set_current_path(scene->get_scene_file_path()); }; file->set_title(p_option == FILE_OPEN_SCENE ? TTR("Open Scene") : TTR("Open Base Scene")); file->popup_file_dialog(); @@ -2465,7 +2488,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { if (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) { Node *scene_root = editor_data.get_edited_scene_root(tab_closing); if (scene_root) { - String scene_filename = scene_root->get_filename(); + String scene_filename = scene_root->get_scene_file_path(); save_confirmation->get_ok_button()->set_text(TTR("Save & Close")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene")); save_confirmation->popup_centered(); @@ -2484,20 +2507,22 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case SCENE_TAB_CLOSE: case FILE_SAVE_SCENE: { int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing; - Node *scene = editor_data.get_edited_scene_root(scene_idx); - if (scene && scene->get_filename() != "") { - if (scene_idx != editor_data.get_edited_scene()) { - _save_scene_with_preview(scene->get_filename(), scene_idx); - } else { - _save_scene_with_preview(scene->get_filename()); - } + if (scene && scene->get_scene_file_path() != "") { + if (DirAccess::exists(scene->get_scene_file_path().get_base_dir())) { + if (scene_idx != editor_data.get_edited_scene()) { + _save_scene_with_preview(scene->get_scene_file_path(), scene_idx); + } else { + _save_scene_with_preview(scene->get_scene_file_path()); + } - if (scene_idx != -1) { - _discard_changes(); + if (scene_idx != -1) { + _discard_changes(); + } + save_layout(); + } else { + show_save_accept(vformat(TTR("%s no longer exists! Please specify a new save location."), scene->get_scene_file_path().get_base_dir()), TTR("OK")); } - save_layout(); - break; } [[fallthrough]]; @@ -2539,8 +2564,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); } - if (scene->get_filename() != "") { - String path = scene->get_filename(); + if (scene->get_scene_file_path() != "") { + String path = scene->get_scene_file_path(); file->set_current_path(path); if (extensions.size()) { String ext = path.get_extension().to_lower(); @@ -2638,7 +2663,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { break; } - String filename = scene->get_filename(); + String filename = scene->get_scene_file_path(); if (filename == String()) { show_warning(TTR("Can't reload a scene that was never saved.")); @@ -2760,7 +2785,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { String unsaved_scenes; int i = _next_unsaved_scene(true, 0); while (i != -1) { - unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_filename(); + unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_scene_file_path(); i = _next_unsaved_scene(true, ++i); } @@ -2835,7 +2860,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { Node *scene = editor_data.get_edited_scene_root(); if (scene) { - file->set_current_path(scene->get_filename()); + file->set_current_path(scene->get_scene_file_path()); }; file->set_title(TTR("Pick a Main Scene")); file->popup_file_dialog(); @@ -2937,7 +2962,7 @@ int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) { int current = editor_data.get_edited_scene(); bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0; if (unsaved) { - String scene_filename = editor_data.get_edited_scene_root(i)->get_filename(); + String scene_filename = editor_data.get_edited_scene_root(i)->get_scene_file_path(); if (p_valid_filename && scene_filename.length() == 0) { continue; } @@ -2969,7 +2994,7 @@ void EditorNode::_discard_changes(const String &p_str) { case SCENE_TAB_CLOSE: { Node *scene = editor_data.get_edited_scene_root(tab_closing); if (scene != nullptr) { - String scene_filename = scene->get_filename(); + String scene_filename = scene->get_scene_file_path(); if (scene_filename != "") { previous_scenes.push_back(scene_filename); } @@ -3177,8 +3202,8 @@ void EditorNode::_update_addon_config() { Vector<String> enabled_addons; - for (Map<String, EditorPlugin *>::Element *E = plugin_addons.front(); E; E = E->next()) { - enabled_addons.push_back(E->key()); + for (const KeyValue<String, EditorPlugin *> &E : plugin_addons) { + enabled_addons.push_back(E.key); } if (enabled_addons.size() == 0) { @@ -3560,9 +3585,9 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b dependency_errors.erase(lpath); //at least not self path - for (Map<String, Set<String>>::Element *E = dependency_errors.front(); E; E = E->next()) { - String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E->key()) + "\n"; - for (Set<String>::Element *F = E->get().front(); F; F = F->next()) { + for (KeyValue<String, Set<String>> &E : dependency_errors) { + String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E.key) + "\n"; + for (Set<String>::Element *F = E.value.front(); F; F = F->next()) { txt += "\t" + F->get() + "\n"; } add_io_error(txt); @@ -3598,7 +3623,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b Ref<SceneState> state = sdata->get_state(); state->set_path(lpath); new_scene->set_scene_inherited_state(state); - new_scene->set_filename(String()); + new_scene->set_scene_file_path(String()); } new_scene->set_scene_instance_state(Ref<SceneState>()); @@ -3771,7 +3796,7 @@ void EditorNode::_load_error_notify(void *p_ud, const String &p_text) { } bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const { - if (p_node->get_filename() == p_path) { + if (p_node->get_scene_file_path() == p_path) { return true; } @@ -3949,7 +3974,7 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na pick_main_scene->hide(); current_option = SETTINGS_PICK_MAIN_SCENE; - _dialog_action(scene->get_filename()); + _dialog_action(scene->get_scene_file_path()); } } @@ -4025,8 +4050,8 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p } const Map<String, Vector<EditorData::CustomType>> &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType>>::Element *E = p_map.front(); E; E = E->next()) { - const Vector<EditorData::CustomType> &ct = E->value(); + for (const KeyValue<String, Vector<EditorData::CustomType>> &E : p_map) { + const Vector<EditorData::CustomType> &ct = E.value; for (int i = 0; i < ct.size(); ++i) { if (ct[i].name == p_class) { if (ct[i].icon.is_valid()) { @@ -4150,6 +4175,13 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) { accept->popup_centered(); } +void EditorNode::show_save_accept(const String &p_text, const String &p_title) { + current_option = -1; + save_accept->get_ok_button()->set_text(p_title); + save_accept->set_text(p_text); + save_accept->popup_centered(); +} + void EditorNode::show_warning(const String &p_text, const String &p_title) { if (warning->is_inside_tree()) { warning->set_text(p_text); @@ -4932,7 +4964,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) { editor_data.get_scene_version(p_tab) != 0; if (unsaved) { save_confirmation->get_ok_button()->set_text(TTR("Save & Close")); - save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene")); + save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_scene_file_path() != "" ? scene->get_scene_file_path() : "unsaved scene")); save_confirmation->popup_centered(); } else { _discard_changes(); @@ -5967,7 +5999,7 @@ EditorNode::EditorNode() { EDITOR_DEF_RST("interface/editor/save_each_scene_on_quit", true); EDITOR_DEF("interface/editor/show_update_spinner", false); EDITOR_DEF("interface/editor/update_continuously", false); - EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false); + EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", true); EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true); EDITOR_DEF_RST("interface/inspector/capitalize_properties", true); EDITOR_DEF_RST("interface/inspector/default_float_step", 0.001); @@ -5984,6 +6016,11 @@ EditorNode::EditorNode() { EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (const String &E : textfile_ext) { + textfile_extensions.insert(E); + } + theme_base = memnew(Control); add_child(theme_base); theme_base->set_anchors_and_offsets_preset(Control::PRESET_WIDE); @@ -6105,9 +6142,9 @@ EditorNode::EditorNode() { dock_tab_move_right = memnew(Button); dock_tab_move_right->set_flat(true); if (gui_base->is_layout_rtl()) { - dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); - } else { dock_tab_move_right->set_icon(theme->get_icon("Back", "EditorIcons")); + } else { + dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); } dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_right->connect("pressed", callable_mp(this, &EditorNode::_dock_move_right)); @@ -6184,12 +6221,12 @@ EditorNode::EditorNode() { scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); scene_tabs->set_drag_to_rearrange_enabled(true); scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed)); - scene_tabs->connect("right_button_pressed", callable_mp(this, &EditorNode::_scene_tab_script_edited)); + scene_tabs->connect("tab_rmb_clicked", callable_mp(this, &EditorNode::_scene_tab_script_edited)); scene_tabs->connect("tab_closed", callable_mp(this, &EditorNode::_scene_tab_closed), varray(SCENE_TAB_CLOSE)); scene_tabs->connect("tab_hovered", callable_mp(this, &EditorNode::_scene_tab_hovered)); scene_tabs->connect("mouse_exited", callable_mp(this, &EditorNode::_scene_tab_exit)); scene_tabs->connect("gui_input", callable_mp(this, &EditorNode::_scene_tab_input)); - scene_tabs->connect("reposition_active_tab_request", callable_mp(this, &EditorNode::_reposition_active_tab)); + scene_tabs->connect("active_tab_rearranged", callable_mp(this, &EditorNode::_reposition_active_tab)); scene_tabs->connect("resized", callable_mp(this, &EditorNode::_update_scene_tabs)); tabbar_container = memnew(HBoxContainer); @@ -6203,11 +6240,9 @@ EditorNode::EditorNode() { tabbar_container->add_child(scene_tabs); distraction_free = memnew(Button); distraction_free->set_flat(true); -#ifdef OSX_ENABLED - distraction_free->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_D)); -#else - distraction_free->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11)); -#endif + ED_SHORTCUT_AND_COMMAND("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11); + ED_SHORTCUT_OVERRIDE("editor/distraction_free_mode", "macos", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_D); + distraction_free->set_shortcut(ED_GET_SHORTCUT("editor/distraction_free_mode")); distraction_free->set_tooltip(TTR("Toggle distraction-free mode.")); distraction_free->connect("pressed", callable_mp(this, &EditorNode::_toggle_distraction_free_mode)); distraction_free->set_icon(gui_base->get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons"))); @@ -6265,6 +6300,10 @@ EditorNode::EditorNode() { gui_base->add_child(accept); accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current)); + save_accept = memnew(AcceptDialog); + gui_base->add_child(save_accept); + save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), make_binds((int)MenuOptions::FILE_SAVE_AS_SCENE)); + project_export = memnew(ProjectExportDialog); gui_base->add_child(project_export); @@ -6395,11 +6434,9 @@ EditorNode::EditorNode() { p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/reload_current_project", TTR("Reload Current Project")), RUN_RELOAD_CURRENT_PROJECT); -#ifdef OSX_ENABLED - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true); -#else - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Q), RUN_PROJECT_MANAGER, true); -#endif + ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Q); + ED_SHORTCUT_OVERRIDE("editor/quit_to_project_list", "macos", KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q); + p->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), RUN_PROJECT_MANAGER, true); menu_hb->add_spacer(); @@ -6424,11 +6461,10 @@ EditorNode::EditorNode() { left_menu_hb->add_child(settings_menu); p = settings_menu->get_popup(); -#ifdef OSX_ENABLED - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings..."), KEY_MASK_CMD + KEY_COMMA), SETTINGS_PREFERENCES); -#else - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings...")); + ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KEY_MASK_CMD + KEY_COMMA); + p->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), SETTINGS_PREFERENCES); p->add_shortcut(ED_SHORTCUT("editor/command_palette", TTR("Command Palette..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_P), HELP_COMMAND_PALETTE); p->add_separator(); @@ -6438,17 +6474,17 @@ EditorNode::EditorNode() { editor_layouts->connect("id_pressed", callable_mp(this, &EditorNode::_layout_menu_option)); p->add_submenu_item(TTR("Editor Layout"), "Layouts"); p->add_separator(); -#ifdef OSX_ENABLED - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CMD | KEY_F12), EDITOR_SCREENSHOT); -#else - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CTRL | KEY_F12), EDITOR_SCREENSHOT); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CTRL | KEY_F12); + ED_SHORTCUT_OVERRIDE("editor/take_screenshot", "macos", KEY_MASK_CMD | KEY_F12); + p->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_SCREENSHOT); + p->set_item_tooltip(p->get_item_count() - 1, TTR("Screenshots are stored in the Editor Data/Settings Folder.")); -#ifdef OSX_ENABLED - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F), SETTINGS_TOGGLE_FULLSCREEN); -#else - p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11); + ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F); + p->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), SETTINGS_TOGGLE_FULLSCREEN); + #if defined(WINDOWS_ENABLED) && defined(WINDOWS_SUBSYSTEM_CONSOLE) // The console can only be toggled if the application was built for the console subsystem, // not the GUI subsystem. @@ -6457,7 +6493,7 @@ EditorNode::EditorNode() { p->add_separator(); 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) + // Configuration and data folders are located in the same place (Windows/macos) p->add_item(TTR("Open Editor Data/Settings Folder"), SETTINGS_EDITOR_DATA_FOLDER); } else { // Separate configuration and data folders (Linux) @@ -6479,11 +6515,10 @@ EditorNode::EditorNode() { p = help_menu->get_popup(); p->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option)); -#ifdef OSX_ENABLED - p->add_icon_shortcut(gui_base->get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE), HELP_SEARCH); -#else - p->add_icon_shortcut(gui_base->get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTR("Search Help"), KEY_F1), HELP_SEARCH); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTR("Search Help"), KEY_F1); + ED_SHORTCUT_OVERRIDE("editor/editor_help", "macos", KEY_MASK_ALT | KEY_SPACE); + p->add_icon_shortcut(gui_base->get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH); p->add_separator(); p->add_icon_shortcut(gui_base->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS); p->add_icon_shortcut(gui_base->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA); @@ -6506,11 +6541,10 @@ EditorNode::EditorNode() { play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY)); play_button->set_tooltip(TTR("Play the project.")); -#ifdef OSX_ENABLED - play_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), KEY_MASK_CMD | KEY_B)); -#else - play_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), KEY_F5)); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), KEY_F5); + ED_SHORTCUT_OVERRIDE("editor/play", "macos", KEY_MASK_CMD | KEY_B); + play_button->set_shortcut(ED_GET_SHORTCUT("editor/play")); pause_button = memnew(Button); pause_button->set_flat(true); @@ -6520,11 +6554,10 @@ EditorNode::EditorNode() { pause_button->set_tooltip(TTR("Pause the scene execution for debugging.")); pause_button->set_disabled(true); play_hb->add_child(pause_button); -#ifdef OSX_ENABLED - pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_Y)); -#else - pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_F7)); -#endif + + ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_F7); + ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_Y); + pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_scene")); stop_button = memnew(Button); stop_button->set_flat(true); @@ -6534,11 +6567,10 @@ EditorNode::EditorNode() { stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_STOP)); stop_button->set_tooltip(TTR("Stop the scene.")); stop_button->set_disabled(true); -#ifdef OSX_ENABLED - stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_MASK_CMD | KEY_PERIOD)); -#else - stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_F8)); -#endif + + ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_F8); + ED_SHORTCUT_OVERRIDE("editor/stop", "macos", KEY_MASK_CMD | KEY_PERIOD); + stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop")); run_native = memnew(EditorRunNative); play_hb->add_child(run_native); @@ -6552,11 +6584,10 @@ EditorNode::EditorNode() { play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY_SCENE)); play_scene_button->set_tooltip(TTR("Play the edited scene.")); -#ifdef OSX_ENABLED - play_scene_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), KEY_MASK_CMD | KEY_R)); -#else - play_scene_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), KEY_F6)); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), KEY_F6); + ED_SHORTCUT_OVERRIDE("editor/play_scene", "macos", KEY_MASK_CMD | KEY_R); + play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_scene")); play_custom_scene_button = memnew(Button); play_custom_scene_button->set_flat(true); @@ -6566,11 +6597,10 @@ EditorNode::EditorNode() { play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_PLAY_CUSTOM_SCENE)); play_custom_scene_button->set_tooltip(TTR("Play custom scene")); -#ifdef OSX_ENABLED - play_custom_scene_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R)); -#else - play_custom_scene_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5)); -#endif + + ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5); + ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R); + play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene")); HBoxContainer *right_menu_hb = memnew(HBoxContainer); menu_hb->add_child(right_menu_hb); @@ -7106,20 +7136,19 @@ EditorNode::EditorNode() { ResourceSaver::set_save_callback(_resource_saved); ResourceLoader::set_load_callback(_resource_loaded); -#ifdef OSX_ENABLED - ED_SHORTCUT_AND_COMMAND("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1); - ED_SHORTCUT_AND_COMMAND("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2); - ED_SHORTCUT_AND_COMMAND("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_ALT | KEY_3); - ED_SHORTCUT_AND_COMMAND("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_ALT | KEY_4); -#else // Use the Ctrl modifier so F2 can be used to rename nodes in the scene tree dock. ED_SHORTCUT_AND_COMMAND("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_CTRL | KEY_F1); ED_SHORTCUT_AND_COMMAND("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_CTRL | KEY_F2); ED_SHORTCUT_AND_COMMAND("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_CTRL | KEY_F3); ED_SHORTCUT_AND_COMMAND("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_CTRL | KEY_F4); -#endif - ED_SHORTCUT_AND_COMMAND("editor/editor_next", TTR("Next Editor Tab")); - ED_SHORTCUT_AND_COMMAND("editor/editor_prev", TTR("Previous Editor Tab")); + + ED_SHORTCUT_OVERRIDE("editor/editor_2d", "macos", KEY_MASK_ALT | KEY_1); + ED_SHORTCUT_OVERRIDE("editor/editor_3d", "macos", KEY_MASK_ALT | KEY_2); + ED_SHORTCUT_OVERRIDE("editor/editor_script", "macos", KEY_MASK_ALT | KEY_3); + ED_SHORTCUT_OVERRIDE("editor/editor_assetlib", "macos", KEY_MASK_ALT | KEY_4); + + ED_SHORTCUT_AND_COMMAND("editor/editor_next", TTR("Open the next Editor")); + ED_SHORTCUT_AND_COMMAND("editor/editor_prev", TTR("Open the previous Editor")); screenshot_timer = memnew(Timer); screenshot_timer->set_one_shot(true); |