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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "QtQuick1/private/qdeclarativebehavior_p.h"
44 #include "QtQuick1/private/qdeclarativeanimation_p.h"
45 #include "QtQuick1/private/qdeclarativetransition_p.h"
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeinfo.h>
49 #include <QtDeclarative/private/qdeclarativeproperty_p.h>
50 #include <QtDeclarative/private/qdeclarativeguard_p.h>
51 #include <QtDeclarative/private/qdeclarativeengine_p.h>
53 #include <private/qobject_p.h>
59 class QDeclarative1BehaviorPrivate : public QObjectPrivate
61 Q_DECLARE_PUBLIC(QDeclarative1Behavior)
63 QDeclarative1BehaviorPrivate() : animation(0), enabled(true), finalized(false)
64 , blockRunningChanged(false) {}
66 QDeclarativeProperty property;
67 QVariant currentValue;
69 QDeclarativeGuard<QDeclarative1AbstractAnimation> animation;
72 bool blockRunningChanged;
76 \qmlclass Behavior QDeclarative1Behavior
77 \inqmlmodule QtQuick 1
78 \ingroup qml-animation-transition
80 \brief The Behavior element allows you to specify a default animation for a property change.
82 A Behavior defines the default animation to be applied whenever a
83 particular property value changes.
85 For example, the following Behavior defines a NumberAnimation to be run
86 whenever the \l Rectangle's \c width value changes. When the MouseArea
87 is clicked, the \c width is changed, triggering the behavior's animation:
89 \snippet doc/src/snippets/qtquick1/behavior.qml 0
91 Note that a property cannot have more than one assigned Behavior. To provide
92 multiple animations within a Behavior, use ParallelAnimation or
95 If a \l{QML States}{state change} has a \l Transition that matches the same property as a
96 Behavior, the \l Transition animation overrides the Behavior for that
97 state change. For general advice on using Behaviors to animate state changes, see
98 \l{Using QML Behaviors with States}.
100 \sa {QML Animation and Transitions}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
104 QDeclarative1Behavior::QDeclarative1Behavior(QObject *parent)
105 : QObject(*(new QDeclarative1BehaviorPrivate), parent)
109 QDeclarative1Behavior::~QDeclarative1Behavior()
114 \qmlproperty Animation QtQuick1::Behavior::animation
117 This property holds the animation to run when the behavior is triggered.
120 QDeclarative1AbstractAnimation *QDeclarative1Behavior::animation()
122 Q_D(QDeclarative1Behavior);
126 void QDeclarative1Behavior::setAnimation(QDeclarative1AbstractAnimation *animation)
128 Q_D(QDeclarative1Behavior);
130 qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
134 d->animation = animation;
136 d->animation->setDefaultTarget(d->property);
137 d->animation->setDisableUserControl();
138 connect(d->animation->qtAnimation(),
139 SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
141 SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
146 void QDeclarative1Behavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
148 Q_D(QDeclarative1Behavior);
149 if (!d->blockRunningChanged)
150 d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
155 \qmlproperty bool QtQuick1::Behavior::enabled
157 This property holds whether the behavior will be triggered when the tracked
158 property changes value.
160 By default a Behavior is enabled.
163 bool QDeclarative1Behavior::enabled() const
165 Q_D(const QDeclarative1Behavior);
169 void QDeclarative1Behavior::setEnabled(bool enabled)
171 Q_D(QDeclarative1Behavior);
172 if (d->enabled == enabled)
174 d->enabled = enabled;
175 emit enabledChanged();
178 void QDeclarative1Behavior::write(const QVariant &value)
180 Q_D(QDeclarative1Behavior);
181 qmlExecuteDeferred(this);
182 if (!d->animation || !d->enabled || !d->finalized) {
183 QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
184 d->targetValue = value;
188 if (d->animation->isRunning() && value == d->targetValue)
191 d->currentValue = d->property.read();
192 d->targetValue = value;
194 if (d->animation->qtAnimation()->duration() != -1
195 && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
196 d->blockRunningChanged = true;
197 d->animation->qtAnimation()->stop();
200 QDeclarative1StateOperation::ActionList actions;
201 QDeclarative1Action action;
202 action.property = d->property;
203 action.fromValue = d->currentValue;
204 action.toValue = value;
207 QList<QDeclarativeProperty> after;
208 d->animation->transition(actions, after, QDeclarative1AbstractAnimation::Forward);
209 d->animation->qtAnimation()->start();
210 d->blockRunningChanged = false;
211 if (!after.contains(d->property))
212 QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
215 void QDeclarative1Behavior::setTarget(const QDeclarativeProperty &property)
217 Q_D(QDeclarative1Behavior);
218 d->property = property;
219 d->currentValue = property.read();
221 d->animation->setDefaultTarget(property);
223 QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
224 engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
227 void QDeclarative1Behavior::componentFinalized()
229 Q_D(QDeclarative1Behavior);