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 touch_seq_files(void);
|
||||||
void transform_seq(int mode, int context);
|
void transform_seq(int mode, int context);
|
||||||
void un_meta(void);
|
void un_meta(void);
|
||||||
|
void seq_cut(short cutframe);
|
||||||
|
|
||||||
/* drawseq.c */
|
/* drawseq.c */
|
||||||
void do_seqbuttons(short);
|
void do_seqbuttons(short);
|
||||||
|
|||||||
@@ -1754,7 +1754,9 @@ void enter_meta(void)
|
|||||||
typedef struct TransSeq {
|
typedef struct TransSeq {
|
||||||
int start, machine;
|
int start, machine;
|
||||||
int startstill, endstill;
|
int startstill, endstill;
|
||||||
|
int startdisp, enddisp;
|
||||||
int startofs, endofs;
|
int startofs, endofs;
|
||||||
|
int len;
|
||||||
} TransSeq;
|
} TransSeq;
|
||||||
|
|
||||||
void transform_seq(int mode, int context)
|
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)
|
void seq_snap_menu(void)
|
||||||
{
|
{
|
||||||
short event;
|
short event;
|
||||||
|
|||||||
@@ -325,7 +325,10 @@ static void do_seq_editmenu(void *arg, int event)
|
|||||||
break;
|
break;
|
||||||
case 12: /* Snap to Current Frame */
|
case 12: /* Snap to Current Frame */
|
||||||
seq_snap(event);
|
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, "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, "");
|
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, "");
|
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, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
|
||||||
|
|||||||
@@ -3438,6 +3438,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
if((G.qual==0))
|
if((G.qual==0))
|
||||||
transform_seq('g', 0);
|
transform_seq('g', 0);
|
||||||
break;
|
break;
|
||||||
|
case KKEY:
|
||||||
|
if((G.qual==0)) { /* Cut at current frame */
|
||||||
|
if(okee("Cut strips")) seq_cut(CFRA);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MKEY:
|
case MKEY:
|
||||||
if(G.qual==LR_ALTKEY)
|
if(G.qual==LR_ALTKEY)
|
||||||
un_meta();
|
un_meta();
|
||||||
|
|||||||
Reference in New Issue
Block a user