From a2511fc8cc122412ddf3955aec73a6b42c601d92 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Nov 2009 14:30:59 +1000 Subject: Distinguish between reversing and rewinding a state change. Task-number: QTBUG-5769 --- src/declarative/util/qmlpropertychanges.cpp | 14 ++- src/declarative/util/qmlstate.cpp | 4 + src/declarative/util/qmlstate_p.h | 5 +- src/declarative/util/qmlstateoperations.cpp | 147 ++++++++++++++++++-------- src/declarative/util/qmlstateoperations_p.h | 4 + src/declarative/util/qmltransitionmanager.cpp | 4 +- 6 files changed, 131 insertions(+), 47 deletions(-) diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index a1e92b5..28c8e4f 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -83,7 +83,8 @@ QT_BEGIN_NAMESPACE class QmlReplaceSignalHandler : public ActionEvent { public: - QmlReplaceSignalHandler() : expression(0), reverseExpression(0), ownedExpression(0) {} + QmlReplaceSignalHandler() : expression(0), reverseExpression(0), + rewindExpression(0), ownedExpression(0) {} ~QmlReplaceSignalHandler() { delete ownedExpression; } @@ -93,6 +94,7 @@ public: QmlMetaProperty property; QmlExpression *expression; QmlExpression *reverseExpression; + QmlExpression *rewindExpression; QGuard ownedExpression; virtual void execute() { @@ -104,7 +106,15 @@ public: ownedExpression = property.setSignalExpression(reverseExpression); } - virtual void saveOriginals() { reverseExpression = property.signalExpression(); } + virtual void saveOriginals() { + saveCurrentValues(); + reverseExpression = rewindExpression; + } + + virtual void rewind() { + ownedExpression = property.setSignalExpression(rewindExpression); + } + virtual void saveCurrentValues() { rewindExpression = property.signalExpression(); } virtual bool override(ActionEvent*other) { if (other == this) diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp index 1f5dbad..c05c539 100644 --- a/src/declarative/util/qmlstate.cpp +++ b/src/declarative/util/qmlstate.cpp @@ -362,6 +362,8 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever } if (!found || action.event != d->revertList.at(jj).event) action.event->saveOriginals(); + else if (action.event->isRewindable()) + action.event->saveCurrentValues(); } else { action.fromBinding = action.property.binding(); @@ -422,6 +424,8 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever a.specifiedProperty = d->revertList.at(ii).specifiedProperty; a.event = d->revertList.at(ii).event; a.reverseEvent = d->revertList.at(ii).reverseEvent; + if (a.event && a.event->isRewindable()) + a.event->saveCurrentValues(); applyList << a; // Store these special reverts in the reverting list d->reverting << d->revertList.at(ii).property; diff --git a/src/declarative/util/qmlstate_p.h b/src/declarative/util/qmlstate_p.h index 50c5401..856af8a 100644 --- a/src/declarative/util/qmlstate_p.h +++ b/src/declarative/util/qmlstate_p.h @@ -43,7 +43,6 @@ #define QMLSTATE_H #include -#include #include QT_BEGIN_HEADER @@ -91,6 +90,10 @@ public: virtual void reverse(); virtual void saveOriginals() {} + virtual bool isRewindable() { return isReversable(); } + virtual void rewind() {} + virtual void saveCurrentValues() {} + //virtual bool hasExtraActions(); virtual QList extraActions(); diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index 2d32fdb..0d977de 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -57,12 +57,15 @@ class QmlParentChangePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlParentChange) public: - QmlParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0) {} + QmlParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0), + rewindParent(0), rewindStackBefore(0) {} QmlGraphicsItem *target; QmlGraphicsItem *parent; QGuard origParent; QGuard origStackBefore; + QmlGraphicsItem *rewindParent; + QmlGraphicsItem *rewindStackBefore; void doChange(QmlGraphicsItem *targetParent, QmlGraphicsItem *stackBefore = 0); }; @@ -222,31 +225,9 @@ public: void QmlParentChange::saveOriginals() { Q_D(QmlParentChange); - if (!d->target) { - d->origParent = 0; - d->origStackBefore = 0; - return; - } - - d->origParent = d->target->parentItem(); - - if (!d->origParent) { - d->origStackBefore = 0; - return; - } - - //try to determine the item's original stack position so we can restore it - int siblingIndex = ((AccessibleFxItem*)d->target)->siblingIndex() + 1; - QList children = d->origParent->childItems(); - for (int i = 0; i < children.count(); ++i) { - QmlGraphicsItem *child = qobject_cast(children.at(i)); - if (!child) - continue; - if (((AccessibleFxItem*)child)->siblingIndex() == siblingIndex) { - d->origStackBefore = child; - break; - } - } + saveCurrentValues(); + d->origParent = d->rewindParent; + d->origStackBefore = d->rewindStackBefore; } void QmlParentChange::execute() @@ -281,6 +262,42 @@ bool QmlParentChange::override(ActionEvent*other) return false; } +void QmlParentChange::saveCurrentValues() +{ + Q_D(QmlParentChange); + 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 children = d->rewindParent->childItems(); + for (int i = 0; i < children.count(); ++i) { + QmlGraphicsItem *child = qobject_cast(children.at(i)); + if (!child) + continue; + if (((AccessibleFxItem*)child)->siblingIndex() == siblingIndex) { + d->rewindStackBefore = child; + break; + } + } +} + +void QmlParentChange::rewind() +{ + Q_D(QmlParentChange); + d->doChange(d->rewindParent, d->rewindStackBefore); +} + class QmlStateChangeScriptPrivate : public QObjectPrivate { public: @@ -399,10 +416,19 @@ public: QmlGraphicsAnchorLine origBottom; QmlGraphicsAnchorLine origVCenter; QmlGraphicsAnchorLine origBaseline; - qreal origX; - qreal origY; - qreal origWidth; - qreal origHeight; + + QmlGraphicsAnchorLine rewindLeft; + QmlGraphicsAnchorLine rewindRight; + QmlGraphicsAnchorLine rewindHCenter; + QmlGraphicsAnchorLine rewindTop; + QmlGraphicsAnchorLine rewindBottom; + QmlGraphicsAnchorLine rewindVCenter; + QmlGraphicsAnchorLine rewindBaseline; + + qreal fromX; + qreal fromY; + qreal fromWidth; + qreal fromHeight; }; /*! @@ -613,19 +639,19 @@ QList QmlAnchorChanges::extraActions() // we shouldn't set explicit width if there wasn't one before. if (d->target) { Action a; - a.fromValue = d->origX; + a.fromValue = d->fromX; a.property = QmlMetaProperty(d->target, QLatin1String("x")); extra << a; - a.fromValue = d->origY; + a.fromValue = d->fromY; a.property = QmlMetaProperty(d->target, QLatin1String("y")); extra << a; - a.fromValue = d->origWidth; + a.fromValue = d->fromWidth; a.property = QmlMetaProperty(d->target, QLatin1String("width")); extra << a; - a.fromValue = d->origHeight; + a.fromValue = d->fromHeight; a.property = QmlMetaProperty(d->target, QLatin1String("height")); extra << a; } @@ -648,15 +674,17 @@ void QmlAnchorChanges::saveOriginals() d->origBottom = d->target->anchors()->bottom(); d->origVCenter = d->target->anchors()->verticalCenter(); d->origBaseline = d->target->anchors()->baseline(); + + saveCurrentValues(); } void QmlAnchorChanges::clearForwardBindings() { Q_D(QmlAnchorChanges); - d->origX = d->target->x(); - d->origY = d->target->y(); - d->origWidth = d->target->width(); - d->origHeight = d->target->height(); + 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"))) @@ -694,10 +722,10 @@ void QmlAnchorChanges::clearForwardBindings() void QmlAnchorChanges::clearReverseBindings() { Q_D(QmlAnchorChanges); - d->origX = d->target->x(); - d->origY = d->target->y(); - d->origWidth = d->target->width(); - d->origHeight = d->target->height(); + 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 != QmlGraphicsAnchorLine::Invalid) @@ -743,6 +771,41 @@ bool QmlAnchorChanges::override(ActionEvent*other) return false; } +void QmlAnchorChanges::rewind() +{ + Q_D(QmlAnchorChanges); + if (!d->target) + return; + + //restore previous anchors + if (d->rewindLeft.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setLeft(d->rewindLeft); + if (d->rewindRight.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setRight(d->rewindRight); + if (d->rewindHCenter.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setHorizontalCenter(d->rewindHCenter); + if (d->rewindTop.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setTop(d->rewindTop); + if (d->rewindBottom.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setBottom(d->rewindBottom); + if (d->rewindVCenter.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setVerticalCenter(d->rewindVCenter); + if (d->rewindBaseline.anchorLine != QmlGraphicsAnchorLine::Invalid) + d->target->anchors()->setBaseline(d->rewindBaseline); +} + +void QmlAnchorChanges::saveCurrentValues() +{ + Q_D(QmlAnchorChanges); + 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 "qmlstateoperations.moc" #include "moc_qmlstateoperations_p.cpp" diff --git a/src/declarative/util/qmlstateoperations_p.h b/src/declarative/util/qmlstateoperations_p.h index a9488dc..589fe20 100644 --- a/src/declarative/util/qmlstateoperations_p.h +++ b/src/declarative/util/qmlstateoperations_p.h @@ -79,6 +79,8 @@ public: virtual void reverse(); virtual QString typeName() const; virtual bool override(ActionEvent*other); + virtual void rewind(); + virtual void saveCurrentValues(); }; class QmlStateChangeScriptPrivate; @@ -166,6 +168,8 @@ public: virtual void saveOriginals(); virtual void clearForwardBindings(); virtual void clearReverseBindings(); + virtual void rewind(); + virtual void saveCurrentValues(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qmltransitionmanager.cpp b/src/declarative/util/qmltransitionmanager.cpp index bae7e81..d1db9ec 100644 --- a/src/declarative/util/qmltransitionmanager.cpp +++ b/src/declarative/util/qmltransitionmanager.cpp @@ -173,11 +173,11 @@ void QmlTransitionManager::transition(const QList &list, if (action.event->isReversable()) { if (action.reverseEvent) { //reverse the reverse action.event->clearForwardBindings(); - action.event->execute(); + action.event->rewind(); action.event->clearReverseBindings(); } else { action.event->clearReverseBindings(); - action.event->reverse(); + action.event->rewind(); action.event->clearForwardBindings(); } } -- cgit v0.12