Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / quick / util / qdeclarativebehavior.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdeclarativebehavior_p.h"
43
44 #include "qdeclarativeanimation_p.h"
45 #include <qdeclarativecontext.h>
46 #include <qdeclarativeinfo.h>
47 #include <private/qdeclarativeproperty_p.h>
48 #include <private/qdeclarativeguard_p.h>
49 #include <private/qdeclarativeengine_p.h>
50
51 #include <private/qobject_p.h>
52
53 QT_BEGIN_NAMESPACE
54
55 class QDeclarativeBehaviorPrivate : public QObjectPrivate
56 {
57     Q_DECLARE_PUBLIC(QDeclarativeBehavior)
58 public:
59     QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
60       , blockRunningChanged(false) {}
61
62     QDeclarativeProperty property;
63     QVariant targetValue;
64     QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
65     bool enabled;
66     bool finalized;
67     bool blockRunningChanged;
68 };
69
70 /*!
71     \qmlclass Behavior QDeclarativeBehavior
72     \inqmlmodule QtQuick 2
73     \ingroup qml-animation-transition
74     \brief The Behavior element allows you to specify a default animation for a property change.
75
76     A Behavior defines the default animation to be applied whenever a
77     particular property value changes.
78
79     For example, the following Behavior defines a NumberAnimation to be run
80     whenever the \l Rectangle's \c width value changes. When the MouseArea
81     is clicked, the \c width is changed, triggering the behavior's animation:
82
83     \snippet doc/src/snippets/declarative/behavior.qml 0
84
85     Note that a property cannot have more than one assigned Behavior. To provide
86     multiple animations within a Behavior, use ParallelAnimation or
87     SequentialAnimation.
88
89     If a \l{QML States}{state change} has a \l Transition that matches the same property as a
90     Behavior, the \l Transition animation overrides the Behavior for that
91     state change. For general advice on using Behaviors to animate state changes, see
92     \l{Using QML Behaviors with States}.
93
94     \sa {QML Animation and Transitions}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
95 */
96
97
98 QDeclarativeBehavior::QDeclarativeBehavior(QObject *parent)
99     : QObject(*(new QDeclarativeBehaviorPrivate), parent)
100 {
101 }
102
103 QDeclarativeBehavior::~QDeclarativeBehavior()
104 {
105 }
106
107 /*!
108     \qmlproperty Animation QtQuick2::Behavior::animation
109     \default
110
111     This property holds the animation to run when the behavior is triggered.
112 */
113
114 QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation()
115 {
116     Q_D(QDeclarativeBehavior);
117     return d->animation;
118 }
119
120 void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation)
121 {
122     Q_D(QDeclarativeBehavior);
123     if (d->animation) {
124         qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
125         return;
126     }
127
128     d->animation = animation;
129     if (d->animation) {
130         d->animation->setDefaultTarget(d->property);
131         d->animation->setDisableUserControl();
132         FAST_CONNECT(d->animation->qtAnimation(),
133                      SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
134                      this,
135                      SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)))
136     }
137 }
138
139
140 void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
141 {
142     Q_D(QDeclarativeBehavior);
143     if (!d->blockRunningChanged)
144         d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
145 }
146
147
148 /*!
149     \qmlproperty bool QtQuick2::Behavior::enabled
150
151     This property holds whether the behavior will be triggered when the tracked
152     property changes value.
153
154     By default a Behavior is enabled.
155 */
156
157 bool QDeclarativeBehavior::enabled() const
158 {
159     Q_D(const QDeclarativeBehavior);
160     return d->enabled;
161 }
162
163 void QDeclarativeBehavior::setEnabled(bool enabled)
164 {
165     Q_D(QDeclarativeBehavior);
166     if (d->enabled == enabled)
167         return;
168     d->enabled = enabled;
169     emit enabledChanged();
170 }
171
172 void QDeclarativeBehavior::write(const QVariant &value)
173 {
174     Q_D(QDeclarativeBehavior);
175     bool bypass = !d->enabled || !d->finalized;
176     if (!bypass)
177         qmlExecuteDeferred(this);
178     if (!d->animation || bypass) {
179         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
180         d->targetValue = value;
181         return;
182     }
183
184     if (d->animation->isRunning() && value == d->targetValue)
185         return;
186
187     const QVariant &currentValue = d->property.read();
188     d->targetValue = value;
189
190     if (d->animation->qtAnimation()->duration() != -1
191             && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
192         d->blockRunningChanged = true;
193         d->animation->qtAnimation()->stop();
194     }
195
196     QDeclarativeStateOperation::ActionList actions;
197     QDeclarativeAction action;
198     action.property = d->property;
199     action.fromValue = currentValue;
200     action.toValue = value;
201     actions << action;
202
203     QList<QDeclarativeProperty> after;
204     d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
205     d->animation->qtAnimation()->start();
206     d->blockRunningChanged = false;
207     if (!after.contains(d->property))
208         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
209 }
210
211 void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
212 {
213     Q_D(QDeclarativeBehavior);
214     d->property = property;
215     if (d->animation)
216         d->animation->setDefaultTarget(property);
217
218     QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
219     engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
220 }
221
222 void QDeclarativeBehavior::componentFinalized()
223 {
224     Q_D(QDeclarativeBehavior);
225     d->finalized = true;
226 }
227
228 QT_END_NAMESPACE