diff options
author | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2015-07-29 12:15:02 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2015-08-07 08:19:56 +0000 |
commit | 3aeb0261ad809220965d5bea57109911c1dbb3cb (patch) | |
tree | 40252e315b2bf1e99b0ff515baffaf9b56ede898 | |
parent | bc42a1e691927049e9691cc8403a993e23bc4a23 (diff) |
Add padding test to Tumbler auto tests.
Change-Id: I78d580c28287fecaf287c4634a166c44926c48fb
Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
-rw-r--r-- | src/extras/qquicktumbler.cpp | 47 | ||||
-rw-r--r-- | src/extras/qquicktumbler_p.h | 3 | ||||
-rw-r--r-- | src/imports/extras/Tumbler.qml | 2 | ||||
-rw-r--r-- | tests/auto/extras/data/tst_tumbler.qml | 103 |
4 files changed, 134 insertions, 21 deletions
diff --git a/src/extras/qquicktumbler.cpp b/src/extras/qquicktumbler.cpp index f278c9ca..ba8576b4 100644 --- a/src/extras/qquicktumbler.cpp +++ b/src/extras/qquicktumbler.cpp @@ -85,8 +85,8 @@ public: QQmlComponent *delegate; int visibleItemCount; - void updateItemHeights(); - void updateItemWidths(); + void _q_updateItemHeights(); + void _q_updateItemWidths(); void itemChildAdded(QQuickItem *, QQuickItem *) Q_DECL_OVERRIDE; void itemChildRemoved(QQuickItem *, QQuickItem *) Q_DECL_OVERRIDE; @@ -103,10 +103,9 @@ static QList<QQuickItem *> contentItemChildItems(QQuickItem *contentItem) } namespace { - static inline qreal delegateHeight(const QQuickItem *contentItem, qreal topPadding, qreal bottomPadding, int visibleItemCount) + static inline qreal delegateHeight(const QQuickTumbler *tumbler) { - // TODO: can we/do we want to support spacing? - return (contentItem->height()/* - qMax(0, itemCount - 1) * spacing*/ - topPadding - bottomPadding) / visibleItemCount; + return tumbler->availableHeight() / tumbler->visibleItemCount(); } enum ContentItemType { @@ -148,35 +147,45 @@ namespace { } } -void QQuickTumblerPrivate::updateItemHeights() +void QQuickTumblerPrivate::_q_updateItemHeights() { - const qreal itemHeight = delegateHeight(contentItem, topPadding, bottomPadding, visibleItemCount); + // Can't use our own private padding members here, as the padding property might be set, + // which doesn't affect them, only their getters. + Q_Q(const QQuickTumbler); + const qreal itemHeight = delegateHeight(q); foreach (QQuickItem *childItem, contentItemChildItems(contentItem)) childItem->setHeight(itemHeight); } -void QQuickTumblerPrivate::updateItemWidths() +void QQuickTumblerPrivate::_q_updateItemWidths() { + Q_Q(const QQuickTumbler); + const qreal availableWidth = q->availableWidth(); foreach (QQuickItem *childItem, contentItemChildItems(contentItem)) - childItem->setWidth(width); + childItem->setWidth(availableWidth); } void QQuickTumblerPrivate::itemChildAdded(QQuickItem *, QQuickItem *) { - updateItemWidths(); - updateItemHeights(); + _q_updateItemWidths(); + _q_updateItemHeights(); } void QQuickTumblerPrivate::itemChildRemoved(QQuickItem *, QQuickItem *) { - updateItemWidths(); - updateItemHeights(); + _q_updateItemWidths(); + _q_updateItemHeights(); } QQuickTumbler::QQuickTumbler(QQuickItem *parent) : QQuickControl(*(new QQuickTumblerPrivate), parent) { setActiveFocusOnTab(true); + + connect(this, SIGNAL(leftPaddingChanged()), this, SLOT(_q_updateItemWidths())); + connect(this, SIGNAL(rightPaddingChanged()), this, SLOT(_q_updateItemWidths())); + connect(this, SIGNAL(topPaddingChanged()), this, SLOT(_q_updateItemHeights())); + connect(this, SIGNAL(bottomPaddingChanged()), this, SLOT(_q_updateItemHeights())); } QQuickTumbler::~QQuickTumbler() @@ -279,7 +288,7 @@ void QQuickTumbler::setVisibleItemCount(int visibleItemCount) Q_D(QQuickTumbler); if (visibleItemCount != d->visibleItemCount) { d->visibleItemCount = visibleItemCount; - d->updateItemHeights(); + d->_q_updateItemHeights(); emit visibleItemCountChanged(); } } @@ -301,18 +310,18 @@ void QQuickTumbler::geometryChanged(const QRectF &newGeometry, const QRectF &old QQuickControl::geometryChanged(newGeometry, oldGeometry); - d->updateItemHeights(); + d->_q_updateItemHeights(); if (newGeometry.width() != oldGeometry.width()) - d->updateItemWidths(); + d->_q_updateItemWidths(); } void QQuickTumbler::componentComplete() { Q_D(QQuickTumbler); QQuickControl::componentComplete(); - d->updateItemHeights(); - d->updateItemWidths(); + d->_q_updateItemHeights(); + d->_q_updateItemWidths(); } void QQuickTumbler::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) @@ -477,7 +486,7 @@ void QQuickTumblerAttachedPrivate::_q_calculateDisplacement() displacement += tumbler->count(); } else { const qreal contentY = tumbler->contentItem()->property("contentY").toReal(); - const qreal delegateH = delegateHeight(tumbler->contentItem(), tumbler->topPadding(), tumbler->bottomPadding(), tumbler->visibleItemCount()); + const qreal delegateH = delegateHeight(tumbler); const qreal preferredHighlightBegin = tumbler->contentItem()->property("preferredHighlightBegin").toReal(); // Tumbler's displacement goes from negative at the top to positive towards the bottom, so we must switch this around. const qreal reverseDisplacement = (contentY + preferredHighlightBegin) / delegateH; diff --git a/src/extras/qquicktumbler_p.h b/src/extras/qquicktumbler_p.h index 4dc29ba9..ecefad18 100644 --- a/src/extras/qquicktumbler_p.h +++ b/src/extras/qquicktumbler_p.h @@ -106,6 +106,9 @@ protected: private: Q_DISABLE_COPY(QQuickTumbler) Q_DECLARE_PRIVATE(QQuickTumbler) + + Q_PRIVATE_SLOT(d_func(), void _q_updateItemWidths()) + Q_PRIVATE_SLOT(d_func(), void _q_updateItemHeights()) }; Q_DECLARE_TYPEINFO(QQuickTumbler, Q_COMPLEX_TYPE); diff --git a/src/imports/extras/Tumbler.qml b/src/imports/extras/Tumbler.qml index 4fba84bf..7dc7ba1f 100644 --- a/src/imports/extras/Tumbler.qml +++ b/src/imports/extras/Tumbler.qml @@ -74,7 +74,7 @@ AbstractTumbler { } } - property real delegateHeight: (control.height - control.topPadding - control.bottomPadding) / control.visibleItemCount + property real delegateHeight: control.availableHeight / control.visibleItemCount } //! [contentItem] } diff --git a/tests/auto/extras/data/tst_tumbler.qml b/tests/auto/extras/data/tst_tumbler.qml index 24686646..928d53fa 100644 --- a/tests/auto/extras/data/tst_tumbler.qml +++ b/tests/auto/extras/data/tst_tumbler.qml @@ -51,7 +51,9 @@ TestCase { name: "Tumbler" property var tumbler: null - readonly property real defaultImplicitDelegateHeight: 200 / 3 + readonly property real implicitTumblerWidth: 60 + readonly property real implicitTumblerHeight: 200 + readonly property real defaultImplicitDelegateHeight: implicitTumblerHeight / 3 readonly property real defaultListViewTumblerOffset: -defaultImplicitDelegateHeight function init() { @@ -564,4 +566,103 @@ TestCase { object.destroy(); gridView.destroy(); } + + property Component paddingDelegate: Text { + objectName: "delegate" + index + text: modelData + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "red" + border.width: 1 + } + } + + function test_padding_data() { + var data = []; + + data.push({ padding: 0 }); + data.push({ padding: 10 }); + data.push({ left: 10, top: 10 }); + data.push({ right: 10, bottom: 10 }); + + for (var i = 0; i < data.length; ++i) { + var tag = ""; + + if (data[i].padding !== undefined) + tag += "padding: " + data[i].padding + " "; + if (data[i].left !== undefined) + tag += "left: " + data[i].left + " "; + if (data[i].right !== undefined) + tag += "right: " + data[i].right + " "; + if (data[i].top !== undefined) + tag += "top: " + data[i].top + " "; + if (data[i].bottom !== undefined) + tag += "bottom: " + data[i].bottom + " "; + tag = tag.slice(0, -1); + + data[i].tag = tag; + } + + return data; + } + + function test_padding(data) { + tumbler.delegate = paddingDelegate; + tumbler.model = 5; + compare(tumbler.padding, 0); + compare(tumbler.leftPadding, 0); + compare(tumbler.rightPadding, 0); + compare(tumbler.topPadding, 0); + compare(tumbler.bottomPadding, 0); + compare(tumbler.contentItem.x, 0); + compare(tumbler.contentItem.y, 0); + + if (data.padding !== undefined) + tumbler.padding = data.padding; + if (data.left !== undefined) + tumbler.leftPadding = data.left; + if (data.right !== undefined) + tumbler.rightPadding = data.right; + if (data.top !== undefined) + tumbler.topPadding = data.top; + if (data.bottom !== undefined) + tumbler.bottomPadding = data.bottom; + + compare(tumbler.availableWidth, implicitTumblerWidth - tumbler.leftPadding - tumbler.rightPadding); + compare(tumbler.availableHeight, implicitTumblerHeight - tumbler.topPadding - tumbler.bottomPadding); + compare(tumbler.contentItem.x, tumbler.leftPadding); + compare(tumbler.contentItem.y, tumbler.topPadding); + + var pathView = tumbler.contentItem; + var expectedDelegateHeight = tumbler.availableHeight / tumbler.visibleItemCount; + var itemIndicesInVisualOrder = [4, 0, 1]; + for (var i = 0; i < itemIndicesInVisualOrder.length; ++i) { + var delegate = findChild(pathView, "delegate" + itemIndicesInVisualOrder[i]); + verify(delegate, "Couldn't find delegate at index " + itemIndicesInVisualOrder[i] + + " (iteration " + i + " out of " + (pathView.children.length - 1) + ")"); + + compare(delegate.width, tumbler.availableWidth); + compare(delegate.height, expectedDelegateHeight); + + var expectedY = tumbler.topPadding + i * expectedDelegateHeight; + var mappedPos = delegate.mapToItem(null, delegate.width / 2, 0); + fuzzyCompare(mappedPos.y, expectedY, 0.5, + "Tumbler's PathView delegate at index " + itemIndicesInVisualOrder[i] + + " should have a y pos of " + expectedY + ", but it's actually " + mappedPos.y.toFixed(20)); + + var expectedX = tumbler.leftPadding; + compare(delegate.mapToItem(null, 0, 0).x, expectedX, + "Tumbler's PathView delegate at index " + itemIndicesInVisualOrder[i] + + " should have a x pos of " + expectedX + ", but it's actually " + mappedPos.x.toFixed(20)); + } + + // Force new items to be created, as there was a bug where the path was correct until this happened. + compare(tumbler.contentItem.offset, 0); + ++tumbler.currentIndex; + tryCompare(tumbler.contentItem, "offset", 4, tumbler.contentItem.highlightMoveDuration * 2); + } } |