Revision: 38172
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38172
Author:   aligorith
Date:     2011-07-07 03:35:48 +0000 (Thu, 07 Jul 2011)
Log Message:
-----------
Outliner RMB Menu - AnimData mangement

* When clicking on "Animation" items in the Outliner, there's now a
menu containing from which you can change the action used, and
refresh/delete all drivers.

* Moved action-setting logic for AnimData actions to a single utility
function in anim_sys, since this was starting to be done in too many
places already.

* Fixed Outliner refresh bug after changing the active action

Modified Paths:
--------------
    branches/soc-2011-pepper/source/blender/blenkernel/BKE_animsys.h
    branches/soc-2011-pepper/source/blender/blenkernel/intern/anim_sys.c
    branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c
    
branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner_intern.h
    
branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner_ops.c
    
branches/soc-2011-pepper/source/blender/editors/space_outliner/space_outliner.c
    branches/soc-2011-pepper/source/blender/makesrna/intern/rna_animation.c
    branches/soc-2011-pepper/source/blender/makesrna/intern/rna_nla.c

Modified: branches/soc-2011-pepper/source/blender/blenkernel/BKE_animsys.h
===================================================================
--- branches/soc-2011-pepper/source/blender/blenkernel/BKE_animsys.h    
2011-07-07 00:59:48 UTC (rev 38171)
+++ branches/soc-2011-pepper/source/blender/blenkernel/BKE_animsys.h    
2011-07-07 03:35:48 UTC (rev 38172)
@@ -41,6 +41,7 @@
 struct KS_Path;
 
 struct PointerRNA;
+struct ReportList;
 struct bAction;
 struct bActionGroup;
 struct AnimMapper;
@@ -57,6 +58,9 @@
 /* Add AnimData to the given ID-block */
 struct AnimData *BKE_id_add_animdata(struct ID *id);
 
+/* Set active action used by AnimData from the given ID-block */
+short BKE_animdata_set_action(struct ReportList *reports, struct ID *id, 
struct bAction *act);
+
 /* Free AnimData */
 void BKE_free_animdata(struct ID *id);
 

Modified: branches/soc-2011-pepper/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- branches/soc-2011-pepper/source/blender/blenkernel/intern/anim_sys.c        
2011-07-07 00:59:48 UTC (rev 38171)
+++ branches/soc-2011-pepper/source/blender/blenkernel/intern/anim_sys.c        
2011-07-07 03:35:48 UTC (rev 38172)
@@ -56,6 +56,7 @@
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_library.h"
+#include "BKE_report.h"
 #include "BKE_utildefines.h"
 
 #include "RNA_access.h"
@@ -144,6 +145,59 @@
                return NULL;
 }
 
+/* Action Setter --------------------------------------- */
+
+/* Called when user tries to change the active action of an AnimData block 
(via RNA, Outliner, etc.) */
+short BKE_animdata_set_action (ReportList *reports, ID *id, bAction *act)
+{
+       AnimData *adt = BKE_animdata_from_id(id);
+       short ok = 0;
+       
+       /* animdata validity check */
+       if (adt == NULL) {
+               BKE_report(reports, RPT_WARNING, "No AnimData to set action 
on");
+               return ok;
+       }
+       
+       /* active action is only editable when it is not a tweaking strip 
+        * see rna_AnimData_action_editable() in rna_animation.c
+        */
+       if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) {
+               /* cannot remove, otherwise things turn to custard */
+               BKE_report(reports, RPT_ERROR, "Cannot change action, as it is 
still being edited in NLA");
+               return ok;
+       }
+       
+       /* manage usercount for current action */
+       if (adt->action)
+               id_us_min((ID*)adt->action);
+       
+       /* assume that AnimData's action can in fact be edited... */
+       if (act) {
+               /* action must have same type as owner */
+               if (ELEM(act->idroot, 0, GS(id->name))) {
+                       /* can set */
+                       adt->action = act;
+                       id_us_plus((ID*)adt->action);
+                       ok = 1;
+               }
+               else {
+                       /* cannot set */
+                       BKE_reportf(reports, RPT_ERROR,
+                                       "Couldn't set Action '%s' onto ID '%s', 
as it doesn't have suitably rooted paths for this purpose", 
+                                       act->id.name+2, id->name);
+                       //ok = 0;
+               }
+       }
+       else {
+               /* just clearing the action... */
+               adt->action = NULL;
+               ok = 1;
+       }
+       
+       return ok;
+}
+
 /* Freeing -------------------------------------------- */
 
 /* Free AnimData used by the nominated ID-block, and clear ID-block's AnimData 
pointer */

Modified: 
branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c   
2011-07-07 00:59:48 UTC (rev 38171)
+++ branches/soc-2011-pepper/source/blender/editors/space_outliner/outliner.c   
2011-07-07 03:35:48 UTC (rev 38172)
@@ -101,6 +101,7 @@
 
 #include "RNA_access.h"
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
 
 #include "ED_keyframing.h"
 
@@ -3170,29 +3171,10 @@
        }
 }
 
-static void unlink_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement 
*te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem))
+static void unlink_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement 
*UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem))
 {
-       IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
-       AnimData *adt = iat->adt;
-       
-       //printf("iat = '%s' | act = '%s'\n", iat->id.name, tselem->id->name);
-       
-       /* active action is only editable when it is not a tweaking strip 
-        * see rna_AnimData_action_editable() in rna_animation.c
-        */
-       if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) {
-               /* cannot remove, otherwise things turn to custard */
-               ReportList *reports = CTX_wm_reports(C);
-               
-               // FIXME: this only gets shown in info-window, since this is 
global not operator report
-               BKE_report(reports, RPT_ERROR, "Cannot unlink action, as it is 
still being edited in NLA");
-               
-               return;
-       }
-       
-       /* remove action... */
-       id_us_min((ID*)adt->action);
-       adt->action = NULL;
+       /* just set action to NULL */
+       BKE_animdata_set_action(CTX_wm_reports(C), tsep->id, NULL);
 }
 
 static void unlink_material_cb(bContext *UNUSED(C), Scene *UNUSED(scene), 
TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem))
@@ -3414,6 +3396,36 @@
 
 /* ******************************************** */
 
+static void unlinkact_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), 
TreeStoreElem *tselem)
+{
+       /* just set action to NULL */
+       BKE_animdata_set_action(NULL, tselem->id, NULL);
+}
+
+static void cleardrivers_animdata_cb(int UNUSED(event), TreeElement 
*UNUSED(te), TreeStoreElem *tselem)
+{
+       IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
+       
+       /* just free drivers - stored as a list of F-Curves */
+       free_fcurves(&iat->adt->drivers);
+}
+
+static void refreshdrivers_animdata_cb(int UNUSED(event), TreeElement 
*UNUSED(te), TreeStoreElem *tselem)
+{
+       IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
+       FCurve *fcu;
+       
+       /* loop over drivers, performing refresh (i.e. check graph_buttons.c 
and rna_fcurve.c for details) */
+       for (fcu = iat->adt->drivers.first; fcu; fcu= fcu->next) {
+               fcu->flag &= ~FCURVE_DISABLED;
+               
+               if (fcu->driver)
+                       fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
+       }
+}
+
+/* --------------------------------- */
+
 static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
 {
        bPoseChannel *pchan= (bPoseChannel *)te->directdata;
@@ -3775,6 +3787,224 @@
 
 /* **************************************** */
 
+static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase 
*lb, ID *newid,
+                                                                               
 void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *))
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       for (te=lb->first; te; te= te->next) {
+               tselem= TREESTORE(te);
+               if (tselem->flag & TSE_SELECTED) {
+                       if(tselem->type==type) {
+                               TreeStoreElem *tsep = TREESTORE(te->parent);
+                               operation_cb(te, tselem, tsep, newid);
+                       }
+               }
+               if ((tselem->flag & TSE_CLOSED)==0) {
+                       outliner_do_id_set_operation(soops, type, &te->subtree, 
newid, operation_cb);
+               }
+       }
+}
+
+/* ------------------------------------------ */
+
+static void actionset_id_cb(TreeElement *te, TreeStoreElem *tselem, 
TreeStoreElem *tsep, ID *actId)
+{
+       bAction *act = (bAction *)actId;
+       
+       if (tselem->type == TSE_ANIM_DATA) {
+               /* "animation" entries - action is child of this */
+               BKE_animdata_set_action(NULL, tselem->id, act);
+       }
+       /* TODO: if any other "expander" channels which own actions need to 
support this menu, 
+        * add: tselem->type = ...
+        */
+       else if (tsep && (tsep->type == TSE_ANIM_DATA)) {
+               /* "animation" entries case again */
+               BKE_animdata_set_action(NULL, tsep->id, act);
+       }
+       // TODO: other cases not supported yet
+}
+
+static int outliner_action_set_exec(bContext *C, wmOperator *op)
+{
+       SpaceOops *soops= CTX_wm_space_outliner(C);
+       int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
+       
+       bAction *act;
+       
+       /* check for invalid states */
+       if (soops == NULL)
+               return OPERATOR_CANCELLED;
+       set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, 
&idlevel, &datalevel);
+       
+       /* get action to use */
+       act= BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, 
"action"));
+       
+       if (act == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "No valid Action to add.");
+               return OPERATOR_CANCELLED;
+       }
+       else if (act->idroot == 0) {
+               /* hopefully in this case (i.e. library of userless actions), 
the user knows what they're doing... */
+               BKE_reportf(op->reports, RPT_WARNING,
+                       "Action '%s' does not specify what datablocks it can be 
used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for 
this Action to avoid future problems",
+                       act->id.name+2);
+       }
+       
+       /* perform action if valid channel */
+       if (datalevel == TSE_ANIM_DATA)
+               outliner_do_id_set_operation(soops, datalevel, &soops->tree, 
(ID*)act, actionset_id_cb);
+       else if (idlevel == ID_AC)
+               outliner_do_id_set_operation(soops, idlevel, &soops->tree, 
(ID*)act, actionset_id_cb);
+       else
+               return OPERATOR_CANCELLED;
+               
+       /* set notifier that things have changed */
+       WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL);
+       ED_undo_push(C, "Set action");
+       
+       /* done */
+       return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_action_set(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+
+       /* identifiers */
+       ot->name= "Outliner Set Action";
+       ot->idname= "OUTLINER_OT_action_set";
+       ot->description= "Change the active action used";
+       
+       /* api callbacks */
+       ot->invoke= WM_enum_search_invoke;
+       ot->exec= outliner_action_set_exec;
+       ot->poll= ED_operator_outliner_active;
+       
+       /* flags */
+       ot->flag= 0;
+       
+       /* props */
+               // TODO: this would be nicer as an ID-pointer...
+       prop= RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, 
"Action", "");
+       RNA_def_enum_funcs(prop, RNA_action_itemf);
+       ot->prop= prop;
+}
+
+/* **************************************** */
+
+typedef enum eOutliner_AnimDataOps {
+       OUTLINER_ANIMOP_INVALID = 0,
+       
+       OUTLINER_ANIMOP_SET_ACT,
+       OUTLINER_ANIMOP_CLEAR_ACT,
+       
+       OUTLINER_ANIMOP_REFRESH_DRV,
+       OUTLINER_ANIMOP_CLEAR_DRV
+       
+       //OUTLINER_ANIMOP_COPY_DRIVERS,
+       //OUTLINER_ANIMOP_PASTE_DRIVERS
+} eOutliner_AnimDataOps;
+
+static EnumPropertyItem prop_animdata_op_types[] = {
+       {OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""},
+       {OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""},
+       {OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", 
""},
+       //{OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""},
+       //{OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", 
""},
+       {OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
+static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
+{
+       SpaceOops *soops= CTX_wm_space_outliner(C);

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to