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 "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);