diff --git a/common/view/zoom_controller.cpp b/common/view/zoom_controller.cpp index 9320585a1a..b69bb96693 100644 --- a/common/view/zoom_controller.cpp +++ b/common/view/zoom_controller.cpp @@ -66,7 +66,7 @@ ACCELERATING_ZOOM_CONTROLLER::ACCELERATING_ZOOM_CONTROLLER( m_timestampProv = m_ownTimestampProv.get(); } - m_lastTimestamp = m_timestampProv->GetTimestamp(); + m_prevTimestamp = m_timestampProv->GetTimestamp(); } @@ -76,9 +76,9 @@ double ACCELERATING_ZOOM_CONTROLLER::GetScaleForRotation( int aRotation ) const double minStep = 1.05; const auto timestamp = m_timestampProv->GetTimestamp(); - auto timeDiff = std::chrono::duration_cast( timestamp - m_lastTimestamp ); + auto timeDiff = std::chrono::duration_cast( timestamp - m_prevTimestamp ); - m_lastTimestamp = timestamp; + m_prevTimestamp = timestamp; wxLogTrace( traceZoomScroll, wxString::Format( "Rot %d, time diff: %ldms", aRotation, (long)timeDiff.count() ) ); @@ -86,7 +86,8 @@ double ACCELERATING_ZOOM_CONTROLLER::GetScaleForRotation( int aRotation ) double zoomScale; // Set scaling speed depending on scroll wheel event interval - if( timeDiff < m_accTimeout ) + if( timeDiff < m_accTimeout + && ( (aRotation > 0) == m_prevRotationPositive ) ) { zoomScale = ( 2.05 * m_scale / 5.0 ) - timeDiff / m_accTimeout; @@ -100,6 +101,7 @@ double ACCELERATING_ZOOM_CONTROLLER::GetScaleForRotation( int aRotation ) { zoomScale = ( aRotation > 0 ) ? minStep : 1 / minStep; } + m_prevRotationPositive = aRotation > 0; wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoomScale ) ); diff --git a/include/view/zoom_controller.h b/include/view/zoom_controller.h index 85c33c4ebb..738bced10a 100644 --- a/include/view/zoom_controller.h +++ b/include/view/zoom_controller.h @@ -120,12 +120,15 @@ private: ///< Any provider owned by this class (the default one, if used). std::unique_ptr m_ownTimestampProv; - ///< The timestamp of the last event. - TIME_PT m_lastTimestamp; + ///< The timestamp of the previous event. + TIME_PT m_prevTimestamp; ///< The timeout value. TIMEOUT m_accTimeout; + /// Previous rotation was positive. + bool m_prevRotationPositive = false; + /// A multiplier for the minimum zoom step size double m_scale; }; diff --git a/qa/unittests/common/view/test_zoom_controller.cpp b/qa/unittests/common/view/test_zoom_controller.cpp index 38bc1b4c7e..356889baa1 100644 --- a/qa/unittests/common/view/test_zoom_controller.cpp +++ b/qa/unittests/common/view/test_zoom_controller.cpp @@ -116,9 +116,9 @@ struct ACCEL_ZOOM_CASE static const std::vector accel_cases = { // Scrolls widely spaced, just go up and down by a constant factor - { 500, { 0, 1000, 2000, 3000 }, { 120, 120, -120 }, { 1.05, 1.05, 1 / 1.05 } }, - // Close scrolls - acceleration on the latter - { 500, { 0, 1000, 1100 }, { 120, 120 }, { 1.05, 2.05 } }, + { 500, { 0, 1000, 2000, 3000, 4000 }, { 120, 120, -120, -120 }, { 1.05, 1.05, 1 / 1.05, 1 / 1.05 } }, + // Close scrolls - acceleration, apart from when changing direction + { 500, { 0, 1000, 1100, 1200, 1300, 1400 }, { 120, 120, -120, -120, 120 }, { 1.05, 2.05, 1 / 1.05, 1 / 2.05, 1.05 } }, };