diff options
author | Joshua Leung <aligorith@gmail.com> | 2011-01-19 02:38:36 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2011-01-19 02:38:36 +0300 |
commit | dddb9aa30f96961023f02846c97c955e1f2b5f0c (patch) | |
tree | 60bab060fefd0d7b9eeb5befa985fd6893b21b5a /source/blender/editors/space_nla/nla_edit.c | |
parent | 11f8b5fceb45b6e7a04686fa6f9ed255c83b58a4 (diff) |
NLA Editor: Swap Strips (Alt-F) and Bugfixes
1) Added a new operator to swap the order of strips within a track
(Alt-F).
This makes it possible to select two strips (or more precisely, two
islands of consecutive + selected strips) in a single track and change
the order in which the appear without needing a extra tracks to
perform the move through.
As usual, the non-overlapping rules apply, so there may be some cases
where swapping in this way is not possible without adjusting the
intermediate strips first manually. Otherwise, everything just gets
too tricky to manage deciding what adjustments should be done to the
obstructing strips to make a fit.
2) Freeing meta-strips didn't free their local data properly (i.e.
modifiers they may have had).
3) Adding strips to tracks, where the endframes for the strips
overlapped would cause problems with incorrect ordering of strips. I
still need to double-check whether evaluation works ok in this case...
Diffstat (limited to 'source/blender/editors/space_nla/nla_edit.c')
-rw-r--r-- | source/blender/editors/space_nla/nla_edit.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index d1417d69ae3..921660b0b8b 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1006,6 +1006,164 @@ void NLA_OT_mute_toggle (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ******************** Swap Strips Operator ************************** */ +/* Tries to exchange strips within their owner tracks */ + +static int nlaedit_swap_exec (bContext *C, wmOperator *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 a list of the editable tracks being shown in the NLA */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* consider each track in turn */ + for (ale= anim_data.first; ale; ale= ale->next) { + NlaTrack *nlt= (NlaTrack *)ale->data; + + NlaStrip *strip, *stripN=NULL; + NlaStrip *sa=NULL, *sb=NULL; + + /* make temporary metastrips so that entire islands of selections can be moved around */ + BKE_nlastrips_make_metas(&nlt->strips, 1); + + /* special case: if there is only 1 island (i.e. temp meta BUT NOT unselected/normal/normal-meta strips) left after this, + * and this island has two strips inside it, then we should be able to just swap these still... + */ + if (nlt->strips.first == nlt->strips.last) { + NlaStrip *mstrip = (NlaStrip *)nlt->strips.first; + + if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) && (BLI_countlist(&mstrip->strips) == 2)) + { + /* remove this temp meta, so that we can see the strips inside */ + BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + } + } + + /* get two selected strips only (these will be metas due to prev step) to operate on + * - only allow swapping 2, as with more the context becomes unclear + */ + for (strip = nlt->strips.first; strip; strip = stripN) { + stripN = strip->next; + + if (strip->flag & NLASTRIP_FLAG_SELECT) { + /* first or second strip? */ + if (sa == NULL) { + /* store as first */ + sa = strip; + } + else if (sb == NULL) { + /* store as second */ + sb = strip; + } + else { + /* too many selected */ + break; + } + } + } + + if (strip) { + /* too many selected warning */ + BKE_reportf(op->reports, RPT_WARNING, + "Too many clusters of strips selected in NLA Track (%s). Needs exactly 2 to be selected.", + nlt->name); + } + else if (sa == NULL) { + /* no warning as this is just a common case, and it may get annoying when doing multiple tracks */ + } + else if (sb == NULL) { + /* too few selected warning */ + BKE_reportf(op->reports, RPT_WARNING, + "Too few clusters of strips selected in NLA Track (%s). Needs exactly 2 to be selected.", + nlt->name); + } + else { + float nsa[2], nsb[2]; + + /* remove these strips from the track, so that we can test if they can fit in the proposed places */ + BLI_remlink(&nlt->strips, sa); + BLI_remlink(&nlt->strips, sb); + + /* calculate new extents for strips */ + /* a --> b */ + nsa[0] = sb->start; + nsa[1] = sb->start + (sa->end - sa->start); + /* b --> a */ + nsb[0] = sa->start; + nsb[1] = sa->start + (sb->end - sb->start); + + /* check if the track has room for the strips to be swapped */ + if (BKE_nlastrips_has_space(&nlt->strips, nsa[0], nsa[1]) && + BKE_nlastrips_has_space(&nlt->strips, nsb[0], nsb[1])) + { + /* set new extents for strips then */ + sa->start = nsa[0]; + sa->end = nsa[1]; + BKE_nlameta_flush_transforms(sa); + + sb->start = nsb[0]; + sb->end = nsb[1]; + BKE_nlameta_flush_transforms(sb); + } + else { + /* not enough room to swap, so show message */ + if ((sa->flag & NLASTRIP_FLAG_TEMP_META) || (sb->flag & NLASTRIP_FLAG_TEMP_META)) { + BKE_report(op->reports, RPT_WARNING, + "Cannot swap selected strips as they will not be able to fit in their new places"); + } + else { + BKE_reportf(op->reports, RPT_WARNING, + "Cannot swap '%s' and '%s' as one or both will not be able to fit in their new places", + sa->name, sb->name); + } + } + + /* add strips back to track now */ + BKE_nlatrack_add_strip(nlt, sa); + BKE_nlatrack_add_strip(nlt, sb); + } + + /* clear (temp) metastrips */ + BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + } + + /* free temp data */ + BLI_freelistN(&anim_data); + + /* refresh auto strip properties */ + ED_nla_postop_refresh(&ac); + + /* set notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_EDITED, NULL); + + /* done */ + return OPERATOR_FINISHED; +} + +void NLA_OT_swap (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Swap Strips"; + ot->idname= "NLA_OT_swap"; + ot->description= "Swap order of selected strips within tracks"; + + /* api callbacks */ + ot->exec= nlaedit_swap_exec; + ot->poll= nlaop_poll_tweakmode_off; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ******************** Move Strips Up Operator ************************** */ /* Tries to move the selected strips into the track above if possible. */ |