diff options
Diffstat (limited to 'editor')
34 files changed, 290 insertions, 82 deletions
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 1d3c7aec3f..2f7183b883 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -314,12 +314,18 @@ void EditorDebuggerNode::stop(bool p_force) { void EditorDebuggerNode::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - if (tabs->get_tab_count() > 1 && EditorThemeManager::is_generated_theme_outdated()) { + if (!EditorThemeManager::is_generated_theme_outdated()) { + return; + } + + if (tabs->get_tab_count() > 1) { add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT)); add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT)); tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles))); } + + remote_scene_tree->update_icon_max_width(); } break; case NOTIFICATION_READY: { diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 63053d2574..12b590da3c 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -31,6 +31,7 @@ #include "editor_debugger_tree.h" #include "editor/editor_node.h" +#include "editor/editor_string_names.h" #include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" #include "scene/debugger/scene_debugger.h" @@ -62,6 +63,10 @@ void EditorDebuggerTree::_notification(int p_what) { connect("item_collapsed", callable_mp(this, &EditorDebuggerTree::_scene_tree_folded)); connect("item_mouse_selected", callable_mp(this, &EditorDebuggerTree::_scene_tree_rmb_selected)); } break; + + case NOTIFICATION_ENTER_TREE: { + update_icon_max_width(); + } break; } } @@ -293,6 +298,10 @@ Variant EditorDebuggerTree::get_drag_data(const Point2 &p_point) { return vformat("\"%s\"", path); } +void EditorDebuggerTree::update_icon_max_width() { + add_theme_constant_override("icon_max_width", get_theme_constant("class_icon_size", EditorStringName(Editor))); +} + String EditorDebuggerTree::get_selected_path() { if (!get_selected()) { return ""; diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 895f33f1a2..dbffb0f219 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -72,6 +72,7 @@ public: virtual Variant get_drag_data(const Point2 &p_point) override; + void update_icon_max_width(); String get_selected_path(); ObjectID get_selected_object(); int get_current_debugger(); // Would love to have one tree for every debugger. diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 69cf13ea0b..0e2a7ee599 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -34,6 +34,7 @@ #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/themes/editor_scale.h" +#include "editor/themes/editor_theme_manager.h" #include "scene/resources/image_texture.h" void EditorProfiler::_make_metric_ptrs(Metric &m) { @@ -423,6 +424,15 @@ void EditorProfiler::_notification(int p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { activate->set_icon(get_editor_theme_icon(SNAME("Play"))); clear_button->set_icon(get_editor_theme_icon(SNAME("Clear"))); + + theme_cache.seek_line_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor)); + theme_cache.seek_line_color.a = 0.8; + theme_cache.seek_line_hover_color = theme_cache.seek_line_color; + theme_cache.seek_line_hover_color.a = 0.4; + + if (total_metrics > 0) { + _update_plot(); + } } break; } } @@ -434,11 +444,11 @@ void EditorProfiler::_graph_tex_draw() { if (seeking) { int frame = cursor_metric_edit->get_value() - _get_frame_metric(0).frame_number; int cur_x = (2 * frame + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1; - graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.8)); + graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), theme_cache.seek_line_color); } if (hover_metric > -1 && hover_metric < total_metrics) { int cur_x = (2 * hover_metric + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1; - graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.4)); + graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), theme_cache.seek_line_hover_color); } } diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h index 620d21fe98..64253070b1 100644 --- a/editor/debugger/editor_profiler.h +++ b/editor/debugger/editor_profiler.h @@ -94,6 +94,11 @@ public: }; private: + struct ThemeCache { + Color seek_line_color; + Color seek_line_hover_color; + } theme_cache; + Button *activate = nullptr; Button *clear_button = nullptr; TextureRect *graph = nullptr; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 9884241708..48c0c7ac06 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -2890,7 +2890,7 @@ void EditorHelp::_load_doc_thread(void *p_udata) { callable_mp_static(&EditorHelp::_gen_extensions_docs).call_deferred(); } else { // We have to go back to the main thread to start from scratch, bypassing any possibly existing cache. - callable_mp_static(&EditorHelp::generate_doc).bind(false).call_deferred(); + callable_mp_static(&EditorHelp::generate_doc).call_deferred(false); } OS::get_singleton()->benchmark_end_measure("EditorHelp", vformat("Generate Documentation (Run %d)", doc_generation_count)); diff --git a/editor/editor_inspector.compat.inc b/editor/editor_inspector.compat.inc new file mode 100644 index 0000000000..53c410ba26 --- /dev/null +++ b/editor/editor_inspector.compat.inc @@ -0,0 +1,41 @@ +/**************************************************************************/ +/* editor_inspector.compat.inc */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef DISABLE_DEPRECATED + +void EditorInspectorPlugin::_add_property_editor_bind_compat_92322(const String &p_for_property, Control *p_prop, bool p_add_to_end) { + add_property_editor(p_for_property, p_prop, p_add_to_end, ""); +} + +void EditorInspectorPlugin::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("add_property_editor", "property", "editor", "add_to_end"), &EditorInspectorPlugin::_add_property_editor_bind_compat_92322, DEFVAL(false)); +} + +#endif // DISABLE_DEPRECATED diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 7c5e3877f2..f4dcc8bd4a 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -29,6 +29,7 @@ /**************************************************************************/ #include "editor_inspector.h" +#include "editor_inspector.compat.inc" #include "core/os/keyboard.h" #include "editor/doc_tools.h" @@ -1128,11 +1129,12 @@ void EditorInspectorPlugin::add_custom_control(Control *control) { added_editors.push_back(ae); } -void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Control *p_prop, bool p_add_to_end) { +void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Control *p_prop, bool p_add_to_end, const String &p_label) { AddedEditor ae; ae.properties.push_back(p_for_property); ae.property_editor = p_prop; ae.add_to_end = p_add_to_end; + ae.label = p_label; added_editors.push_back(ae); } @@ -1174,7 +1176,7 @@ void EditorInspectorPlugin::parse_end(Object *p_object) { void EditorInspectorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("add_custom_control", "control"), &EditorInspectorPlugin::add_custom_control); - ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor", "add_to_end"), &EditorInspectorPlugin::add_property_editor, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor", "add_to_end", "label"), &EditorInspectorPlugin::add_property_editor, DEFVAL(false), DEFVAL(String())); ClassDB::bind_method(D_METHOD("add_property_editor_for_multiple_properties", "label", "properties", "editor"), &EditorInspectorPlugin::add_property_editor_for_multiple_properties); GDVIRTUAL_BIND(_can_handle, "object") @@ -3782,7 +3784,6 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo } emit_signal(_prop_edited, p_name); - } else if (Object::cast_to<MultiNodeEdit>(object)) { Object::cast_to<MultiNodeEdit>(object)->set_property_field(p_name, p_value, p_changed_field); _edit_request_change(object, p_name); @@ -3959,7 +3960,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { //property checked if (autoclear) { if (!p_checked) { - object->set(p_path, Variant()); + _edit_set(p_path, Variant(), false, ""); } else { Variant to_create; List<PropertyInfo> pinfo; @@ -3971,7 +3972,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { break; } } - object->set(p_path, to_create); + _edit_set(p_path, to_create, false, ""); } if (editor_property_map.has(p_path)) { @@ -3982,7 +3983,6 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { E->update_cache(); } } - } else { emit_signal(SNAME("property_toggled"), p_path, p_checked); } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 3cbee5c502..a0ced55bd8 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -252,9 +252,13 @@ protected: GDVIRTUAL7R(bool, _parse_property, Object *, Variant::Type, String, PropertyHint, String, BitField<PropertyUsageFlags>, bool) GDVIRTUAL1(_parse_end, Object *) +#ifndef DISABLE_DEPRECATED + void _add_property_editor_bind_compat_92322(const String &p_for_property, Control *p_prop, bool p_add_to_end); + static void _bind_compatibility_methods(); +#endif // DISABLE_DEPRECATED public: void add_custom_control(Control *control); - void add_property_editor(const String &p_for_property, Control *p_prop, bool p_add_to_end = false); + void add_property_editor(const String &p_for_property, Control *p_prop, bool p_add_to_end = false, const String &p_label = String()); void add_property_editor_for_multiple_properties(const String &p_label, const Vector<String> &p_properties, Control *p_prop); virtual bool can_handle(Object *p_object); @@ -344,7 +348,7 @@ class EditorInspectorArray : public EditorInspectorSection { MODE_NONE, MODE_USE_COUNT_PROPERTY, MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION, - } mode; + } mode = MODE_NONE; StringName count_property; StringName array_element_prefix; String swap_method; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 6615133dea..166d09af30 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -59,7 +59,7 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f MessageType message_type = p_type == ERR_HANDLER_WARNING ? MSG_TYPE_WARNING : MSG_TYPE_ERROR; if (self->current != Thread::get_caller_id()) { - callable_mp(self, &EditorLog::add_message).bind(err_str, message_type).call_deferred(); + callable_mp(self, &EditorLog::add_message).call_deferred(err_str, message_type); } else { self->add_message(err_str, message_type); } @@ -273,6 +273,10 @@ void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) { } void EditorLog::_rebuild_log() { + if (messages.is_empty()) { + return; + } + log->clear(); int line_count = 0; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 581294d677..6599a58da4 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -671,7 +671,7 @@ void EditorNode::_notification(int p_what) { callable_mp(this, &EditorNode::_begin_first_scan).call_deferred(); - DisplayServer::get_singleton()->set_system_theme_change_callback(callable_mp(this, &EditorNode::_update_theme)); + DisplayServer::get_singleton()->set_system_theme_change_callback(callable_mp(this, &EditorNode::_update_theme).bind(false)); /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -5541,7 +5541,7 @@ void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, Str } void EditorNode::_file_access_close_error_notify(const String &p_str) { - callable_mp_static(&EditorNode::_file_access_close_error_notify_impl).bind(p_str).call_deferred(); + callable_mp_static(&EditorNode::_file_access_close_error_notify_impl).call_deferred(p_str); } void EditorNode::_file_access_close_error_notify_impl(const String &p_str) { @@ -6163,7 +6163,7 @@ static Node *_resource_get_edited_scene() { } void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich) { - callable_mp_static(&EditorNode::_print_handler_impl).bind(p_string, p_error, p_rich).call_deferred(); + callable_mp_static(&EditorNode::_print_handler_impl).call_deferred(p_string, p_error, p_rich); } void EditorNode::_print_handler_impl(const String &p_string, bool p_error, bool p_rich) { @@ -6302,6 +6302,9 @@ EditorNode::EditorNode() { ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | Key::G); ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::G); + // Used in the GPUParticles/CPUParticles 2D/3D editor plugins. + ED_SHORTCUT("particles/restart_emission", TTR("Restart Emission"), KeyModifierMask::CTRL | Key::R); + FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); _update_vsync_mode(); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 49b30bd06e..103ea3ffc3 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2645,7 +2645,7 @@ void EditorPropertyColor::_color_changed(const Color &p_color) { } void EditorPropertyColor::_popup_closed() { - get_edited_object()->set(get_edited_property(), last_color); + get_edited_object()->set(get_edited_property(), was_checked ? Variant(last_color) : Variant()); if (!picker->get_pick_color().is_equal_approx(last_color)) { emit_changed(get_edited_property(), picker->get_pick_color(), "", false); } @@ -2653,6 +2653,7 @@ void EditorPropertyColor::_popup_closed() { void EditorPropertyColor::_picker_opening() { last_color = picker->get_pick_color(); + was_checked = !is_checkable() || is_checked(); } void EditorPropertyColor::_notification(int p_what) { @@ -3217,7 +3218,7 @@ void EditorPropertyResource::_open_editor_pressed() { Ref<Resource> res = get_edited_property_value(); if (res.is_valid()) { // May clear the editor so do it deferred. - callable_mp(EditorNode::get_singleton(), &EditorNode::edit_item).bind(res.ptr(), this).call_deferred(); + callable_mp(EditorNode::get_singleton(), &EditorNode::edit_item).call_deferred(res.ptr(), this); } } diff --git a/editor/editor_properties.h b/editor/editor_properties.h index d16c80bfc4..f2c5497e4f 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -625,6 +625,7 @@ class EditorPropertyColor : public EditorProperty { Color last_color; bool live_changes_enabled = true; + bool was_checked = false; protected: virtual void _set_read_only(bool p_read_only) override; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index ca1070d7f3..b4fc47323a 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -960,6 +960,7 @@ void EditorPropertyDictionary::update_property() { memdelete(container); button_add_item = nullptr; container = nullptr; + add_panel = nullptr; slots.clear(); } return; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 5f311ae445..2e88540fc4 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -3279,7 +3279,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, const Vect if (p_paths.size() == 1) { const String &fpath = p_paths[0]; - bool added_separator = false; + [[maybe_unused]] bool added_separator = false; if (favorites_list.has(fpath)) { TreeItem *favorites_item = tree->get_root()->get_first_child(); diff --git a/editor/gui/editor_toaster.cpp b/editor/gui/editor_toaster.cpp index 7aa5335b77..df6c494392 100644 --- a/editor/gui/editor_toaster.cpp +++ b/editor/gui/editor_toaster.cpp @@ -149,7 +149,7 @@ void EditorToaster::_notification(int p_what) { void EditorToaster::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { // This may be called from a thread. Since we will deal with non-thread-safe elements, // we have to put it in the queue for safety. - callable_mp_static(&EditorToaster::_error_handler_impl).bind(String::utf8(p_file), p_line, String::utf8(p_error), String::utf8(p_errorexp), p_editor_notify, p_type).call_deferred(); + callable_mp_static(&EditorToaster::_error_handler_impl).call_deferred(String::utf8(p_file), p_line, String::utf8(p_error), String::utf8(p_errorexp), p_editor_notify, p_type); } void EditorToaster::_error_handler_impl(const String &p_file, int p_line, const String &p_error, const String &p_errorexp, bool p_editor_notify, int p_type) { diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index fa0dad41dc..ddf22c46e6 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -614,9 +614,9 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { updating_tree = true; tree->clear(); + last_hash = hash_djb2_one_64(0); if (get_scene_node()) { _add_nodes(get_scene_node(), nullptr); - last_hash = hash_djb2_one_64(0); _compute_hash(get_scene_node(), last_hash); } updating_tree = false; diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index 23c22a8049..c0d38af26a 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -279,7 +279,7 @@ bool ResourceImporterScene::get_option_visibility(const String &p_path, const St } } - if (animation_importer && (p_option.begins_with("nodes/") || p_option.begins_with("meshes/") || p_option.begins_with("skins/"))) { + if (animation_importer && (p_option == "nodes/root_type" || p_option == "nodes/root_name" || p_option.begins_with("meshes/") || p_option.begins_with("skins/"))) { return false; // Nothing to do here for animations. } diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp index bde2e3d0bf..6b20a8c9d5 100644 --- a/editor/import/resource_importer_shader_file.cpp +++ b/editor/import/resource_importer_shader_file.cpp @@ -106,7 +106,7 @@ Error ResourceImporterShaderFile::import(const String &p_source_file, const Stri if (err != OK) { if (!ShaderFileEditor::singleton->is_visible_in_tree()) { - callable_mp_static(&EditorNode::add_io_error).bind(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file)).call_deferred(); + callable_mp_static(&EditorNode::add_io_error).call_deferred(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file)); } } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1366a38bec..62369cc2c1 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1711,7 +1711,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2_step_prepare(int p_step_offs OS::get_singleton()->get_main_loop()->process(0); // This is the key: process the frame and let all callbacks/updates/notifications happen // so everything (transforms, skeletons, etc.) is up-to-date visually. - callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_2_step_capture).bind(p_step_offset, p_capture_idx).call_deferred(); + callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_2_step_capture).call_deferred(p_step_offset, p_capture_idx); return; } else { next_capture_idx++; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index ee96de8f23..8b44d6b486 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5638,7 +5638,7 @@ CanvasItemEditor::CanvasItemEditor() { clear(); // Make sure values are initialized. // Update the menus' checkboxes. - callable_mp(this, &CanvasItemEditor::set_state).bind(get_state()).call_deferred(); + callable_mp(this, &CanvasItemEditor::set_state).call_deferred(get_state()); } CanvasItemEditor *CanvasItemEditor::singleton = nullptr; diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index dfc8323fc0..1d53a1b4d4 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "canvas_item_editor_plugin.h" #include "core/io/image_loader.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" @@ -268,7 +269,7 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() { toolbar->hide(); menu = memnew(MenuButton); - menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART); + menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("particles/restart_emission"), MENU_RESTART); menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK); menu->get_popup()->add_item(TTR("Convert to GPUParticles2D"), MENU_CONVERT_TO_GPU_PARTICLES); menu->set_text(TTR("CPUParticles2D")); diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp index b5e3f102cf..baf70e45f0 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "cpu_particles_3d_editor_plugin.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/gui/scene_tree_editor.h" #include "editor/plugins/node_3d_editor_plugin.h" @@ -168,7 +169,7 @@ CPUParticles3DEditor::CPUParticles3DEditor() { particles_editor_hb->hide(); options->set_text(TTR("CPUParticles3D")); - options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART); + options->get_popup()->add_shortcut(ED_GET_SHORTCUT("particles/restart_emission"), MENU_OPTION_RESTART); options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB); options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); options->get_popup()->add_item(TTR("Convert to GPUParticles3D"), MENU_OPTION_CONVERT_TO_GPU_PARTICLES); diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index e9f1b07c34..328b272562 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "canvas_item_editor_plugin.h" #include "core/io/image_loader.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" @@ -370,7 +371,7 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() { toolbar->hide(); menu = memnew(MenuButton); - menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART); + menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("particles/restart_emission"), MENU_RESTART); menu->get_popup()->add_item(TTR("Generate Visibility Rect"), MENU_GENERATE_VISIBILITY_RECT); menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK); // menu->get_popup()->add_item(TTR("Clear Emission Mask"), MENU_CLEAR_EMISSION_MASK); diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 04b0a8aa26..9063109ece 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "core/io/resource_loader.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/scene_tree_dock.h" @@ -414,7 +415,7 @@ GPUParticles3DEditor::GPUParticles3DEditor() { particles_editor_hb->hide(); options->set_text(TTR("GPUParticles3D")); - options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART); + options->get_popup()->add_shortcut(ED_GET_SHORTCUT("particles/restart_emission"), MENU_OPTION_RESTART); options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB); options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); options->get_popup()->add_item(TTR("Convert to CPUParticles3D"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index e9e5b2294f..69b66cd7b2 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -739,9 +739,21 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { return; } + Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); + + // Prevent selection of nodes not owned by the edited scene. + while (node && node != edited_scene->get_parent()) { + Node *node_owner = node->get_owner(); + if (node_owner == edited_scene || node == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) { + break; + } + node = node->get_parent(); + selected = Object::cast_to<Node3D>(node); + } + if (!p_allow_locked) { // Replace the node by the group if grouped - while (node && node != EditorNode::get_singleton()->get_edited_scene()->get_parent()) { + while (node && node != edited_scene->get_parent()) { Node3D *selected_tmp = Object::cast_to<Node3D>(node); if (selected_tmp && node->has_meta("_edit_group_")) { selected = selected_tmp; @@ -1044,25 +1056,34 @@ void Node3DEditorViewport::_select_region() { found_nodes.insert(sp); - Node *item = Object::cast_to<Node>(sp); - if (item != edited_scene) { - item = edited_scene->get_deepest_editable_node(item); + Node *node = Object::cast_to<Node>(sp); + if (node != edited_scene) { + node = edited_scene->get_deepest_editable_node(node); + } + + // Prevent selection of nodes not owned by the edited scene. + while (node && node != edited_scene->get_parent()) { + Node *node_owner = node->get_owner(); + if (node_owner == edited_scene || node == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) { + break; + } + node = node->get_parent(); } // Replace the node by the group if grouped - if (item->is_class("Node3D")) { - Node3D *sel = Object::cast_to<Node3D>(item); - while (item && item != EditorNode::get_singleton()->get_edited_scene()->get_parent()) { - Node3D *selected_tmp = Object::cast_to<Node3D>(item); - if (selected_tmp && item->has_meta("_edit_group_")) { + if (node->is_class("Node3D")) { + Node3D *sel = Object::cast_to<Node3D>(node); + while (node && node != EditorNode::get_singleton()->get_edited_scene()->get_parent()) { + Node3D *selected_tmp = Object::cast_to<Node3D>(node); + if (selected_tmp && node->has_meta("_edit_group_")) { sel = selected_tmp; } - item = item->get_parent(); + node = node->get_parent(); } - item = sel; + node = sel; } - if (_is_node_locked(item)) { + if (_is_node_locked(node)) { continue; } @@ -1074,7 +1095,7 @@ void Node3DEditorViewport::_select_region() { } if (seg->intersect_frustum(camera, frustum)) { - selected.push_back(item); + selected.push_back(node); } } } @@ -1531,23 +1552,35 @@ bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) { } void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { - _find_items_at_pos(b->get_position(), selection_results, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); + Vector<_RayResult> potential_selection_results; + _find_items_at_pos(b->get_position(), potential_selection_results, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); - Node *scene = EditorNode::get_singleton()->get_edited_scene(); + Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); - for (int i = 0; i < selection_results.size(); i++) { - Node3D *item = selection_results[i].item; - if (item != scene && item->get_owner() != scene && item != scene->get_deepest_editable_node(item)) { - //invalid result - selection_results.remove_at(i); - i--; + // Filter to a list of nodes which include either the edited scene or nodes directly owned by the edited scene. + // If a node has an invalid owner, recursively check their parents until a valid node is found. + for (int i = 0; i < potential_selection_results.size(); i++) { + Node3D *node = potential_selection_results[i].item; + while (true) { + if (node == nullptr || node == edited_scene->get_parent()) { + break; + } else { + Node *node_owner = node->get_owner(); + if (node == edited_scene || node_owner == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) { + if (selection_results.has(node)) { + selection_results.append(node); + } + break; + } + } + node = Object::cast_to<Node3D>(node->get_parent()); } } clicked_wants_append = b->is_shift_pressed(); if (selection_results.size() == 1) { - clicked = selection_results[0].item->get_instance_id(); + clicked = selection_results[0]->get_instance_id(); selection_results.clear(); if (clicked.is_valid()) { @@ -1558,7 +1591,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { StringName root_name = root_path.get_name(root_path.get_name_count() - 1); for (int i = 0; i < selection_results.size(); i++) { - Node3D *spat = selection_results[i].item; + Node3D *spat = selection_results[i]; Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(spat, "Node"); @@ -2901,10 +2934,8 @@ void Node3DEditorViewport::_notification(int p_what) { // FPS Counter. bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME)); - if (show_fps != fps_label->is_visible()) { - cpu_time_label->set_visible(show_fps); - gpu_time_label->set_visible(show_fps); - fps_label->set_visible(show_fps); + if (show_fps != frame_time_panel->is_visible()) { + frame_time_panel->set_visible(show_fps); RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps); for (int i = 0; i < FRAME_TIME_HISTORY; i++) { // Initialize to 120 FPS, so that the initial estimation until we get enough data is always reasonable. @@ -3033,9 +3064,15 @@ void Node3DEditorViewport::_notification(int p_what) { frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), EditorStringName(Editor))); info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); - cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); - gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); - fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); + + frame_time_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); + // Set a minimum width to prevent the width from changing all the time + // when numbers vary rapidly. This minimum width is set based on a + // GPU time of 999.99 ms in the current editor language. + const float min_width = get_theme_font(SNAME("main"), EditorStringName(EditorFonts))->get_string_size(vformat(TTR("GPU Time: %s ms"), 999.99)).x; + frame_time_panel->set_custom_minimum_size(Size2(min_width, 0) * EDSCALE); + frame_time_vbox->add_theme_constant_override("separation", Math::round(-1 * EDSCALE)); + cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles))); } break; @@ -3750,7 +3787,7 @@ void Node3DEditorViewport::_selection_result_pressed(int p_result) { return; } - clicked = selection_results_menu[p_result].item->get_instance_id(); + clicked = selection_results_menu[p_result]->get_instance_id(); if (clicked.is_valid()) { _select_clicked(spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); @@ -5379,10 +5416,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p top_right_vbox = memnew(VBoxContainer); top_right_vbox->set_anchors_and_offsets_preset(PRESET_TOP_RIGHT, PRESET_MODE_MINSIZE, 10.0 * EDSCALE); top_right_vbox->set_h_grow_direction(GROW_DIRECTION_BEGIN); - // Make sure frame time labels don't touch the viewport's edge. - top_right_vbox->set_custom_minimum_size(Size2(100, 0) * EDSCALE); - // Prevent visible spacing between frame time labels. - top_right_vbox->add_theme_constant_override("separation", 0); const int navigation_control_size = 150; @@ -5414,18 +5447,22 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p rotation_control->set_viewport(this); top_right_vbox->add_child(rotation_control); + frame_time_panel = memnew(PanelContainer); + top_right_vbox->add_child(frame_time_panel); + frame_time_panel->hide(); + + frame_time_vbox = memnew(VBoxContainer); + frame_time_panel->add_child(frame_time_vbox); + // Individual Labels are used to allow coloring each label with its own color. cpu_time_label = memnew(Label); - top_right_vbox->add_child(cpu_time_label); - cpu_time_label->hide(); + frame_time_vbox->add_child(cpu_time_label); gpu_time_label = memnew(Label); - top_right_vbox->add_child(gpu_time_label); - gpu_time_label->hide(); + frame_time_vbox->add_child(gpu_time_label); fps_label = memnew(Label); - top_right_vbox->add_child(fps_label); - fps_label->hide(); + frame_time_vbox->add_child(fps_label); surface->add_child(top_right_vbox); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 4990b11a47..859d075732 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -255,6 +255,8 @@ private: ViewportNavigationControl *look_control = nullptr; ViewportRotationControl *rotation_control = nullptr; Gradient *frame_time_gradient = nullptr; + PanelContainer *frame_time_panel = nullptr; + VBoxContainer *frame_time_vbox = nullptr; Label *cpu_time_label = nullptr; Label *gpu_time_label = nullptr; Label *fps_label = nullptr; @@ -296,8 +298,8 @@ private: ObjectID clicked; ObjectID material_target; - Vector<_RayResult> selection_results; - Vector<_RayResult> selection_results_menu; + Vector<Node3D *> selection_results; + Vector<Node3D *> selection_results_menu; bool clicked_wants_append = false; bool selection_in_progress = false; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 56f8e1173f..c14336418c 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -2181,6 +2181,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_h->set_min(1); split_sheet_h->set_max(128); split_sheet_h->set_step(1); + split_sheet_h->set_select_all_on_focus(true); split_sheet_h_hb->add_child(split_sheet_h); split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); split_sheet_settings_vb->add_child(split_sheet_h_hb); @@ -2197,6 +2198,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_v->set_min(1); split_sheet_v->set_max(128); split_sheet_v->set_step(1); + split_sheet_v->set_select_all_on_focus(true); split_sheet_v_hb->add_child(split_sheet_v); split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); split_sheet_settings_vb->add_child(split_sheet_v_hb); @@ -2216,6 +2218,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_size_x->set_min(1); split_sheet_size_x->set_step(1); split_sheet_size_x->set_suffix("px"); + split_sheet_size_x->set_select_all_on_focus(true); split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); split_sheet_size_vb->add_child(split_sheet_size_x); split_sheet_size_y = memnew(SpinBox); @@ -2223,6 +2226,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_size_y->set_min(1); split_sheet_size_y->set_step(1); split_sheet_size_y->set_suffix("px"); + split_sheet_size_y->set_select_all_on_focus(true); split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); split_sheet_size_vb->add_child(split_sheet_size_y); split_sheet_size_hb->add_child(split_sheet_size_vb); @@ -2242,12 +2246,14 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_sep_x->set_min(0); split_sheet_sep_x->set_step(1); split_sheet_sep_x->set_suffix("px"); + split_sheet_sep_x->set_select_all_on_focus(true); split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_sep_vb->add_child(split_sheet_sep_x); split_sheet_sep_y = memnew(SpinBox); split_sheet_sep_y->set_min(0); split_sheet_sep_y->set_step(1); split_sheet_sep_y->set_suffix("px"); + split_sheet_sep_y->set_select_all_on_focus(true); split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_sep_vb->add_child(split_sheet_sep_y); split_sheet_sep_hb->add_child(split_sheet_sep_vb); @@ -2267,12 +2273,14 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_offset_x->set_min(0); split_sheet_offset_x->set_step(1); split_sheet_offset_x->set_suffix("px"); + split_sheet_offset_x->set_select_all_on_focus(true); split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_offset_vb->add_child(split_sheet_offset_x); split_sheet_offset_y = memnew(SpinBox); split_sheet_offset_y->set_min(0); split_sheet_offset_y->set_step(1); split_sheet_offset_y->set_suffix("px"); + split_sheet_offset_y->set_select_all_on_focus(true); split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); split_sheet_offset_vb->add_child(split_sheet_offset_y); split_sheet_offset_hb->add_child(split_sheet_offset_vb); diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp index bb74bf8d1f..d6cef3ccb9 100644 --- a/editor/plugins/text_shader_editor.cpp +++ b/editor/plugins/text_shader_editor.cpp @@ -30,12 +30,12 @@ #include "text_shader_editor.h" +#include "core/config/project_settings.h" #include "core/version_generated.gen.h" +#include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" -#include "editor/filesystem_dock.h" -#include "editor/project_settings_editor.h" #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme_manager.h" #include "scene/gui/split_container.h" @@ -735,6 +735,13 @@ void TextShaderEditor::_menu_option(int p_option) { } } +void TextShaderEditor::_prepare_edit_menu() { + const CodeEdit *tx = code_editor->get_text_editor(); + PopupMenu *popup = edit_menu->get_popup(); + popup->set_item_disabled(popup->get_item_index(EDIT_UNDO), !tx->has_undo()); + popup->set_item_disabled(popup->get_item_index(EDIT_REDO), !tx->has_redo()); +} + void TextShaderEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: @@ -1088,6 +1095,9 @@ void TextShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + context_menu->set_item_disabled(context_menu->get_item_index(EDIT_UNDO), !code_editor->get_text_editor()->has_undo()); + context_menu->set_item_disabled(context_menu->get_item_index(EDIT_REDO), !code_editor->get_text_editor()->has_redo()); + context_menu->set_position(get_screen_position() + p_position); context_menu->reset_size(); context_menu->popup(); @@ -1128,6 +1138,7 @@ TextShaderEditor::TextShaderEditor() { edit_menu->set_shortcut_context(this); edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); + edit_menu->connect("about_to_popup", callable_mp(this, &TextShaderEditor::_prepare_edit_menu)); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); diff --git a/editor/plugins/text_shader_editor.h b/editor/plugins/text_shader_editor.h index be16148744..6d2ac743b8 100644 --- a/editor/plugins/text_shader_editor.h +++ b/editor/plugins/text_shader_editor.h @@ -34,7 +34,6 @@ #include "editor/code_editor.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" -#include "scene/gui/panel_container.h" #include "scene/gui/rich_text_label.h" #include "servers/rendering/shader_warnings.h" @@ -153,6 +152,7 @@ class TextShaderEditor : public MarginContainer { bool compilation_success = true; void _menu_option(int p_option); + void _prepare_edit_menu(); mutable Ref<Shader> shader; mutable Ref<ShaderInclude> shader_inc; diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 2b86268414..52b58b74a3 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -59,6 +59,9 @@ void TileAtlasView::_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<In } Size2i TileAtlasView::_compute_base_tiles_control_size() { + if (tile_set_atlas_source.is_null()) { + return Size2i(); + } // Update the texture. Vector2i size; Ref<Texture2D> texture = tile_set_atlas_source->get_texture(); @@ -69,6 +72,9 @@ Size2i TileAtlasView::_compute_base_tiles_control_size() { } Size2i TileAtlasView::_compute_alternative_tiles_control_size() { + if (tile_set_atlas_source.is_null()) { + return Size2i(); + } Vector2i size; for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { Vector2i tile_id = tile_set_atlas_source->get_tile_id(i); @@ -89,6 +95,9 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() { } void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) { + if (tile_set_atlas_source.is_null()) { + return; + } float zoom = zoom_widget->get_zoom(); // Compute the minimum sizes. @@ -153,6 +162,9 @@ void TileAtlasView::_center_view() { } void TileAtlasView::_base_tiles_root_control_gui_input(const Ref<InputEvent> &p_event) { + if (tile_set_atlas_source.is_null()) { + return; + } base_tiles_root_control->set_tooltip_text(""); Ref<InputEventMouseMotion> mm = p_event; @@ -169,6 +181,9 @@ void TileAtlasView::_base_tiles_root_control_gui_input(const Ref<InputEvent> &p_ } void TileAtlasView::_draw_base_tiles() { + if (tile_set.is_null() || tile_set_atlas_source.is_null()) { + return; + } Ref<Texture2D> texture = tile_set_atlas_source->get_texture(); if (texture.is_valid()) { Vector2i margins = tile_set_atlas_source->get_margins(); @@ -314,6 +329,9 @@ void TileAtlasView::_clear_material_canvas_items() { } void TileAtlasView::_draw_base_tiles_texture_grid() { + if (tile_set_atlas_source.is_null()) { + return; + } Ref<Texture2D> texture = tile_set_atlas_source->get_texture(); if (texture.is_valid()) { Vector2i margins = tile_set_atlas_source->get_margins(); @@ -344,6 +362,9 @@ void TileAtlasView::_draw_base_tiles_texture_grid() { } void TileAtlasView::_draw_base_tiles_shape_grid() { + if (tile_set.is_null() || tile_set_atlas_source.is_null()) { + return; + } // Draw the shapes. Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Vector2i tile_shape_size = tile_set->get_tile_size(); @@ -382,6 +403,9 @@ void TileAtlasView::_alternative_tiles_root_control_gui_input(const Ref<InputEve } void TileAtlasView::_draw_alternatives() { + if (tile_set.is_null() || tile_set_atlas_source.is_null()) { + return; + } // Draw the alternative tiles. Ref<Texture2D> texture = tile_set_atlas_source->get_texture(); if (texture.is_valid()) { @@ -432,12 +456,12 @@ void TileAtlasView::_draw_background_right() { } void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id) { - tile_set = p_tile_set; - tile_set_atlas_source = p_tile_set_atlas_source; + tile_set = Ref<TileSet>(p_tile_set); + tile_set_atlas_source = Ref<TileSetAtlasSource>(p_tile_set_atlas_source); _clear_material_canvas_items(); - if (!tile_set) { + if (tile_set.is_null()) { return; } @@ -485,6 +509,10 @@ void TileAtlasView::set_padding(Side p_side, int p_padding) { } Vector2i TileAtlasView::get_atlas_tile_coords_at_pos(const Vector2 p_pos, bool p_clamp) const { + if (tile_set_atlas_source.is_null()) { + return Vector2i(); + } + Ref<Texture2D> texture = tile_set_atlas_source->get_texture(); if (!texture.is_valid()) { return TileSetSource::INVALID_ATLAS_COORDS; @@ -508,6 +536,10 @@ Vector2i TileAtlasView::get_atlas_tile_coords_at_pos(const Vector2 p_pos, bool p } void TileAtlasView::_update_alternative_tiles_rect_cache() { + if (tile_set_atlas_source.is_null()) { + return; + } + alternative_tiles_rect_cache.clear(); Rect2i current; diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index e5b4863b05..8fcf942056 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -45,8 +45,8 @@ class TileAtlasView : public Control { GDCLASS(TileAtlasView, Control); private: - TileSet *tile_set = nullptr; - TileSetAtlasSource *tile_set_atlas_source = nullptr; + Ref<TileSet> tile_set; + Ref<TileSetAtlasSource> tile_set_atlas_source; int source_id = TileSet::INVALID_SOURCE; enum DragType { diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 1daba1f665..03070bc6b5 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -2938,6 +2938,18 @@ bool EditorInspectorPluginTileData::parse_property(Object *p_object, const Varia add_property_editor(p_path, ep); return true; } + } else if (p_path.begins_with("custom_data_") && p_path.trim_prefix("custom_data_").is_valid_int()) { + // Custom data layers. + int layer_index = components[0].trim_prefix("custom_data_").to_int(); + ERR_FAIL_COND_V(layer_index < 0, false); + EditorProperty *ep = EditorInspectorDefaultPlugin::get_editor_for_property(p_object, p_type, p_path, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); + const TileSetAtlasSourceEditor::AtlasTileProxyObject *proxy_obj = Object::cast_to<TileSetAtlasSourceEditor::AtlasTileProxyObject>(p_object); + const TileSetAtlasSource *atlas_source = *proxy_obj->get_edited_tile_set_atlas_source(); + ERR_FAIL_NULL_V(atlas_source, false); + const TileSet *tile_set = atlas_source->get_tile_set(); + ERR_FAIL_NULL_V(tile_set, false); + add_property_editor(p_path, ep, false, tile_set->get_custom_data_layer_name(layer_index)); + return true; } return false; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ec0380f964..9209c26876 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -3104,7 +3104,23 @@ void SceneTreeDock::set_edited_scene(Node *p_scene) { edited_scene = p_scene; } +static bool _is_same_selection(const Vector<Node *> &p_first, const List<Node *> &p_second) { + if (p_first.size() != p_second.size()) { + return false; + } + for (Node *node : p_second) { + if (!p_first.has(node)) { + return false; + } + } + return true; +} + void SceneTreeDock::set_selection(const Vector<Node *> &p_nodes) { + // If the nodes selected are the same independently of order then return early. + if (_is_same_selection(p_nodes, editor_selection->get_full_selected_node_list())) { + return; + } editor_selection->clear(); for (Node *node : p_nodes) { editor_selection->add_node(node); @@ -3317,9 +3333,9 @@ void SceneTreeDock::_files_dropped(const Vector<String> &p_files, NodePath p_to, // Either instantiate scenes or create AudioStreamPlayers. int to_pos = -1; _normalize_drop(node, to_pos, p_type); - if (res_type == "PackedScene") { + if (ClassDB::is_parent_class(res_type, "PackedScene")) { _perform_instantiate_scenes(p_files, node, to_pos); - } else { + } else if (ClassDB::is_parent_class(res_type, "AudioStream")) { _perform_create_audio_stream_players(p_files, node, to_pos); } } |