Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation/anim_channels_edit.c')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c5042
1 files changed, 2543 insertions, 2499 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 558c5d5bfc1..c2878a64e97 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,7 +58,7 @@
#include "ED_anim_api.h"
#include "ED_armature.h"
-#include "ED_keyframes_edit.h" // XXX move the select modes out of there!
+#include "ED_keyframes_edit.h" // XXX move the select modes out of there!
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
@@ -74,178 +73,173 @@
/* Set the given animation-channel as the active one for the active context */
// TODO: extend for animdata types...
-void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datatype, eAnimFilter_Flags filter, void *channel_data, eAnim_ChannelType channel_type)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
-
- /* try to build list of filtered items */
- ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
- if (BLI_listbase_is_empty(&anim_data))
- return;
-
- /* only clear the 'active' flag for the channels of the same type */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* skip if types don't match */
- if (channel_type != ale->type)
- continue;
-
- /* flag to set depends on type */
- switch (ale->type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
-
- ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale->adt) {
- ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE);
- }
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
- break;
- }
- }
- }
-
- /* set active flag */
- if (channel_data) {
- switch (channel_type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)channel_data;
- agrp->flag |= AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)channel_data;
- fcu->flag |= FCURVE_ACTIVE;
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)channel_data;
- nlt->flag |= NLATRACK_ACTIVE;
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale && ale->adt) {
- ale->adt->flag |= ADT_UI_ACTIVE;
- }
- break;
- }
-
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)channel_data;
- gpl->flag |= GP_LAYER_ACTIVE;
- break;
- }
-
- /* unhandled currently, but may be interesting */
- case ANIMTYPE_MASKLAYER:
- case ANIMTYPE_SHAPEKEY:
- case ANIMTYPE_NLAACTION:
- break;
-
- /* other types */
- default:
- break;
- }
- }
-
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+void ANIM_set_active_channel(bAnimContext *ac,
+ void *data,
+ eAnimCont_Types datatype,
+ eAnimFilter_Flags filter,
+ void *channel_data,
+ eAnim_ChannelType channel_type)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+
+ /* try to build list of filtered items */
+ ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
+ if (BLI_listbase_is_empty(&anim_data))
+ return;
+
+ /* only clear the 'active' flag for the channels of the same type */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* skip if types don't match */
+ if (channel_type != ale->type)
+ continue;
+
+ /* flag to set depends on type */
+ switch (ale->type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+
+ ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE);
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
+ break;
+ }
+ }
+ }
+
+ /* set active flag */
+ if (channel_data) {
+ switch (channel_type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)channel_data;
+ agrp->flag |= AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)channel_data;
+ fcu->flag |= FCURVE_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)channel_data;
+ nlt->flag |= NLATRACK_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale && ale->adt) {
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+ break;
+ }
+
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)channel_data;
+ gpl->flag |= GP_LAYER_ACTIVE;
+ break;
+ }
+
+ /* unhandled currently, but may be interesting */
+ case ANIMTYPE_MASKLAYER:
+ case ANIMTYPE_SHAPEKEY:
+ case ANIMTYPE_NLAACTION:
+ break;
+
+ /* other types */
+ default:
+ break;
+ }
+ }
+
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
}
static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale)
{
- /* Armatures-Specific Feature:
- * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
- */
- if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
- if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
- Object *ob = (Object *)ale->id;
- if (ob->type == OB_ARMATURE) {
- /* Assume for now that any group with corresponding name is what we want
- * (i.e. for an armature whose location is animated, things would break
- * if the user were to add a bone named "Location").
- *
- * TODO: check the first F-Curve or so to be sure...
- */
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- if (agrp->flag & AGRP_SELECTED) {
- ED_pose_bone_select(ob, pchan, true);
- }
- else {
- ED_pose_bone_select(ob, pchan, false);
- }
- }
- }
- }
+ /* Armatures-Specific Feature:
+ * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ Object *ob = (Object *)ale->id;
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ if (agrp->flag & AGRP_SELECTED) {
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ED_pose_bone_select(ob, pchan, false);
+ }
+ }
+ }
+ }
}
/* Deselect all animation channels
@@ -254,195 +248,186 @@ static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp,
* - test: check if deselecting instead of selecting
* - sel: eAnimChannels_SetFlag;
*/
-void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types datatype, bool test, eAnimChannels_SetFlag sel)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- /* NOTE: no list visible, otherwise, we get dangling */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (sel == 0)
- break;
-
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- if (ale->flag & SCE_DS_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_OBJECT:
-#if 0 /* for now, do not take object selection into account, since it gets too annoying */
- if (ale->flag & SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
+void ANIM_deselect_anim_channels(
+ bAnimContext *ac, void *data, eAnimCont_Types datatype, bool test, eAnimChannels_SetFlag sel)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ /* NOTE: no list visible, otherwise, we get dangling */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
+ ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (sel == 0)
+ break;
+
+ switch (ale->type) {
+ case ANIMTYPE_SCENE:
+ if (ale->flag & SCE_DS_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_OBJECT:
+#if 0 /* for now, do not take object selection into account, since it gets too annoying */
+ if (ale->flag & SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
#endif
- break;
- case ANIMTYPE_GROUP:
- if (ale->flag & AGRP_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- if (ale->flag & FCURVE_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_SHAPEKEY:
- if (ale->flag & KEYBLOCK_SEL)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_NLATRACK:
- if (ale->flag & NLATRACK_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
-
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- case ANIMTYPE_GPLAYER:
- if (ale->flag & GP_LAYER_SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_MASKLAYER:
- if (ale->flag & MASK_LAYERFLAG_SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- }
- }
-
- /* Now set the flags */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- {
- Scene *scene = (Scene *)ale->data;
-
- ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
-
- if (scene->adt) {
- ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
- }
- break;
- }
- case ANIMTYPE_OBJECT:
- {
-#if 0 /* for now, do not take object selection into account, since it gets too annoying */
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
-
- ACHANNEL_SET_FLAG(base, sel, SELECT);
- ACHANNEL_SET_FLAG(ob, sel, SELECT);
-
- if (ob->adt) {
- ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
- }
+ break;
+ case ANIMTYPE_GROUP:
+ if (ale->flag & AGRP_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE:
+ if (ale->flag & FCURVE_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_SHAPEKEY:
+ if (ale->flag & KEYBLOCK_SEL)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_NLATRACK:
+ if (ale->flag & NLATRACK_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ case ANIMTYPE_GPLAYER:
+ if (ale->flag & GP_LAYER_SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_MASKLAYER:
+ if (ale->flag & MASK_LAYERFLAG_SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ }
+ }
+
+ /* Now set the flags */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->type) {
+ case ANIMTYPE_SCENE: {
+ Scene *scene = (Scene *)ale->data;
+
+ ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
+
+ if (scene->adt) {
+ ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
+ }
+ break;
+ }
+ case ANIMTYPE_OBJECT: {
+#if 0 /* for now, do not take object selection into account, since it gets too annoying */
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
+
+ ACHANNEL_SET_FLAG(base, sel, SELECT);
+ ACHANNEL_SET_FLAG(ob, sel, SELECT);
+
+ if (ob->adt) {
+ ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
+ }
#endif
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
- select_pchan_for_action_group(ac, agrp, ale);
- agrp->flag &= ~AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
- fcu->flag &= ~FCURVE_ACTIVE;
- break;
- }
- case ANIMTYPE_SHAPEKEY:
- {
- KeyBlock *kb = (KeyBlock *)ale->data;
-
- ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
- nlt->flag &= ~NLATRACK_ACTIVE;
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale->adt) {
- ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED);
- ale->adt->flag &= ~ADT_UI_ACTIVE;
- }
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT);
- break;
- }
- }
- }
-
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
+ select_pchan_for_action_group(ac, agrp, ale);
+ agrp->flag &= ~AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
+ fcu->flag &= ~FCURVE_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_SHAPEKEY: {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+
+ ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
+ nlt->flag &= ~NLATRACK_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED);
+ ale->adt->flag &= ~ADT_UI_ACTIVE;
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT);
+ break;
+ }
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ---------------------------- Graph Editor ------------------------------------- */
@@ -456,137 +441,140 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
* - setting: type of setting to set
* - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode)
-{
- bAnimListElem *ale, *match = NULL;
- int prevLevel = 0, matchLevel = 0;
-
- /* sanity check */
- if (ELEM(NULL, anim_data, anim_data->first))
- return;
-
- if (setting == ACHANNEL_SETTING_ALWAYS_VISIBLE) {
- return;
- }
-
- /* find the channel that got changed */
- for (ale = anim_data->first; ale; ale = ale->next) {
- /* compare data, and type as main way of identifying the channel */
- if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
- /* we also have to check the ID, this is assigned to, since a block may have multiple users */
- /* TODO: is the owner-data more revealing? */
- if (ale->id == ale_setting->id) {
- match = ale;
- break;
- }
- }
- }
- if (match == NULL) {
- printf("ERROR: no channel matching the one changed was found\n");
- return;
- }
- else {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
-
- if (acf == NULL) {
- printf("ERROR: no channel info for the changed channel\n");
- return;
- }
-
- /* get the level of the channel that was affected
- * - we define the level as simply being the offset for the start of the channel
- */
- matchLevel = (acf->get_offset) ? acf->get_offset(ac, ale_setting) : 0;
- prevLevel = matchLevel;
- }
-
- /* flush up?
- *
- * For Visibility:
- * - only flush up if the current state is now enabled (positive 'on' state is default)
- * (otherwise, it's too much work to force the parents to be inactive too)
- *
- * For everything else:
- * - only flush up if the current state is now disabled (negative 'off' state is default)
- * (otherwise, it's too much work to force the parents to be active too)
- */
- if ( ((setting == ACHANNEL_SETTING_VISIBLE) && (mode != ACHANNEL_SETFLAG_CLEAR)) ||
- ((setting != ACHANNEL_SETTING_VISIBLE) && (mode == ACHANNEL_SETFLAG_CLEAR)))
- {
- /* go backwards in the list, until the highest-ranking element (by indention has been covered) */
- for (ale = match->prev; ale; ale = ale->prev) {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- int level;
-
- /* if no channel info was found, skip, since this type might not have any useful info */
- if (acf == NULL)
- continue;
-
- /* get the level of the current channel traversed
- * - we define the level as simply being the offset for the start of the channel
- */
- level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
- /* if the level is 'less than' (i.e. more important) the level we're matching
- * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
- * when toggling visibility of F-Curves, gets flushed, which should happen if we don't let prevLevel
- * get updated below once the first 1st group is found)...
- */
- if (level < prevLevel) {
- /* flush the new status... */
- ANIM_channel_setting_set(ac, ale, setting, mode);
-
- /* store this level as the 'old' level now */
- prevLevel = level;
- }
- /* if the level is 'greater than' (i.e. less important) than the previous level... */
- else if (level > prevLevel) {
- /* if previous level was a base-level (i.e. 0 offset / root of one hierarchy),
- * stop here
- */
- if (prevLevel == 0)
- break;
- /* otherwise, this level weaves into another sibling hierarchy to the previous one just
- * finished, so skip until we get to the parent of this level
- */
- else
- continue;
- }
- }
- }
-
- /* flush down (always) */
- {
- /* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
- for (ale = match->next; ale; ale = ale->next) {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- int level;
-
- /* if no channel info was found, skip, since this type might not have any useful info */
- if (acf == NULL)
- continue;
-
- /* get the level of the current channel traversed
- * - we define the level as simply being the offset for the start of the channel
- */
- level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
- /* if the level is 'greater than' (i.e. less important) the channel that was changed,
- * flush the new status...
- */
- if (level > matchLevel)
- ANIM_channel_setting_set(ac, ale, setting, mode);
- /* however, if the level is 'less than or equal to' the channel that was changed,
- * (i.e. the current channel is as important if not more important than the changed channel)
- * then we should stop, since we've found the last one of the children we should flush
- */
- else
- break;
-
- /* store this level as the 'old' level now */
- // prevLevel = level; // XXX: prevLevel is unused
- }
- }
+void ANIM_flush_setting_anim_channels(bAnimContext *ac,
+ ListBase *anim_data,
+ bAnimListElem *ale_setting,
+ eAnimChannel_Settings setting,
+ eAnimChannels_SetFlag mode)
+{
+ bAnimListElem *ale, *match = NULL;
+ int prevLevel = 0, matchLevel = 0;
+
+ /* sanity check */
+ if (ELEM(NULL, anim_data, anim_data->first))
+ return;
+
+ if (setting == ACHANNEL_SETTING_ALWAYS_VISIBLE) {
+ return;
+ }
+
+ /* find the channel that got changed */
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ /* compare data, and type as main way of identifying the channel */
+ if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
+ /* we also have to check the ID, this is assigned to, since a block may have multiple users */
+ /* TODO: is the owner-data more revealing? */
+ if (ale->id == ale_setting->id) {
+ match = ale;
+ break;
+ }
+ }
+ }
+ if (match == NULL) {
+ printf("ERROR: no channel matching the one changed was found\n");
+ return;
+ }
+ else {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
+
+ if (acf == NULL) {
+ printf("ERROR: no channel info for the changed channel\n");
+ return;
+ }
+
+ /* get the level of the channel that was affected
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ matchLevel = (acf->get_offset) ? acf->get_offset(ac, ale_setting) : 0;
+ prevLevel = matchLevel;
+ }
+
+ /* flush up?
+ *
+ * For Visibility:
+ * - only flush up if the current state is now enabled (positive 'on' state is default)
+ * (otherwise, it's too much work to force the parents to be inactive too)
+ *
+ * For everything else:
+ * - only flush up if the current state is now disabled (negative 'off' state is default)
+ * (otherwise, it's too much work to force the parents to be active too)
+ */
+ if (((setting == ACHANNEL_SETTING_VISIBLE) && (mode != ACHANNEL_SETFLAG_CLEAR)) ||
+ ((setting != ACHANNEL_SETTING_VISIBLE) && (mode == ACHANNEL_SETFLAG_CLEAR))) {
+ /* go backwards in the list, until the highest-ranking element (by indention has been covered) */
+ for (ale = match->prev; ale; ale = ale->prev) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ int level;
+
+ /* if no channel info was found, skip, since this type might not have any useful info */
+ if (acf == NULL)
+ continue;
+
+ /* get the level of the current channel traversed
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+
+ /* if the level is 'less than' (i.e. more important) the level we're matching
+ * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
+ * when toggling visibility of F-Curves, gets flushed, which should happen if we don't let prevLevel
+ * get updated below once the first 1st group is found)...
+ */
+ if (level < prevLevel) {
+ /* flush the new status... */
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+
+ /* store this level as the 'old' level now */
+ prevLevel = level;
+ }
+ /* if the level is 'greater than' (i.e. less important) than the previous level... */
+ else if (level > prevLevel) {
+ /* if previous level was a base-level (i.e. 0 offset / root of one hierarchy),
+ * stop here
+ */
+ if (prevLevel == 0)
+ break;
+ /* otherwise, this level weaves into another sibling hierarchy to the previous one just
+ * finished, so skip until we get to the parent of this level
+ */
+ else
+ continue;
+ }
+ }
+ }
+
+ /* flush down (always) */
+ {
+ /* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
+ for (ale = match->next; ale; ale = ale->next) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ int level;
+
+ /* if no channel info was found, skip, since this type might not have any useful info */
+ if (acf == NULL)
+ continue;
+
+ /* get the level of the current channel traversed
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+
+ /* if the level is 'greater than' (i.e. less important) the channel that was changed,
+ * flush the new status...
+ */
+ if (level > matchLevel)
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+ /* however, if the level is 'less than or equal to' the channel that was changed,
+ * (i.e. the current channel is as important if not more important than the changed channel)
+ * then we should stop, since we've found the last one of the children we should flush
+ */
+ else
+ break;
+
+ /* store this level as the 'old' level now */
+ // prevLevel = level; // XXX: prevLevel is unused
+ }
+ }
}
/* -------------------------- F-Curves ------------------------------------- */
@@ -594,59 +582,59 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
/* Delete the given F-Curve from its AnimData block */
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu)
{
- /* - if no AnimData, we've got nowhere to remove the F-Curve from
- * (this doesn't guarantee that the F-Curve is in there, but at least we tried
- * - if no F-Curve, there is nothing to remove
- */
- if (ELEM(NULL, adt, fcu))
- return;
-
- /* remove from whatever list it came from
- * - Action Group
- * - Action
- * - Drivers
- * - TODO... some others?
- */
- if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
- /* driver F-Curve */
- BLI_remlink(&adt->drivers, fcu);
- }
- else if (adt->action) {
- bAction *act = adt->action;
-
- /* remove from group or action, whichever one "owns" the F-Curve */
- if (fcu->grp) {
- bActionGroup *agrp = fcu->grp;
-
- /* remove F-Curve from group+action */
- action_groups_remove_channel(act, fcu);
-
- /* if group has no more channels, remove it too,
- * otherwise can have many dangling groups [#33541]
- */
- if (BLI_listbase_is_empty(&agrp->channels)) {
- BLI_freelinkN(&act->groups, agrp);
- }
- }
- else {
- BLI_remlink(&act->curves, fcu);
- }
-
- /* if action has no more F-Curves as a result of this, unlink it from
- * AnimData if it did not come from a NLA Strip being tweaked.
- *
- * This is done so that we don't have dangling Object+Action entries in
- * channel list that are empty, and linger around long after the data they
- * are for has disappeared (and probably won't come back).
- */
- if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
- id_us_min(&act->id);
- adt->action = NULL;
- }
- }
-
- /* free the F-Curve itself */
- free_fcurve(fcu);
+ /* - if no AnimData, we've got nowhere to remove the F-Curve from
+ * (this doesn't guarantee that the F-Curve is in there, but at least we tried
+ * - if no F-Curve, there is nothing to remove
+ */
+ if (ELEM(NULL, adt, fcu))
+ return;
+
+ /* remove from whatever list it came from
+ * - Action Group
+ * - Action
+ * - Drivers
+ * - TODO... some others?
+ */
+ if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
+ /* driver F-Curve */
+ BLI_remlink(&adt->drivers, fcu);
+ }
+ else if (adt->action) {
+ bAction *act = adt->action;
+
+ /* remove from group or action, whichever one "owns" the F-Curve */
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
+
+ /* remove F-Curve from group+action */
+ action_groups_remove_channel(act, fcu);
+
+ /* if group has no more channels, remove it too,
+ * otherwise can have many dangling groups [#33541]
+ */
+ if (BLI_listbase_is_empty(&agrp->channels)) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ else {
+ BLI_remlink(&act->curves, fcu);
+ }
+
+ /* if action has no more F-Curves as a result of this, unlink it from
+ * AnimData if it did not come from a NLA Strip being tweaked.
+ *
+ * This is done so that we don't have dangling Object+Action entries in
+ * channel list that are empty, and linger around long after the data they
+ * are for has disappeared (and probably won't come back).
+ */
+ if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
+ id_us_min(&act->id);
+ adt->action = NULL;
+ }
+ }
+
+ /* free the F-Curve itself */
+ free_fcurve(fcu);
}
/* ************************************************************************** */
@@ -657,40 +645,40 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
/* poll callback for being in an Animation Editor channels list region */
static bool animedit_poll_channels_active(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
- /* animation editor test */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
+ /* animation editor test */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
+ return 0;
- return 1;
+ return 1;
}
/* poll callback for Animation Editor channels list region + not in NLA-tweakmode for NLA */
static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ Scene *scene = CTX_data_scene(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
- /* animation editor test */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
+ /* animation editor test */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
+ return 0;
- /* NLA TweakMode test */
- if (sa->spacetype == SPACE_NLA) {
- if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
- return 0;
- }
+ /* NLA TweakMode test */
+ if (sa->spacetype == SPACE_NLA) {
+ if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
+ return 0;
+ }
- return 1;
+ return 1;
}
/* ****************** Rearrange Channels Operator ******************* */
@@ -698,146 +686,144 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
/* constants for channel rearranging */
/* WARNING: don't change existing ones without modifying rearrange func accordingly */
typedef enum eRearrangeAnimChan_Mode {
- REARRANGE_ANIMCHAN_TOP = -2,
- REARRANGE_ANIMCHAN_UP = -1,
- REARRANGE_ANIMCHAN_DOWN = 1,
- REARRANGE_ANIMCHAN_BOTTOM = 2,
+ REARRANGE_ANIMCHAN_TOP = -2,
+ REARRANGE_ANIMCHAN_UP = -1,
+ REARRANGE_ANIMCHAN_DOWN = 1,
+ REARRANGE_ANIMCHAN_BOTTOM = 2,
} eRearrangeAnimChan_Mode;
/* defines for rearranging channels */
static const EnumPropertyItem prop_animchannel_rearrange_types[] = {
- {REARRANGE_ANIMCHAN_TOP, "TOP", 0, "To Top", ""},
- {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
- {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
- {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
- {0, NULL, 0, NULL, NULL},
+ {REARRANGE_ANIMCHAN_TOP, "TOP", 0, "To Top", ""},
+ {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
+ {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
+ {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* Reordering "Islands" Defines ----------------------------------- */
/* Island definition - just a listbase container */
typedef struct tReorderChannelIsland {
- struct tReorderChannelIsland *next, *prev;
+ struct tReorderChannelIsland *next, *prev;
- ListBase channels; /* channels within this region with the same state */
- int flag; /* eReorderIslandFlag */
+ ListBase channels; /* channels within this region with the same state */
+ int flag; /* eReorderIslandFlag */
} tReorderChannelIsland;
/* flags for channel reordering islands */
typedef enum eReorderIslandFlag {
- REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
- REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
- REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
- REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
+ REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
+ REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
+ REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
+ REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
} eReorderIslandFlag;
-
/* Rearrange Methods --------------------------------------------- */
static bool rearrange_island_ok(tReorderChannelIsland *island)
{
- /* island must not be untouchable */
- if (island->flag & REORDER_ISLAND_UNTOUCHABLE)
- return 0;
+ /* island must not be untouchable */
+ if (island->flag & REORDER_ISLAND_UNTOUCHABLE)
+ return 0;
- /* island should be selected to be moved */
- return (island->flag & REORDER_ISLAND_SELECTED) && !(island->flag & REORDER_ISLAND_MOVED);
+ /* island should be selected to be moved */
+ return (island->flag & REORDER_ISLAND_SELECTED) && !(island->flag & REORDER_ISLAND_MOVED);
}
/* ............................. */
static bool rearrange_island_top(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (rearrange_island_ok(island)) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* make it first element */
- BLI_insertlinkbefore(list, list->first, island);
+ /* make it first element */
+ BLI_insertlinkbefore(list, list->first, island);
- return 1;
- }
+ return 1;
+ }
- return 0;
+ return 0;
}
static bool rearrange_island_up(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* moving up = moving before the previous island, otherwise we're in the same place */
- tReorderChannelIsland *prev = island->prev;
+ if (rearrange_island_ok(island)) {
+ /* moving up = moving before the previous island, otherwise we're in the same place */
+ tReorderChannelIsland *prev = island->prev;
- /* Skip hidden islands! */
- while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
- prev = prev->prev;
- }
+ /* Skip hidden islands! */
+ while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
+ prev = prev->prev;
+ }
- if (prev) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (prev) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* push it up */
- BLI_insertlinkbefore(list, prev, island);
+ /* push it up */
+ BLI_insertlinkbefore(list, prev, island);
- return 1;
- }
- }
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
static bool rearrange_island_down(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* moving down = moving after the next island, otherwise we're in the same place */
- tReorderChannelIsland *next = island->next;
+ if (rearrange_island_ok(island)) {
+ /* moving down = moving after the next island, otherwise we're in the same place */
+ tReorderChannelIsland *next = island->next;
- /* Skip hidden islands! */
- while (next && next->flag & REORDER_ISLAND_HIDDEN) {
- next = next->next;
- }
+ /* Skip hidden islands! */
+ while (next && next->flag & REORDER_ISLAND_HIDDEN) {
+ next = next->next;
+ }
- if (next) {
- /* can only move past if next is not untouchable (i.e. nothing can go after it) */
- if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (next) {
+ /* can only move past if next is not untouchable (i.e. nothing can go after it) */
+ if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* push it down */
- BLI_insertlinkafter(list, next, island);
+ /* push it down */
+ BLI_insertlinkafter(list, next, island);
- return true;
- }
- }
- /* else: no next channel, so we're at the bottom already, so can't move */
- }
+ return true;
+ }
+ }
+ /* else: no next channel, so we're at the bottom already, so can't move */
+ }
- return false;
+ return false;
}
static bool rearrange_island_bottom(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- tReorderChannelIsland *last = list->last;
-
- /* remove island from current position */
- BLI_remlink(list, island);
+ if (rearrange_island_ok(island)) {
+ tReorderChannelIsland *last = list->last;
- /* add before or after the last channel? */
- if ((last->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
- /* can add after it */
- BLI_addtail(list, island);
- }
- else {
- /* can at most go just before it, since last cannot be moved */
- BLI_insertlinkbefore(list, last, island);
+ /* remove island from current position */
+ BLI_remlink(list, island);
- }
+ /* add before or after the last channel? */
+ if ((last->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
+ /* can add after it */
+ BLI_addtail(list, island);
+ }
+ else {
+ /* can at most go just before it, since last cannot be moved */
+ BLI_insertlinkbefore(list, last, island);
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* ............................. */
@@ -854,184 +840,187 @@ typedef bool (*AnimChanRearrangeFp)(ListBase *list, tReorderChannelIsland *islan
/* get rearranging function, given 'rearrange' mode */
static AnimChanRearrangeFp rearrange_get_mode_func(eRearrangeAnimChan_Mode mode)
{
- switch (mode) {
- case REARRANGE_ANIMCHAN_TOP:
- return rearrange_island_top;
- case REARRANGE_ANIMCHAN_UP:
- return rearrange_island_up;
- case REARRANGE_ANIMCHAN_DOWN:
- return rearrange_island_down;
- case REARRANGE_ANIMCHAN_BOTTOM:
- return rearrange_island_bottom;
- default:
- return NULL;
- }
+ switch (mode) {
+ case REARRANGE_ANIMCHAN_TOP:
+ return rearrange_island_top;
+ case REARRANGE_ANIMCHAN_UP:
+ return rearrange_island_up;
+ case REARRANGE_ANIMCHAN_DOWN:
+ return rearrange_island_down;
+ case REARRANGE_ANIMCHAN_BOTTOM:
+ return rearrange_island_bottom;
+ default:
+ return NULL;
+ }
}
/* Rearrange Islands Generics ------------------------------------- */
/* add channel into list of islands */
-static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList,
- Link *channel, eAnim_ChannelType type,
+static void rearrange_animchannel_add_to_islands(ListBase *islands,
+ ListBase *srcList,
+ Link *channel,
+ eAnim_ChannelType type,
const bool is_hidden)
{
- /* always try to add to last island if possible */
- tReorderChannelIsland *island = islands->last;
- bool is_sel = false, is_untouchable = false;
-
- /* get flags - selected and untouchable from the channel */
- switch (type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)channel;
-
- is_sel = SEL_AGRP(agrp);
- is_untouchable = (agrp->flag & AGRP_TEMP) != 0;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)channel;
-
- is_sel = SEL_FCU(fcu);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)channel;
-
- is_sel = SEL_NLT(nlt);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)channel;
-
- is_sel = SEL_GPL(gpl);
- break;
- }
- default:
- printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %u\n", type);
- return;
- }
-
- /* do we need to add to a new island? */
- if (/* 1) no islands yet */
- (island == NULL) ||
- /* 2) unselected islands have single channels only - to allow up/down movement */
- ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
- /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
- (is_sel == 0) ||
- /* 4) hidden status changes */
- ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)
- )
- {
- /* create a new island now */
- island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
- BLI_addtail(islands, island);
-
- if (is_sel)
- island->flag |= REORDER_ISLAND_SELECTED;
- if (is_untouchable)
- island->flag |= REORDER_ISLAND_UNTOUCHABLE;
- if (is_hidden)
- island->flag |= REORDER_ISLAND_HIDDEN;
- }
-
- /* add channel to island - need to remove it from its existing list first though */
- BLI_remlink(srcList, channel);
- BLI_addtail(&island->channels, channel);
+ /* always try to add to last island if possible */
+ tReorderChannelIsland *island = islands->last;
+ bool is_sel = false, is_untouchable = false;
+
+ /* get flags - selected and untouchable from the channel */
+ switch (type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)channel;
+
+ is_sel = SEL_AGRP(agrp);
+ is_untouchable = (agrp->flag & AGRP_TEMP) != 0;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)channel;
+
+ is_sel = SEL_FCU(fcu);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)channel;
+
+ is_sel = SEL_NLT(nlt);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)channel;
+
+ is_sel = SEL_GPL(gpl);
+ break;
+ }
+ default:
+ printf(
+ "rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %u\n",
+ type);
+ return;
+ }
+
+ /* do we need to add to a new island? */
+ if (/* 1) no islands yet */
+ (island == NULL) ||
+ /* 2) unselected islands have single channels only - to allow up/down movement */
+ ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
+ /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ (is_sel == 0) ||
+ /* 4) hidden status changes */
+ ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)) {
+ /* create a new island now */
+ island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
+ BLI_addtail(islands, island);
+
+ if (is_sel)
+ island->flag |= REORDER_ISLAND_SELECTED;
+ if (is_untouchable)
+ island->flag |= REORDER_ISLAND_UNTOUCHABLE;
+ if (is_hidden)
+ island->flag |= REORDER_ISLAND_HIDDEN;
+ }
+
+ /* add channel to island - need to remove it from its existing list first though */
+ BLI_remlink(srcList, channel);
+ BLI_addtail(&island->channels, channel);
}
/* flatten islands out into a single list again */
static void rearrange_animchannel_flatten_islands(ListBase *islands, ListBase *srcList)
{
- tReorderChannelIsland *island, *isn = NULL;
+ tReorderChannelIsland *island, *isn = NULL;
- /* make sure srcList is empty now */
- BLI_assert(BLI_listbase_is_empty(srcList));
+ /* make sure srcList is empty now */
+ BLI_assert(BLI_listbase_is_empty(srcList));
- /* go through merging islands */
- for (island = islands->first; island; island = isn) {
- isn = island->next;
+ /* go through merging islands */
+ for (island = islands->first; island; island = isn) {
+ isn = island->next;
- /* merge island channels back to main list, then delete the island */
- BLI_movelisttolist(srcList, &island->channels);
- BLI_freelinkN(islands, island);
- }
+ /* merge island channels back to main list, then delete the island */
+ BLI_movelisttolist(srcList, &island->channels);
+ BLI_freelinkN(islands, island);
+ }
}
/* ............................. */
/* get a list of all bAnimListElem's of a certain type which are currently visible */
-static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, bAnimContext *ac, eAnim_ChannelType type)
+static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible,
+ bAnimContext *ac,
+ eAnim_ChannelType type)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale, *ale_next;
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale, *ale_next;
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- /* get all visible channels */
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* get all visible channels */
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* now, only keep the ones that are of the types we are interested in */
- for (ale = anim_data.first; ale; ale = ale_next) {
- ale_next = ale->next;
+ /* now, only keep the ones that are of the types we are interested in */
+ for (ale = anim_data.first; ale; ale = ale_next) {
+ ale_next = ale->next;
- if (ale->type != type) {
- BLI_freelinkN(&anim_data, ale);
- }
- }
+ if (ale->type != type) {
+ BLI_freelinkN(&anim_data, ale);
+ }
+ }
- /* return cleaned up list */
- *anim_data_visible = anim_data;
+ /* return cleaned up list */
+ *anim_data_visible = anim_data;
}
/* performing rearranging of channels using islands */
-static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func,
- eRearrangeAnimChan_Mode mode, eAnim_ChannelType type,
+static bool rearrange_animchannel_islands(ListBase *list,
+ AnimChanRearrangeFp rearrange_func,
+ eRearrangeAnimChan_Mode mode,
+ eAnim_ChannelType type,
ListBase *anim_data_visible)
{
- ListBase islands = {NULL, NULL};
- Link *channel, *chanNext = NULL;
- bool done = false;
-
- /* don't waste effort on an empty list */
- if (BLI_listbase_is_empty(list))
- return 0;
-
- /* group channels into islands */
- for (channel = list->first; channel; channel = chanNext) {
- /* find out whether this channel is present in anim_data_visible or not! */
- const bool is_hidden = (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
- chanNext = channel->next;
- rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
- }
-
- /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
- * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
- * shouldn't need to encounter items we've moved already
- */
- if (islands.first != islands.last) {
- tReorderChannelIsland *first = (mode > 0) ? islands.last : islands.first;
- tReorderChannelIsland *island, *isn = NULL;
-
- for (island = first; island; island = isn) {
- isn = (mode > 0) ? island->prev : island->next;
-
- /* perform rearranging */
- if (rearrange_func(&islands, island)) {
- island->flag |= REORDER_ISLAND_MOVED;
- done = true;
- }
- }
- }
-
- /* ungroup islands */
- rearrange_animchannel_flatten_islands(&islands, list);
-
- /* did we do anything? */
- return done;
+ ListBase islands = {NULL, NULL};
+ Link *channel, *chanNext = NULL;
+ bool done = false;
+
+ /* don't waste effort on an empty list */
+ if (BLI_listbase_is_empty(list))
+ return 0;
+
+ /* group channels into islands */
+ for (channel = list->first; channel; channel = chanNext) {
+ /* find out whether this channel is present in anim_data_visible or not! */
+ const bool is_hidden =
+ (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
+ chanNext = channel->next;
+ rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
+ }
+
+ /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
+ * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
+ * shouldn't need to encounter items we've moved already
+ */
+ if (islands.first != islands.last) {
+ tReorderChannelIsland *first = (mode > 0) ? islands.last : islands.first;
+ tReorderChannelIsland *island, *isn = NULL;
+
+ for (island = first; island; island = isn) {
+ isn = (mode > 0) ? island->prev : island->next;
+
+ /* perform rearranging */
+ if (rearrange_func(&islands, island)) {
+ island->flag |= REORDER_ISLAND_MOVED;
+ done = true;
+ }
+ }
+ }
+
+ /* ungroup islands */
+ rearrange_animchannel_flatten_islands(&islands, list);
+
+ /* did we do anything? */
+ return done;
}
/* NLA Specific Stuff ----------------------------------------------------- */
@@ -1042,25 +1031,26 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
*/
static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
{
- AnimChanRearrangeFp rearrange_func;
- ListBase anim_data_visible = {NULL, NULL};
+ AnimChanRearrangeFp rearrange_func;
+ ListBase anim_data_visible = {NULL, NULL};
- /* hack: invert mode so that functions will work in right order */
- mode *= -1;
+ /* hack: invert mode so that functions will work in right order */
+ mode *= -1;
- /* get rearranging function */
- rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ /* get rearranging function */
+ rearrange_func = rearrange_get_mode_func(mode);
+ if (rearrange_func == NULL)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
- /* perform rearranging on tracks list */
- rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
+ /* perform rearranging on tracks list */
+ rearrange_animchannel_islands(
+ &adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Drivers Specific Stuff ------------------------------------------------- */
@@ -1068,27 +1058,30 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
/* Change the order drivers within AnimData block
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
+static void rearrange_driver_channels(bAnimContext *ac,
+ AnimData *adt,
+ eRearrangeAnimChan_Mode mode)
{
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- ListBase anim_data_visible = {NULL, NULL};
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ ListBase anim_data_visible = {NULL, NULL};
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* only consider drivers if they're accessible */
- if (EXPANDED_DRVD(adt) == 0)
- return;
+ /* only consider drivers if they're accessible */
+ if (EXPANDED_DRVD(adt) == 0)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
- /* perform rearranging on drivers list (drivers are really just F-Curves) */
- rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+ /* perform rearranging on drivers list (drivers are really just F-Curves) */
+ rearrange_animchannel_islands(
+ &adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Action Specific Stuff ------------------------------------------------- */
@@ -1096,88 +1089,88 @@ static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, eRearrang
/* make sure all action-channels belong to a group (and clear action's list) */
static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
{
- bActionGroup *agrp;
- FCurve *fcu;
-
- if (act == NULL)
- return;
-
- /* Separate F-Curves into lists per group */
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- if (agrp->channels.first) {
- fcu = agrp->channels.last;
- act->curves.first = fcu->next;
-
- fcu = agrp->channels.first;
- fcu->prev = NULL;
-
- fcu = agrp->channels.last;
- fcu->next = NULL;
- }
- }
-
- /* Initialize memory for temp-group */
- memset(tgrp, 0, sizeof(bActionGroup));
- tgrp->flag |= (AGRP_EXPANDED | AGRP_TEMP);
- BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
-
- /* Move any action-channels not already moved, to the temp group */
- if (act->curves.first) {
- /* start of list */
- fcu = act->curves.first;
- fcu->prev = NULL;
- tgrp->channels.first = fcu;
- act->curves.first = NULL;
-
- /* end of list */
- fcu = act->curves.last;
- fcu->next = NULL;
- tgrp->channels.last = fcu;
- act->curves.last = NULL;
-
- /* ensure that all of these get their group set to this temp group
- * (so that visibility filtering works)
- */
- for (fcu = tgrp->channels.first; fcu; fcu = fcu->next) {
- fcu->grp = tgrp;
- }
- }
-
- /* Add temp-group to list */
- BLI_addtail(&act->groups, tgrp);
+ bActionGroup *agrp;
+ FCurve *fcu;
+
+ if (act == NULL)
+ return;
+
+ /* Separate F-Curves into lists per group */
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ if (agrp->channels.first) {
+ fcu = agrp->channels.last;
+ act->curves.first = fcu->next;
+
+ fcu = agrp->channels.first;
+ fcu->prev = NULL;
+
+ fcu = agrp->channels.last;
+ fcu->next = NULL;
+ }
+ }
+
+ /* Initialize memory for temp-group */
+ memset(tgrp, 0, sizeof(bActionGroup));
+ tgrp->flag |= (AGRP_EXPANDED | AGRP_TEMP);
+ BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
+
+ /* Move any action-channels not already moved, to the temp group */
+ if (act->curves.first) {
+ /* start of list */
+ fcu = act->curves.first;
+ fcu->prev = NULL;
+ tgrp->channels.first = fcu;
+ act->curves.first = NULL;
+
+ /* end of list */
+ fcu = act->curves.last;
+ fcu->next = NULL;
+ tgrp->channels.last = fcu;
+ act->curves.last = NULL;
+
+ /* ensure that all of these get their group set to this temp group
+ * (so that visibility filtering works)
+ */
+ for (fcu = tgrp->channels.first; fcu; fcu = fcu->next) {
+ fcu->grp = tgrp;
+ }
+ }
+
+ /* Add temp-group to list */
+ BLI_addtail(&act->groups, tgrp);
}
/* link lists of channels that groups have */
static void join_groups_action_temp(bAction *act)
{
- bActionGroup *agrp;
+ bActionGroup *agrp;
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- ListBase tempGroup;
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ ListBase tempGroup;
- /* add list of channels to action's channels */
- tempGroup = agrp->channels;
- BLI_movelisttolist(&act->curves, &agrp->channels);
- agrp->channels = tempGroup;
+ /* add list of channels to action's channels */
+ tempGroup = agrp->channels;
+ BLI_movelisttolist(&act->curves, &agrp->channels);
+ agrp->channels = tempGroup;
- /* clear moved flag */
- agrp->flag &= ~AGRP_MOVED;
+ /* clear moved flag */
+ agrp->flag &= ~AGRP_MOVED;
- /* if group was temporary one:
- * - unassign all FCurves which were temporarily added to it
- * - remove from list (but don't free as it's on the stack!)
- */
- if (agrp->flag & AGRP_TEMP) {
- FCurve *fcu;
+ /* if group was temporary one:
+ * - unassign all FCurves which were temporarily added to it
+ * - remove from list (but don't free as it's on the stack!)
+ */
+ if (agrp->flag & AGRP_TEMP) {
+ FCurve *fcu;
- for (fcu = agrp->channels.first; fcu; fcu = fcu->next) {
- fcu->grp = NULL;
- }
+ for (fcu = agrp->channels.first; fcu; fcu = fcu->next) {
+ fcu->grp = NULL;
+ }
- BLI_remlink(&act->groups, agrp);
- break;
- }
- }
+ BLI_remlink(&act->groups, agrp);
+ break;
+ }
+ }
}
/* Change the order of anim-channels within action
@@ -1185,635 +1178,644 @@ static void join_groups_action_temp(bAction *act)
*/
static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrangeAnimChan_Mode mode)
{
- bActionGroup tgrp;
- ListBase anim_data_visible = {NULL, NULL};
- bool do_channels;
+ bActionGroup tgrp;
+ ListBase anim_data_visible = {NULL, NULL};
+ bool do_channels;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* make sure we're only operating with groups (vs a mixture of groups+curves) */
- split_groups_action_temp(act, &tgrp);
+ /* make sure we're only operating with groups (vs a mixture of groups+curves) */
+ split_groups_action_temp(act, &tgrp);
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
- /* rearrange groups first
- * - the group's channels will only get considered if nothing happened when rearranging the groups
- * i.e. the rearrange function returned 0
- */
- do_channels = (rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP,
- &anim_data_visible) == 0);
+ /* rearrange groups first
+ * - the group's channels will only get considered if nothing happened when rearranging the groups
+ * i.e. the rearrange function returned 0
+ */
+ do_channels = (rearrange_animchannel_islands(
+ &act->groups, rearrange_func, mode, ANIMTYPE_GROUP, &anim_data_visible) == 0);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
- if (do_channels) {
- bActionGroup *agrp;
+ if (do_channels) {
+ bActionGroup *agrp;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* only consider F-Curves if they're visible (group expanded) */
- if (EXPANDED_AGRP(ac, agrp)) {
- rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE,
- &anim_data_visible);
- }
- }
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ /* only consider F-Curves if they're visible (group expanded) */
+ if (EXPANDED_AGRP(ac, agrp)) {
+ rearrange_animchannel_islands(
+ &agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+ }
+ }
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
- }
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
+ }
- /* assemble lists into one list (and clear moved tags) */
- join_groups_action_temp(act);
+ /* assemble lists into one list (and clear moved tags) */
+ join_groups_action_temp(act);
}
/* ------------------- */
-static void rearrange_nla_control_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
+static void rearrange_nla_control_channels(bAnimContext *ac,
+ AnimData *adt,
+ eRearrangeAnimChan_Mode mode)
{
- ListBase anim_data_visible = {NULL, NULL};
+ ListBase anim_data_visible = {NULL, NULL};
- NlaTrack *nlt;
- NlaStrip *strip;
+ NlaTrack *nlt;
+ NlaStrip *strip;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* skip if these curves aren't being shown */
- if (adt->flag & ADT_NLA_SKEYS_COLLAPSED)
- return;
+ /* skip if these curves aren't being shown */
+ if (adt->flag & ADT_NLA_SKEYS_COLLAPSED)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLACURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLACURVE);
- /* we cannot rearrange between strips, but within each strip, we can rearrange those curves */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- for (strip = nlt->strips.first; strip; strip = strip->next) {
- rearrange_animchannel_islands(
- &strip->fcurves, rearrange_func, mode, ANIMTYPE_NLACURVE,
- &anim_data_visible);
- }
- }
+ /* we cannot rearrange between strips, but within each strip, we can rearrange those curves */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ for (strip = nlt->strips.first; strip; strip = strip->next) {
+ rearrange_animchannel_islands(
+ &strip->fcurves, rearrange_func, mode, ANIMTYPE_NLACURVE, &anim_data_visible);
+ }
+ }
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* ------------------- */
static void rearrange_gpencil_channels(bAnimContext *ac, eRearrangeAnimChan_Mode mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* get Grease Pencil datablocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* get Grease Pencil datablocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- ListBase anim_data_visible = {NULL, NULL};
- bGPdata *gpd = ale->data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ListBase anim_data_visible = {NULL, NULL};
+ bGPdata *gpd = ale->data;
- /* only consider layers if this datablock is open */
- BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
- if ((gpd->flag & GP_DATA_EXPAND) == 0)
- continue;
+ /* only consider layers if this datablock is open */
+ BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
+ if ((gpd->flag & GP_DATA_EXPAND) == 0)
+ continue;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
- /* rearrange datablock's layers */
- rearrange_animchannel_islands(&gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
+ /* rearrange datablock's layers */
+ rearrange_animchannel_islands(
+ &gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
- /* free visible layers data */
- BLI_freelistN(&anim_data_visible);
- }
+ /* free visible layers data */
+ BLI_freelistN(&anim_data_visible);
+ }
- /* free GPD channel data */
- ANIM_animdata_freelist(&anim_data);
+ /* free GPD channel data */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- eRearrangeAnimChan_Mode mode;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get mode */
- mode = RNA_enum_get(op->ptr, "direction");
-
- /* method to move channels depends on the editor */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- /* Grease Pencil channels */
- rearrange_gpencil_channels(&ac, mode);
- }
- else if (ac.datatype == ANIMCONT_MASK) {
- /* Grease Pencil channels */
- printf("Mask does not supported for moving yet\n");
- }
- else if (ac.datatype == ANIMCONT_ACTION) {
- /* Directly rearrange action's channels */
- rearrange_action_channels(&ac, ac.data, mode);
- }
- else {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get animdata blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ale->data;
-
- switch (ac.datatype) {
- case ANIMCONT_NLA: /* NLA-tracks only */
- rearrange_nla_channels(&ac, adt, mode);
- DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
- break;
-
- case ANIMCONT_DRIVERS: /* Drivers list only */
- rearrange_driver_channels(&ac, adt, mode);
- break;
-
- case ANIMCONT_ACTION: /* Single Action only... */
- case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
- {
- if (adt->action)
- rearrange_action_channels(&ac, adt->action, mode);
- else if (G.debug & G_DEBUG)
- printf("Animdata has no action\n");
- break;
- }
-
- default: /* DopeSheet/Graph Editor - Some Actions + NLA Control Curves */
- {
- /* NLA Control Curves */
- if (adt->nla_tracks.first)
- rearrange_nla_control_channels(&ac, adt, mode);
-
- /* Action */
- if (adt->action)
- rearrange_action_channels(&ac, adt->action, mode);
- else if (G.debug & G_DEBUG)
- printf("Animdata has no action\n");
- break;
- }
- }
- }
-
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
- }
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ eRearrangeAnimChan_Mode mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get mode */
+ mode = RNA_enum_get(op->ptr, "direction");
+
+ /* method to move channels depends on the editor */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ /* Grease Pencil channels */
+ rearrange_gpencil_channels(&ac, mode);
+ }
+ else if (ac.datatype == ANIMCONT_MASK) {
+ /* Grease Pencil channels */
+ printf("Mask does not supported for moving yet\n");
+ }
+ else if (ac.datatype == ANIMCONT_ACTION) {
+ /* Directly rearrange action's channels */
+ rearrange_action_channels(&ac, ac.data, mode);
+ }
+ else {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get animdata blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ale->data;
+
+ switch (ac.datatype) {
+ case ANIMCONT_NLA: /* NLA-tracks only */
+ rearrange_nla_channels(&ac, adt, mode);
+ DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
+ break;
+
+ case ANIMCONT_DRIVERS: /* Drivers list only */
+ rearrange_driver_channels(&ac, adt, mode);
+ break;
+
+ case ANIMCONT_ACTION: /* Single Action only... */
+ case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
+ {
+ if (adt->action)
+ rearrange_action_channels(&ac, adt->action, mode);
+ else if (G.debug & G_DEBUG)
+ printf("Animdata has no action\n");
+ break;
+ }
+
+ default: /* DopeSheet/Graph Editor - Some Actions + NLA Control Curves */
+ {
+ /* NLA Control Curves */
+ if (adt->nla_tracks.first)
+ rearrange_nla_control_channels(&ac, adt, mode);
+
+ /* Action */
+ if (adt->action)
+ rearrange_action_channels(&ac, adt->action, mode);
+ else if (G.debug & G_DEBUG)
+ printf("Animdata has no action\n");
+ break;
+ }
+ }
+ }
+
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_move(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move Channels";
- ot->idname = "ANIM_OT_channels_move";
- ot->description = "Rearrange selected animation channels";
+ /* identifiers */
+ ot->name = "Move Channels";
+ ot->idname = "ANIM_OT_channels_move";
+ ot->description = "Rearrange selected animation channels";
- /* api callbacks */
- ot->exec = animchannels_rearrange_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_rearrange_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna,
+ "direction",
+ prop_animchannel_rearrange_types,
+ REARRANGE_ANIMCHAN_DOWN,
+ "Direction",
+ "");
}
/* ******************** Group Channel Operator ************************ */
static bool animchannels_grouping_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- SpaceLink *sl;
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceLink *sl;
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
- /* animation editor test - must be suitable modes only */
- sl = CTX_wm_space_data(C);
+ /* animation editor test - must be suitable modes only */
+ sl = CTX_wm_space_data(C);
- switch (sa->spacetype) {
- /* supported... */
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)sl;
+ switch (sa->spacetype) {
+ /* supported... */
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
- /* dopesheet and action only - all others are for other datatypes or have no groups */
- if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
- return 0;
+ /* dopesheet and action only - all others are for other datatypes or have no groups */
+ if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
+ return 0;
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)sl;
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
- /* drivers can't have groups... */
- if (sipo->mode != SIPO_MODE_ANIMATION)
- return 0;
+ /* drivers can't have groups... */
+ if (sipo->mode != SIPO_MODE_ANIMATION)
+ return 0;
- break;
- }
- /* unsupported... */
- default:
- return 0;
- }
+ break;
+ }
+ /* unsupported... */
+ default:
+ return 0;
+ }
- return 1;
+ return 1;
}
/* ----------------------------------------------------------- */
-static void animchannels_group_channels(bAnimContext *ac, bAnimListElem *adt_ref, const char name[])
+static void animchannels_group_channels(bAnimContext *ac,
+ bAnimListElem *adt_ref,
+ const char name[])
{
- AnimData *adt = adt_ref->adt;
- bAction *act = adt->action;
+ AnimData *adt = adt_ref->adt;
+ bAction *act = adt->action;
- if (act) {
- ListBase anim_data = {NULL, NULL};
- int filter;
+ if (act) {
+ ListBase anim_data = {NULL, NULL};
+ int filter;
- /* find selected F-Curves to re-group */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
- ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
+ /* find selected F-Curves to re-group */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
+ ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
- if (anim_data.first) {
- bActionGroup *agrp;
- bAnimListElem *ale;
+ if (anim_data.first) {
+ bActionGroup *agrp;
+ bAnimListElem *ale;
- /* create new group, which should now be part of the action */
- agrp = action_groups_add_new(act, name);
- BLI_assert(agrp != NULL);
+ /* create new group, which should now be part of the action */
+ agrp = action_groups_add_new(act, name);
+ BLI_assert(agrp != NULL);
- /* transfer selected F-Curves across to new group */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- bActionGroup *grp = fcu->grp;
+ /* transfer selected F-Curves across to new group */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bActionGroup *grp = fcu->grp;
- /* remove F-Curve from group, then group too if it is now empty */
- action_groups_remove_channel(act, fcu);
+ /* remove F-Curve from group, then group too if it is now empty */
+ action_groups_remove_channel(act, fcu);
- if ((grp) && BLI_listbase_is_empty(&grp->channels)) {
- BLI_freelinkN(&act->groups, grp);
- }
+ if ((grp) && BLI_listbase_is_empty(&grp->channels)) {
+ BLI_freelinkN(&act->groups, grp);
+ }
- /* add F-Curve to group */
- action_groups_add_channel(act, agrp, fcu);
- }
- }
+ /* add F-Curve to group */
+ action_groups_add_channel(act, agrp, fcu);
+ }
+ }
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- }
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ }
}
static int animchannels_group_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- char name[MAX_NAME];
+ bAnimContext ac;
+ char name[MAX_NAME];
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get name for new group */
- RNA_string_get(op->ptr, "name", name);
+ /* get name for new group */
+ RNA_string_get(op->ptr, "name", name);
- /* XXX: name for group should never be empty... */
- if (name[0]) {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ /* XXX: name for group should never be empty... */
+ if (name[0]) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- animchannels_group_channels(&ac, ale, name);
- }
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ animchannels_group_channels(&ac, ale, name);
+ }
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
- /* updatss */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- }
+ /* updatss */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_group(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Group Channels";
- ot->idname = "ANIM_OT_channels_group";
- ot->description = "Add selected F-Curves to a new group";
+ /* identifiers */
+ ot->name = "Group Channels";
+ ot->idname = "ANIM_OT_channels_group";
+ ot->description = "Add selected F-Curves to a new group";
- /* callbacks */
- ot->invoke = WM_operator_props_popup;
- ot->exec = animchannels_group_exec;
- ot->poll = animchannels_grouping_poll;
+ /* callbacks */
+ ot->invoke = WM_operator_props_popup;
+ ot->exec = animchannels_group_exec;
+ ot->poll = animchannels_grouping_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_string(ot->srna, "name", "New Group",
- sizeof(((bActionGroup *)NULL)->name),
- "Name", "Name of newly created group");
- /* XXX: still not too sure about this - keeping same text is confusing... */
- // RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ /* props */
+ ot->prop = RNA_def_string(ot->srna,
+ "name",
+ "New Group",
+ sizeof(((bActionGroup *)NULL)->name),
+ "Name",
+ "Name of newly created group");
+ /* XXX: still not too sure about this - keeping same text is confusing... */
+ // RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
/* ----------------------------------------------------------- */
static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* just selected F-Curves... */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* just selected F-Curves... */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* find action for this F-Curve... */
- if (ale->adt && ale->adt->action) {
- FCurve *fcu = (FCurve *)ale->data;
- bAction *act = ale->adt->action;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* find action for this F-Curve... */
+ if (ale->adt && ale->adt->action) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bAction *act = ale->adt->action;
- /* only proceed to remove if F-Curve is in a group... */
- if (fcu->grp) {
- bActionGroup *agrp = fcu->grp;
+ /* only proceed to remove if F-Curve is in a group... */
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
- /* remove F-Curve from group and add at tail (ungrouped) */
- action_groups_remove_channel(act, fcu);
- BLI_addtail(&act->curves, fcu);
+ /* remove F-Curve from group and add at tail (ungrouped) */
+ action_groups_remove_channel(act, fcu);
+ BLI_addtail(&act->curves, fcu);
- /* delete group if it is now empty */
- if (BLI_listbase_is_empty(&agrp->channels)) {
- BLI_freelinkN(&act->groups, agrp);
- }
- }
- }
- }
+ /* delete group if it is now empty */
+ if (BLI_listbase_is_empty(&agrp->channels)) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ }
+ }
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
- /* updates */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* updates */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Ungroup Channels";
- ot->idname = "ANIM_OT_channels_ungroup";
- ot->description = "Remove selected F-Curves from their current groups";
+ /* identifiers */
+ ot->name = "Ungroup Channels";
+ ot->idname = "ANIM_OT_channels_ungroup";
+ ot->description = "Remove selected F-Curves from their current groups";
- /* callbacks */
- ot->exec = animchannels_ungroup_exec;
- ot->poll = animchannels_grouping_poll;
+ /* callbacks */
+ ot->exec = animchannels_ungroup_exec;
+ ot->poll = animchannels_grouping_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Delete Channel Operator *********************** */
static void update_dependencies_on_delete(bAnimListElem *ale)
{
- ID *id = ale->id;
- AnimData *adt = BKE_animdata_from_id(id);
- /* TODO(sergey): Technically, if the animation element is being deleted
- * from a driver we don't have to tag action. This is something we can check
- * for in the future. For now just do most reliable tag whic hwas always
- * happening. */
- if (adt != NULL) {
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
- if (adt->action != NULL) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
- }
- }
- /* Deals with NLA and drivers.
- * Doesn't cause overhead for action updates, since object will receive
- * animation update after dependency graph flushes update from action to
- * all its users. */
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ ID *id = ale->id;
+ AnimData *adt = BKE_animdata_from_id(id);
+ /* TODO(sergey): Technically, if the animation element is being deleted
+ * from a driver we don't have to tag action. This is something we can check
+ * for in the future. For now just do most reliable tag whic hwas always
+ * happening. */
+ if (adt != NULL) {
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
+ }
+ }
+ /* Deals with NLA and drivers.
+ * Doesn't cause overhead for action updates, since object will receive
+ * animation update after dependency graph flushes update from action to
+ * all its users. */
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
}
static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* cannot delete in shapekey */
- if (ac.datatype == ANIMCONT_SHAPEKEY)
- return OPERATOR_CANCELLED;
-
-
- /* do groups only first (unless in Drivers mode, where there are none) */
- if (ac.datatype != ANIMCONT_DRIVERS) {
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* delete selected groups and their associated channels */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* only groups - don't check other types yet, since they may no-longer exist */
- if (ale->type == ANIMTYPE_GROUP) {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- AnimData *adt = ale->adt;
- FCurve *fcu, *fcn;
-
- /* skip this group if no AnimData available, as we can't safely remove the F-Curves */
- if (adt == NULL)
- continue;
-
- /* delete all of the Group's F-Curves, but no others */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcn) {
- fcn = fcu->next;
-
- /* remove from group and action, then free */
- action_groups_remove_channel(adt->action, fcu);
- free_fcurve(fcu);
- }
-
- /* free the group itself */
- if (adt->action) {
- BLI_freelinkN(&adt->action->groups, agrp);
- DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_ANIMATION);
- }
- else
- MEM_freeN(agrp);
- }
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- }
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* delete selected data channels */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->type) {
- case ANIMTYPE_FCURVE:
- {
- /* F-Curves if we can identify its parent */
- AnimData *adt = ale->adt;
- FCurve *fcu = (FCurve *)ale->data;
-
- /* try to free F-Curve */
- ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
- update_dependencies_on_delete(ale);
- break;
- }
- case ANIMTYPE_NLACURVE:
- {
- /* NLA Control Curve - Deleting it should disable the corresponding setting... */
- NlaStrip *strip = (NlaStrip *)ale->owner;
- FCurve *fcu = (FCurve *)ale->data;
-
- if (STREQ(fcu->rna_path, "strip_time")) {
- strip->flag &= ~NLASTRIP_FLAG_USR_TIME;
- }
- else if (STREQ(fcu->rna_path, "influence")) {
- strip->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
- }
- else {
- printf("ERROR: Trying to delete NLA Control Curve for unknown property '%s'\n", fcu->rna_path);
- }
-
- /* unlink and free the F-Curve */
- BLI_remlink(&strip->fcurves, fcu);
- free_fcurve(fcu);
- update_dependencies_on_delete(ale);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- /* Grease Pencil layer */
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- /* try to delete the layer's data and the layer itself */
- BKE_gpencil_layer_delete(gpd, gpl);
- ale->update = ANIM_UPDATE_DEPS;
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- /* Mask layer */
- Mask *mask = (Mask *)ale->id;
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- /* try to delete the layer's data and the layer itself */
- BKE_mask_layer_remove(mask, masklay);
- break;
- }
- }
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- DEG_relations_tag_update(CTX_data_main(C));
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* cannot delete in shapekey */
+ if (ac.datatype == ANIMCONT_SHAPEKEY)
+ return OPERATOR_CANCELLED;
+
+ /* do groups only first (unless in Drivers mode, where there are none) */
+ if (ac.datatype != ANIMCONT_DRIVERS) {
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* delete selected groups and their associated channels */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* only groups - don't check other types yet, since they may no-longer exist */
+ if (ale->type == ANIMTYPE_GROUP) {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ AnimData *adt = ale->adt;
+ FCurve *fcu, *fcn;
+
+ /* skip this group if no AnimData available, as we can't safely remove the F-Curves */
+ if (adt == NULL)
+ continue;
+
+ /* delete all of the Group's F-Curves, but no others */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcn) {
+ fcn = fcu->next;
+
+ /* remove from group and action, then free */
+ action_groups_remove_channel(adt->action, fcu);
+ free_fcurve(fcu);
+ }
+
+ /* free the group itself */
+ if (adt->action) {
+ BLI_freelinkN(&adt->action->groups, agrp);
+ DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_ANIMATION);
+ }
+ else
+ MEM_freeN(agrp);
+ }
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* delete selected data channels */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->type) {
+ case ANIMTYPE_FCURVE: {
+ /* F-Curves if we can identify its parent */
+ AnimData *adt = ale->adt;
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* try to free F-Curve */
+ ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
+ update_dependencies_on_delete(ale);
+ break;
+ }
+ case ANIMTYPE_NLACURVE: {
+ /* NLA Control Curve - Deleting it should disable the corresponding setting... */
+ NlaStrip *strip = (NlaStrip *)ale->owner;
+ FCurve *fcu = (FCurve *)ale->data;
+
+ if (STREQ(fcu->rna_path, "strip_time")) {
+ strip->flag &= ~NLASTRIP_FLAG_USR_TIME;
+ }
+ else if (STREQ(fcu->rna_path, "influence")) {
+ strip->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
+ }
+ else {
+ printf("ERROR: Trying to delete NLA Control Curve for unknown property '%s'\n",
+ fcu->rna_path);
+ }
+
+ /* unlink and free the F-Curve */
+ BLI_remlink(&strip->fcurves, fcu);
+ free_fcurve(fcu);
+ update_dependencies_on_delete(ale);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ /* Grease Pencil layer */
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* try to delete the layer's data and the layer itself */
+ BKE_gpencil_layer_delete(gpd, gpl);
+ ale->update = ANIM_UPDATE_DEPS;
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ /* Mask layer */
+ Mask *mask = (Mask *)ale->id;
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ /* try to delete the layer's data and the layer itself */
+ BKE_mask_layer_remove(mask, masklay);
+ break;
+ }
+ }
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ DEG_relations_tag_update(CTX_data_main(C));
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Channels";
- ot->idname = "ANIM_OT_channels_delete";
- ot->description = "Delete all selected animation channels";
+ /* identifiers */
+ ot->name = "Delete Channels";
+ ot->idname = "ANIM_OT_channels_delete";
+ ot->description = "Delete all selected animation channels";
- /* api callbacks */
- ot->exec = animchannels_delete_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_delete_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ********************** Set Flags Operator *********************** */
/* defines for setting animation-channel flags */
static const EnumPropertyItem prop_animchannel_setflag_types[] = {
- {ACHANNEL_SETFLAG_TOGGLE, "TOGGLE", 0, "Toggle", ""},
- {ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
- {ACHANNEL_SETFLAG_ADD, "ENABLE", 0, "Enable", ""},
- {ACHANNEL_SETFLAG_INVERT, "INVERT", 0, "Invert", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACHANNEL_SETFLAG_TOGGLE, "TOGGLE", 0, "Toggle", ""},
+ {ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
+ {ACHANNEL_SETFLAG_ADD, "ENABLE", 0, "Enable", ""},
+ {ACHANNEL_SETFLAG_INVERT, "INVERT", 0, "Invert", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* defines for set animation-channel settings */
// TODO: could add some more types, but those are really quite dependent on the mode...
static const EnumPropertyItem prop_animchannel_settings_types[] = {
- {ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
- {ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
+ {ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
+ {0, NULL, 0, NULL, NULL},
};
-
/* ------------------- */
/* Set/clear a particular flag (setting) for all selected + visible channels
@@ -1822,288 +1824,302 @@ static const EnumPropertyItem prop_animchannel_settings_types[] = {
* onlysel: only selected channels get the flag set
*/
// TODO: enable a setting which turns flushing on/off?
-static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode, bool onlysel, bool flush)
-{
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data that we need if flush is on */
- if (flush) {
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy visibility needs to be ignored so that settings can get flushed
- * "down" inside closed containers
- */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- ANIM_animdata_filter(ac, &all_data, filter, ac->data, ac->datatype);
- }
-
- /* filter data that we're working on
- * - hierarchy matters if we're doing this from the channels region
- * since we only want to apply this to channels we can "see",
- * and have these affect their relatives
- * - but for Graph Editor, this gets used also from main region
- * where hierarchy doesn't apply [#21276]
- */
- if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
- /* graph editor (case 2) */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- /* standard case */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- }
- if (onlysel) filter |= ANIMFILTER_SEL;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* if toggling, check if disable or enable */
- if (mode == ACHANNEL_SETFLAG_TOGGLE) {
- /* default to turn all on, unless we encounter one that's on... */
- mode = ACHANNEL_SETFLAG_ADD;
-
- /* see if we should turn off instead... */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* set the setting in the appropriate way (if available) */
- if (ANIM_channel_setting_get(ac, ale, setting) > 0) {
- mode = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- }
- }
-
- /* apply the setting */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* skip channel if setting is not available */
- if (ANIM_channel_setting_get(ac, ale, setting) == -1)
- continue;
-
- /* set the setting in the appropriate way */
- ANIM_channel_setting_set(ac, ale, setting, mode);
-
- /* if flush status... */
- if (flush)
- ANIM_flush_setting_anim_channels(ac, &all_data, ale, setting, mode);
- }
-
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
+static void setflag_anim_channels(bAnimContext *ac,
+ eAnimChannel_Settings setting,
+ eAnimChannels_SetFlag mode,
+ bool onlysel,
+ bool flush)
+{
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data that we need if flush is on */
+ if (flush) {
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy visibility needs to be ignored so that settings can get flushed
+ * "down" inside closed containers
+ */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
+ ANIM_animdata_filter(ac, &all_data, filter, ac->data, ac->datatype);
+ }
+
+ /* filter data that we're working on
+ * - hierarchy matters if we're doing this from the channels region
+ * since we only want to apply this to channels we can "see",
+ * and have these affect their relatives
+ * - but for Graph Editor, this gets used also from main region
+ * where hierarchy doesn't apply [#21276]
+ */
+ if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
+ /* graph editor (case 2) */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ /* standard case */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS |
+ ANIMFILTER_NODUPLIS);
+ }
+ if (onlysel)
+ filter |= ANIMFILTER_SEL;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* if toggling, check if disable or enable */
+ if (mode == ACHANNEL_SETFLAG_TOGGLE) {
+ /* default to turn all on, unless we encounter one that's on... */
+ mode = ACHANNEL_SETFLAG_ADD;
+
+ /* see if we should turn off instead... */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* set the setting in the appropriate way (if available) */
+ if (ANIM_channel_setting_get(ac, ale, setting) > 0) {
+ mode = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ }
+ }
+
+ /* apply the setting */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* skip channel if setting is not available */
+ if (ANIM_channel_setting_get(ac, ale, setting) == -1)
+ continue;
+
+ /* set the setting in the appropriate way */
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+
+ /* if flush status... */
+ if (flush)
+ ANIM_flush_setting_anim_channels(ac, &all_data, ale, setting, mode);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
}
/* ------------------- */
static int animchannels_setflag_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- eAnimChannel_Settings setting;
- eAnimChannels_SetFlag mode;
- bool flush = true;
+ bAnimContext ac;
+ eAnimChannel_Settings setting;
+ eAnimChannels_SetFlag mode;
+ bool flush = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
- mode = RNA_enum_get(op->ptr, "mode");
- setting = RNA_enum_get(op->ptr, "type");
+ /* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
+ mode = RNA_enum_get(op->ptr, "mode");
+ setting = RNA_enum_get(op->ptr, "type");
- /* check if setting is flushable */
- if (setting == ACHANNEL_SETTING_EXPAND)
- flush = false;
+ /* check if setting is flushable */
+ if (setting == ACHANNEL_SETTING_EXPAND)
+ flush = false;
- /* modify setting
- * - only selected channels are affected
- */
- setflag_anim_channels(&ac, setting, mode, true, flush);
+ /* modify setting
+ * - only selected channels are affected
+ */
+ setflag_anim_channels(&ac, setting, mode, true, flush);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Enable Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_enable";
- ot->description = "Enable specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Enable Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_enable";
+ ot->description = "Enable specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Disable Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_disable";
- ot->description = "Disable specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Disable Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_disable";
+ ot->description = "Disable specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Toggle Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_toggle";
- ot->description = "Toggle specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Toggle Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_toggle";
+ ot->description = "Toggle specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Toggle Channel Editability";
- ot->idname = "ANIM_OT_channels_editable_toggle";
- ot->description = "Toggle editability of selected channels";
+ /* identifiers */
+ ot->name = "Toggle Channel Editability";
+ ot->idname = "ANIM_OT_channels_editable_toggle";
+ ot->description = "Toggle editability of selected channels";
- /* api callbacks */
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
- /* setting to set */
- prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* props */
+ /* flag-setting mode */
+ RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ /* setting to set */
+ prop = RNA_def_enum(
+ ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
}
/* ********************** Expand Channels Operator *********************** */
static int animchannels_expand_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bool onlysel = true;
+ bAnimContext ac;
+ bool onlysel = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* only affect selected channels? */
- if (RNA_boolean_get(op->ptr, "all"))
- onlysel = false;
+ /* only affect selected channels? */
+ if (RNA_boolean_get(op->ptr, "all"))
+ onlysel = false;
- /* modify setting */
- setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel, false);
+ /* modify setting */
+ setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel, false);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_expand(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Expand Channels";
- ot->idname = "ANIM_OT_channels_expand";
- ot->description = "Expand (i.e. open) all selected expandable animation channels";
+ /* identifiers */
+ ot->name = "Expand Channels";
+ ot->idname = "ANIM_OT_channels_expand";
+ ot->description = "Expand (i.e. open) all selected expandable animation channels";
- /* api callbacks */
- ot->exec = animchannels_expand_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_expand_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
+ /* props */
+ ot->prop = RNA_def_boolean(
+ ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
}
/* ********************** Collapse Channels Operator *********************** */
static int animchannels_collapse_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bool onlysel = true;
+ bAnimContext ac;
+ bool onlysel = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* only affect selected channels? */
- if (RNA_boolean_get(op->ptr, "all"))
- onlysel = false;
+ /* only affect selected channels? */
+ if (RNA_boolean_get(op->ptr, "all"))
+ onlysel = false;
- /* modify setting */
- setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel, false);
+ /* modify setting */
+ setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel, false);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_collapse(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Collapse Channels";
- ot->idname = "ANIM_OT_channels_collapse";
- ot->description = "Collapse (i.e. close) all selected expandable animation channels";
+ /* identifiers */
+ ot->name = "Collapse Channels";
+ ot->idname = "ANIM_OT_channels_collapse";
+ ot->description = "Collapse (i.e. close) all selected expandable animation channels";
- /* api callbacks */
- ot->exec = animchannels_collapse_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_collapse_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
+ /* props */
+ ot->prop = RNA_def_boolean(
+ ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
}
/* ************ Remove All "Empty" AnimData Blocks Operator ********* */
@@ -2120,170 +2136,169 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
-
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get animdata blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- ID *id = ale->id;
- AnimData *adt = ale->data;
-
- bool action_empty = false;
- bool nla_empty = false;
- bool drivers_empty = false;
-
- /* sanity checks */
- BLI_assert((id != NULL) && (adt != NULL));
-
- /* check if this is "empty" and can be deleted */
- /* (For now, there are only these 3 criteria) */
-
- /* 1) Active Action is missing or empty */
- if (ELEM(NULL, adt->action, adt->action->curves.first)) {
- action_empty = true;
- }
- else {
- /* TODO: check for keyframe + fmodifier data on these too */
- }
-
- /* 2) No NLA Tracks and/or NLA Strips */
- if (adt->nla_tracks.first == NULL) {
- nla_empty = true;
- }
- else {
- NlaTrack *nlt;
-
- /* empty tracks? */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- if (nlt->strips.first) {
- /* stop searching, as we found one that actually had stuff we don't want lost
- * NOTE: nla_empty gets reset to false, as a previous track may have been empty
- */
- nla_empty = false;
- break;
- }
- else if (nlt->strips.first == NULL) {
- /* this track is empty, but another one may still have stuff in it, so can't break yet */
- nla_empty = true;
- }
- }
- }
-
- /* 3) Drivers */
- drivers_empty = (adt->drivers.first == NULL);
-
-
- /* remove AnimData? */
- if (action_empty && nla_empty && drivers_empty) {
- BKE_animdata_free(id, true);
- }
- }
-
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get animdata blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ID *id = ale->id;
+ AnimData *adt = ale->data;
+
+ bool action_empty = false;
+ bool nla_empty = false;
+ bool drivers_empty = false;
+
+ /* sanity checks */
+ BLI_assert((id != NULL) && (adt != NULL));
+
+ /* check if this is "empty" and can be deleted */
+ /* (For now, there are only these 3 criteria) */
+
+ /* 1) Active Action is missing or empty */
+ if (ELEM(NULL, adt->action, adt->action->curves.first)) {
+ action_empty = true;
+ }
+ else {
+ /* TODO: check for keyframe + fmodifier data on these too */
+ }
+
+ /* 2) No NLA Tracks and/or NLA Strips */
+ if (adt->nla_tracks.first == NULL) {
+ nla_empty = true;
+ }
+ else {
+ NlaTrack *nlt;
+
+ /* empty tracks? */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ if (nlt->strips.first) {
+ /* stop searching, as we found one that actually had stuff we don't want lost
+ * NOTE: nla_empty gets reset to false, as a previous track may have been empty
+ */
+ nla_empty = false;
+ break;
+ }
+ else if (nlt->strips.first == NULL) {
+ /* this track is empty, but another one may still have stuff in it, so can't break yet */
+ nla_empty = true;
+ }
+ }
+ }
+
+ /* 3) Drivers */
+ drivers_empty = (adt->drivers.first == NULL);
+
+ /* remove AnimData? */
+ if (action_empty && nla_empty && drivers_empty) {
+ BKE_animdata_free(id, true);
+ }
+ }
+
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Empty Animation Data";
- ot->idname = "ANIM_OT_channels_clean_empty";
- ot->description = "Delete all empty animation data containers from visible data-blocks";
+ /* identifiers */
+ ot->name = "Remove Empty Animation Data";
+ ot->idname = "ANIM_OT_channels_clean_empty";
+ ot->description = "Delete all empty animation data containers from visible data-blocks";
- /* api callbacks */
- ot->exec = animchannels_clean_empty_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_clean_empty_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************* Reenable Disabled Operator ******************* */
static bool animchannels_enable_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
- /* animation editor test - Action/Dopesheet/etc. and Graph only */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH) == 0)
- return 0;
+ /* animation editor test - Action/Dopesheet/etc. and Graph only */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH) == 0)
+ return 0;
- return 1;
+ return 1;
}
static int animchannels_enable_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through filtered data and clean curves */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
+ /* loop through filtered data and clean curves */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
- /* remove disabled flags from F-Curves */
- fcu->flag &= ~FCURVE_DISABLED;
+ /* remove disabled flags from F-Curves */
+ fcu->flag &= ~FCURVE_DISABLED;
- /* for drivers, let's do the same too */
- if (fcu->driver)
- fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
+ /* for drivers, let's do the same too */
+ if (fcu->driver)
+ fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
- /* tag everything for updates - in particular, this is needed to get drivers working again */
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ /* tag everything for updates - in particular, this is needed to get drivers working again */
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Revive Disabled F-Curves";
- ot->idname = "ANIM_OT_channels_fcurves_enable";
- ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
+ /* identifiers */
+ ot->name = "Revive Disabled F-Curves";
+ ot->idname = "ANIM_OT_channels_fcurves_enable";
+ ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
- /* api callbacks */
- ot->exec = animchannels_enable_exec;
- ot->poll = animchannels_enable_poll;
+ /* api callbacks */
+ ot->exec = animchannels_enable_exec;
+ ot->poll = animchannels_enable_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** Find / Set Filter Operator ******************** */
@@ -2291,253 +2306,256 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
/* XXX: make this generic? */
static bool animchannels_find_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- if (sa == NULL)
- return 0;
+ if (sa == NULL)
+ return 0;
- /* animation editor with dopesheet */
- return ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
+ /* animation editor with dopesheet */
+ return ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
}
/* find_invoke() - Get initial channels */
static int animchannels_find_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* set initial filter text, and enable filter */
- RNA_string_set(op->ptr, "query", ac.ads->searchstr);
+ /* set initial filter text, and enable filter */
+ RNA_string_set(op->ptr, "query", ac.ads->searchstr);
- /* defer to popup */
- return WM_operator_props_popup(C, op, evt);
+ /* defer to popup */
+ return WM_operator_props_popup(C, op, evt);
}
/* find_exec() - Called to set the value */
static int animchannels_find_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* update filter text */
- RNA_string_get(op->ptr, "query", ac.ads->searchstr);
+ /* update filter text */
+ RNA_string_get(op->ptr, "query", ac.ads->searchstr);
- /* redraw */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* redraw */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_find(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Find Channels";
- ot->idname = "ANIM_OT_channels_find";
- ot->description = "Filter the set of channels shown to only include those with matching names";
+ /* identifiers */
+ ot->name = "Find Channels";
+ ot->idname = "ANIM_OT_channels_find";
+ ot->description = "Filter the set of channels shown to only include those with matching names";
- /* callbacks */
- ot->invoke = animchannels_find_invoke;
- ot->exec = animchannels_find_exec;
- ot->poll = animchannels_find_poll;
+ /* callbacks */
+ ot->invoke = animchannels_find_invoke;
+ ot->exec = animchannels_find_exec;
+ ot->poll = animchannels_find_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- ot->prop = RNA_def_string(ot->srna, "query", "Query", sizeof(((bDopeSheet *)NULL)->searchstr), "", "Text to search for in channel names");
+ /* properties */
+ ot->prop = RNA_def_string(ot->srna,
+ "query",
+ "Query",
+ sizeof(((bDopeSheet *)NULL)->searchstr),
+ "",
+ "Text to search for in channel names");
}
/* ********************** Select All Operator *********************** */
static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* 'standard' behavior - check if selected, then apply relevant selection */
- const int action = RNA_enum_get(op->ptr, "action");
- switch (action) {
- case SEL_TOGGLE:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
- break;
- case SEL_SELECT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_ADD);
- break;
- case SEL_DESELECT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_CLEAR);
- break;
- case SEL_INVERT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* 'standard' behavior - check if selected, then apply relevant selection */
+ const int action = RNA_enum_get(op->ptr, "action");
+ switch (action) {
+ case SEL_TOGGLE:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
+ break;
+ case SEL_SELECT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_ADD);
+ break;
+ case SEL_DESELECT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ break;
+ case SEL_INVERT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "ANIM_OT_channels_select_all";
- ot->description = "Toggle selection of all animation channels";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "ANIM_OT_channels_select_all";
+ ot->description = "Toggle selection of all animation channels";
- /* api callbacks */
- ot->exec = animchannels_deselectall_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_deselectall_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_all(ot);
+ /* properties */
+ WM_operator_properties_select_all(ot);
}
/* ******************** Box Select Operator *********************** */
static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectmode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceNla *snla = (SpaceNla *)ac->sl;
- View2D *v2d = &ac->ar->v2d;
- rctf rectf;
- float ymin, ymax;
-
- /* set initial y extents */
- if (ac->datatype == ANIMCONT_NLA) {
- ymin = (float)(-NLACHANNEL_HEIGHT(snla));
- ymax = 0.0f;
- }
- else {
- ymin = 0.0f;
- ymax = (float)(-ACHANNEL_HEIGHT(ac));
- }
-
- /* convert border-region to view coordinates */
- UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax - 2, &rectf.xmax, &rectf.ymax);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop over data, doing box select */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ac->datatype == ANIMCONT_NLA)
- ymin = ymax - NLACHANNEL_STEP(snla);
- else
- ymin = ymax - ACHANNEL_STEP(ac);
-
- /* if channel is within border-select region, alter it */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- /* set selection flags only */
- ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_SELECT, selectmode);
-
- /* type specific actions */
- switch (ale->type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- select_pchan_for_action_group(ac, agrp, ale);
- /* always clear active flag after doing this */
- agrp->flag &= ~AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- /* for now, it's easier just to do this here manually, as defining a new type
- * currently adds complications when doing other stuff
- */
- ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
- break;
- }
- }
- }
-
- /* set minimum extent to be the maximum of the next channel */
- ymax = ymin;
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceNla *snla = (SpaceNla *)ac->sl;
+ View2D *v2d = &ac->ar->v2d;
+ rctf rectf;
+ float ymin, ymax;
+
+ /* set initial y extents */
+ if (ac->datatype == ANIMCONT_NLA) {
+ ymin = (float)(-NLACHANNEL_HEIGHT(snla));
+ ymax = 0.0f;
+ }
+ else {
+ ymin = 0.0f;
+ ymax = (float)(-ACHANNEL_HEIGHT(ac));
+ }
+
+ /* convert border-region to view coordinates */
+ UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin);
+ UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax - 2, &rectf.xmax, &rectf.ymax);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop over data, doing box select */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ac->datatype == ANIMCONT_NLA)
+ ymin = ymax - NLACHANNEL_STEP(snla);
+ else
+ ymin = ymax - ACHANNEL_STEP(ac);
+
+ /* if channel is within border-select region, alter it */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ /* set selection flags only */
+ ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_SELECT, selectmode);
+
+ /* type specific actions */
+ switch (ale->type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ select_pchan_for_action_group(ac, agrp, ale);
+ /* always clear active flag after doing this */
+ agrp->flag &= ~AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ /* for now, it's easier just to do this here manually, as defining a new type
+ * currently adds complications when doing other stuff
+ */
+ ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
+ break;
+ }
+ }
+ }
+
+ /* set minimum extent to be the maximum of the next channel */
+ ymax = ymin;
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int animchannels_box_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- rcti rect;
- short selectmode = 0;
- const bool select = !RNA_boolean_get(op->ptr, "deselect");
- const bool extend = RNA_boolean_get(op->ptr, "extend");
+ bAnimContext ac;
+ rcti rect;
+ short selectmode = 0;
+ const bool select = !RNA_boolean_get(op->ptr, "deselect");
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get settings from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
+ /* get settings from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
- if (!extend) {
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_CLEAR);
- }
+ if (!extend) {
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_CLEAR);
+ }
- if (select) {
- selectmode = ACHANNEL_SETFLAG_ADD;
- }
- else {
- selectmode = ACHANNEL_SETFLAG_CLEAR;
- }
+ if (select) {
+ selectmode = ACHANNEL_SETFLAG_ADD;
+ }
+ else {
+ selectmode = ACHANNEL_SETFLAG_CLEAR;
+ }
- /* apply box_select animation channels */
- box_select_anim_channels(&ac, &rect, selectmode);
+ /* apply box_select animation channels */
+ box_select_anim_channels(&ac, &rect, selectmode);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->idname = "ANIM_OT_channels_select_box";
- ot->description = "Select all animation channels within the specified region";
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->idname = "ANIM_OT_channels_select_box";
+ ot->description = "Select all animation channels within the specified region";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = animchannels_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = animchannels_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* rna */
- WM_operator_properties_gesture_box_select(ot);
+ /* rna */
+ WM_operator_properties_gesture_box_select(ot);
}
/* ******************* Rename Operator ***************************** */
@@ -2545,114 +2563,131 @@ static void ANIM_OT_channels_select_box(wmOperatorType *ot)
static bool rename_anim_channels(bAnimContext *ac, int channel_index)
{
- ListBase anim_data = {NULL, NULL};
- const bAnimChannelType *acf;
- bAnimListElem *ale;
- int filter;
- bool success = false;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return false;
- }
-
- /* check that channel can be renamed */
- acf = ANIM_channel_get_typeinfo(ale);
- if (acf && acf->name_prop) {
- PointerRNA ptr;
- PropertyRNA *prop;
-
- /* ok if we can get name property to edit from this channel */
- if (acf->name_prop(ale, &ptr, &prop)) {
- /* actually showing the rename textfield is done on redraw,
- * so here we just store the index of this channel in the
- * dopesheet data, which will get utilized when drawing the
- * channel...
- *
- * +1 factor is for backwards compat issues
- */
- if (ac->ads) {
- ac->ads->renameIndex = channel_index + 1;
- success = true;
- }
- }
- }
-
- /* free temp data and tag for refresh */
- ANIM_animdata_freelist(&anim_data);
- ED_region_tag_redraw(ac->ar);
- return success;
+ ListBase anim_data = {NULL, NULL};
+ const bAnimChannelType *acf;
+ bAnimListElem *ale;
+ int filter;
+ bool success = false;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return false;
+ }
+
+ /* check that channel can be renamed */
+ acf = ANIM_channel_get_typeinfo(ale);
+ if (acf && acf->name_prop) {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* ok if we can get name property to edit from this channel */
+ if (acf->name_prop(ale, &ptr, &prop)) {
+ /* actually showing the rename textfield is done on redraw,
+ * so here we just store the index of this channel in the
+ * dopesheet data, which will get utilized when drawing the
+ * channel...
+ *
+ * +1 factor is for backwards compat issues
+ */
+ if (ac->ads) {
+ ac->ads->renameIndex = channel_index + 1;
+ success = true;
+ }
+ }
+ }
+
+ /* free temp data and tag for refresh */
+ ANIM_animdata_freelist(&anim_data);
+ ED_region_tag_redraw(ac->ar);
+ return success;
}
static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
{
- ARegion *ar;
- View2D *v2d;
- int channel_index;
- float x, y;
-
- /* get useful pointers from animation context data */
- ar = ac->ar;
- v2d = &ar->v2d;
-
- /* figure out which channel user clicked in
- * Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
- * so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
- * ACHANNEL_HEIGHT_HALF.
- */
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
-
- if (ac->datatype == ANIMCONT_NLA) {
- SpaceNla *snla = (SpaceNla *)ac->sl;
- UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
- }
- else {
- UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index);
- }
-
- return channel_index;
+ ARegion *ar;
+ View2D *v2d;
+ int channel_index;
+ float x, y;
+
+ /* get useful pointers from animation context data */
+ ar = ac->ar;
+ v2d = &ar->v2d;
+
+ /* figure out which channel user clicked in
+ * Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
+ * so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
+ * ACHANNEL_HEIGHT_HALF.
+ */
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
+
+ if (ac->datatype == ANIMCONT_NLA) {
+ SpaceNla *snla = (SpaceNla *)ac->sl;
+ UI_view2d_listview_view_to_cell(v2d,
+ NLACHANNEL_NAMEWIDTH,
+ NLACHANNEL_STEP(snla),
+ 0,
+ (float)NLACHANNEL_HEIGHT_HALF(snla),
+ x,
+ y,
+ NULL,
+ &channel_index);
+ }
+ else {
+ UI_view2d_listview_view_to_cell(v2d,
+ ACHANNEL_NAMEWIDTH,
+ ACHANNEL_STEP(ac),
+ 0,
+ (float)ACHANNEL_HEIGHT_HALF(ac),
+ x,
+ y,
+ NULL,
+ &channel_index);
+ }
+
+ return channel_index;
}
static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- bAnimContext ac;
- int channel_index;
+ bAnimContext ac;
+ int channel_index;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- channel_index = animchannels_channel_get(&ac, event->mval);
+ channel_index = animchannels_channel_get(&ac, event->mval);
- /* handle click */
- if (rename_anim_channels(&ac, channel_index))
- return OPERATOR_FINISHED;
- else
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
+ /* handle click */
+ if (rename_anim_channels(&ac, channel_index))
+ return OPERATOR_FINISHED;
+ else
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channels_rename(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Rename Channels";
- ot->idname = "ANIM_OT_channels_rename";
- ot->description = "Rename animation channel under mouse";
+ /* identifiers */
+ ot->name = "Rename Channels";
+ ot->idname = "ANIM_OT_channels_rename";
+ ot->description = "Rename animation channel under mouse";
- /* api callbacks */
- ot->invoke = animchannels_rename_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_rename_invoke;
+ ot->poll = animedit_poll_channels_active;
}
/* ******************** Mouse-Click Operator *********************** */
@@ -2660,357 +2695,355 @@ static void ANIM_OT_channels_rename(wmOperatorType *ot)
static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, short selectmode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- int notifierFlags = 0;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return 0;
- }
-
- /* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
- /* TODO: should this feature be extended to work with other channel types too? */
- if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
- /* normal channels should not behave normally in this case */
- ANIM_animdata_freelist(&anim_data);
- return 0;
- }
-
- /* action to take depends on what channel we've got */
- /* WARNING: must keep this in sync with the equivalent function in nla_channels.c */
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- {
- Scene *sce = (Scene *)ale->data;
- AnimData *adt = sce->adt;
-
- /* set selection status */
- if (selectmode == SELECT_INVERT) {
- /* swap select */
- sce->flag ^= SCE_DS_SELECTED;
- if (adt) adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- sce->flag |= SCE_DS_SELECTED;
- if (adt) adt->flag |= ADT_UI_SELECTED;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_OBJECT:
- {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ int notifierFlags = 0;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return 0;
+ }
+
+ /* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
+ /* TODO: should this feature be extended to work with other channel types too? */
+ if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
+ /* normal channels should not behave normally in this case */
+ ANIM_animdata_freelist(&anim_data);
+ return 0;
+ }
+
+ /* action to take depends on what channel we've got */
+ /* WARNING: must keep this in sync with the equivalent function in nla_channels.c */
+ switch (ale->type) {
+ case ANIMTYPE_SCENE: {
+ Scene *sce = (Scene *)ale->data;
+ AnimData *adt = sce->adt;
+
+ /* set selection status */
+ if (selectmode == SELECT_INVERT) {
+ /* swap select */
+ sce->flag ^= SCE_DS_SELECTED;
+ if (adt)
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ sce->flag |= SCE_DS_SELECTED;
+ if (adt)
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_OBJECT: {
#if 0
- bDopeSheet *ads = (bDopeSheet *)ac->data;
- Scene *sce = (Scene *)ads->source;
+ bDopeSheet *ads = (bDopeSheet *)ac->data;
+ Scene *sce = (Scene *)ads->source;
#endif
- ViewLayer *view_layer = ac->view_layer;
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
- AnimData *adt = ob->adt;
-
- /* set selection status */
- if (base->flag & BASE_SELECTABLE) {
- if (selectmode == SELECT_INVERT) {
- /* swap select */
- ED_object_base_select(base, BA_INVERT);
- BKE_scene_object_base_flag_sync_from_base(base);
-
- if (adt) adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- Base *b;
-
- /* deselect all */
- /* TODO: should this deselect all other types of channels too? */
- for (b = view_layer->object_bases.first; b; b = b->next) {
- ED_object_base_select(b, BA_DESELECT);
- BKE_scene_object_base_flag_sync_from_base(b);
- if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
- }
-
- /* select object now */
- ED_object_base_select(base, BA_SELECT);
- BKE_scene_object_base_flag_sync_from_base(base);
- if (adt) adt->flag |= ADT_UI_SELECTED;
- }
-
- /* change active object - regardless of whether it is now selected [T37883] */
- ED_object_base_activate(C, base); /* adds notifier */
-
- if ((adt) && (adt->flag & ADT_UI_SELECTED))
- adt->flag |= ADT_UI_ACTIVE;
-
- /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
- if (ob != CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- }
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* sanity checking... */
- if (ale->adt) {
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this AnimData block only */
- ale->adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- /* select AnimData block by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- ale->adt->flag |= ADT_UI_SELECTED;
- }
-
- /* set active? */
- if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
- ale->adt->flag |= ADT_UI_ACTIVE;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
-
- Object *ob = NULL;
- bPoseChannel *pchan = NULL;
-
-
- /* Armatures-Specific Feature:
- * Since groups are used to collect F-Curves of the same Bone by default
- * (via Keying Sets) so that they can be managed better, we try to make
- * things here easier for animators by mapping group selection to bone
- * selection.
- *
- * Only do this if "Only Selected" dopesheet filter is not active, or else it
- * becomes too unpredictable/tricky to manage
- */
- if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
- if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
- ob = (Object *)ale->id;
-
- if (ob->type == OB_ARMATURE) {
- /* Assume for now that any group with corresponding name is what we want
- * (i.e. for an armature whose location is animated, things would break
- * if the user were to add a bone named "Location").
- *
- * TODO: check the first F-Curve or so to be sure...
- */
- pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- }
- }
- }
-
- /* select/deselect group */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this group only */
- agrp->flag ^= AGRP_SELECTED;
- }
- else if (selectmode == -1) {
- /* select all in group (and deselect everything else) */
- FCurve *fcu;
-
- /* deselect all other channels */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
- /* only select channels in group and group itself */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next)
- fcu->flag |= FCURVE_SELECTED;
- agrp->flag |= AGRP_SELECTED;
- }
- else {
- /* select group by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
- agrp->flag |= AGRP_SELECTED;
- }
-
- /* if group is selected now, make group the 'active' one in the visible list */
- if (agrp->flag & AGRP_SELECTED) {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
- if (pchan) ED_pose_bone_select(ob, pchan, true);
- }
- else {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP);
- if (pchan) ED_pose_bone_select(ob, pchan, false);
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this F-Curve only */
- fcu->flag ^= FCURVE_SELECTED;
- }
- else {
- /* select F-Curve by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- fcu->flag |= FCURVE_SELECTED;
- }
-
- /* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
- if (fcu->flag & FCURVE_SELECTED)
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_SHAPEKEY:
- {
- KeyBlock *kb = (KeyBlock *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this ShapeKey only */
- kb->flag ^= KEYBLOCK_SEL;
- }
- else {
- /* select ShapeKey by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- kb->flag |= KEYBLOCK_SEL;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_NLACONTROLS:
- {
- AnimData *adt = (AnimData *)ale->data;
-
- /* toggle expand
- * - Although the triangle widget already allows this, since there's nothing else that can be done here now,
- * let's just use it for easier expand/collapse for now
- */
- adt->flag ^= ADT_NLA_SKEYS_COLLAPSED;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_GPDATABLOCK:
- {
- bGPdata *gpd = (bGPdata *)ale->data;
-
- /* toggle expand
- * - although the triangle widget already allows this, the whole channel can also be used for this purpose
- */
- gpd->flag ^= GP_DATA_EXPAND;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* invert selection status of this layer only */
- gpl->flag ^= GP_LAYER_SELECT;
- }
- else {
- /* select layer by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- gpl->flag |= GP_LAYER_SELECT;
- }
-
- /* change active layer, if this is selected (since we must always have an active layer) */
- if (gpl->flag & GP_LAYER_SELECT) {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
- /* update other layer status */
- BKE_gpencil_layer_setactive(gpd, gpl);
- }
-
- /* Grease Pencil updates */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
- break;
- }
- case ANIMTYPE_MASKDATABLOCK:
- {
- Mask *mask = (Mask *)ale->data;
-
- /* toggle expand
- * - although the triangle widget already allows this, the whole channel can also be used for this purpose
- */
- mask->flag ^= MASK_ANIMF_EXPAND;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* invert selection status of this layer only */
- masklay->flag ^= MASK_LAYERFLAG_SELECT;
- }
- else {
- /* select layer by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- masklay->flag |= MASK_LAYERFLAG_SELECT;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- default:
- if (G.debug & G_DEBUG)
- printf("Error: Invalid channel type in mouse_anim_channels()\n");
- break;
- }
-
- /* free channels */
- ANIM_animdata_freelist(&anim_data);
-
- /* return notifier flags */
- return notifierFlags;
+ ViewLayer *view_layer = ac->view_layer;
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
+ AnimData *adt = ob->adt;
+
+ /* set selection status */
+ if (base->flag & BASE_SELECTABLE) {
+ if (selectmode == SELECT_INVERT) {
+ /* swap select */
+ ED_object_base_select(base, BA_INVERT);
+ BKE_scene_object_base_flag_sync_from_base(base);
+
+ if (adt)
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ Base *b;
+
+ /* deselect all */
+ /* TODO: should this deselect all other types of channels too? */
+ for (b = view_layer->object_bases.first; b; b = b->next) {
+ ED_object_base_select(b, BA_DESELECT);
+ BKE_scene_object_base_flag_sync_from_base(b);
+ if (b->object->adt)
+ b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
+ }
+
+ /* select object now */
+ ED_object_base_select(base, BA_SELECT);
+ BKE_scene_object_base_flag_sync_from_base(base);
+ if (adt)
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* change active object - regardless of whether it is now selected [T37883] */
+ ED_object_base_activate(C, base); /* adds notifier */
+
+ if ((adt) && (adt->flag & ADT_UI_SELECTED))
+ adt->flag |= ADT_UI_ACTIVE;
+
+ /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
+ if (ob != CTX_data_edit_object(C)) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ }
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* sanity checking... */
+ if (ale->adt) {
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ ale->adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ ale->adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+
+ Object *ob = NULL;
+ bPoseChannel *pchan = NULL;
+
+ /* Armatures-Specific Feature:
+ * Since groups are used to collect F-Curves of the same Bone by default
+ * (via Keying Sets) so that they can be managed better, we try to make
+ * things here easier for animators by mapping group selection to bone
+ * selection.
+ *
+ * Only do this if "Only Selected" dopesheet filter is not active, or else it
+ * becomes too unpredictable/tricky to manage
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ ob = (Object *)ale->id;
+
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ }
+ }
+ }
+
+ /* select/deselect group */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this group only */
+ agrp->flag ^= AGRP_SELECTED;
+ }
+ else if (selectmode == -1) {
+ /* select all in group (and deselect everything else) */
+ FCurve *fcu;
+
+ /* deselect all other channels */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ if (pchan)
+ ED_pose_deselect_all(ob, SEL_DESELECT, false);
+
+ /* only select channels in group and group itself */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next)
+ fcu->flag |= FCURVE_SELECTED;
+ agrp->flag |= AGRP_SELECTED;
+ }
+ else {
+ /* select group by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ if (pchan)
+ ED_pose_deselect_all(ob, SEL_DESELECT, false);
+
+ agrp->flag |= AGRP_SELECTED;
+ }
+
+ /* if group is selected now, make group the 'active' one in the visible list */
+ if (agrp->flag & AGRP_SELECTED) {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ if (pchan)
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP);
+ if (pchan)
+ ED_pose_bone_select(ob, pchan, false);
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this F-Curve only */
+ fcu->flag ^= FCURVE_SELECTED;
+ }
+ else {
+ /* select F-Curve by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ fcu->flag |= FCURVE_SELECTED;
+ }
+
+ /* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
+ if (fcu->flag & FCURVE_SELECTED)
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_SHAPEKEY: {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this ShapeKey only */
+ kb->flag ^= KEYBLOCK_SEL;
+ }
+ else {
+ /* select ShapeKey by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ kb->flag |= KEYBLOCK_SEL;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_NLACONTROLS: {
+ AnimData *adt = (AnimData *)ale->data;
+
+ /* toggle expand
+ * - Although the triangle widget already allows this, since there's nothing else that can be done here now,
+ * let's just use it for easier expand/collapse for now
+ */
+ adt->flag ^= ADT_NLA_SKEYS_COLLAPSED;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_GPDATABLOCK: {
+ bGPdata *gpd = (bGPdata *)ale->data;
+
+ /* toggle expand
+ * - although the triangle widget already allows this, the whole channel can also be used for this purpose
+ */
+ gpd->flag ^= GP_DATA_EXPAND;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* invert selection status of this layer only */
+ gpl->flag ^= GP_LAYER_SELECT;
+ }
+ else {
+ /* select layer by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ gpl->flag |= GP_LAYER_SELECT;
+ }
+
+ /* change active layer, if this is selected (since we must always have an active layer) */
+ if (gpl->flag & GP_LAYER_SELECT) {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
+ /* update other layer status */
+ BKE_gpencil_layer_setactive(gpd, gpl);
+ }
+
+ /* Grease Pencil updates */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
+ break;
+ }
+ case ANIMTYPE_MASKDATABLOCK: {
+ Mask *mask = (Mask *)ale->data;
+
+ /* toggle expand
+ * - although the triangle widget already allows this, the whole channel can also be used for this purpose
+ */
+ mask->flag ^= MASK_ANIMF_EXPAND;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* invert selection status of this layer only */
+ masklay->flag ^= MASK_LAYERFLAG_SELECT;
+ }
+ else {
+ /* select layer by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ masklay->flag |= MASK_LAYERFLAG_SELECT;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ default:
+ if (G.debug & G_DEBUG)
+ printf("Error: Invalid channel type in mouse_anim_channels()\n");
+ break;
+ }
+
+ /* free channels */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* return notifier flags */
+ return notifierFlags;
}
/* ------------------- */
@@ -3018,177 +3051,188 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
/* handle clicking */
static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- ARegion *ar;
- View2D *v2d;
- int channel_index;
- int notifierFlags = 0;
- short selectmode;
- float x, y;
-
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get useful pointers from animation context data */
- ar = ac.ar;
- v2d = &ar->v2d;
-
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend")) {
- selectmode = SELECT_INVERT;
- }
- else if (RNA_boolean_get(op->ptr, "children_only")) {
- /* this is a bit of a special case for ActionGroups only...
- * should it be removed or extended to all instead? */
- selectmode = -1;
- }
- else {
- selectmode = SELECT_REPLACE;
- }
-
- /* figure out which channel user clicked in
- *
- * Note:
- * although channels technically start at (y = ACHANNEL_FIRST),
- * we need to adjust by half a channel's height so that the tops of channels get caught ok.
- * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF.
- */
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
- UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(&ac), 0, (float)ACHANNEL_HEIGHT_HALF(&ac), x, y, NULL, &channel_index);
-
- /* handle mouse-click in the relevant channel then */
- notifierFlags = mouse_anim_channels(C, &ac, channel_index, selectmode);
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ARegion *ar;
+ View2D *v2d;
+ int channel_index;
+ int notifierFlags = 0;
+ short selectmode;
+ float x, y;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get useful pointers from animation context data */
+ ar = ac.ar;
+ v2d = &ar->v2d;
+
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend")) {
+ selectmode = SELECT_INVERT;
+ }
+ else if (RNA_boolean_get(op->ptr, "children_only")) {
+ /* this is a bit of a special case for ActionGroups only...
+ * should it be removed or extended to all instead? */
+ selectmode = -1;
+ }
+ else {
+ selectmode = SELECT_REPLACE;
+ }
+
+ /* figure out which channel user clicked in
+ *
+ * Note:
+ * although channels technically start at (y = ACHANNEL_FIRST),
+ * we need to adjust by half a channel's height so that the tops of channels get caught ok.
+ * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF.
+ */
+ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
+ UI_view2d_listview_view_to_cell(v2d,
+ ACHANNEL_NAMEWIDTH,
+ ACHANNEL_STEP(&ac),
+ 0,
+ (float)ACHANNEL_HEIGHT_HALF(&ac),
+ x,
+ y,
+ NULL,
+ &channel_index);
+
+ /* handle mouse-click in the relevant channel then */
+ notifierFlags = mouse_anim_channels(C, &ac, channel_index, selectmode);
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_click(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Mouse Click on Channels";
- ot->idname = "ANIM_OT_channels_click";
- ot->description = "Handle mouse-clicks over animation channels";
+ /* identifiers */
+ ot->name = "Mouse Click on Channels";
+ ot->idname = "ANIM_OT_channels_click";
+ ot->description = "Handle mouse-clicks over animation channels";
- /* api callbacks */
- ot->invoke = animchannels_mouseclick_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_mouseclick_invoke;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "children_only", false, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "children_only", false, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static bool select_anim_channel_keys(bAnimContext *ac, int channel_index, bool extend)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool success = false;
- FCurve *fcu;
- int i;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return false;
- }
-
- fcu = (FCurve *)ale->key_data;
- success = (fcu != NULL);
-
- ANIM_animdata_freelist(&anim_data);
-
- /* F-Curve may not have any keyframes */
- if (fcu && fcu->bezt) {
- BezTriple *bezt;
-
- if (!extend) {
- filter = (ANIMFILTER_DATA_VISIBLE);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu_inner = (FCurve *)ale->key_data;
-
- if (fcu_inner != NULL && fcu_inner->bezt != NULL) {
- for (i = 0, bezt = fcu_inner->bezt; i < fcu_inner->totvert; i++, bezt++) {
- bezt->f2 = bezt->f1 = bezt->f3 = 0;
- }
- }
- }
-
- ANIM_animdata_freelist(&anim_data);
- }
-
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- bezt->f2 = bezt->f1 = bezt->f3 = SELECT;
- }
- }
-
- /* free temp data and tag for refresh */
- ED_region_tag_redraw(ac->ar);
- return success;
-}
-
-static int animchannels_channel_select_keys_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- bAnimContext ac;
- int channel_index;
- bool extend = RNA_boolean_get(op->ptr, "extend");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- channel_index = animchannels_channel_get(&ac, event->mval);
-
- /* handle click */
- if (select_anim_channel_keys(&ac, channel_index, extend)) {
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
- }
- else
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool success = false;
+ FCurve *fcu;
+ int i;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return false;
+ }
+
+ fcu = (FCurve *)ale->key_data;
+ success = (fcu != NULL);
+
+ ANIM_animdata_freelist(&anim_data);
+
+ /* F-Curve may not have any keyframes */
+ if (fcu && fcu->bezt) {
+ BezTriple *bezt;
+
+ if (!extend) {
+ filter = (ANIMFILTER_DATA_VISIBLE);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu_inner = (FCurve *)ale->key_data;
+
+ if (fcu_inner != NULL && fcu_inner->bezt != NULL) {
+ for (i = 0, bezt = fcu_inner->bezt; i < fcu_inner->totvert; i++, bezt++) {
+ bezt->f2 = bezt->f1 = bezt->f3 = 0;
+ }
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ bezt->f2 = bezt->f1 = bezt->f3 = SELECT;
+ }
+ }
+
+ /* free temp data and tag for refresh */
+ ED_region_tag_redraw(ac->ar);
+ return success;
+}
+
+static int animchannels_channel_select_keys_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
+{
+ bAnimContext ac;
+ int channel_index;
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ channel_index = animchannels_channel_get(&ac, event->mval);
+
+ /* handle click */
+ if (select_anim_channel_keys(&ac, channel_index, extend)) {
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ else
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Channel keyframes";
- ot->idname = "ANIM_OT_channel_select_keys";
- ot->description = "Select all keyframes of channel under mouse";
+ /* identifiers */
+ ot->name = "Select Channel keyframes";
+ ot->idname = "ANIM_OT_channel_select_keys";
+ ot->description = "Select all keyframes of channel under mouse";
- /* api callbacks */
- ot->invoke = animchannels_channel_select_keys_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_channel_select_keys_invoke;
+ ot->poll = animedit_poll_channels_active;
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************************************** */
@@ -3196,41 +3240,41 @@ static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
void ED_operatortypes_animchannels(void)
{
- WM_operatortype_append(ANIM_OT_channels_select_all);
- WM_operatortype_append(ANIM_OT_channels_select_box);
+ WM_operatortype_append(ANIM_OT_channels_select_all);
+ WM_operatortype_append(ANIM_OT_channels_select_box);
- WM_operatortype_append(ANIM_OT_channels_click);
- WM_operatortype_append(ANIM_OT_channel_select_keys);
- WM_operatortype_append(ANIM_OT_channels_rename);
+ WM_operatortype_append(ANIM_OT_channels_click);
+ WM_operatortype_append(ANIM_OT_channel_select_keys);
+ WM_operatortype_append(ANIM_OT_channels_rename);
- WM_operatortype_append(ANIM_OT_channels_find);
+ WM_operatortype_append(ANIM_OT_channels_find);
- WM_operatortype_append(ANIM_OT_channels_setting_enable);
- WM_operatortype_append(ANIM_OT_channels_setting_disable);
- WM_operatortype_append(ANIM_OT_channels_setting_toggle);
+ WM_operatortype_append(ANIM_OT_channels_setting_enable);
+ WM_operatortype_append(ANIM_OT_channels_setting_disable);
+ WM_operatortype_append(ANIM_OT_channels_setting_toggle);
- WM_operatortype_append(ANIM_OT_channels_delete);
+ WM_operatortype_append(ANIM_OT_channels_delete);
- /* XXX does this need to be a separate operator? */
- WM_operatortype_append(ANIM_OT_channels_editable_toggle);
+ /* XXX does this need to be a separate operator? */
+ WM_operatortype_append(ANIM_OT_channels_editable_toggle);
- WM_operatortype_append(ANIM_OT_channels_move);
+ WM_operatortype_append(ANIM_OT_channels_move);
- WM_operatortype_append(ANIM_OT_channels_expand);
- WM_operatortype_append(ANIM_OT_channels_collapse);
+ WM_operatortype_append(ANIM_OT_channels_expand);
+ WM_operatortype_append(ANIM_OT_channels_collapse);
- WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
+ WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
- WM_operatortype_append(ANIM_OT_channels_clean_empty);
+ WM_operatortype_append(ANIM_OT_channels_clean_empty);
- WM_operatortype_append(ANIM_OT_channels_group);
- WM_operatortype_append(ANIM_OT_channels_ungroup);
+ WM_operatortype_append(ANIM_OT_channels_group);
+ WM_operatortype_append(ANIM_OT_channels_ungroup);
}
// TODO: check on a poll callback for this, to get hotkeys into menus
void ED_keymap_animchannels(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "Animation Channels", 0, 0);
+ WM_keymap_ensure(keyconf, "Animation Channels", 0, 0);
}
/* ************************************************************************** */