From 48a64768616078f9a6a676e8d2ce7867702675f5 Mon Sep 17 00:00:00 2001 From: ajreckof Date: Sun, 14 Apr 2024 12:56:49 +0200 Subject: [PATCH] Fix going forward backward in editor selection history. --- editor/editor_node.cpp | 14 +++++++++++--- editor/multi_node_edit.cpp | 2 +- editor/multi_node_edit.h | 15 ++++++++++++++- editor/scene_tree_dock.cpp | 7 +++++++ editor/scene_tree_dock.h | 1 + 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4fb1a86ce201..f74ccdcd620e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2355,7 +2355,13 @@ static bool overrides_external_editor(Object *p_object) { void EditorNode::_add_to_history(const Object *p_object, const String &p_property, bool p_inspector_only) { ObjectID id = p_object->get_instance_id(); - if (id != editor_history.get_current()) { + ObjectID history_id = editor_history.get_current(); + if (id != history_id) { + const MultiNodeEdit *multi_node_edit = Object::cast_to(p_object); + const MultiNodeEdit *history_multi_node_edit = Object::cast_to(ObjectDB::get_instance(history_id)); + if (multi_node_edit && history_multi_node_edit && multi_node_edit->is_same_selection(history_multi_node_edit)) { + return; + } if (p_inspector_only) { editor_history.add_object(id, String(), true); } else if (p_property.is_empty()) { @@ -2449,6 +2455,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update if (current_node->is_inside_tree()) { NodeDock::get_singleton()->set_node(current_node); SceneTreeDock::get_singleton()->set_selected(current_node); + SceneTreeDock::get_singleton()->set_selection({ current_node }); InspectorDock::get_singleton()->update(current_node); if (!inspector_only && !skip_main_plugin) { skip_main_plugin = stay_in_script_editor_on_node_selected && !ScriptEditor::get_singleton()->is_editor_floating() && ScriptEditor::get_singleton()->is_visible_in_tree(); @@ -2470,13 +2477,13 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update } else { Node *selected_node = nullptr; + Vector multi_nodes; if (current_obj->is_class("MultiNodeEdit")) { Node *scene = get_edited_scene(); if (scene) { MultiNodeEdit *multi_node_edit = Object::cast_to(current_obj); int node_count = multi_node_edit->get_node_count(); if (node_count > 0) { - List multi_nodes; for (int node_index = 0; node_index < node_count; ++node_index) { Node *node = scene->get_node(multi_node_edit->get_node(node_index)); if (node) { @@ -2486,7 +2493,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update if (!multi_nodes.is_empty()) { // Pick the top-most node. multi_nodes.sort_custom(); - selected_node = multi_nodes.front()->get(); + selected_node = multi_nodes[0]; } } } @@ -2495,6 +2502,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update InspectorDock::get_inspector_singleton()->edit(current_obj); NodeDock::get_singleton()->set_node(nullptr); SceneTreeDock::get_singleton()->set_selected(selected_node); + SceneTreeDock::get_singleton()->set_selection(multi_nodes); InspectorDock::get_singleton()->update(nullptr); } diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index 4f0db70681fe..45786c0ab5e2 100644 --- a/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp @@ -244,7 +244,7 @@ int MultiNodeEdit::get_node_count() const { } NodePath MultiNodeEdit::get_node(int p_index) const { - ERR_FAIL_INDEX_V(p_index, nodes.size(), NodePath()); + ERR_FAIL_INDEX_V(p_index, get_node_count(), NodePath()); return nodes[p_index]; } diff --git a/editor/multi_node_edit.h b/editor/multi_node_edit.h index deef88633ed9..000d41c4c1fe 100644 --- a/editor/multi_node_edit.h +++ b/editor/multi_node_edit.h @@ -36,7 +36,7 @@ class MultiNodeEdit : public RefCounted { GDCLASS(MultiNodeEdit, RefCounted); - List nodes; + LocalVector nodes; struct PLData { int uses = 0; PropertyInfo info; @@ -67,6 +67,19 @@ public: void set_property_field(const StringName &p_property, const Variant &p_value, const String &p_field); + // If the nodes selected are the same independently of order then return true. + bool is_same_selection(const MultiNodeEdit *p_other) const { + if (get_node_count() != p_other->get_node_count()) { + return false; + } + for (int i = 0; i < get_node_count(); i++) { + if (nodes.find(p_other->get_node(i)) == -1) { + return false; + } + } + + return true; + } MultiNodeEdit(); }; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 0b489cbb363c..e1084d48738d 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -3020,6 +3020,13 @@ void SceneTreeDock::set_edited_scene(Node *p_scene) { edited_scene = p_scene; } +void SceneTreeDock::set_selection(const Vector &p_nodes) { + editor_selection->clear(); + for (Node *node : p_nodes) { + editor_selection->add_node(node); + } +} + void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) { scene_tree->set_selected(p_node, p_emit_selected); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 86e9ff8a475c..21e1b00f931d 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -322,6 +322,7 @@ public: void set_edited_scene(Node *p_scene); void instantiate(const String &p_file); void instantiate_scenes(const Vector &p_files, Node *p_parent = nullptr); + void set_selection(const Vector &p_nodes); void set_selected(Node *p_node, bool p_emit_selected = false); void fill_path_renames(Node *p_node, Node *p_new_parent, HashMap *p_renames); void perform_node_renames(Node *p_base, HashMap *p_renames, HashMap, HashSet> *r_rem_anims = nullptr);