Mercurial > hg > easyhg
changeset 403:44cef6368690
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
author | Chris Cannam |
---|---|
date | Wed, 25 May 2011 16:16:01 +0100 |
parents | 75003687f364 |
children | 9510a32a96ab |
files | src/panned.cpp src/panned.h |
diffstat | 2 files changed, 69 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- 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); + } } }
--- 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 *);