Commit 7716f4a5 authored by luyikei's avatar luyikei

Timeline: Find new positions by the frame

parent d776fa28
...@@ -31,6 +31,7 @@ Rectangle { ...@@ -31,6 +31,7 @@ Rectangle {
property int lastPosition property int lastPosition
property int begin property int begin
property int end property int end
property int length
property string libraryUuid // Library UUID: For thumbnails property string libraryUuid // Library UUID: For thumbnails
property string uuid // Instance UUID property string uuid // Instance UUID
property var linkedClips: linkedClipsDict[uuid] ? linkedClipsDict[uuid] : [] // Uuid property var linkedClips: linkedClipsDict[uuid] ? linkedClipsDict[uuid] : [] // Uuid
...@@ -40,19 +41,12 @@ Rectangle { ...@@ -40,19 +41,12 @@ Rectangle {
property var clipInfo property var clipInfo
function setPixelPosition( pixels ) function forcePosition()
{ {
if ( pixels >= 0 ) // Reset the binding so that it will reset the x position
position = ptof( pixels );
// FIXME: Binding can be lost because of dragging.
x = Qt.binding( function() { return ftop( position ); } ); x = Qt.binding( function() { return ftop( position ); } );
} }
function pixelPosition()
{
return ftop( position );
}
function resize() { function resize() {
// This function updates Backend // This function updates Backend
workflow.resizeClip( uuid, begin, end, position ); workflow.resizeClip( uuid, begin, end, position );
......
...@@ -47,31 +47,29 @@ Item { ...@@ -47,31 +47,29 @@ Item {
property var aClipInfo: null property var aClipInfo: null
property var vClipInfo: null property var vClipInfo: null
property int lastX: 0 property int lastPos: 0
property int deltaX: 0 property int deltaPos: 0
function findNewPosition( newX, target, dragSource, useMagneticMode ) {
var oldX = target.pixelPosition();
function findNewPosition( newPos, target, dragSource, useMagneticMode ) {
if ( useMagneticMode === true ) { if ( useMagneticMode === true ) {
var leastDistance = magneticMargin; var leastDistance = ptof( magneticMargin );
// Check two times // Check two times
for ( var k = 0; k < 2; ++k ) { for ( var k = 0; k < 2; ++k ) {
for ( var j = 0; j < markers.count; ++j ) { for ( var j = 0; j < markers.count; ++j ) {
var mx = ftop( markers.get( j ).position ); var mPos = markers.get( j ).position;
if ( Math.abs( newX - mx ) < leastDistance ) { if ( Math.abs( newPos - mPos ) < leastDistance ) {
leastDistance = Math.abs( newX - mx ); leastDistance = Math.abs( newPos - mPos );
newX = mx; newPos = mPos;
} }
else if ( Math.abs( newX + target.width - mx ) < leastDistance ) { else if ( Math.abs( newPos + target.length - 1 - mPos ) < leastDistance ) {
leastDistance = Math.abs( newX + target.width - mx ); leastDistance = Math.abs( newPos + target.length - 1 - mPos );
newX = mx - target.width; newPos = mPos - target.length + 1;
} }
} }
} }
// Magnet for the left edge of the timeline // Magnet for the left edge of the timeline
if ( newX < magneticMargin ) if ( newPos < ptof( magneticMargin ) )
newX = 0; newPos = 0;
} }
// Collision detection // Collision detection
...@@ -80,7 +78,7 @@ Item { ...@@ -80,7 +78,7 @@ Item {
if ( currentTrack ) if ( currentTrack )
var clips = currentTrack["clips"]; var clips = currentTrack["clips"];
else else
return oldX; return target.position;
for ( j = 0; j < clips.count + 2 && isCollided; ++j ) { for ( j = 0; j < clips.count + 2 && isCollided; ++j ) {
isCollided = false; isCollided = false;
for ( k = 0; k < clips.count; ++k ) { for ( k = 0; k < clips.count; ++k ) {
...@@ -89,30 +87,29 @@ Item { ...@@ -89,30 +87,29 @@ Item {
( clip.uuid === dragSource.uuid && target.newTrackId !== dragSource.newTrackId ) ( clip.uuid === dragSource.uuid && target.newTrackId !== dragSource.newTrackId )
) )
continue; continue;
var sw = target.width; // Width of the source clip var cPos = clip.uuid === dragSource.uuid ? ptof( dragSource.x ) : clip["position"];
var cx = clip.uuid === dragSource.uuid ? dragSource.x : ftop( clip["position"] ); var cEndPos = clip["position"] + clip["length"] - 1;
var cw = ftop( clip["end"] - clip["begin"] + 1);
// Set a right position if ( cEndPos >= newPos && newPos + target.length - 1 >= cPos )
//
// HACK: If magnetic mode, consider clips bigger
// but not if it's also selected because both of them will be moving
// and we want to keep the same distance between them as much as possible
var clipMargin = useMagneticMode && findClipItem( clip.uuid ).selected === false ? magneticMargin : 0;
if ( cx + cw > newX && newX + sw > cx )
isCollided = true; isCollided = true;
cw += clipMargin * 2 // HACK: If magnetic mode, consider clips bigger
cx -= clipMargin // but not if "clip" is also selected because both of them will be moving
if ( cx + cw > newX && newX + sw > cx ) { // and we want to keep the same distance between them as much as possible
if ( cx > newX ) { var clipMargin = useMagneticMode && findClipItem( clip.uuid ).selected === false ? ptof( magneticMargin ) : 0;
if ( cx - sw > 0 ) cPos += clipMargin * 2;
newX = cx - sw + clipMargin; cEndPos -= clipMargin;
if ( cEndPos >= newPos && newPos + target.length - 1 >= cPos ) {
if ( cPos >= newPos ) {
if ( cPos - target.length + 1 > 0 )
newPos = cPos - target.length + clipMargin;
else else
newX = oldX; newPos = target.position;
} else { } else {
newX = cx + cw - clipMargin; newPos = cEndPos - clipMargin + 1;
} }
} }
if ( isCollided ) if ( isCollided )
break; break;
} }
...@@ -124,13 +121,13 @@ Item { ...@@ -124,13 +121,13 @@ Item {
if ( clip.uuid === target.uuid || if ( clip.uuid === target.uuid ||
( clip.uuid === dragSource.uuid && target.newTrackId !== dragSource.newTrackId ) ) ( clip.uuid === dragSource.uuid && target.newTrackId !== dragSource.newTrackId ) )
continue; continue;
cx = clip.uuid === dragSource.uuid ? dragSource.x : ftop( clip["position"] ); cPos = clip.uuid === dragSource.uuid ? ptof( dragSource.x ) : clip["position"];
cw = ftop( clip["end"] - clip["begin"] + 1); cEndPos = clip["position"] + clip["length"] - 1;
newX = Math.max( newX, cx + cw ); newPos = Math.max( newPos, cEndPos + 1 );
} }
} }
return newX; return newPos;
} }
onDropped: { onDropped: {
...@@ -191,10 +188,10 @@ Item { ...@@ -191,10 +188,10 @@ Item {
vClipInfo = addClip( "Video", trackId, newClipInfo ); vClipInfo = addClip( "Video", trackId, newClipInfo );
} }
} }
lastX = drag.x; lastPos = ptof( drag.x );
} }
else { else {
lastX = drag.source.x; lastPos = ptof( drag.source.x );
// HACK: Call onPositoinChanged forcely here. // HACK: Call onPositoinChanged forcely here.
// x will be rounded so it won't affect actual its position. // x will be rounded so it won't affect actual its position.
drag.source.x = drag.source.x + 0.000001; drag.source.x = drag.source.x + 0.000001;
...@@ -256,16 +253,16 @@ Item { ...@@ -256,16 +253,16 @@ Item {
} }
} }
deltaX = drag.source.x - lastX; deltaPos = ptof( drag.source.x ) - lastPos;
} }
else else
deltaX = drag.x - lastX; deltaPos = ptof( drag.x ) - lastPos;
while ( toMove.length > 0 ) { while ( toMove.length > 0 ) {
target = findClipItem( toMove[0] ); target = findClipItem( toMove[0] );
var oldX = target.pixelPosition(); var oldPos = target.position;
var newX = findNewPosition( Math.max( oldX + deltaX, 0 ), target, drag.source, isMagneticMode ); var newPos = findNewPosition( Math.max( oldPos + deltaPos, 0 ), target, drag.source, isMagneticMode );
deltaX = newX - oldX; deltaPos = newPos - oldPos;
// Let's find newX of the linked clip // Let's find newX of the linked clip
for ( i = 0; i < target.linkedClips.length; ++i ) for ( i = 0; i < target.linkedClips.length; ++i )
...@@ -273,28 +270,28 @@ Item { ...@@ -273,28 +270,28 @@ Item {
var linkedClipItem = findClipItem( target.linkedClips[i] ); var linkedClipItem = findClipItem( target.linkedClips[i] );
if ( linkedClipItem ) { if ( linkedClipItem ) {
var newLinkedClipX = findNewPosition( newX, linkedClipItem, drag.source, isMagneticMode ); var newLinkedClipPos = findNewPosition( newPos, linkedClipItem, drag.source, isMagneticMode );
// If linked clip collides // If linked clip collides
if ( ptof( Math.abs( newLinkedClipX - newX ) ) !== 0 ) { if ( newLinkedClipPos !== newPos ) {
// Recalculate target's newX // Recalculate target's newX
// This time, don't use magnets // This time, don't use magnets
if ( isMagneticMode === true ) if ( isMagneticMode === true )
{ {
newLinkedClipX = findNewPosition( newX, linkedClipItem, drag.source, false ); newLinkedClipPos = findNewPosition( newPos, linkedClipItem, drag.source, false );
newX = findNewPosition( newX, target, drag.source, false ); newPos = findNewPosition( newPos, target, drag.source, false );
// And if newX collides again, we don't move // And if newX collides again, we don't move
if ( ptof( Math.abs( newLinkedClipX - newX ) ) !== 0 ) if ( newLinkedClipPos !== newPos )
deltaX = 0 deltaPos = 0
else else
deltaX = newX - oldX; deltaPos = newPos - oldPos;
} }
else else
deltaX = 0; deltaPos = 0;
} }
else else
deltaX = newX - oldX; deltaPos = newPos - oldPos;
var ind = toMove.indexOf( linkedClipItem.uuid ); var ind = toMove.indexOf( linkedClipItem.uuid );
if ( ind > 0 ) if ( ind > 0 )
...@@ -302,28 +299,28 @@ Item { ...@@ -302,28 +299,28 @@ Item {
} }
} }
newX = oldX + deltaX; newPos = oldPos + deltaPos;
toMove.splice( 0, 1 ); toMove.splice( 0, 1 );
} }
// END of while ( toMove.length > 0 ) // END of while ( toMove.length > 0 )
if ( deltaX === 0 && dMode === dropMode.Move ) { if ( deltaPos === 0 && dMode === dropMode.Move ) {
drag.source.setPixelPosition( drag.source.pixelPosition() ); drag.source.forcePosition(); // Use the original position
return; return;
} }
for ( i = 0; i < selectedClips.length; ++i ) { for ( i = 0; i < selectedClips.length; ++i ) {
target = findClipItem( selectedClips[i] ); target = findClipItem( selectedClips[i] );
newX = target.pixelPosition() + deltaX; newPos = target.position + deltaPos;
// We only want to update the length when the left edge of the timeline // We only want to update the length when the left edge of the timeline
// is exposed. // is exposed.
if ( sView.flickableItem.contentX + page.width > sView.width && if ( sView.flickableItem.contentX + page.width > sView.width &&
length < ptof( newX + target.width ) ) { length < newPos + target.length ) {
length = ptof( newX + target.width ); length = newPos + target.length;
} }
target.setPixelPosition( newX ); target.position = newPos;
// Scroll if needed // Scroll if needed
if ( drag.source === target || dMode === dropMode.New ) if ( drag.source === target || dMode === dropMode.New )
...@@ -331,9 +328,9 @@ Item { ...@@ -331,9 +328,9 @@ Item {
} }
if ( dMode === dropMode.Move ) if ( dMode === dropMode.Move )
lastX = drag.source.x; lastPos = ptof( drag.source.x );
else else
lastX = drag.x; lastPos = ptof( drag.x );
} }
} }
...@@ -351,6 +348,7 @@ Item { ...@@ -351,6 +348,7 @@ Item {
lastPosition: model.position lastPosition: model.position
begin: model.begin begin: model.begin
end: model.end end: model.end
length: model.length
clipInfo: model clipInfo: model
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment