aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickstateoperations.cpp59
-rw-r--r--tests/auto/quick/qquickstates/data/anchorRewind.qml31
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp24
4 files changed, 100 insertions, 15 deletions
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 197d891b2a..2fdb0f00c8 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -477,6 +477,7 @@ private:
friend class QSGRenderer;
friend class QAccessibleQuickItem;
friend class QQuickAccessibleAttached;
+ friend class QQuickAnchorChanges;
Q_DISABLE_COPY(QQuickItem)
Q_DECLARE_PRIVATE(QQuickItem)
};
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index d8380af756..719c682769 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -1094,6 +1094,7 @@ void QQuickAnchorChanges::reverse()
QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
+ const QRectF oldGeometry(d->target->position(), d->target->size());
bool stateSetWidth = (stateHAnchors &&
stateHAnchors != QQuickAnchors::LeftAnchor &&
stateHAnchors != QQuickAnchors::RightAnchor &&
@@ -1102,8 +1103,11 @@ void QQuickAnchorChanges::reverse()
origHAnchors != QQuickAnchors::LeftAnchor &&
origHAnchors != QQuickAnchors::RightAnchor &&
origHAnchors != QQuickAnchors::HCenterAnchor);
- if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
- d->target->setWidth(d->origWidth.value);
+ if (d->origWidth.isValid() && stateSetWidth && !origSetWidth && !qt_is_nan(d->origWidth)) {
+ targetPrivate->widthValidFlag = true;
+ if (targetPrivate->width != d->origWidth)
+ targetPrivate->width.setValueBypassingBindings(d->origWidth);
+ }
bool stateSetHeight = (stateVAnchors &&
stateVAnchors != QQuickAnchors::TopAnchor &&
@@ -1115,14 +1119,23 @@ void QQuickAnchorChanges::reverse()
origVAnchors != QQuickAnchors::BottomAnchor &&
origVAnchors != QQuickAnchors::VCenterAnchor &&
origVAnchors != QQuickAnchors::BaselineAnchor);
- if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
- d->target->setHeight(d->origHeight.value);
+ if (d->origHeight.isValid() && stateSetHeight && !origSetHeight && !!qt_is_nan(d->origHeight)) {
+ targetPrivate->heightValidFlag = true;
+ if (targetPrivate->height != d->origHeight)
+ targetPrivate->height.setValueBypassingBindings(d->origHeight);
+ }
+
+ if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x)
+ targetPrivate->x.setValueBypassingBindings(d->origX);
- if (stateHAnchors && !origHAnchors)
- d->target->setX(d->origX);
+ if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y)
+ targetPrivate->y.setValueBypassingBindings(d->origY);
- if (stateVAnchors && !origVAnchors)
- d->target->setY(d->origY);
+ const QRectF newGeometry(d->target->position(), d->target->size());
+ if (newGeometry != oldGeometry) {
+ targetPrivate->dirty(QQuickItemPrivate::Position);
+ d->target->geometryChange(newGeometry, oldGeometry);
+ }
}
QQuickStateActionEvent::EventType QQuickAnchorChanges::type() const
@@ -1316,15 +1329,31 @@ void QQuickAnchorChanges::rewind()
return;
QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+ const QRectF oldGeometry(d->target->position(), d->target->size());
+
+ // Restore previous values (but not previous bindings, i.e. anchors).
+ // Also, don't drop any new bindings.
+ if (!qt_is_nan(d->rewindX) && d->rewindX != targetPrivate->x)
+ targetPrivate->x.setValueBypassingBindings(d->rewindX);
+ if (!qt_is_nan(d->rewindY) && d->rewindY != targetPrivate->y)
+ targetPrivate->y.setValueBypassingBindings(d->rewindY);
+
+ if (targetPrivate->widthValid() && !qt_is_nan(d->rewindWidth)) {
+ targetPrivate->widthValidFlag = true;
+ if (d->rewindWidth != targetPrivate->width)
+ targetPrivate->width.setValueBypassingBindings(d->rewindWidth);
+ }
- //restore previous values (but not previous bindings, i.e. anchors)
- d->target->setX(d->rewindX);
- d->target->setY(d->rewindY);
- if (targetPrivate->widthValid()) {
- d->target->setWidth(d->rewindWidth);
+ if (targetPrivate->heightValid() && !qt_is_nan(d->rewindHeight)) {
+ targetPrivate->heightValidFlag = true;
+ if (d->rewindHeight != targetPrivate->height)
+ targetPrivate->height.setValueBypassingBindings(d->rewindHeight);
}
- if (targetPrivate->heightValid()) {
- d->target->setHeight(d->rewindHeight);
+
+ const QRectF newGeometry(d->target->position(), d->target->size());
+ if (newGeometry != oldGeometry) {
+ targetPrivate->dirty(QQuickItemPrivate::Position);
+ d->target->geometryChange(newGeometry, oldGeometry);
}
}
diff --git a/tests/auto/quick/qquickstates/data/anchorRewind.qml b/tests/auto/quick/qquickstates/data/anchorRewind.qml
new file mode 100644
index 0000000000..740c94cf42
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorRewind.qml
@@ -0,0 +1,31 @@
+import QtQuick
+
+Item {
+ width: 400
+ height: 400
+ Item {
+ id: outer
+ anchors.fill: parent
+ Item {
+ id: inner
+ width: parent.width / 2
+ height: parent.height / 2
+ anchors.left: parent.right
+ anchors.top: parent.bottom
+ }
+ states: [
+ State {
+ when: true
+ AnchorChanges {
+ target: inner
+ anchors.left: outer.left
+ anchors.top: outer.top
+ }
+ }
+ ]
+ transitions: Transition {
+ AnchorAnimation {}
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index 788b9c68ec..d6814bd057 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -206,6 +206,7 @@ private slots:
void bindableProperties();
void parentChangeInvolvingBindings();
void deferredProperties();
+ void rewindAnchorChange();
};
void tst_qquickstates::initTestCase()
@@ -1954,6 +1955,29 @@ void tst_qquickstates::deferredProperties()
QCOMPARE(root->height(), 100.0);
}
+void tst_qquickstates::rewindAnchorChange()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("anchorRewind.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> root(c.create());
+ QVERIFY(root);
+
+ QQmlContext *context = qmlContext(root.data());
+ QVERIFY(context);
+
+ QObject *inner = context->objectForName(QStringLiteral("inner"));
+ QVERIFY(inner);
+
+ QQuickItem *innerRect = qobject_cast<QQuickItem *>(inner);
+ QVERIFY(innerRect);
+
+ QTRY_COMPARE(innerRect->x(), 0);
+ QTRY_COMPARE(innerRect->y(), 0);
+ QTRY_COMPARE(innerRect->width(), 200);
+ QTRY_COMPARE(innerRect->height(), 200);
+}
+
QTEST_MAIN(tst_qquickstates)
#include "tst_qquickstates.moc"