Patch provided by Matt Ebb, cut sequence strips (patch tracker).
There were a couple of issues with the implementation: - there was no proper test if selected strips would be cut or not - cutting meta strips could go very wrong... for example when the cut of meta was in an internal gap. With meta's being recursive, and too complex, I've disabled Meta-cutting - added an OK menu for hotkey K - added warnings when no cut was done This is the first time in 6 years I do work in sequencer... man, this has grown into a messy bizz! Like sequence variables... using names like: start, startdisp, startstill, startoffs... totally confusing here. Could use giant cleanup! Implementation was weak from scratch though, Mea Culpa!
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 <seq->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;
|
||||
|
||||
@@ -326,6 +326,9 @@ static void do_seq_editmenu(void *arg, int event)
|
||||
case 12: /* Snap to Current Frame */
|
||||
seq_snap(event);
|
||||
break;
|
||||
case 13: /* Cut at Current Frame */
|
||||
seq_cut(CFRA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +350,10 @@ static uiBlock *seq_editmenu(void *arg_unused)
|
||||
|
||||
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, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user