diff options
Diffstat (limited to 'editor/editor_node.cpp')
-rw-r--r-- | editor/editor_node.cpp | 362 |
1 files changed, 233 insertions, 129 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b59d42a5f7..a1998a1d7c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -60,6 +60,7 @@ #include "editor/import/editor_import_collada.h" #include "editor/import/editor_scene_importer_gltf.h" #include "editor/import/resource_importer_bitmask.h" +#include "editor/import/resource_importer_csv.h" #include "editor/import/resource_importer_csv_translation.h" #include "editor/import/resource_importer_image.h" #include "editor/import/resource_importer_layered_texture.h" @@ -122,6 +123,7 @@ #include "editor/plugins/theme_editor_plugin.h" #include "editor/plugins/tile_map_editor_plugin.h" #include "editor/plugins/tile_set_editor_plugin.h" +#include "editor/plugins/version_control_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/pvrtc_compress.h" #include "editor/register_exporters.h" @@ -135,6 +137,8 @@ void EditorNode::_update_scene_tabs() { bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button"); + OS::get_singleton()->global_menu_clear("_dock"); + scene_tabs->clear_tabs(); Ref<Texture> script_icon = gui_base->get_icon("Script", "EditorIcons"); for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { @@ -149,11 +153,16 @@ void EditorNode::_update_scene_tabs() { bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0; scene_tabs->add_tab(editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), icon); + OS::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), GLOBAL_SCENE, i); + if (show_rb && editor_data.get_scene_root_script(i).is_valid()) { scene_tabs->set_tab_right_button(i, script_icon); } } + OS::get_singleton()->global_menu_add_separator("_dock"); + OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant()); + scene_tabs->set_current_tab(editor_data.get_edited_scene()); if (scene_tabs->get_offset_buttons_visible()) { @@ -177,6 +186,20 @@ void EditorNode::_update_scene_tabs() { } } +void EditorNode::_version_control_menu_option(int p_idx) { + + switch (vcs_actions_menu->get_item_id(p_idx)) { + case RUN_VCS_SETTINGS: { + + VersionControlEditorPlugin::get_singleton()->popup_vcs_set_up_dialog(gui_base); + } break; + case RUN_VCS_SHUT_DOWN: { + + VersionControlEditorPlugin::get_singleton()->shut_down(); + } break; + } +} + void EditorNode::_update_title() { String appname = ProjectSettings::get_singleton()->get("application/config/name"); @@ -290,6 +313,7 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->set_auto_accept_quit(false); get_tree()->connect("files_dropped", this, "_dropped_files"); + get_tree()->connect("global_menu_action", this, "_global_menu_action"); /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -334,6 +358,11 @@ void EditorNode::_notification(int p_what) { OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec"))); } break; + case MainLoop::NOTIFICATION_WM_ABOUT: { + + show_about(); + } break; + case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { _menu_option_confirm(FILE_QUIT, false); @@ -397,6 +426,8 @@ void EditorNode::_notification(int p_what) { distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons")); scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons")); + bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons")); + // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); @@ -1574,6 +1605,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in get_inspector()->edit(NULL); node_dock->set_node(NULL); scene_tree_dock->set_selected(NULL); + inspector_dock->update(NULL); return; } @@ -1662,9 +1694,10 @@ void EditorNode::_edit_current() { Resource *current_res = Object::cast_to<Resource>(current_obj); ERR_FAIL_COND(!current_res); - scene_tree_dock->set_selected(NULL); get_inspector()->edit(current_res); + scene_tree_dock->set_selected(NULL); node_dock->set_node(NULL); + inspector_dock->update(NULL); EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path()); int subr_idx = current_res->get_path().find("::"); @@ -1691,9 +1724,11 @@ void EditorNode::_edit_current() { if (current_node->is_inside_tree()) { node_dock->set_node(current_node); scene_tree_dock->set_selected(current_node); + inspector_dock->update(current_node); } else { node_dock->set_node(NULL); scene_tree_dock->set_selected(NULL); + inspector_dock->update(NULL); } if (get_edited_scene() && get_edited_scene()->get_filename() != String()) { @@ -1713,6 +1748,8 @@ void EditorNode::_edit_current() { get_inspector()->edit(current_obj); node_dock->set_node(NULL); + scene_tree_dock->set_selected(NULL); + inspector_dock->update(NULL); } inspector_dock->set_warning(editable_warning); @@ -1814,6 +1851,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { String main_scene; String run_filename; String args; + bool skip_breakpoints; if (p_current || (editor_data.get_edited_scene_root() && p_custom == editor_data.get_edited_scene_root()->get_filename())) { @@ -1879,8 +1917,9 @@ void EditorNode::_run(bool p_current, const String &p_custom) { editor_data.get_editor_breakpoints(&breakpoints); args = ProjectSettings::get_singleton()->get("editor/main_run_args"); + skip_breakpoints = ScriptEditor::get_singleton()->get_debugger()->is_skip_breakpoints(); - Error error = editor_run.run(run_filename, args, breakpoints); + Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints); if (error != OK) { @@ -1913,10 +1952,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { switch (p_option) { case FILE_NEW_SCENE: { - int idx = editor_data.add_edited_scene(-1); - _scene_tab_changed(idx); - editor_data.clear_editor_states(); - _update_scene_tabs(); + new_scene(); } break; case FILE_NEW_INHERITED_SCENE: @@ -1963,6 +1999,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { break; opening_prev = true; open_request(previous_scenes.back()->get()); + previous_scenes.pop_back(); } break; case FILE_CLOSE_OTHERS: @@ -2488,12 +2525,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { screenshot_timer->start(); } break; - case EDITOR_OPEN_SCREENSHOT: { - - bool is_checked = settings_menu->get_popup()->is_item_checked(settings_menu->get_popup()->get_item_index(EDITOR_OPEN_SCREENSHOT)); - settings_menu->get_popup()->set_item_checked(settings_menu->get_popup()->get_item_index(EDITOR_OPEN_SCREENSHOT), !is_checked); - EditorSettings::get_singleton()->set_project_metadata("screenshot_options", "open_screenshot", !is_checked); - } break; case SETTINGS_PICK_MAIN_SCENE: { file->set_mode(EditorFileDialog::MODE_OPEN_FILE); @@ -2553,7 +2584,7 @@ void EditorNode::_screenshot(bool p_use_utc) { String name = "editor_screenshot_" + OS::get_singleton()->get_iso_date_time(p_use_utc).replace(":", "") + ".png"; NodePath path = String("user://") + name; _save_screenshot(path); - if (EditorSettings::get_singleton()->get_project_metadata("screenshot_options", "open_screenshot", true)) { + if (EditorSettings::get_singleton()->get("interface/editor/automatically_open_screenshots")) { OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->globalize_path(path)); } } @@ -2619,11 +2650,8 @@ void EditorNode::_exit_editor() { resource_preview->stop(); //stop early to avoid crashes _save_docks(); - // Dim the editor window while it's quitting to make it clearer that it's busy. - // No transition is applied, as the effect needs to be visible immediately - float c = 1.0f - float(EDITOR_GET("interface/editor/dim_amount")); - Color dim_color = Color(c, c, c); - gui_base->set_modulate(dim_color); + // Dim the editor window while it's quitting to make it clearer that it's busy + dim_editor(true, true); get_tree()->quit(); } @@ -2640,6 +2668,14 @@ void EditorNode::_discard_changes(const String &p_str) { case FILE_CLOSE_ALL: case SCENE_TAB_CLOSE: { + Node *scene = editor_data.get_edited_scene_root(tab_closing); + if (scene != NULL) { + String scene_filename = scene->get_filename(); + if (scene_filename != "") { + previous_scenes.push_back(scene_filename); + } + } + _remove_scene(tab_closing); _update_scene_tabs(); @@ -2705,6 +2741,21 @@ void EditorNode::_update_debug_options() { if (check_reload_scripts) _menu_option_confirm(RUN_RELOAD_SCRIPTS, true); } +void EditorNode::_update_file_menu_opened() { + + Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene"); + close_scene_sc->set_name(TTR("Close Scene")); + Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); + reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene")); + PopupMenu *pop = file_menu->get_popup(); + pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty()); +} + +void EditorNode::_update_file_menu_closed() { + PopupMenu *pop = file_menu->get_popup(); + pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), false); +} + Control *EditorNode::get_viewport() { return viewport; @@ -2757,6 +2808,19 @@ void EditorNode::_editor_select(int p_which) { } } +void EditorNode::select_editor_by_name(const String &p_name) { + ERR_FAIL_COND(p_name == ""); + + for (int i = 0; i < main_editor_buttons.size(); i++) { + if (main_editor_buttons[i]->get_text() == p_name) { + _editor_select(i); + return; + } + } + + ERR_FAIL_MSG("The editor name '" + p_name + "' was not found."); +} + void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) { if (p_editor->has_main_screen()) { @@ -2880,36 +2944,39 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, return; } - String path = cf->get_value("plugin", "script"); - path = String("res://addons").plus_file(p_addon).plus_file(path); + String script_path = cf->get_value("plugin", "script"); + Ref<Script> script; // We need to save it for creating "ep" below. - Ref<Script> script = ResourceLoader::load(path); + // Only try to load the script if it has a name. Else, the plugin has no init script. + if (script_path.length() > 0) { + script_path = String("res://addons").plus_file(p_addon).plus_file(script_path); + script = ResourceLoader::load(script_path); - if (script.is_null()) { - show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), path)); - return; - } + if (script.is_null()) { + show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), script_path)); + return; + } - //errors in the script cause the base_type to be "" - if (String(script->get_instance_base_type()) == "") { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), path)); - return; - } + // Errors in the script cause the base_type to be an empty string. + if (String(script->get_instance_base_type()) == "") { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), script_path)); + return; + } - //could check inheritance.. - if (String(script->get_instance_base_type()) != "EditorPlugin") { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path)); - return; - } + // Plugin init scripts must inherit from EditorPlugin and be tools. + if (String(script->get_instance_base_type()) != "EditorPlugin") { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path)); + return; + } - if (!script->is_tool()) { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), path)); - return; + if (!script->is_tool()) { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path)); + return; + } } EditorPlugin *ep = memnew(EditorPlugin); ep->set_script(script.get_ref_ptr()); - ep->set_dir_cache(p_addon); plugin_addons[p_addon] = ep; add_editor_plugin(ep, p_config_changed); @@ -3117,6 +3184,14 @@ void EditorNode::fix_dependencies(const String &p_for_file) { dependency_fixer->edit(p_for_file); } +int EditorNode::new_scene() { + int idx = editor_data.add_edited_scene(-1); + _scene_tab_changed(idx); + editor_data.clear_editor_states(); + _update_scene_tabs(); + return idx; +} + Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) { if (!is_inside_tree()) { @@ -3277,6 +3352,13 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b void EditorNode::open_request(const String &p_path) { + if (!opening_prev) { + List<String>::Element *prev_scene = previous_scenes.find(p_path); + if (prev_scene != NULL) { + prev_scene->erase(); + } + } + load_scene(p_path); // as it will be opened in separate tab } @@ -3459,6 +3541,7 @@ void EditorNode::register_editor_types() { ClassDB::register_class<EditorResourcePreviewGenerator>(); ClassDB::register_virtual_class<EditorFileSystem>(); ClassDB::register_class<EditorFileSystemDirectory>(); + ClassDB::register_class<EditorVCSInterface>(); ClassDB::register_virtual_class<ScriptEditor>(); ClassDB::register_virtual_class<EditorInterface>(); ClassDB::register_class<EditorExportPlugin>(); @@ -3768,9 +3851,13 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) { void EditorNode::show_warning(const String &p_text, const String &p_title) { - warning->set_text(p_text); - warning->set_title(p_title); - warning->popup_centered_minsize(); + if (warning->is_inside_tree()) { + warning->set_text(p_text); + warning->set_title(p_title); + warning->popup_centered_minsize(); + } else { + WARN_PRINTS(p_title + " " + p_text); + } } void EditorNode::_copy_warning(const String &p_str) { @@ -4314,6 +4401,15 @@ bool EditorNode::ensure_main_scene(bool p_from_native) { return true; } +void EditorNode::run_play() { + _menu_option_confirm(RUN_STOP, true); + _run(false); +} + +void EditorNode::run_stop() { + _menu_option_confirm(RUN_STOP, false); +} + int EditorNode::get_current_tab() { return scene_tabs->get_current_tab(); } @@ -4477,8 +4573,17 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) { scene_tabs_context_menu->add_separator(); scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), FILE_SHOW_IN_FILESYSTEM); scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE); + scene_tabs_context_menu->add_separator(); - scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE); + Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene"); + close_tab_sc->set_name(TTR("Close Tab")); + scene_tabs_context_menu->add_shortcut(close_tab_sc, FILE_CLOSE); + Ref<ShortCut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); + undo_close_tab_sc->set_name(TTR("Undo Close Tab")); + scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV); + if (previous_scenes.empty()) { + scene_tabs_context_menu->set_item_disabled(scene_tabs_context_menu->get_item_index(FILE_OPEN_PREV), true); + } scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), FILE_CLOSE_OTHERS); scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), FILE_CLOSE_RIGHT); scene_tabs_context_menu->add_item(TTR("Close All Tabs"), FILE_CLOSE_ALL); @@ -4722,8 +4827,7 @@ void EditorNode::remove_control_from_dock(Control *p_control) { } } - ERR_EXPLAIN("Control was not in dock"); - ERR_FAIL_COND(!dock); + ERR_FAIL_COND_MSG(!dock, "Control was not in dock."); dock->remove_child(p_control); _update_dock_slots_visibility(); @@ -4861,6 +4965,23 @@ void EditorNode::remove_tool_menu_item(const String &p_name) { } } +void EditorNode::_global_menu_action(const Variant &p_id, const Variant &p_meta) { + + int id = (int)p_id; + if (id == GLOBAL_NEW_WINDOW) { + if (OS::get_singleton()->get_main_loop()) { + List<String> args; + String exec = OS::get_singleton()->get_executable_path(); + + OS::ProcessID pid = 0; + OS::get_singleton()->execute(exec, args, false, &pid); + } + } else if (id == GLOBAL_SCENE) { + int idx = (int)p_meta; + scene_tabs->set_current_tab(idx); + } +} + void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) { String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_selected_path()); @@ -5028,47 +5149,12 @@ void EditorNode::_open_imported() { load_scene(open_import_request, true, false, true, true); } -void EditorNode::dim_editor(bool p_dimming) { - static int dim_count = 0; - bool dim_ui = EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup"); - if (p_dimming) { - if (dim_ui && dim_count == 0) { - _start_dimming(true); - } - dim_count++; - } else { - if (dim_count == 1) { - _start_dimming(false); - } - if (dim_count > 0) { - dim_count--; - } else { - ERR_PRINT("Undimmed before dimming!"); - } - } -} - -void EditorNode::_start_dimming(bool p_dimming) { - _dimming = p_dimming; - _dim_time = 0.0f; - _dim_timer->start(); -} - -void EditorNode::_dim_timeout() { - - _dim_time += _dim_timer->get_wait_time(); - float wait_time = EditorSettings::get_singleton()->get("interface/editor/dim_transition_time"); - - float c = 1.0f - (float)EditorSettings::get_singleton()->get("interface/editor/dim_amount"); - - Color base = _dimming ? Color(1, 1, 1) : Color(c, c, c); - Color final = _dimming ? Color(c, c, c) : Color(1, 1, 1); - - if (_dim_time + _dim_timer->get_wait_time() >= wait_time) { - gui_base->set_modulate(final); - _dim_timer->stop(); +void EditorNode::dim_editor(bool p_dimming, bool p_force_dim) { + // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor + if ((p_force_dim || EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup")) && p_dimming) { + gui_base->set_modulate(Color(0.5, 0.5, 0.5)); } else { - gui_base->set_modulate(base.linear_interpolate(final, _dim_time / wait_time)); + gui_base->set_modulate(Color(1, 1, 1)); } } @@ -5100,18 +5186,12 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { - if (p_pressed) { - top_split->hide(); - bottom_panel_raise->set_icon(gui_base->get_icon("ShrinkBottomDock", "EditorIcons")); - } else { - top_split->show(); - bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons")); - } + top_split->set_visible(!p_pressed); } void EditorNode::_update_video_driver_color() { - //todo probably should de-harcode this and add to editor settings + // TODO: Probably should de-hardcode this and add to editor settings. if (video_driver->get_text() == "GLES2") { video_driver->add_color_override("font_color", Color::hex(0x5586a4ff)); } else if (video_driver->get_text() == "GLES3") { @@ -5196,6 +5276,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed); ClassDB::bind_method("edit_node", &EditorNode::edit_node); ClassDB::bind_method("_unhandled_input", &EditorNode::_unhandled_input); + ClassDB::bind_method("_update_file_menu_opened", &EditorNode::_update_file_menu_opened); + ClassDB::bind_method("_update_file_menu_closed", &EditorNode::_update_file_menu_closed); ClassDB::bind_method(D_METHOD("push_item", "object", "property", "inspector_only"), &EditorNode::push_item, DEFVAL(""), DEFVAL(false)); @@ -5247,7 +5329,9 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history); ClassDB::bind_method("_dropped_files", &EditorNode::_dropped_files); + ClassDB::bind_method(D_METHOD("_global_menu_action"), &EditorNode::_global_menu_action, DEFVAL(Variant())); ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode); + ClassDB::bind_method("_version_control_menu_option", &EditorNode::_version_control_menu_option); ClassDB::bind_method("edit_item_resource", &EditorNode::edit_item_resource); ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base); @@ -5255,7 +5339,6 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_open_imported"), &EditorNode::_open_imported); ClassDB::bind_method(D_METHOD("_inherit_imported"), &EditorNode::_inherit_imported); - ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout); ClassDB::bind_method("_copy_warning", &EditorNode::_copy_warning); @@ -5440,6 +5523,9 @@ EditorNode::EditorNode() { } } + // Define a minimum window size to prevent UI elements from overlapping or being cut off + OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE); + ResourceLoader::set_abort_on_missing_resources(false); FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); @@ -5474,6 +5560,10 @@ EditorNode::EditorNode() { import_csv_translation.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation); + Ref<ResourceImporterCSV> import_csv; + import_csv.instance(); + ResourceFormatImporter::get_singleton()->add_importer(import_csv); + Ref<ResourceImporterWAV> import_wav; import_wav.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_wav); @@ -5563,12 +5653,16 @@ EditorNode::EditorNode() { EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false); 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); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::REAL, "interface/inspector/default_float_step", PROPERTY_HINT_EXP_RANGE, "0,1,0")); EDITOR_DEF_RST("interface/inspector/disable_folding", false); EDITOR_DEF_RST("interface/inspector/auto_unfold_foreign_scenes", true); EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false); EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true); EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true); EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "SpatialMaterial,Script,MeshLibrary,TileSet"); + EDITOR_DEF("interface/inspector/default_color_picker_mode", 0); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); theme_base = memnew(Control); @@ -5712,6 +5806,7 @@ EditorNode::EditorNode() { dock_slot[i]->set_drag_to_rearrange_enabled(true); dock_slot[i]->set_tabs_rearrange_group(1); dock_slot[i]->connect("tab_changed", this, "_dock_tab_changed"); + dock_slot[i]->set_use_hidden_tabs_for_min_size(true); } dock_drag_timer = memnew(Timer); @@ -5870,23 +5965,25 @@ EditorNode::EditorNode() { PopupMenu *p; file_menu->set_tooltip(TTR("Operations with scene files.")); + p = file_menu->get_popup(); p->set_hide_on_window_lose_focus(true); p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE); p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE); p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE); + p->add_shortcut(ED_SHORTCUT("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_T), FILE_OPEN_PREV); + p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT); + p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE); p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE); p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE); - p->add_separator(); - p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT); + p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/quick_open", TTR("Quick Open..."), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN); p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE); p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT); + p->add_separator(); PopupMenu *pm_export = memnew(PopupMenu); pm_export->set_name("Export"); @@ -5899,8 +5996,10 @@ EditorNode::EditorNode() { p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true); p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true); + p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT); + p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE); recent_scenes = memnew(PopupMenu); recent_scenes->set_name("RecentScenes"); @@ -5908,7 +6007,7 @@ EditorNode::EditorNode() { recent_scenes->connect("id_pressed", this, "_open_recent_scene"); p->add_separator(); - p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q); + p->add_shortcut(ED_SHORTCUT("editor/file_quit", TTR("Quit"), KEY_MASK_CMD + KEY_Q), FILE_QUIT, true); project_menu = memnew(MenuButton); project_menu->set_flat(false); @@ -5920,10 +6019,22 @@ EditorNode::EditorNode() { p = project_menu->get_popup(); p->set_hide_on_window_lose_focus(true); - p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings")), RUN_SETTINGS); - p->add_separator(); + p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings...")), RUN_SETTINGS); p->connect("id_pressed", this, "_menu_option"); - p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export")), FILE_EXPORT_PROJECT); + + vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel(); + vcs_actions_menu->set_name("Version Control"); + vcs_actions_menu->connect("index_pressed", this, "_version_control_menu_option"); + p->add_separator(); + p->add_child(vcs_actions_menu); + p->add_submenu_item(TTR("Version Control"), "Version Control"); + vcs_actions_menu->add_item(TTR("Set Up Version Control"), RUN_VCS_SETTINGS); + vcs_actions_menu->add_item(TTR("Shut Down Version Control"), RUN_VCS_SHUT_DOWN); + + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export...")), FILE_EXPORT_PROJECT); + p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE); + p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER); plugin_config_dialog = memnew(PluginConfigDialog); plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready"); @@ -5932,19 +6043,15 @@ EditorNode::EditorNode() { tool_menu = memnew(PopupMenu); tool_menu->set_name("Tools"); tool_menu->connect("index_pressed", this, "_tool_menu_option"); - p->add_separator(); p->add_child(tool_menu); p->add_submenu_item(TTR("Tools"), "Tools"); - tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES); - tool_menu->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER); - p->add_separator(); - p->add_item(TTR("Install Android Build Template"), FILE_INSTALL_ANDROID_SOURCE); - p->add_separator(); + tool_menu->add_item(TTR("Orphan Resource Explorer..."), TOOLS_ORPHAN_RESOURCES); + p->add_separator(); #ifdef OSX_ENABLED - p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q); + p->add_shortcut(ED_SHORTCUT("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_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q); + p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q), RUN_PROJECT_MANAGER, true); #endif menu_hb->add_spacer(); @@ -5992,7 +6099,7 @@ EditorNode::EditorNode() { p = settings_menu->get_popup(); p->set_hide_on_window_lose_focus(true); - p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings")), SETTINGS_PREFERENCES); + p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES); p->add_separator(); editor_layouts = memnew(PopupMenu); @@ -6000,16 +6107,13 @@ EditorNode::EditorNode() { p->add_child(editor_layouts); editor_layouts->connect("id_pressed", this, "_layout_menu_option"); p->add_submenu_item(TTR("Editor Layout"), "Layouts"); + p->add_separator(); #ifdef OSX_ENABLED p->add_shortcut(ED_SHORTCUT("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CMD | KEY_F12), EDITOR_SCREENSHOT); #else p->add_shortcut(ED_SHORTCUT("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CTRL | KEY_F12), EDITOR_SCREENSHOT); #endif p->set_item_tooltip(p->get_item_count() - 1, TTR("Screenshots are stored in the Editor Data/Settings Folder.")); - p->add_check_shortcut(ED_SHORTCUT("editor/open_screenshot", TTR("Automatically Open Screenshots")), EDITOR_OPEN_SCREENSHOT); - bool is_open_screenshot = EditorSettings::get_singleton()->get_project_metadata("screenshot_options", "open_screenshot", true); - p->set_item_checked(p->get_item_count() - 1, is_open_screenshot); - p->set_item_tooltip(p->get_item_count() - 1, TTR("Open in an external image editor.")); #ifdef OSX_ENABLED p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F), SETTINGS_TOGGLE_FULLSCREEN); #else @@ -6030,11 +6134,8 @@ EditorNode::EditorNode() { } p->add_separator(); - p->add_item(TTR("Manage Editor Features"), SETTINGS_MANAGE_FEATURE_PROFILES); - - p->add_separator(); - - p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES); + p->add_item(TTR("Manage Editor Features..."), SETTINGS_MANAGE_FEATURE_PROFILES); + p->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES); // Help Menu help_menu = memnew(MenuButton); @@ -6262,6 +6363,13 @@ EditorNode::EditorNode() { bottom_panel_hb_editors = memnew(HBoxContainer); bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL); bottom_panel_hb->add_child(bottom_panel_hb_editors); + + version_label = memnew(Label); + version_label->set_text(VERSION_FULL_CONFIG); + // Fade out the version label to be less prominent, but still readable + version_label->set_self_modulate(Color(1, 1, 1, 0.6)); + bottom_panel_hb->add_child(version_label); + bottom_panel_raise = memnew(ToolButton); bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons")); @@ -6300,13 +6408,13 @@ EditorNode::EditorNode() { gui_base->add_child(custom_build_manage_templates); install_android_build_template = memnew(ConfirmationDialog); - install_android_build_template->set_text(TTR("This will install the Android project for custom builds.\nNote that, in order to use it, it needs to be enabled per export preset.")); + install_android_build_template->set_text(TTR("This will set up your project for custom Android builds by installing the source template to \"res://android/build\".\nYou can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.).\nNote that in order to make custom builds instead of using pre-built APKs, the \"Use Custom Build\" option should be enabled in the Android export preset.")); install_android_build_template->get_ok()->set_text(TTR("Install")); install_android_build_template->connect("confirmed", this, "_menu_confirm_current"); gui_base->add_child(install_android_build_template); remove_android_build_template = memnew(ConfirmationDialog); - remove_android_build_template->set_text(TTR("Android build template is already installed and it won't be overwritten.\nRemove the \"build\" directory manually before attempting this operation again.")); + remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again.")); remove_android_build_template->get_ok()->set_text(TTR("Show in File Manager")); remove_android_build_template->connect("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES)); gui_base->add_child(remove_android_build_template); @@ -6358,6 +6466,8 @@ EditorNode::EditorNode() { file_script->connect("file_selected", this, "_dialog_action"); file_menu->get_popup()->connect("id_pressed", this, "_menu_option"); + file_menu->connect("about_to_show", this, "_update_file_menu_opened"); + file_menu->get_popup()->connect("popup_hide", this, "_update_file_menu_closed"); settings_menu->get_popup()->connect("id_pressed", this, "_menu_option"); @@ -6394,6 +6504,7 @@ EditorNode::EditorNode() { //more visually meaningful to have this later raise_bottom_panel_item(AnimationPlayerEditor::singleton); + add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin(this))); add_editor_plugin(memnew(VisualShaderEditorPlugin(this))); @@ -6574,13 +6685,6 @@ EditorNode::EditorNode() { waiting_for_first_scan = true; - _dimming = false; - _dim_time = 0.0f; - _dim_timer = memnew(Timer); - _dim_timer->set_wait_time(0.01666f); - _dim_timer->connect("timeout", this, "_dim_timeout"); - add_child(_dim_timer); - print_handler.printfunc = _print_handler; print_handler.userdata = this; add_print_handler(&print_handler); |