changeset 1303:13f5f84fbfad

Collect the bits of bookkeeping for mouse wheel events, and use in all widgets
author Chris Cannam
date Fri, 22 Jun 2018 17:19:48 +0100
parents f3d3fab250ac
children a575dae05fbf
files files.pri widgets/LevelPanWidget.cpp widgets/LevelPanWidget.h widgets/Panner.cpp widgets/Panner.h widgets/Thumbwheel.cpp widgets/Thumbwheel.h widgets/WheelCounter.h
diffstat 8 files changed, 113 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/files.pri	Fri Jun 22 13:41:54 2018 +0100
+++ b/files.pri	Fri Jun 22 17:19:48 2018 +0100
@@ -87,6 +87,7 @@
            widgets/TipDialog.h \
            widgets/TransformFinder.h \
            widgets/UnitConverter.h \
+           widgets/WheelCounter.h \
            widgets/WidgetScale.h \
            widgets/WindowShapePreview.h \
            widgets/WindowTypeSelector.h
--- a/widgets/LevelPanWidget.cpp	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/LevelPanWidget.cpp	Fri Jun 22 17:19:48 2018 +0100
@@ -74,8 +74,7 @@
     m_editable(true),
     m_editing(false),
     m_includeMute(true),
-    m_includeHalfSteps(true),
-    m_pendingWheelAngle(0)
+    m_includeHalfSteps(true)
 {
     setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan"));
     setLevel(1.0);
@@ -284,45 +283,20 @@
 void
 LevelPanWidget::wheelEvent(QWheelEvent *e)
 {
-    e->accept();
-    
-    int dy = e->angleDelta().y();
-    if (dy == 0) {
+    int delta = m_wheelCounter.count(e);
+
+    if (delta == 0) {
         return;
     }
 
-    if (e->phase() == Qt::ScrollBegin ||
-        std::abs(dy) >= 120 ||
-        (dy > 0 && m_pendingWheelAngle < 0) ||
-        (dy < 0 && m_pendingWheelAngle > 0)) {
-        m_pendingWheelAngle = dy;
+    if (e->modifiers() & Qt::ControlModifier) {
+        m_pan = clampPan(m_pan + delta);
+        emitPanChanged();
+        update();
     } 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 {
-            m_notch += sign;
-            m_notch = clampNotch(m_notch);
-            emitLevelChanged();
-            update();
-        }
-
-        m_pendingWheelAngle -= sign * 120;
+        m_notch = clampNotch(m_notch + delta);
+        emitLevelChanged();
+        update();
     }
 }
 
--- a/widgets/LevelPanWidget.h	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/LevelPanWidget.h	Fri Jun 22 17:19:48 2018 +0100
@@ -17,6 +17,8 @@
 
 #include <QWidget>
 
+#include "WheelCounter.h"
+
 /**
  * A simple widget for coarse level and pan control.
  */
@@ -98,7 +100,8 @@
     bool m_editing;
     bool m_includeMute;
     bool m_includeHalfSteps;
-    int m_pendingWheelAngle;
+
+    WheelCounter m_wheelCounter;
 
     int clampNotch(int notch) const;
     int clampPan(int pan) const;
--- a/widgets/Panner.cpp	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/Panner.cpp	Fri Jun 22 17:19:48 2018 +0100
@@ -64,6 +64,12 @@
 void
 Panner::scroll(bool up)
 {
+    scroll(up, 1);
+}
+
+void
+Panner::scroll(bool up, int count)
+{
     float unit = m_scrollUnit;
     if (unit == 0.f) {
         unit = float(m_rectHeight) / (6 * float(height()));
@@ -71,9 +77,9 @@
     }
 
     if (!up) {
-        m_rectY += unit;
+        m_rectY += unit * count;
     } else {
-        m_rectY -= unit;
+        m_rectY -= unit * count;
     }
 
     normalise();
@@ -134,7 +140,8 @@
 void
 Panner::wheelEvent(QWheelEvent *e)
 {
-    scroll(e->delta() > 0);
+    int delta = m_wheelCounter.count(e);
+    scroll(delta > 0, abs(delta));
 }
 
 void
--- a/widgets/Panner.h	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/Panner.h	Fri Jun 22 17:19:48 2018 +0100
@@ -13,11 +13,13 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _PANNER_H_
-#define _PANNER_H_
+#ifndef SV_PANNER_H
+#define SV_PANNER_H
 
 #include <QWidget>
 
+#include "WheelCounter.h"
+
 class Panner : public QWidget
 {
     Q_OBJECT
@@ -109,6 +111,12 @@
      */
     void scroll(bool up);
 
+    /**
+     * Move up (if up is true) or down a bit.  This is basically the
+     * same action as rolling the mouse wheel n notches.
+     */
+    void scroll(bool up, int n);
+
     void resetToDefault();
 
 protected:
@@ -145,6 +153,8 @@
     QPoint m_clickPos;
     float m_dragStartX;
     float m_dragStartY;
+
+    WheelCounter m_wheelCounter;
 };
 
 #endif
--- a/widgets/Thumbwheel.cpp	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/Thumbwheel.cpp	Fri Jun 22 17:19:48 2018 +0100
@@ -426,15 +426,13 @@
 void
 Thumbwheel::wheelEvent(QWheelEvent *e)
 {
-    int step = int(lrintf(m_speed));
-    if (step == 0) step = 1;
+    int delta = m_wheelCounter.count(e);
 
-    if (e->delta() > 0) {
-        setValue(m_value + step);
-    } else {
-        setValue(m_value - step);
+    if (delta == 0) {
+        return;
     }
-    
+
+    setValue(m_value + delta);
     emit valueChanged(getValue());
 }
 
--- a/widgets/Thumbwheel.h	Fri Jun 22 13:41:54 2018 +0100
+++ b/widgets/Thumbwheel.h	Fri Jun 22 17:19:48 2018 +0100
@@ -13,14 +13,16 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _THUMBWHEEL_H_
-#define _THUMBWHEEL_H_
+#ifndef SV_THUMBWHEEL_H
+#define SV_THUMBWHEEL_H
 
 #include <QWidget>
 #include <QImage>
 
 #include <map>
 
+#include "WheelCounter.h"
+
 class RangeMapper;
 
 class Thumbwheel : public QWidget
@@ -96,6 +98,7 @@
     bool m_showTooltip;
     RangeMapper *m_rangeMapper;
     QImage m_cache;
+    WheelCounter m_wheelCounter;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/widgets/WheelCounter.h	Fri Jun 22 17:19:48 2018 +0100
@@ -0,0 +1,65 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_WHEEL_COUNTER_H
+#define SV_WHEEL_COUNTER_H
+
+#include <QWheelEvent>
+
+/**
+ * Manage the little bit of tedious book-keeping associated with
+ * translating vertical wheel events into up/down notch counts
+ */
+class WheelCounter
+{
+public:
+    WheelCounter() : m_pendingWheelAngle(0) { }
+
+    ~WheelCounter() { }
+
+    int count(QWheelEvent *e) {
+        
+        e->accept();
+    
+        int delta = e->angleDelta().y();
+        if (delta == 0) {
+            return 0;
+        }
+
+        if (e->phase() == Qt::ScrollBegin ||
+            std::abs(delta) >= 120 ||
+            (delta > 0 && m_pendingWheelAngle < 0) ||
+            (delta < 0 && m_pendingWheelAngle > 0)) {
+            m_pendingWheelAngle = delta;
+        } else {
+            m_pendingWheelAngle += delta;
+        }
+
+        if (abs(m_pendingWheelAngle) >= 600) {
+            // Sometimes on Linux we're seeing absurdly extreme angles
+            // on the first wheel event -- discard those entirely
+            m_pendingWheelAngle = 0;
+            return 0;
+        }
+
+        int count = m_pendingWheelAngle / 120;
+        m_pendingWheelAngle -= count * 120;
+        return count;
+    }
+
+private:
+    int m_pendingWheelAngle;
+};
+
+#endif