aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickstateoperations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquickstateoperations.cpp')
-rw-r--r--src/quick/items/qquickstateoperations.cpp190
1 files changed, 94 insertions, 96 deletions
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 34c5b46892..35b29b9134 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickstateoperations_p.h"
#include "qquickitem_p.h"
@@ -43,7 +7,10 @@
#include <private/qquickstate_p_p.h>
#include <QtQml/qqmlinfo.h>
+
#include <QtCore/qmath.h>
+#include <QtCore/qpointer.h>
+
#include <memory>
QT_BEGIN_NAMESPACE
@@ -179,10 +146,6 @@ QQuickParentChange::QQuickParentChange(QObject *parent)
{
}
-QQuickParentChange::~QQuickParentChange()
-{
-}
-
/*!
\qmlproperty real QtQuick::ParentChange::x
\qmlproperty real QtQuick::ParentChange::y
@@ -196,7 +159,7 @@ QQuickParentChange::~QQuickParentChange()
QQmlScriptString QQuickParentChange::x() const
{
Q_D(const QQuickParentChange);
- return d->xString.value;
+ return d->xString.value();
}
void QQuickParentChange::setX(const QQmlScriptString &x)
@@ -214,7 +177,7 @@ bool QQuickParentChange::xIsSet() const
QQmlScriptString QQuickParentChange::y() const
{
Q_D(const QQuickParentChange);
- return d->yString.value;
+ return d->yString.value();
}
void QQuickParentChange::setY(const QQmlScriptString &y)
@@ -232,7 +195,7 @@ bool QQuickParentChange::yIsSet() const
QQmlScriptString QQuickParentChange::width() const
{
Q_D(const QQuickParentChange);
- return d->widthString.value;
+ return d->widthString.value();
}
void QQuickParentChange::setWidth(const QQmlScriptString &width)
@@ -250,7 +213,7 @@ bool QQuickParentChange::widthIsSet() const
QQmlScriptString QQuickParentChange::height() const
{
Q_D(const QQuickParentChange);
- return d->heightString.value;
+ return d->heightString.value();
}
void QQuickParentChange::setHeight(const QQmlScriptString &height)
@@ -268,7 +231,7 @@ bool QQuickParentChange::heightIsSet() const
QQmlScriptString QQuickParentChange::scale() const
{
Q_D(const QQuickParentChange);
- return d->scaleString.value;
+ return d->scaleString.value();
}
void QQuickParentChange::setScale(const QQmlScriptString &scale)
@@ -286,7 +249,7 @@ bool QQuickParentChange::scaleIsSet() const
QQmlScriptString QQuickParentChange::rotation() const
{
Q_D(const QQuickParentChange);
- return d->rotationString.value;
+ return d->rotationString.value();
}
void QQuickParentChange::setRotation(const QQmlScriptString &rotation)
@@ -353,14 +316,14 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->xString.isValid()) {
bool ok = false;
- qreal x = d->xString.value.numberLiteral(&ok);
+ qreal x = d->xString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction xa(d->target, QLatin1String("x"), x);
actions << xa;
} else {
QQmlProperty property(d->target, QLatin1String("x"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->xString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(
+ property, d->xString.value(), d->target, qmlContext(this));
QQuickStateAction xa;
xa.property = property;
xa.toBinding = newBinding;
@@ -372,14 +335,14 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->yString.isValid()) {
bool ok = false;
- qreal y = d->yString.value.numberLiteral(&ok);
+ qreal y = d->yString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction ya(d->target, QLatin1String("y"), y);
actions << ya;
} else {
QQmlProperty property(d->target, QLatin1String("y"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->yString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(
+ property, d->yString.value(), d->target, qmlContext(this));
QQuickStateAction ya;
ya.property = property;
ya.toBinding = newBinding;
@@ -391,14 +354,14 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->scaleString.isValid()) {
bool ok = false;
- qreal scale = d->scaleString.value.numberLiteral(&ok);
+ qreal scale = d->scaleString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction sa(d->target, QLatin1String("scale"), scale);
actions << sa;
} else {
QQmlProperty property(d->target, QLatin1String("scale"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->scaleString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(
+ property, d->scaleString.value(), d->target, qmlContext(this));
QQuickStateAction sa;
sa.property = property;
sa.toBinding = newBinding;
@@ -410,14 +373,14 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->rotationString.isValid()) {
bool ok = false;
- qreal rotation = d->rotationString.value.numberLiteral(&ok);
+ qreal rotation = d->rotationString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction ra(d->target, QLatin1String("rotation"), rotation);
actions << ra;
} else {
QQmlProperty property(d->target, QLatin1String("rotation"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->rotationString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(
+ property, d->rotationString.value(), d->target, qmlContext(this));
QQuickStateAction ra;
ra.property = property;
ra.toBinding = newBinding;
@@ -429,14 +392,13 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->widthString.isValid()) {
bool ok = false;
- qreal width = d->widthString.value.numberLiteral(&ok);
+ qreal width = d->widthString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction wa(d->target, QLatin1String("width"), width);
actions << wa;
} else {
QQmlProperty property(d->target, QLatin1String("width"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->widthString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->widthString, d->target, qmlContext(this));
QQuickStateAction wa;
wa.property = property;
wa.toBinding = newBinding;
@@ -448,14 +410,13 @@ QQuickStateOperation::ActionList QQuickParentChange::actions()
if (d->heightString.isValid()) {
bool ok = false;
- qreal height = d->heightString.value.numberLiteral(&ok);
+ qreal height = d->heightString.value().numberLiteral(&ok);
if (ok) {
QQuickStateAction ha(d->target, QLatin1String("height"), height);
actions << ha;
} else {
QQmlProperty property(d->target, QLatin1String("height"));
- QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->heightString.value, d->target, qmlContext(this));
- newBinding->setTarget(property);
+ auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->heightString, d->target, qmlContext(this));
QQuickStateAction ha;
ha.property = property;
ha.toBinding = newBinding;
@@ -492,11 +453,13 @@ void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuick
{
if (!target || !snapshot)
return;
- target->setX(snapshot->x);
- target->setY(snapshot->y);
+
+ // leave existing bindings alive; new bindings are applied in applyBindings
+ // setPosition and setSize update the geometry without invalidating bindings
+ target->setPosition(QPointF(snapshot->x, snapshot->y));
+ target->setSize(QSizeF(snapshot->width, snapshot->height));
+
target->setScale(snapshot->scale);
- target->setWidth(snapshot->width);
- target->setHeight(snapshot->height);
target->setRotation(snapshot->rotation);
target->setParentItem(snapshot->parent);
if (snapshot->stackBefore)
@@ -548,7 +511,7 @@ void QQuickParentChange::saveCurrentValues()
return;
QList<QQuickItem *> children = d->rewind->parent->childItems();
- for (int ii = 0; ii < children.count() - 1; ++ii) {
+ for (int ii = 0; ii < children.size() - 1; ++ii) {
if (children.at(ii) == d->target) {
d->rewind->stackBefore = children.at(ii + 1);
break;
@@ -573,7 +536,7 @@ void QQuickParentChange::rewind()
The AnchorChanges type is used to modify the anchors of an item in a \l State.
AnchorChanges cannot be used to modify the margins on an item. For this, use
- PropertyChanges intead.
+ PropertyChanges instead.
In the following example we change the top and bottom anchors of an item
using AnchorChanges, and the top and bottom anchor margins using
@@ -854,10 +817,6 @@ QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
{
}
-QQuickAnchorChanges::~QQuickAnchorChanges()
-{
-}
-
QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
{
Q_D(QQuickAnchorChanges);
@@ -1106,35 +1065,59 @@ 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 &&
stateHAnchors != QQuickAnchors::HCenterAnchor);
+ // in case of an additive AnchorChange, we _did_ end up modifying the width
+ stateSetWidth |= ((stateHAnchors & QQuickAnchors::LeftAnchor) && (origHAnchors & QQuickAnchors::RightAnchor)) ||
+ ((stateHAnchors & QQuickAnchors::RightAnchor) && (origHAnchors & QQuickAnchors::LeftAnchor));
bool origSetWidth = (origHAnchors &&
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 &&
stateVAnchors != QQuickAnchors::BottomAnchor &&
stateVAnchors != QQuickAnchors::VCenterAnchor &&
stateVAnchors != QQuickAnchors::BaselineAnchor);
+ // in case of an additive AnchorChange, we _did_ end up modifying the height
+ stateSetHeight |= ((stateVAnchors & QQuickAnchors::TopAnchor) && (origVAnchors & QQuickAnchors::BottomAnchor)) ||
+ ((stateVAnchors & QQuickAnchors::BottomAnchor) && (origVAnchors & QQuickAnchors::TopAnchor));
bool origSetHeight = (origVAnchors &&
origVAnchors != QQuickAnchors::TopAnchor &&
origVAnchors != QQuickAnchors::BottomAnchor &&
origVAnchors != QQuickAnchors::VCenterAnchor &&
origVAnchors != QQuickAnchors::BaselineAnchor);
- if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
- d->target->setHeight(d->origHeight.value);
-
- if (stateHAnchors && !origHAnchors)
- d->target->setX(d->origX);
+ 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 (stateVAnchors && !origVAnchors)
- d->target->setY(d->origY);
+ if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x)
+ targetPrivate->x.setValueBypassingBindings(d->origX);
+
+ if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y)
+ targetPrivate->y.setValueBypassingBindings(d->origY);
+
+ const QRectF newGeometry(d->target->position(), d->target->size());
+ if (newGeometry != oldGeometry) {
+ QQuickItemPrivate::DirtyType dirtyFlags {};
+ if (newGeometry.topLeft() != oldGeometry.topLeft())
+ dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Position);
+ if (newGeometry.size() != oldGeometry.size())
+ dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Size);
+ targetPrivate->dirty(dirtyFlags);
+ d->target->geometryChange(newGeometry, oldGeometry);
+ }
}
QQuickStateActionEvent::EventType QQuickAnchorChanges::type() const
@@ -1198,9 +1181,9 @@ void QQuickAnchorChanges::saveOriginals()
d->origBaselineBinding = QQmlPropertyPrivate::binding(d->baselineProp);
QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
- if (targetPrivate->widthValid)
+ if (targetPrivate->widthValid())
d->origWidth = d->target->width();
- if (targetPrivate->heightValid)
+ if (targetPrivate->heightValid())
d->origHeight = d->target->height();
d->origX = d->target->x();
d->origY = d->target->y();
@@ -1328,15 +1311,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);
}
}
@@ -1373,7 +1372,6 @@ void QQuickAnchorChanges::saveTargetValues()
d->toHeight = d->target->height();
}
-#include <moc_qquickstateoperations_p.cpp>
-
QT_END_NAMESPACE
+#include <moc_qquickstateoperations_p.cpp>