Пример #1
0
void SceneTreeDock::_node_prerenamed(Node* p_node, const String& p_new_name) {


	List<Pair<NodePath,NodePath> > path_renames;

	Vector<StringName> base_path;
	Node *n = p_node->get_parent();
	while(n) {
		base_path.push_back(n->get_name());
		n=n->get_parent();
	}
	base_path.invert();


	Vector<StringName> new_base_path=base_path;
	base_path.push_back(p_node->get_name());

	new_base_path.push_back(p_new_name);

	Pair<NodePath,NodePath> npp;
	npp.first = NodePath(base_path,true);
	npp.second = NodePath(new_base_path,true);
	path_renames.push_back(npp);


	for(int i=0;i<p_node->get_child_count();i++)
		_fill_path_renames(base_path,new_base_path,p_node->get_child(i),&path_renames);

	perform_node_renames(NULL,&path_renames);

}
Пример #2
0
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();

}
Пример #3
0
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);
}
Пример #4
0
void SceneTreeDock::perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims) {

	Map<Ref<Animation>, Set<int> > rem_anims;

	if (!r_rem_anims)
		r_rem_anims=&rem_anims;

	if (!bool(EDITOR_DEF("animation/autorename_animation_tracks",true)))
		return;

	if (!p_base) {

		p_base=edited_scene;
	}

	if (!p_base)
		return;


	if (p_base->cast_to<AnimationPlayer>()) {

		AnimationPlayer *ap=p_base->cast_to<AnimationPlayer>();
		List<StringName> anims;
		ap->get_animation_list(&anims);
		Node *root = ap->get_node(ap->get_root());


		if (root) {


			NodePath root_path=root->get_path();
			NodePath new_root_path=root_path;


			for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) {

				if (E->get().first==root_path) {
					new_root_path=E->get().second;
					break;
				}
			}

			if (new_root_path!=NodePath()) {
				//will not be erased

				for(List<StringName>::Element *E=anims.front();E;E=E->next()) {

					Ref<Animation> anim=ap->get_animation(E->get());
					if (!r_rem_anims->has(anim)) {
						r_rem_anims->insert(anim,Set<int>());
						Set<int> &ran = r_rem_anims->find(anim)->get();
						for(int i=0;i<anim->get_track_count();i++)
							ran.insert(i);
					}

					Set<int> &ran = r_rem_anims->find(anim)->get();

					if (anim.is_null())
						continue;

					for(int i=0;i<anim->get_track_count();i++) {

						NodePath track_np=anim->track_get_path(i);
						Node *n = root->get_node(track_np);
						if (!n) {
							continue;
						}

						NodePath old_np = n->get_path();

						if (!ran.has(i))
							continue; //channel was removed

						for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) {

							if (E->get().first==old_np) {


								if (E->get().second==NodePath()) {
									//will be erased

									int idx=0;
									Set<int>::Element *EI=ran.front();
									ERR_FAIL_COND(!EI); //bug
									while(EI->get()!=i) {
										idx++;
										EI=EI->next();
										ERR_FAIL_COND(!EI); //another bug

									}

									editor_data->get_undo_redo().add_do_method(anim.ptr(),"remove_track",idx);
									editor_data->get_undo_redo().add_undo_method(anim.ptr(),"add_track",anim->track_get_type(i),idx);
									editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",idx,track_np);
									editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_interpolation_type",idx,anim->track_get_interpolation_type(i));
									for(int j=0;j<anim->track_get_key_count(i);j++) {

										editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_insert_key",idx,anim->track_get_key_time(i,j),anim->track_get_key_value(i,j),anim->track_get_key_transition(i,j));
									}

									ran.erase(i); //byebye channel

								} else {
									//will be renamed
									NodePath rel_path = new_root_path.rel_path_to(E->get().second);

									NodePath new_path = NodePath( rel_path.get_names(), track_np.get_subnames(), false, track_np.get_property() );
									if (new_path==track_np)
										continue; //bleh
									editor_data->get_undo_redo().add_do_method(anim.ptr(),"track_set_path",i,new_path);
									editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",i,track_np);
								}
							}
						}
					}
				}
			}
		}
	}


	for(int i=0;i<p_base->get_child_count();i++)
		perform_node_renames(p_base->get_child(i),p_renames,r_rem_anims);

}
Пример #5
0
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);
}