changeset 1302:f3d3fab250ac

Proper handling for wheel rotation distance
author Chris Cannam
date Fri, 22 Jun 2018 13:41:54 +0100
parents e8368466fa34
children 13f5f84fbfad
files widgets/LevelPanWidget.cpp widgets/LevelPanWidget.h
diffstat 2 files changed, 51 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/widgets/LevelPanWidget.cpp	Thu Jun 21 15:36:29 2018 +0100
+++ b/widgets/LevelPanWidget.cpp	Fri Jun 22 13:41:54 2018 +0100
@@ -74,7 +74,8 @@
     m_editable(true),
     m_editing(false),
     m_includeMute(true),
-    m_includeHalfSteps(true)
+    m_includeHalfSteps(true),
+    m_pendingWheelAngle(0)
 {
     setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan"));
     setLevel(1.0);
@@ -112,6 +113,14 @@
 }
 
 int
+LevelPanWidget::clampPan(int pan) const
+{
+    if (pan < -maxPan) pan = -maxPan;
+    if (pan > maxPan) pan = maxPan;
+    return pan;
+}
+
+int
 LevelPanWidget::audioLevelToNotch(float audioLevel) const
 {
     int notch = AudioLevel::multiplier_to_fader
@@ -151,8 +160,7 @@
 LevelPanWidget::audioPanToPan(float audioPan) const
 {
     int pan = int(round(audioPan * maxPan));
-    if (pan < -maxPan) pan = -maxPan;
-    if (pan > maxPan) pan = maxPan;
+    pan = clampPan(pan);
     return pan;
 }
 
@@ -276,34 +284,45 @@
 void
 LevelPanWidget::wheelEvent(QWheelEvent *e)
 {
-    if (e->modifiers() & Qt::ControlModifier) {
-        if (e->delta() > 0) {
-            if (m_pan < maxPan) {
-                ++m_pan;
-                emitPanChanged();
-                update();
-            }
+    e->accept();
+    
+    int dy = e->angleDelta().y();
+    if (dy == 0) {
+        return;
+    }
+
+    if (e->phase() == Qt::ScrollBegin ||
+        std::abs(dy) >= 120 ||
+        (dy > 0 && m_pendingWheelAngle < 0) ||
+        (dy < 0 && m_pendingWheelAngle > 0)) {
+        m_pendingWheelAngle = dy;
+    } else {
+        m_pendingWheelAngle += dy;
+    }
+
+    if (abs(m_pendingWheelAngle) >= 600) {
+        // discard absurd results
+        m_pendingWheelAngle = 0;
+        return;
+    }
+
+    while (abs(m_pendingWheelAngle) >= 120) {
+
+        int sign = (m_pendingWheelAngle < 0 ? -1 : 1);
+
+        if (e->modifiers() & Qt::ControlModifier) {
+            m_pan += sign;
+            m_pan = clampPan(m_pan);
+            emitPanChanged();
+            update();
         } else {
-            if (m_pan > -maxPan) {
-                --m_pan;
-                emitPanChanged();
-                update();
-            }
+            m_notch += sign;
+            m_notch = clampNotch(m_notch);
+            emitLevelChanged();
+            update();
         }
-    } else {
-        if (e->delta() > 0) {
-            if (m_notch < m_maxNotch) {
-                ++m_notch;
-                emitLevelChanged();
-                update();
-            }
-        } else {
-            if (m_notch > m_minNotch) {
-                --m_notch;
-                emitLevelChanged();
-                update();
-            }
-        }
+
+        m_pendingWheelAngle -= sign * 120;
     }
 }
 
@@ -330,8 +349,7 @@
     double cell = w / npan;
 
     int pan = int((loc.x() - rect.x()) / cell) - maxPan;
-    if (pan < -maxPan) pan = -maxPan;
-    if (pan > maxPan) pan = maxPan;
+    pan = clampPan(pan);
 
     return pan;
 }
--- a/widgets/LevelPanWidget.h	Thu Jun 21 15:36:29 2018 +0100
+++ b/widgets/LevelPanWidget.h	Fri Jun 22 13:41:54 2018 +0100
@@ -98,8 +98,10 @@
     bool m_editing;
     bool m_includeMute;
     bool m_includeHalfSteps;
+    int m_pendingWheelAngle;
 
     int clampNotch(int notch) const;
+    int clampPan(int pan) const;
 
     int audioLevelToNotch(float audioLevel) const;
     float notchToAudioLevel(int notch) const;