From 8655d50bb25b8fa5bd02026508b19be7a86482a7 Mon Sep 17 00:00:00 2001 From: IanCaio Date: Fri, 25 Dec 2020 09:28:49 -0300 Subject: [PATCH] Fixes bug with pasting of TCOs (#5840) (#5847) * Fixes bug with pasting of TCOs (#5840) TimePos::quantize works for negative values, but ends up snapping the TCO to the opposite direction. This is because the snapping happens in the direction of the origin, which is left for positive values and right for negative values. That wasn't accounted for in the pasteSelection method and we ended up with wrong positions when pasting before the TCO(s) we copied. This PR fixes the issue by ensuring that we snap in the same direction when halfway through an interval, regardless of negative or positive offset. * Fixes a calculation on TimePos::quantize Since we are working with integers, using "offset / (interval/2)" would be problematic if interval was odd. We instead multiply both sides by two and use "(2 * offset) / interval" to obtain the result for snapUp. --- src/core/TimePos.cpp | 7 ++++++- src/gui/widgets/TrackContentWidget.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/TimePos.cpp b/src/core/TimePos.cpp index 9d25b9ce1..4a22a1eb9 100644 --- a/src/core/TimePos.cpp +++ b/src/core/TimePos.cpp @@ -72,7 +72,12 @@ TimePos TimePos::quantize(float bars) const //Offset from the lower position int offset = m_ticks % interval; //1 if we should snap up, 0 if we shouldn't - int snapUp = offset / (interval / 2); + // Ternary expression is making sure that the snap happens in the direction to + // the right even if m_ticks is negative and the offset is exactly half-way + // More details on issue #5840 and PR #5847 + int snapUp = ((2 * offset) == -interval) + ? 0 + : (2 * offset) / interval; return (lowPos + snapUp) * interval; } diff --git a/src/gui/widgets/TrackContentWidget.cpp b/src/gui/widgets/TrackContentWidget.cpp index 5dd237948..11ac3a60f 100644 --- a/src/gui/widgets/TrackContentWidget.cpp +++ b/src/gui/widgets/TrackContentWidget.cpp @@ -477,7 +477,7 @@ bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, b // All patterns should be offset the same amount as the grabbed pattern TimePos offset = TimePos(tcoPos - grabbedTCOPos); // Users expect clips to "fall" backwards, so bias the offset - offset = offset - TimePos::ticksPerBar() * snapSize / 2; + offset -= TimePos::ticksPerBar() * snapSize / 2; // The offset is quantized (rather than the positions) to preserve fine adjustments offset = offset.quantize(snapSize);