diff --git a/src/libs/tracing/timelinerenderer.cpp b/src/libs/tracing/timelinerenderer.cpp index 07abb071445..ace3efe3ffe 100644 --- a/src/libs/tracing/timelinerenderer.cpp +++ b/src/libs/tracing/timelinerenderer.cpp @@ -183,23 +183,28 @@ void TimelineRenderer::wheelEvent(QWheelEvent *event) // ctrl-wheel means zoom if (event->modifiers() & Qt::ControlModifier) { event->setAccepted(true); + if (event->angleDelta().y() == 0) + return; TimelineZoomControl *zoom = zoomer(); - int degrees = (event->angleDelta().x() + event->angleDelta().y()) / 8; - const qint64 circle = 360; - qint64 mouseTime = event->position().toPoint().x() * zoom->windowDuration() / width() + - zoom->windowStart(); - qint64 beforeMouse = (mouseTime - zoom->rangeStart()) * (circle - degrees) / circle; - qint64 afterMouse = (zoom->rangeEnd() - mouseTime) * (circle - degrees) / circle; - - qint64 newStart = qBound(zoom->traceStart(), zoom->traceEnd(), mouseTime - beforeMouse); - if (newStart + zoom->minimumRangeLength() > zoom->traceEnd()) - return; // too close to trace end - - qint64 newEnd = qBound(newStart + zoom->minimumRangeLength(), zoom->traceEnd(), - mouseTime + afterMouse); - - zoom->setRange(newStart, newEnd); + // Handle similar to text editor, but avoid floats. + // angleDelta of 120 is considered a 10% change in zoom. + const qint64 delta = event->angleDelta().y(); + const qint64 newDuration = qBound(zoom->minimumRangeLength(), + zoom->rangeDuration() * 1200 / (1200 + delta), + std::max(zoom->minimumRangeLength(), + zoom->traceDuration())); + const qint64 mouseTime = event->position().toPoint().x() * zoom->windowDuration() / width() + + zoom->windowStart(); + // Try to keep mouseTime where it was in relation to the shown range, + // but keep within traceStart/End + const qint64 newStart + = qBound(zoom->traceStart(), + mouseTime + - newDuration * /*rest is mouse time position [0,1] in range:*/ + (mouseTime - zoom->rangeStart()) / zoom->rangeDuration(), + std::max(zoom->traceStart(), zoom->traceEnd() - newDuration)); + zoom->setRange(newStart, newStart + newDuration); } else { TimelineAbstractRenderer::wheelEvent(event); }