# HG changeset patch # User Chris Cannam # Date 1405692364 -3600 # Node ID 43256b925e1509a0a07b38f30160ae72d6509dd5 # Parent f7590917177cca082dbee5a84ac42baab06bce4d Support horizontal two-finger scrolling on Mac, and adjust zoom rate on vertical scroll to make it less crazily fast diff -r f7590917177c -r 43256b925e15 view/Pane.cpp --- 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(); } diff -r f7590917177c -r 43256b925e15 view/Pane.h --- 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,