* operators for toggling, making, separating metastrip's. (tab, m, alt+m)
* transform support for metastrips * active strip is set to NULL if its freed again.
This commit is contained in:
@@ -137,7 +137,7 @@ struct SeqEffectHandle {
|
||||
/* sequence.c */
|
||||
|
||||
// extern
|
||||
void seq_free_sequence(struct Sequence *seq);
|
||||
void seq_free_sequence(struct Editing *ed, struct Sequence *seq);
|
||||
void seq_free_strip(struct Strip *strip);
|
||||
void seq_free_editing(struct Editing *ed);
|
||||
char *give_seqname(struct Sequence *seq);
|
||||
@@ -175,5 +175,7 @@ int seq_tx_get_final_right(struct Sequence *seq, int metaclip);
|
||||
void seq_tx_set_final_left(struct Sequence *seq, int val);
|
||||
void seq_tx_set_final_right(struct Sequence *seq, int val);
|
||||
void seq_tx_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag);
|
||||
int seq_tx_test(struct Sequence * seq);
|
||||
int check_single_seq(struct Sequence *seq);
|
||||
void fix_single_seq(struct Sequence *seq);
|
||||
|
||||
|
||||
@@ -165,10 +165,8 @@ void seq_free_strip(Strip *strip)
|
||||
MEM_freeN(strip);
|
||||
}
|
||||
|
||||
void seq_free_sequence(Sequence *seq)
|
||||
void seq_free_sequence(Editing *ed, Sequence *seq)
|
||||
{
|
||||
//XXX Sequence *last_seq = get_last_seq();
|
||||
|
||||
if(seq->strip) seq_free_strip(seq->strip);
|
||||
|
||||
if(seq->anim) IMB_free_anim(seq->anim);
|
||||
@@ -180,7 +178,8 @@ void seq_free_sequence(Sequence *seq)
|
||||
sh.free(seq);
|
||||
}*/
|
||||
|
||||
//XXX if(seq==last_seq) set_last_seq(NULL);
|
||||
if (ed->act_seq==seq)
|
||||
ed->act_seq= NULL;
|
||||
|
||||
MEM_freeN(seq);
|
||||
}
|
||||
@@ -194,7 +193,7 @@ void seq_free_editing(Editing *ed)
|
||||
return;
|
||||
|
||||
SEQ_BEGIN(ed, seq) {
|
||||
seq_free_sequence(seq);
|
||||
seq_free_sequence(ed, seq);
|
||||
}
|
||||
SEQ_END
|
||||
|
||||
@@ -3192,4 +3191,9 @@ void fix_single_seq(Sequence *seq)
|
||||
seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
|
||||
seq->start += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int seq_tx_test(Sequence * seq)
|
||||
{
|
||||
return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
|
||||
}
|
||||
|
||||
@@ -747,7 +747,7 @@ static int add_seq_effect(Scene *scene, View2D *v2d, int type, char *str)
|
||||
|
||||
if(newseq->plugin==0) {
|
||||
BLI_remlink(ed->seqbasep, newseq);
|
||||
seq_free_sequence(newseq);
|
||||
seq_free_sequence(ed, newseq);
|
||||
set_last_seq(scene, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "BKE_sequence.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
@@ -252,7 +253,7 @@ void shuffle_seq(Scene *scene, Sequence *test)
|
||||
error("There is no more space to add a sequence strip");
|
||||
|
||||
BLI_remlink(ed->seqbasep, test);
|
||||
seq_free_sequence(test);
|
||||
seq_free_sequence(ed, test);
|
||||
return;
|
||||
}
|
||||
test->machine++;
|
||||
@@ -312,12 +313,6 @@ void boundbox_seq(Scene *scene, rctf *rect)
|
||||
|
||||
}
|
||||
|
||||
int sequence_is_free_transformable(Sequence * seq)
|
||||
{
|
||||
return seq->type < SEQ_EFFECT
|
||||
|| (get_sequence_effect_num_inputs(seq->type) == 0);
|
||||
}
|
||||
|
||||
/* XXX - use mouse_frame_side instead */
|
||||
char mouse_cfra_side(View2D *v2d, int frame )
|
||||
{
|
||||
@@ -458,7 +453,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, short mval[2])
|
||||
if( ((seq->startdisp < seq->enddisp) && (seq->startdisp<=x && seq->enddisp>=x)) ||
|
||||
((seq->startdisp > seq->enddisp) && (seq->startdisp>=x && seq->enddisp<=x)) )
|
||||
{
|
||||
if(sequence_is_free_transformable(seq)) {
|
||||
if(seq_tx_test(seq)) {
|
||||
|
||||
/* clamp handles to defined size in pixel space */
|
||||
|
||||
@@ -662,7 +657,7 @@ static void reload_sound_strip(Scene *scene, char *name)
|
||||
calc_sequence(seqact);
|
||||
|
||||
seq->strip= 0;
|
||||
seq_free_sequence(seq);
|
||||
seq_free_sequence(ed, seq);
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
|
||||
seq= ed->seqbasep->first;
|
||||
@@ -702,7 +697,7 @@ static void reload_image_strip(Scene *scene, char *name)
|
||||
calc_sequence(seqact);
|
||||
|
||||
seq->strip= 0;
|
||||
seq_free_sequence(seq);
|
||||
seq_free_sequence(ed, seq);
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
|
||||
update_changed_seq_and_deps(scene, seqact, 1, 1);
|
||||
@@ -969,7 +964,7 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de
|
||||
if(seq==last_seq) set_last_seq(scene, NULL);
|
||||
if(seq->type==SEQ_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1);
|
||||
if(seq->ipo) seq->ipo->id.us--;
|
||||
seq_free_sequence(seq);
|
||||
seq_free_sequence((Editing *)scene->ed, seq);
|
||||
}
|
||||
seq= seqn;
|
||||
}
|
||||
@@ -1453,203 +1448,6 @@ void no_gaps(Scene *scene)
|
||||
}
|
||||
|
||||
|
||||
/* ****************** META ************************* */
|
||||
|
||||
void make_meta(Scene *scene)
|
||||
{
|
||||
Sequence *seq, *seqm, *next;
|
||||
Editing *ed;
|
||||
int tot;
|
||||
|
||||
ed= scene->ed;
|
||||
if(ed==NULL) return;
|
||||
|
||||
/* is there more than 1 select */
|
||||
tot= 0;
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
tot++;
|
||||
if (seq->type == SEQ_RAM_SOUND) {
|
||||
error("Can't make Meta Strip from audio");
|
||||
return;
|
||||
}
|
||||
}
|
||||
seq= seq->next;
|
||||
}
|
||||
if(tot < 1) return;
|
||||
|
||||
if(okee("Make Meta Strip")==0) return;
|
||||
|
||||
/* test relationships */
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
if(seq->type & SEQ_EFFECT) {
|
||||
if(seq->seq1 &&
|
||||
(seq->seq1->flag & SELECT)==0) tot= 0;
|
||||
if(seq->seq2 &&
|
||||
(seq->seq2->flag & SELECT)==0) tot= 0;
|
||||
if(seq->seq3 &&
|
||||
(seq->seq3->flag & SELECT)==0) tot= 0;
|
||||
}
|
||||
}
|
||||
else if(seq->type & SEQ_EFFECT) {
|
||||
if(seq->seq1 &&
|
||||
(seq->seq1->flag & SELECT)) tot= 0;
|
||||
if(seq->seq2 &&
|
||||
(seq->seq2->flag & SELECT)) tot= 0;
|
||||
if(seq->seq3 &&
|
||||
(seq->seq3->flag & SELECT)) tot= 0;
|
||||
}
|
||||
if(tot==0) break;
|
||||
seq= seq->next;
|
||||
}
|
||||
if(tot==0) {
|
||||
error("Please select all related strips");
|
||||
return;
|
||||
}
|
||||
|
||||
/* remove all selected from main list, and put in meta */
|
||||
|
||||
seqm= alloc_sequence(((Editing *)scene->ed)->seqbasep, 1, 1);
|
||||
seqm->type= SEQ_META;
|
||||
seqm->flag= SELECT;
|
||||
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
next= seq->next;
|
||||
if(seq!=seqm && (seq->flag & SELECT)) {
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
BLI_addtail(&seqm->seqbase, seq);
|
||||
}
|
||||
seq= next;
|
||||
}
|
||||
calc_sequence(seqm);
|
||||
|
||||
seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
|
||||
seqm->strip->len= seqm->len;
|
||||
seqm->strip->us= 1;
|
||||
|
||||
if( test_overlap_seq(scene, seqm) ) shuffle_seq(scene, seqm);
|
||||
|
||||
BIF_undo_push("Make Meta Strip, Sequencer");
|
||||
}
|
||||
|
||||
static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
|
||||
{
|
||||
if (seq == seqm) return 1;
|
||||
else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
|
||||
else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
|
||||
else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void un_meta(Scene *scene)
|
||||
{
|
||||
Editing *ed;
|
||||
Sequence *seq, *last_seq = get_last_seq(scene);
|
||||
|
||||
ed= scene->ed;
|
||||
if(ed==NULL) return;
|
||||
|
||||
if(last_seq==0 || last_seq->type!=SEQ_META) return;
|
||||
|
||||
if(okee("Un Meta Strip")==0) return;
|
||||
|
||||
addlisttolist(ed->seqbasep, &last_seq->seqbase);
|
||||
|
||||
last_seq->seqbase.first= 0;
|
||||
last_seq->seqbase.last= 0;
|
||||
|
||||
BLI_remlink(ed->seqbasep, last_seq);
|
||||
seq_free_sequence(last_seq);
|
||||
|
||||
/* emtpy meta strip, delete all effects depending on it */
|
||||
for(seq=ed->seqbasep->first; seq; seq=seq->next)
|
||||
if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
|
||||
seq->flag |= SEQ_FLAG_DELETE;
|
||||
|
||||
recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0);
|
||||
|
||||
/* test for effects and overlap */
|
||||
SEQP_BEGIN(ed, seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
seq->flag &= ~SEQ_OVERLAP;
|
||||
if( test_overlap_seq(scene, seq) ) {
|
||||
shuffle_seq(scene, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
SEQ_END;
|
||||
|
||||
sort_seq(scene);
|
||||
|
||||
BIF_undo_push("Un-Make Meta Strip, Sequencer");
|
||||
}
|
||||
|
||||
void exit_meta(Scene *scene)
|
||||
{
|
||||
Sequence *seq;
|
||||
MetaStack *ms;
|
||||
Editing *ed;
|
||||
|
||||
ed= scene->ed;
|
||||
if(ed==NULL) return;
|
||||
|
||||
if(ed->metastack.first==0) return;
|
||||
|
||||
ms= ed->metastack.last;
|
||||
BLI_remlink(&ed->metastack, ms);
|
||||
|
||||
ed->seqbasep= ms->oldbasep;
|
||||
|
||||
/* recalc all: the meta can have effects connected to it */
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
calc_sequence(seq);
|
||||
seq= seq->next;
|
||||
}
|
||||
|
||||
set_last_seq(scene, ms->parseq);
|
||||
|
||||
ms->parseq->flag |= SELECT;
|
||||
recurs_sel_seq(ms->parseq);
|
||||
|
||||
MEM_freeN(ms);
|
||||
|
||||
BIF_undo_push("Exit Meta Strip, Sequence");
|
||||
}
|
||||
|
||||
|
||||
void enter_meta(Scene *scene)
|
||||
{
|
||||
MetaStack *ms;
|
||||
Editing *ed;
|
||||
Sequence *last_seq= get_last_seq(scene);
|
||||
|
||||
ed= scene->ed;
|
||||
if(ed==NULL) return;
|
||||
|
||||
if(last_seq==0 || last_seq->type!=SEQ_META || (last_seq->flag & SELECT)==0) {
|
||||
exit_meta(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
ms= MEM_mallocN(sizeof(MetaStack), "metastack");
|
||||
BLI_addtail(&ed->metastack, ms);
|
||||
ms->parseq= last_seq;
|
||||
ms->oldbasep= ed->seqbasep;
|
||||
|
||||
ed->seqbasep= &last_seq->seqbase;
|
||||
|
||||
set_last_seq(scene, NULL);
|
||||
BIF_undo_push("Enter Meta Strip, Sequence");
|
||||
}
|
||||
|
||||
|
||||
/* ****************** END META ************************* */
|
||||
|
||||
static int seq_get_snaplimit(View2D *v2d)
|
||||
{
|
||||
/* fake mouse coords to get the snap value
|
||||
@@ -1970,7 +1768,7 @@ void transform_seq(Scene *scene, SpaceSeq *sseq, View2D *v2d, int mode, int cont
|
||||
seq_tx_handle_xlimits(seq, sel_flag & SEQ_LEFTSEL, sel_flag & SEQ_RIGHTSEL);
|
||||
|
||||
if( (sel_flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
|
||||
if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
|
||||
if(seq_tx_test(seq)) seq->start= ts->start+ ix;
|
||||
|
||||
/* Y Transformation */
|
||||
if(seq->depth==0) seq->machine= ts->machine+ iy;
|
||||
@@ -2008,7 +1806,7 @@ void transform_seq(Scene *scene, SpaceSeq *sseq, View2D *v2d, int mode, int cont
|
||||
for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
|
||||
if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
|
||||
/* only move the contents of the metastrip otherwise the transformation is applied twice */
|
||||
if (sequence_is_free_transformable(seq) && seq->type != SEQ_META) {
|
||||
if (seq_tx_test(seq) && seq->type != SEQ_META) {
|
||||
|
||||
move_left = move_right = 0;
|
||||
|
||||
@@ -2292,7 +2090,7 @@ void seq_snap(Scene *scene, short event)
|
||||
/* also check metas */
|
||||
SEQP_BEGIN(ed, seq) {
|
||||
if (seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK) &&
|
||||
sequence_is_free_transformable(seq)) {
|
||||
seq_tx_test(seq)) {
|
||||
if((seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0) {
|
||||
seq->start= CFRA-seq->startofs+seq->startstill;
|
||||
} else {
|
||||
@@ -2751,7 +2549,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
|
||||
start_ofs += step;
|
||||
}
|
||||
|
||||
seq_free_sequence(seq);
|
||||
seq_free_sequence(ed, seq);
|
||||
seq = seq->next;
|
||||
} else {
|
||||
seq = seq->next;
|
||||
@@ -2780,3 +2578,244 @@ void SEQUENCER_OT_separate_images(wmOperatorType *ot)
|
||||
|
||||
ot->poll= ED_operator_sequencer_active;
|
||||
}
|
||||
|
||||
|
||||
/* META Operators */
|
||||
|
||||
/* separate_meta_toggle operator */
|
||||
static int sequencer_meta_toggle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= scene->ed;
|
||||
Sequence *last_seq= get_last_seq(scene);
|
||||
MetaStack *ms;
|
||||
|
||||
|
||||
|
||||
if(last_seq && last_seq->type==SEQ_META && last_seq->flag & SELECT) {
|
||||
/* Enter Metastrip */
|
||||
ms= MEM_mallocN(sizeof(MetaStack), "metastack");
|
||||
BLI_addtail(&ed->metastack, ms);
|
||||
ms->parseq= last_seq;
|
||||
ms->oldbasep= ed->seqbasep;
|
||||
|
||||
ed->seqbasep= &last_seq->seqbase;
|
||||
|
||||
set_last_seq(scene, NULL);
|
||||
|
||||
ED_undo_push(C, "Enter Meta Strip, Sequence");
|
||||
}
|
||||
else {
|
||||
/* Exit Metastrip (if possible) */
|
||||
|
||||
Sequence *seq;
|
||||
|
||||
if(ed->metastack.first==NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
ms= ed->metastack.last;
|
||||
BLI_remlink(&ed->metastack, ms);
|
||||
|
||||
ed->seqbasep= ms->oldbasep;
|
||||
|
||||
/* recalc all: the meta can have effects connected to it */
|
||||
for(seq= ed->seqbasep->first; seq; seq= seq->next)
|
||||
calc_sequence(seq);
|
||||
|
||||
set_last_seq(scene, ms->parseq);
|
||||
|
||||
ms->parseq->flag |= SELECT;
|
||||
recurs_sel_seq(ms->parseq);
|
||||
|
||||
MEM_freeN(ms);
|
||||
|
||||
ED_undo_push(C, "Exit Meta Strip, Sequence");
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Toggle Meta Strip";
|
||||
ot->idname= "SEQUENCER_OT_meta_toggle";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= sequencer_meta_toggle_exec;
|
||||
|
||||
ot->poll= ED_operator_sequencer_active;
|
||||
}
|
||||
|
||||
|
||||
/* separate_meta_make operator */
|
||||
static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= scene->ed;
|
||||
|
||||
Sequence *seq, *seqm, *next;
|
||||
|
||||
int tot;
|
||||
|
||||
/* is there more than 1 select */
|
||||
tot= 0;
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
tot++;
|
||||
if (seq->type == SEQ_RAM_SOUND) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't make Meta Strip from audio");
|
||||
return OPERATOR_CANCELLED;;
|
||||
}
|
||||
}
|
||||
seq= seq->next;
|
||||
}
|
||||
if(tot < 1) return OPERATOR_CANCELLED;;
|
||||
|
||||
|
||||
/* test relationships */
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
if(seq->type & SEQ_EFFECT) {
|
||||
if(seq->seq1 &&
|
||||
(seq->seq1->flag & SELECT)==0) tot= 0;
|
||||
if(seq->seq2 &&
|
||||
(seq->seq2->flag & SELECT)==0) tot= 0;
|
||||
if(seq->seq3 &&
|
||||
(seq->seq3->flag & SELECT)==0) tot= 0;
|
||||
}
|
||||
}
|
||||
else if(seq->type & SEQ_EFFECT) {
|
||||
if(seq->seq1 &&
|
||||
(seq->seq1->flag & SELECT)) tot= 0;
|
||||
if(seq->seq2 &&
|
||||
(seq->seq2->flag & SELECT)) tot= 0;
|
||||
if(seq->seq3 &&
|
||||
(seq->seq3->flag & SELECT)) tot= 0;
|
||||
}
|
||||
if(tot==0) break;
|
||||
seq= seq->next;
|
||||
}
|
||||
|
||||
if(tot==0) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* remove all selected from main list, and put in meta */
|
||||
|
||||
seqm= alloc_sequence(((Editing *)scene->ed)->seqbasep, 1, 1);
|
||||
seqm->type= SEQ_META;
|
||||
seqm->flag= SELECT;
|
||||
|
||||
seq= ed->seqbasep->first;
|
||||
while(seq) {
|
||||
next= seq->next;
|
||||
if(seq!=seqm && (seq->flag & SELECT)) {
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
BLI_addtail(&seqm->seqbase, seq);
|
||||
}
|
||||
seq= next;
|
||||
}
|
||||
calc_sequence(seqm);
|
||||
|
||||
seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
|
||||
seqm->strip->len= seqm->len;
|
||||
seqm->strip->us= 1;
|
||||
|
||||
set_last_seq(scene, seqm);
|
||||
|
||||
if( test_overlap_seq(scene, seqm) ) shuffle_seq(scene, seqm);
|
||||
|
||||
ED_undo_push(C, "Make Meta Strip, Sequencer");
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_meta_make(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Make Meta Strip";
|
||||
ot->idname= "SEQUENCER_OT_meta_make";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_operator_confirm;
|
||||
ot->exec= sequencer_meta_make_exec;
|
||||
|
||||
ot->poll= ED_operator_sequencer_active;
|
||||
}
|
||||
|
||||
|
||||
static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
|
||||
{
|
||||
if (seq == seqm) return 1;
|
||||
else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
|
||||
else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
|
||||
else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* separate_meta_make operator */
|
||||
static int sequencer_meta_separate_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= scene->ed;
|
||||
|
||||
Sequence *seq, *last_seq = get_last_seq(scene);
|
||||
|
||||
if(last_seq==0 || last_seq->type!=SEQ_META)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
addlisttolist(ed->seqbasep, &last_seq->seqbase);
|
||||
|
||||
last_seq->seqbase.first= 0;
|
||||
last_seq->seqbase.last= 0;
|
||||
|
||||
BLI_remlink(ed->seqbasep, last_seq);
|
||||
seq_free_sequence(ed, last_seq);
|
||||
|
||||
/* emtpy meta strip, delete all effects depending on it */
|
||||
for(seq=ed->seqbasep->first; seq; seq=seq->next)
|
||||
if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
|
||||
seq->flag |= SEQ_FLAG_DELETE;
|
||||
|
||||
recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0);
|
||||
|
||||
/* test for effects and overlap */
|
||||
SEQP_BEGIN(ed, seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
seq->flag &= ~SEQ_OVERLAP;
|
||||
if( test_overlap_seq(scene, seq) ) {
|
||||
shuffle_seq(scene, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
SEQ_END;
|
||||
|
||||
sort_seq(scene);
|
||||
|
||||
ED_undo_push(C, "UnMeta Strip, Sequencer");
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "UnMeta Strip";
|
||||
ot->idname= "SEQUENCER_OT_meta_separate";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_operator_confirm;
|
||||
ot->exec= sequencer_meta_separate_exec;
|
||||
|
||||
ot->poll= ED_operator_sequencer_active;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_add_duplicate(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_delete(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_separate_images(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_meta_toggle(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_meta_make(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_meta_separate(struct wmOperatorType *ot);
|
||||
|
||||
|
||||
/* sequencer_select.c */
|
||||
|
||||
@@ -70,6 +70,9 @@ void sequencer_operatortypes(void)
|
||||
WM_operatortype_append(SEQUENCER_OT_add_duplicate);
|
||||
WM_operatortype_append(SEQUENCER_OT_delete);
|
||||
WM_operatortype_append(SEQUENCER_OT_separate_images);
|
||||
WM_operatortype_append(SEQUENCER_OT_meta_toggle);
|
||||
WM_operatortype_append(SEQUENCER_OT_meta_make);
|
||||
WM_operatortype_append(SEQUENCER_OT_meta_separate);
|
||||
|
||||
/* sequencer_select.c */
|
||||
WM_operatortype_append(SEQUENCER_OT_deselect_all);
|
||||
@@ -112,6 +115,11 @@ void sequencer_keymap(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_separate_images", YKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_toggle", TABKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_make", MKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_separate", MKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
|
||||
|
||||
@@ -261,6 +261,13 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
|
||||
adr[0]= out[0];
|
||||
adr[1]= out[1];
|
||||
}
|
||||
else if(t->spacetype==SPACE_SEQ) { /* XXX not tested yet, but should work */
|
||||
int out[2] = {0, 0};
|
||||
|
||||
UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1);
|
||||
adr[0]= out[0];
|
||||
adr[1]= out[1];
|
||||
}
|
||||
}
|
||||
|
||||
void projectFloatView(TransInfo *t, float *vec, float *adr)
|
||||
|
||||
@@ -153,7 +153,9 @@ typedef struct TransDataCurveHandleFlags {
|
||||
/* for sequencer transform */
|
||||
typedef struct TransDataSeq {
|
||||
struct Sequence *seq;
|
||||
int flag; /* a copy of seq->flag that may be modified for nested strips */
|
||||
short sel_flag; /* one of SELECT, SEQ_LEFTSEL and SEQ_RIGHTSEL */
|
||||
|
||||
} TransDataSeq;
|
||||
|
||||
typedef struct TransData {
|
||||
|
||||
@@ -2311,6 +2311,12 @@ void flushTransSeq(TransInfo *t)
|
||||
TransDataSeq *tdsq= NULL;
|
||||
Sequence *seq;
|
||||
|
||||
|
||||
/* prevent updating the same seq twice
|
||||
* if the transdata order is changed this will mess up
|
||||
* but so will TransDataSeq */
|
||||
Sequence *seq_prev= NULL;
|
||||
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for(a=0; a<t->total; a++, td++, td2d++) {
|
||||
|
||||
@@ -2325,22 +2331,38 @@ void flushTransSeq(TransInfo *t)
|
||||
|
||||
switch (tdsq->sel_flag) {
|
||||
case SELECT:
|
||||
seq->start= new_frame;
|
||||
seq->machine= (int)(td2d->loc[1] + 0.5f);
|
||||
if (seq->type != SEQ_META) /* for meta's, their children move */
|
||||
seq->start= new_frame;
|
||||
|
||||
if (seq->depth==0) {
|
||||
seq->machine= (int)(td2d->loc[1] + 0.5f);
|
||||
CLAMP(seq->machine, 1, MAXSEQ);
|
||||
}
|
||||
break;
|
||||
case SEQ_LEFTSEL: /* no vertical transform */
|
||||
seq_tx_set_final_left(seq, new_frame);
|
||||
seq_tx_handle_xlimits(seq, seq->flag&SEQ_LEFTSEL, seq->flag&SEQ_RIGHTSEL);
|
||||
seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
|
||||
fix_single_seq(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
|
||||
break;
|
||||
case SEQ_RIGHTSEL: /* no vertical transform */
|
||||
seq_tx_set_final_right(seq, new_frame);
|
||||
seq_tx_handle_xlimits(seq, seq->flag&SEQ_LEFTSEL, seq->flag&SEQ_RIGHTSEL);
|
||||
seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
|
||||
fix_single_seq(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
|
||||
break;
|
||||
}
|
||||
|
||||
calc_sequence(seq);
|
||||
|
||||
if (seq != seq_prev) {
|
||||
if(seq->depth==0) {
|
||||
/* Calculate this strip and all nested strips
|
||||
* children are ALWAYS transformed first
|
||||
* so we dont need to do this in another loop. */
|
||||
calc_sequence(seq);
|
||||
}
|
||||
else {
|
||||
calc_sequence_disp(seq);
|
||||
}
|
||||
}
|
||||
seq_prev= seq;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3263,8 +3285,86 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list)
|
||||
}
|
||||
|
||||
|
||||
/* This function applies the rules for transforming a strip so duplicate
|
||||
* checks dont need to be added in multiple places.
|
||||
*
|
||||
* count and recursive MUST be set.
|
||||
*
|
||||
* seq->depth must be set
|
||||
*/
|
||||
static void SeqTransInfo(Sequence *seq, int *recursive, int *count, int *flag)
|
||||
{
|
||||
|
||||
static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int sel_flag)
|
||||
if (seq->depth == 0) {
|
||||
|
||||
/* Count */
|
||||
|
||||
/* Non nested strips (resect selection and handles) */
|
||||
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK) || (seq_tx_test(seq) == 0)) {
|
||||
*recursive= *count= *flag= 0;
|
||||
return; /* unselected strip, lockedd or the strip is an effect - then dont bother */
|
||||
}
|
||||
else if ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == (SEQ_LEFTSEL|SEQ_RIGHTSEL)) {
|
||||
*flag= seq->flag;
|
||||
*count= 2; /* we need 2 transdata's */
|
||||
} else {
|
||||
*flag= seq->flag;
|
||||
*count= 1; /* selected or with a handle selected */
|
||||
}
|
||||
|
||||
/* Recursive */
|
||||
|
||||
if ((seq->type == SEQ_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) {
|
||||
/* if any handles are selected, dont recurse */
|
||||
*recursive = 1;
|
||||
}
|
||||
else {
|
||||
*recursive = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Nested, different rules apply */
|
||||
|
||||
if (seq->type == SEQ_META) {
|
||||
/* Meta's can only directly be moved between channels since they
|
||||
* dont have their start and length set directly (children affect that)
|
||||
* since this Meta is nested we dont need any of its data infact.
|
||||
* calc_sequence() will update its settings when run on the toplevel meta */
|
||||
*flag= 0;
|
||||
*count= 0;
|
||||
*recursive = 1;
|
||||
}
|
||||
else {
|
||||
*flag= (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL);
|
||||
*count= 1; /* ignore the selection for nested */
|
||||
*recursive = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int SeqTransCount(ListBase *seqbase, int depth)
|
||||
{
|
||||
Sequence *seq;
|
||||
int tot= 0, recursive, count, flag;
|
||||
|
||||
for (seq= seqbase->first; seq; seq= seq->next) {
|
||||
seq->depth= depth;
|
||||
|
||||
SeqTransInfo(seq, &recursive, &count, &flag); /* ignore the flag */
|
||||
tot += count;
|
||||
|
||||
if (recursive) {
|
||||
tot += SeqTransCount(&seq->seqbase, depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
|
||||
static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
|
||||
{
|
||||
switch(sel_flag) {
|
||||
case SELECT:
|
||||
@@ -3283,8 +3383,13 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq
|
||||
td2d->loc2d = NULL;
|
||||
|
||||
|
||||
tdsq->sel_flag= sel_flag;
|
||||
tdsq->seq= seq;
|
||||
|
||||
/* Use instead of seq->flag for nested strips and other
|
||||
* cases where the selection may need to be modified */
|
||||
tdsq->flag= flag;
|
||||
tdsq->sel_flag= sel_flag;
|
||||
|
||||
|
||||
td->extra= (void *)tdsq; /* allow us to update the strip from here */
|
||||
|
||||
@@ -3307,6 +3412,50 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq
|
||||
return td;
|
||||
}
|
||||
|
||||
static int SeqToTransData_Recursive(ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
|
||||
{
|
||||
Sequence *seq;
|
||||
int recursive, count, flag;
|
||||
int tot= 0;
|
||||
|
||||
for (seq= seqbase->first; seq; seq= seq->next) {
|
||||
|
||||
SeqTransInfo(seq, &recursive, &count, &flag);
|
||||
|
||||
/* add children first so recalculating metastrips does nested strips first */
|
||||
if (recursive) {
|
||||
int tot_children= SeqToTransData_Recursive(&seq->seqbase, td, td2d, tdsq);
|
||||
|
||||
td= td + tot_children;
|
||||
td2d= td2d + tot_children;
|
||||
tdsq= tdsq + tot_children;
|
||||
|
||||
tot += tot_children;
|
||||
}
|
||||
|
||||
/* use 'flag' which is derived from seq->flag but modified for special cases */
|
||||
if (flag & SELECT) {
|
||||
if (flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) {
|
||||
if (flag & SEQ_LEFTSEL) {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
|
||||
tot++;
|
||||
}
|
||||
if (flag & SEQ_RIGHTSEL) {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT);
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
|
||||
static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
@@ -3320,16 +3469,7 @@ static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
int count=0;
|
||||
float cfra;
|
||||
|
||||
for (seq=ed->seqbasep->first; seq; seq= seq->next) {
|
||||
if (seq->flag & SELECT) {
|
||||
if ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == (SEQ_LEFTSEL|SEQ_RIGHTSEL)) {
|
||||
count += 2; /* transform both sides of the strip (not all that common) */
|
||||
}
|
||||
else {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = SeqTransCount(ed->seqbasep, 0);
|
||||
|
||||
/* stop if trying to build list if nothing selected */
|
||||
if (count == 0) {
|
||||
@@ -3343,22 +3483,10 @@ static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransSeq TransData2D");
|
||||
tdsq = t->customData= MEM_callocN(t->total*sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
||||
|
||||
|
||||
|
||||
/* loop 2: build transdata array */
|
||||
for (seq=ed->seqbasep->first; seq; seq= seq->next) {
|
||||
if (seq->flag & SELECT) {
|
||||
if (seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) {
|
||||
if (seq->flag & SEQ_LEFTSEL) {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, SEQ_LEFTSEL);
|
||||
}
|
||||
if (seq->flag & SEQ_RIGHTSEL) {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, SEQ_RIGHTSEL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SeqToTransData(td++, td2d++, tdsq++, seq, SELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
SeqToTransData_Recursive(ed->seqbasep, td, td2d, tdsq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user