소스 검색

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");