diff options
Diffstat (limited to 'src/quick/items/qquickstateoperations.cpp')
-rw-r--r-- | src/quick/items/qquickstateoperations.cpp | 190 |
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> |