Browse Source

Merge pull request #85386 from RedMser/scene-tree-editor-improvements

Improve SceneTreeEditor usability
Rémi Verschelde 1 year ago
parent
commit
e302fb2167

+ 7 - 2
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();
 }

+ 1 - 1
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<Node *>(p_cd.target));

+ 9 - 2
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<Node>(val);
+	}
+	scene_tree->popup_scenetree_dialog(n, get_base_node());
 }
 
 void EditorPropertyNodePath::_update_menu() {
@@ -3184,7 +3192,6 @@ void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource)
 			add_child(scene_tree);
 			scene_tree->connect("selected", callable_mp(this, &EditorPropertyResource::_viewport_selected));
 		}
-
 		scene_tree->popup_scenetree_dialog();
 	}
 }

+ 24 - 1
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);
 }
 

+ 3 - 3
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<Node *> &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<Node *> &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<StringName> &p_valid);
 
 	SceneTreeEditor *get_scene_tree() { return tree; }

+ 0 - 1
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: {

+ 4 - 2
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() {

+ 1 - 6
editor/reparent_dialog.cpp

@@ -60,7 +60,7 @@ void ReparentDialog::_reparent() {
 
 void ReparentDialog::set_current(const HashSet<Node *> &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"));
 }
 

+ 1 - 1
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();
 }