[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12275] trunk/blender/source/blender: Sequencer transform snap to marker, works with grab and extend, takes handle selection into account.
Campbell Barton
cbarton at metavr.com
Thu Oct 18 00:32:00 CEST 2007
Revision: 12275
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12275
Author: campbellbarton
Date: 2007-10-18 00:31:59 +0200 (Thu, 18 Oct 2007)
Log Message:
-----------
Sequencer transform snap to marker, works with grab and extend, takes handle selection into account.
this will snap one if 2/4 points to the marker when transforming. the active sequences bounds and the bounds of all selected clips.
Modified Paths:
--------------
trunk/blender/source/blender/include/BIF_editseq.h
trunk/blender/source/blender/src/editseq.c
Modified: trunk/blender/source/blender/include/BIF_editseq.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editseq.h 2007-10-17 18:33:01 UTC (rev 12274)
+++ trunk/blender/source/blender/include/BIF_editseq.h 2007-10-17 22:31:59 UTC (rev 12275)
@@ -83,6 +83,10 @@
void seq_tx_set_final_left(struct Sequence *seq, int i);
void seq_tx_set_final_right(struct Sequence *seq, int i);
+/* check if one side can be transformed */
+int seq_tx_check_left(struct Sequence *seq);
+int seq_tx_check_right(struct Sequence *seq);
+
#define SEQ_DEBUG_INFO(seq) printf("seq into '%s' -- len:%i start:%i startstill:%i endstill:%i startofs:%i endofs:%i\n",\
seq->name, seq->len, seq->start, seq->startstill, seq->endstill, seq->startofs, seq->endofs)
Modified: trunk/blender/source/blender/src/editseq.c
===================================================================
--- trunk/blender/source/blender/src/editseq.c 2007-10-17 18:33:01 UTC (rev 12274)
+++ trunk/blender/source/blender/src/editseq.c 2007-10-17 22:31:59 UTC (rev 12275)
@@ -191,6 +191,33 @@
}
}
+/* check if one side can be transformed */
+int seq_tx_check_left(Sequence *seq)
+{
+ if (seq->flag & SELECT) {
+ if (seq->flag & SEQ_LEFTSEL)
+ return 1;
+ else if (seq->flag & SEQ_RIGHTSEL)
+ return 0;
+
+ return 1; /* selected and neither left or right handles are, so let us move both */
+ }
+ return 0;
+}
+
+int seq_tx_check_right(Sequence *seq)
+{
+ if (seq->flag & SELECT) {
+ if (seq->flag & SEQ_RIGHTSEL)
+ return 1;
+ else if (seq->flag & SEQ_LEFTSEL)
+ return 0;
+
+ return 1; /* selected and neither left or right handles are, so let us move both */
+ }
+ return 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)
@@ -2569,6 +2596,18 @@
/* ****************** END META ************************* */
+static int seq_get_snaplimit(void)
+{
+ /* fake mouse coords to get the snap value
+ a bit lazy but its only done once pre transform */
+ float xmouse, ymouse, x;
+ short mval[2] = {24, 0}; /* 24 screen px snap */
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ x = xmouse;
+ mval[0] = 0;
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ return (int)(x - xmouse);
+}
typedef struct TransSeq {
int start, machine;
@@ -2626,22 +2665,34 @@
void transform_seq(int mode, int context)
{
SpaceSeq *sseq= curarea->spacedata.first;
- Sequence *seq;
+ Sequence *seq, *last_seq;
Editing *ed;
float dx, dy, dvec[2], div;
TransSeq *transmain, *ts;
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 */
+ int ix_old = 0;
unsigned short event = 0;
short mval[2], val, xo, yo, xn, yn;
char str[32];
char side; /* for extend mode only - use to know which side to extend on */
+ /* used for extend in a number of places */
+ int cfra = CFRA;
+
+ /* for snapping */
+ char snapskip = 0, snap, snap_old;
+ int snapdist_max = seq_get_snaplimit();
+ /* at the moment there are only 4 possible snap points,
+ last_seq start,end and selected bounds start/end */
+ int snap_points[4], snap_point_num = 0;
+ int j; /* loop on snap_points */
+
/* for markers */
int *oldframe, totmark, a;
TimeMarker *marker;
-
+
if(mode!='g' && mode!='e') return; /* from gesture */
/* which seqs are involved */
@@ -2656,7 +2707,9 @@
if(tot==0) return;
G.moving= 1;
-
+
+ last_seq = get_last_seq();
+
ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
WHILE_SEQ(ed->seqbasep) {
@@ -2685,7 +2738,7 @@
if (mode=='e') {
float xmouse, ymouse;
areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
- side = (xmouse > CFRA) ? 'R' : 'L';
+ side = (xmouse > cfra) ? 'R' : 'L';
}
/* Markers */
@@ -2700,7 +2753,7 @@
if (mode=='e') {
/* when extending, invalidate markers on the other side by using an invalid frame value */
- if ((side == 'L' && marker->frame > CFRA) || (side == 'R' && marker->frame < CFRA)) {
+ if ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)) {
oldframe[a] = MAXFRAME+1;
} else {
oldframe[a]= marker->frame;
@@ -2719,189 +2772,277 @@
while(afbreek==0) {
getmouseco_areawin(mval);
- if(mval[0]!=xo || mval[1]!=yo || firsttime) {
- firsttime= 0;
+ G.qual = get_qual();
+ snap = (G.qual & LR_CTRLKEY) ? 1 : 0;
+
+ if(mval[0]!=xo || mval[1]!=yo || firsttime || snap != snap_old) {
+ if (firsttime) {
+ snap_old = snap;
+ firsttime= 0;
+ }
+
+ /* run for either grab or extend */
+ dx= mval[0]- xo;
+ dy= mval[1]- yo;
- if(mode=='g' || mode=='e') {
+ div= G.v2d->mask.xmax-G.v2d->mask.xmin;
+ dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
- dx= mval[0]- xo;
- dy= mval[1]- yo;
+ div= G.v2d->mask.ymax-G.v2d->mask.ymin;
+ dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
- div= G.v2d->mask.xmax-G.v2d->mask.xmin;
- dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
+ if(G.qual & LR_SHIFTKEY) {
+ if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
+ }
- div= G.v2d->mask.ymax-G.v2d->mask.ymin;
- dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
+ dvec[0]+= dx;
+ dvec[1]+= dy;
- if(G.qual & LR_SHIFTKEY) {
- if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
- }
-
- dvec[0]+= dx;
- dvec[1]+= dy;
-
- if(midtog) dvec[proj]= 0.0;
- ix= floor(dvec[0]+0.5);
- iy= floor(dvec[1]+0.5);
+ if(midtog) dvec[proj]= 0.0;
+ ix= floor(dvec[0]+0.5);
+ iy= floor(dvec[1]+0.5);
+
+ ts= transmain;
+
+ /* SNAP! use the active Seq */
+ snap = G.qual & LR_CTRLKEY ? 1 : 0;
+
+ if (!snap) {
+ snapskip = 0;
+ } else {
+ int dist;
+ int snap_ofs;
+ int snap_dist= snapdist_max;
- ts= transmain;
+ /* Get sequence points to snap to the markers */
- if (mode=='g') {
- /* Grab */
+ snap_point_num=0;
+ if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */
+ if(seq_tx_check_left(last_seq))
+ snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq);
+ if(seq_tx_check_right(last_seq))
+ snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq);
+ }
+ if (tot > 1) { /* selection bounds */
+ int bounds_left = MAXFRAME*2;
+ int bounds_right = -(MAXFRAME*2);
+
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_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
- }
- transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
-
- 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_tx_check_left(seq))
+ bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq));
+ if(seq_tx_check_right(seq))
+ bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq));
}
}
END_SEQ
- /* Markers */
- if (sseq->flag & SEQ_MARKER_TRANS) {
- for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) {
- marker->frame= oldframe[a] + ix;
- a++;
+ /* its possible there were no points to set on either side */
+ if (bounds_left != MAXFRAME*2)
+ snap_points[snap_point_num++] = bounds_left;
+ if (bounds_right != -(MAXFRAME*2))
+ snap_points[snap_point_num++] = bounds_right;
+ }
+
+ /* Detect the best marker to snap to! */
+ for(a=0, marker= G.scene->markers.first; marker; a++, marker= marker->next) {
+
+ /* dont snap to a marker on the wrong extend side */
+ if (mode=='e' && ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)))
+ continue;
+
+ /* when we are moving markers, dont snap to selected markers, durr */
+ if ((sseq->flag & SEQ_MARKER_TRANS)==0 || (marker->flag & SELECT)==0) {
+
+ /* loop over the sticky points - max 4 */
+ for(j=0; j<snap_point_num; j++) {
+ /* see if this beats the current best snap point */
+ dist = abs(snap_points[j] - marker->frame);
+ if (dist < snap_dist) {
+ snap_ofs = marker->frame - snap_points[j];
+ snap_dist = dist;
}
}
+ if (snap_dist == 0) break; /* alredy snapped? - stop looking */
}
- /* 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) {
- /* only move the contents of the metastrip otherwise the transformation is applied twice */
- if (sequence_is_free_transformable(seq) && seq->type != SEQ_META) {
-
- 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 (abs(ix_old-ix) >= snapdist_max) {
+ /* mouse has moved out of snap range */
+ snapskip = 0;
+ } else if (snap_dist==0) {
+ /* nowhere to move, dont do anything */
+ snapskip = 1;
+ } else if (snap_dist < snapdist_max) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list