1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-24 16:01:16 +02:00

Bug 1290 - "Split New" clips cannot be dragged back into the track they came from.

Earlier fix was broken and allowed clips to overlap.  Updated code:
- Checks that the modified slide amount is legal, against ALL clips, not just against later clips in the array.
- Computes tolerance correctly.
- Typically uses tolerance just once.
- Moves selection with clip
- Only restarts sliding with a 'clean slate' IF there was room on the original track.

Previously the code could reject a move to a new track, and then mistakenly allow just the horizontal part of the move on the original track(s), even with a clip blocking the way.
This commit is contained in:
James Crook 2017-08-23 18:15:00 +01:00
parent 33d9a130c8
commit 1b4999d0d3
2 changed files with 50 additions and 12 deletions

View File

@ -2382,16 +2382,18 @@ bool WaveTrack::CanInsertClip(WaveClip* clip, double &slideBy, double &toleranc
{
// clips overlap.
// Try to rescue it.
// The rescue logic is not perfect, but
// a) will not move the clip by more than once
// b) is OK in simple scenarios.
// The rescue logic is not perfect, and will typically
// move the clip at most once.
// We divide by 1000 rather than set to 0, to allow for
// a second 'micro move' that is really about rounding error.
if( -d1 < tolerance ){
// right edge of clip overlaps slightly.
// slide clip left a small amount.
slideBy +=d1;
d2 += d1;
tolerance /=1000;
}
if( -d2 < tolerance ){
} else if( -d2 < tolerance ){
// left edge of clip overlaps slightly.
// slide clip right a small amount.
slideBy -= d2;
tolerance /=1000;
}

View File

@ -711,7 +711,7 @@ UIHandle::Result TimeShiftHandle::Drag
// The tolerance is supposed to be the time for one pixel, i.e. one pixel tolerance
// at current zoom.
double slide = desiredSlideAmount; // remember amount requested.
double tolerance = viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x+1);
double tolerance = viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x);
// The desiredSlideAmount may change and the tolerance may get used up.
for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size();
@ -722,24 +722,61 @@ UIHandle::Result TimeShiftHandle::Drag
ok = trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance);
}
if( ok ) {
// fits ok, but desiredSlideAmount could have been updated to get the clip to fit.
// Check again, in the new position, this time with zero tolerance.
tolerance = 0.0;
for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size();
ok && ii < nn; ++ii) {
TrackClip &trackClip = mClipMoveState.capturedClipArray[ii];
WaveClip *const pSrcClip = trackClip.clip;
if (pSrcClip)
ok = trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance);
}
}
if (!ok) {
// Failure, even with using tolerance.
// Failure -- put clips back where they were
// Failure -- we'll put clips back where they were
// ok will next indicate if a horizontal slide is OK.
ok = true; // assume slide is OK.
tolerance = 0.0;
desiredSlideAmount = slide;
for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size();
ii < nn; ++ii) {
TrackClip &trackClip = mClipMoveState.capturedClipArray[ii];
WaveClip *const pSrcClip = trackClip.clip;
if (pSrcClip){
// back to the track it came from...
trackClip.dstTrack = static_cast<WaveTrack*>(trackClip.track);
ok = ok && trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance);
}
}
for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size();
ii < nn; ++ii) {
TrackClip &trackClip = mClipMoveState.capturedClipArray[ii];
WaveClip *const pSrcClip = trackClip.clip;
if (pSrcClip){
// Attempt to move to a new track did not work.
// Put the clip back appropriately shifted!
trackClip.holder->Offset(slide);
if( ok)
trackClip.holder->Offset(slide);
// Assume track is wave because it has a clip
static_cast<WaveTrack*>(trackClip.track)->
AddClip(std::move(trackClip.holder));
}
}
// Make the offset permanent; start from a "clean slate"
mMouseClickX = event.m_x;
if( ok ) {
mMouseClickX = event.m_x;
if (mClipMoveState.capturedClipIsSelection) {
// Slide the selection, too
viewInfo.selectedRegion.move( slide );
}
mClipMoveState.hSlideAmount = 0;
}
return RefreshAll;
}
else {
@ -778,7 +815,6 @@ UIHandle::Result TimeShiftHandle::Drag
viewInfo.selectedRegion.move( mClipMoveState.hSlideAmount );
}
if (slidVertically) {
// NEW origin
mClipMoveState.hSlideAmount = 0;