Keyframes on NLA-Strip F-Curves are detected by RNA buttons too
authorJoshua Leung <aligorith@gmail.com>
Fri, 24 Jan 2014 04:09:21 +0000 (17:09 +1300)
committerJoshua Leung <aligorith@gmail.com>
Sat, 28 Mar 2015 12:39:52 +0000 (01:39 +1300)
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/intern/fcurve.c
source/blender/editors/interface/interface_anim.c
source/blender/makesrna/intern/rna_access.c

index 83783946d4f979ebe2c178114d28af529bf7ff9c..275ab3f1ebb0c58ab9deab412e9a00956dd7c8be 100644 (file)
@@ -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)
index b46958a030850a6c700697f74c2fb43dbccb4f3e..a986640582707859d8ae379cd4c7000ff7f5deb4 100644 (file)
@@ -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);
        }
index 24a30ebe3d8f5c1bcbab7deebef8420951da70bf..f6757b3546282c13d68335248351f6f66a9d7e26 100644 (file)
 
 #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;
index 06fdf6d3b77e9adf53775f5b312455aa528f6415..ef798820321c4789171a729bd0e01dd00e576e65 100644 (file)
@@ -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;
        }