diff options
Diffstat (limited to 'editor/editor_node.cpp')
-rw-r--r-- | editor/editor_node.cpp | 511 |
1 files changed, 191 insertions, 320 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 913f70c442..06e1e8b22e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -37,7 +37,6 @@ #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/io/stream_peer_tls.h" #include "core/object/class_db.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" @@ -47,10 +46,7 @@ #include "core/string/translation.h" #include "core/version.h" #include "main/main.h" -#include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/gui/center_container.h" #include "scene/gui/color_picker.h" -#include "scene/gui/control.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" #include "scene/gui/link_button.h" @@ -61,18 +57,13 @@ #include "scene/gui/split_container.h" #include "scene/gui/tab_bar.h" #include "scene/gui/tab_container.h" -#include "scene/gui/texture_progress_bar.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" -#include "servers/navigation_server_2d.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" -#include "servers/rendering/rendering_device.h" -#include "editor/animation_track_editor.h" #include "editor/audio_stream_preview.h" -#include "editor/debugger/debug_adapter/debug_adapter_server.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/dependency_editor.h" #include "editor/editor_about.h" @@ -82,7 +73,6 @@ #include "editor/editor_data.h" #include "editor/editor_feature_profile.h" #include "editor/editor_file_dialog.h" -#include "editor/editor_file_system.h" #include "editor/editor_folding.h" #include "editor/editor_help.h" #include "editor/editor_inspector.h" @@ -93,15 +83,12 @@ #include "editor/editor_properties.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_quick_open.h" -#include "editor/editor_resource_picker.h" #include "editor/editor_resource_preview.h" #include "editor/editor_run.h" #include "editor/editor_run_native.h" -#include "editor/editor_run_script.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_settings_dialog.h" -#include "editor/editor_spin_slider.h" #include "editor/editor_themes.h" #include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" @@ -110,6 +97,7 @@ #include "editor/export/export_template_manager.h" #include "editor/export/project_export.h" #include "editor/filesystem_dock.h" +#include "editor/history_dock.h" #include "editor/import/audio_stream_import_settings.h" #include "editor/import/dynamic_font_import_settings.h" #include "editor/import/editor_import_collada.h" @@ -121,88 +109,32 @@ #include "editor/import/resource_importer_imagefont.h" #include "editor/import/resource_importer_layered_texture.h" #include "editor/import/resource_importer_obj.h" -#include "editor/import/resource_importer_scene.h" #include "editor/import/resource_importer_shader_file.h" #include "editor/import/resource_importer_texture.h" #include "editor/import/resource_importer_texture_atlas.h" #include "editor/import/resource_importer_wav.h" #include "editor/import/scene_import_settings.h" #include "editor/import_dock.h" +#include "editor/inspector_dock.h" #include "editor/multi_node_edit.h" #include "editor/node_dock.h" #include "editor/plugin_config_dialog.h" -#include "editor/plugins/animation_blend_space_1d_editor.h" -#include "editor/plugins/animation_blend_space_2d_editor.h" -#include "editor/plugins/animation_blend_tree_editor_plugin.h" #include "editor/plugins/animation_player_editor_plugin.h" -#include "editor/plugins/animation_state_machine_editor.h" -#include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" -#include "editor/plugins/audio_stream_randomizer_editor_plugin.h" -#include "editor/plugins/bit_map_editor_plugin.h" -#include "editor/plugins/bone_map_editor_plugin.h" -#include "editor/plugins/camera_3d_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" -#include "editor/plugins/cast_2d_editor_plugin.h" -#include "editor/plugins/collision_polygon_2d_editor_plugin.h" -#include "editor/plugins/collision_shape_2d_editor_plugin.h" -#include "editor/plugins/control_editor_plugin.h" -#include "editor/plugins/cpu_particles_2d_editor_plugin.h" -#include "editor/plugins/cpu_particles_3d_editor_plugin.h" -#include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/debugger_editor_plugin.h" -#include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" #include "editor/plugins/editor_resource_conversion_plugin.h" -#include "editor/plugins/font_config_plugin.h" #include "editor/plugins/gdextension_export_plugin.h" -#include "editor/plugins/gpu_particles_2d_editor_plugin.h" -#include "editor/plugins/gpu_particles_3d_editor_plugin.h" -#include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h" -#include "editor/plugins/gradient_editor_plugin.h" -#include "editor/plugins/gradient_texture_2d_editor_plugin.h" -#include "editor/plugins/input_event_editor_plugin.h" -#include "editor/plugins/light_occluder_2d_editor_plugin.h" -#include "editor/plugins/lightmap_gi_editor_plugin.h" -#include "editor/plugins/line_2d_editor_plugin.h" #include "editor/plugins/material_editor_plugin.h" -#include "editor/plugins/mesh_editor_plugin.h" -#include "editor/plugins/mesh_instance_3d_editor_plugin.h" #include "editor/plugins/mesh_library_editor_plugin.h" -#include "editor/plugins/multimesh_editor_plugin.h" -#include "editor/plugins/navigation_link_2d_editor_plugin.h" -#include "editor/plugins/navigation_polygon_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "editor/plugins/occluder_instance_3d_editor_plugin.h" #include "editor/plugins/packed_scene_translation_parser_plugin.h" -#include "editor/plugins/path_2d_editor_plugin.h" -#include "editor/plugins/path_3d_editor_plugin.h" -#include "editor/plugins/physical_bone_3d_editor_plugin.h" -#include "editor/plugins/polygon_2d_editor_plugin.h" -#include "editor/plugins/polygon_3d_editor_plugin.h" -#include "editor/plugins/resource_preloader_editor_plugin.h" #include "editor/plugins/root_motion_editor_plugin.h" -#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_text_editor.h" -#include "editor/plugins/shader_editor_plugin.h" -#include "editor/plugins/shader_file_editor_plugin.h" -#include "editor/plugins/skeleton_2d_editor_plugin.h" -#include "editor/plugins/skeleton_3d_editor_plugin.h" -#include "editor/plugins/skeleton_ik_3d_editor_plugin.h" -#include "editor/plugins/sprite_2d_editor_plugin.h" -#include "editor/plugins/sprite_frames_editor_plugin.h" -#include "editor/plugins/style_box_editor_plugin.h" -#include "editor/plugins/sub_viewport_preview_editor_plugin.h" #include "editor/plugins/text_editor.h" -#include "editor/plugins/texture_3d_editor_plugin.h" -#include "editor/plugins/texture_editor_plugin.h" -#include "editor/plugins/texture_layered_editor_plugin.h" -#include "editor/plugins/texture_region_editor_plugin.h" -#include "editor/plugins/theme_editor_plugin.h" -#include "editor/plugins/tiles/tiles_editor_plugin.h" #include "editor/plugins/version_control_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" -#include "editor/plugins/voxel_gi_editor_plugin.h" #include "editor/progress_dialog.h" #include "editor/project_settings_editor.h" #include "editor/register_exporters.h" @@ -243,15 +175,11 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String full_path = p_full_paths[set_idx]; // Get rid of file extensions and res:// prefixes. - if (scene_name.rfind(".") >= 0) { - scene_name = scene_name.substr(0, scene_name.rfind(".")); - } + scene_name = scene_name.get_basename(); if (full_path.begins_with("res://")) { full_path = full_path.substr(6); } - if (full_path.rfind(".") >= 0) { - full_path = full_path.substr(0, full_path.rfind(".")); - } + full_path = full_path.get_basename(); // Normalize trailing slashes when normalizing directory names. scene_name = scene_name.trim_suffix("/"); @@ -269,7 +197,7 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String parent = full_path.substr(0, difference); int slash_idx = parent.rfind("/"); slash_idx = parent.rfind("/", slash_idx - 1); - parent = slash_idx >= 0 ? parent.substr(slash_idx + 1) : parent; + parent = (slash_idx >= 0 && parent.length() > 1) ? parent.substr(slash_idx + 1) : parent; r_filenames.write[set_idx] = parent + r_filenames[set_idx]; } } @@ -301,15 +229,11 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String path = p_full_paths[E->get()]; // Get rid of file extensions and res:// prefixes. - if (scene_name.rfind(".") >= 0) { - scene_name = scene_name.substr(0, scene_name.rfind(".")); - } + scene_name = scene_name.get_basename(); if (path.begins_with("res://")) { path = path.substr(6); } - if (path.rfind(".") >= 0) { - path = path.substr(0, path.rfind(".")); - } + path = path.get_basename(); // Normalize trailing slashes when normalizing directory names. scene_name = scene_name.trim_suffix("/"); @@ -335,7 +259,7 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto // TODO: This REALLY should be done in a better way than replacing all tabs after almost EVERY action. void EditorNode::_update_scene_tabs() { - bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button"); + bool show_rb = EDITOR_GET("interface/scene_tabs/show_script_button"); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) { DisplayServer::get_singleton()->global_menu_clear("_dock"); @@ -428,7 +352,7 @@ void EditorNode::_version_control_menu_option(int p_idx) { } void EditorNode::_update_title() { - const String appname = ProjectSettings::get_singleton()->get("application/config/name"); + const String appname = GLOBAL_GET("application/config/name"); String title = (appname.is_empty() ? TTR("Unnamed Project") : appname); const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_scene_file_path() : String(); if (!edited.is_empty()) { @@ -543,7 +467,7 @@ void EditorNode::_update_from_settings() { RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"))); RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size")); - bool use_half_res_gi = GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); + bool use_half_res_gi = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi); bool snap_2d_transforms = GLOBAL_GET("rendering/2d/snap/snap_2d_transforms_to_pixel"); @@ -635,7 +559,7 @@ void EditorNode::_notification(int p_what) { update_spinner_step_frame = frame + 1; // Update the icon itself only when the spinner is visible. - if (EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")) { + if (EDITOR_GET("interface/editor/show_update_spinner")) { update_spinner->set_icon(gui_base->get_theme_icon("Progress" + itos(update_spinner_step + 1), SNAME("EditorIcons"))); } } @@ -700,7 +624,7 @@ void EditorNode::_notification(int p_what) { _initializing_plugins = true; Vector<String> addons; if (ProjectSettings::get_singleton()->has_setting("editor_plugins/enabled")) { - addons = ProjectSettings::get_singleton()->get("editor_plugins/enabled"); + addons = GLOBAL_GET("editor_plugins/enabled"); } for (int i = 0; i < addons.size(); i++) { @@ -847,7 +771,7 @@ void EditorNode::_notification(int p_what) { HashSet<String> updated_textfile_extensions; bool extensions_match = true; - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_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)) { @@ -866,9 +790,9 @@ void EditorNode::_notification(int p_what) { } void EditorNode::_update_update_spinner() { - update_spinner->set_visible(EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")); + update_spinner->set_visible(EDITOR_GET("interface/editor/show_update_spinner")); - const bool update_continuously = EditorSettings::get_singleton()->get("interface/editor/update_continuously"); + 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); @@ -892,8 +816,8 @@ void EditorNode::_update_update_spinner() { } void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) { - Ref<Script> script = Object::cast_to<Script>(p_script); - if (script.is_null()) { + Ref<Script> scr = Object::cast_to<Script>(p_script); + if (scr.is_null()) { return; } if (p_activate_name.length()) { @@ -901,7 +825,7 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam } project_settings_editor->update_plugins(); project_settings_editor->hide(); - push_item(script.operator->()); + push_item(scr.operator->()); } void EditorNode::_remove_plugin_from_enabled(const String &p_name) { @@ -1181,7 +1105,8 @@ void EditorNode::_vp_resized() { } void EditorNode::_titlebar_resized() { - const Size2 &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID); + DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_global_position().y + menu_hb->get_size().y / 2, menu_hb->get_global_position().y + menu_hb->get_size().y / 2), DisplayServer::MAIN_WINDOW_ID); + const Vector3i &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID); if (left_menu_spacer) { int w = (gui_base->is_layout_rtl()) ? margin.y : margin.x; left_menu_spacer->set_custom_minimum_size(Size2(w, 0)); @@ -1190,6 +1115,9 @@ void EditorNode::_titlebar_resized() { int w = (gui_base->is_layout_rtl()) ? margin.x : margin.y; right_menu_spacer->set_custom_minimum_size(Size2(w, 0)); } + if (menu_hb) { + menu_hb->set_custom_minimum_size(Size2(0, margin.z - menu_hb->get_global_position().y)); + } } void EditorNode::_version_button_pressed() { @@ -1266,10 +1194,14 @@ void EditorNode::edit_node(Node *p_node) { push_item(p_node); } +void EditorNode::edit_resource(const Ref<Resource> &p_resource) { + InspectorDock::get_singleton()->edit_resource(p_resource); +} + void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } @@ -1614,7 +1546,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { // which would result in an invalid texture. if (c3d == 0 && c2d == 0) { img.instantiate(); - img->create(1, 1, false, Image::FORMAT_RGB8); + img->initialize_data(1, 1, false, Image::FORMAT_RGB8); } else if (c3d < c2d) { Ref<ViewportTexture> viewport_texture = scene_root->get_texture(); if (viewport_texture->get_width() > 0 && viewport_texture->get_height() > 0) { @@ -1636,7 +1568,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { save.step(TTR("Creating Thumbnail"), 2); save.step(TTR("Creating Thumbnail"), 3); - int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int preview_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); preview_size *= EDSCALE; // Consider a square region. @@ -1665,10 +1597,8 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { cache_base = temp_path.path_join("resthumb-" + cache_base); // Does not have it, try to load a cached thumbnail. - String file = cache_base + ".png"; - post_process_preview(img); - img->save_png(file); + img->save_png(cache_base + ".png"); } } @@ -1699,7 +1629,7 @@ int EditorNode::_save_external_resources() { // Save external resources and its subresources if any was modified. int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; @@ -1768,7 +1698,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } if (!scene->get_scene_file_path().is_empty() && _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")); + show_accept(TTR("This scene can't be saved because there is a cyclic instance inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK")); return; } @@ -1805,7 +1735,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; @@ -2038,8 +1968,8 @@ void EditorNode::_dialog_action(String p_file) { ERR_FAIL_COND(saving_resource.is_null()); save_resource_in_path(saving_resource, p_file); saving_resource = Ref<Resource>(); - ObjectID current = editor_history.get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = editor_history.get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; ERR_FAIL_COND(!current_obj); current_obj->notify_property_list_changed(); } break; @@ -2240,8 +2170,8 @@ static bool overrides_external_editor(Object *p_object) { } void EditorNode::_edit_current(bool p_skip_foreign) { - ObjectID current = editor_history.get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = editor_history.get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; Ref<Resource> res = Object::cast_to<Resource>(current_obj); if (p_skip_foreign && res.is_valid()) { @@ -2336,7 +2266,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (get_edited_scene() && !get_edited_scene()->get_scene_file_path().is_empty()) { String source_scene = get_edited_scene()->get_scene_file_path(); if (FileAccess::exists(source_scene + ".import")) { - editable_info = 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."); + editable_info = TTR("This scene was imported, so changes to it won't be kept.\nInstantiating or inheriting it will allow you to make changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); info_is_warning = true; } } @@ -2344,7 +2274,9 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } else { Node *selected_node = nullptr; - if (current_obj->is_class("MultiNodeEdit")) { + if (current_obj->is_class("EditorDebuggerRemoteObject")) { + disable_folding = true; + } else if (current_obj->is_class("MultiNodeEdit")) { Node *scene = get_edited_scene(); if (scene) { MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(current_obj); @@ -2405,7 +2337,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (main_plugin && !skip_main_plugin) { // Special case if use of external editor is true. Resource *current_res = Object::cast_to<Resource>(current_obj); - if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { + if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EDITOR_GET("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { if (!changing_scene) { main_plugin->edit(current_obj); } @@ -2691,9 +2623,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { save_confirmation->set_text(TTR("Save modified resources before closing?")); } } else { - Node *scene_root = editor_data.get_edited_scene_root(tab_closing_idx); - if (scene_root) { - String scene_filename = scene_root->get_scene_file_path(); + Node *ed_scene_root = editor_data.get_edited_scene_root(tab_closing_idx); + if (ed_scene_root) { + String scene_filename = ed_scene_root->get_scene_file_path(); if (p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) { save_confirmation->set_ok_button_text(TTR("Save & Reload")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before reloading?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene")); @@ -3103,7 +3035,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } String EditorNode::adjust_scene_name_casing(const String &root_name) { - switch (ProjectSettings::get_singleton()->get("editor/scene/scene_naming").operator int()) { + switch (GLOBAL_GET("editor/scene/scene_naming").operator int()) { case SCENE_NAME_CASING_AUTO: // Use casing of the root node. break; @@ -3123,7 +3055,7 @@ void EditorNode::_screenshot(bool p_use_utc) { String name = "editor_screenshot_" + Time::get_singleton()->get_datetime_string_from_system(p_use_utc).replace(":", "") + ".png"; NodePath path = String("user://") + name; _save_screenshot(path); - if (EditorSettings::get_singleton()->get("interface/editor/automatically_open_screenshots")) { + if (EDITOR_GET("interface/editor/automatically_open_screenshots")) { OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->globalize_path(path)); } } @@ -3368,7 +3300,7 @@ void EditorNode::editor_select(int p_which) { editor_data.get_editor_plugin(i)->notify_main_screen_changed(editor_plugin_screen->get_name()); } - if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) { + if (EDITOR_GET("interface/editor/separate_distraction_mode")) { if (p_which == EDITOR_SCRIPT) { set_distraction_free_mode(script_distraction_free); } else { @@ -3426,7 +3358,9 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) { if (p_editor->has_main_screen()) { - for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { + // Remove the main editor button and update the bindings of + // all buttons behind it to point to the correct main window. + for (int i = singleton->main_editor_buttons.size() - 1; i >= 0; i--) { if (p_editor->get_name() == singleton->main_editor_buttons[i]->get_text()) { if (singleton->main_editor_buttons[i]->is_pressed()) { singleton->editor_select(EDITOR_SCRIPT); @@ -3436,6 +3370,9 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan singleton->main_editor_buttons.remove_at(i); break; + } else { + singleton->main_editor_buttons[i]->disconnect("pressed", callable_mp(singleton, &EditorNode::editor_select)); + singleton->main_editor_buttons[i]->connect("pressed", callable_mp(singleton, &EditorNode::editor_select).bind(i - 1)); } } @@ -3511,39 +3448,39 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, } String script_path = cf->get_value("plugin", "script"); - Ref<Script> script; // We need to save it for creating "ep" below. + Ref<Script> scr; // We need to save it for creating "ep" below. // 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 = addon_path.get_base_dir().path_join(script_path); - script = ResourceLoader::load(script_path); + scr = ResourceLoader::load(script_path); - if (script.is_null()) { + if (scr.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 an empty StringName. - if (script->get_instance_base_type() == StringName()) { + if (scr->get_instance_base_type() == StringName()) { show_warning(vformat(TTR("Unable to load addon script from path: '%s'. This might be due to a code error in that script.\nDisabling the addon at '%s' to prevent further errors."), script_path, addon_path)); _remove_plugin_from_enabled(addon_path); return; } // Plugin init scripts must inherit from EditorPlugin and be tools. - if (String(script->get_instance_base_type()) != "EditorPlugin") { + if (String(scr->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()) { + if (!scr->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); + ep->set_script(scr); addon_name_to_plugin[addon_path] = ep; add_editor_plugin(ep, p_config_changed); @@ -3558,6 +3495,14 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const { return addon_name_to_plugin.has("res://addons/" + p_addon + "/plugin.cfg"); } +void EditorNode::set_movie_maker_enabled(bool p_enabled) { + write_movie_button->set_pressed(p_enabled); +} + +bool EditorNode::is_movie_maker_enabled() const { + return write_movie_button->is_pressed(); +} + void EditorNode::_remove_edited_scene(bool p_change_tab) { int new_index = editor_data.get_edited_scene(); int old_index = new_index; @@ -3641,17 +3586,17 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - int current = -1; + int current_tab = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { - current = i; + current_tab = i; break; } } if (p_state.has("editor_index")) { int index = p_state["editor_index"]; - if (current < 2) { // If currently in spatial/2d, only switch to spatial/2d. If currently in script, stay there. + if (current_tab < 2) { // If currently in spatial/2d, only switch to spatial/2d. If currently in script, stay there. if (index < 2 || !get_edited_scene()) { editor_select(index); } @@ -3659,7 +3604,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { } if (get_edited_scene()) { - if (current < 2) { + if (current_tab < 2) { // Use heuristic instead. int n2d = 0, n3d = 0; _find_node_types(get_edited_scene(), n2d, n3d); @@ -3687,6 +3632,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { EditorDebuggerNode::get_singleton()->update_live_edit_root(); ScriptEditor::get_singleton()->set_scene_root_script(editor_data.get_scene_root_script(editor_data.get_edited_scene())); editor_data.notify_edited_scene_changed(); + emit_signal(SNAME("scene_changed")); } bool EditorNode::is_changing_scene() const { @@ -3772,7 +3718,7 @@ int EditorNode::new_scene() { if (editor_data.get_edited_scene_count() > 1) { for (int i = 0; i < editor_data.get_edited_scene_count() - 1; i++) { bool unsaved = get_undo_redo()->is_history_unsaved(editor_data.get_scene_history_id(i)); - if (!unsaved && editor_data.get_scene_path(i).is_empty()) { + if (!unsaved && editor_data.get_scene_path(i).is_empty() && editor_data.get_edited_scene_root(i) == nullptr) { editor_data.remove_scene(i); idx--; } @@ -3939,9 +3885,9 @@ 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 != nullptr) { - prev_scene->erase(); + List<String>::Element *prev_scene_item = previous_scenes.find(p_path); + if (prev_scene_item != nullptr) { + prev_scene_item->erase(); } } @@ -3988,7 +3934,7 @@ bool EditorNode::is_resource_read_only(Ref<Resource> p_resource, bool p_foreign_ return false; } -void EditorNode::request_instance_scene(const String &p_path) { +void EditorNode::request_instantiate_scene(const String &p_path) { SceneTreeDock::get_singleton()->instantiate(p_path); } @@ -4073,7 +4019,7 @@ void EditorNode::_quick_opened() { List<String> scene_extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); - if (open_scene_dialog || scene_extensions.find(files[i].get_extension())) { + if (open_scene_dialog || scene_extensions.find(files[i].get_extension().to_lower())) { open_request(res_path); } else { load_resource(res_path); @@ -4124,62 +4070,6 @@ bool EditorNode::is_scene_in_use(const String &p_path) { return false; } -void EditorNode::register_editor_types() { - ResourceLoader::set_timestamp_on_load(true); - ResourceSaver::set_timestamp_on_save(true); - - GDREGISTER_CLASS(EditorPaths); - GDREGISTER_CLASS(EditorPlugin); - GDREGISTER_CLASS(EditorTranslationParserPlugin); - GDREGISTER_CLASS(EditorImportPlugin); - GDREGISTER_CLASS(EditorScript); - GDREGISTER_CLASS(EditorSelection); - GDREGISTER_CLASS(EditorFileDialog); - GDREGISTER_ABSTRACT_CLASS(EditorSettings); - GDREGISTER_CLASS(EditorNode3DGizmo); - GDREGISTER_CLASS(EditorNode3DGizmoPlugin); - GDREGISTER_ABSTRACT_CLASS(EditorResourcePreview); - GDREGISTER_CLASS(EditorResourcePreviewGenerator); - GDREGISTER_ABSTRACT_CLASS(EditorFileSystem); - GDREGISTER_CLASS(EditorFileSystemDirectory); - GDREGISTER_CLASS(EditorVCSInterface); - GDREGISTER_ABSTRACT_CLASS(ScriptEditor); - GDREGISTER_ABSTRACT_CLASS(ScriptEditorBase); - GDREGISTER_CLASS(EditorSyntaxHighlighter); - GDREGISTER_ABSTRACT_CLASS(EditorInterface); - GDREGISTER_CLASS(EditorExportPlugin); - GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform); - GDREGISTER_CLASS(EditorResourceConversionPlugin); - GDREGISTER_CLASS(EditorSceneFormatImporter); - GDREGISTER_CLASS(EditorScenePostImportPlugin); - GDREGISTER_CLASS(EditorInspector); - GDREGISTER_CLASS(EditorInspectorPlugin); - GDREGISTER_CLASS(EditorProperty); - GDREGISTER_CLASS(AnimationTrackEditPlugin); - GDREGISTER_CLASS(ScriptCreateDialog); - GDREGISTER_CLASS(EditorFeatureProfile); - GDREGISTER_CLASS(EditorSpinSlider); - GDREGISTER_CLASS(EditorResourcePicker); - GDREGISTER_CLASS(EditorScriptPicker); - GDREGISTER_ABSTRACT_CLASS(EditorUndoRedoManager); - - GDREGISTER_ABSTRACT_CLASS(FileSystemDock); - GDREGISTER_VIRTUAL_CLASS(EditorFileSystemImportFormatSupportQuery); - - GDREGISTER_CLASS(EditorScenePostImport); - GDREGISTER_CLASS(EditorCommandPalette); - GDREGISTER_CLASS(EditorDebuggerPlugin); -} - -void EditorNode::unregister_editor_types() { - _init_callbacks.clear(); - if (EditorPaths::get_singleton()) { - EditorPaths::free(); - } - - EditorResourcePicker::clear_caches(); -} - void EditorNode::stop_child_process(OS::ProcessID p_pid) { if (has_child_process(p_pid)) { editor_run.stop_child_process(p_pid); @@ -4192,9 +4082,9 @@ void EditorNode::stop_child_process(OS::ProcessID p_pid) { Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) const { ERR_FAIL_COND_V(!p_object, nullptr); - Ref<Script> script = p_object->get_script(); + Ref<Script> scr = p_object->get_script(); - if (script.is_valid()) { + if (scr.is_valid()) { // Uncommenting would break things! Consider adding a parameter if you need it. // StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); // if (name != StringName()) { @@ -4202,18 +4092,18 @@ Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) cons // } // TODO: Should probably be deprecated in 4.x - StringName base = script->get_instance_base_type(); + StringName base = scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; - Ref<Script> base_script = script; - while (base_script.is_valid()) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script) { + if (types[i].script == base_scr) { return types[i].script; } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } } } @@ -4224,30 +4114,30 @@ Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) cons StringName EditorNode::get_object_custom_type_name(const Object *p_object) const { ERR_FAIL_COND_V(!p_object, StringName()); - Ref<Script> script = p_object->get_script(); - if (script.is_null() && Object::cast_to<Script>(p_object)) { - script = p_object; + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && Object::cast_to<Script>(p_object)) { + scr = p_object; } - if (script.is_valid()) { - Ref<Script> base_script = script; - while (base_script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (scr.is_valid()) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_scr->get_path()); if (name != StringName()) { return name; } // TODO: Should probably be deprecated in 4.x. - StringName base = base_script->get_instance_base_type(); + StringName base = base_scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script) { + if (types[i].script == base_scr) { return types[i].name; } } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } } @@ -4291,40 +4181,40 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) { ERR_FAIL_COND_V(!p_object || !gui_base, nullptr); - Ref<Script> script = p_object->get_script(); - if (script.is_null() && p_object->is_class("Script")) { - script = p_object; + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && p_object->is_class("Script")) { + scr = p_object; } - if (script.is_valid() && !script_icon_cache.has(script)) { - Ref<Script> base_script = script; - while (base_script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (scr.is_valid() && !script_icon_cache.has(scr)) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_scr->get_path()); String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); Ref<ImageTexture> icon = _load_custom_class_icon(icon_path); if (icon.is_valid()) { - script_icon_cache[script] = icon; + script_icon_cache[scr] = icon; return icon; } // TODO: should probably be deprecated in 4.x - StringName base = base_script->get_instance_base_type(); + StringName base = base_scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script && types[i].icon.is_valid()) { - script_icon_cache[script] = types[i].icon; + if (types[i].script == base_scr && types[i].icon.is_valid()) { + script_icon_cache[scr] = types[i].icon; return types[i].icon; } } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } // If no icon found, cache it as null. - script_icon_cache[script] = Ref<Texture>(); - } else if (script.is_valid() && script_icon_cache.has(script) && script_icon_cache[script].is_valid()) { - return script_icon_cache[script]; + script_icon_cache[scr] = Ref<Texture>(); + } else if (scr.is_valid() && script_icon_cache.has(scr) && script_icon_cache[scr].is_valid()) { + return script_icon_cache[scr]; } // TODO: Should probably be deprecated in 4.x. @@ -4348,7 +4238,7 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p if (ScriptServer::is_global_class(p_class)) { String class_name = p_class; - Ref<Script> script = EditorNode::get_editor_data().script_class_load_script(class_name); + Ref<Script> scr = EditorNode::get_editor_data().script_class_load_script(class_name); while (true) { String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(class_name); @@ -4359,18 +4249,18 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p // Find next global class along the inheritance chain. do { - Ref<Script> base_script = script->get_base_script(); - if (base_script.is_null()) { + Ref<Script> base_scr = scr->get_base_script(); + if (base_scr.is_null()) { // We've reached a native class, use its icon. String base_type; - script->get_language()->get_global_class_name(script->get_path(), &base_type); + scr->get_language()->get_global_class_name(scr->get_path(), &base_type); if (gui_base->has_theme_icon(base_type, "EditorIcons")) { return gui_base->get_theme_icon(base_type, "EditorIcons"); } return gui_base->get_theme_icon(p_fallback, "EditorIcons"); } - script = base_script; - class_name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + scr = base_scr; + class_name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); } while (class_name.is_empty()); } } @@ -4390,6 +4280,27 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p return nullptr; } +bool EditorNode::is_object_of_custom_type(const Object *p_object, const StringName &p_class) { + ERR_FAIL_COND_V(!p_object, false); + + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && Object::cast_to<Script>(p_object)) { + scr = p_object; + } + + if (scr.is_valid()) { + Ref<Script> base_script = scr; + while (base_script.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (name == p_class) { + return true; + } + base_script = base_script->get_base_script(); + } + } + return false; +} + void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) { if (singleton->cmdline_export_mode) { print_line(p_task + ": begin: " + p_label + " steps: " + itos(p_steps)); @@ -4531,8 +4442,9 @@ void EditorNode::_dock_floating_close_request(Control *p_control) { dock_slot[window_slot]->add_child(p_control); dock_slot[window_slot]->move_child(p_control, MIN((int)window->get_meta("dock_index"), dock_slot[window_slot]->get_tab_count())); dock_slot[window_slot]->set_current_tab(window->get_meta("dock_index")); + dock_slot[window_slot]->set_tab_title(dock_slot[window_slot]->get_tab_idx_from_control(p_control), TTRGET(p_control->get_name())); - window->queue_delete(); + window->queue_free(); _update_dock_containers(); @@ -4554,7 +4466,7 @@ void EditorNode::_dock_make_float() { dock_slot[dock_popup_selected_idx]->remove_child(dock); Window *window = memnew(Window); - window->set_title(dock->get_name()); + window->set_title(TTRGET(dock->get_name())); Panel *p = memnew(Panel); p->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("PanelForeground"), SNAME("EditorStyles"))); p->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); @@ -4675,26 +4587,24 @@ void EditorNode::_dock_move_left() { if (dock_popup_selected_idx < 0 || dock_popup_selected_idx >= DOCK_SLOT_MAX) { return; } - Control *current = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); - Control *prev = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); - if (!current || !prev) { + Control *current_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); + Control *prev_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); + if (!current_ctl || !prev_ctl) { return; } - dock_slot[dock_popup_selected_idx]->move_child(current, prev->get_index()); - dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); + dock_slot[dock_popup_selected_idx]->move_child(current_ctl, prev_ctl->get_index(false)); dock_select->queue_redraw(); _edit_current(); _save_docks(); } void EditorNode::_dock_move_right() { - Control *current = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); - Control *next = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); - if (!current || !next) { + Control *current_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); + Control *next_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); + if (!current_ctl || !next_ctl) { return; } - dock_slot[dock_popup_selected_idx]->move_child(next, current->get_index()); - dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); + dock_slot[dock_popup_selected_idx]->move_child(next_ctl, current_ctl->get_index(false)); dock_select->queue_redraw(); _edit_current(); _save_docks(); @@ -4978,7 +4888,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String Vector<String> names = String(p_layout->get_value(p_section, "dock_" + itos(i + 1))).split(","); - for (int j = 0; j < names.size(); j++) { + for (int j = names.size() - 1; j >= 0; j--) { String name = names[j]; // FIXME: Find it, in a horribly inefficient way. int atidx = -1; @@ -4999,7 +4909,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String } if (atidx == i) { - node->move_to_front(); + dock_slot[i]->move_child(node, 0); continue; } @@ -5009,6 +4919,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String dock_slot[atidx]->hide(); } dock_slot[i]->add_child(node); + dock_slot[i]->move_child(node, 0); dock_slot[i]->show(); } } @@ -5111,7 +5022,7 @@ bool EditorNode::has_scenes_in_session() { bool EditorNode::ensure_main_scene(bool p_from_native) { pick_main_scene->set_meta("from_native", p_from_native); // Whether from play button or native run. - String main_scene = GLOBAL_DEF_BASIC("application/run/main_scene", ""); + String main_scene = GLOBAL_GET("application/run/main_scene"); if (main_scene.is_empty()) { current_menu_option = -1; @@ -5178,7 +5089,7 @@ bool EditorNode::is_run_playing() const { String EditorNode::get_run_playing_scene() const { String run_filename = editor_run.get_running_scene(); if (run_filename.is_empty() && is_run_playing()) { - run_filename = GLOBAL_DEF_BASIC("application/run/main_scene", ""); // Must be the main scene then. + run_filename = GLOBAL_GET("application/run/main_scene"); // Must be the main scene then. } return run_filename; @@ -5210,6 +5121,10 @@ bool EditorNode::immediate_confirmation_dialog(const String &p_text, const Strin return singleton->immediate_dialog_confirmed; } +void EditorNode::cleanup() { + _init_callbacks.clear(); +} + int EditorNode::get_current_tab() { return scene_tabs->get_current_tab(); } @@ -5283,9 +5198,9 @@ void EditorNode::_layout_menu_option(int p_id) { } void EditorNode::_scene_tab_script_edited(int p_tab) { - Ref<Script> script = editor_data.get_scene_root_script(p_tab); - if (script.is_valid()) { - InspectorDock::get_singleton()->edit_resource(script); + Ref<Script> scr = editor_data.get_scene_root_script(p_tab); + if (scr.is_valid()) { + InspectorDock::get_singleton()->edit_resource(scr); } } @@ -5538,7 +5453,7 @@ bool EditorNode::get_docks_visible() const { } void EditorNode::_toggle_distraction_free_mode() { - if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) { + if (EDITOR_GET("interface/editor/separate_distraction_mode")) { int screen = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { @@ -5738,7 +5653,7 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) { } void EditorNode::_dropped_files(const Vector<String> &p_files) { - String to_path = ProjectSettings::get_singleton()->globalize_path(FileSystemDock::get_singleton()->get_selected_path()); + String to_path = ProjectSettings::get_singleton()->globalize_path(FileSystemDock::get_singleton()->get_current_directory()); _add_dropped_files_recursive(p_files, to_path); @@ -5909,7 +5824,7 @@ void EditorNode::_update_renderer_color() { if (renderer->get_text() == "gl_compatibility") { renderer->add_theme_color_override("font_color", Color::hex(0x5586a4ff)); } else if (renderer->get_text() == "forward_plus" || renderer->get_text() == "mobile") { - renderer->add_theme_color_override("font_color", theme_base->get_theme_color(SNAME("vulkan_color"), SNAME("Editor"))); + renderer->add_theme_color_override("font_color", theme_base->get_theme_color(SNAME("highend_color"), SNAME("Editor"))); } } @@ -5945,12 +5860,14 @@ void EditorNode::_feature_profile_changed() { TabContainer *import_tabs = cast_to<TabContainer>(ImportDock::get_singleton()->get_parent()); TabContainer *node_tabs = cast_to<TabContainer>(NodeDock::get_singleton()->get_parent()); TabContainer *fs_tabs = cast_to<TabContainer>(FileSystemDock::get_singleton()->get_parent()); + TabContainer *history_tabs = cast_to<TabContainer>(history_dock->get_parent()); if (profile.is_valid()) { node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK)); // The Import dock is useless without the FileSystem dock. Ensure the configuration is valid. bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK); fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), fs_dock_disabled); import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); + history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_HISTORY_DOCK)); main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); @@ -5966,9 +5883,7 @@ void EditorNode::_feature_profile_changed() { import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), false); node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), false); fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), false); - ImportDock::get_singleton()->set_visible(true); - NodeDock::get_singleton()->set_visible(true); - FileSystemDock::get_singleton()->set_visible(true); + history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), false); main_editor_buttons[EDITOR_3D]->set_visible(true); main_editor_buttons[EDITOR_SCRIPT]->set_visible(true); if (AssetLibraryEditorPlugin::is_available()) { @@ -6011,6 +5926,7 @@ void EditorNode::_bind_methods() { ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj"))); ADD_SIGNAL(MethodInfo("scene_saved", PropertyInfo(Variant::STRING, "path"))); ADD_SIGNAL(MethodInfo("project_settings_changed")); + ADD_SIGNAL(MethodInfo("scene_changed")); } static Node *_resource_get_edited_scene() { @@ -6147,7 +6063,7 @@ EditorNode::EditorNode() { FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); { - int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); + int display_scale = EDITOR_GET("interface/editor/display_scale"); switch (display_scale) { case 0: @@ -6173,7 +6089,7 @@ EditorNode::EditorNode() { editor_set_scale(2.0); break; default: - editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); + editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale")); break; } } @@ -6181,10 +6097,17 @@ EditorNode::EditorNode() { // Define a minimum window size to prevent UI elements from overlapping or being cut off. DisplayServer::get_singleton()->window_set_min_size(Size2(1024, 600) * EDSCALE); + FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int()); + + int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); + if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer. + // Swap on means OK first. + AcceptDialog::set_swap_cancel_ok(swap_cancel_ok == 2); + } + 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")); - EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); ResourceLoader::set_error_notify_func(this, _load_error_notify); ResourceLoader::set_dependency_error_notify_func(this, _dependency_error_report); @@ -6345,7 +6268,7 @@ EditorNode::EditorNode() { ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), Key::SPACE); - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { textfile_extensions.insert(E); } @@ -7065,10 +6988,12 @@ EditorNode::EditorNode() { FileSystemDock *filesystem_dock = memnew(FileSystemDock); filesystem_dock->connect("inherit", callable_mp(this, &EditorNode::_inherit_request)); - filesystem_dock->connect("instance", callable_mp(this, &EditorNode::_instantiate_request)); + filesystem_dock->connect("instantiate", callable_mp(this, &EditorNode::_instantiate_request)); filesystem_dock->connect("display_mode_changed", callable_mp(this, &EditorNode::_save_docks)); get_project_settings()->connect_filesystem_dock_signals(filesystem_dock); + history_dock = memnew(HistoryDock); + // Scene: Top left. dock_slot[DOCK_SLOT_LEFT_UR]->add_child(SceneTreeDock::get_singleton()); dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(dock_slot[DOCK_SLOT_LEFT_UR]->get_tab_idx_from_control(SceneTreeDock::get_singleton()), TTR("Scene")); @@ -7089,6 +7014,10 @@ EditorNode::EditorNode() { dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(NodeDock::get_singleton()); dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(NodeDock::get_singleton()), TTR("Node")); + // History: Full height right, behind Node. + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(history_dock); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(history_dock), TTR("History")); + // Hide unused dock slots and vsplits. dock_slot[DOCK_SLOT_LEFT_UL]->hide(); dock_slot[DOCK_SLOT_LEFT_BL]->hide(); @@ -7109,7 +7038,7 @@ EditorNode::EditorNode() { // Dock numbers are based on DockSlot enum value + 1. default_layout->set_value(docks_section, "dock_3", "Scene,Import"); default_layout->set_value(docks_section, "dock_4", "FileSystem"); - default_layout->set_value(docks_section, "dock_5", "Inspector,Node"); + default_layout->set_value(docks_section, "dock_5", "Inspector,Node,History"); for (int i = 0; i < vsplits.size(); i++) { default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0); @@ -7282,7 +7211,6 @@ EditorNode::EditorNode() { add_child(audio_preview_gen); add_editor_plugin(memnew(DebuggerEditorPlugin(debug_menu))); - add_editor_plugin(memnew(DebugAdapterServer())); disk_changed = memnew(ConfirmationDialog); { @@ -7332,63 +7260,7 @@ EditorNode::EditorNode() { raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); - - // This list is alphabetized, and plugins that depend on Node2D are in their own section below. - add_editor_plugin(memnew(AnimationTreeEditorPlugin)); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); - add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin)); - add_editor_plugin(memnew(BitMapEditorPlugin)); - add_editor_plugin(memnew(BoneMapEditorPlugin)); - add_editor_plugin(memnew(Camera3DEditorPlugin)); - add_editor_plugin(memnew(ControlEditorPlugin)); - add_editor_plugin(memnew(CPUParticles3DEditorPlugin)); - add_editor_plugin(memnew(CurveEditorPlugin)); - add_editor_plugin(memnew(FontEditorPlugin)); - add_editor_plugin(memnew(GPUParticles3DEditorPlugin)); - add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin)); - add_editor_plugin(memnew(GradientEditorPlugin)); - add_editor_plugin(memnew(GradientTexture2DEditorPlugin)); - add_editor_plugin(memnew(InputEventEditorPlugin)); - add_editor_plugin(memnew(LightmapGIEditorPlugin)); - add_editor_plugin(memnew(MaterialEditorPlugin)); - add_editor_plugin(memnew(MeshEditorPlugin)); - add_editor_plugin(memnew(MeshInstance3DEditorPlugin)); - add_editor_plugin(memnew(MeshLibraryEditorPlugin)); - add_editor_plugin(memnew(MultiMeshEditorPlugin)); - add_editor_plugin(memnew(OccluderInstance3DEditorPlugin)); - add_editor_plugin(memnew(Path3DEditorPlugin)); - add_editor_plugin(memnew(PhysicalBone3DEditorPlugin)); - add_editor_plugin(memnew(Polygon3DEditorPlugin)); - add_editor_plugin(memnew(ResourcePreloaderEditorPlugin)); - add_editor_plugin(memnew(ShaderEditorPlugin)); - add_editor_plugin(memnew(ShaderFileEditorPlugin)); - add_editor_plugin(memnew(Skeleton3DEditorPlugin)); - add_editor_plugin(memnew(SkeletonIK3DEditorPlugin)); - add_editor_plugin(memnew(SpriteFramesEditorPlugin)); - add_editor_plugin(memnew(StyleBoxEditorPlugin)); - add_editor_plugin(memnew(SubViewportPreviewEditorPlugin)); - add_editor_plugin(memnew(Texture3DEditorPlugin)); - add_editor_plugin(memnew(TextureEditorPlugin)); - add_editor_plugin(memnew(TextureLayeredEditorPlugin)); - add_editor_plugin(memnew(TextureRegionEditorPlugin)); - add_editor_plugin(memnew(ThemeEditorPlugin)); - add_editor_plugin(memnew(VoxelGIEditorPlugin)); - - // 2D - add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin)); - add_editor_plugin(memnew(CollisionShape2DEditorPlugin)); - add_editor_plugin(memnew(CPUParticles2DEditorPlugin)); - add_editor_plugin(memnew(GPUParticles2DEditorPlugin)); - add_editor_plugin(memnew(LightOccluder2DEditorPlugin)); - add_editor_plugin(memnew(Line2DEditorPlugin)); - add_editor_plugin(memnew(NavigationLink2DEditorPlugin)); - add_editor_plugin(memnew(NavigationPolygonEditorPlugin)); - add_editor_plugin(memnew(Path2DEditorPlugin)); - add_editor_plugin(memnew(Polygon2DEditorPlugin)); - add_editor_plugin(memnew(Cast2DEditorPlugin)); - add_editor_plugin(memnew(Skeleton2DEditorPlugin)); - add_editor_plugin(memnew(Sprite2DEditorPlugin)); - add_editor_plugin(memnew(TilesEditorPlugin)); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i)); @@ -7564,7 +7436,6 @@ EditorNode::EditorNode() { // Extend menu bar to window title. if (can_expand) { - DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_minimum_size().y / 2, menu_hb->get_minimum_size().y / 2), DisplayServer::MAIN_WINDOW_ID); DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE, true, DisplayServer::MAIN_WINDOW_ID); menu_hb->set_can_move_window(true); } |