diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h index 48a7ca34672..fb85a3290c2 100644 --- a/source/blender/include/BIF_editseq.h +++ b/source/blender/include/BIF_editseq.h @@ -57,6 +57,7 @@ void swap_select_seq(void); void touch_seq_files(void); void transform_seq(int mode, int context); void un_meta(void); +void seq_cut(short cutframe); /* drawseq.c */ void do_seqbuttons(short); diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index c9aff9b42cc..14d545a7262 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -1754,7 +1754,9 @@ void enter_meta(void) typedef struct TransSeq { int start, machine; int startstill, endstill; + int startdisp, enddisp; int startofs, endofs; + int len; } TransSeq; void transform_seq(int mode, int context) @@ -2074,6 +2076,136 @@ void clever_numbuts_seq(void) } } +void seq_cut(short cutframe) +{ + Editing *ed; + Sequence *seq; + TransSeq *ts, *transmain; + int tot=0; + ListBase newlist; + + ed= G.scene->ed; + if(ed==0) return; + + /* test for validity */ + for(seq= ed->seqbasep->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + if(cutframe > seq->startdisp && cutframe < seq->enddisp) + if(seq->type==SEQ_META) break; + } + } + if(seq) { + error("Cannot cut Meta strips"); + return; + } + + /* we build an array of TransSeq, to denote which strips take part in cutting */ + for(seq= ed->seqbasep->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + if(cutframe > seq->startdisp && cutframe < seq->enddisp) + tot++; + else + seq->flag &= ~SELECT; // bad code, but we need it for recurs_dupli_seq... note that this ~SELECT assumption is used in loops below too (ton) + } + } + + if(tot==0) { + error("No strips to cut"); + return; + } + + ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq"); + + for(seq= ed->seqbasep->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + + ts->start= seq->start; + ts->machine= seq->machine; + ts->startstill= seq->startstill; + ts->endstill= seq->endstill; + ts->startdisp= seq->startdisp; + ts->enddisp= seq->enddisp; + ts->startofs= seq->startofs; + ts->endofs= seq->endofs; + ts->len= seq->len; + + ts++; + } + } + + for(seq= ed->seqbasep->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + + /* strips with extended stillframes before */ + if ((seq->startstill) && (cutframe start)) { + seq->start= cutframe -1; + seq->startstill= cutframe -seq->startdisp -1; + seq->len= 1; + seq->endstill= 0; + } + + /* normal strip */ + else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) { + seq->endofs = (seq->start+seq->len) - cutframe; + } + + /* strips with extended stillframes after */ + else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) { + seq->endstill -= seq->enddisp - cutframe; + } + + calc_sequence(seq); + } + } + + newlist.first= newlist.last= NULL; + + /* now we duplicate the cut strip and move it into place afterwards */ + recurs_dupli_seq(ed->seqbasep, &newlist); + addlisttolist(ed->seqbasep, &newlist); + + ts= transmain; + + /* go through all the strips and correct them based on their stored values */ + for(seq= ed->seqbasep->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + + /* strips with extended stillframes before */ + if ((seq->startstill) && (cutframe == seq->start + 1)) { + seq->start = ts->start; + seq->startstill= ts->start- cutframe; + seq->len = ts->len; + seq->endstill = ts->endstill; + } + + /* normal strip */ + else if ((cutframe>=seq->start)&&(cutframe<=(seq->start+seq->len))) { + seq->startstill = 0; + seq->startofs = cutframe - ts->start; + seq->endofs = ts->endofs; + seq->endstill = ts->endstill; + } + + /* strips with extended stillframes after */ + else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) { + seq->start = cutframe - ts->len +1; + seq->startofs = ts->len-1; + seq->endstill = ts->enddisp - cutframe -1; + seq->startstill = 0; + } + calc_sequence(seq); + + ts++; + } + } + + /* as last: */ + sort_seq(); + MEM_freeN(transmain); + + allqueue(REDRAWSEQ, 0); +} + void seq_snap_menu(void) { short event; diff --git a/source/blender/src/header_seq.c b/source/blender/src/header_seq.c index b38aba31a8e..cd65317145b 100644 --- a/source/blender/src/header_seq.c +++ b/source/blender/src/header_seq.c @@ -325,7 +325,10 @@ static void do_seq_editmenu(void *arg, int event) break; case 12: /* Snap to Current Frame */ seq_snap(event); - break; + break; + case 13: /* Cut at Current Frame */ + seq_cut(CFRA); + break; } } @@ -345,6 +348,10 @@ static uiBlock *seq_editmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Snap to Current Frame|Shift S, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cut at Current Frame|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, ""); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 259eee7b300..a91841afe7c 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3438,6 +3438,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if((G.qual==0)) transform_seq('g', 0); break; + case KKEY: + if((G.qual==0)) { /* Cut at current frame */ + if(okee("Cut strips")) seq_cut(CFRA); + } + break; case MKEY: if(G.qual==LR_ALTKEY) un_meta();