[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38172] branches/soc-2011-pepper/source/ blender: Outliner RMB Menu - AnimData mangement
Joshua Leung
aligorith at gmail.com
Thu Jul 7 05:35:48 CEST 2011
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. @@
More information about the Bf-blender-cvs
mailing list