diff options
Diffstat (limited to 'editor/scene_tree_dock.cpp')
-rw-r--r-- | editor/scene_tree_dock.cpp | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index aeee829de2..2ddf1f7056 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -399,6 +399,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } Node *selected = scene_tree->get_selected(); + if (!selected && !editor_selection->get_selected_node_list().empty()) + selected = editor_selection->get_selected_node_list().front()->get(); + if (selected) create_dialog->popup_create(false, true, selected->get_class()); @@ -756,7 +759,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { _delete_confirm(); } else { - delete_dialog->set_text(TTR("Delete Node(s)?")); + if (remove_list.size() >= 2) { + delete_dialog->set_text(vformat(TTR("Delete %d nodes?"), remove_list.size())); + } else if (remove_list.size() == 1 && remove_list[0] == editor_data->get_edited_scene_root()) { + delete_dialog->set_text(vformat(TTR("Delete the root node \"%s\"?"), remove_list[0]->get_name())); + } else if (remove_list.size() == 1 && remove_list[0]->get_filename() == "" && remove_list[0]->get_child_count() >= 1) { + // Display this message only for non-instanced scenes + delete_dialog->set_text(vformat(TTR("Delete node \"%s\" and its children?"), remove_list[0]->get_name())); + } else { + delete_dialog->set_text(vformat(TTR("Delete node \"%s\"?"), remove_list[0]->get_name())); + } + + // Resize the dialog to its minimum size. + // This prevents the dialog from being too wide after displaying + // a deletion confirmation for a node with a long name. + delete_dialog->set_size(Size2()); delete_dialog->popup_centered_minsize(); } @@ -983,9 +1000,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } else { new_node = Object::cast_to<Node>(ClassDB::instance(selected_favorite_root)); } + if (!new_node) { - ERR_EXPLAIN("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead."); new_node = memnew(Node); + ERR_PRINTS("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead."); } } else { switch (p_tool) { @@ -1491,7 +1509,7 @@ bool SceneTreeDock::_validate_no_foreign() { // 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 - // delete it + // delete it. if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) { continue; } @@ -1515,7 +1533,7 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) { List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.empty()) - return; //nothing to reparent + return; // Nothing to reparent. Vector<Node *> nodes; @@ -1531,21 +1549,32 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V Node *new_parent = p_new_parent; ERR_FAIL_COND(!new_parent); + if (p_nodes.size() == 0) + return; // Nothing to reparent. + + p_nodes.sort_custom<Node::Comparator>(); //Makes result reliable. + + bool no_change = 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 || p_position_in_parent + ni != p_nodes[ni]->get_position_in_parent()) + no_change = false; + } + + if (no_change) + return; // Position and parent didn't change. + Node *validate = new_parent; while (validate) { - if (p_nodes.find(validate) != -1) { - ERR_EXPLAIN("Selection changed at some point.. can't reparent"); - ERR_FAIL(); - } + ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent."); 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>(); editor_data->get_undo_redo().create_action(TTR("Reparent Node")); @@ -1557,7 +1586,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V 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]; fill_path_renames(node, new_parent, &path_renames); @@ -1567,14 +1596,11 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V node->get_owned_by(node->get_owner(), &owned); Array owners; for (List<Node *>::Element *E = owned.front(); E; E = E->next()) { - 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(new_parent, "add_child", node); @@ -1586,17 +1612,17 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V String old_name = former_names[ni]; 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) { - // 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 new_path; Vector<StringName> unfixed_new_names = old_new_name.get_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++) { fixed_new_names.push_back(unfixed_new_names[a]); } @@ -1630,8 +1656,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V 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++) { Node *node = p_nodes[ni]; @@ -1983,6 +2008,10 @@ void SceneTreeDock::_create() { } else if (current_option == TOOL_REPLACE) { List<Node *> selection = editor_selection->get_selected_node_list(); ERR_FAIL_COND(selection.size() <= 0); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change type of node(s)")); + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { Node *n = E->get(); ERR_FAIL_COND(!n); @@ -1993,8 +2022,13 @@ void SceneTreeDock::_create() { Node *newnode = Object::cast_to<Node>(c); ERR_FAIL_COND(!newnode); - replace_node(n, newnode); + ur->add_do_method(this, "replace_node", n, newnode, true, false); + ur->add_do_reference(newnode); + ur->add_undo_method(this, "replace_node", newnode, n, false, false); + ur->add_undo_reference(n); } + + ur->commit_action(); } else if (current_option == TOOL_REPARENT_TO_NEW_NODE) { List<Node *> selection = editor_selection->get_selected_node_list(); ERR_FAIL_COND(selection.size() <= 0); @@ -2241,8 +2275,7 @@ void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) { //drop at above selected node if (to_node == EditorNode::get_singleton()->get_edited_scene()) { to_node = NULL; - ERR_EXPLAIN("Cannot perform drop above the root node!"); - ERR_FAIL(); + ERR_FAIL_MSG("Cannot perform drop above the root node!"); } to_pos = to_node->get_index(); @@ -2700,6 +2733,7 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_feature_profile_changed"), &SceneTreeDock::_feature_profile_changed); ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance); + ClassDB::bind_method(D_METHOD("get_tree_editor"), &SceneTreeDock::get_tree_editor); ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node); ADD_SIGNAL(MethodInfo("remote_tree_selected")); |