Sfoglia il codice sorgente

Ability to edit all kinds of arrays from the property editor.
Yes, I'm trying to convince you to test the alpha release by adding all these now :)

Juan Linietsky 10 anni fa
parent
commit
04cb3c9eb1

+ 3 - 3
modules/gdscript/gd_parser.cpp

@@ -2625,14 +2625,14 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 					Node *subexpr=NULL;
 
-					subexpr = _parse_and_reduce_expression(p_class,false);
+					subexpr = _parse_and_reduce_expression(p_class,false,autoexport);
 					if (!subexpr)
 						return;
 
 					member.expression=subexpr;
 
 					if (autoexport) {
-						if (subexpr->type==Node::TYPE_ARRAY) {
+						if (1)/*(subexpr->type==Node::TYPE_ARRAY) {
 
 							member._export.type=Variant::ARRAY;
 
@@ -2640,7 +2640,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 							member._export.type=Variant::DICTIONARY;
 
-						} else {
+						} else*/ {
 
 							if (subexpr->type!=Node::TYPE_CONSTANT) {
 

+ 224 - 0
tools/editor/array_property_edit.cpp

@@ -0,0 +1,224 @@
+#include "array_property_edit.h"
+
+#include "editor_node.h"
+
+#define ITEMS_PER_PAGE 100
+
+Variant ArrayPropertyEdit::get_array() const{
+
+	Object*o = ObjectDB::get_instance(obj);
+	if (!o)
+		return Array();
+	return o->get(property);
+}
+
+void ArrayPropertyEdit::_notif_change() {
+	_change_notify();
+}
+void ArrayPropertyEdit::_notif_changev(const String& p_v) {
+
+	_change_notify(p_v.utf8().get_data());
+}
+
+void ArrayPropertyEdit::_set_size(int p_size) {
+
+	Variant arr = get_array();
+	arr.call("resize",p_size);
+	Object*o = ObjectDB::get_instance(obj);
+	if (!o)
+		return;
+
+	o->set(property,arr);
+
+}
+
+void ArrayPropertyEdit::_set_value(int p_idx,const Variant& p_value) {
+
+	Variant arr = get_array();
+	arr.set(p_idx,p_value);
+	Object*o = ObjectDB::get_instance(obj);
+	if (!o)
+		return;
+
+	o->set(property,arr);
+}
+
+bool ArrayPropertyEdit::_set(const StringName& p_name, const Variant& p_value){
+
+	String pn=p_name;
+
+	if (pn.begins_with("array/")) {
+
+		if (pn=="array/size") {
+
+			Variant arr = get_array();
+			int size = arr.call("size");
+
+			int newsize=p_value;
+			if (newsize==size)
+				return true;
+
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+			ur->create_action("Resize Array");
+			ur->add_do_method(this,"_set_size",newsize);
+			ur->add_undo_method(this,"_set_size",size);
+			if (newsize<size) {
+				for(int i=newsize;i<size;i++) {
+					ur->add_undo_method(this,"_set_value",i,arr.get(i));
+
+				}
+			}
+			ur->add_do_method(this,"_notif_change");
+			ur->add_undo_method(this,"_notif_change");
+			ur->commit_action();
+			return true;
+		}
+		if (pn=="array/page") {
+			page=p_value;
+			_change_notify();
+			return true;
+		}
+	} else if (pn.begins_with("indices")) {
+
+		if (pn.find("_")!=-1) {
+			//type
+			int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
+
+			int type = p_value;
+
+			Variant arr = get_array();
+
+			Variant value = arr.get(idx);
+			if (value.get_type()!=type && type>=0 && type<Variant::VARIANT_MAX) {
+				Variant::CallError ce;
+				Variant new_value=Variant::construct(Variant::Type(type),NULL,0,ce);
+				UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+				ur->create_action("Change Array Value Type");
+				ur->add_do_method(this,"_set_value",idx,new_value);
+				ur->add_undo_method(this,"_set_value",idx,value);
+				ur->add_do_method(this,"_notif_change");
+				ur->add_undo_method(this,"_notif_change");
+				ur->commit_action();
+
+			}
+			return true;
+
+		} else {
+			int idx=pn.get_slicec('/',1).to_int();
+			Variant arr = get_array();
+
+			Variant value = arr.get(idx);
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+			ur->create_action("Change Array Value");
+			ur->add_do_method(this,"_set_value",idx,p_value);
+			ur->add_undo_method(this,"_set_value",idx,value);
+			ur->add_do_method(this,"_notif_changev",p_name);
+			ur->add_undo_method(this,"_notif_changev",p_name);
+			ur->commit_action();
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool ArrayPropertyEdit::_get(const StringName& p_name,Variant &r_ret) const {
+
+	Variant arr = get_array();
+	//int size = arr.call("size");
+
+	String pn=p_name;
+	if (pn.begins_with("array/")) {
+
+		if (pn=="array/size") {
+			r_ret=arr.call("size");
+			return true;
+		}
+		if (pn=="array/page") {
+			r_ret=page;
+			return true;
+		}
+	} else if (pn.begins_with("indices")) {
+
+		if (pn.find("_")!=-1) {
+			//type
+			int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
+			bool valid;
+			r_ret=arr.get(idx,&valid);
+			if (valid)
+				r_ret=r_ret.get_type();
+			return valid;
+
+		} else {
+			int idx=pn.get_slicec('/',1).to_int();
+			bool valid;
+			r_ret=arr.get(idx,&valid);
+			return valid;
+		}
+	}
+
+	return false;
+}
+
+void ArrayPropertyEdit::_get_property_list( List<PropertyInfo> *p_list) const{
+
+	Variant arr = get_array();
+	int size = arr.call("size");
+
+	p_list->push_back( PropertyInfo(Variant::INT,"array/size",PROPERTY_HINT_RANGE,"0,100000,1") );
+	int pages = size/ITEMS_PER_PAGE;
+	if (pages>0)
+		p_list->push_back( PropertyInfo(Variant::INT,"array/page",PROPERTY_HINT_RANGE,"0,"+itos(pages)+",1") );
+
+	int offset=page*ITEMS_PER_PAGE;
+
+	int items=MIN(size-offset,ITEMS_PER_PAGE);
+
+
+	for(int i=0;i<items;i++) {
+
+		Variant v=arr.get(i+offset);
+		if (arr.get_type()==Variant::ARRAY) {
+			p_list->push_back(PropertyInfo(Variant::INT,"indices/"+itos(i+offset)+"_type",PROPERTY_HINT_ENUM,vtypes));
+		}
+		if (arr.get_type()!=Variant::ARRAY || v.get_type()!=Variant::NIL) {
+			PropertyInfo pi(v.get_type(),"indices/"+itos(i+offset));
+			if (v.get_type()==Variant::OBJECT) {
+				pi.hint=PROPERTY_HINT_RESOURCE_TYPE;
+				pi.hint_string="Resource";
+			}
+			p_list->push_back(pi);
+		}
+	}
+
+}
+
+void ArrayPropertyEdit::edit(Object* p_obj,const StringName& p_prop) {
+
+	page=0;
+	property=p_prop;
+	obj=p_obj->get_instance_ID();
+
+}
+
+void ArrayPropertyEdit::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("_set_size"),&ArrayPropertyEdit::_set_size);
+	ObjectTypeDB::bind_method(_MD("_set_value"),&ArrayPropertyEdit::_set_value);
+	ObjectTypeDB::bind_method(_MD("_notif_change"),&ArrayPropertyEdit::_notif_change);
+	ObjectTypeDB::bind_method(_MD("_notif_changev"),&ArrayPropertyEdit::_notif_changev);
+}
+
+ArrayPropertyEdit::ArrayPropertyEdit()
+{
+	page=0;
+	for(int i=0;i<Variant::VARIANT_MAX;i++) {
+
+		if (i>0)
+			vtypes+=",";
+		vtypes+=Variant::get_type_name( Variant::Type(i) );
+	}
+
+}

+ 35 - 0
tools/editor/array_property_edit.h

@@ -0,0 +1,35 @@
+#ifndef ARRAY_PROPERTY_EDIT_H
+#define ARRAY_PROPERTY_EDIT_H
+
+#include "scene/main/node.h"
+
+class ArrayPropertyEdit : public Reference {
+
+	OBJ_TYPE(ArrayPropertyEdit,Reference);
+
+	int page;
+	ObjectID obj;
+	StringName property;
+	String vtypes;
+	Variant get_array() const;
+
+	void _notif_change();
+	void _notif_changev(const String& p_v);
+	void _set_size(int p_size);
+	void _set_value(int p_idx,const Variant& p_value);
+
+protected:
+
+	static void _bind_methods();
+	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 edit(Object* p_obj,const StringName& p_prop);
+
+	ArrayPropertyEdit();
+};
+
+#endif // ARRAY_PROPERTY_EDIT_H

+ 104 - 9
tools/editor/property_editor.cpp

@@ -40,6 +40,7 @@
 #include "editor_import_export.h"
 #include "editor_node.h"
 #include "multi_node_edit.h"
+#include "array_property_edit.h"
 
 void CustomPropertyEditor::_notification(int p_what) {
 	
@@ -2450,11 +2451,32 @@ void PropertyEditor::update_tree() {
 				}
 
 			} break;
+			case Variant::ARRAY: {
+
+				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"Array["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"Array[]");
+				item->set_icon( 0, get_icon("ArrayData","EditorIcons") );
+
+
+			} break;
+
 			case Variant::INT_ARRAY: {
 
 				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
-				item->set_editable( 1, !read_only );
-				item->set_text(1,"[IntArray]");
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"IntArray["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"IntArray[]");
 				item->set_icon( 0, get_icon("ArrayInt","EditorIcons") );
 
 
@@ -2462,26 +2484,86 @@ void PropertyEditor::update_tree() {
 			case Variant::REAL_ARRAY: {
 
 				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
-				item->set_editable( 1, !read_only );
-				item->set_text(1,"[RealArray]");
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"FloatArray["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"FloatArray[]");
 				item->set_icon( 0, get_icon("ArrayReal","EditorIcons") );
 
+
 			} break;
 			case Variant::STRING_ARRAY: {
 
 				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
-				item->set_editable( 1, !read_only );
-				item->set_text(1,"[StringArray]");
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"String["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"String[]");
 				item->set_icon( 0, get_icon("ArrayString","EditorIcons") );
 
+
 			} break;
 			case Variant::RAW_ARRAY: {
 
 				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
-				item->set_editable( 1, !read_only );
-				item->set_text(1,"[Raw Data]");
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"Byte["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"Byte[]");
 				item->set_icon( 0, get_icon("ArrayData","EditorIcons") );
 
+
+			} break;
+			case Variant::VECTOR2_ARRAY: {
+
+				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"Vector2["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"Vector2[]");
+				item->set_icon( 0, get_icon("Vector2","EditorIcons") );
+
+
+			} break;
+			case Variant::VECTOR3_ARRAY: {
+
+				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"Vector3["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"Vector3[]");
+				item->set_icon( 0, get_icon("Vector","EditorIcons") );
+
+
+			} break;
+			case Variant::COLOR_ARRAY: {
+
+				item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+				item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+				Variant v = obj->get(p.name);
+				if (v.is_array())
+					item->set_text(1,"Color["+itos(v.call("size"))+"]");
+				else
+					item->set_text(1,"Color[]");
+				item->set_icon( 0, get_icon("Color","EditorIcons") );
+
+
 			} break;
 			case Variant::VECTOR2: {
 
@@ -2677,7 +2759,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
 		}
 	}
 
-	if (!undo_redo || obj->cast_to<MultiNodeEdit>()) { //kind of hacky
+	if (!undo_redo || obj->cast_to<MultiNodeEdit>() || obj->cast_to<ArrayPropertyEdit>()) { //kind of hacky
 
 		obj->set(p_name,p_value);
 		_changed_callbacks(obj,p_name);
@@ -2997,6 +3079,19 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
 
 				emit_signal("resource_selected",r,n);
 			}
+		} else if (t==Variant::ARRAY || t==Variant::INT_ARRAY || t==Variant::REAL_ARRAY || t==Variant::STRING_ARRAY || t==Variant::VECTOR2_ARRAY || t==Variant::VECTOR3_ARRAY || t==Variant::COLOR_ARRAY || t==Variant::RAW_ARRAY) {
+
+			Variant v = obj->get(n);
+
+			if (v.get_type()!=t) {
+				Variant::CallError ce;
+				v=Variant::construct(Variant::Type(t),NULL,0,ce);
+			}
+
+			Ref<ArrayPropertyEdit> ape = memnew( ArrayPropertyEdit );
+			ape->edit(obj,n);
+
+			EditorNode::get_singleton()->push_item(ape.ptr());
 		}
 	}
 }