diff options
author | Joshua Leung <aligorith@gmail.com> | 2013-03-16 09:09:32 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2013-03-16 09:09:32 +0400 |
commit | 150891605f3f098070b2bb0cd6ef37ae930698d7 (patch) | |
tree | 2e2b96e670d84f60b97161b3eb5599e6127444a3 /source | |
parent | 7fc79615e0c88aff445178f17e9c267f11a0d791 (diff) |
NLA "Add Track" can now be used to add tracks to previously empty AnimData
blocks, provided the blocks in question are in fact selected.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 8 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 5 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_channels.c | 93 |
3 files changed, 86 insertions, 20 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index b3b0b09bac0..7416c559522 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1296,7 +1296,9 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope ANIMDATA_FILTER_CASES(iat, { /* AnimData */ /* specifically filter animdata block */ - ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id); + if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) { + ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id); + } }, { /* NLA */ items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id); @@ -1346,7 +1348,9 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke // TODO: somehow manage to pass dopesheet info down here too? if (key->adt) { if (filter_mode & ANIMFILTER_ANIMDATA) { - ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key); + if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) { + ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key); + } } else if (key->adt->action) { items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key); diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 20f568a3642..954ea18e0ab 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -292,11 +292,14 @@ typedef enum eAnimFilter_Flags { #define SEL_MASKLAY(masklay) (masklay->flag & SELECT) - /* NLA only */ #define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED) #define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0) + +/* AnimData - NLA mostly... */ +#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED) + /* -------------- Channel Defines -------------- */ /* channel heights */ diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index f9732a79a11..a4b036bf00f 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -48,6 +48,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_screen.h" +#include "BKE_report.h" #include "ED_anim_api.h" #include "ED_keyframes_edit.h" @@ -393,24 +394,18 @@ void NLA_OT_channels_click(wmOperatorType *ot) /* ******************** Add Tracks Operator ***************************** */ /* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */ -static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op) +/* helper - add NLA Tracks alongside existing ones */ +static bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel) { - bAnimContext ac; - ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; - AnimData *lastAdt = NULL; - short above_sel = RNA_boolean_get(op->ptr, "above_selected"); + bool added = false; - /* get editor data */ - if (ANIM_animdata_get_context(C, &ac) == 0) - return OPERATOR_CANCELLED; - - /* get a list of the AnimData blocks being shown in the NLA */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + /* get a list of the (selected) NLA Tracks being shown in the NLA */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* add tracks... */ for (ale = anim_data.first; ale; ale = ale->next) { @@ -424,11 +419,13 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op) if (above_sel) { /* just add a new one above this one */ add_nlatrack(adt, nlt); + added = true; } else if ((lastAdt == NULL) || (adt != lastAdt)) { /* add one track to the top of the owning AnimData's stack, then don't add anymore to this stack */ add_nlatrack(adt, NULL); lastAdt = adt; + added = true; } } } @@ -436,17 +433,79 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op) /* free temp data */ BLI_freelistN(&anim_data); - /* set notifier that things have changed */ - WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); + return added; +} + +/* helper - add NLA Tracks to empty (and selected) AnimData blocks */ +static bool nlaedit_add_tracks_empty(bAnimContext *ac) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + bool added = false; - /* done */ - return OPERATOR_FINISHED; + /* get a list of the selected AnimData blocks in the NLA */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* check if selected AnimData blocks are empty, and add tracks if so... */ + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ale->adt; + + /* sanity check */ + BLI_assert(adt->flag & ADT_UI_SELECTED); + + /* ensure it is empty */ + if (adt->nla_tracks.first == NULL) { + /* add new track to this AnimData block then */ + add_nlatrack(adt, NULL); + added = true; + } + } + + /* cleanup */ + BLI_freelistN(&anim_data); + + return added; +} + +/* Add Tracks exec() */ +static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + bool above_sel = RNA_boolean_get(op->ptr, "above_selected"); + bool op_done = false; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* perform adding in two passes - existing first so that we don't double up for empty */ + op_done |= nlaedit_add_tracks_existing(&ac, above_sel); + op_done |= nlaedit_add_tracks_empty(&ac); + + /* done? */ + if (op_done) { + /* set notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); + + /* done */ + return OPERATOR_FINISHED; + } + else { + /* failed to add any tracks */ + BKE_report(op->reports, RPT_WARNING, + "Select an existing NLA Track or an empty action line first"); + + /* not done */ + return OPERATOR_CANCELLED; + } } void NLA_OT_tracks_add(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Track(s)"; + ot->name = "Add Tracks"; ot->idname = "NLA_OT_tracks_add"; ot->description = "Add NLA-Tracks above/after the selected tracks"; |