diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_access.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 176 |
1 files changed, 127 insertions, 49 deletions
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 2197764794b..793552c5c34 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -273,9 +273,9 @@ static IDProperty *rna_idproperty_ui_container(PropertyRNA *prop) } /* return a UI local ID prop definition for this prop */ -static IDProperty *rna_idproperty_ui(PropertyRNA *prop) +static const IDProperty *rna_idproperty_ui(const PropertyRNA *prop) { - IDProperty *idprop = rna_idproperty_ui_container(prop); + IDProperty *idprop = rna_idproperty_ui_container((PropertyRNA *)prop); if (idprop) { return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP); @@ -558,9 +558,15 @@ static PropertyRNA *arraytypemap[IDP_NUMTYPES] = { (PropertyRNA *)&rna_PropertyGroupItem_double_array, }; -static void *rna_idproperty_check_ex(PropertyRNA **prop, - PointerRNA *ptr, - const bool return_rnaprop) +/* This function initializes a PropertyRNAOrID with all required info, from a given PropertyRNA + * and PointerRNA data. It deals properly with the three cases (static RNA, runtime RNA, and + * IDProperty). + * WARNING: given `ptr` PointerRNA is assumed to be a valid data one here, calling code is + * responsible to ensure that. + */ +void rna_property_rna_or_id_get(PropertyRNA *prop, + PointerRNA *ptr, + PropertyRNAOrID *r_prop_rna_or_id) { /* This is quite a hack, but avoids some complexity in the API. we * pass IDProperty structs as PropertyRNA pointers to the outside. @@ -568,36 +574,64 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop, * distinguish it from IDProperty structs. If it is an ID property, * we look up an IDP PropertyRNA based on the type, and set the data * pointer to the IDProperty. */ + memset(r_prop_rna_or_id, 0, sizeof(*r_prop_rna_or_id)); + + r_prop_rna_or_id->ptr = *ptr; + r_prop_rna_or_id->rawprop = prop; - if ((*prop)->magic == RNA_MAGIC) { - if ((*prop)->flag & PROP_IDPROPERTY) { - IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier); + if (prop->magic == RNA_MAGIC) { + r_prop_rna_or_id->rnaprop = prop; + r_prop_rna_or_id->identifier = prop->identifier; - if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) { + r_prop_rna_or_id->is_array = prop->getlength || prop->totarraylength; + if (r_prop_rna_or_id->is_array) { + int arraylen[RNA_MAX_ARRAY_DIMENSION]; + r_prop_rna_or_id->array_len = (prop->getlength && ptr->data) ? + (uint)prop->getlength(ptr, arraylen) : + prop->totarraylength; + } + + if (prop->flag & PROP_IDPROPERTY) { + IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier); + + if (idprop != NULL && !rna_idproperty_verify_valid(ptr, prop, idprop)) { IDProperty *group = RNA_struct_idprops(ptr, 0); IDP_FreeFromGroup(group, idprop); - return NULL; + idprop = NULL; } - return idprop; + r_prop_rna_or_id->idprop = idprop; + r_prop_rna_or_id->is_set = idprop != NULL && (idprop->flag & IDP_FLAG_GHOST) == 0; } else { - return return_rnaprop ? *prop : NULL; + /* Full static RNA properties are always set. */ + r_prop_rna_or_id->is_set = true; } } + else { + IDProperty *idprop = (IDProperty *)prop; + /* Given prop may come from the custom properties of another data, ensure we get the one from + * given data ptr. */ + IDProperty *idprop_evaluated = rna_idproperty_find(ptr, idprop->name); + if (idprop_evaluated != NULL && idprop->type != idprop_evaluated->type) { + idprop_evaluated = NULL; + } - { - IDProperty *idprop = (IDProperty *)(*prop); + r_prop_rna_or_id->idprop = idprop_evaluated; + r_prop_rna_or_id->is_idprop = true; + /* Full IDProperties are always set, if it exists. */ + r_prop_rna_or_id->is_set = (idprop_evaluated != NULL); + r_prop_rna_or_id->identifier = idprop->name; if (idprop->type == IDP_ARRAY) { - *prop = arraytypemap[(int)(idprop->subtype)]; + r_prop_rna_or_id->rnaprop = arraytypemap[(int)(idprop->subtype)]; + r_prop_rna_or_id->is_array = true; + r_prop_rna_or_id->array_len = idprop_evaluated != NULL ? (uint)idprop_evaluated->len : 0; } else { - *prop = typemap[(int)(idprop->type)]; + r_prop_rna_or_id->rnaprop = typemap[(int)(idprop->type)]; } - - return idprop; } } @@ -605,14 +639,26 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop, * or NULL (in case IDProp could not be found, or prop is a real RNA property). */ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) { - return rna_idproperty_check_ex(prop, ptr, false); + PropertyRNAOrID prop_rna_or_id; + + rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id); + + *prop = prop_rna_or_id.rnaprop; + return prop_rna_or_id.idprop; } /* This function always return the valid, real data pointer, be it a regular RNA property one, * or an IDProperty one. */ PropertyRNA *rna_ensure_property_realdata(PropertyRNA **prop, PointerRNA *ptr) { - return rna_idproperty_check_ex(prop, ptr, true); + PropertyRNAOrID prop_rna_or_id; + + rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id); + + *prop = prop_rna_or_id.rnaprop; + return (prop_rna_or_id.is_idprop || prop_rna_or_id.idprop != NULL) ? + (PropertyRNA *)prop_rna_or_id.idprop : + prop_rna_or_id.rnaprop; } PropertyRNA *rna_ensure_property(PropertyRNA *prop) @@ -645,7 +691,7 @@ static const char *rna_ensure_property_identifier(const PropertyRNA *prop) } } -static const char *rna_ensure_property_description(PropertyRNA *prop) +static const char *rna_ensure_property_description(const PropertyRNA *prop) { const char *description = NULL; @@ -654,7 +700,7 @@ static const char *rna_ensure_property_description(PropertyRNA *prop) } else { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING); @@ -1140,7 +1186,7 @@ PropertySubType RNA_property_subtype(PropertyRNA *prop) /* Restrict to arrays only for now for performance reasons. */ if (idprop->type == IDP_ARRAY && ELEM(idprop->subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE)) { - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "subtype", IDP_STRING); @@ -1312,7 +1358,7 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -1353,7 +1399,7 @@ void RNA_property_int_ui_range( if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -1403,7 +1449,7 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -1448,7 +1494,7 @@ void RNA_property_float_ui_range(PointerRNA *ptr, if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -2025,35 +2071,34 @@ int RNA_property_enum_bitflag_identifiers( return 0; } -const char *RNA_property_ui_name(PropertyRNA *prop) +const char *RNA_property_ui_name(const PropertyRNA *prop) { return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop)); } -const char *RNA_property_ui_name_raw(PropertyRNA *prop) +const char *RNA_property_ui_name_raw(const PropertyRNA *prop) { return rna_ensure_property_name(prop); } -const char *RNA_property_ui_description(PropertyRNA *prop) +const char *RNA_property_ui_description(const PropertyRNA *prop) { return TIP_(rna_ensure_property_description(prop)); } -const char *RNA_property_ui_description_raw(PropertyRNA *prop) +const char *RNA_property_ui_description_raw(const PropertyRNA *prop) { return rna_ensure_property_description(prop); } -const char *RNA_property_translation_context(PropertyRNA *_prop) +const char *RNA_property_translation_context(const PropertyRNA *prop) { - PropertyRNA *prop = rna_ensure_property(_prop); - return prop->translation_context; + return rna_ensure_property((PropertyRNA *)prop)->translation_context; } -int RNA_property_ui_icon(PropertyRNA *prop) +int RNA_property_ui_icon(const PropertyRNA *prop) { - return rna_ensure_property(prop)->icon; + return rna_ensure_property((PropertyRNA *)prop)->icon; } bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop_orig) @@ -2065,9 +2110,10 @@ bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop_orig) PropertyRNA *prop = rna_ensure_property(prop_orig); flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag; - return ((flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0 && - (!id || ((!ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION)) && - (!id->override_library || RNA_property_overridable_get(ptr, prop_orig))))); + return ( + (flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0 && + (!id || ((!ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION)) && + (!ID_IS_OVERRIDE_LIBRARY(id) || RNA_property_overridable_get(ptr, prop_orig))))); } /** @@ -2101,10 +2147,8 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char * } return false; } - if (id->override_library != NULL) { - /* We need the real data property in case of IDProperty here... */ - PropertyRNA *real_prop = rna_ensure_property_realdata(&prop, ptr); - if (real_prop == NULL || !RNA_property_overridable_get(ptr, real_prop)) { + if (ID_IS_OVERRIDE_LIBRARY(id)) { + if (!RNA_property_overridable_get(ptr, prop)) { if (!(*r_info)[0]) { *r_info = N_("Can't edit this property from an override data-block"); } @@ -2847,7 +2891,7 @@ int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop) if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -2883,7 +2927,7 @@ void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int if (prop->magic != RNA_MAGIC) { int length = rna_ensure_property_array_length(ptr, prop); - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); IDProperty *item = idp_ui ? IDP_GetPropertyFromGroup(idp_ui, "default") : NULL; int defval = (item && item->type == IDP_INT) ? IDP_Int(item) : iprop->defaultvalue; @@ -3220,7 +3264,7 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop) if (prop->magic != RNA_MAGIC) { /* attempt to get the local ID values */ - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); if (idp_ui) { IDProperty *item; @@ -3256,7 +3300,7 @@ void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, fl if (prop->magic != RNA_MAGIC) { int length = rna_ensure_property_array_length(ptr, prop); - IDProperty *idp_ui = rna_idproperty_ui(prop); + const IDProperty *idp_ui = rna_idproperty_ui(prop); IDProperty *item = idp_ui ? IDP_GetPropertyFromGroup(idp_ui, "default") : NULL; float defval = (item && item->type == IDP_DOUBLE) ? IDP_Double(item) : fprop->defaultvalue; @@ -3473,6 +3517,24 @@ void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, { StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop); + if (prop->magic != RNA_MAGIC) { + /* attempt to get the local ID values */ + const IDProperty *idp_ui = rna_idproperty_ui(prop); + + if (idp_ui) { + IDProperty *item; + + item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_STRING); + if (item) { + strcpy(value, IDP_String(item)); + return; + } + } + + strcpy(value, ""); + return; + } + BLI_assert(RNA_property_type(prop) == PROP_STRING); strcpy(value, sprop->defaultvalue); @@ -3507,6 +3569,22 @@ int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *pro { StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop); + if (prop->magic != RNA_MAGIC) { + /* attempt to get the local ID values */ + const IDProperty *idp_ui = rna_idproperty_ui(prop); + + if (idp_ui) { + IDProperty *item; + + item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_STRING); + if (item) { + return strlen(IDP_String(item)); + } + } + + return 0; + } + BLI_assert(RNA_property_type(prop) == PROP_STRING); return strlen(sprop->defaultvalue); @@ -5380,7 +5458,7 @@ bool RNA_path_resolve_property_full( * This is a convenience method to avoid logic errors and ugly syntax, * it combines both \a RNA_path_resolve and #RNA_path_resolve_property in a single call. * \note Assumes all pointers provided are valid. - * \param r_item_pointer: The final Pointer or Collection item value. + * \param r_item_ptr: The final Pointer or Collection item value. * You must check for its validity before use! * \return True only if both a valid pointer and property are found after resolving the path */ @@ -5406,7 +5484,7 @@ bool RNA_path_resolve_property_and_item_pointer(PointerRNA *ptr, * it combines both \a RNA_path_resolve_full and * \a RNA_path_resolve_property_full in a single call. * \note Assumes all pointers provided are valid. - * \param r_item_pointer: The final Pointer or Collection item value. + * \param r_item_ptr: The final Pointer or Collection item value. * You must check for its validity before use! * \return True only if both a valid pointer and property are found after resolving the path */ |