summaryrefslogtreecommitdiff
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickanimation.cpp487
-rw-r--r--src/quick/items/qquickanimation_p.h34
-rw-r--r--src/quick/items/qquickanimation_p_p.h44
-rw-r--r--src/quick/items/qquickcanvas.cpp4
-rw-r--r--src/quick/items/qquickcanvas_p.h1
-rw-r--r--src/quick/items/qquickgridview.cpp9
-rw-r--r--src/quick/items/qquicklistview.cpp8
7 files changed, 421 insertions, 166 deletions
diff --git a/src/quick/items/qquickanimation.cpp b/src/quick/items/qquickanimation.cpp
index 34377e92dd..517b504640 100644
--- a/src/quick/items/qquickanimation.cpp
+++ b/src/quick/items/qquickanimation.cpp
@@ -48,36 +48,66 @@
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtCore/qmath.h>
-#include <QtCore/qsequentialanimationgroup.h>
-#include <QtCore/qparallelanimationgroup.h>
+#include "private/qsequentialanimationgroupjob_p.h"
+#include "private/qparallelanimationgroupjob_p.h"
#include <QtGui/qtransform.h>
QT_BEGIN_NAMESPACE
-QQuickParentAnimation::QQuickParentAnimation(QObject *parent)
- : QDeclarativeAnimationGroup(*(new QQuickParentAnimationPrivate), parent)
-{
- Q_D(QQuickParentAnimation);
- d->topLevelGroup = new QSequentialAnimationGroup;
- QDeclarative_setParent_noEvent(d->topLevelGroup, this);
+/*!
+ \qmlclass ParentAnimation QQuickParentAnimation
+ \inqmlmodule QtQuick 2
+ \ingroup qml-animation-transition
+ \since QtQuick 2.0
+ \inherits Animation
+ \brief The ParentAnimation element animates changes in parent values.
+
+ ParentAnimation is used to animate a parent change for an \l Item.
- d->startAction = new QActionAnimation;
- QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
- d->topLevelGroup->addAnimation(d->startAction);
+ For example, the following ParentChange changes \c blueRect to become
+ a child of \c redRect when it is clicked. The inclusion of the
+ ParentAnimation, which defines a NumberAnimation to be applied during
+ the transition, ensures the item animates smoothly as it moves to
+ its new parent:
- d->ag = new QParallelAnimationGroup;
- QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
- d->topLevelGroup->addAnimation(d->ag);
+ \snippet doc/src/snippets/declarative/parentanimation.qml 0
- d->endAction = new QActionAnimation;
- QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
- d->topLevelGroup->addAnimation(d->endAction);
+ A ParentAnimation can contain any number of animations. These animations will
+ be run in parallel; to run them sequentially, define them within a
+ SequentialAnimation.
+
+ In some cases, such as when reparenting between items with clipping enabled, it is useful
+ to animate the parent change via another item that does not have clipping
+ enabled. Such an item can be set using the \l via property.
+
+ For convenience, when a ParentAnimation is used in a \l Transition, it will
+ animate any ParentChange that has occurred during the state change.
+ This can be overridden by setting a specific target item using the
+ \l target property.
+
+ Like any other animation element, a ParentAnimation can be applied in a
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
+
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
+*/
+QQuickParentAnimation::QQuickParentAnimation(QObject *parent)
+ : QDeclarativeAnimationGroup(*(new QQuickParentAnimationPrivate), parent)
+{
}
QQuickParentAnimation::~QQuickParentAnimation()
{
}
+/*!
+ \qmlproperty Item QtQuick2::ParentAnimation::target
+ The item to reparent.
+
+ When used in a transition, if no target is specified, all
+ ParentChange occurrences are animated by the ParentAnimation.
+*/
QQuickItem *QQuickParentAnimation::target() const
{
Q_D(const QQuickParentAnimation);
@@ -94,6 +124,15 @@ void QQuickParentAnimation::setTarget(QQuickItem *target)
emit targetChanged();
}
+/*!
+ \qmlproperty Item QtQuick2::ParentAnimation::newParent
+ The new parent to animate to.
+
+ If the ParentAnimation is defined within a \l Transition or \l Behavior,
+ this value defaults to the value defined in the end state of the
+ \l Transition, or the value of the property change that triggered the
+ \l Behavior.
+*/
QQuickItem *QQuickParentAnimation::newParent() const
{
Q_D(const QQuickParentAnimation);
@@ -110,6 +149,19 @@ void QQuickParentAnimation::setNewParent(QQuickItem *newParent)
emit newParentChanged();
}
+/*!
+ \qmlproperty Item QtQuick2::ParentAnimation::via
+ The item to reparent via. This provides a way to do an unclipped animation
+ when both the old parent and new parent are clipped.
+
+ \qml
+ ParentAnimation {
+ target: myItem
+ via: topLevelItem
+ // ...
+ }
+ \endqml
+*/
QQuickItem *QQuickParentAnimation::via() const
{
Q_D(const QQuickParentAnimation);
@@ -152,7 +204,7 @@ QPointF QQuickParentAnimationPrivate::computeTransformOrigin(QQuickItem::Transfo
}
}
-void QQuickParentAnimation::transition(QDeclarativeStateActions &actions,
+QAbstractAnimationJob* QQuickParentAnimation::transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction)
{
@@ -318,63 +370,105 @@ void QQuickParentAnimation::transition(QDeclarativeStateActions &actions,
}
}
+ QSequentialAnimationGroupJob *topLevelGroup = new QSequentialAnimationGroupJob;
+ QActionAnimation *viaAction = d->via ? new QActionAnimation : 0;
+ QActionAnimation *targetAction = new QActionAnimation;
+ //we'll assume the common case by far is to have children, and always create ag
+ QParallelAnimationGroupJob *ag = new QParallelAnimationGroupJob;
+
if (data->actions.count()) {
- if (direction == QDeclarativeAbstractAnimation::Forward) {
- d->startAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
- d->endAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
+ if (d->via)
+ viaAction->setAnimAction(viaData);
+ targetAction->setAnimAction(data);
+
+ //take care of any child animations
+ bool valid = d->defaultProperty.isValid();
+ QAbstractAnimationJob* anim;
+ for (int ii = 0; ii < d->animations.count(); ++ii) {
+ if (valid)
+ d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
+ anim = d->animations.at(ii)->transition(actions, modified, direction);
+ ag->appendAnimation(anim);
+ }
+
+ //TODO: simplify/clarify logic
+ bool forwards = direction == QDeclarativeAbstractAnimation::Forward;
+ if (forwards) {
+ topLevelGroup->appendAnimation(d->via ? viaAction : targetAction);
+ topLevelGroup->appendAnimation(ag);
+ if (d->via)
+ topLevelGroup->appendAnimation(targetAction);
} else {
- d->endAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
- d->startAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
+ if (d->via)
+ topLevelGroup->appendAnimation(targetAction);
+ topLevelGroup->appendAnimation(ag);
+ topLevelGroup->appendAnimation(d->via ? viaAction : targetAction);
}
} else {
delete data;
delete viaData;
}
- //take care of any child animations
- bool valid = d->defaultProperty.isValid();
- for (int ii = 0; ii < d->animations.count(); ++ii) {
- if (valid)
- d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
- d->animations.at(ii)->transition(actions, modified, direction);
- }
-
+ return initInstance(topLevelGroup);
}
-QAbstractAnimation *QQuickParentAnimation::qtAnimation()
-{
- Q_D(QQuickParentAnimation);
- return d->topLevelGroup;
-}
+/*!
+ \qmlclass AnchorAnimation QQuickAnchorAnimation
+ \inqmlmodule QtQuick 2
+ \ingroup qml-animation-transition
+ \inherits Animation
+ \brief The AnchorAnimation element animates changes in anchor values.
+
+ AnchorAnimation is used to animate an anchor change.
+ In the following snippet we animate the addition of a right anchor to a \l Rectangle:
+
+ \snippet doc/src/snippets/declarative/anchoranimation.qml 0
+
+ For convenience, when an AnchorAnimation is used in a \l Transition, it will
+ animate any AnchorChanges that have occurred during the state change.
+ This can be overridden by setting a specific target item using the
+ \l target property.
+
+ Like any other animation element, an AnchorAnimation can be applied in a
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
+
+ \sa {QML Animation and Transitions}, AnchorChanges
+*/
QQuickAnchorAnimation::QQuickAnchorAnimation(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QQuickAnchorAnimationPrivate), parent)
{
- Q_D(QQuickAnchorAnimation);
- d->va = new QDeclarativeBulkValueAnimator;
- QDeclarative_setParent_noEvent(d->va, this);
}
QQuickAnchorAnimation::~QQuickAnchorAnimation()
{
}
-QAbstractAnimation *QQuickAnchorAnimation::qtAnimation()
-{
- Q_D(QQuickAnchorAnimation);
- return d->va;
-}
+/*!
+ \qmlproperty list<Item> QtQuick2::AnchorAnimation::targets
+ The items to reanchor.
+ If no targets are specified all AnchorChanges will be
+ animated by the AnchorAnimation.
+*/
QDeclarativeListProperty<QQuickItem> QQuickAnchorAnimation::targets()
{
Q_D(QQuickAnchorAnimation);
return QDeclarativeListProperty<QQuickItem>(this, d->targets);
}
+/*!
+ \qmlproperty int QtQuick2::AnchorAnimation::duration
+ This property holds the duration of the animation, in milliseconds.
+
+ The default value is 250.
+*/
int QQuickAnchorAnimation::duration() const
{
Q_D(const QQuickAnchorAnimation);
- return d->va->duration();
+ return d->duration;
}
void QQuickAnchorAnimation::setDuration(int duration)
@@ -385,29 +479,47 @@ void QQuickAnchorAnimation::setDuration(int duration)
}
Q_D(QQuickAnchorAnimation);
- if (d->va->duration() == duration)
+ if (d->duration == duration)
return;
- d->va->setDuration(duration);
+ d->duration = duration;
emit durationChanged(duration);
}
+/*!
+ \qmlproperty enumeration QtQuick2::AnchorAnimation::easing.type
+ \qmlproperty real QtQuick2::AnchorAnimation::easing.amplitude
+ \qmlproperty real QtQuick2::AnchorAnimation::easing.overshoot
+ \qmlproperty real QtQuick2::AnchorAnimation::easing.period
+ \brief the easing curve used for the animation.
+
+ To specify an easing curve you need to specify at least the type. For some curves you can also specify
+ amplitude, period and/or overshoot. The default easing curve is
+ Linear.
+
+ \qml
+ AnchorAnimation { easing.type: Easing.InOutQuad }
+ \endqml
+
+ See the \l{PropertyAnimation::easing.type} documentation for information
+ about the different types of easing curves.
+*/
QEasingCurve QQuickAnchorAnimation::easing() const
{
Q_D(const QQuickAnchorAnimation);
- return d->va->easingCurve();
+ return d->easing;
}
void QQuickAnchorAnimation::setEasing(const QEasingCurve &e)
{
Q_D(QQuickAnchorAnimation);
- if (d->va->easingCurve() == e)
+ if (d->easing == e)
return;
- d->va->setEasingCurve(e);
+ d->easing = e;
emit easingChanged(e);
}
-void QQuickAnchorAnimation::transition(QDeclarativeStateActions &actions,
+QAbstractAnimationJob* QQuickAnchorAnimation::transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction)
{
@@ -416,7 +528,6 @@ void QQuickAnchorAnimation::transition(QDeclarativeStateActions &actions,
QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
data->interpolatorType = QMetaType::QReal;
data->interpolator = d->interpolator;
-
data->reverse = direction == Backward ? true : false;
data->fromSourced = false;
data->fromDefined = false;
@@ -429,35 +540,65 @@ void QQuickAnchorAnimation::transition(QDeclarativeStateActions &actions,
}
}
+ QDeclarativeBulkValueAnimator *animator = new QDeclarativeBulkValueAnimator;
if (data->actions.count()) {
- if (!d->rangeIsSet) {
- d->va->setStartValue(qreal(0));
- d->va->setEndValue(qreal(1));
- d->rangeIsSet = true;
- }
- d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
- d->va->setFromSourcedValue(&data->fromSourced);
+ animator->setAnimValue(data);
+ animator->setFromSourcedValue(&data->fromSourced);
} else {
delete data;
}
+
+ return initInstance(animator);
}
+/*!
+ \qmlclass PathAnimation QQuickPathAnimation
+ \inqmlmodule QtQuick 2
+ \ingroup qml-animation-transition
+ \inherits Animation
+ \brief The PathAnimation element animates an item along a path.
+
+ When used in a transition, the path can be specified without start
+ or end points, for example:
+ \qml
+ PathAnimation {
+ path: Path {
+ //no startX, startY
+ PathCurve { x: 100; y: 100}
+ PathCurve {} //last element is empty with no end point specified
+ }
+ }
+ \endqml
+
+ In the above case, the path start will be the item's current position, and the
+ path end will be the item's target position in the target state.
+
+ \sa {QML Animation and Transitions}, PathInterpolator
+*/
QQuickPathAnimation::QQuickPathAnimation(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QQuickPathAnimationPrivate), parent)
{
- Q_D(QQuickPathAnimation);
- d->pa = new QDeclarativeBulkValueAnimator;
- QDeclarative_setParent_noEvent(d->pa, this);
}
QQuickPathAnimation::~QQuickPathAnimation()
{
+ Q_D(QQuickPathAnimation);
+ QHash<QQuickItem*, QQuickPathAnimationAnimator* >::iterator it;
+ for (it = d->activeAnimations.begin(); it != d->activeAnimations.end(); ++it) {
+ it.value()->clearTemplate();
+ }
}
+/*!
+ \qmlproperty int QtQuick2::PathAnimation::duration
+ This property holds the duration of the animation, in milliseconds.
+
+ The default value is 250.
+*/
int QQuickPathAnimation::duration() const
{
Q_D(const QQuickPathAnimation);
- return d->pa->duration();
+ return d->duration;
}
void QQuickPathAnimation::setDuration(int duration)
@@ -468,28 +609,48 @@ void QQuickPathAnimation::setDuration(int duration)
}
Q_D(QQuickPathAnimation);
- if (d->pa->duration() == duration)
+ if (d->duration == duration)
return;
- d->pa->setDuration(duration);
+ d->duration = duration;
emit durationChanged(duration);
}
+/*!
+ \qmlproperty enumeration QtQuick2::PathAnimation::easing.type
+ \qmlproperty real QtQuick2::PathAnimation::easing.amplitude
+ \qmlproperty list<real> QtQuick2::PathAnimation::easing.bezierCurve
+ \qmlproperty real QtQuick2::PathAnimation::easing.overshoot
+ \qmlproperty real QtQuick2::PathAnimation::easing.period
+ \brief the easing curve used for the animation.
+
+ To specify an easing curve you need to specify at least the type. For some curves you can also specify
+ amplitude, period, overshoot or custom bezierCurve data. The default easing curve is \c Easing.Linear.
+
+ See the \l{PropertyAnimation::easing.type} documentation for information
+ about the different types of easing curves.
+*/
QEasingCurve QQuickPathAnimation::easing() const
{
Q_D(const QQuickPathAnimation);
- return d->pa->easingCurve();
+ return d->easingCurve;
}
void QQuickPathAnimation::setEasing(const QEasingCurve &e)
{
Q_D(QQuickPathAnimation);
- if (d->pa->easingCurve() == e)
+ if (d->easingCurve == e)
return;
- d->pa->setEasingCurve(e);
+ d->easingCurve = e;
emit easingChanged(e);
}
+/*!
+ \qmlproperty Path QtQuick2::PathAnimation::path
+ This property holds the path to animate along.
+
+ For more information on defining a path see the \l Path documentation.
+*/
QDeclarativePath *QQuickPathAnimation::path() const
{
Q_D(const QQuickPathAnimation);
@@ -506,6 +667,10 @@ void QQuickPathAnimation::setPath(QDeclarativePath *path)
emit pathChanged();
}
+/*!
+ \qmlproperty Item QtQuick2::PathAnimation::target
+ This property holds the item to animate.
+*/
QQuickItem *QQuickPathAnimation::target() const
{
Q_D(const QQuickPathAnimation);
@@ -522,6 +687,22 @@ void QQuickPathAnimation::setTarget(QQuickItem *target)
emit targetChanged();
}
+/*!
+ \qmlproperty enumeration QtQuick2::PathAnimation::orientation
+ This property controls the rotation of the item as it animates along the path.
+
+ If a value other than \c Fixed is specified, the PathAnimation will rotate the
+ item to achieve the specified orientation as it travels along the path.
+
+ \list
+ \o PathAnimation.Fixed (default) - the PathAnimation will not control
+ the rotation of the item.
+ \o PathAnimation.RightFirst - The right side of the item will lead along the path.
+ \o PathAnimation.LeftFirst - The left side of the item will lead along the path.
+ \o PathAnimation.BottomFirst - The bottom of the item will lead along the path.
+ \o PathAnimation.TopFirst - The top of the item will lead along the path.
+ \endlist
+*/
QQuickPathAnimation::Orientation QQuickPathAnimation::orientation() const
{
Q_D(const QQuickPathAnimation);
@@ -538,6 +719,15 @@ void QQuickPathAnimation::setOrientation(Orientation orientation)
emit orientationChanged(d->orientation);
}
+/*!
+ \qmlproperty point QtQuick2::PathAnimation::anchorPoint
+ This property holds the anchor point for the item being animated.
+
+ By default, the upper-left corner of the target (its 0,0 point)
+ will be anchored to (or follow) the path. The anchorPoint property can be used to
+ specify a different point for anchoring. For example, specifying an anchorPoint of
+ 5,5 for a 10x10 item means the center of the item will follow the path.
+*/
QPointF QQuickPathAnimation::anchorPoint() const
{
Q_D(const QQuickPathAnimation);
@@ -554,36 +744,66 @@ void QQuickPathAnimation::setAnchorPoint(const QPointF &point)
emit anchorPointChanged(point);
}
-qreal QQuickPathAnimation::orientationEntryInterval() const
+/*!
+ \qmlproperty real QtQuick2::PathAnimation::orientationEntryDuration
+ This property holds the duration (in milliseconds) of the transition in to the orientation.
+
+ If an orientation has been specified for the PathAnimation, and the starting
+ rotation of the item does not match that given by the orientation,
+ orientationEntryDuration can be used to smoothly transition from the item's
+ starting rotation to the rotation given by the path orientation.
+*/
+int QQuickPathAnimation::orientationEntryDuration() const
{
Q_D(const QQuickPathAnimation);
- return d->entryInterval;
+ return d->entryDuration;
}
-void QQuickPathAnimation::setOrientationEntryInterval(qreal interval)
+void QQuickPathAnimation::setOrientationEntryDuration(int duration)
{
Q_D(QQuickPathAnimation);
- if (d->entryInterval == interval)
+ if (d->entryDuration == duration)
return;
- d->entryInterval = interval;
- emit orientationEntryIntervalChanged(interval);
+ d->entryDuration = duration;
+ emit orientationEntryDurationChanged(duration);
}
-qreal QQuickPathAnimation::orientationExitInterval() const
+/*!
+ \qmlproperty real QtQuick2::PathAnimation::orientationExitDuration
+ This property holds the duration (in milliseconds) of the transition out of the orientation.
+
+ If an orientation and endRotation have been specified for the PathAnimation,
+ orientationExitDuration can be used to smoothly transition from the rotation given
+ by the path orientation to the specified endRotation.
+*/
+int QQuickPathAnimation::orientationExitDuration() const
{
Q_D(const QQuickPathAnimation);
- return d->exitInterval;
+ return d->exitDuration;
}
-void QQuickPathAnimation::setOrientationExitInterval(qreal interval)
+void QQuickPathAnimation::setOrientationExitDuration(int duration)
{
Q_D(QQuickPathAnimation);
- if (d->exitInterval == interval)
+ if (d->exitDuration == duration)
return;
- d->exitInterval = interval;
- emit orientationExitIntervalChanged(interval);
+ d->exitDuration = duration;
+ emit orientationExitDurationChanged(duration);
}
+/*!
+ \qmlproperty real QtQuick2::PathAnimation::endRotation
+ This property holds the ending rotation for the target.
+
+ If an orientation has been specified for the PathAnimation,
+ and the path doesn't end with the item at the desired rotation,
+ the endRotation property can be used to manually specify an end
+ rotation.
+
+ This property is typically used with orientationExitDuration, as specifying
+ an endRotation without an orientationExitDuration may cause a jump to
+ the final rotation, rather than a smooth transition.
+*/
qreal QQuickPathAnimation::endRotation() const
{
Q_D(const QQuickPathAnimation);
@@ -600,24 +820,37 @@ void QQuickPathAnimation::setEndRotation(qreal rotation)
emit endRotationChanged(d->endRotation);
}
-
-QAbstractAnimation *QQuickPathAnimation::qtAnimation()
-{
- Q_D(QQuickPathAnimation);
- return d->pa;
-}
-
-void QQuickPathAnimation::transition(QDeclarativeStateActions &actions,
+QAbstractAnimationJob* QQuickPathAnimation::transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction)
{
Q_D(QQuickPathAnimation);
- QQuickPathAnimationUpdater *data = new QQuickPathAnimationUpdater;
+
+ QQuickPathAnimationUpdater prevData;
+ bool havePrevData = false;
+ if (d->activeAnimations.contains(d->target)) {
+ havePrevData = true;
+ prevData = *d->activeAnimations[d->target]->pathUpdater();
+ }
+
+ QList<QQuickItem*> keys = d->activeAnimations.keys();
+ foreach (QQuickItem *item, keys) {
+ QQuickPathAnimationAnimator *anim = d->activeAnimations.value(item);
+ if (anim->state() == QAbstractAnimationJob::Stopped) {
+ anim->clearTemplate();
+ d->activeAnimations.remove(item);
+ }
+ }
+
+ QQuickPathAnimationUpdater *data = new QQuickPathAnimationUpdater();
+ QQuickPathAnimationAnimator *pa = new QQuickPathAnimationAnimator(d);
+
+ d->activeAnimations[d->target] = pa;
data->orientation = d->orientation;
data->anchorPoint = d->anchorPoint;
- data->entryInterval = d->entryInterval;
- data->exitInterval = d->exitInterval;
+ data->entryInterval = d->duration ? qreal(d->entryDuration) / d->duration : qreal(0);
+ data->exitInterval = d->duration ? qreal(d->exitDuration) / d->duration : qreal(0);
data->endRotation = d->endRotation;
data->reverse = direction == Backward ? true : false;
data->fromSourced = false;
@@ -645,46 +878,42 @@ void QQuickPathAnimation::transition(QDeclarativeStateActions &actions,
(modified.count() > origModifiedSize || data->toDefined)) {
data->target = d->target;
data->path = d->path;
- if (!d->rangeIsSet) {
- d->pa->setStartValue(qreal(0));
- d->pa->setEndValue(qreal(1));
- d->rangeIsSet = true;
- }
- /*
- NOTE: The following block relies on the fact that the previous value hasn't
- yet been deleted, and has the same target, etc, which may be a bit fragile.
- */
- if (d->pa->getAnimValue()) {
- QQuickPathAnimationUpdater *prevData = static_cast<QQuickPathAnimationUpdater*>(d->pa->getAnimValue());
+ data->path->invalidateSequentialHistory();
+ if (havePrevData) {
// get the original start angle that was used (so we can exactly reverse).
- data->startRotation = prevData->startRotation;
+ data->startRotation = prevData.startRotation;
// treat interruptions specially, otherwise we end up with strange paths
- if ((data->reverse || prevData->reverse) && prevData->currentV > 0 && prevData->currentV < 1) {
- if (!data->fromDefined && !data->toDefined && !prevData->painterPath.isEmpty()) {
- QPointF pathPos = QDeclarativePath::sequentialPointAt(prevData->painterPath, prevData->pathLength, prevData->attributePoints, prevData->prevBez, prevData->currentV);
- if (!prevData->anchorPoint.isNull())
- pathPos -= prevData->anchorPoint;
+ if ((data->reverse || prevData.reverse) && prevData.currentV > 0 && prevData.currentV < 1) {
+ if (!data->fromDefined && !data->toDefined && !prevData.painterPath.isEmpty()) {
+ QPointF pathPos = QDeclarativePath::sequentialPointAt(prevData.painterPath, prevData.pathLength, prevData.attributePoints, prevData.prevBez, prevData.currentV);
+ if (!prevData.anchorPoint.isNull())
+ pathPos -= prevData.anchorPoint;
if (pathPos == data->target->pos()) { //only treat as interruption if we interrupted ourself
- data->painterPath = prevData->painterPath;
+ data->painterPath = prevData.painterPath;
data->toDefined = data->fromDefined = data->fromSourced = true;
data->prevBez.isValid = false;
- data->interruptStart = prevData->currentV;
- data->startRotation = prevData->startRotation;
- data->pathLength = prevData->pathLength;
- data->attributePoints = prevData->attributePoints;
+ data->interruptStart = prevData.currentV;
+ data->startRotation = prevData.startRotation;
+ data->pathLength = prevData.pathLength;
+ data->attributePoints = prevData.attributePoints;
}
}
}
}
- d->pa->setFromSourcedValue(&data->fromSourced);
- d->pa->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ pa->setFromSourcedValue(&data->fromSourced);
+ pa->setAnimValue(data);
} else {
- d->pa->setFromSourcedValue(0);
- d->pa->setAnimValue(0, QAbstractAnimation::DeleteWhenStopped);
+ pa->setFromSourcedValue(0);
+ pa->setAnimValue(0);
+ delete pa;
delete data;
}
+
+ pa->setDuration(d->duration);
+ pa->setEasingCurve(d->easingCurve);
+ return initInstance(pa);
}
void QQuickPathAnimationUpdater::setValue(qreal v)
@@ -721,9 +950,7 @@ void QQuickPathAnimationUpdater::setValue(qreal v)
}
}
- //### could cache properties rather than reconstructing each time
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("x")), currentPos.x(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("y")), currentPos.y(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ target->setPos(currentPos);
//adjust angle according to orientation
if (!fixed) {
@@ -761,6 +988,7 @@ void QQuickPathAnimationUpdater::setValue(qreal v)
}
//smoothly transition to the desired orientation
+ //TODO: shortest distance calculations
if (startRotation.isValid()) {
if (reverse && v == 0.0)
angle = startRotation;
@@ -768,13 +996,13 @@ void QQuickPathAnimationUpdater::setValue(qreal v)
angle = angle * v / entryInterval + startRotation * (entryInterval - v) / entryInterval;
}
if (endRotation.isValid()) {
- qreal exitStart = 1 - exitInterval;
+ qreal exitStart = 1 - entryInterval;
if (!reverse && v == 1.0)
angle = endRotation;
else if (v > exitStart)
angle = endRotation * (v - exitStart) / exitInterval + angle * (exitInterval - (v - exitStart)) / exitInterval;
}
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("rotation")), angle, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ target->setRotation(angle);
}
/*
@@ -789,4 +1017,19 @@ void QQuickPathAnimationUpdater::setValue(qreal v)
}
}
+QQuickPathAnimationAnimator::QQuickPathAnimationAnimator(QQuickPathAnimationPrivate *priv)
+ : animationTemplate(priv)
+{
+}
+
+QQuickPathAnimationAnimator::~QQuickPathAnimationAnimator()
+{
+ if (animationTemplate && pathUpdater()) {
+ QHash<QQuickItem*, QQuickPathAnimationAnimator* >::iterator it =
+ animationTemplate->activeAnimations.find(pathUpdater()->target);
+ if (it != animationTemplate->activeAnimations.end() && it.value() == this)
+ animationTemplate->activeAnimations.erase(it);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickanimation_p.h b/src/quick/items/qquickanimation_p.h
index 05d4ff61c7..f6de6da9fb 100644
--- a/src/quick/items/qquickanimation_p.h
+++ b/src/quick/items/qquickanimation_p.h
@@ -47,14 +47,12 @@
#include <QtQuick/private/qdeclarativeanimation_p.h>
-#include <QtCore/qabstractanimation.h>
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QQuickParentAnimationPrivate;
-class QQuickParentAnimation : public QDeclarativeAnimationGroup
+class Q_QUICK_PRIVATE_EXPORT QQuickParentAnimation : public QDeclarativeAnimationGroup
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickParentAnimation)
@@ -82,14 +80,13 @@ Q_SIGNALS:
void viaChanged();
protected:
- virtual void transition(QDeclarativeStateActions &actions,
+ virtual QAbstractAnimationJob* transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction);
- virtual QAbstractAnimation *qtAnimation();
};
class QQuickAnchorAnimationPrivate;
-class QQuickAnchorAnimation : public QDeclarativeAbstractAnimation
+class Q_QUICK_PRIVATE_EXPORT QQuickAnchorAnimation : public QDeclarativeAbstractAnimation
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnchorAnimation)
@@ -114,16 +111,15 @@ Q_SIGNALS:
void easingChanged(const QEasingCurve&);
protected:
- virtual void transition(QDeclarativeStateActions &actions,
+ virtual QAbstractAnimationJob* transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction);
- virtual QAbstractAnimation *qtAnimation();
};
class QQuickItem;
class QDeclarativePath;
class QQuickPathAnimationPrivate;
-class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QDeclarativeAbstractAnimation
+class Q_QUICK_PRIVATE_EXPORT QQuickPathAnimation : public QDeclarativeAbstractAnimation
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickPathAnimation)
@@ -134,8 +130,8 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QDeclarativeAbstractAnimati
Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
Q_PROPERTY(QPointF anchorPoint READ anchorPoint WRITE setAnchorPoint NOTIFY anchorPointChanged)
- Q_PROPERTY(qreal orientationEntryInterval READ orientationEntryInterval WRITE setOrientationEntryInterval NOTIFY orientationEntryIntervalChanged)
- Q_PROPERTY(qreal orientationExitInterval READ orientationExitInterval WRITE setOrientationExitInterval NOTIFY orientationExitIntervalChanged)
+ Q_PROPERTY(int orientationEntryDuration READ orientationEntryDuration WRITE setOrientationEntryDuration NOTIFY orientationEntryDurationChanged)
+ Q_PROPERTY(int orientationExitDuration READ orientationExitDuration WRITE setOrientationExitDuration NOTIFY orientationExitDurationChanged)
Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
public:
@@ -169,21 +165,19 @@ public:
QPointF anchorPoint() const;
void setAnchorPoint(const QPointF &point);
- qreal orientationEntryInterval() const;
- void setOrientationEntryInterval(qreal);
+ int orientationEntryDuration() const;
+ void setOrientationEntryDuration(int);
- qreal orientationExitInterval() const;
- void setOrientationExitInterval(qreal);
+ int orientationExitDuration() const;
+ void setOrientationExitDuration(int);
qreal endRotation() const;
void setEndRotation(qreal);
protected:
- virtual void transition(QDeclarativeStateActions &actions,
+ virtual QAbstractAnimationJob* transition(QDeclarativeStateActions &actions,
QDeclarativeProperties &modified,
TransitionDirection direction);
- virtual QAbstractAnimation *qtAnimation();
-
Q_SIGNALS:
void durationChanged(int);
void easingChanged(const QEasingCurve &);
@@ -191,8 +185,8 @@ Q_SIGNALS:
void targetChanged();
void orientationChanged(Orientation);
void anchorPointChanged(const QPointF &);
- void orientationEntryIntervalChanged(qreal);
- void orientationExitIntervalChanged(qreal);
+ void orientationEntryDurationChanged(qreal);
+ void orientationExitDurationChanged(qreal);
void endRotationChanged(qreal);
};
diff --git a/src/quick/items/qquickanimation_p_p.h b/src/quick/items/qquickanimation_p_p.h
index 4a4f839ae0..6bab7780db 100644
--- a/src/quick/items/qquickanimation_p_p.h
+++ b/src/quick/items/qquickanimation_p_p.h
@@ -65,18 +65,13 @@ class QQuickParentAnimationPrivate : public QDeclarativeAnimationGroupPrivate
{
Q_DECLARE_PUBLIC(QQuickParentAnimation)
public:
- QQuickParentAnimationPrivate()
- : QDeclarativeAnimationGroupPrivate(), target(0), newParent(0),
- via(0), topLevelGroup(0), startAction(0), endAction(0) {}
+ QQuickParentAnimationPrivate()
+ : QDeclarativeAnimationGroupPrivate(), target(0), newParent(0), via(0) {}
QQuickItem *target;
QQuickItem *newParent;
QQuickItem *via;
- QSequentialAnimationGroup *topLevelGroup;
- QActionAnimation *startAction;
- QActionAnimation *endAction;
-
QPointF computeTransformOrigin(QQuickItem::TransformOrigin origin, qreal width, qreal height) const;
};
@@ -84,12 +79,11 @@ class QQuickAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
{
Q_DECLARE_PUBLIC(QQuickAnchorAnimation)
public:
- QQuickAnchorAnimationPrivate() : rangeIsSet(false), va(0),
- interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
+ QQuickAnchorAnimationPrivate() : interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)), duration(250) {}
- bool rangeIsSet;
- QDeclarativeBulkValueAnimator *va;
QVariantAnimation::Interpolator interpolator;
+ int duration;
+ QEasingCurve easing;
QList<QQuickItem*> targets;
};
@@ -102,7 +96,7 @@ public:
entryInterval(0), exitInterval(0) {}
~QQuickPathAnimationUpdater() {}
- void setValue(qreal v);
+ void setValue(qreal v);
QDeclarativePath *path;
@@ -129,22 +123,38 @@ public:
QDeclarativeNullableValue<qreal> startRotation;
};
+class QQuickPathAnimationPrivate;
+class QQuickPathAnimationAnimator : public QDeclarativeBulkValueAnimator
+{
+public:
+ QQuickPathAnimationAnimator(QQuickPathAnimationPrivate * = 0);
+ ~QQuickPathAnimationAnimator();
+
+ void clearTemplate() { animationTemplate = 0; }
+
+ QQuickPathAnimationUpdater *pathUpdater() { return static_cast<QQuickPathAnimationUpdater*>(getAnimValue()); }
+private:
+ QQuickPathAnimationPrivate *animationTemplate;
+};
+
class QQuickPathAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
{
Q_DECLARE_PUBLIC(QQuickPathAnimation)
public:
QQuickPathAnimationPrivate() : path(0), target(0),
- rangeIsSet(false), orientation(QQuickPathAnimation::Fixed), entryInterval(0), exitInterval(0), pa(0) {}
+ orientation(QQuickPathAnimation::Fixed), entryDuration(0), exitDuration(0), duration(250) {}
QDeclarativePath *path;
QQuickItem *target;
- bool rangeIsSet;
QQuickPathAnimation::Orientation orientation;
+
QPointF anchorPoint;
- qreal entryInterval;
- qreal exitInterval;
+ qreal entryDuration;
+ qreal exitDuration;
QDeclarativeNullableValue<qreal> endRotation;
- QDeclarativeBulkValueAnimator *pa;
+ int duration;
+ QEasingCurve easingCurve;
+ QHash<QQuickItem*, QQuickPathAnimationAnimator* > activeAnimations;
};
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index fa7931a102..8866ec5436 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -55,13 +55,13 @@
#include <private/qguiapplication_p.h>
#include <QtGui/QInputPanel>
-#include <private/qabstractanimation_p.h>
+#include <QtCore/private/qabstractanimation_p.h>
#include <QtGui/qpainter.h>
#include <QtGui/qevent.h>
#include <QtGui/qmatrix4x4.h>
#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qabstractanimation.h>
+#include "private/qabstractanimation_p.h"
#include <QtDeclarative/qdeclarativeincubator.h>
#include <private/qdeclarativedebugtrace_p.h>
diff --git a/src/quick/items/qquickcanvas_p.h b/src/quick/items/qquickcanvas_p.h
index 82da4d092d..b75e5c92c8 100644
--- a/src/quick/items/qquickcanvas_p.h
+++ b/src/quick/items/qquickcanvas_p.h
@@ -188,7 +188,6 @@ private:
static void cleanupNodesOnShutdown(QQuickItem *);
};
-
Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickCanvasPrivate::FocusOptions)
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 594bbce220..f25f2f8196 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -216,6 +216,11 @@ public:
, snapMode(QQuickGridView::NoSnap)
, highlightXAnimator(0), highlightYAnimator(0)
{}
+ ~QQuickGridViewPrivate()
+ {
+ delete highlightXAnimator;
+ delete highlightYAnimator;
+ }
};
Qt::Orientation QQuickGridViewPrivate::layoutOrientation() const
@@ -641,10 +646,10 @@ void QQuickGridViewPrivate::createHighlight()
FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true);
if (autoHighlight)
resetHighlightPosition();
- highlightXAnimator = new QSmoothedAnimation(q);
+ highlightXAnimator = new QSmoothedAnimation;
highlightXAnimator->target = QDeclarativeProperty(item, QLatin1String("x"));
highlightXAnimator->userDuration = highlightMoveDuration;
- highlightYAnimator = new QSmoothedAnimation(q);
+ highlightYAnimator = new QSmoothedAnimation;
highlightYAnimator->target = QDeclarativeProperty(item, QLatin1String("y"));
highlightYAnimator->userDuration = highlightMoveDuration;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 80681f7dd7..38b157b07b 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -168,6 +168,10 @@ public:
, sectionCriteria(0), currentSectionItem(0), nextSectionItem(0)
, overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
{}
+ ~QQuickListViewPrivate() {
+ delete highlightPosAnimator;
+ delete highlightSizeAnimator;
+ }
friend class QQuickViewSection;
};
@@ -790,13 +794,13 @@ void QQuickListViewPrivate::createHighlight()
newHighlight->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
}
const QLatin1String posProp(orient == QQuickListView::Vertical ? "y" : "x");
- highlightPosAnimator = new QSmoothedAnimation(q);
+ highlightPosAnimator = new QSmoothedAnimation;
highlightPosAnimator->target = QDeclarativeProperty(item, posProp);
highlightPosAnimator->velocity = highlightMoveSpeed;
highlightPosAnimator->userDuration = highlightMoveDuration;
const QLatin1String sizeProp(orient == QQuickListView::Vertical ? "height" : "width");
- highlightSizeAnimator = new QSmoothedAnimation(q);
+ highlightSizeAnimator = new QSmoothedAnimation;
highlightSizeAnimator->velocity = highlightResizeSpeed;
highlightSizeAnimator->userDuration = highlightResizeDuration;
highlightSizeAnimator->target = QDeclarativeProperty(item, sizeProp);