Fix drag-dropping nodes to parent with internal nodes
This commit is contained in:
parent
950f4c3b41
commit
3f6e35bdb2
@ -262,6 +262,9 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
|
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
|
||||||
|
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||||
|
ERR_FAIL_COND_MSG(base->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to replace internal node, this is not supported.");
|
||||||
|
|
||||||
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
|
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
|
||||||
if (!sdata.is_valid()) {
|
if (!sdata.is_valid()) {
|
||||||
accept->set_text(vformat(TTR("Error loading scene from %s"), p_file));
|
accept->set_text(vformat(TTR("Error loading scene from %s"), p_file));
|
||||||
@ -282,7 +285,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
|
|||||||
undo_redo->create_action(TTR("Replace with Branch Scene"));
|
undo_redo->create_action(TTR("Replace with Branch Scene"));
|
||||||
|
|
||||||
Node *parent = base->get_parent();
|
Node *parent = base->get_parent();
|
||||||
int pos = base->get_index();
|
int pos = base->get_index(false);
|
||||||
undo_redo->add_do_method(parent, "remove_child", base);
|
undo_redo->add_do_method(parent, "remove_child", base);
|
||||||
undo_redo->add_undo_method(parent, "remove_child", instantiated_scene);
|
undo_redo->add_undo_method(parent, "remove_child", instantiated_scene);
|
||||||
undo_redo->add_do_method(parent, "add_child", instantiated_scene, true);
|
undo_redo->add_do_method(parent, "add_child", instantiated_scene, true);
|
||||||
@ -607,10 +610,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||||||
selection.reverse();
|
selection.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
int lowest_id = common_parent->get_child_count() - 1;
|
int lowest_id = common_parent->get_child_count(false) - 1;
|
||||||
int highest_id = 0;
|
int highest_id = 0;
|
||||||
for (Node *E : selection) {
|
for (Node *E : selection) {
|
||||||
int index = E->get_index();
|
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||||
|
ERR_FAIL_COND_MSG(E->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to move internal node, this is not supported.");
|
||||||
|
int index = E->get_index(false);
|
||||||
|
|
||||||
if (index > highest_id) {
|
if (index > highest_id) {
|
||||||
highest_id = index;
|
highest_id = index;
|
||||||
@ -624,7 +629,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0)) {
|
if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count(false) - MOVING_DOWN) || (MOVING_UP && lowest_id == 0)) {
|
||||||
break; // one or more nodes can not be moved
|
break; // one or more nodes can not be moved
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,8 +648,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||||||
ERR_FAIL_COND(!top_node->get_parent());
|
ERR_FAIL_COND(!top_node->get_parent());
|
||||||
ERR_FAIL_COND(!bottom_node->get_parent());
|
ERR_FAIL_COND(!bottom_node->get_parent());
|
||||||
|
|
||||||
int bottom_node_pos = bottom_node->get_index();
|
int bottom_node_pos = bottom_node->get_index(false);
|
||||||
int top_node_pos_next = top_node->get_index() + (MOVING_DOWN ? 1 : -1);
|
int top_node_pos_next = top_node->get_index(false) + (MOVING_DOWN ? 1 : -1);
|
||||||
|
|
||||||
undo_redo->add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next);
|
undo_redo->add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next);
|
||||||
undo_redo->add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos);
|
undo_redo->add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos);
|
||||||
@ -775,6 +780,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||||
|
ERR_FAIL_COND_MSG(node->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to set internal node as scene root, this is not supported.");
|
||||||
|
|
||||||
//check that from node to root, all owners are right
|
//check that from node to root, all owners are right
|
||||||
|
|
||||||
if (root->get_scene_inherited_state().is_valid()) {
|
if (root->get_scene_inherited_state().is_valid()) {
|
||||||
@ -811,7 +819,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||||||
undo_redo->add_undo_method(node, "remove_child", root);
|
undo_redo->add_undo_method(node, "remove_child", root);
|
||||||
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", root);
|
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", root);
|
||||||
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
|
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
|
||||||
undo_redo->add_undo_method(node->get_parent(), "move_child", node, node->get_index());
|
undo_redo->add_undo_method(node->get_parent(), "move_child", node, node->get_index(false));
|
||||||
undo_redo->add_undo_method(root, "set_owner", (Object *)nullptr);
|
undo_redo->add_undo_method(root, "set_owner", (Object *)nullptr);
|
||||||
undo_redo->add_undo_method(node, "set_owner", root);
|
undo_redo->add_undo_method(node, "set_owner", root);
|
||||||
_node_replace_owner(root, root, root, MODE_UNDO);
|
_node_replace_owner(root, root, root, MODE_UNDO);
|
||||||
@ -1898,8 +1906,10 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||||||
if (p_nodes[ni] == p_new_parent) {
|
if (p_nodes[ni] == p_new_parent) {
|
||||||
return; // Attempt to reparent to itself.
|
return; // Attempt to reparent to itself.
|
||||||
}
|
}
|
||||||
|
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||||
|
ERR_FAIL_COND_MSG(p_nodes[ni]->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to move internal node, this is not supported.");
|
||||||
|
|
||||||
if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_index()) {
|
if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_index(false)) {
|
||||||
no_change = false;
|
no_change = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1940,7 +1950,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool same_parent = new_parent == node->get_parent();
|
bool same_parent = new_parent == node->get_parent();
|
||||||
if (same_parent && node->get_index() < p_position_in_parent + ni) {
|
if (same_parent && node->get_index(false) < p_position_in_parent + ni) {
|
||||||
inc--; // If the child will generate a gap when moved, adjust.
|
inc--; // If the child will generate a gap when moved, adjust.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,7 +1992,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||||||
}
|
}
|
||||||
|
|
||||||
undo_redo->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, new_position_in_parent);
|
undo_redo->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, new_position_in_parent);
|
||||||
undo_redo->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index());
|
undo_redo->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index(false));
|
||||||
|
|
||||||
if (p_keep_global_xform) {
|
if (p_keep_global_xform) {
|
||||||
if (Object::cast_to<Node2D>(node)) {
|
if (Object::cast_to<Node2D>(node)) {
|
||||||
@ -2019,7 +2029,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
|
|||||||
owners.push_back(E);
|
owners.push_back(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
int child_pos = node->get_index();
|
int child_pos = node->get_index(false);
|
||||||
|
|
||||||
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
|
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
|
||||||
undo_redo->add_undo_method(node->get_parent(), "move_child", node, child_pos);
|
undo_redo->add_undo_method(node->get_parent(), "move_child", node, child_pos);
|
||||||
@ -2167,6 +2177,10 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
|
|||||||
undo_redo->add_undo_method(scene_tree, "update_tree");
|
undo_redo->add_undo_method(scene_tree, "update_tree");
|
||||||
undo_redo->add_undo_reference(edited_scene);
|
undo_redo->add_undo_reference(edited_scene);
|
||||||
} else {
|
} else {
|
||||||
|
for (const Node *E : remove_list) {
|
||||||
|
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||||
|
ERR_FAIL_COND_MSG(E->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to remove internal node, this is not supported.");
|
||||||
|
}
|
||||||
if (delete_tracks_checkbox->is_pressed() || p_cut) {
|
if (delete_tracks_checkbox->is_pressed() || p_cut) {
|
||||||
remove_list.sort_custom<Node::Comparator>(); // Sort nodes to keep positions.
|
remove_list.sort_custom<Node::Comparator>(); // Sort nodes to keep positions.
|
||||||
HashMap<Node *, NodePath> path_renames;
|
HashMap<Node *, NodePath> path_renames;
|
||||||
@ -2198,7 +2212,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
|
|||||||
|
|
||||||
undo_redo->add_do_method(n->get_parent(), "remove_child", n);
|
undo_redo->add_do_method(n->get_parent(), "remove_child", n);
|
||||||
undo_redo->add_undo_method(n->get_parent(), "add_child", n, true);
|
undo_redo->add_undo_method(n->get_parent(), "add_child", n, true);
|
||||||
undo_redo->add_undo_method(n->get_parent(), "move_child", n, n->get_index());
|
undo_redo->add_undo_method(n->get_parent(), "move_child", n, n->get_index(false));
|
||||||
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == n) {
|
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == n) {
|
||||||
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n);
|
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n);
|
||||||
}
|
}
|
||||||
@ -2207,7 +2221,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
|
|||||||
|
|
||||||
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
|
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
|
||||||
undo_redo->add_do_method(ed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id());
|
undo_redo->add_do_method(ed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id());
|
||||||
undo_redo->add_undo_method(ed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index());
|
undo_redo->add_undo_method(ed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
@ -2608,7 +2622,7 @@ void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
|
|||||||
ERR_FAIL_MSG("Cannot perform drop above the root node!");
|
ERR_FAIL_MSG("Cannot perform drop above the root node!");
|
||||||
}
|
}
|
||||||
|
|
||||||
to_pos = to_node->get_index();
|
to_pos = to_node->get_index(false);
|
||||||
to_node = to_node->get_parent();
|
to_node = to_node->get_parent();
|
||||||
|
|
||||||
} else if (p_type == 1) {
|
} else if (p_type == 1) {
|
||||||
@ -2624,15 +2638,15 @@ void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
|
|||||||
if (_has_visible_children(to_node)) {
|
if (_has_visible_children(to_node)) {
|
||||||
to_pos = 0;
|
to_pos = 0;
|
||||||
} else {
|
} else {
|
||||||
for (int i = to_node->get_index() + 1; i < to_node->get_parent()->get_child_count(); i++) {
|
for (int i = to_node->get_index(false) + 1; i < to_node->get_parent()->get_child_count(false); i++) {
|
||||||
Node *c = to_node->get_parent()->get_child(i);
|
Node *c = to_node->get_parent()->get_child(i, false);
|
||||||
if (_is_node_visible(c)) {
|
if (_is_node_visible(c)) {
|
||||||
lower_sibling = c;
|
lower_sibling = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lower_sibling) {
|
if (lower_sibling) {
|
||||||
to_pos = lower_sibling->get_index();
|
to_pos = lower_sibling->get_index(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
to_node = to_node->get_parent();
|
to_node = to_node->get_parent();
|
||||||
|
@ -1340,6 +1340,10 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node::InternalMode Node::get_internal_mode() const {
|
||||||
|
return data.internal_mode;
|
||||||
|
}
|
||||||
|
|
||||||
void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalMode p_internal_mode) {
|
void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalMode p_internal_mode) {
|
||||||
//add a child node quickly, without name validation
|
//add a child node quickly, without name validation
|
||||||
|
|
||||||
|
@ -386,6 +386,8 @@ public:
|
|||||||
String get_description() const;
|
String get_description() const;
|
||||||
void set_name(const String &p_name);
|
void set_name(const String &p_name);
|
||||||
|
|
||||||
|
InternalMode get_internal_mode() const;
|
||||||
|
|
||||||
void add_child(Node *p_child, bool p_force_readable_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED);
|
void add_child(Node *p_child, bool p_force_readable_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED);
|
||||||
void add_sibling(Node *p_sibling, bool p_force_readable_name = false);
|
void add_sibling(Node *p_sibling, bool p_force_readable_name = false);
|
||||||
void remove_child(Node *p_child);
|
void remove_child(Node *p_child);
|
||||||
|
Loading…
Reference in New Issue
Block a user