Jelajahi Sumber

Merge branch 'master' of https://github.com/okamstudio/godot

Mariano Javier Suligoy 10 tahun lalu
induk
melakukan
cbf05355ed

+ 3 - 3
tools/editor/editor_data.cpp

@@ -39,7 +39,7 @@ void EditorHistory::_cleanup_history() {
 		bool fail=false;
 
 		for(int j=0;j<history[i].path.size();j++) {
-			if (!history[i].path[j].res.is_null())
+			if (!history[i].path[j].ref.is_null())
 				continue;
 
 			if (ObjectDB::get_instance(history[i].path[j].object))
@@ -70,10 +70,10 @@ void EditorHistory::_add_object(ObjectID p_object,const String& p_property,int p
 
 	Object *obj = ObjectDB::get_instance(p_object);
 	ERR_FAIL_COND(!obj);
-	Resource *r = obj->cast_to<Resource>();
+	Reference *r = obj->cast_to<Reference>();
 	Obj o;
 	if (r)
-		o.res=RES(r);
+		o.ref=REF(r);
 	o.object=p_object;
 	o.property=p_property;
 

+ 1 - 1
tools/editor/editor_data.h

@@ -45,7 +45,7 @@ class EditorHistory {
 
 	struct Obj {
 
-		RES res;
+		REF ref;
 		ObjectID object;
 		String property;
 	};

+ 7 - 4
tools/editor/editor_node.cpp

@@ -1427,10 +1427,7 @@ void EditorNode::_edit_current() {
 
 		resources_dock->add_resource(Ref<Resource>(current_res));
 		//top_pallete->set_current_tab(1);
-	}
-
-
-	if (current_obj->is_type("Node")) {
+	} else if (current_obj->is_type("Node")) {
 
 		Node * current_node = current_obj->cast_to<Node>();
 		ERR_FAIL_COND(!current_node);
@@ -1445,6 +1442,12 @@ void EditorNode::_edit_current() {
 
 		//top_pallete->set_current_tab(0);
 
+	} else {
+
+		property_editor->edit( current_obj );
+		//scene_tree_dock->set_selected(current_node);
+		//object_menu->get_popup()->clear();
+
 	}
 
 	/* Take care of PLUGIN EDITOR */

TEMPAT SAMPAH
tools/editor/icons/icon_multi_node_edit.png


+ 118 - 0
tools/editor/multi_node_edit.cpp

@@ -0,0 +1,118 @@
+#include "multi_node_edit.h"
+#include "editor_node.h"
+
+bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){
+
+	Node *es = EditorNode::get_singleton()->get_edited_scene();
+	if (!es)
+		return false;
+
+	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+
+	ur->create_action("MultiNode Set "+String(p_name));
+	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+		if (!es->has_node(E->get()))
+			continue;
+
+		Node*n=es->get_node(E->get());
+		if (!n)
+			continue;
+
+		ur->add_do_property(n,p_name,p_value);
+		ur->add_undo_property(n,p_name,n->get(p_name));
+
+	}
+
+	ur->commit_action();
+	return true;
+}
+
+bool MultiNodeEdit::_get(const StringName& p_name,Variant &r_ret) const {
+
+	Node *es = EditorNode::get_singleton()->get_edited_scene();
+	if (!es)
+		return false;
+
+	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+		if (!es->has_node(E->get()))
+			continue;
+
+		const Node*n=es->get_node(E->get());
+		if (!n)
+			continue;
+
+		bool found;
+		r_ret=n->get(p_name,&found);
+		if (found)
+			return true;
+
+	}
+
+	return false;
+}
+
+void MultiNodeEdit::_get_property_list( List<PropertyInfo> *p_list) const{
+
+	HashMap<String,PLData> usage;
+
+	Node *es = EditorNode::get_singleton()->get_edited_scene();
+	if (!es)
+		return;
+
+	int nc=0;
+
+	List<PLData*> datas;
+
+	for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+		if (!es->has_node(E->get()))
+			continue;
+
+		Node*n=es->get_node(E->get());
+		if (!n)
+			continue;
+
+		List<PropertyInfo> plist;
+		n->get_property_list(&plist,true);
+
+		for(List<PropertyInfo>::Element *F=plist.front();F;F=F->next()) {
+
+			if (!usage.has(F->get().name)) {
+				PLData pld;
+				pld.uses=0;
+				pld.info=F->get();
+				usage[F->get().name]=pld;
+				datas.push_back(usage.getptr(F->get().name));
+			}
+
+			usage[F->get().name].uses++;
+		}
+
+		nc++;
+	}
+
+	for (List<PLData*>::Element *E=datas.front();E;E=E->next()) {
+
+		if (nc==E->get()->uses) {
+			p_list->push_back(E->get()->info);
+		}
+	}
+
+
+}
+
+void MultiNodeEdit::clear_nodes() {
+
+	nodes.clear();
+}
+
+void MultiNodeEdit::add_node(const NodePath& p_node){
+
+	nodes.push_back(p_node);
+}
+
+MultiNodeEdit::MultiNodeEdit()
+{
+}

+ 32 - 0
tools/editor/multi_node_edit.h

@@ -0,0 +1,32 @@
+#ifndef MULTI_NODE_EDIT_H
+#define MULTI_NODE_EDIT_H
+
+#include "scene/main/node.h"
+
+class MultiNodeEdit : public Reference {
+
+	OBJ_TYPE(MultiNodeEdit,Reference);
+
+	List<NodePath> nodes;
+	struct PLData {
+		int uses;
+		PropertyInfo info;
+	};
+
+protected:
+
+	bool _set(const StringName& p_name, const Variant& p_value);
+	bool _get(const StringName& p_name,Variant &r_ret) const;
+	void _get_property_list( List<PropertyInfo> *p_list) const;
+
+public:
+
+
+
+	void clear_nodes();
+	void add_node(const NodePath& p_node);
+
+	MultiNodeEdit();
+};
+
+#endif // MULTI_NODE_EDIT_H

+ 2 - 1
tools/editor/property_editor.cpp

@@ -39,6 +39,7 @@
 #include "editor_settings.h"
 #include "editor_import_export.h"
 #include "editor_node.h"
+#include "multi_node_edit.h"
 
 void CustomPropertyEditor::_notification(int p_what) {
 	
@@ -2676,7 +2677,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
 		}
 	}
 
-	if (!undo_redo) {
+	if (!undo_redo || obj->cast_to<MultiNodeEdit>()) { //kind of hacky
 
 		obj->set(p_name,p_value);
 		_changed_callbacks(obj,p_name);

+ 34 - 1
tools/editor/scene_tree_dock.cpp

@@ -35,7 +35,7 @@
 #include "tools/editor/plugins/canvas_item_editor_plugin.h"
 #include "script_editor_debugger.h"
 #include "tools/editor/plugins/script_editor_plugin.h"
-
+#include "multi_node_edit.h"
 void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
 
 
@@ -449,6 +449,19 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 			reparent_dialog->popup_centered_ratio();
 			reparent_dialog->set_current( nodeset );
 
+		} break;
+		case TOOL_MULTI_EDIT: {
+
+			Node*root=EditorNode::get_singleton()->get_edited_scene();
+			if (!root)
+				break;
+			Ref<MultiNodeEdit> mne = memnew( MultiNodeEdit );
+			for (const Map<Node*,Object*>::Element *E=EditorNode::get_singleton()->get_editor_selection()->get_selection().front();E;E=E->next()) {
+				mne->add_node(root->get_path_to(E->key()));
+			}
+
+			EditorNode::get_singleton()->push_item(mne.ptr());
+
 		} break;
 		case TOOL_ERASE: {
 
@@ -507,6 +520,7 @@ void SceneTreeDock::_notification(int p_what) {
 				"MoveDown",
 				"Duplicate",
 				"Reparent",
+				"MultiNodeEdit",
 				"Remove",
 			};
 
@@ -515,6 +529,8 @@ void SceneTreeDock::_notification(int p_what) {
 			for(int i=0;i<TOOL_BUTTON_MAX;i++)
 				tool_buttons[i]->set_icon(get_icon(button_names[i],"EditorIcons"));
 
+			EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed",this,"_selection_changed");
+
 		} break;
 	}
 }
@@ -1075,9 +1091,19 @@ void SceneTreeDock::_update_tool_buttons() {
 	tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
 	tool_buttons[TOOL_REPARENT]->set_disabled(disable_root);
 	tool_buttons[TOOL_ERASE]->set_disabled(disable);
+	tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
+
 
 }
 
+
+void SceneTreeDock::_selection_changed() {
+
+	tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
+
+}
+
+
 void SceneTreeDock::_create() {
 
 
@@ -1262,6 +1288,7 @@ void SceneTreeDock::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_delete_confirm"),&SceneTreeDock::_delete_confirm);
 	ObjectTypeDB::bind_method(_MD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed);
 	ObjectTypeDB::bind_method(_MD("_import_subscene"),&SceneTreeDock::_import_subscene);
+	ObjectTypeDB::bind_method(_MD("_selection_changed"),&SceneTreeDock::_selection_changed);
 
 	ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance);
 }
@@ -1364,6 +1391,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
 
 	hbc_bottom->add_spacer();
 
+	tb = memnew( ToolButton );
+	tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MULTI_EDIT, false));
+	tb->set_tooltip("Multi-Edit Selected Nodes");
+	hbc_bottom->add_child(tb);
+	tool_buttons[TOOL_MULTI_EDIT]=tb;
+
 	tb = memnew( ToolButton );
 	tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_ERASE, false));
 	tb->set_tooltip("Erase Selected Node(s)");

+ 2 - 0
tools/editor/scene_tree_dock.h

@@ -62,6 +62,7 @@ class SceneTreeDock : public VBoxContainer {
 		TOOL_MOVE_DOWN,
 		TOOL_DUPLICATE,
 		TOOL_REPARENT,
+		TOOL_MULTI_EDIT,
 		TOOL_ERASE,
 		TOOL_BUTTON_MAX
 	};
@@ -119,6 +120,7 @@ class SceneTreeDock : public VBoxContainer {
 	void _import_subscene();
 
 	bool _validate_no_foreign();
+	void _selection_changed();
 
 	void _fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node, List<Pair<NodePath,NodePath> > *p_renames);