From 9cd30208d6a89462d70bdd6f5bc97dd1119e05b0 Mon Sep 17 00:00:00 2001 From: RedMser Date: Sun, 26 Nov 2023 16:44:18 +0100 Subject: [PATCH] Improve SceneTreeEditor usability - Mark contextually relevant node - Remember/Clear selection as appropriate - Scroll to marked/selected node --- editor/animation_track_editor.cpp | 9 +++++-- editor/connections_dialog.cpp | 2 +- editor/editor_properties.cpp | 11 ++++++-- editor/gui/scene_tree_editor.cpp | 25 ++++++++++++++++++- editor/gui/scene_tree_editor.h | 6 ++--- .../cpu_particles_3d_editor_plugin.cpp | 1 - editor/plugins/multimesh_editor_plugin.cpp | 6 +++-- editor/reparent_dialog.cpp | 7 +----- .../multiplayer/editor/replication_editor.cpp | 2 +- 9 files changed, 50 insertions(+), 19 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 99ba35a6d0f9..bec95d40c6aa 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -5006,12 +5006,17 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { } void AnimationTrackEditor::_add_track(int p_type) { - if (!root) { + AnimationPlayer *ap = AnimationPlayerEditor::get_singleton()->get_player(); + if (!ap) { + ERR_FAIL_EDMSG("No AnimationPlayer is currently being edited."); + } + Node *root_node = ap->get_node_or_null(ap->get_root_node()); + if (!root_node) { EditorNode::get_singleton()->show_warning(TTR("Not possible to add a new track without a root")); return; } adding_track_type = p_type; - pick_track->popup_scenetree_dialog(); + pick_track->popup_scenetree_dialog(nullptr, root_node); pick_track->get_filter_line_edit()->clear(); pick_track->get_filter_line_edit()->grab_focus(); } diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 22a3326fc515..2db5b02d63be 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -616,7 +616,7 @@ void ConnectDialog::init(const ConnectionData &p_cd, const PackedStringArray &p_ signal_args = p_signal_args; tree->set_selected(nullptr); - tree->set_marked(source, true); + tree->set_marked(source); if (p_cd.target) { set_dst_node(static_cast(p_cd.target)); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index b7380c9fc2d9..c6a6163a4e04 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2751,7 +2751,15 @@ void EditorPropertyNodePath::_node_assign() { add_child(scene_tree); scene_tree->connect("selected", callable_mp(this, &EditorPropertyNodePath::_node_selected)); } - scene_tree->popup_scenetree_dialog(); + + Variant val = get_edited_property_value(); + Node *n = nullptr; + if (val.get_type() == Variant::Type::NODE_PATH) { + n = get_base_node()->get_node_or_null(val); + } else { + n = Object::cast_to(val); + } + scene_tree->popup_scenetree_dialog(n, get_base_node()); } void EditorPropertyNodePath::_update_menu() { @@ -3184,7 +3192,6 @@ void EditorPropertyResource::_resource_changed(const Ref &p_resource) add_child(scene_tree); scene_tree->connect("selected", callable_mp(this, &EditorPropertyResource::_viewport_selected)); } - scene_tree->popup_scenetree_dialog(); } } diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 835f95360392..0dd75ea03351 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -925,6 +925,27 @@ void SceneTreeEditor::_notification(int p_what) { _update_tree(); } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (is_visible()) { + TreeItem *item = nullptr; + if (selected) { + // Scroll to selected node. + item = _find(tree->get_root(), selected->get_path()); + } else if (marked.size() == 1) { + // Scroll to a single marked node. + Node *marked_node = *marked.begin(); + if (marked_node) { + item = _find(tree->get_root(), marked_node->get_path()); + } + } + + if (item) { + // Must wait until tree is properly sized before scrolling. + callable_mp(tree, &Tree::scroll_to_item).call_deferred(item, true); + } + } + } break; } } @@ -1567,7 +1588,9 @@ SceneTreeEditor::~SceneTreeEditor() { /******** DIALOG *********/ -void SceneTreeDialog::popup_scenetree_dialog() { +void SceneTreeDialog::popup_scenetree_dialog(Node *p_selected_node, Node *p_marked_node, bool p_marked_node_selectable, bool p_marked_node_children_selectable) { + get_scene_tree()->set_marked(p_marked_node, p_marked_node_selectable, p_marked_node_children_selectable); + get_scene_tree()->set_selected(p_selected_node); popup_centered_clamped(Size2(350, 700) * EDSCALE); } diff --git a/editor/gui/scene_tree_editor.h b/editor/gui/scene_tree_editor.h index a869e867b82d..c1abdcef8b0c 100644 --- a/editor/gui/scene_tree_editor.h +++ b/editor/gui/scene_tree_editor.h @@ -157,8 +157,8 @@ public: void set_as_scene_tree_dock(); void set_display_foreign_nodes(bool p_display); - void set_marked(const HashSet &p_marked, bool p_selectable = false, bool p_children_selectable = true); - void set_marked(Node *p_marked, bool p_selectable = false, bool p_children_selectable = true); + void set_marked(const HashSet &p_marked, bool p_selectable = true, bool p_children_selectable = true); + void set_marked(Node *p_marked, bool p_selectable = true, bool p_children_selectable = true); void set_selected(Node *p_node, bool p_emit_selected = true); Node *get_selected(); void set_can_rename(bool p_can_rename) { can_rename = p_can_rename; } @@ -201,7 +201,7 @@ protected: static void _bind_methods(); public: - void popup_scenetree_dialog(); + void popup_scenetree_dialog(Node *p_selected_node = nullptr, Node *p_marked_node = nullptr, bool p_marked_node_selectable = true, bool p_marked_node_children_selectable = true); void set_valid_types(const Vector &p_valid); SceneTreeEditor *get_scene_tree() { return tree; } diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp index bf427f733b1f..b5e3f102cf92 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp @@ -56,7 +56,6 @@ void CPUParticles3DEditor::_menu_option(int p_option) { switch (p_option) { case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { emission_tree_dialog->popup_scenetree_dialog(); - } break; case MENU_OPTION_RESTART: { diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 086abc0859ad..9fec263af3e8 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -255,13 +255,15 @@ void MultiMeshEditor::edit(MultiMeshInstance3D *p_multimesh) { void MultiMeshEditor::_browse(bool p_source) { browsing_source = p_source; - std->get_scene_tree()->set_marked(node, false); - std->popup_scenetree_dialog(); + Node *browsed_node = nullptr; if (p_source) { + browsed_node = node->get_node_or_null(mesh_source->get_text()); std->set_title(TTR("Select a Source Mesh:")); } else { + browsed_node = node->get_node_or_null(surface_source->get_text()); std->set_title(TTR("Select a Target Surface:")); } + std->popup_scenetree_dialog(browsed_node); } void MultiMeshEditor::_bind_methods() { diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index ec5208b54922..a139d180f041 100644 --- a/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp @@ -60,7 +60,7 @@ void ReparentDialog::_reparent() { void ReparentDialog::set_current(const HashSet &p_selection) { tree->set_marked(p_selection, false, false); - //tree->set_selected(p_node->get_parent()); + tree->set_selected(nullptr); } void ReparentDialog::_bind_methods() { @@ -74,7 +74,6 @@ ReparentDialog::ReparentDialog() { VBoxContainer *vbc = memnew(VBoxContainer); add_child(vbc); - //set_child_rect(vbc); tree = memnew(SceneTreeEditor(false)); tree->set_show_enabled_subscene(true); @@ -86,10 +85,6 @@ ReparentDialog::ReparentDialog() { keep_transform->set_pressed(true); vbc->add_child(keep_transform); - //vbc->add_margin_child("Options:",node_only); - - //cancel->connect("pressed", this,"_cancel"); - set_ok_button_text(TTR("Reparent")); } diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp index 58803124cfc6..6000e2b1d35a 100644 --- a/modules/multiplayer/editor/replication_editor.cpp +++ b/modules/multiplayer/editor/replication_editor.cpp @@ -131,7 +131,7 @@ void ReplicationEditor::_pick_new_property() { EditorNode::get_singleton()->show_warning(TTR("Not possible to add a new property to synchronize without a root.")); return; } - pick_node->popup_scenetree_dialog(); + pick_node->popup_scenetree_dialog(nullptr, current); pick_node->get_filter_line_edit()->clear(); pick_node->get_filter_line_edit()->grab_focus(); }