void SceneTreeDock::_node_reparent(NodePath p_path,bool p_node_only) { Node *node = scene_tree->get_selected(); ERR_FAIL_COND(!node); ERR_FAIL_COND(node==edited_scene); Node *new_parent = scene_root->get_node(p_path); ERR_FAIL_COND(!new_parent); Node *validate=new_parent; while(validate) { if (editor_selection->is_selected(validate)) { ERR_EXPLAIN("Selection changed at some point.. can't reparent"); ERR_FAIL(); return; } validate=validate->get_parent(); } //ok all valid List<Node*> selection = editor_selection->get_selected_node_list(); if (selection.empty()) return; //nothing to reparent //sort by tree order, so re-adding is easy selection.sort_custom<Node::Comparator>(); editor_data->get_undo_redo().create_action("Reparent Node"); List<Pair<NodePath,NodePath> > path_renames; for(List<Node*>::Element *E=selection.front();E;E=E->next()) { //no undo for now, sorry Node *node = E->get(); fill_path_renames(node,new_parent,&path_renames); List<Node*> owned; 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()); } 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); editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners); if (editor->get_animation_editor()->get_root()==node) editor_data->get_undo_redo().add_do_method(editor->get_animation_editor(),"set_root",node); editor_data->get_undo_redo().add_undo_method(new_parent,"remove_child",node); } //add and move in a second step.. (so old order is preserved) for(List<Node*>::Element *E=selection.front();E;E=E->next()) { Node *node = E->get(); List<Node*> owned; 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()); } int child_pos = node->get_position_in_parent(); editor_data->get_undo_redo().add_undo_method(node->get_parent(),"add_child",node); editor_data->get_undo_redo().add_undo_method(node->get_parent(),"move_child",node,child_pos); editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); if (editor->get_animation_editor()->get_root()==node) editor_data->get_undo_redo().add_undo_method(editor->get_animation_editor(),"set_root",node); } perform_node_renames(NULL,&path_renames); editor_data->get_undo_redo().commit_action(); //node->set_owner(owner); }
void SceneTreeDock::_delete_confirm() { List<Node*> remove_list = editor_selection->get_selected_node_list(); if (remove_list.empty()) return; if (editor->get_editor_plugin_over()) editor->get_editor_plugin_over()->make_visible(false); editor_data->get_undo_redo().create_action("Remove Node(s)"); bool entire_scene=false; for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { if (E->get()==edited_scene) { entire_scene=true; } } if (entire_scene) { editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",(Object*)NULL); editor_data->get_undo_redo().add_undo_method(editor,"set_edited_scene",edited_scene); editor_data->get_undo_redo().add_undo_method(edited_scene,"set_owner",edited_scene->get_owner()); editor_data->get_undo_redo().add_undo_reference(edited_scene); } else { remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions List<Pair<NodePath,NodePath> > path_renames; //delete from animation for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { Node *n = E->get(); if (!n->is_inside_scene() || !n->get_parent()) continue; fill_path_renames(n,NULL,&path_renames); } perform_node_renames(NULL,&path_renames); //delete for read for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { Node *n = E->get(); if (!n->is_inside_scene() || !n->get_parent()) continue; List<Node*> owned; n->get_owned_by(n->get_owner(),&owned); Array owners; for(List<Node*>::Element *E=owned.front();E;E=E->next()) { owners.push_back(E->get()); } editor_data->get_undo_redo().add_do_method(n->get_parent(),"remove_child",n); editor_data->get_undo_redo().add_undo_method(n->get_parent(),"add_child",n); editor_data->get_undo_redo().add_undo_method(n->get_parent(),"move_child",n,n->get_index()); if (editor->get_animation_editor()->get_root()==n) editor_data->get_undo_redo().add_undo_method(editor->get_animation_editor(),"set_root",n); editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); //editor_data->get_undo_redo().add_undo_method(n,"set_owner",n->get_owner()); editor_data->get_undo_redo().add_undo_reference(n); } } editor_data->get_undo_redo().commit_action(); _update_tool_buttons(); }
void SceneTreeDock::_node_reparent(NodePath p_path,bool p_keep_global_xform) { Node *node = scene_tree->get_selected(); ERR_FAIL_COND(!node); ERR_FAIL_COND(node==edited_scene); Node *new_parent = scene_root->get_node(p_path); ERR_FAIL_COND(!new_parent); Node *validate=new_parent; while(validate) { if (editor_selection->is_selected(validate)) { ERR_EXPLAIN("Selection changed at some point.. can't reparent"); ERR_FAIL(); return; } validate=validate->get_parent(); } //ok all valid List<Node*> selection = editor_selection->get_selected_node_list(); if (selection.empty()) return; //nothing to reparent //sort by tree order, so re-adding is easy selection.sort_custom<Node::Comparator>(); editor_data->get_undo_redo().create_action("Reparent Node"); List<Pair<NodePath,NodePath> > path_renames; for(List<Node*>::Element *E=selection.front();E;E=E->next()) { //no undo for now, sorry Node *node = E->get(); fill_path_renames(node,new_parent,&path_renames); List<Node*> owned; 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()); } 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); ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); String new_name = new_parent->validate_child_name(node->get_name()); editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1); editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index()); if (p_keep_global_xform) { if (node->cast_to<Node2D>()) editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Node2D>()->get_global_transform()); if (node->cast_to<Spatial>()) editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Spatial>()->get_global_transform()); if (node->cast_to<Control>()) { bool can_do_it=false; Control *c=node->cast_to<Control>(); if (c->get_parent()->cast_to<Container>()) can_do_it=false; for(int i=0;i<4;i++) { if (c->get_anchor(Margin(i))!=ANCHOR_BEGIN) can_do_it=false; } editor_data->get_undo_redo().add_do_method(node,"set_global_pos",node->cast_to<Control>()->get_global_pos()); } } editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners); if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); editor_data->get_undo_redo().add_undo_method(new_parent,"remove_child",node); } //add and move in a second step.. (so old order is preserved) for(List<Node*>::Element *E=selection.front();E;E=E->next()) { Node *node = E->get(); List<Node*> owned; 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()); } int child_pos = node->get_position_in_parent(); editor_data->get_undo_redo().add_undo_method(node->get_parent(),"add_child",node); editor_data->get_undo_redo().add_undo_method(node->get_parent(),"move_child",node,child_pos); editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); if (p_keep_global_xform) { if (node->cast_to<Node2D>()) editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Node2D>()->get_transform()); if (node->cast_to<Spatial>()) editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Spatial>()->get_transform()); if (node->cast_to<Control>()) { bool can_do_it=false; Control *c=node->cast_to<Control>(); if (c->get_parent()->cast_to<Container>()) can_do_it=false; for(int i=0;i<4;i++) { if (c->get_anchor(Margin(i))!=ANCHOR_BEGIN) can_do_it=false; } editor_data->get_undo_redo().add_undo_method(node,"set_pos",node->cast_to<Control>()->get_pos()); } } } perform_node_renames(NULL,&path_renames); editor_data->get_undo_redo().commit_action(); //node->set_owner(owner); }