diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 83783946d4f..275ab3f1ebb 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -223,12 +223,12 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c */ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName); -/* find an f-curve based on an rna property. */ +/* Find an f-curve based on an rna property. */ struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, - struct AnimData **adt, struct bAction **action, bool *r_driven); + struct AnimData **adt, struct bAction **action, bool *r_driven, bool *r_special); /* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */ struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, - int rnaindex, struct AnimData **adt, struct bAction **action, bool *r_driven); + int rnaindex, struct AnimData **adt, struct bAction **action, bool *r_driven, bool *r_special); /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. * Returns the index to insert at (data already at that index will be offset if replace is 0) diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index b46958a0308..a9866405827 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -309,19 +309,22 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, return matches; } -FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **adt, bAction **action, bool *r_driven) +FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **adt, + bAction **action, bool *r_driven, bool *r_special) { - return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, adt, action, r_driven); + return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, adt, action, r_driven, r_special); } -FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, - AnimData **animdata, bAction **action, bool *r_driven) +FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **animdata, + bAction **action, bool *r_driven, bool *r_special) { FCurve *fcu = NULL; PointerRNA tptr = *ptr; if (animdata) *animdata = NULL; *r_driven = false; + *r_special = false; + if (action) *action = NULL; /* there must be some RNA-pointer + property combon */ @@ -343,6 +346,7 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *pro path = RNA_path_from_ID_to_property(&tptr, prop); } + // XXX: the logic here is duplicated with a function up above if (path) { /* animation takes priority over drivers */ if (adt->action && adt->action->curves.first) { @@ -380,6 +384,32 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *pro } } } + + /* if we still haven't found anything, check whether it's a "special" property */ + if ((fcu == NULL) && (adt->nla_tracks.first)) { + NlaTrack *nlt; + const char *propname = RNA_property_identifier(prop); + + for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { + NlaStrip *strip; + + if (fcu) + break; + + /* FIXME: need to do recursive search here for correctness, + * but this will do for most use cases (i.e. interactive editing), + * where nested strips can't be easily edited + */ + for (strip = nlt->strips.first; strip; strip = strip->next) { + fcu = list_find_fcurve(&strip->fcurves, propname, rnaindex); + + if (fcu) { + *r_special = true; + break; + } + } + } + } } MEM_SAFE_FREE(path); } diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 24a30ebe3d8..f6757b35462 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -54,13 +54,13 @@ #include "interface_intern.h" -static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven) +static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven, bool *r_special) { /* for entire array buttons we check the first component, it's not perfect * but works well enough in typical cases */ int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; - return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven); + return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special); } void ui_but_anim_flag(uiBut *but, float cfra) @@ -69,11 +69,16 @@ void ui_but_anim_flag(uiBut *but, float cfra) bAction *act; FCurve *fcu; bool driven; - + bool special; + but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN); - - fcu = ui_but_get_fcurve(but, &adt, &act, &driven); - + + /* NOTE: "special" is reserved for special F-Curves stored on the animation data + * itself (which are used to animate properties of the animation data). + * We count those as "animated" too for now + */ + fcu = ui_but_get_fcurve(but, &adt, &act, &driven, &special); + if (fcu) { if (!driven) { but->flag |= UI_BUT_ANIMATED; @@ -98,10 +103,10 @@ bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen) { FCurve *fcu; ChannelDriver *driver; - bool driven; - - fcu = ui_but_get_fcurve(but, NULL, NULL, &driven); - + bool driven, special; + + fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special); + if (fcu && driven) { driver = fcu->driver; @@ -118,9 +123,9 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str) { FCurve *fcu; ChannelDriver *driver; - bool driven; + bool driven, special; - fcu = ui_but_get_fcurve(but, NULL, NULL, &driven); + fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special); if (fcu && driven) { driver = fcu->driver; @@ -215,8 +220,9 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra) bAction *action; FCurve *fcu; bool driven; + bool special; - fcu = ui_but_get_fcurve(but, NULL, &action, &driven); + fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special); if (fcu && !driven) { id = but->rnapoin.id.data; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 06fdf6d3b77..ef798820321 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1622,7 +1622,7 @@ bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop) bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop) { int len = 1, index; - bool driven; + bool driven, special; if (!prop) return false; @@ -1631,7 +1631,7 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop) len = RNA_property_array_length(ptr, prop); for (index = 0; index < len; index++) { - if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven)) + if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven, &special)) return true; }