Flickable: fix minXExtent/minYExtent when content is smaller than view

At the moment, defining leftMargin (or topMargin) and contentWidth
(or contentHeight) so that "leftMargin+contentWidth < flickable.width"
(or topMargin+contentHeight < flickable.height) leads to widthRatio
(or heightRatio) having value != 1.
The value should, however, be 1, as the content is completely visible
inside the view, margins included.

As a sideeffect, under the assumptions described above, it will now
not be possible to scroll the leftMargin (or topMargin) out of screen,
something which was possible (and it shouldn't have) before this fix.

Task-number: QTBUG-53726
Change-Id: I22426c8038e90a2cfc7445914206eae0e781a3fb
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Reviewed-by: Albert Astals Cid <albert.astals@canonical.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Andrea Bernabei 2016-05-31 14:21:44 +01:00 committed by Shawn Rutledge
parent 1b897195a1
commit 240c2ef60e
3 changed files with 49 additions and 2 deletions

View File

@ -1580,13 +1580,13 @@ qreal QQuickFlickable::minXExtent() const
qreal QQuickFlickable::maxXExtent() const
{
Q_D(const QQuickFlickable);
return qMin<qreal>(0, width() - vWidth() - d->hData.endMargin);
return qMin<qreal>(minXExtent(), width() - vWidth() - d->hData.endMargin);
}
/* returns -ve */
qreal QQuickFlickable::maxYExtent() const
{
Q_D(const QQuickFlickable);
return qMin<qreal>(0, height() - vHeight() - d->vData.endMargin);
return qMin<qreal>(minYExtent(), height() - vHeight() - d->vData.endMargin);
}
void QQuickFlickable::componentComplete()

View File

@ -0,0 +1,19 @@
import QtQuick 2.0
Flickable {
property double heightRatioIs: visibleArea.heightRatio
property double widthRatioIs: visibleArea.widthRatio
width: 200
height: 200
contentWidth: item.width
contentHeight: item.height
topMargin: 20
leftMargin: 40
Item {
id: item
width: 100
height: 100
}
}

View File

@ -95,6 +95,7 @@ private slots:
void movementFromProgrammaticFlick();
void cleanup();
void contentSize();
void ratios_smallContent();
private:
void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
@ -1817,6 +1818,33 @@ void tst_qquickflickable::contentSize()
QCOMPARE(chspy.count(), 1);
}
// QTBUG-53726
void tst_qquickflickable::ratios_smallContent()
{
QScopedPointer<QQuickView> window(new QQuickView);
window->setSource(testFileUrl("ratios_smallContent.qml"));
QTRY_COMPARE(window->status(), QQuickView::Ready);
QQuickViewTestUtil::centerOnScreen(window.data());
QQuickViewTestUtil::moveMouseAway(window.data());
window->setTitle(QTest::currentTestFunction());
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickItem *root = window->rootObject();
QVERIFY(root);
QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(root);
QVERIFY(obj != 0);
//doublecheck the item, as specified by contentWidth/Height, fits in the view
//use tryCompare to allow a bit of stabilization in component's properties
QTRY_COMPARE(obj->leftMargin() + obj->contentWidth() + obj->rightMargin() <= obj->width(), true);
QTRY_COMPARE(obj->topMargin() + obj->contentHeight() + obj->bottomMargin() <= obj->height(), true);
//the whole item fits in the flickable, heightRatio should be 1
QCOMPARE(obj->property("heightRatioIs").toDouble(), 1.);
QCOMPARE(obj->property("widthRatioIs").toDouble(), 1.);
}
QTEST_MAIN(tst_qquickflickable)
#include "tst_qquickflickable.moc"