Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editseq.c')
-rw-r--r--source/blender/src/editseq.c301
1 files changed, 243 insertions, 58 deletions
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index 7a6d0aa2766..ed99c71dec5 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -143,6 +143,53 @@ void clear_last_seq(Sequence *seq)
_last_seq_init = 0;
}
+
+
+/* seq funcs's for transforming internally
+ notice the difference between start/end and left/right.
+
+ left and right are the bounds at which the setuence is rendered,
+start and end are from the start and fixed length of the sequence.
+*/
+int seq_tx_get_start(Sequence *seq) {
+ return seq->start;
+}
+int seq_tx_get_end(Sequence *seq)
+{
+ return seq->start+seq->len;
+}
+
+int seq_tx_get_final_left(Sequence *seq)
+{
+ return (seq->start - seq->startstill) + seq->startofs;
+}
+int seq_tx_get_final_right(Sequence *seq)
+{
+ return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
+}
+
+void seq_tx_set_final_left(Sequence *seq, int val)
+{
+ if (val < (seq)->start) {
+ seq->startstill = abs(val - (seq)->start);
+ (seq)->startofs = 0;
+ } else {
+ seq->startofs = abs(val - (seq)->start);
+ seq->startstill = 0;
+ }
+}
+
+void seq_tx_set_final_right(Sequence *seq, int val)
+{
+ if (val > (seq)->start + (seq)->len) {
+ seq->endstill = abs(val - (seq->start + (seq)->len));
+ (seq)->endofs = 0;
+ } else {
+ seq->endofs = abs(val - ((seq)->start + (seq)->len));
+ seq->endstill = 0;
+ }
+}
+
/* used so we can do a quick check for single image seq
since they work a bit differently to normal image seq's (during transform) */
int check_single_image_seq(Sequence *seq)
@@ -161,12 +208,12 @@ static void fix_single_image_seq(Sequence *seq)
/* make sure the image is always at the start since there is only one,
adjusting its start should be ok */
- left = SEQ_GET_FINAL_LEFT(seq);
+ left = seq_tx_get_final_left(seq);
start = seq->start;
if (start != left) {
offset = left - start;
- SEQ_SET_FINAL_LEFT( seq, SEQ_GET_FINAL_LEFT(seq) - offset );
- SEQ_SET_FINAL_RIGHT( seq, SEQ_GET_FINAL_RIGHT(seq) - offset );
+ seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset );
+ seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset );
seq->start += offset;
}
}
@@ -2464,21 +2511,68 @@ typedef struct TransSeq {
int startstill, endstill;
int startdisp, enddisp;
int startofs, endofs;
+ int final_left, final_right;
int len;
} TransSeq;
+/* use to impose limits when dragging/extending - so impossible situations dont happen */
+static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
+{
+ if(leftflag) {
+ if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) {
+ seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1);
+ }
+
+ if (check_single_image_seq(seq)==0) {
+ if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) {
+ seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
+ }
+
+ /* dosnt work now - TODO */
+ /*
+ if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) {
+ int ofs;
+ ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq);
+ seq->start -= ofs;
+ seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs );
+ }*/
+
+ }
+ }
+
+ if(rightflag) {
+ if (seq_tx_get_final_right(seq) <= seq_tx_get_final_left(seq)) {
+ seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1);
+ }
+
+ if (check_single_image_seq(seq)==0) {
+ if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) {
+ seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
+ }
+ }
+ }
+
+ /* sounds cannot be extended past their endpoints */
+ if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
+ seq->startstill= 0;
+ seq->endstill= 0;
+ }
+}
+
void transform_seq(int mode, int context)
{
Sequence *seq;
Editing *ed;
float dx, dy, dvec[2], div;
TransSeq *transmain, *ts;
- int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+ int tot=0, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+ int ix, iy; /* these values are used for storing the mouses offset from its original location */
unsigned short event = 0;
short mval[2], val, xo, yo, xn, yn;
char str[32];
-
- if(mode!='g') return; /* from gesture */
+ char side; /* for extend mode only - use to know which side to extend on */
+
+ if(mode!='g' && mode!='e') return; /* from gesture */
/* which seqs are involved */
ed= G.scene->ed;
@@ -2498,20 +2592,32 @@ void transform_seq(int mode, int context)
WHILE_SEQ(ed->seqbasep) {
if(seq->flag & SELECT) {
-
ts->start= seq->start;
ts->machine= seq->machine;
ts->startstill= seq->startstill;
ts->endstill= seq->endstill;
ts->startofs= seq->startofs;
ts->endofs= seq->endofs;
-
+
+ /* for extend only */
+ if (mode=='e') {
+ ts->final_left = seq_tx_get_final_left(seq);
+ ts->final_right = seq_tx_get_final_right(seq);
+ }
ts++;
}
}
END_SEQ
getmouseco_areawin(mval);
+
+ /* choose the side based on which side of the playhead the mouse is on */
+ if (mode=='e') {
+ float xmouse, ymouse;
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+
xo=xn= mval[0];
yo=yn= mval[1];
dvec[0]= dvec[1]= 0.0;
@@ -2521,7 +2627,7 @@ void transform_seq(int mode, int context)
if(mval[0]!=xo || mval[1]!=yo || firsttime) {
firsttime= 0;
- if(mode=='g') {
+ if(mode=='g' || mode=='e') {
dx= mval[0]- xo;
dy= mval[1]- yo;
@@ -2542,60 +2648,135 @@ void transform_seq(int mode, int context)
if(midtog) dvec[proj]= 0.0;
ix= floor(dvec[0]+0.5);
iy= floor(dvec[1]+0.5);
-
+
ts= transmain;
-
- WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
- int myofs;
- //SEQ_DEBUG_INFO(seq);
- if(seq->flag & SEQ_LEFTSEL) {
- myofs = (ts->startofs - ts->startstill);
- SEQ_SET_FINAL_LEFT(seq, ts->start + (myofs + ix));
- if (SEQ_GET_FINAL_LEFT(seq) >= SEQ_GET_FINAL_RIGHT(seq)) {
- SEQ_SET_FINAL_LEFT(seq, SEQ_GET_FINAL_RIGHT(seq)-1);
- }
- if (check_single_image_seq(seq)==0) {
- if (SEQ_GET_FINAL_LEFT(seq) >= SEQ_GET_END(seq)) {
- SEQ_SET_FINAL_LEFT(seq, SEQ_GET_END(seq)-1);
- }
+
+ if (mode=='g') {
+ /* Grab */
+ WHILE_SEQ(ed->seqbasep) {
+ if(seq->flag & SELECT) {
+ int myofs;
+ // SEQ_DEBUG_INFO(seq);
+
+ /* X Transformation */
+ if(seq->flag & SEQ_LEFTSEL) {
+ myofs = (ts->startofs - ts->startstill);
+ seq_tx_set_final_left(seq, ts->start + (myofs + ix));
}
- }
- if(seq->flag & SEQ_RIGHTSEL) {
- myofs = (ts->endstill - ts->endofs);
- SEQ_SET_FINAL_RIGHT(seq, ts->start + seq->len + (myofs + ix));
- if (SEQ_GET_FINAL_RIGHT(seq) <= SEQ_GET_FINAL_LEFT(seq)) {
- SEQ_SET_FINAL_RIGHT(seq, SEQ_GET_FINAL_LEFT(seq)+1);
+ if(seq->flag & SEQ_RIGHTSEL) {
+ myofs = (ts->endstill - ts->endofs);
+ seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
}
+ transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
- if (check_single_image_seq(seq)==0) {
- if (SEQ_GET_FINAL_RIGHT(seq) <= SEQ_GET_START(seq)) {
- SEQ_SET_FINAL_RIGHT(seq, SEQ_GET_START(seq)+1);
- }
+ if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
+ if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
+
+ /* Y Transformation */
+ if(seq->depth==0) seq->machine= ts->machine+ iy;
+
+ if(seq->machine<1) seq->machine= 1;
+ else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
}
+ calc_sequence(seq);
+ ts++;
}
-
- if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
- seq->startstill= 0;
- seq->endstill= 0;
- }
-
- if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
- if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
-
- if(seq->depth==0) seq->machine= ts->machine+ iy;
-
- if(seq->machine<1) seq->machine= 1;
- else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
+ }
+ END_SEQ
+ /* Extend, grabs one side of the current frame */
+ } else if (mode=='e') {
+ int cfra = CFRA;
+ int myofs; /* offset from start of the seq clip */
+ int xnew, final_left, final_right; /* just to store results from seq_tx_get_final_left/right */
+
+ /* we dont use seq side selection flags for this,
+ instead we need to calculate which sides to move
+ based on its initial position from the cursor */
+ int move_left, move_right;
+
+ /* Extend, Similar to grab but operate on one side of the cursor */
+ WHILE_SEQ(ed->seqbasep) {
+ if(seq->flag & SELECT) {
+ if (sequence_is_free_transformable(seq)) {
+
+ move_left = move_right = 0;
+
+ //SEQ_DEBUG_INFO(seq);
+
+ final_left = seq_tx_get_final_left(seq);
+ final_right = seq_tx_get_final_right(seq);
+
+ /* Only X Axis moving */
+
+ /* work out which sides to move first */
+ if (side=='L') {
+ if (final_left <= cfra || ts->final_left <= cfra) move_left = 1;
+ if (final_right <= cfra || ts->final_right <= cfra) move_right = 1;
+ } else {
+ if (final_left >= cfra || ts->final_left >= cfra) move_left = 1;
+ if (final_right >= cfra || ts->final_right >= cfra) move_right = 1;
+ }
+
+ if (move_left && move_right) {
+ /* simple move - dont need to do anything complicated */
+ seq->start= ts->start+ ix;
+ } else {
+ if (side=='L') {
+ if (move_left) {
+
+ /* Similar to other funcs */
+ myofs = (ts->startofs - ts->startstill);
+ xnew = ts->start + (ix + myofs);
+
+ /* make sure the we dont resize down to 0 or less in size
+ also include the startstill so the contense dosnt go outside the bounds,
+ if the seq->startofs is 0 then its ignored */
+
+ /* TODO remove, add check to transform_grab_xlimits, works ok for now */
+ if (xnew + seq->startstill > final_right-1) {
+ xnew = (final_right-1) - seq->startstill;
+ }
+ /* Note, this is the only case where the start needs to be adjusted
+ since its not needed when modifying the end or when moving the entire sequence */
+ //seq->start = ts->start+ix; // This works when xnew is not clamped, line below takes clamping into account
+ seq->start= xnew - myofs; /* TODO see above */
+ /* done with unique stuff */
+
+ seq_tx_set_final_left(seq, xnew);
+ transform_grab_xlimits(seq, 1, 0);
+
+ /* Special case again - setting the end back to what it was */
+ seq_tx_set_final_right(seq, final_right);
+ }
+ if (move_right) {
+ myofs = (ts->endstill - ts->endofs);
+ xnew = ts->start + seq->len + (myofs + ix);
+ seq_tx_set_final_right(seq, xnew);
+ transform_grab_xlimits(seq, 0, 1);
+ }
+ } else { /* R */
+ if (move_left) {
+ myofs = (ts->startofs - ts->startstill);
+ xnew = ts->start + (myofs + ix);
+ seq_tx_set_final_left(seq, xnew);
+ transform_grab_xlimits(seq, 1, 0);
+ }
+ if (move_right) {
+ myofs = (ts->endstill - ts->endofs);
+ xnew = ts->start + seq->len + (myofs + ix);
+ seq_tx_set_final_right(seq, xnew);
+ transform_grab_xlimits(seq, 0, 1);
+ }
+ }
+ }
+ }
+ calc_sequence(seq);
+ ts++;
}
-
- calc_sequence(seq);
-
- ts++;
}
+ END_SEQ
}
- END_SEQ
-
+
sprintf(str, "X: %d Y: %d ", ix, iy);
headerprint(str);
}
@@ -2621,6 +2802,7 @@ void transform_seq(int mode, int context)
END_SEQ;
force_draw(0);
+
}
else BIF_wait_for_statechange();
@@ -2675,8 +2857,7 @@ void transform_seq(int mode, int context)
}
END_SEQ
- }
- else {
+ } else {
/* images, effects and overlap */
WHILE_SEQ(ed->seqbasep) {
@@ -2706,8 +2887,12 @@ void transform_seq(int mode, int context)
G.moving= 0;
MEM_freeN(transmain);
-
- BIF_undo_push("Transform Sequencer");
+
+ if (mode=='g')
+ BIF_undo_push("Transform Grab");
+ else if (mode=='e')
+ BIF_undo_push("Transform Extend");
+
allqueue(REDRAWSEQ, 0);
}