diff options
-rw-r--r-- | src/quicktemplates2/qquickscrollbar.cpp | 19 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_scrollbar.qml | 34 |
2 files changed, 45 insertions, 8 deletions
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index f118a2b3..25d2f087 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -199,12 +199,17 @@ void QQuickScrollBarPrivate::resizeContent() if (!contentItem) return; + // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size + // - positive overshoot (pos + size > 1): clamp the size to 1-pos + const qreal clampedSize = qBound<qreal>(0, size + qMin<qreal>(0, position), 1.0 - position); + const qreal clampedPos = qBound<qreal>(0, position, 1.0 - clampedSize); + if (orientation == Qt::Horizontal) { - contentItem->setPosition(QPointF(q->leftPadding() + position * q->availableWidth(), q->topPadding())); - contentItem->setSize(QSizeF(q->availableWidth() * size, q->availableHeight())); + contentItem->setPosition(QPointF(q->leftPadding() + clampedPos * q->availableWidth(), q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth() * clampedSize, q->availableHeight())); } else { - contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + position * q->availableHeight())); - contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * size)); + contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + clampedPos * q->availableHeight())); + contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * clampedSize)); } } @@ -275,7 +280,6 @@ qreal QQuickScrollBar::size() const void QQuickScrollBar::setSize(qreal size) { Q_D(QQuickScrollBar); - size = qBound<qreal>(0.0, size, 1.0 - d->position); if (qFuzzyCompare(d->size, size)) return; @@ -304,7 +308,6 @@ qreal QQuickScrollBar::position() const void QQuickScrollBar::setPosition(qreal position) { Q_D(QQuickScrollBar); - position = qBound<qreal>(0.0, position, 1.0 - d->size); if (qFuzzyCompare(d->position, position)) return; @@ -531,7 +534,7 @@ void QQuickScrollBar::increase() qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; bool wasActive = d->active; setActive(true); - setPosition(d->position + step); + setPosition(qMin<qreal>(1.0 - d->size, d->position + step)); setActive(wasActive); } @@ -548,7 +551,7 @@ void QQuickScrollBar::decrease() qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; bool wasActive = d->active; setActive(true); - setPosition(d->position - step); + setPosition(qMax<qreal>(0.0, d->position - step)); setActive(wasActive); } diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index 0a7fab9e..cf1a8559 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -492,4 +492,38 @@ TestCase { compare(control.visible, true) verify(control.state === "active" || control.contentItem.state === "active") } + + function test_overshoot() { + var container = flickable.createObject(testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollBar.createObject(container, {size: 0.5}) + container.ScrollBar.vertical = vertical + + var horizontal = scrollBar.createObject(container, {size: 0.5}) + container.ScrollBar.horizontal = horizontal + + // negative vertical overshoot (pos < 0) + vertical.position = -0.1 + compare(vertical.contentItem.y, vertical.topPadding) + compare(vertical.contentItem.height, 0.4 * vertical.availableHeight) + + // positive vertical overshoot (pos + size > 1) + vertical.position = 0.8 + compare(vertical.contentItem.y, vertical.topPadding + 0.8 * vertical.availableHeight) + compare(vertical.contentItem.height, 0.2 * vertical.availableHeight) + + // negative horizontal overshoot (pos < 0) + horizontal.position = -0.1 + compare(horizontal.contentItem.x, horizontal.leftPadding) + compare(horizontal.contentItem.width, 0.4 * horizontal.availableWidth) + + // positive horizontal overshoot (pos + size > 1) + horizontal.position = 0.8 + compare(horizontal.contentItem.x, horizontal.leftPadding + 0.8 * horizontal.availableWidth) + compare(horizontal.contentItem.width, 0.2 * horizontal.availableWidth) + + container.destroy() + } } |