changeset 826:43256b925e15 tonioni

Support horizontal two-finger scrolling on Mac, and adjust zoom rate on vertical scroll to make it less crazily fast
author Chris Cannam
date Fri, 18 Jul 2014 15:06:04 +0100
parents f7590917177c
children ea098f7565eb 8432d2551fb2
files view/Pane.cpp view/Pane.h
diffstat 2 files changed, 124 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/view/Pane.cpp	Fri Jul 18 11:07:40 2014 +0100
+++ b/view/Pane.cpp	Fri Jul 18 15:06:04 2014 +0100
@@ -78,6 +78,7 @@
     m_releasing(false),
     m_centreLineVisible(true),
     m_scaleWidth(0),
+    m_pendingWheelAngle(0),
     m_headsUpDisplay(0),
     m_vpan(0),
     m_hthumb(0),
@@ -2239,28 +2240,131 @@
 void
 Pane::wheelEvent(QWheelEvent *e)
 {
-    //cerr << "wheelEvent, delta " << e->delta() << endl;
-
-    int count = e->delta();
-
-    if (count > 0) {
-    if (count >= 120) count /= 120;
-    else count = 1;
-    } 
-
-    if (count < 0) {
-    if (count <= -120) count /= 120;
-    else count = -1;
+    cerr << "wheelEvent, delta " << e->delta() << ", angleDelta " << e->angleDelta().x() << "," << e->angleDelta().y() << ", pixelDelta " << e->pixelDelta().x() << "," << e->pixelDelta().y() << ", modifiers " << e->modifiers() << endl;
+
+    int dx = e->angleDelta().x();
+    int dy = e->angleDelta().y();
+
+    if (dx == 0 && dy == 0) {
+        return;
     }
 
-    if (e->modifiers() & Qt::ControlModifier) {
+    int d = dy;
+    bool horizontal = false;
+
+    if (abs(dx) > abs(dy)) {
+        d = dx;
+        horizontal = true;
+    } else if (e->modifiers() & Qt::ControlModifier) {
+        // treat a vertical wheel as horizontal
+        horizontal = true;
+    }
+
+    if (e->phase() == Qt::ScrollBegin ||
+        fabs(d) >= 120 ||
+        (d > 0 && m_pendingWheelAngle < 0) ||
+        (d < 0 && m_pendingWheelAngle > 0)) {
+        m_pendingWheelAngle = d;
+    } else {
+        m_pendingWheelAngle += d;
+    }
+
+    if (horizontal && e->pixelDelta().x() != 0) {
+
+        // Have fine pixel information: use it
+
+        wheelHorizontalFine(e->pixelDelta().x(), e->modifiers());
+    
+        m_pendingWheelAngle = 0;
+
+    } else {
+
+        // Coarse wheel information (or vertical zoom, which is
+        // necessarily coarse itself)
+
+        while (abs(m_pendingWheelAngle) >= 120) {
+
+            int sign = (m_pendingWheelAngle < 0 ? -1 : 1);
+
+            if (horizontal) {
+                wheelHorizontal(sign, e->modifiers());
+            } else {
+                wheelVertical(sign, e->modifiers());
+            }
+
+            m_pendingWheelAngle -= sign * 120;
+        }
+    }
+}
+
+void
+Pane::wheelVertical(int sign, Qt::KeyboardModifiers mods)
+{
+    cerr << "wheelVertical: sign = " << sign << endl;
+
+    if (mods & Qt::ShiftModifier) {
+
+        // Pan vertically
+
+        if (m_vpan) {
+            m_vpan->scroll(sign > 0);
+        }
+
+    } else if (mods & Qt::AltModifier) {
+
+        // Zoom vertically
+
+        if (m_vthumb) {
+            m_vthumb->scroll(sign > 0);
+        }
+
+    } else {
+
+        // Zoom in or out
+
+        int newZoomLevel = m_zoomLevel;
+  
+        if (sign > 0) {
+            if (newZoomLevel <= 2) {
+                newZoomLevel = 1;
+            } else {
+                newZoomLevel = getZoomConstraintBlockSize
+                    (newZoomLevel - 1, ZoomConstraint::RoundDown);
+            }
+        } else { // sign < 0
+            newZoomLevel = getZoomConstraintBlockSize
+                (newZoomLevel + 1, ZoomConstraint::RoundUp);
+        }
+    
+        if (newZoomLevel != m_zoomLevel) {
+            setZoomLevel(newZoomLevel);
+        }
+    }
+
+    emit paneInteractedWith();
+}
+
+void
+Pane::wheelHorizontal(int sign, Qt::KeyboardModifiers mods)
+{
+    cerr << "wheelHorizontal: sign = " << sign << endl;
 
     // Scroll left or right, rapidly
 
+    wheelHorizontalFine((width() / 4) * sign, mods);
+}
+
+void
+Pane::wheelHorizontalFine(int pixels, Qt::KeyboardModifiers)
+{
+    cerr << "wheelHorizontalFine: pixels = " << pixels << endl;
+
+    // Scroll left or right by a fixed number of pixels
+
     if (getStartFrame() < 0 && 
         getEndFrame() >= getModelsEndFrame()) return;
 
-    int delta = ((width() / 2) * count * m_zoomLevel);
+    int delta = (pixels * m_zoomLevel);
 
     if (m_centreFrame < delta) {
         setCentreFrame(0);
@@ -2270,49 +2374,6 @@
         setCentreFrame(m_centreFrame - delta);
     }
 
-    } else if (e->modifiers() & Qt::ShiftModifier) {
-
-        // Zoom vertically
-
-        if (m_vpan) {
-            m_vpan->scroll(e->delta() > 0);
-        }
-
-    } else if (e->modifiers() & Qt::AltModifier) {
-
-        // Zoom vertically
-
-        if (m_vthumb) {
-            m_vthumb->scroll(e->delta() > 0);
-        }
-
-    } else {
-
-    // Zoom in or out
-
-    int newZoomLevel = m_zoomLevel;
-  
-    while (count > 0) {
-        if (newZoomLevel <= 2) {
-        newZoomLevel = 1;
-        break;
-        }
-        newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, 
-                              ZoomConstraint::RoundDown);
-        --count;
-    }
-    
-    while (count < 0) {
-        newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1,
-                              ZoomConstraint::RoundUp);
-        ++count;
-    }
-    
-    if (newZoomLevel != m_zoomLevel) {
-        setZoomLevel(newZoomLevel);
-    }
-    }
-
     emit paneInteractedWith();
 }
 
--- a/view/Pane.h	Fri Jul 18 11:07:40 2014 +0100
+++ b/view/Pane.h	Fri Jul 18 15:06:04 2014 +0100
@@ -113,6 +113,10 @@
     virtual void dragEnterEvent(QDragEnterEvent *e);
     virtual void dropEvent(QDropEvent *e);
 
+    void wheelVertical(int sign, Qt::KeyboardModifiers);
+    void wheelHorizontal(int sign, Qt::KeyboardModifiers);
+    void wheelHorizontalFine(int pixels, Qt::KeyboardModifiers);
+
     void drawVerticalScale(QRect r, Layer *, QPainter &);
     void drawFeatureDescription(Layer *, QPainter &);
     void drawCentreLine(int, QPainter &, bool omitLine);
@@ -171,6 +175,8 @@
     int m_editingSelectionEdge;
     mutable int m_scaleWidth;
 
+    int m_pendingWheelAngle;
+
     enum DragMode {
         UnresolvedDrag,
         VerticalDrag,