# HG changeset patch # User Chris Cannam # Date 1306336561 -3600 # Node ID 44cef6368690c08c33fe77fc025436397516e2f8 # Parent 75003687f3647d6a353b23c9487a2f5065ece7e0 Ensure drags are constrained to either horizontal or vertical once the user's primary direction has become clear, switching to free drag only if the user makes a big move in the other axis diff -r 75003687f364 -r 44cef6368690 src/panned.cpp --- a/src/panned.cpp Wed May 25 16:05:40 2011 +0100 +++ b/src/panned.cpp Wed May 25 16:16:01 2011 +0100 @@ -174,12 +174,55 @@ ev->accept(); m_dragging = true; m_lastDragPos = ev->pos(); + m_lastDragStart = ev->pos(); m_lastOrigin = QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()); m_velocity = QPointF(0, 0); m_dragTimer->start(m_dragTimerMs); + m_dragDirection = UnknownDrag; + } +} + +void +Panned::updateDragDirection(QPoint pos) +{ + if (m_dragDirection == FreeDrag) { + return; } + QPoint overall = pos - m_lastDragStart; + + int smallThreshold = 10; + int largeThreshold = 30; + int dx = qAbs(overall.x()); + int dy = qAbs(overall.y()); + + switch (m_dragDirection) { + + case UnknownDrag: + if (dx > smallThreshold) { + if (dy > smallThreshold) { + m_dragDirection = FreeDrag; + } else { + m_dragDirection = HorizontalDrag; + } + } else if (dy > smallThreshold) { + m_dragDirection = VerticalDrag; + } + break; + + case HorizontalDrag: + if (dy > largeThreshold) { + m_dragDirection = FreeDrag; + } + break; + + case VerticalDrag: + if (dx > largeThreshold) { + m_dragDirection = FreeDrag; + } + break; + }; } void @@ -191,11 +234,17 @@ } DEBUG << "Panned::mouseMoveEvent: dragging" << endl; ev->accept(); + updateDragDirection(ev->pos()); QScrollBar *hBar = horizontalScrollBar(); QScrollBar *vBar = verticalScrollBar(); QPoint delta = ev->pos() - m_lastDragPos; - hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x())); - vBar->setValue(vBar->value() - delta.y()); + if (m_dragDirection != VerticalDrag) { + hBar->setValue(hBar->value() + + (isRightToLeft() ? delta.x() : -delta.x())); + } + if (m_dragDirection != HorizontalDrag) { + vBar->setValue(vBar->value() - delta.y()); + } m_lastDragPos = ev->pos(); } @@ -235,10 +284,14 @@ DEBUG << "Panned::dragTimerTimeout: velocity adjusted to " << m_velocity << endl; m_lastOrigin = origin; //!!! need to store origin in floats - horizontalScrollBar()->setValue(m_lastOrigin.x() + - m_velocity.x() * m_dragTimerMs); - verticalScrollBar()->setValue(m_lastOrigin.y() + - m_velocity.y() * m_dragTimerMs); + if (m_dragDirection != VerticalDrag) { + horizontalScrollBar()->setValue(m_lastOrigin.x() + + m_velocity.x() * m_dragTimerMs); + } + if (m_dragDirection != HorizontalDrag) { + verticalScrollBar()->setValue(m_lastOrigin.y() + + m_velocity.y() * m_dragTimerMs); + } } } diff -r 75003687f364 -r 44cef6368690 src/panned.h --- a/src/panned.h Wed May 25 16:05:40 2011 +0100 +++ b/src/panned.h Wed May 25 16:16:01 2011 +0100 @@ -54,12 +54,22 @@ QRectF m_pannedRect; QPoint m_lastDragPos; + QPoint m_lastDragStart; QPoint m_lastOrigin; QPointF m_velocity; bool m_dragging; int m_dragTimerMs; QTimer *m_dragTimer; + enum DragDirection { + UnknownDrag, + HorizontalDrag, + VerticalDrag, + FreeDrag + }; + DragDirection m_dragDirection; + void updateDragDirection(QPoint); + virtual void mousePressEvent(QMouseEvent *); virtual void mouseMoveEvent(QMouseEvent *); virtual void mouseReleaseEvent(QMouseEvent *);