diff options
Diffstat (limited to 'editor')
47 files changed, 401 insertions, 183 deletions
diff --git a/editor/debugger/debug_adapter/debug_adapter_types.h b/editor/debugger/debug_adapter/debug_adapter_types.h index 4d77b6d51c..fd66905f9b 100644 --- a/editor/debugger/debug_adapter/debug_adapter_types.h +++ b/editor/debugger/debug_adapter/debug_adapter_types.h @@ -220,7 +220,7 @@ struct StackFrame { int column; static uint32_t hash(const StackFrame &p_frame) { - return hash_djb2_one_32(p_frame.id); + return hash_murmur3_one_32(p_frame.id); } bool operator==(const StackFrame &p_other) const { return id == p_other.id; diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index 8dc53690eb..d50cbec291 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -72,7 +72,7 @@ private: static uint32_t hash(const Breakpoint &p_val) { uint32_t h = HashMapHasherDefault::hash(p_val.source); - return hash_djb2_one_32(p_val.line, h); + return hash_murmur3_one_32(p_val.line, h); } bool operator==(const Breakpoint &p_b) const { return (line == p_b.line && source == p_b.source); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 97699d0349..9a1b2b5ff5 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -487,7 +487,7 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector< void DependencyRemoveDialog::ok_pressed() { for (int i = 0; i < files_to_delete.size(); ++i) { if (ResourceCache::has(files_to_delete[i])) { - Resource *res = ResourceCache::get(files_to_delete[i]); + Ref<Resource> res = ResourceCache::get_ref(files_to_delete[i]); res->set_path(""); } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index f9a4c14c48..adbba98897 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1792,9 +1792,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it //to reload properly - if (ResourceCache::has(file)) { - Resource *r = ResourceCache::get(file); + Ref<Resource> r = ResourceCache::get_ref(file); + if (r.is_valid()) { if (!r->get_import_path().is_empty()) { String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(file); r->set_import_path(dst_path); @@ -2034,9 +2034,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it //to reload properly - if (ResourceCache::has(p_file)) { - Resource *r = ResourceCache::get(p_file); - + Ref<Resource> r = ResourceCache::get_ref(p_file); + if (r.is_valid()) { if (!r->get_import_path().is_empty()) { String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file); r->set_import_path(dst_path); diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 9e1b361f64..8c508494c0 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -193,10 +193,7 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) { for (int i = 0; i < res_unfolds.size(); i += 2) { String path2 = res_unfolds[i]; - Ref<Resource> res; - if (ResourceCache::has(path2)) { - res = Ref<Resource>(ResourceCache::get(path2)); - } + Ref<Resource> res = ResourceCache::get_ref(path2); if (res.is_null()) { continue; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 67d0b83bd6..9b0ac305d1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -582,9 +582,10 @@ void EditorNode::_notification(int p_what) { opening_prev = false; } + bool unsaved_cache_changed = false; if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) { unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version()); - _update_title(); + unsaved_cache_changed = true; } if (last_checked_version != editor_data.get_undo_redo().get_version()) { @@ -615,6 +616,10 @@ void EditorNode::_notification(int p_what) { ResourceImporterTexture::get_singleton()->update_imports(); + if (settings_changed || unsaved_cache_changed) { + _update_title(); + } + if (settings_changed) { _update_from_settings(); settings_changed = false; @@ -876,7 +881,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) { int rc = p_resources.size(); for (int i = 0; i < rc; i++) { - Ref<Resource> res(ResourceCache::get(p_resources.get(i))); + Ref<Resource> res = ResourceCache::get_ref(p_resources.get(i)); if (res.is_null()) { continue; } @@ -1006,8 +1011,8 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) { continue; } // Reload normally. - Resource *resource = ResourceCache::get(p_resources[i]); - if (resource) { + Ref<Resource> resource = ResourceCache::get_ref(p_resources[i]); + if (resource.is_valid()) { resource->reload_from_file(); } } @@ -1720,7 +1725,7 @@ void EditorNode::_save_scene(String p_file, int idx) { // We must update it, but also let the previous scene state go, as // old version still work for referencing changes in instantiated or inherited scenes. - sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(p_file))); + sdata = ResourceCache::get_ref(p_file); if (sdata.is_valid()) { sdata->recreate_state(); } else { @@ -2342,6 +2347,20 @@ void EditorNode::_run(bool p_current, const String &p_custom) { return; } + String write_movie_file; + if (write_movie_button->is_pressed()) { + if (p_current && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->has_meta("movie_file")) { + // If the scene file has a movie_file metadata set, use this as file. Quick workaround if you want to have multiple scenes that write to multiple movies. + write_movie_file = get_tree()->get_edited_scene_root()->get_meta("movie_file"); + } else { + write_movie_file = GLOBAL_GET("editor/movie_writer/movie_file"); + } + if (write_movie_file == String()) { + show_accept(TTR("Movie Maker mode is enabled, but no movie file path has been specified.\nA default movie file path can be specified in the project settings under the 'Editor/Movie Writer' category.\nAlternatively, for running single scenes, a 'movie_path' metadata can be added to the root node,\nspecifying the path to a movie file that will be used when recording that scene."), TTR("OK")); + return; + } + } + play_button->set_pressed(false); play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); play_scene_button->set_pressed(false); @@ -2405,7 +2424,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { } EditorDebuggerNode::get_singleton()->start(); - Error error = editor_run.run(run_filename); + Error error = editor_run.run(run_filename, write_movie_file); if (error != OK) { EditorDebuggerNode::get_singleton()->stop(); show_accept(TTR("Could not start subprocess(es)!"), TTR("OK")); @@ -2788,6 +2807,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case RUN_SETTINGS: { project_settings_editor->popup_project_settings(); } break; + case RUN_WRITE_MOVIE: { + _update_write_movie_icon(); + } break; case FILE_INSTALL_ANDROID_SOURCE: { if (p_confirmed) { export_template_manager->install_android_template(); @@ -3695,7 +3717,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b if (ResourceCache::has(lpath)) { // Used from somewhere else? No problem! Update state and replace sdata. - Ref<PackedScene> ps = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(lpath))); + Ref<PackedScene> ps = ResourceCache::get_ref(lpath); if (ps.is_valid()) { ps->replace_state(sdata->get_state()); ps->set_last_modified_time(sdata->get_last_modified_time()); @@ -4949,6 +4971,14 @@ String EditorNode::get_run_playing_scene() const { return run_filename; } +void EditorNode::_update_write_movie_icon() { + if (write_movie_button->is_pressed()) { + write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWriteEnabled"), SNAME("EditorIcons"))); + } else { + write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons"))); + } +} + void EditorNode::_immediate_dialog_confirmed() { immediate_dialog_confirmed = true; } @@ -6704,6 +6734,23 @@ EditorNode::EditorNode() { ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::R); play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene")); + write_movie_button = memnew(Button); + write_movie_button->set_flat(true); + write_movie_button->set_toggle_mode(true); + play_hb->add_child(write_movie_button); + write_movie_button->set_pressed(false); + write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons"))); + write_movie_button->set_focus_mode(Control::FOCUS_NONE); + write_movie_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_WRITE_MOVIE)); + write_movie_button->set_tooltip(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file.")); + // Restore these values to something more useful so it ignores the theme + write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.4)); + write_movie_button->add_theme_color_override("icon_pressed_color", Color(1, 1, 1, 1)); + write_movie_button->add_theme_color_override("icon_hover_color", Color(1.2, 1.2, 1.2, 0.4)); + write_movie_button->add_theme_color_override("icon_hover_pressed_color", Color(1.2, 1.2, 1.2, 1)); + write_movie_button->add_theme_color_override("icon_focus_color", Color(1, 1, 1, 1)); + write_movie_button->add_theme_color_override("icon_disabled_color", Color(1, 1, 1, 0.4)); + HBoxContainer *right_menu_hb = memnew(HBoxContainer); menu_hb->add_child(right_menu_hb); @@ -7054,7 +7101,6 @@ EditorNode::EditorNode() { add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin)); add_editor_plugin(memnew(ShaderFileEditorPlugin)); - add_editor_plugin(memnew(VisualShaderEditorPlugin)); add_editor_plugin(memnew(Camera3DEditorPlugin)); add_editor_plugin(memnew(ThemeEditorPlugin)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 48df767562..89f80baeb9 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -173,6 +173,7 @@ private: RUN_PLAY_CUSTOM_SCENE, RUN_SETTINGS, RUN_USER_DATA_FOLDER, + RUN_WRITE_MOVIE, RELOAD_CURRENT_PROJECT, RUN_PROJECT_MANAGER, RUN_VCS_METADATA, @@ -333,6 +334,7 @@ private: Button *play_scene_button = nullptr; Button *play_custom_scene_button = nullptr; Button *search_button = nullptr; + Button *write_movie_button = nullptr; TextureProgressBar *audio_vu = nullptr; Timer *screenshot_timer = nullptr; @@ -667,7 +669,7 @@ private: void _pick_main_scene_custom_action(const String &p_custom_action_name); void _immediate_dialog_confirmed(); - + void _update_write_movie_icon(); void _select_default_main_screen_plugin(); void _bottom_panel_switch(bool p_enable, int p_idx); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index a5c02c70d9..2562c740aa 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3601,7 +3601,7 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri hint.greater = true; } else if (slice == "or_lesser") { hint.lesser = true; - } else if (slice == "noslider") { + } else if (slice == "no_slider") { hint.hide_slider = true; } else if (slice == "exp") { hint.exp_range = true; @@ -3747,11 +3747,11 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyLocale *editor = memnew(EditorPropertyLocale); editor->setup(p_hint_text); return editor; - } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) { + } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) { Vector<String> extensions = p_hint_text.split(","); - bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE; + bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE; bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR; - bool save = p_hint == PROPERTY_HINT_SAVE_FILE; + bool save = p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE; EditorPropertyPath *editor = memnew(EditorPropertyPath); editor->setup(extensions, folder, global); if (save) { diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 397afc0653..09d2992e07 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -176,6 +176,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["lowpass"] = "Low-pass"; capitalize_string_remaps["macos"] = "macOS"; capitalize_string_remaps["mb"] = "(MB)"; // Unit. + capitalize_string_remaps["mjpeg"] = "MJPEG"; capitalize_string_remaps["mms"] = "MMS"; capitalize_string_remaps["ms"] = "(ms)"; // Unit capitalize_string_remaps["msaa"] = "MSAA"; diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 6a2ff50ee0..04a3bf2915 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -43,7 +43,7 @@ String EditorRun::get_running_scene() const { return running_scene; } -Error EditorRun::run(const String &p_scene) { +Error EditorRun::run(const String &p_scene, const String &p_write_movie) { List<String> args; String resource_path = ProjectSettings::get_singleton()->get_resource_path(); @@ -68,6 +68,16 @@ Error EditorRun::run(const String &p_scene) { args.push_back("--debug-navigation"); } + if (p_write_movie != "") { + args.push_back("--write-movie"); + args.push_back(p_write_movie); + args.push_back("--fixed-fps"); + args.push_back(itos(GLOBAL_GET("editor/movie_writer/fps"))); + if (bool(GLOBAL_GET("editor/movie_writer/disable_vsync"))) { + args.push_back("--disable-vsync"); + } + } + int screen = EditorSettings::get_singleton()->get("run/window_placement/screen"); if (screen == 0) { // Same as editor diff --git a/editor/editor_run.h b/editor/editor_run.h index 50604ff032..4cbc6838e4 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -50,7 +50,7 @@ private: public: Status get_status() const; String get_running_scene() const; - Error run(const String &p_scene); + Error run(const String &p_scene, const String &p_write_movie = ""); void run_native_notify() { status = STATUS_PLAY; } void stop(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 7a80cf36a8..10412eac41 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -464,6 +464,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color icon_hover_color = icon_normal_color * (dark_theme ? 1.15 : 1.45); icon_hover_color.a = 1.0; Color icon_focus_color = icon_hover_color; + Color icon_disabled_color = Color(icon_normal_color, 0.4); // Make the pressed icon color overbright because icons are not completely white on a dark theme. // On a light theme, icons are dark, so we need to modulate them with an even brighter color. Color icon_pressed_color = accent_color * (dark_theme ? 1.15 : 3.5); @@ -738,10 +739,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "Button", font_focus_color); theme->set_color("font_pressed_color", "Button", accent_color); theme->set_color("font_disabled_color", "Button", font_disabled_color); + theme->set_color("icon_normal_color", "Button", icon_normal_color); theme->set_color("icon_hover_color", "Button", icon_hover_color); theme->set_color("icon_focus_color", "Button", icon_focus_color); theme->set_color("icon_pressed_color", "Button", icon_pressed_color); + theme->set_color("icon_disabled_color", "Button", icon_disabled_color); const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE; @@ -768,7 +771,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // When pressed, don't tint the icons with the accent color, just leave them normal. theme->set_color("icon_pressed_color", "EditorLogFilterButton", icon_normal_color); // When unpressed, dim the icons. - theme->set_color("icon_normal_color", "EditorLogFilterButton", font_disabled_color); + theme->set_color("icon_normal_color", "EditorLogFilterButton", icon_disabled_color); // When pressed, add a small bottom border to the buttons to better show their active state, // similar to active tabs. Ref<StyleBoxFlat> editor_log_button_pressed = style_widget_pressed->duplicate(); @@ -805,8 +808,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "OptionButton", font_focus_color); theme->set_color("font_pressed_color", "OptionButton", accent_color); theme->set_color("font_disabled_color", "OptionButton", font_disabled_color); + + theme->set_color("icon_normal_color", "OptionButton", icon_normal_color); theme->set_color("icon_hover_color", "OptionButton", icon_hover_color); theme->set_color("icon_focus_color", "OptionButton", icon_focus_color); + theme->set_color("icon_pressed_color", "OptionButton", icon_pressed_color); + theme->set_color("icon_disabled_color", "OptionButton", icon_disabled_color); + theme->set_icon("arrow", "OptionButton", theme->get_icon(SNAME("GuiOptionArrow"), SNAME("EditorIcons"))); theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); theme->set_constant("modulate_arrow", "OptionButton", true); @@ -833,8 +841,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "CheckButton", font_focus_color); theme->set_color("font_pressed_color", "CheckButton", accent_color); theme->set_color("font_disabled_color", "CheckButton", font_disabled_color); + + theme->set_color("icon_normal_color", "CheckButton", icon_normal_color); theme->set_color("icon_hover_color", "CheckButton", icon_hover_color); theme->set_color("icon_focus_color", "CheckButton", icon_focus_color); + theme->set_color("icon_pressed_color", "CheckButton", icon_pressed_color); + theme->set_color("icon_disabled_color", "CheckButton", icon_disabled_color); theme->set_constant("h_separation", "CheckButton", 8 * EDSCALE); theme->set_constant("check_v_adjust", "CheckButton", 0 * EDSCALE); @@ -864,8 +876,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "CheckBox", font_focus_color); theme->set_color("font_pressed_color", "CheckBox", accent_color); theme->set_color("font_disabled_color", "CheckBox", font_disabled_color); + + theme->set_color("icon_normal_color", "CheckBox", icon_normal_color); theme->set_color("icon_hover_color", "CheckBox", icon_hover_color); theme->set_color("icon_focus_color", "CheckBox", icon_focus_color); + theme->set_color("icon_pressed_color", "CheckBox", icon_pressed_color); + theme->set_color("icon_disabled_color", "CheckBox", icon_disabled_color); theme->set_constant("h_separation", "CheckBox", 8 * EDSCALE); theme->set_constant("check_v_adjust", "CheckBox", 0 * EDSCALE); diff --git a/editor/icons/BaseButton.svg b/editor/icons/BaseButton.svg new file mode 100644 index 0000000000..9aa0ae1c07 --- /dev/null +++ b/editor/icons/BaseButton.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.5 9c-.831 0-1.5.669-1.5 1.5v1.5h-2v2h12v-2h-2v-1.5c0-.831-.669-1.5-1.5-1.5z" fill="#8eef97"/></svg> diff --git a/editor/icons/GeometryInstance3D.svg b/editor/icons/GeometryInstance3D.svg new file mode 100644 index 0000000000..759d5fe413 --- /dev/null +++ b/editor/icons/GeometryInstance3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7304688v6.5410152a2 2 0 0 0 -1 1.728516 2 2 0 0 0 2 2 2 2 0 0 0 1.7304688-1h6.5410152a2 2 0 0 0 1.728516 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.03125-1.75h.03125v-6.5214844a2 2 0 0 0 1-1.7285156 2 2 0 0 0 -2-2 2 2 0 0 0 -1.730469 1h-6.5410154a2 2 0 0 0 -1.7285156-1zm1 3h1.4140625 3.5859375 2.271484a2 2 0 0 0 .728516.7304688v1.2695312 4.585938 1.414062h-1.414062-4.585938-1.2714844a2 2 0 0 0 -.7285156-.730469v-3.269531-2.5859375z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/ImporterMeshInstance3D.svg b/editor/icons/ImporterMeshInstance3D.svg new file mode 100644 index 0000000000..7e7598ac2b --- /dev/null +++ b/editor/icons/ImporterMeshInstance3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7304688v6.5410152a2 2 0 0 0 -1 1.728516 2 2 0 0 0 2 2 2 2 0 0 0 1.7304688-1h6.5410152a2 2 0 0 0 1.728516 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.03125-1.75h.03125v-6.5214844a2 2 0 0 0 1-1.7285156 2 2 0 0 0 -2-2 2 2 0 0 0 -1.730469 1h-6.5410154a2 2 0 0 0 -1.7285156-1zm1 3h1.4140625 3.5859375 2.271484a2 2 0 0 0 .728516.7304688v1.2695312 4.585938 1.414062h-1.414062-4.585938-1.2714844a2 2 0 0 0 -.7285156-.730469v-3.269531-2.5859375z"/><path d="m7 7h2v4h-2z"/><path d="m7 5h2v1h-2z"/></g></svg> diff --git a/editor/icons/MainMovieWrite.svg b/editor/icons/MainMovieWrite.svg new file mode 100644 index 0000000000..21464bb57c --- /dev/null +++ b/editor/icons/MainMovieWrite.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 4-1.535V14h.002a2 2 0 0 0 .266 1A2 2 0 0 0 14 16h1v-2h-.5a.5.5 0 0 1-.5-.5V8a6 6 0 0 0-6-6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1zm3.441 2a1 1 0 0 1 .89.5 1 1 0 0 1-.366 1.365 1 1 0 0 1-1.367-.365 1 1 0 0 1 .367-1.365A1 1 0 0 1 11.44 5zm-6.953.002a1 1 0 0 1 .547.133A1 1 0 0 1 5.402 6.5a1 1 0 0 1-1.367.365A1 1 0 0 1 3.67 5.5a1 1 0 0 1 .818-.498zM4.512 9a1 1 0 0 1 .89.5 1 1 0 0 1-.367 1.365A1 1 0 0 1 3.67 10.5a1 1 0 0 1 .365-1.365A1 1 0 0 1 4.512 9zm6.904.002a1 1 0 0 1 .549.133 1 1 0 0 1 .365 1.365 1 1 0 0 1-1.365.365 1 1 0 0 1-.367-1.365 1 1 0 0 1 .818-.498zM8 11a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MainMovieWriteEnabled.svg b/editor/icons/MainMovieWriteEnabled.svg new file mode 100644 index 0000000000..b12ea38bed --- /dev/null +++ b/editor/icons/MainMovieWriteEnabled.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 4-1.535V14h.002a2 2 0 0 0 .266 1A2 2 0 0 0 14 16h1v-2h-.5a.5.5 0 0 1-.5-.5V8a6 6 0 0 0-6-6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1zm3.441 2a1 1 0 0 1 .89.5 1 1 0 0 1-.366 1.365 1 1 0 0 1-1.367-.365 1 1 0 0 1 .367-1.365A1 1 0 0 1 11.44 5zm-6.953.002a1 1 0 0 1 .547.133A1 1 0 0 1 5.402 6.5a1 1 0 0 1-1.367.365A1 1 0 0 1 3.67 5.5a1 1 0 0 1 .818-.498zM4.512 9a1 1 0 0 1 .89.5 1 1 0 0 1-.367 1.365A1 1 0 0 1 3.67 10.5a1 1 0 0 1 .365-1.365A1 1 0 0 1 4.512 9zm6.904.002a1 1 0 0 1 .549.133 1 1 0 0 1 .365 1.365 1 1 0 0 1-1.365.365 1 1 0 0 1-.367-1.365 1 1 0 0 1 .818-.498zM8 11a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#e0e0e0" style="fill:#ee5353;fill-opacity:1"/></svg> diff --git a/editor/icons/MultiplayerSpawner.svg b/editor/icons/MultiplayerSpawner.svg new file mode 100644 index 0000000000..68ffd3aab4 --- /dev/null +++ b/editor/icons/MultiplayerSpawner.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path style="fill:none;fill-opacity:.996078;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:16.5;stroke-opacity:1;paint-order:stroke markers fill" d="M4.936 7.429A4 4 0 0 1 8 6a4 4 0 0 1 3.064 1.429M1.872 4.858A8 8 0 0 1 8 2a8 8 0 0 1 6.128 2.858"/><path d="M7 9v2H5v2h2v2h2v-2h2v-2H9V9Z" fill="#5fff97"/></svg> diff --git a/editor/icons/MultiplayerSynchronizer.svg b/editor/icons/MultiplayerSynchronizer.svg new file mode 100644 index 0000000000..1547ec5a2b --- /dev/null +++ b/editor/icons/MultiplayerSynchronizer.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path style="fill:#5fff97;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" d="M5 10h3l-2 4-2-4Z"/><path style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" d="M9 14h3l-2-4-2 4Z"/><path style="fill:none;fill-opacity:.996078;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:16.5;stroke-opacity:1;paint-order:stroke markers fill" d="M4.936 7.429A4 4 0 0 1 8 6a4 4 0 0 1 3.064 1.429M1.872 4.858A8 8 0 0 1 8 2a8 8 0 0 1 6.128 2.858"/></svg> diff --git a/editor/icons/NavigationAgent2D.svg b/editor/icons/NavigationAgent2D.svg index 3f1d571a7e..05aeb95e12 100644 --- a/editor/icons/NavigationAgent2D.svg +++ b/editor/icons/NavigationAgent2D.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3 0-5 2-5 5s3 6 5 9c2-3 5.007-6.03 5-9 0-3-2-5-5-5zm0 2.5c1.371 0 2.5 1.129 2.5 2.5s-1.129 2.5-2.5 2.5-2.5-1.129-2.5-2.5 1.129-2.5 2.5-2.5z" fill="#e0e0e0" fill-rule="nonzero"/></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v2.5c1.371 0 2.5 1.129 2.5 2.5s-1.129 2.5-2.5 2.5v6.5c2-3 5.007-6.03 5-9 0-3-2-5-5-5z" fill="#8da5f3" fill-opacity=".988235"/><path d="m8 1c-3 0-5 2-5 5s3 6 5 9v-6.5c-1.371 0-2.5-1.129-2.5-2.5s1.129-2.5 2.5-2.5z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/NavigationAgent3D.svg b/editor/icons/NavigationAgent3D.svg index 947b2129c3..5a2d8b3489 100644 --- a/editor/icons/NavigationAgent3D.svg +++ b/editor/icons/NavigationAgent3D.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m9 1c-1.371 0-2.308.429-2.939 1.074-.668.663-1.34 1.324-2.01 1.985-.046 1.741.757 4.327 2.365 4.843.178.317.384.649.584.977v5.121l2-2c2-3 4-6 4-8s-1-4-4-4z" fill="#fff" fill-opacity=".39"/><path d="m7 3c-3 0-4 2-4 4s2 5 4 8c2-3 4-6 4-8s-1-4-4-4zm0 2c1.097 0 2 .903 2 2s-.903 2-2 2-2-.903-2-2 .903-2 2-2z" fill="#e0e0e0"/></g></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m8 1.0859375c-.8454344.1560829-1.4755929.5141293-1.9394531.9882813-.668.663-1.3397656 1.323375-2.0097657 1.984375-.046 1.7409999.7572344 4.32775 2.3652344 4.84375.178.317.3839844.6485624.5839844.9765624v5.1210938l1-1z" fill="#e0e0e0" fill-opacity=".501961"/><path d="m7 3c-3 0-4 2-4 4s2 5 4 8c.3378629-.506794.671779-1.011698 1-1.513672v-4.7597655c-.2952789.1727801-.6361816.2734375-1 .2734375-1.097 0-2-.903-2-2s.903-2 2-2c.3638184 0 .7047211.1006574 1 .2734375v-2.1894531c-.3055959-.054762-.6378835-.0839844-1-.0839844z" fill="#e0e0e0"/><g fill="#fc7f7f"><path d="m9 1c-.3631515 0-.6953702.0296972-1 .0859375v12.9140625l1-1c2-3 4-6 4-8s-1-4-4-4z" fill-opacity=".501961"/><path d="m8 3.0839844v2.1894531c.5950581.3481936 1 .9933809 1 1.7265625s-.4049419 1.3783689-1 1.7265625v4.7597655c1.6147033-2.469489 3-4.8241909 3-6.486328 0-1.758589-.773848-3.5170952-3-3.9160156z"/></g></g></svg> diff --git a/editor/icons/NavigationObstacle2D.svg b/editor/icons/NavigationObstacle2D.svg index 8fcb5617dd..a5073898f4 100644 --- a/editor/icons/NavigationObstacle2D.svg +++ b/editor/icons/NavigationObstacle2D.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .875c-.625 0-1.25.375-1.5 1.125l-3 10h9l-3-10c-.25-.75-.875-1.125-1.5-1.125zm-1.5 4.125h3l1 4h-5zm-4.5 8c-1 0-1 2 0 2h12c1 0 1-2 0-2z" fill="#e0e0e0" fill-rule="nonzero"/></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .875c-.625 0-1.25.375-1.5 1.125l-3 10h4.5v-3h-2.5l1-4h1.5zm-6 12.125c-1 0-1 2 0 2h6v-2z" fill="#e0e0e0"/><path d="m8 .875v4.125h1.5l1 4h-2.5v3h4.5l-3-10c-.25-.75-.875-1.125-1.5-1.125zm0 12.125v2h6c1 0 1-2 0-2z" fill="#8da5f3" fill-opacity=".988235"/></svg> diff --git a/editor/icons/NavigationObstacle3D.svg b/editor/icons/NavigationObstacle3D.svg index c5e58eebf7..d8ccd3a646 100644 --- a/editor/icons/NavigationObstacle3D.svg +++ b/editor/icons/NavigationObstacle3D.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m4.607 8.379c-1.798.928-3.607 2.072-3.607 2.621 0 1 6 4 7 4s7-3 7-4c0-.549-1.809-1.693-3.607-2.621l.607 1.621c2 4-10 4-8 0z" fill="#fff" fill-opacity=".39"/><path d="m8 .875c-.375 0-.75.375-1 1.125l-3 8c-2 4 10 4 8 0l-3-8c-.25-.75-.625-1.125-1-1.125zm-1.5 4.125c1 .5 2 .5 3 0l1 3.5c-1.5 1-3.5 1-5 0z" fill="#e0e0e0"/></g></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m4.6074219 8.3789062c-1.798.9280001-3.6074219 2.0720938-3.6074219 2.6210938 0 1 6 4 7 4v-2c-2.5 0-5-1-4-3z" fill="#e0e0e0" fill-opacity=".501961"/><path d="m8 .875c-.375 0-.75.375-1 1.125l-3 8c-1 2 1.5 3 4 3v-3.75c-.875 0-1.75-.25-2.5-.75l1-3.5c.5.25 1 .375 1.5.375z" fill="#e0e0e0"/><g fill="#fc7f7f"><path d="m11.392578 8.3789062.607422 1.6210938c1.002342 2.004685-1.511742 3.004696-4.0175781 3v1.998047c.0053893.000157.0124503.001953.0175781.001953 1 0 7-3 7-4 0-.549-1.809422-1.6930938-3.607422-2.6210938z" fill-opacity=".501961"/><path d="m8 .875c-.00585 0-.011729.001771-.017578.001953v4.498047c.5058535.0029611 1.0117243-.1220732 1.517578-.375l1 3.5c-.7550159.5033439-1.6367318.7533663-2.5175781.75v3.75c2.5058361.004696 5.0199201-.995315 4.0175781-3l-3-8c-.25-.75-.625-1.125-1-1.125z"/></g></g></svg> diff --git a/editor/icons/Range.svg b/editor/icons/Range.svg new file mode 100644 index 0000000000..49311546b0 --- /dev/null +++ b/editor/icons/Range.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.8027344 2.7714844c-1.0905892.2029663-1.089037 1.7659969.00195 1.9667968l2.8808595.5761719.576172 2.8808594c.231158 1.3504655 2.264924.9453327 1.960937-.390625l-.7070279-3.5371094c-.039663-.1968491-.137665-.3771998-.28125-.5175781-.138135-.1351849-.312483-.2274468-.501953-.265625l-3.5371095-.7070312c-.1291868-.0278728-.262617-.0298643-.3925781-.0058594zm-3.9941406 4.2167968c-.6571498-.0349349-1.1683412.5633914-1.03125 1.2070313l.7070312 3.5371095c.079467.394998.3882047.703736.7832031.783203l3.5371094.707031c1.3359577.303987 1.7410905-1.729779.390625-1.960937l-2.8808594-.576172-.5761719-2.8808595c-.0369237-.1982539-.1329195-.3807141-.2753906-.5234375-.1744016-.1751556-.407488-.2795227-.6542968-.2929688z" fill="#8eef97"/></svg> diff --git a/editor/icons/SkeletonIK3D.svg b/editor/icons/SkeletonIK3D.svg index 45697a1b42..7210019749 100644 --- a/editor/icons/SkeletonIK3D.svg +++ b/editor/icons/SkeletonIK3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.453125v3.546875a2 2 0 0 0 1 1.732422 2 2 0 0 0 1 .265625v.001953h2v-2h-1v-1h-1v1h-1v-3.1308594-.8691406h1v1h1v-1h1v-1h-1v-1h1v-5zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#e0e0e0"/><path d="m8 2v5h1v1h-1v1h1v1h1v-1h1v.8671875 3.1328125h-1v-1h-1v1h-1v2h2v-.001953a2 2 0 0 0 1-.265625 2 2 0 0 0 1-1.732422v-3.546875a4 4 0 0 0 2-3.453125 4 4 0 0 0 -4-4zm3 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/VideoPlayer.svg b/editor/icons/VideoStreamPlayer.svg index 092a26b955..092a26b955 100644 --- a/editor/icons/VideoPlayer.svg +++ b/editor/icons/VideoStreamPlayer.svg diff --git a/editor/icons/VisualInstance3D.svg b/editor/icons/VisualInstance3D.svg new file mode 100644 index 0000000000..e5e43b59dd --- /dev/null +++ b/editor/icons/VisualInstance3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><circle cx="3" cy="3" r="2"/><circle cx="13" cy="3" r="2"/><circle cx="13" cy="13" r="2"/><circle cx="3" cy="13" r="2"/></g></svg> diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index f2975b1d7a..171ef5bf4c 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1115,7 +1115,7 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani } if (ResourceCache::has(p_save_to_path)) { - Ref<Animation> old_anim = Ref<Resource>(ResourceCache::get(p_save_to_path)); + Ref<Animation> old_anim = ResourceCache::get_ref(p_save_to_path); if (old_anim.is_valid()) { old_anim->copy_from(anim); anim = old_anim; @@ -1711,7 +1711,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } if (!save_to_file.is_empty()) { - Ref<Mesh> existing = Ref<Resource>(ResourceCache::get(save_to_file)); + Ref<Mesh> existing = ResourceCache::get_ref(save_to_file); if (existing.is_valid()) { //if somehow an existing one is useful, create existing->reset_state(); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index a055dca8ad..deb3047864 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -65,15 +65,6 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<CompressedTexture2D } singleton->make_flags[path].flags |= MAKE_3D_FLAG; - - // For small textures, don't use VRAM compression as it decreases quality too much compared to the memory saved. - // The minimum size for VRAM compression is defined on each axis. - // It is then squared to handle non-square input texture sizes in a more human-readable manner. - const float minimum_size = float(GLOBAL_GET("rendering/textures/vram_compression/minimum_size")); - if (p_tex->get_width() * p_tex->get_height() >= int(Math::pow(minimum_size, 2.0f) - CMP_EPSILON)) { - // Texture is larger than `minimum_size × minimum_size` pixels (if square). - singleton->make_flags[path].flags |= MAKE_VRAM_COMPRESS_FLAG; - } } void ResourceImporterTexture::_texture_reimport_normal(const Ref<CompressedTexture2D> &p_tex) { @@ -112,33 +103,7 @@ void ResourceImporterTexture::update_imports() { bool changed = false; - if (E.value.flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { - if (E.value.flags & MAKE_VRAM_COMPRESS_FLAG) { - // Texture is large enough to benefit from VRAM compression. - const int compress_to = cf->get_value("params", "detect_3d/compress_to"); - String compress_string; - if (compress_to == 1) { - cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); - compress_string = "VRAM Compressed (S3TC/ETC/BPTC)"; - } else if (compress_to == 2) { - cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); - compress_string = "Basis Universal"; - } - print_line(vformat(TTR("%s: Texture detected as used in 3D. Enabling mipmap generation and setting the texture compression mode to %s."), String(E.key), compress_string)); - } else { - print_line(vformat(TTR("%s: Small texture detected as used in 3D. Enabling mipmap generation but not VRAM compression."), String(E.key))); - } - - cf->set_value("params", "mipmaps/generate", true); - cf->set_value("params", "detect_3d/compress_to", 0); - - changed = true; - } - - if (E.value.flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0 && int(cf->get_value("params", "compress/mode")) != COMPRESS_LOSSLESS) { - // Normal map compression is not available for textures with Lossless compression. - // This is ignored in the importer, but printing a message about normal map compression - // being enabled in this case is misleading. + if (E.value.flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { print_line(vformat(TTR("%s: Texture detected as used as a normal map in 3D. Enabling red-green texture compression to reduce memory usage (blue channel is discarded)."), String(E.key))); cf->set_value("params", "compress/normal_map", 1); changed = true; @@ -151,6 +116,22 @@ void ResourceImporterTexture::update_imports() { changed = true; } + if (E.value.flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { + const int compress_to = cf->get_value("params", "detect_3d/compress_to"); + String compress_string; + cf->set_value("params", "detect_3d/compress_to", 0); + if (compress_to == 1) { + cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); + compress_string = "VRAM Compressed (S3TC/ETC/BPTC)"; + } else if (compress_to == 2) { + cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); + compress_string = "Basis Universal"; + } + print_line(vformat(TTR("%s: Texture detected as used in 3D. Enabling mipmap generation and setting the texture compression mode to %s."), String(E.key), compress_string)); + cf->set_value("params", "mipmaps/generate", true); + changed = true; + } + if (changed) { cf->save(src_path); to_reimport.push_back(E.key); diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index e65c15ae78..7def2d4f77 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -54,9 +54,8 @@ public: protected: enum { MAKE_3D_FLAG = 1, - MAKE_VRAM_COMPRESS_FLAG = 2, - MAKE_ROUGHNESS_FLAG = 4, - MAKE_NORMAL_FLAG = 8, + MAKE_ROUGHNESS_FLAG = 2, + MAKE_NORMAL_FLAG = 4 }; Mutex mutex; diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index aa338a6c0d..e5fe99890e 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -306,10 +306,8 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file //update cache if existing, else create Ref<Texture2D> cache; - if (ResourceCache::has(p_group_file)) { - Resource *resptr = ResourceCache::get(p_group_file); - cache.reference_ptr(resptr); - } else { + cache = ResourceCache::get_ref(p_group_file); + if (!cache.is_valid()) { Ref<ImageTexture> res_cache; res_cache.instantiate(); res_cache->create_from_image(new_atlas); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 98ccc1fdbe..e5ca5d66e8 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1053,7 +1053,7 @@ void AnimationPlayerEditor::_animation_duplicate() { _update_name_dialog_library_dropdown(); name_dialog_op = TOOL_DUPLICATE_ANIM; - name_dialog->set_title("Duplicate Animation"); + name_dialog->set_title(TTR("Duplicate Animation")); name_title->set_text(TTR("Duplicated Animation Name:")); name->set_text(new_name); name_dialog->popup_centered(Size2(300, 90)); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 2ba2466646..00cc5a6ca0 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -817,11 +817,11 @@ bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<Ani Vector<Ref<AnimationNodeStateMachine>> parents = p_parents; if (from_root) { - Ref<AnimationNodeStateMachine> prev = p_nodesm->get_prev_state_machine(); + AnimationNodeStateMachine *prev = p_nodesm->get_prev_state_machine(); - while (prev.is_valid()) { + while (prev != nullptr) { parents.push_back(prev); - p_nodesm = prev; + p_nodesm = Ref<AnimationNodeStateMachine>(prev); prev_path += "../"; prev = prev->get_prev_state_machine(); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 1ea0299d4e..dea4aaded7 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5455,7 +5455,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & } child->set_name(name); - Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(ResourceCache::get(path))); + Ref<Texture2D> texture = ResourceCache::get_ref(path); if (parent) { editor_data->get_undo_redo().add_do_method(parent, "add_child", child, true); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index d85087b5ea..d1f858315c 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -350,8 +350,8 @@ struct MeshInstance3DEditorEdgeSort { Vector2 b; static uint32_t hash(const MeshInstance3DEditorEdgeSort &p_edge) { - uint32_t h = hash_djb2_one_32(HashMapHasherDefault::hash(p_edge.a)); - return hash_djb2_one_32(HashMapHasherDefault::hash(p_edge.b), h); + uint32_t h = hash_murmur3_one_32(HashMapHasherDefault::hash(p_edge.a)); + return hash_fmix32(hash_murmur3_one_32(HashMapHasherDefault::hash(p_edge.b), h)); } bool operator==(const MeshInstance3DEditorEdgeSort &p_b) const { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index b9d99fcc93..6ab2366a44 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3547,7 +3547,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader")); shader_editor->edit(res.ptr()); shader_editor->make_visible(true); - shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end); + shader_editor->get_shader_editor(res)->goto_line_selection(line_number - 1, begin, end); return; } else if (fpath.get_extension() == "tscn") { EditorNode::get_singleton()->load_scene(fpath); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index c13d0dc197..04b407ce65 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -38,8 +38,12 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/filesystem_dock.h" +#include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/project_settings_editor.h" #include "editor/property_editor.h" +#include "editor/shader_create_dialog.h" +#include "scene/gui/split_container.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -836,50 +840,216 @@ ShaderEditor::ShaderEditor() { _editor_settings_changed(); } +void ShaderEditorPlugin::_update_shader_list() { + shader_list->clear(); + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + String text; + String path = edited_shaders[i].shader->get_path(); + String _class = edited_shaders[i].shader->get_class(); + + if (path.is_resource_file()) { + text = path.get_file(); + } else if (edited_shaders[i].shader->get_name() != "") { + text = edited_shaders[i].shader->get_name(); + } else { + text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id()); + } + + if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) { + _class = "Resource"; + } + Ref<Texture2D> icon = shader_list->get_theme_icon(_class, SNAME("EditorIcons")); + + shader_list->add_item(text, icon); + shader_list->set_item_tooltip(shader_list->get_item_count() - 1, path); + } + + if (shader_tabs->get_tab_count()) { + shader_list->select(shader_tabs->get_current_tab()); + } + + for (int i = 1; i < FILE_MAX; i++) { + file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), edited_shaders.size() == 0); + } +} + void ShaderEditorPlugin::edit(Object *p_object) { Shader *s = Object::cast_to<Shader>(p_object); - shader_editor->edit(s); + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader.ptr() == s) { + // Exists, select. + shader_tabs->set_current_tab(i); + shader_list->select(i); + return; + } + } + // Add. + EditedShader es; + es.shader = Ref<Shader>(s); + Ref<VisualShader> vs = es.shader; + if (vs.is_valid()) { + es.visual_shader_editor = memnew(VisualShaderEditor); + es.visual_shader_editor->edit(vs.ptr()); + shader_tabs->add_child(es.visual_shader_editor); + } else { + es.shader_editor = memnew(ShaderEditor); + es.shader_editor->edit(s); + shader_tabs->add_child(es.shader_editor); + } + shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1); + edited_shaders.push_back(es); + _update_shader_list(); } bool ShaderEditorPlugin::handles(Object *p_object) const { - Shader *shader = Object::cast_to<Shader>(p_object); - return shader != nullptr && shader->is_text_shader(); + return Object::cast_to<Shader>(p_object) != nullptr; } void ShaderEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor); - - } else { - button->hide(); - if (shader_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); - } - shader_editor->apply_shaders(); + EditorNode::get_singleton()->make_bottom_panel_item_visible(main_split); } } void ShaderEditorPlugin::selected_notify() { - shader_editor->ensure_select_current(); +} + +ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_shader) { + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader == p_for_shader) { + return edited_shaders[i].shader_editor; + } + } + return nullptr; } void ShaderEditorPlugin::save_external_data() { - shader_editor->save_external_data(); + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader_editor) { + edited_shaders[i].shader_editor->save_external_data(); + } + } } void ShaderEditorPlugin::apply_changes() { - shader_editor->apply_shaders(); + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader_editor) { + edited_shaders[i].shader_editor->apply_shaders(); + } + } +} + +void ShaderEditorPlugin::_shader_selected(int p_index) { + shader_tabs->set_current_tab(p_index); +} + +void ShaderEditorPlugin::_close_shader(int p_index) { + int index = shader_tabs->get_current_tab(); + ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); + Control *c = shader_tabs->get_tab_control(index); + memdelete(c); + edited_shaders.remove_at(index); + _update_shader_list(); +} + +void ShaderEditorPlugin::_resource_saved(Object *obj) { + // May have been renamed on save. + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader.ptr() == obj) { + _update_shader_list(); + return; + } + } +} + +void ShaderEditorPlugin::_menu_item_pressed(int p_index) { + switch (p_index) { + case FILE_NEW: { + String base_path = FileSystemDock::get_singleton()->get_current_path(); + shader_create_dialog->config(base_path.plus_file("new_shader"), false, false, 0); + shader_create_dialog->popup_centered(); + } break; + case FILE_OPEN: { + InspectorDock::get_singleton()->open_resource("Shader"); + } break; + case FILE_SAVE: { + int index = shader_tabs->get_current_tab(); + ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); + EditorNode::get_singleton()->save_resource(edited_shaders[index].shader); + } break; + case FILE_SAVE_AS: { + int index = shader_tabs->get_current_tab(); + ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); + String path = edited_shaders[index].shader->get_path(); + if (!path.is_resource_file()) { + path = ""; + } + EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader, path); + } break; + case FILE_INSPECT: { + int index = shader_tabs->get_current_tab(); + ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); + EditorNode::get_singleton()->push_item(edited_shaders[index].shader.ptr()); + } break; + case FILE_CLOSE: { + _close_shader(shader_tabs->get_current_tab()); + } break; + } +} + +void ShaderEditorPlugin::_shader_created(Ref<Shader> p_shader) { + EditorNode::get_singleton()->push_item(p_shader.ptr()); } ShaderEditorPlugin::ShaderEditorPlugin() { - shader_editor = memnew(ShaderEditor); + main_split = memnew(HSplitContainer); + + VBoxContainer *vb = memnew(VBoxContainer); + + HBoxContainer *file_hb = memnew(HBoxContainer); + vb->add_child(file_hb); + file_menu = memnew(MenuButton); + file_menu->set_text(TTR("File")); + file_menu->get_popup()->add_item(TTR("New Shader"), FILE_NEW); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_item(TTR("Load Shader"), FILE_OPEN); + file_menu->get_popup()->add_item(TTR("Save Shader"), FILE_SAVE); + file_menu->get_popup()->add_item(TTR("Save Shader As"), FILE_SAVE_AS); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_item(TTR("Open Shader in Inspector"), FILE_INSPECT); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_item(TTR("Close Shader"), FILE_CLOSE); + file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed)); + file_hb->add_child(file_menu); + + for (int i = 1; i < FILE_MAX; i++) { + file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), true); + } + + shader_list = memnew(ItemList); + shader_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vb->add_child(shader_list); + shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected)); + + main_split->add_child(vb); + vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE); + + shader_tabs = memnew(TabContainer); + shader_tabs->set_tabs_visible(false); + shader_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL); + main_split->add_child(shader_tabs); + Ref<StyleBoxEmpty> empty; + empty.instantiate(); + shader_tabs->add_theme_style_override("panel", empty); + + button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader Editor"), main_split); - shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader"), shader_editor); - button->hide(); + // Defer connect because Editor class is not in the binding system yet. + EditorNode::get_singleton()->call_deferred("connect", "resource_saved", callable_mp(this, &ShaderEditorPlugin::_resource_saved), varray(), CONNECT_DEFERRED); - _2d = false; + shader_create_dialog = memnew(ShaderCreateDialog); + vb->add_child(shader_create_dialog); + shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created)); } ShaderEditorPlugin::~ShaderEditorPlugin() { diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index bd0c2db824..e1e815f939 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -42,6 +42,11 @@ #include "scene/resources/shader.h" #include "servers/rendering/shader_warnings.h" +class ItemList; +class VisualShaderEditor; +class HSplitContainer; +class ShaderCreateDialog; + class ShaderTextEditor : public CodeTextEditor { GDCLASS(ShaderTextEditor, CodeTextEditor); @@ -160,9 +165,40 @@ public: class ShaderEditorPlugin : public EditorPlugin { GDCLASS(ShaderEditorPlugin, EditorPlugin); - bool _2d; - ShaderEditor *shader_editor = nullptr; + struct EditedShader { + Ref<Shader> shader; + ShaderEditor *shader_editor = nullptr; + VisualShaderEditor *visual_shader_editor = nullptr; + }; + + LocalVector<EditedShader> edited_shaders; + + enum { + FILE_NEW, + FILE_OPEN, + FILE_SAVE, + FILE_SAVE_AS, + FILE_INSPECT, + FILE_CLOSE, + FILE_MAX + }; + + HSplitContainer *main_split = nullptr; + ItemList *shader_list = nullptr; + TabContainer *shader_tabs = nullptr; + Button *button = nullptr; + MenuButton *file_menu = nullptr; + + ShaderCreateDialog *shader_create_dialog = nullptr; + + void _update_shader_list(); + void _shader_selected(int p_index); + void _menu_item_pressed(int p_index); + void _resource_saved(Object *obj); + void _close_shader(int p_index); + + void _shader_created(Ref<Shader> p_shader); public: virtual String get_name() const override { return "Shader"; } @@ -172,7 +208,7 @@ public: virtual void make_visible(bool p_visible) override; virtual void selected_notify() override; - ShaderEditor *get_shader_editor() const { return shader_editor; } + ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader); virtual void save_external_data() override; virtual void apply_changes() override; diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index ec45341970..468681c967 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -1147,7 +1147,7 @@ void TileDataDefaultEditor::setup_property_editor(Variant::Type p_type, String p property_editor = EditorInspectorDefaultPlugin::get_editor_for_property(dummy_object, p_type, p_property, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); property_editor->set_object_and_property(dummy_object, p_property); if (p_label.is_empty()) { - property_editor->set_label(p_property); + property_editor->set_label(EditorPropertyNameProcessor::get_singleton()->process_name(p_property, EditorPropertyNameProcessor::get_default_inspector_style())); } else { property_editor->set_label(p_label); } @@ -1173,6 +1173,7 @@ TileDataDefaultEditor::TileDataDefaultEditor() { label = memnew(Label); label->set_text(TTR("Painting:")); + label->set_theme_type_variation("HeaderSmall"); add_child(label); toolbar->add_child(memnew(VSeparator)); @@ -2566,7 +2567,8 @@ TileDataTerrainsEditor::TileDataTerrainsEditor() { undo_redo = EditorNode::get_undo_redo(); label = memnew(Label); - label->set_text("Painting:"); + label->set_text(TTR("Painting:")); + label->set_theme_type_variation("HeaderSmall"); add_child(label); // Toolbar diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 77a3c07548..d914b9c363 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -884,6 +884,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over if (atlas_source) { // Get tile data. TileData *tile_data = atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile); + if (!tile_data) { + continue; + } // Compute the offset Rect2i source_rect = atlas_source->get_tile_texture_region(E.value.get_atlas_coords()); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 66459d3ef9..37ccc6ad45 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -97,9 +97,9 @@ bool TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get(const StringN void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "margins", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "separation", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "texture_region_size", PROPERTY_HINT_NONE, "")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, "margins", PROPERTY_HINT_NONE, "suffix:px")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, "separation", PROPERTY_HINT_NONE, "suffix:px")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, "texture_region_size", PROPERTY_HINT_NONE, "suffix:px")); p_list->push_back(PropertyInfo(Variant::BOOL, "use_texture_padding", PROPERTY_HINT_NONE, "")); } @@ -401,15 +401,15 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro if (all_alternatve_id_zero) { p_list->push_back(PropertyInfo(Variant::NIL, "Animation", PROPERTY_HINT_NONE, "animation_", PROPERTY_USAGE_GROUP)); p_list->push_back(PropertyInfo(Variant::INT, "animation_columns", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "animation_separation", PROPERTY_HINT_NONE, "")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, "animation_separation", PROPERTY_HINT_NONE, "suffix:px")); p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_speed", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Frames,animation_frame_")); // Not optimal, but returns value for the first tile. This is similar to what MultiNodeEdit does. if (tile_set_atlas_source->get_tile_animation_frames_count(tiles.front()->get().tile) == 1) { - p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_frame_0/duration", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY)); + p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_frame_0/duration", PROPERTY_HINT_NONE, "suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY)); } else { for (int i = 0; i < tile_set_atlas_source->get_tile_animation_frames_count(tiles.front()->get().tile); i++) { - p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/duration", i), PROPERTY_HINT_NONE, "")); + p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/duration", i), PROPERTY_HINT_NONE, "suffix:s")); } } } @@ -2335,6 +2335,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { // Tile inspector. tile_inspector_label = memnew(Label); tile_inspector_label->set_text(TTR("Tile Properties:")); + tile_inspector_label->set_theme_type_variation("HeaderSmall"); middle_vbox_container->add_child(tile_inspector_label); tile_proxy_object = memnew(AtlasTileProxyObject(this)); @@ -2350,7 +2351,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_inspector_no_tile_selected_label = memnew(Label); tile_inspector_no_tile_selected_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - tile_inspector_no_tile_selected_label->set_text(TTR("No tile selected.")); + tile_inspector_no_tile_selected_label->set_text(TTR("No tiles selected.")); middle_vbox_container->add_child(tile_inspector_no_tile_selected_label); // Property values palette. @@ -2358,6 +2359,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_data_editors_label = memnew(Label); tile_data_editors_label->set_text(TTR("Paint Properties:")); + tile_data_editors_label->set_theme_type_variation("HeaderSmall"); middle_vbox_container->add_child(tile_data_editors_label); tile_data_editor_dropdown_button = memnew(Button); @@ -2381,6 +2383,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { // Atlas source inspector. atlas_source_inspector_label = memnew(Label); atlas_source_inspector_label->set_text(TTR("Atlas Properties:")); + atlas_source_inspector_label->set_theme_type_variation("HeaderSmall"); middle_vbox_container->add_child(atlas_source_inspector_label); atlas_source_proxy_object = memnew(TileSetAtlasSourceProxyObject()); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 3491f8a468..8c72a886ea 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5645,48 +5645,6 @@ VisualShaderEditor::VisualShaderEditor() { property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); } -///////////////// - -void VisualShaderEditorPlugin::edit(Object *p_object) { - visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object)); -} - -bool VisualShaderEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("VisualShader"); -} - -void VisualShaderEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - //editor->hide_animation_player_editors(); - //editor->animation_panel_make_visible(true); - button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(visual_shader_editor); - visual_shader_editor->update_nodes(); - visual_shader_editor->set_process_input(true); - //visual_shader_editor->set_process(true); - } else { - if (visual_shader_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); - } - button->hide(); - visual_shader_editor->set_process_input(false); - //visual_shader_editor->set_process(false); - } -} - -VisualShaderEditorPlugin::VisualShaderEditorPlugin() { - visual_shader_editor = memnew(VisualShaderEditor); - visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor); - button->hide(); -} - -VisualShaderEditorPlugin::~VisualShaderEditorPlugin() { -} - -//////////////// - class VisualShaderNodePluginInputEditor : public OptionButton { GDCLASS(VisualShaderNodePluginInputEditor, OptionButton); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 1b56892ebf..b8da266ed7 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -493,23 +493,6 @@ public: VisualShaderEditor(); }; -class VisualShaderEditorPlugin : public EditorPlugin { - GDCLASS(VisualShaderEditorPlugin, EditorPlugin); - - VisualShaderEditor *visual_shader_editor = nullptr; - Button *button = nullptr; - -public: - virtual String get_name() const override { return "VisualShader"; } - bool has_main_screen() const override { return false; } - virtual void edit(Object *p_object) override; - virtual bool handles(Object *p_object) const override; - virtual void make_visible(bool p_visible) override; - - VisualShaderEditorPlugin(); - ~VisualShaderEditorPlugin(); -}; - class VisualShaderNodePluginDefault : public VisualShaderNodePlugin { GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 404199d2da..1524993bd0 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -35,6 +35,7 @@ #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "servers/movie_writer/movie_writer.h" ProjectSettingsEditor *ProjectSettingsEditor::singleton = nullptr; @@ -261,6 +262,7 @@ void ProjectSettingsEditor::_add_feature_overrides() { presets.insert("standalone"); presets.insert("32"); presets.insert("64"); + presets.insert("movie"); EditorExport *ee = EditorExport::get_singleton(); @@ -698,4 +700,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { import_defaults_editor->set_name(TTR("Import Defaults")); tab_container->add_child(import_defaults_editor); import_defaults_editor->connect("project_settings_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); + + MovieWriter::set_extensions_hint(); // ensure extensions are properly displayed. } diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index 53da945868..4938699fc4 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -146,8 +146,8 @@ void EditorQuickOpen::_confirmed() { return; } _cleanup(); - emit_signal(SNAME("quick_open")); hide(); + emit_signal(SNAME("quick_open")); } void EditorQuickOpen::cancel_pressed() { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 08df4cdf3c..2e1090e6c0 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2418,8 +2418,8 @@ void SceneTreeDock::_new_scene_from(String p_file) { Node *copy = base->duplicate_from_editor(duplimap); if (copy) { - for (int i = 0; i < copy->get_child_count(); i++) { - _set_node_owner_recursive(copy->get_child(i), copy); + for (int i = 0; i < copy->get_child_count(false); i++) { + _set_node_owner_recursive(copy->get_child(i, false), copy); } Ref<PackedScene> sdata = memnew(PackedScene); @@ -2456,8 +2456,8 @@ void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner) { p_node->set_owner(p_owner); } - for (int i = 0; i < p_node->get_child_count(); i++) { - _set_node_owner_recursive(p_node->get_child(i), p_owner); + for (int i = 0; i < p_node->get_child_count(false); i++) { + _set_node_owner_recursive(p_node->get_child(i, false), p_owner); } } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 5536e09da7..86fa9222c0 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -1353,8 +1353,9 @@ void SceneTreeDialog::_cancel() { void SceneTreeDialog::_select() { if (tree->get_selected()) { - emit_signal(SNAME("selected"), tree->get_selected()->get_path()); + // The signal may cause another dialog to be displayed, so be sure to hide this one first. hide(); + emit_signal(SNAME("selected"), tree->get_selected()->get_path()); } } |