aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2018-01-18 13:36:26 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2018-01-18 13:36:26 +0100
commitdeb779cdbaeeaea52ca0e99c9295db587c25f41c (patch)
tree82765e08678818ed21a6f9d5354ac852b0613460 /src
parent26056b52b182b4452855f54a2c811d64246c434a (diff)
parentd64774add9fafa24406a202d0313e10780e1e715 (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: src/imports/controls/Tumbler.qml src/quicktemplates2/qquicktumbler.cpp src/quicktemplates2/qquicktumbler_p.h src/quicktemplates2/qquicktumbler_p_p.h Change-Id: I8d50991183fe3c5b50a49e00f01bcd3049f5346c
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/Tumbler.qml2
-rw-r--r--src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-custom.qml2
-rw-r--r--src/imports/controls/material/Tumbler.qml2
-rw-r--r--src/imports/controls/universal/Tumbler.qml2
-rw-r--r--src/quickcontrols2/qquicktumblerview.cpp9
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp91
-rw-r--r--src/quicktemplates2/qquicktumbler_p.h1
-rw-r--r--src/quicktemplates2/qquicktumbler_p_p.h1
8 files changed, 77 insertions, 33 deletions
diff --git a/src/imports/controls/Tumbler.qml b/src/imports/controls/Tumbler.qml
index 752d5834..eb912553 100644
--- a/src/imports/controls/Tumbler.qml
+++ b/src/imports/controls/Tumbler.qml
@@ -48,7 +48,7 @@ T.Tumbler {
text: modelData
color: control.visualFocus ? control.palette.highlight : control.palette.text
font: control.font
- opacity: 1.0 - Math.abs(Tumbler.displacement) / (visibleItemCount / 2)
+ opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-custom.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-custom.qml
index b3645587..cc37d541 100644
--- a/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-custom.qml
+++ b/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-custom.qml
@@ -56,7 +56,7 @@ Tumbler {
font: control.font
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- opacity: 1.0 - Math.abs(Tumbler.displacement) / (visibleItemCount / 2)
+ opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)
}
Rectangle {
diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml
index 8d58257f..4364581d 100644
--- a/src/imports/controls/material/Tumbler.qml
+++ b/src/imports/controls/material/Tumbler.qml
@@ -49,7 +49,7 @@ T.Tumbler {
text: modelData
color: control.Material.foreground
font: control.font
- opacity: (1.0 - Math.abs(Tumbler.displacement) / (visibleItemCount / 2)) * (control.enabled ? 1 : 0.6)
+ opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/src/imports/controls/universal/Tumbler.qml b/src/imports/controls/universal/Tumbler.qml
index 70e80354..30b3b785 100644
--- a/src/imports/controls/universal/Tumbler.qml
+++ b/src/imports/controls/universal/Tumbler.qml
@@ -50,7 +50,7 @@ T.Tumbler {
text: modelData
font: control.font
color: control.Universal.foreground
- opacity: (1.0 - Math.abs(Tumbler.displacement) / (visibleItemCount / 2)) * (control.enabled ? 1 : 0.6)
+ opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp
index e8f0c364..4469810c 100644
--- a/src/quickcontrols2/qquicktumblerview.cpp
+++ b/src/quickcontrols2/qquicktumblerview.cpp
@@ -173,14 +173,19 @@ void QQuickTumblerView::createView()
m_listView->setParentItem(this);
m_listView->setSnapMode(QQuickListView::SnapToItem);
m_listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
- m_listView->setHighlightMoveDuration(1000);
m_listView->setClip(true);
- m_listView->setDelegate(m_delegate);
// Give the view a size.
updateView();
// Set the model.
updateModel();
+
+ // Set these after the model is set so that the currentItem animation
+ // happens instantly on startup/after switching models. If we set them too early,
+ // the view animates any potential currentIndex change over one second,
+ // which we don't want when the contentItem has just been created.
+ m_listView->setDelegate(m_delegate);
+ m_listView->setHighlightMoveDuration(1000);
}
}
}
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index bed3e400..efa61dad 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -120,17 +120,24 @@ namespace {
*/
QQuickItem *QQuickTumblerPrivate::determineViewType(QQuickItem *contentItem)
{
+ if (!contentItem) {
+ resetViewData();
+ return nullptr;
+ }
+
if (contentItem->inherits("QQuickPathView")) {
view = contentItem;
viewContentItem = contentItem;
viewContentItemType = PathViewContentItem;
viewOffset = 0;
+
return contentItem;
} else if (contentItem->inherits("QQuickListView")) {
view = contentItem;
viewContentItem = qobject_cast<QQuickFlickable*>(contentItem)->contentItem();
viewContentItemType = ListViewContentItem;
viewContentY = 0;
+
return contentItem;
} else {
const auto childItems = contentItem->childItems();
@@ -142,6 +149,7 @@ QQuickItem *QQuickTumblerPrivate::determineViewType(QQuickItem *contentItem)
}
resetViewData();
+ viewContentItemType = UnsupportedContentItemType;
return nullptr;
}
@@ -153,7 +161,7 @@ void QQuickTumblerPrivate::resetViewData()
viewOffset = 0;
else if (viewContentItemType == ListViewContentItem)
viewContentY = 0;
- viewContentItemType = UnsupportedContentItemType;
+ viewContentItemType = NoContentItem;
}
QList<QQuickItem *> QQuickTumblerPrivate::viewContentItemChildItems() const
@@ -257,24 +265,16 @@ void QQuickTumblerPrivate::calculateDisplacements()
}
}
-void QQuickTumblerPrivate::itemChildAdded(QQuickItem *, QQuickItem *child)
+void QQuickTumblerPrivate::itemChildAdded(QQuickItem *, QQuickItem *)
{
_q_updateItemWidths();
_q_updateItemHeights();
-
- QQuickTumblerAttached *attached = qobject_cast<QQuickTumblerAttached *>(qmlAttachedPropertiesObject<QQuickTumbler>(child, false));
- if (attached)
- QQuickTumblerAttachedPrivate::get(attached)->calculateDisplacement();
}
-void QQuickTumblerPrivate::itemChildRemoved(QQuickItem *, QQuickItem *child)
+void QQuickTumblerPrivate::itemChildRemoved(QQuickItem *, QQuickItem *)
{
_q_updateItemWidths();
_q_updateItemHeights();
-
- QQuickTumblerAttached *attached = qobject_cast<QQuickTumblerAttached *>(qmlAttachedPropertiesObject<QQuickTumbler>(child, false));
- if (attached)
- QQuickTumblerAttachedPrivate::get(attached)->calculateDisplacement();
}
void QQuickTumblerPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &)
@@ -527,8 +527,6 @@ void QQuickTumbler::componentComplete()
{
Q_D(QQuickTumbler);
QQuickControl::componentComplete();
- d->_q_updateItemHeights();
- d->_q_updateItemWidths();
if (!d->view) {
// Force the view to be created.
@@ -536,6 +534,17 @@ void QQuickTumbler::componentComplete()
// Determine the type of view for attached properties, etc.
d->setupViewData(d->contentItem);
}
+
+ // If there was no contentItem or it was of an unsupported type,
+ // we don't have anything else to do.
+ if (!d->view)
+ return;
+
+ // Update item heights after we've populated the model,
+ // otherwise ignoreSignals will cause these functions to return early.
+ d->_q_updateItemHeights();
+ d->_q_updateItemWidths();
+ d->_q_onViewCountChanged();
}
void QQuickTumbler::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
@@ -554,6 +563,9 @@ void QQuickTumbler::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
// Make sure we use the new content item and not the current one, as that won't
// be changed until after contentItemChange() has finished.
d->setupViewData(newItem);
+
+ d->_q_updateItemHeights();
+ d->_q_updateItemWidths();
}
}
}
@@ -593,6 +605,9 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem)
determineViewType(newControlContentItem);
+ if (viewContentItemType == QQuickTumblerPrivate::NoContentItem)
+ return;
+
if (viewContentItemType == QQuickTumblerPrivate::UnsupportedContentItemType) {
qWarning() << "Tumbler: contentItem must contain either a PathView or a ListView";
return;
@@ -617,6 +632,8 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem)
// Sync the view's currentIndex with ours.
syncCurrentIndex();
+
+ calculateDisplacements();
}
void QQuickTumblerPrivate::syncCurrentIndex()
@@ -624,17 +641,27 @@ void QQuickTumblerPrivate::syncCurrentIndex()
const int actualViewIndex = view->property("currentIndex").toInt();
Q_Q(QQuickTumbler);
+ const bool isPendingCurrentIndex = pendingCurrentIndex != -1;
+ const int indexToSet = isPendingCurrentIndex ? pendingCurrentIndex : currentIndex;
+
// Nothing to do.
- if (actualViewIndex == currentIndex)
+ if (actualViewIndex == indexToSet) {
+ pendingCurrentIndex = -1;
return;
+ }
// PathView likes to use 0 as currentIndex for empty models, but we use -1 for that.
if (q->count() == 0 && actualViewIndex == 0)
return;
ignoreCurrentIndexChanges = true;
- view->setProperty("currentIndex", currentIndex);
+ view->setProperty("currentIndex", QVariant(indexToSet));
ignoreCurrentIndexChanges = false;
+
+ if (view->property("currentIndex").toInt() == indexToSet)
+ pendingCurrentIndex = -1;
+ else if (isPendingCurrentIndex)
+ q->polish();
}
void QQuickTumblerPrivate::setCount(int newCount)
@@ -685,11 +712,17 @@ void QQuickTumblerPrivate::setWrap(bool shouldWrap, bool isExplicit)
ignoreCurrentIndexChanges = false;
- // The view should have been created now, so we can start determining its type, etc.
- // If the delegates use attached properties, this will have already been called,
- // in which case it will return early. If the delegate doesn't use attached properties,
- // we need to call it here.
- setupViewData(contentItem);
+ // If isComponentComplete() is true, we require a contentItem. If it's not
+ // true, it might not have been created yet, so we wait until
+ // componentComplete() is called.
+ //
+ // When the contentItem (usually QQuickTumblerView) has been created, we
+ // can start determining its type, etc. If the delegates use attached
+ // properties, this will have already been called, in which case it will
+ // return early. If the delegate doesn't use attached properties, we need
+ // to call it here.
+ if (q->isComponentComplete() || contentItem)
+ setupViewData(contentItem);
q->setCurrentIndex(oldCurrentIndex);
}
@@ -724,6 +757,10 @@ void QQuickTumbler::updatePolish()
{
Q_D(QQuickTumbler);
if (d->pendingCurrentIndex != -1) {
+ // Update our count, as ignoreSignals might have been true
+ // when _q_onViewCountChanged() was last called.
+ d->setCount(d->view->property("count").toInt());
+
// If the count is still 0, it's not going to happen.
if (d->count == 0) {
d->pendingCurrentIndex = -1;
@@ -789,9 +826,9 @@ void QQuickTumblerAttachedPrivate::calculateDisplacement()
const int previousDisplacement = displacement;
displacement = 0;
- // Can happen if the attached properties are accessed on the wrong type of item or the tumbler was destroyed.
if (!tumbler) {
- emitIfDisplacementChanged(previousDisplacement, displacement);
+ // Can happen if the attached properties are accessed on the wrong type of item or the tumbler was destroyed.
+ // We don't want to emit the change signal though, as this could cause warnings about Tumbler.tumbler being null.
return;
}
@@ -860,10 +897,12 @@ QQuickTumblerAttached::QQuickTumblerAttached(QObject *parent)
QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(d->tumbler);
tumblerPrivate->setupViewData(tumblerPrivate->contentItem);
- if (!tumblerPrivate->viewContentItem)
- return;
-
- d->calculateDisplacement();
+ if (delegateItem->parentItem() == tumblerPrivate->viewContentItem) {
+ // This item belongs to the "new" view, meaning that the tumbler's contentItem
+ // was probably assigned declaratively. If they're not equal, calling
+ // calculateDisplacement() would use the old contentItem data, which is bad.
+ d->calculateDisplacement();
+ }
}
}
diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h
index c388c28d..5d4df4a7 100644
--- a/src/quicktemplates2/qquicktumbler_p.h
+++ b/src/quicktemplates2/qquicktumbler_p.h
@@ -70,7 +70,6 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl
Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION 1)
// 2.2 (Qt 5.9)
Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION 2)
- Q_CLASSINFO("DeferredPropertyNames", "background")
public:
explicit QQuickTumbler(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h
index fe8a4ad2..75b1a396 100644
--- a/src/quicktemplates2/qquicktumbler_p_p.h
+++ b/src/quicktemplates2/qquicktumbler_p_p.h
@@ -63,6 +63,7 @@ public:
~QQuickTumblerPrivate();
enum ContentItemType {
+ NoContentItem,
UnsupportedContentItemType,
PathViewContentItem,
ListViewContentItem