diff options
-rw-r--r-- | doc/classes/Node.xml | 9 | ||||
-rw-r--r-- | scene/2d/node_2d.cpp | 8 | ||||
-rw-r--r-- | scene/2d/node_2d.h | 1 | ||||
-rw-r--r-- | scene/3d/node_3d.cpp | 8 | ||||
-rw-r--r-- | scene/3d/node_3d.h | 1 | ||||
-rw-r--r-- | scene/gui/control.cpp | 8 | ||||
-rw-r--r-- | scene/gui/control.h | 1 | ||||
-rw-r--r-- | scene/main/node.cpp | 13 | ||||
-rw-r--r-- | scene/main/node.h | 1 |
9 files changed, 50 insertions, 0 deletions
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 24df5977f9..0ccc4155b4 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -612,6 +612,15 @@ Removes a node from the [param group]. Does nothing if the node is not in the [param group]. See notes in the description, and the group methods in [SceneTree]. </description> </method> + <method name="reparent"> + <return type="void" /> + <param index="0" name="new_parent" type="Node" /> + <param index="1" name="keep_global_transform" type="bool" default="true" /> + <description> + Changes the parent of this [Node] to the [param new_parent]. The node needs to already have a parent. + If [param keep_global_transform] is [code]true[/code], the node's global transform will be preserved if supported. [Node2D], [Node3D] and [Control] support this argument (but [Control] keeps only position). + </description> + </method> <method name="replace_by"> <return type="void" /> <param index="0" name="node" type="Node" /> diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 0b7cdafdef..1c0efe773f 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -133,6 +133,14 @@ void Node2D::_update_transform() { _notify_transform(); } +void Node2D::reparent(Node *p_parent, bool p_keep_global_transform) { + Transform2D temp = get_global_transform(); + Node::reparent(p_parent); + if (p_keep_global_transform) { + set_global_transform(temp); + } +} + void Node2D::set_position(const Point2 &p_pos) { if (_xform_dirty) { const_cast<Node2D *>(this)->_update_xform_values(); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index e332745da5..119e23cd98 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -70,6 +70,7 @@ public: virtual void _edit_set_rect(const Rect2 &p_edit_rect) override; #endif + virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override; void set_position(const Point2 &p_pos); void set_rotation(real_t p_radians); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index a0382b73dc..66e8831d15 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -623,6 +623,14 @@ void Node3D::set_disable_gizmos(bool p_enabled) { #endif } +void Node3D::reparent(Node *p_parent, bool p_keep_global_transform) { + Transform3D temp = get_global_transform(); + Node::reparent(p_parent); + if (p_keep_global_transform) { + set_global_transform(temp); + } +} + void Node3D::set_disable_scale(bool p_enabled) { data.disable_scale = p_enabled; } diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 0901ab331b..98bcab5fd4 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -206,6 +206,7 @@ public: virtual void set_transform_gizmo_visible(bool p_enabled) { data.transform_gizmo_visible = p_enabled; }; virtual bool is_transform_gizmo_visible() const { return data.transform_gizmo_visible; }; #endif + virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override; void set_disable_gizmos(bool p_enabled); void update_gizmos(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 64d1d38abb..7daeb6eab6 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -186,6 +186,14 @@ Size2 Control::_edit_get_minimum_size() const { } #endif +void Control::reparent(Node *p_parent, bool p_keep_global_transform) { + Transform2D temp = get_global_transform(); + Node::reparent(p_parent); + if (p_keep_global_transform) { + set_global_position(temp.get_origin()); + } +} + // Editor integration. void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { diff --git a/scene/gui/control.h b/scene/gui/control.h index 288de7c9e7..a11f7da00f 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -387,6 +387,7 @@ public: virtual Size2 _edit_get_minimum_size() const override; #endif + virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override; // Editor integration. diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 8f173e4c0d..3544ec4c83 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1439,6 +1439,18 @@ TypedArray<Node> Node::find_children(const String &p_pattern, const String &p_ty return ret; } +void Node::reparent(Node *p_parent, bool p_keep_global_transform) { + ERR_FAIL_NULL(p_parent); + ERR_FAIL_NULL_MSG(data.parent, "Node needs a parent to be reparented."); + + if (p_parent == data.parent) { + return; + } + + data.parent->remove_child(this); + p_parent->add_child(this); +} + Node *Node::get_parent() const { return data.parent; } @@ -2784,6 +2796,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name); ClassDB::bind_method(D_METHOD("add_child", "node", "force_readable_name", "internal"), &Node::add_child, DEFVAL(false), DEFVAL(0)); ClassDB::bind_method(D_METHOD("remove_child", "node"), &Node::remove_child); + ClassDB::bind_method(D_METHOD("reparent", "new_parent", "keep_global_transform"), &Node::reparent, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_child_count", "include_internal"), &Node::get_child_count, DEFVAL(false)); // Note that the default value bound for include_internal is false, while the method is declared with true. This is because internal nodes are irrelevant for GDSCript. ClassDB::bind_method(D_METHOD("get_children", "include_internal"), &Node::_get_children, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_child", "idx", "include_internal"), &Node::get_child, DEFVAL(false)); diff --git a/scene/main/node.h b/scene/main/node.h index 611f48c400..398465c3cd 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -317,6 +317,7 @@ public: bool has_node_and_resource(const NodePath &p_path) const; Node *get_node_and_resource(const NodePath &p_path, Ref<Resource> &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const; + virtual void reparent(Node *p_parent, bool p_keep_global_transform = true); Node *get_parent() const; Node *find_parent(const String &p_pattern) const; |