瀏覽代碼

Merge pull request #32143 from YeldhamDev/scenedock_reparent_fixes

Fix some errors while reparenting nodes in the Scene dock
Rémi Verschelde 6 年之前
父節點
當前提交
65286c6b46
共有 1 個文件被更改,包括 27 次插入19 次删除
  1. 27 19
      editor/scene_tree_dock.cpp

+ 27 - 19
editor/scene_tree_dock.cpp

@@ -1504,7 +1504,7 @@ bool SceneTreeDock::_validate_no_foreign() {
 
 
 		// When edited_scene inherits from another one the root Node will be the parent Scene,
 		// When edited_scene inherits from another one the root Node will be the parent Scene,
 		// we don't want to consider that Node a foreign one otherwise we would not be able to
 		// we don't want to consider that Node a foreign one otherwise we would not be able to
-		// delete it
+		// delete it.
 		if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) {
 		if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) {
 			continue;
 			continue;
 		}
 		}
@@ -1528,7 +1528,7 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
 	List<Node *> selection = editor_selection->get_selected_node_list();
 	List<Node *> selection = editor_selection->get_selected_node_list();
 
 
 	if (selection.empty())
 	if (selection.empty())
-		return; //nothing to reparent
+		return; // Nothing to reparent.
 
 
 	Vector<Node *> nodes;
 	Vector<Node *> nodes;
 
 
@@ -1544,18 +1544,30 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
 	Node *new_parent = p_new_parent;
 	Node *new_parent = p_new_parent;
 	ERR_FAIL_COND(!new_parent);
 	ERR_FAIL_COND(!new_parent);
 
 
+	if (p_nodes.size() == 0)
+		return; // Nothing to reparent.
+
+	bool same_parent = true;
+	for (int ni = 0; ni < p_nodes.size(); ni++) {
+
+		if (p_nodes[ni] == p_new_parent)
+			return; // Attempt to reparent to itself.
+
+		if (p_nodes[ni]->get_parent() != p_new_parent)
+			same_parent = false;
+	}
+
+	if (same_parent)
+		return; // No new parent changes.
+
 	Node *validate = new_parent;
 	Node *validate = new_parent;
 	while (validate) {
 	while (validate) {
 
 
-		ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point.. can't reparent.");
+		ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent.");
 		validate = validate->get_parent();
 		validate = validate->get_parent();
 	}
 	}
-	//ok all valid
-
-	if (p_nodes.size() == 0)
-		return; //nothing to reparent
 
 
-	//sort by tree order, so re-adding is easy
+	// Sort by tree order, so re-adding is easy.
 	p_nodes.sort_custom<Node::Comparator>();
 	p_nodes.sort_custom<Node::Comparator>();
 
 
 	editor_data->get_undo_redo().create_action(TTR("Reparent Node"));
 	editor_data->get_undo_redo().create_action(TTR("Reparent Node"));
@@ -1567,7 +1579,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
 
 
 	for (int ni = 0; ni < p_nodes.size(); ni++) {
 	for (int ni = 0; ni < p_nodes.size(); ni++) {
 
 
-		//no undo for now, sorry
+		// No undo implemented for this yet.
 		Node *node = p_nodes[ni];
 		Node *node = p_nodes[ni];
 
 
 		fill_path_renames(node, new_parent, &path_renames);
 		fill_path_renames(node, new_parent, &path_renames);
@@ -1577,14 +1589,11 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
 		node->get_owned_by(node->get_owner(), &owned);
 		node->get_owned_by(node->get_owner(), &owned);
 		Array owners;
 		Array owners;
 		for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
 		for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
-
 			owners.push_back(E->get());
 			owners.push_back(E->get());
 		}
 		}
 
 
-		if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni) {
-			//if child will generate a gap when moved, adjust
-			inc--;
-		}
+		if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni)
+			inc--; // If the child will generate a gap when moved, adjust.
 
 
 		editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
 		editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
 		editor_data->get_undo_redo().add_do_method(new_parent, "add_child", node);
 		editor_data->get_undo_redo().add_do_method(new_parent, "add_child", node);
@@ -1596,17 +1605,17 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
 		String old_name = former_names[ni];
 		String old_name = former_names[ni];
 		String new_name = new_parent->validate_child_name(node);
 		String new_name = new_parent->validate_child_name(node);
 
 
-		// name was modified, fix the path renames
+		// Name was modified, fix the path renames.
 		if (old_name.casecmp_to(new_name) != 0) {
 		if (old_name.casecmp_to(new_name) != 0) {
 
 
-			// Fix the to name to have the new name
+			// Fix the to name to have the new name.
 			NodePath old_new_name = path_renames[ni].second;
 			NodePath old_new_name = path_renames[ni].second;
 			NodePath new_path;
 			NodePath new_path;
 
 
 			Vector<StringName> unfixed_new_names = old_new_name.get_names();
 			Vector<StringName> unfixed_new_names = old_new_name.get_names();
 			Vector<StringName> fixed_new_names;
 			Vector<StringName> fixed_new_names;
 
 
-			// Get last name and replace with fixed new name
+			// Get last name and replace with fixed new name.
 			for (int a = 0; a < (unfixed_new_names.size() - 1); a++) {
 			for (int a = 0; a < (unfixed_new_names.size() - 1); a++) {
 				fixed_new_names.push_back(unfixed_new_names[a]);
 				fixed_new_names.push_back(unfixed_new_names[a]);
 			}
 			}
@@ -1640,8 +1649,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
 		inc++;
 		inc++;
 	}
 	}
 
 
-	//add and move in a second step.. (so old order is preserved)
-
+	// Add and move in a second step (so old order is preserved).
 	for (int ni = 0; ni < p_nodes.size(); ni++) {
 	for (int ni = 0; ni < p_nodes.size(); ni++) {
 
 
 		Node *node = p_nodes[ni];
 		Node *node = p_nodes[ni];