Fix T40350: Some texture prop did not have visual feedback they were driven.
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 6 Oct 2014 15:03:19 +0000 (17:03 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 6 Oct 2014 15:08:24 +0000 (17:08 +0200)
This is only a (hacky) partial fix, actually, since `RNA_property_animated()` will still
not work in those cases... Better that than nothing, though.

Thanks to Campbell for review.

source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/fcurve.c
source/blender/editors/animation/drivers.c
source/blender/editors/interface/interface_anim.c

index 80d2750fe82e0975a93076d6a26354a033f933e0..e79822daa4dddc5ae927c394f46a5c20ea95b1c9 100644 (file)
@@ -37,8 +37,10 @@ struct Main;
 struct AnimData;
 struct KeyingSet;
 struct KS_Path;
+struct bContext;
 
 struct PointerRNA;
+struct PropertyRNA;
 struct ReportList;
 struct bAction;
 struct bActionGroup;
@@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc
 /* Move F-Curves from src to destination if it's path is based on basepath */
 void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
 
+char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
+                                    char *base_path);
+
 /* ************************************* */
 /* Batch AnimData API */
 
index 0e86be9b97cc0499c78b68e5a44884e399b2dc16..c377769b2713883e7add26e29db465c1fec3679e 100644 (file)
@@ -43,6 +43,7 @@ struct DriverVar;
 struct DriverTarget;
 struct FCM_EnvelopeData;
 
+struct bContext;
 struct bAction;
 struct BezTriple;
 struct StructRNA;
@@ -221,8 +222,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 */
-struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven);
+/* find an f-curve based on an rna property. */
+struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
+                              struct bAction **action, bool *r_driven);
+/* 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 bAction **action, bool *r_driven);
 
 /* 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 5ee82bb584293aa1e5a0fa5a3c5772cbb1c70da1..2fb832dc72de75e84a074ef73739402d65470f8a 100644 (file)
 #include "DNA_material_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_world_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
+#include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_fcurve.h"
 #include "BKE_nla.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
+#include "BKE_material.h"
 #include "BKE_library.h"
 #include "BKE_report.h"
+#include "BKE_texture.h"
 
 #include "RNA_access.h"
 
@@ -551,6 +556,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
        }
 }
 
+/**
+ * Temporary wrapper for driver operators for buttons to make it easier to create
+ * such drivers by rerouting all paths through the active object instead so that
+ * they will get picked up by the dependency system.
+ *
+ * \param C Context pointer - for getting active data
+ * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
+ * \param prop RNA definition of property to add for
+ * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
+ */
+char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
+{
+       ID *id = (ID *)ptr->id.data;
+       ScrArea *sa = CTX_wm_area(C);
+
+       /* get standard path which may be extended */
+       char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
+       char *path = basepath; /* in case no remapping is needed */
+
+       /* Remapping will only be performed in the Properties Editor, as only this
+        * restricts the subspace of options to the 'active' data (a manageable state)
+        */
+       /* TODO: watch out for pinned context? */
+       if ((sa) && (sa->spacetype == SPACE_BUTS)) {
+               Object *ob = CTX_data_active_object(C);
+
+               if (ob && id) {
+                       /* only id-types which can be remapped to go through objects should be considered */
+                       switch (GS(id->name)) {
+                               case ID_TE: /* textures */
+                               {
+                                       Material *ma = give_current_material(ob, ob->actcol);
+                                       Tex *tex = give_current_material_texture(ma);
+
+                                       /* assumes: texture will only be shown if it is active material's active texture it's ok */
+                                       if ((ID *)tex == id) {
+                                               char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
+                                               char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
+
+                                               BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
+                                               BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
+
+                                               /* create new path */
+                                               // TODO: use RNA path functions to construct step by step instead?
+                                               // FIXME: maybe this isn't even needed anymore...
+                                               path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
+                                                                   name_esc_ma, name_esc_tex, basepath);
+
+                                               /* free old one */
+                                               if (basepath != base_path)
+                                                       MEM_freeN(basepath);
+                                       }
+                                       break;
+                               }
+                       }
+
+                       /* fix RNA pointer, as we've now changed the ID root by changing the paths */
+                       if (basepath != path) {
+                               /* rebase provided pointer so that it starts from object... */
+                               RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
+                       }
+               }
+       }
+
+       /* the path should now have been corrected for use */
+       return path;
+}
+
 /* Path Validation -------------------------------------------- */
 
 /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
index 09c1dcf701d46cfb80316d70a9d5c9d9005a56cf..de6e6c5335335a9db63a962533ec5c4221351e48 100644 (file)
@@ -55,6 +55,7 @@
 #include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_constraint.h"
+#include "BKE_context.h"
 #include "BKE_curve.h" 
 #include "BKE_global.h"
 #include "BKE_object.h"
@@ -309,20 +310,36 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
 }
 
 FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
+{
+       return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
+}
+
+FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
+                                  bAction **action, bool *r_driven)
 {
        FCurve *fcu = NULL;
+       PointerRNA tptr = *ptr;
        
        *r_driven = false;
        
        /* there must be some RNA-pointer + property combon */
-       if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
-               AnimData *adt = BKE_animdata_from_id(ptr->id.data);
-               char *path;
+       if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
+               AnimData *adt = BKE_animdata_from_id(tptr.id.data);
+               int step = 2;
+               char *path = NULL;
                
-               if (adt) {
+               if (adt == NULL) {
+                       path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL);
+                       adt = BKE_animdata_from_id(tptr.id.data);
+                       step--;
+               }
+               
+               while (adt && step--) {
                        if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
                                /* XXX this function call can become a performance bottleneck */
-                               path = RNA_path_from_ID_to_property(ptr, prop);
+                               if (step) {
+                                       path = RNA_path_from_ID_to_property(&tptr, prop);
+                               }
                                
                                if (path) {
                                        /* animation takes priority over drivers */
@@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
                                                        *r_driven = true;
                                        }
                                        
-                                       if (fcu && action)
+                                       if (fcu && action) {
                                                *action = adt->action;
-                                       
-                                       MEM_freeN(path);
+                                               break;
+                                       }
+                                       else if (step) {
+                                               char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path);
+                                               if (tpath && tpath != path) {
+                                                       MEM_freeN(path);
+                                                       path = tpath;
+                                                       adt = BKE_animdata_from_id(tptr.id.data);
+                                               }
+                                               else {
+                                                       adt = NULL;
+                                               }
+                                       }
                                }
                        }
                }
+               MEM_SAFE_FREE(path);
        }
        
        return fcu;
index 481912f4d1f2da1803308e98b2105d39e319744b..296a52e7f20af8eb3eb9b7ff8349f12eb8af63b0 100644 (file)
@@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
 /* ************************************************** */
 /* UI-Button Interface */
 
-/**
- * Temporary wrapper for driver operators for buttons to make it easier to create
- * such drivers by rerouting all paths through the active object instead so that
- * they will get picked up by the dependency system.
- *
- * \param C Context pointer - for getting active data
- * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
- * \param prop RNA definition of property to add for
- * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
- */
-static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
-{
-       ID *id = (ID *)ptr->id.data;
-       ScrArea *sa = CTX_wm_area(C);
-       
-       /* get standard path which may be extended */
-       char *basepath = RNA_path_from_ID_to_property(ptr, prop);
-       char *path = basepath; /* in case no remapping is needed */
-       
-       
-       /* Remapping will only be performed in the Properties Editor, as only this 
-        * restricts the subspace of options to the 'active' data (a manageable state)
-        */
-       // TODO: watch out for pinned context?
-       if ((sa) && (sa->spacetype == SPACE_BUTS)) {
-               Object *ob = CTX_data_active_object(C);
-               
-               if (ob && id) {
-                       /* only id-types which can be remapped to go through objects should be considered */
-                       switch (GS(id->name)) {
-                               case ID_TE: /* textures */
-                               {
-                                       Material *ma = give_current_material(ob, ob->actcol);
-                                       Tex *tex = give_current_material_texture(ma);
-                                       
-                                       /* assumes: texture will only be shown if it is active material's active texture it's ok */
-                                       if ((ID *)tex == id) {
-                                               char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
-                                               char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
-
-                                               BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
-                                               BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
-
-                                               /* create new path */
-                                               // TODO: use RNA path functions to construct step by step instead?
-                                               // FIXME: maybe this isn't even needed anymore...
-                                               path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", 
-                                                                   name_esc_ma, name_esc_tex, basepath);
-                                                       
-                                               /* free old one */
-                                               MEM_freeN(basepath);
-                                       }
-                                       break;
-                               }
-                       }
-                       
-                       /* fix RNA pointer, as we've now changed the ID root by changing the paths */
-                       if (basepath != path) {
-                               /* rebase provided pointer so that it starts from object... */
-                               RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
-                       }
-               }
-       }
-       
-       /* the path should now have been corrected for use */
-       return path;
-}
-
 /* Add Driver Button Operator ------------------------ */
 
 static int add_driver_button_exec(bContext *C, wmOperator *op)
@@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
                index = -1;
        
        if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
-               char *path = get_driver_path_hack(C, &ptr, prop);
+               char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
                short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
                
                if (path) {
@@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
                index = -1;
        
        if (ptr.id.data && ptr.data && prop) {
-               char *path = get_driver_path_hack(C, &ptr, prop);
+               char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
                
                success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
                MEM_freeN(path);
@@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
        uiContextActiveProperty(C, &ptr, &prop, &index);
        
        if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
-               char *path = get_driver_path_hack(C, &ptr, prop);
+               char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
                
                if (path) {
                        /* only copy the driver for the button that this was involved for */
@@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
        uiContextActiveProperty(C, &ptr, &prop, &index);
        
        if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
-               char *path = get_driver_path_hack(C, &ptr, prop);
+               char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
                
                if (path) {
                        /* only copy the driver for the button that this was involved for */
index fa0832b6273ef1721bf75d6cead2e01c57fc93ed..48e54270e9598b1da39fb7a74e8982ef53dba3ec 100644 (file)
@@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
         * but works well enough in typical cases */
        int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
 
-       return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
+       return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
 }
 
 void ui_but_anim_flag(uiBut *but, float cfra)