summaryrefslogtreecommitdiffstats
path: root/src/declarative/util/qdeclarativestateoperations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util/qdeclarativestateoperations.cpp')
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp834
1 files changed, 834 insertions, 0 deletions
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
new file mode 100644
index 0000000..9df8658
--- /dev/null
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -0,0 +1,834 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativestateoperations_p.h"
+
+#include <qdeclarative.h>
+#include <qdeclarativecontext.h>
+#include <qdeclarativeexpression.h>
+#include <qdeclarativeinfo.h>
+#include <qdeclarativeanchors_p_p.h>
+#include <qdeclarativeitem_p.h>
+#include <qdeclarativeguard_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtGui/qgraphicsitem.h>
+#include <QtCore/qmath.h>
+
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeParentChangePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeParentChange)
+public:
+ QDeclarativeParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
+ rewindParent(0), rewindStackBefore(0) {}
+
+ QDeclarativeItem *target;
+ QDeclarativeItem *parent;
+ QDeclarativeGuard<QDeclarativeItem> origParent;
+ QDeclarativeGuard<QDeclarativeItem> origStackBefore;
+ QDeclarativeItem *rewindParent;
+ QDeclarativeItem *rewindStackBefore;
+
+ void doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore = 0);
+};
+
+void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore)
+{
+ if (targetParent && target && target->parentItem()) {
+ //### for backwards direction, can we just restore original x, y, scale, rotation
+ Q_Q(QDeclarativeParentChange);
+ bool ok;
+ const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
+ if (transform.type() >= QTransform::TxShear || !ok) {
+ qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under complex transform");
+ ok = false;
+ }
+
+ qreal scale = 1;
+ qreal rotation = 0;
+ if (ok && transform.type() != QTransform::TxRotate) {
+ if (transform.m11() == transform.m22())
+ scale = transform.m11();
+ else {
+ qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under non-uniform scale");
+ ok = false;
+ }
+ } else if (ok && transform.type() == QTransform::TxRotate) {
+ if (transform.m11() == transform.m22())
+ scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
+ else {
+ qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under non-uniform scale");
+ ok = false;
+ }
+
+ if (scale != 0)
+ rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+ else {
+ qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under scale of 0");
+ ok = false;
+ }
+ }
+
+ const QPointF &point = transform.map(QPointF(target->x(),target->y()));
+ qreal x = point.x();
+ qreal y = point.y();
+ if (ok && target->transformOrigin() != QDeclarativeItem::TopLeft) {
+ qreal tempxt = target->transformOriginPoint().x();
+ qreal tempyt = target->transformOriginPoint().y();
+ QTransform t;
+ t.translate(-tempxt, -tempyt);
+ t.rotate(rotation);
+ t.scale(scale, scale);
+ t.translate(tempxt, tempyt);
+ const QPointF &offset = t.map(QPointF(0,0));
+ x += offset.x();
+ y += offset.y();
+ }
+
+ target->setParentItem(targetParent);
+ if (ok) {
+ //qDebug() << x << y << rotation << scale;
+ target->setX(x);
+ target->setY(y);
+ target->setRotation(target->rotation() + rotation);
+ target->setScale(target->scale() * scale);
+ }
+ } else if (target) {
+ target->setParentItem(targetParent);
+ }
+
+ //restore the original stack position.
+ //### if stackBefore has also been reparented this won't work
+ if (stackBefore)
+ target->stackBefore(stackBefore);
+}
+
+/*!
+ \preliminary
+ \qmlclass ParentChange QDeclarativeParentChange
+ \brief The ParentChange element allows you to reparent an Item in a state change.
+
+ ParentChange reparents an Item while preserving its visual appearance (position, rotation,
+ and scale) on screen. You can then specify a transition to move/rotate/scale the Item to
+ its final intended appearance.
+
+ ParentChange can only preserve visual appearance if no complex transforms are involved.
+ More specifically, it will not work if the transform property has been set for any
+ Items involved in the reparenting (defined as any Items in the common ancestor tree
+ for the original and new parent).
+
+ You can specify at which point in a transition you want a ParentChange to occur by
+ using a ParentAction.
+*/
+
+
+QDeclarativeParentChange::QDeclarativeParentChange(QObject *parent)
+ : QDeclarativeStateOperation(*(new QDeclarativeParentChangePrivate), parent)
+{
+}
+
+QDeclarativeParentChange::~QDeclarativeParentChange()
+{
+}
+
+/*!
+ \qmlproperty Item ParentChange::target
+ This property holds the item to be reparented
+*/
+
+QDeclarativeItem *QDeclarativeParentChange::object() const
+{
+ Q_D(const QDeclarativeParentChange);
+ return d->target;
+}
+
+void QDeclarativeParentChange::setObject(QDeclarativeItem *target)
+{
+ Q_D(QDeclarativeParentChange);
+ d->target = target;
+}
+
+/*!
+ \qmlproperty Item ParentChange::parent
+ This property holds the parent for the item in this state
+*/
+
+QDeclarativeItem *QDeclarativeParentChange::parent() const
+{
+ Q_D(const QDeclarativeParentChange);
+ return d->parent;
+}
+
+void QDeclarativeParentChange::setParent(QDeclarativeItem *parent)
+{
+ Q_D(QDeclarativeParentChange);
+ d->parent = parent;
+}
+
+QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
+{
+ Q_D(QDeclarativeParentChange);
+ if (!d->target || !d->parent)
+ return ActionList();
+
+ QDeclarativeAction a;
+ a.event = this;
+
+ return ActionList() << a;
+}
+
+class AccessibleFxItem : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
+public:
+ int siblingIndex() {
+ Q_D(QDeclarativeItem);
+ return d->siblingIndex;
+ }
+};
+
+void QDeclarativeParentChange::saveOriginals()
+{
+ Q_D(QDeclarativeParentChange);
+ saveCurrentValues();
+ d->origParent = d->rewindParent;
+ d->origStackBefore = d->rewindStackBefore;
+}
+
+void QDeclarativeParentChange::execute()
+{
+ Q_D(QDeclarativeParentChange);
+ d->doChange(d->parent);
+}
+
+bool QDeclarativeParentChange::isReversable()
+{
+ return true;
+}
+
+void QDeclarativeParentChange::reverse()
+{
+ Q_D(QDeclarativeParentChange);
+ d->doChange(d->origParent, d->origStackBefore);
+}
+
+QString QDeclarativeParentChange::typeName() const
+{
+ return QLatin1String("ParentChange");
+}
+
+bool QDeclarativeParentChange::override(QDeclarativeActionEvent*other)
+{
+ Q_D(QDeclarativeParentChange);
+ if (other->typeName() != QLatin1String("ParentChange"))
+ return false;
+ if (QDeclarativeParentChange *otherPC = static_cast<QDeclarativeParentChange*>(other))
+ return (d->target == otherPC->object());
+ return false;
+}
+
+void QDeclarativeParentChange::saveCurrentValues()
+{
+ Q_D(QDeclarativeParentChange);
+ if (!d->target) {
+ d->rewindParent = 0;
+ d->rewindStackBefore = 0;
+ return;
+ }
+
+ d->rewindParent = d->target->parentItem();
+
+ if (!d->rewindParent) {
+ d->rewindStackBefore = 0;
+ return;
+ }
+
+ //try to determine the item's original stack position so we can restore it
+ int siblingIndex = ((AccessibleFxItem*)d->target)->siblingIndex() + 1;
+ QList<QGraphicsItem*> children = d->rewindParent->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QDeclarativeItem *child = qobject_cast<QDeclarativeItem*>(children.at(i));
+ if (!child)
+ continue;
+ if (((AccessibleFxItem*)child)->siblingIndex() == siblingIndex) {
+ d->rewindStackBefore = child;
+ break;
+ }
+ }
+}
+
+void QDeclarativeParentChange::rewind()
+{
+ Q_D(QDeclarativeParentChange);
+ d->doChange(d->rewindParent, d->rewindStackBefore);
+}
+
+class QDeclarativeStateChangeScriptPrivate : public QObjectPrivate
+{
+public:
+ QDeclarativeStateChangeScriptPrivate() {}
+
+ QDeclarativeScriptString script;
+ QString name;
+};
+
+/*!
+ \qmlclass StateChangeScript QDeclarativeStateChangeScript
+ \brief The StateChangeScript element allows you to run a script in a state.
+
+ The script specified will be run immediately when the state is made current.
+ Alternatively you can use a ScriptAction to specify at which point in the transition
+ you want the StateChangeScript to be run.
+*/
+
+QDeclarativeStateChangeScript::QDeclarativeStateChangeScript(QObject *parent)
+: QDeclarativeStateOperation(*(new QDeclarativeStateChangeScriptPrivate), parent)
+{
+}
+
+QDeclarativeStateChangeScript::~QDeclarativeStateChangeScript()
+{
+}
+
+/*!
+ \qmlproperty script StateChangeScript::script
+ This property holds the script to run when the state is current.
+*/
+QDeclarativeScriptString QDeclarativeStateChangeScript::script() const
+{
+ Q_D(const QDeclarativeStateChangeScript);
+ return d->script;
+}
+
+void QDeclarativeStateChangeScript::setScript(const QDeclarativeScriptString &s)
+{
+ Q_D(QDeclarativeStateChangeScript);
+ d->script = s;
+}
+
+/*!
+ \qmlproperty script StateChangeScript::script
+ This property holds the name of the script. This name can be used by a
+ ScriptAction to target a specific script.
+
+ \sa ScriptAction::stateChangeScriptName
+*/
+QString QDeclarativeStateChangeScript::name() const
+{
+ Q_D(const QDeclarativeStateChangeScript);
+ return d->name;
+}
+
+void QDeclarativeStateChangeScript::setName(const QString &n)
+{
+ Q_D(QDeclarativeStateChangeScript);
+ d->name = n;
+}
+
+void QDeclarativeStateChangeScript::execute()
+{
+ Q_D(QDeclarativeStateChangeScript);
+ const QString &script = d->script.script();
+ if (!script.isEmpty()) {
+ QDeclarativeExpression expr(d->script.context(), script, d->script.scopeObject());
+ expr.value();
+ }
+}
+
+QDeclarativeStateChangeScript::ActionList QDeclarativeStateChangeScript::actions()
+{
+ ActionList rv;
+ QDeclarativeAction a;
+ a.event = this;
+ rv << a;
+ return rv;
+}
+
+QString QDeclarativeStateChangeScript::typeName() const
+{
+ return QLatin1String("StateChangeScript");
+}
+
+/*!
+ \qmlclass AnchorChanges QDeclarativeAnchorChanges
+ \brief The AnchorChanges element allows you to change the anchors of an item in a state.
+
+ In the following example we change the top and bottom anchors of an item:
+ \snippet examples/declarative/anchors/anchor-changes.qml 0
+
+ AnchorChanges will 'inject' \c x, \c y, \c width, and \c height changes into the transition,
+ so you can animate them as you would normally changes to these properties:
+ \qml
+ //animate our anchor changes
+ NumberAnimation { targets: content; properties: "x,y,width,height" }
+ \endqml
+
+ For more information on anchors see \l {anchor-layout}{Anchor Layouts}.
+*/
+
+
+
+class QDeclarativeAnchorChangesPrivate : public QObjectPrivate
+{
+public:
+ QDeclarativeAnchorChangesPrivate() : target(0) {}
+
+ QString name;
+ QDeclarativeItem *target;
+ QString resetString;
+ QStringList resetList;
+ QDeclarativeAnchorLine left;
+ QDeclarativeAnchorLine right;
+ QDeclarativeAnchorLine horizontalCenter;
+ QDeclarativeAnchorLine top;
+ QDeclarativeAnchorLine bottom;
+ QDeclarativeAnchorLine verticalCenter;
+ QDeclarativeAnchorLine baseline;
+
+ QDeclarativeAnchorLine origLeft;
+ QDeclarativeAnchorLine origRight;
+ QDeclarativeAnchorLine origHCenter;
+ QDeclarativeAnchorLine origTop;
+ QDeclarativeAnchorLine origBottom;
+ QDeclarativeAnchorLine origVCenter;
+ QDeclarativeAnchorLine origBaseline;
+
+ QDeclarativeAnchorLine rewindLeft;
+ QDeclarativeAnchorLine rewindRight;
+ QDeclarativeAnchorLine rewindHCenter;
+ QDeclarativeAnchorLine rewindTop;
+ QDeclarativeAnchorLine rewindBottom;
+ QDeclarativeAnchorLine rewindVCenter;
+ QDeclarativeAnchorLine rewindBaseline;
+
+ qreal fromX;
+ qreal fromY;
+ qreal fromWidth;
+ qreal fromHeight;
+};
+
+/*!
+ \qmlproperty Item AnchorChanges::target
+ This property holds the Item whose anchors will change
+*/
+
+QDeclarativeAnchorChanges::QDeclarativeAnchorChanges(QObject *parent)
+ : QDeclarativeStateOperation(*(new QDeclarativeAnchorChangesPrivate), parent)
+{
+}
+
+QDeclarativeAnchorChanges::~QDeclarativeAnchorChanges()
+{
+}
+
+QDeclarativeAnchorChanges::ActionList QDeclarativeAnchorChanges::actions()
+{
+ QDeclarativeAction a;
+ a.event = this;
+ return ActionList() << a;
+}
+
+QDeclarativeItem *QDeclarativeAnchorChanges::object() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->target;
+}
+
+void QDeclarativeAnchorChanges::setObject(QDeclarativeItem *target)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->target = target;
+}
+
+QString QDeclarativeAnchorChanges::reset() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->resetString;
+}
+
+void QDeclarativeAnchorChanges::setReset(const QString &reset)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->resetString = reset;
+ d->resetList = d->resetString.split(QLatin1Char(','));
+ for (int i = 0; i < d->resetList.count(); ++i)
+ d->resetList[i] = d->resetList.at(i).trimmed();
+}
+
+/*!
+ \qmlproperty AnchorLine AnchorChanges::left
+ \qmlproperty AnchorLine AnchorChanges::right
+ \qmlproperty AnchorLine AnchorChanges::horizontalCenter
+ \qmlproperty AnchorLine AnchorChanges::top
+ \qmlproperty AnchorLine AnchorChanges::bottom
+ \qmlproperty AnchorLine AnchorChanges::verticalCenter
+ \qmlproperty AnchorLine AnchorChanges::baseline
+
+ These properties change the respective anchors of the item.
+*/
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::left() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->left;
+}
+
+void QDeclarativeAnchorChanges::setLeft(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->left = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::right() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->right;
+}
+
+void QDeclarativeAnchorChanges::setRight(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->right = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::horizontalCenter() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->horizontalCenter;
+}
+
+void QDeclarativeAnchorChanges::setHorizontalCenter(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->horizontalCenter = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::top() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->top;
+}
+
+void QDeclarativeAnchorChanges::setTop(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->top = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::bottom() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->bottom;
+}
+
+void QDeclarativeAnchorChanges::setBottom(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->bottom = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::verticalCenter() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->verticalCenter;
+}
+
+void QDeclarativeAnchorChanges::setVerticalCenter(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->verticalCenter = edge;
+}
+
+QDeclarativeAnchorLine QDeclarativeAnchorChanges::baseline() const
+{
+ Q_D(const QDeclarativeAnchorChanges);
+ return d->baseline;
+}
+
+void QDeclarativeAnchorChanges::setBaseline(const QDeclarativeAnchorLine &edge)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->baseline = edge;
+}
+
+void QDeclarativeAnchorChanges::execute()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ if (!d->target)
+ return;
+
+ //set any anchors that have been specified
+ if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setLeft(d->left);
+ if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setRight(d->right);
+ if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setHorizontalCenter(d->horizontalCenter);
+ if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setTop(d->top);
+ if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBottom(d->bottom);
+ if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setVerticalCenter(d->verticalCenter);
+ if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBaseline(d->baseline);
+}
+
+bool QDeclarativeAnchorChanges::isReversable()
+{
+ return true;
+}
+
+void QDeclarativeAnchorChanges::reverse()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ if (!d->target)
+ return;
+
+ //restore previous anchors
+ if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setLeft(d->origLeft);
+ if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setRight(d->origRight);
+ if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setHorizontalCenter(d->origHCenter);
+ if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setTop(d->origTop);
+ if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBottom(d->origBottom);
+ if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setVerticalCenter(d->origVCenter);
+ if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBaseline(d->origBaseline);
+}
+
+QString QDeclarativeAnchorChanges::typeName() const
+{
+ return QLatin1String("AnchorChanges");
+}
+
+QList<QDeclarativeAction> QDeclarativeAnchorChanges::extraActions()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ QList<QDeclarativeAction> extra;
+
+ //### try to be smarter about which ones we add.
+ // or short-circuit later on if they haven't actually changed.
+ // we shouldn't set explicit width if there wasn't one before.
+ if (d->target) {
+ QDeclarativeAction a;
+ a.fromValue = d->fromX;
+ a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+ extra << a;
+
+ a.fromValue = d->fromY;
+ a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+ extra << a;
+
+ a.fromValue = d->fromWidth;
+ a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+ extra << a;
+
+ a.fromValue = d->fromHeight;
+ a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+ extra << a;
+ }
+
+ return extra;
+}
+
+bool QDeclarativeAnchorChanges::changesBindings()
+{
+ return true;
+}
+
+void QDeclarativeAnchorChanges::saveOriginals()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->origLeft = d->target->anchors()->left();
+ d->origRight = d->target->anchors()->right();
+ d->origHCenter = d->target->anchors()->horizontalCenter();
+ d->origTop = d->target->anchors()->top();
+ d->origBottom = d->target->anchors()->bottom();
+ d->origVCenter = d->target->anchors()->verticalCenter();
+ d->origBaseline = d->target->anchors()->baseline();
+
+ saveCurrentValues();
+}
+
+void QDeclarativeAnchorChanges::clearForwardBindings()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->fromX = d->target->x();
+ d->fromY = d->target->y();
+ d->fromWidth = d->target->width();
+ d->fromHeight = d->target->height();
+
+ //reset any anchors that have been specified
+ if (d->resetList.contains(QLatin1String("left")))
+ d->target->anchors()->resetLeft();
+ if (d->resetList.contains(QLatin1String("right")))
+ d->target->anchors()->resetRight();
+ if (d->resetList.contains(QLatin1String("horizontalCenter")))
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->resetList.contains(QLatin1String("top")))
+ d->target->anchors()->resetTop();
+ if (d->resetList.contains(QLatin1String("bottom")))
+ d->target->anchors()->resetBottom();
+ if (d->resetList.contains(QLatin1String("verticalCenter")))
+ d->target->anchors()->resetVerticalCenter();
+ if (d->resetList.contains(QLatin1String("baseline")))
+ d->target->anchors()->resetBaseline();
+
+ //reset any anchors that we'll be setting in the state
+ if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetLeft();
+ if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetRight();
+ if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetTop();
+ if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBottom();
+ if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBaseline();
+}
+
+void QDeclarativeAnchorChanges::clearReverseBindings()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->fromX = d->target->x();
+ d->fromY = d->target->y();
+ d->fromWidth = d->target->width();
+ d->fromHeight = d->target->height();
+
+ //reset any anchors that were set in the state
+ if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetLeft();
+ if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetRight();
+ if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetTop();
+ if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBottom();
+ if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBaseline();
+
+ //reset any anchors that were set in the original state
+ if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetLeft();
+ if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetRight();
+ if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetTop();
+ if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBottom();
+ if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBaseline();
+}
+
+bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other)
+{
+ if (other->typeName() != QLatin1String("AnchorChanges"))
+ return false;
+ if (static_cast<QDeclarativeActionEvent*>(this) == other)
+ return true;
+ if (static_cast<QDeclarativeAnchorChanges*>(other)->object() == object())
+ return true;
+ return false;
+}
+
+void QDeclarativeAnchorChanges::rewind()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ if (!d->target)
+ return;
+
+ //restore previous anchors
+ if (d->rewindLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setLeft(d->rewindLeft);
+ if (d->rewindRight.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setRight(d->rewindRight);
+ if (d->rewindHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setHorizontalCenter(d->rewindHCenter);
+ if (d->rewindTop.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setTop(d->rewindTop);
+ if (d->rewindBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBottom(d->rewindBottom);
+ if (d->rewindVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setVerticalCenter(d->rewindVCenter);
+ if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->setBaseline(d->rewindBaseline);
+}
+
+void QDeclarativeAnchorChanges::saveCurrentValues()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->rewindLeft = d->target->anchors()->left();
+ d->rewindRight = d->target->anchors()->right();
+ d->rewindHCenter = d->target->anchors()->horizontalCenter();
+ d->rewindTop = d->target->anchors()->top();
+ d->rewindBottom = d->target->anchors()->bottom();
+ d->rewindVCenter = d->target->anchors()->verticalCenter();
+ d->rewindBaseline = d->target->anchors()->baseline();
+}
+
+#include <qdeclarativestateoperations.moc>
+#include <moc_qdeclarativestateoperations_p.cpp>
+
+QT_END_NAMESPACE
+