1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativebehavior_p.h"
44 #include "private/qdeclarativeanimation_p.h"
45 #include "private/qdeclarativetransition_p.h"
47 #include <qdeclarativecontext.h>
48 #include <qdeclarativeinfo.h>
49 #include <qdeclarativeproperty_p.h>
50 #include <qdeclarativeguard_p.h>
51 #include <qdeclarativeengine_p.h>
53 #include <private/qobject_p.h>
57 class QDeclarativeBehaviorPrivate : public QObjectPrivate
59 Q_DECLARE_PUBLIC(QDeclarativeBehavior)
61 QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
62 , blockRunningChanged(false) {}
64 QDeclarativeProperty property;
65 QVariant currentValue;
67 QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
70 bool blockRunningChanged;
74 \qmlclass Behavior QDeclarativeBehavior
75 \ingroup qml-animation-transition
77 \brief The Behavior element allows you to specify a default animation for a property change.
79 A Behavior defines the default animation to be applied whenever a
80 particular property value changes.
82 For example, the following Behavior defines a NumberAnimation to be run
83 whenever the \l Rectangle's \c width value changes. When the MouseArea
84 is clicked, the \c width is changed, triggering the behavior's animation:
86 \snippet doc/src/snippets/declarative/behavior.qml 0
88 Note that a property cannot have more than one assigned Behavior. To provide
89 multiple animations within a Behavior, use ParallelAnimation or
92 If a \l{QML States}{state change} has a \l Transition that matches the same property as a
93 Behavior, the \l Transition animation overrides the Behavior for that
94 state change. For general advice on using Behaviors to animate state changes, see
95 \l{Using QML Behaviors with States}.
97 \sa {QML Animation and Transitions}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
101 QDeclarativeBehavior::QDeclarativeBehavior(QObject *parent)
102 : QObject(*(new QDeclarativeBehaviorPrivate), parent)
106 QDeclarativeBehavior::~QDeclarativeBehavior()
111 \qmlproperty Animation Behavior::animation
114 This property holds the animation to run when the behavior is triggered.
117 QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation()
119 Q_D(QDeclarativeBehavior);
123 void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation)
125 Q_D(QDeclarativeBehavior);
127 qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
131 d->animation = animation;
133 d->animation->setDefaultTarget(d->property);
134 d->animation->setDisableUserControl();
135 connect(d->animation->qtAnimation(),
136 SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
138 SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
143 void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
145 Q_D(QDeclarativeBehavior);
146 if (!d->blockRunningChanged)
147 d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
152 \qmlproperty bool Behavior::enabled
154 This property holds whether the behavior will be triggered when the tracked
155 property changes value.
157 By default a Behavior is enabled.
160 bool QDeclarativeBehavior::enabled() const
162 Q_D(const QDeclarativeBehavior);
166 void QDeclarativeBehavior::setEnabled(bool enabled)
168 Q_D(QDeclarativeBehavior);
169 if (d->enabled == enabled)
171 d->enabled = enabled;
172 emit enabledChanged();
175 void QDeclarativeBehavior::write(const QVariant &value)
177 Q_D(QDeclarativeBehavior);
178 qmlExecuteDeferred(this);
179 if (!d->animation || !d->enabled || !d->finalized) {
180 QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
181 d->targetValue = value;
185 if (d->animation->isRunning() && value == d->targetValue)
188 d->currentValue = d->property.read();
189 d->targetValue = value;
191 if (d->animation->qtAnimation()->duration() != -1
192 && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
193 d->blockRunningChanged = true;
194 d->animation->qtAnimation()->stop();
197 QDeclarativeStateOperation::ActionList actions;
198 QDeclarativeAction action;
199 action.property = d->property;
200 action.fromValue = d->currentValue;
201 action.toValue = value;
204 QList<QDeclarativeProperty> after;
205 d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
206 d->animation->qtAnimation()->start();
207 d->blockRunningChanged = false;
208 if (!after.contains(d->property))
209 QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
212 void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
214 Q_D(QDeclarativeBehavior);
215 d->property = property;
216 d->currentValue = property.read();
218 d->animation->setDefaultTarget(property);
220 QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
221 engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
224 void QDeclarativeBehavior::componentFinalized()
226 Q_D(QDeclarativeBehavior);