فهرست منبع

Merge pull request #6930 from bojidar-bg/gdscript-export-array-hint

Allow typing hints for Array class (in GDScript and Inspector)
Rémi Verschelde 8 سال پیش
والد
کامیت
42802ab9dc
4فایلهای تغییر یافته به همراه102 افزوده شده و 16 حذف شده
  1. 33 2
      modules/gdscript/gd_parser.cpp
  2. 41 9
      tools/editor/array_property_edit.cpp
  3. 4 1
      tools/editor/array_property_edit.h
  4. 24 4
      tools/editor/property_editor.cpp

+ 33 - 2
modules/gdscript/gd_parser.cpp

@@ -2658,10 +2658,34 @@ void GDParser::_parse_class(ClassNode *p_class) {
 						current_export.type=type;
 						current_export.usage|=PROPERTY_USAGE_SCRIPT_VARIABLE;
 						tokenizer->advance();
+						
+						String hint_prefix ="";
+						
+						if(type == Variant::ARRAY && tokenizer->get_token()==GDTokenizer::TK_COMMA) {
+							tokenizer->advance();
+
+							while(tokenizer->get_token()==GDTokenizer::TK_BUILT_IN_TYPE) {
+								type = tokenizer->get_token_type();
+								
+								tokenizer->advance();
+
+								if(type == Variant::ARRAY) {
+									hint_prefix += itos(Variant::ARRAY)+":";
+									if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
+										tokenizer->advance();
+									}
+								} else {
+									hint_prefix += itos(type);
+									break;
+								}
+							}
+						}
+						
 						if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
 							// hint expected next!
 							tokenizer->advance();
-							switch(current_export.type) {
+
+							switch(type) {
 
 
 								case Variant::INT: {
@@ -3017,7 +3041,14 @@ void GDParser::_parse_class(ClassNode *p_class) {
 									return;
 								} break;
 							}
-
+							
+						}
+						if(current_export.type == Variant::ARRAY && !hint_prefix.empty()) {
+							if(current_export.hint) {
+								hint_prefix += "/"+itos(current_export.hint);
+							}
+							current_export.hint_string=hint_prefix+":"+current_export.hint_string;
+							current_export.hint=PROPERTY_HINT_NONE;
 						}
 
 					} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {

+ 41 - 9
tools/editor/array_property_edit.cpp

@@ -100,13 +100,19 @@ bool ArrayPropertyEdit::_set(const StringName& p_name, const Variant& p_value){
 					ur->add_undo_method(this,"_set_value",i,arr.get(i));
 
 				}
-			} else if (newsize>size && size) {
+			} else if (newsize>size) {
 
 				Variant init;
 				Variant::CallError ce;
-				init = Variant::construct(arr.get(size-1).get_type(),NULL,0,ce);
-				for(int i=size;i<newsize;i++) {
-					ur->add_do_method(this,"_set_value",i,init);
+				Variant::Type new_type = subtype;
+				if(new_type==Variant::NIL && size) {
+					new_type = arr.get(size-1).get_type();
+				}
+				if(new_type!=Variant::NIL) {
+					init = Variant::construct(new_type,NULL,0,ce);
+					for(int i=size;i<newsize;i++) {
+						ur->add_do_method(this,"_set_value",i,init);
+					}
 				}
 
 			}
@@ -223,28 +229,52 @@ void ArrayPropertyEdit::_get_property_list( List<PropertyInfo> *p_list) const{
 	for(int i=0;i<items;i++) {
 
 		Variant v=arr.get(i+offset);
-		if (arr.get_type()==Variant::ARRAY) {
+		bool is_typed = arr.get_type()!=Variant::ARRAY || subtype!=Variant::NIL;
+		
+		if (!is_typed) {
 			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) {
+		
+		if (is_typed || v.get_type()!=Variant::NIL ) {
 			PropertyInfo pi(v.get_type(),"indices/"+itos(i+offset));
-			if (v.get_type()==Variant::OBJECT) {
+			if(subtype!=Variant::NIL) {
+				pi.type = Variant::Type(subtype);
+				pi.hint = PropertyHint(subtype_hint);
+				pi.hint_string = subtype_hint_string;
+			} else 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,Variant::Type p_deftype) {
+void ArrayPropertyEdit::edit(Object* p_obj,const StringName& p_prop,const String& p_hint_string,Variant::Type p_deftype) {
 
 	page=0;
 	property=p_prop;
 	obj=p_obj->get_instance_ID();
 	default_type=p_deftype;
 
+	if(!p_hint_string.empty()) {
+		int hint_subtype_seperator = p_hint_string.find(":");
+		if(hint_subtype_seperator >= 0) {
+			String subtype_string = p_hint_string.substr(0,hint_subtype_seperator);
+			
+			int slash_pos = subtype_string.find("/");
+			if(slash_pos >= 0) {
+				subtype_hint = PropertyHint(subtype_string.substr(slash_pos+1, subtype_string.size()-slash_pos-1).to_int());
+				subtype_string = subtype_string.substr(0,slash_pos);
+			}
+			
+			subtype_hint_string = p_hint_string.substr(hint_subtype_seperator+1, p_hint_string.size() - hint_subtype_seperator-1);
+			subtype=Variant::Type(subtype_string.to_int());
+		}
+	}
+
 }
 
 Node *ArrayPropertyEdit::get_node() {
@@ -274,5 +304,7 @@ ArrayPropertyEdit::ArrayPropertyEdit()
 		vtypes+=Variant::get_type_name( Variant::Type(i) );
 	}
 	default_type=Variant::NIL;
-
+	subtype=Variant::NIL;
+	subtype_hint=PROPERTY_HINT_NONE;
+	subtype_hint_string="";
 }

+ 4 - 1
tools/editor/array_property_edit.h

@@ -39,6 +39,9 @@ class ArrayPropertyEdit : public Reference {
 	ObjectID obj;
 	StringName property;
 	String vtypes;
+	String subtype_hint_string;
+	PropertyHint subtype_hint;
+	Variant::Type subtype;
 	Variant get_array() const;
 	Variant::Type default_type;
 
@@ -56,7 +59,7 @@ protected:
 
 public:
 
-	void edit(Object* p_obj, const StringName& p_prop, Variant::Type p_deftype);
+	void edit(Object* p_obj, const StringName& p_prop, const String& p_hint_string, Variant::Type p_deftype);
 
 	Node *get_node();
 

+ 24 - 4
tools/editor/property_editor.cpp

@@ -3350,7 +3350,7 @@ void PropertyEditor::update_tree() {
 						max=p.hint_string.get_slice(",",1).to_double();
 					}
 
-					if (p.type!=PROPERTY_HINT_SPRITE_FRAME && c>=3) {
+					if (p.hint!=PROPERTY_HINT_SPRITE_FRAME && c>=3) {
 
 						step= p.hint_string.get_slice(",",2).to_double();
 					}
@@ -3495,10 +3495,30 @@ void PropertyEditor::update_tree() {
 
 
 				Variant v = obj->get(p.name);
+				String type_name = "Array";
+				String type_name_suffix = "";
+				
+				String hint = p.hint_string;
+				while(hint.begins_with(itos(Variant::ARRAY)+":")) {
+					type_name += "<Array";
+					type_name_suffix += ">";
+					hint = hint.substr(2, hint.size()-2);
+				}
+				if(hint.find(":") >= 0) {
+					hint = hint.substr(0,hint.find(":"));
+					if(hint.find("/") >= 0) {
+						hint = hint.substr(0,hint.find("/"));
+					}
+					type_name += "<" + Variant::get_type_name(Variant::Type(hint.to_int()));
+					type_name_suffix += ">";
+				}
+				type_name += type_name_suffix;
+				
 				if (v.is_array())
-					item->set_text(1,"Array["+itos(v.call("size"))+"]");
+					item->set_text(1,type_name+"["+itos(v.call("size"))+"]");
 				else
-					item->set_text(1,"Array[]");
+					item->set_text(1,type_name+"[]");
+				
 				if (show_type_icons)
 					item->set_icon( 0, get_icon("ArrayData","EditorIcons") );
 
@@ -4233,7 +4253,7 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
 			}
 
 			Ref<ArrayPropertyEdit> ape = memnew( ArrayPropertyEdit );
-			ape->edit(obj,n,Variant::Type(t));
+			ape->edit(obj,n,ht,Variant::Type(t));
 
 			EditorNode::get_singleton()->push_item(ape.ptr());
 		}