浏览代码

Update the edit scene root in time after it is replaced

When changing the type of the edited scene root node, it may be necessary
to update edited scene root in time for the child nodes to work properly.
Rindbee 2 年之前
父节点
当前提交
eb74079dfb
共有 4 个文件被更改,包括 17 次插入8 次删除
  1. 7 0
      doc/classes/Node.xml
  2. 6 3
      editor/editor_node.cpp
  3. 0 5
      editor/scene_tree_dock.cpp
  4. 4 0
      scene/main/node.cpp

+ 7 - 0
doc/classes/Node.xml

@@ -845,6 +845,13 @@
 				Emitted when the node is renamed.
 			</description>
 		</signal>
+		<signal name="replacing_by">
+			<param index="0" name="node" type="Node" />
+			<description>
+				Emitted when this node is being replaced by the [param node], see [method replace_by].
+				This signal is emitted [i]after[/i] [param node] has been added as a child of the original parent node, but [i]before[/i] all original child nodes have been reparented to [param node].
+			</description>
+		</signal>
 		<signal name="tree_entered">
 			<description>
 				Emitted when the node enters the tree.

+ 6 - 3
editor/editor_node.cpp

@@ -3430,10 +3430,12 @@ void EditorNode::_remove_scene(int index, bool p_change_tab) {
 }
 
 void EditorNode::set_edited_scene(Node *p_scene) {
-	if (get_editor_data().get_edited_scene_root()) {
-		if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root) {
-			scene_root->remove_child(get_editor_data().get_edited_scene_root());
+	Node *old_edited_scene_root = get_editor_data().get_edited_scene_root();
+	if (old_edited_scene_root) {
+		if (old_edited_scene_root->get_parent() == scene_root) {
+			scene_root->remove_child(old_edited_scene_root);
 		}
+		old_edited_scene_root->disconnect(SNAME("replacing_by"), callable_mp(this, &EditorNode::set_edited_scene));
 	}
 	get_editor_data().set_edited_scene_root(p_scene);
 
@@ -3449,6 +3451,7 @@ void EditorNode::set_edited_scene(Node *p_scene) {
 		if (p_scene->get_parent() != scene_root) {
 			scene_root->add_child(p_scene, true);
 		}
+		p_scene->connect(SNAME("replacing_by"), callable_mp(this, &EditorNode::set_edited_scene));
 	}
 }
 

+ 0 - 5
editor/scene_tree_dock.cpp

@@ -2468,11 +2468,6 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
 	}
 	n->replace_by(newnode, true);
 
-	if (n == edited_scene) {
-		edited_scene = newnode;
-		EditorNode::get_singleton()->set_edited_scene(newnode);
-	}
-
 	//small hack to make collisionshapes and other kind of nodes to work
 	for (int i = 0; i < newnode->get_child_count(); i++) {
 		Node *c = newnode->get_child(i);

+ 4 - 0
scene/main/node.cpp

@@ -2500,6 +2500,8 @@ void Node::replace_by(Node *p_node, bool p_keep_groups) {
 		parent->move_child(p_node, index_in_parent);
 	}
 
+	emit_signal(SNAME("replacing_by"), p_node);
+
 	while (get_child_count()) {
 		Node *child = get_child(0);
 		remove_child(child);
@@ -3040,7 +3042,9 @@ void Node::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("tree_exited"));
 	ADD_SIGNAL(MethodInfo("child_entered_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
 	ADD_SIGNAL(MethodInfo("child_exiting_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
+
 	ADD_SIGNAL(MethodInfo("child_order_changed"));
+	ADD_SIGNAL(MethodInfo("replacing_by", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
 
 	ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "unique_name_in_owner", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_unique_name_in_owner", "is_unique_name_in_owner");