diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2017-11-23 15:41:07 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2017-11-23 15:54:11 +0300 |
commit | 23d148ecaf923a490c3dd4a22d6dd96ea7cb9654 (patch) | |
tree | cbc096d925f772bd28b21c18766ddf795af78f46 /source/blender/makesrna | |
parent | 545f671b80f2ad39c8fdee07db3b03119c274187 (diff) |
RNA: Allow structs to define tags for their properties
Adds support for defining a number of tags as part of the rna-struct
definition, which its properties can set similar to property-flags.
BPY supports setting these tags when defining custom properties too.
* To define tags for a struct (which its properties can use then), define the tags in an `EnumPropertyItem` array, and assign them to the struct using `RNA_def_struct_property_tags(...)`.
* To set tags for an RNA-property in C, use the new `RNA_def_property_tags(...)`.
* To set tags for an RNA-property in Python, use the newly added tags parameter. E.g. `bpy.props.FloatProperty(name="Some Float", tags={'SOME_TAG', 'ANOTHER_TAG'})`.
Actual usage of this will be added in a follow-up commit.
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_define.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 28 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 17 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 56 |
7 files changed, 113 insertions, 2 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index ed1795fd39c..9aabf1b70dc 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -761,6 +761,7 @@ const char *RNA_struct_translation_context(const StructRNA *type); int RNA_struct_ui_icon(const StructRNA *type); PropertyRNA *RNA_struct_name_property(const StructRNA *type); +const EnumPropertyItem *RNA_struct_property_tag_defines(const StructRNA *type); PropertyRNA *RNA_struct_iterator_property(StructRNA *type); StructRNA *RNA_struct_base(StructRNA *type); const StructRNA *RNA_struct_base_child_of(const StructRNA *type, const StructRNA *parent_type); @@ -816,6 +817,7 @@ PropertyType RNA_property_type(PropertyRNA *prop); PropertySubType RNA_property_subtype(PropertyRNA *prop); PropertyUnit RNA_property_unit(PropertyRNA *prop); int RNA_property_flag(PropertyRNA *prop); +int RNA_property_tags(PropertyRNA *prop); bool RNA_property_builtin(PropertyRNA *prop); void *RNA_property_py_data_get(PropertyRNA *prop); @@ -852,6 +854,7 @@ bool RNA_enum_name(const EnumPropertyItem *item, const int value, const char **r bool RNA_enum_description(const EnumPropertyItem *item, const int value, const char **description); int RNA_enum_from_value(const EnumPropertyItem *item, const int value); int RNA_enum_from_identifier(const EnumPropertyItem *item, const char *identifier); +unsigned int RNA_enum_items_count(const EnumPropertyItem *item); void RNA_property_enum_items_ex( struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const bool use_static, diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 47648583e14..e9e4276b235 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -66,6 +66,7 @@ void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop); void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname); void RNA_def_struct_flag(StructRNA *srna, int flag); void RNA_def_struct_clear_flag(StructRNA *srna, int flag); +void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines); void RNA_def_struct_refine_func(StructRNA *srna, const char *refine); void RNA_def_struct_idprops_func(StructRNA *srna, const char *refine); void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance); @@ -148,6 +149,7 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag); void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag); +void RNA_def_property_tags(PropertyRNA *prop, int tags); void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype); void RNA_def_property_array(PropertyRNA *prop, int length); void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[]); diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 8f07a6e22d9..293cef52b90 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -3000,7 +3000,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr else fprintf(f, "NULL,\n"); fprintf(f, "\t%d, ", prop->magic); rna_print_c_string(f, prop->identifier); - fprintf(f, ", %d, %d, %d, ", prop->flag, prop->flag_parameter, prop->flag_internal); + fprintf(f, ", %d, %d, %d, %d, ", prop->flag, prop->flag_parameter, prop->flag_internal, prop->tags); rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); rna_print_c_string(f, prop->description); fprintf(f, ",\n\t"); fprintf(f, "%d, ", prop->icon); @@ -3244,7 +3244,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE fprintf(f, "\t"); rna_print_c_string(f, srna->identifier); fprintf(f, ", NULL, NULL"); /* PyType - Cant initialize here */ - fprintf(f, ", %d, ", srna->flag); + fprintf(f, ", %d, NULL, ", srna->flag); rna_print_c_string(f, srna->name); fprintf(f, ",\n\t"); rna_print_c_string(f, srna->description); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index d088a7c23e6..4aebcbb0aaf 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -566,6 +566,11 @@ PropertyRNA *RNA_struct_name_property(const StructRNA *type) return type->nameproperty; } +const EnumPropertyItem *RNA_struct_property_tag_defines(const StructRNA *type) +{ + return type->prop_tag_defines; +} + PropertyRNA *RNA_struct_iterator_property(StructRNA *type) { return type->iteratorproperty; @@ -947,6 +952,17 @@ int RNA_property_flag(PropertyRNA *prop) return rna_ensure_property(prop)->flag; } +/** + * Get the tags set for \a prop as int bitfield. + * \note Doesn't perform any validity check on the set bits. #RNA_def_property_tags does this + * in debug builds (to avoid performance issues in non-debug builds), which should be + * the only way to set tags. Hence, at this point we assume the tag bitfield to be valid. + */ +int RNA_property_tags(PropertyRNA *prop) +{ + return rna_ensure_property(prop)->tags; +} + bool RNA_property_builtin(PropertyRNA *prop) { return (rna_ensure_property(prop)->flag_internal & PROP_INTERN_BUILTIN) != 0; @@ -1613,6 +1629,18 @@ int RNA_enum_from_value(const EnumPropertyItem *item, const int value) return -1; } +unsigned int RNA_enum_items_count(const EnumPropertyItem *item) +{ + unsigned int i = 0; + + while (item->identifier) { + item++; + i++; + } + + return i; +} + bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier) { diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index fd511655c5f..c8a6a503fd9 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -966,6 +966,11 @@ void RNA_def_struct_clear_flag(StructRNA *srna, int flag) srna->flag &= ~flag; } +void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines) +{ + srna->prop_tag_defines = prop_tag_defines; +} + void RNA_def_struct_refine_func(StructRNA *srna, const char *refine) { if (!DefRNA.preprocess) { @@ -1280,6 +1285,18 @@ void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag) prop->flag &= ~flag; } +/** + * Add the property-tags passed as \a tags to \a prop (if valid). + * + * \note Multiple tags can be set by passing them within \a tags (using bitflags). + * \note Doesn't do any type-checking with the tags defined in the parent StructRNA + * of \a prop. This should be done before (e.g. see #WM_operatortype_prop_tag). + */ +void RNA_def_property_tags(PropertyRNA *prop, int tags) +{ + prop->tags |= tags; +} + void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter) { prop->flag |= flag_property; diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index bf34d42116e..b43423464e9 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -159,6 +159,8 @@ struct PropertyRNA { short flag_parameter; /* Internal ("private") flags. */ short flag_internal; + /* The subset of StructRNA.prop_tag_defines values that applies to this property. */ + short tags; /* user readable name */ const char *name; @@ -356,6 +358,9 @@ struct StructRNA { /* various options */ int flag; + /* Each StructRNA type can define own tags which properties can set + * (PropertyRNA.tags) for changed behavior based on struct-type. */ + const EnumPropertyItem *prop_tag_defines; /* user readable name */ const char *name; diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 1d87bdb972e..507262675b3 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -330,6 +330,16 @@ static PointerRNA rna_Struct_functions_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, &RNA_Function, internal->link); } +static void rna_Struct_property_tags_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + /* here ptr->data should always be the same as iter->parent.type */ + StructRNA *srna = (StructRNA *)ptr->data; + const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna); + unsigned int tag_count = RNA_enum_items_count(tag_defines); + + rna_iterator_array_begin(iter, (void *)tag_defines, sizeof(EnumPropertyItem), tag_count, 0, NULL); +} + /* Builtin properties iterator re-uses the Struct properties iterator, only * difference is that we need to set the ptr data to the type of the struct * whose properties we want to iterate over. */ @@ -603,6 +613,34 @@ static int rna_Property_is_library_editable_flag_get(PointerRNA *ptr) return (prop->flag & PROP_LIB_EXCEPTION) != 0; } +static int rna_Property_tags_get(PointerRNA *ptr) +{ + return RNA_property_tags(ptr->data); +} + +static const EnumPropertyItem *rna_Property_tags_itemf( + bContext *UNUSED(C), PointerRNA *ptr, + PropertyRNA *UNUSED(prop), bool *r_free) +{ + PropertyRNA *this_prop = (PropertyRNA *)ptr->data; + const StructRNA *srna = RNA_property_pointer_type(ptr, this_prop); + EnumPropertyItem *prop_tags; + EnumPropertyItem tmp = {0, "", 0, "", ""}; + int totitem = 0; + + for (const EnumPropertyItem *struct_tags = RNA_struct_property_tag_defines(srna); + struct_tags->identifier; + struct_tags++) + { + memcpy(&tmp, struct_tags, sizeof(tmp)); + RNA_enum_item_add(&prop_tags, &totitem, &tmp); + } + RNA_enum_item_end(&prop_tags, &totitem); + *r_free = true; + + return prop_tags; +} + static int rna_Property_array_length_get(PointerRNA *ptr) { PropertyRNA *prop = (PropertyRNA *)ptr->data; @@ -1112,6 +1150,14 @@ static void rna_def_struct(BlenderRNA *brna) "rna_iterator_listbase_end", "rna_Struct_functions_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Functions", ""); + + prop = RNA_def_property(srna, "property_tags", PROP_COLLECTION, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "EnumPropertyItem"); + RNA_def_property_collection_funcs(prop, "rna_Struct_property_tags_begin", "rna_iterator_array_next", + "rna_iterator_array_end", "rna_iterator_array_get", + NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Property Tags", "Tags that properties can use to influence behavior"); } static void rna_def_property(BlenderRNA *brna) @@ -1142,6 +1188,9 @@ static void rna_def_property(BlenderRNA *brna) {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""}, {0, NULL, 0, NULL, NULL} }; + EnumPropertyItem dummy_prop_tags[] = { + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "Property", NULL); RNA_def_struct_ui_text(srna, "Property Definition", "RNA property definition"); @@ -1266,6 +1315,13 @@ static void rna_def_property(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Property_is_library_editable_flag_get", NULL); RNA_def_property_ui_text(prop, "Library Editable", "Property is editable from linked instances (changes not saved)"); + + prop = RNA_def_property(srna, "tags", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_enum_items(prop, dummy_prop_tags); + RNA_def_property_enum_funcs(prop, "rna_Property_tags_get", NULL, "rna_Property_tags_itemf"); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG); + RNA_def_property_ui_text(prop, "Tags", "Subset of tags (defined in parent struct) that are set for this property"); } static void rna_def_function(BlenderRNA *brna) |