diff options
author | Martin Jones <martin.jones@jollamobile.com> | 2013-11-27 16:13:29 +1000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-05 00:57:45 +0100 |
commit | 268f4615dcf19aad3603833af83ba28eca886aa5 (patch) | |
tree | b96dd3d0d81eda0e36d8320cd49d546ca95cb37c /src/quick | |
parent | 7e3578728edec27301b71f5ab5d7b43874ae35a2 (diff) |
Fix Flickable StopAtBounds drag over, back, over behavior.
A Flickable with StopAtBounds failed when:
1. position on a boundary.
Without lifting your finger:
2. attempt to drag beyond the boundary -> doesn't drag
3. drag back to initiate dragging
4. attempt to quickly drag beyond the boundary.
After 4, the view should be back on the boundary, but it could get
stuck a little short of the boundary.
Change-Id: I9bfbb4293f4d464bddb97c5c37e9bb91ed7d48e4
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ae174d86e0..5b0c1c6756 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -508,16 +508,27 @@ void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExt data.vTime = timeline.time(); } +static bool fuzzyLessThanOrEqualTo(qreal a, qreal b) +{ + if (a == 0.0 || b == 0.0) { + // qFuzzyCompare is broken + a += 1.0; + b += 1.0; + } + return a <= b || qFuzzyCompare(a, b); +} + void QQuickFlickablePrivate::updateBeginningEnd() { Q_Q(QQuickFlickable); bool atBoundaryChange = false; // Vertical - const int maxyextent = int(-q->maxYExtent()); + const qreal maxyextent = -q->maxYExtent(); + const qreal minyextent = -q->minYExtent(); const qreal ypos = -vData.move.value(); - bool atBeginning = (ypos <= -q->minYExtent()); - bool atEnd = (maxyextent <= ypos); + bool atBeginning = fuzzyLessThanOrEqualTo(ypos, minyextent); + bool atEnd = fuzzyLessThanOrEqualTo(maxyextent, ypos); if (atBeginning != vData.atBeginning) { vData.atBeginning = atBeginning; @@ -529,10 +540,11 @@ void QQuickFlickablePrivate::updateBeginningEnd() } // Horizontal - const int maxxextent = int(-q->maxXExtent()); + const qreal maxxextent = -q->maxXExtent(); + const qreal minxextent = -q->minXExtent(); const qreal xpos = -hData.move.value(); - atBeginning = (xpos <= -q->minXExtent()); - atEnd = (maxxextent <= xpos); + atBeginning = fuzzyLessThanOrEqualTo(xpos, minxextent); + atEnd = fuzzyLessThanOrEqualTo(maxxextent, xpos); if (atBeginning != hData.atBeginning) { hData.atBeginning = atBeginning; @@ -1046,17 +1058,20 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) // the estimate to be altered const qreal minY = vData.dragMinBound + vData.startMargin; const qreal maxY = vData.dragMaxBound - vData.endMargin; - if (newY > minY) - newY = minY + (newY - minY) / 2; - if (newY < maxY && maxY - minY <= 0) - newY = maxY + (newY - maxY) / 2; - if (boundsBehavior == QQuickFlickable::StopAtBounds && newY <= maxY) { - newY = maxY; - rejectY = vData.pressPos == maxY && dy < 0; - } - if (boundsBehavior == QQuickFlickable::StopAtBounds && newY >= minY) { - newY = minY; - rejectY = vData.pressPos == minY && dy > 0; + if (boundsBehavior == QQuickFlickable::StopAtBounds) { + if (newY <= maxY) { + newY = maxY; + rejectY = vData.pressPos == maxY && vData.move.value() == maxY && dy < 0; + } + if (newY >= minY) { + newY = minY; + rejectY = vData.pressPos == minY && vData.move.value() == minY && dy > 0; + } + } else { + if (newY > minY) + newY = minY + (newY - minY) / 2; + if (newY < maxY && maxY - minY <= 0) + newY = maxY + (newY - maxY) / 2; } if (!rejectY && stealMouse && dy != 0.0) { clearTimeline(); @@ -1077,17 +1092,20 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) qreal newX = dx + hData.pressPos - hData.dragStartOffset; const qreal minX = hData.dragMinBound + hData.startMargin; const qreal maxX = hData.dragMaxBound - hData.endMargin; - if (newX > minX) - newX = minX + (newX - minX) / 2; - if (newX < maxX && maxX - minX <= 0) - newX = maxX + (newX - maxX) / 2; - if (boundsBehavior == QQuickFlickable::StopAtBounds && newX <= maxX) { - newX = maxX; - rejectX = hData.pressPos == maxX && dx < 0; - } - if (boundsBehavior == QQuickFlickable::StopAtBounds && newX >= minX) { - newX = minX; - rejectX = hData.pressPos == minX && dx > 0; + if (boundsBehavior == QQuickFlickable::StopAtBounds) { + if (newX <= maxX) { + newX = maxX; + rejectX = hData.pressPos == maxX && hData.move.value() == maxX && dx < 0; + } + if (newX >= minX) { + newX = minX; + rejectX = hData.pressPos == minX && hData.move.value() == minX && dx > 0; + } + } else { + if (newX > minX) + newX = minX + (newX - minX) / 2; + if (newX < maxX && maxX - minX <= 0) + newX = maxX + (newX - maxX) / 2; } if (!rejectX && stealMouse && dx != 0.0) { |