Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / qtquick1 / 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 "QtQuick1/private/qdeclarativebehavior_p.h"
43
44 #include "QtQuick1/private/qdeclarativeanimation_p.h"
45 #include "QtQuick1/private/qdeclarativetransition_p.h"
46
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>
52
53 #include <private/qobject_p.h>
54
55 QT_BEGIN_NAMESPACE
56
57
58
59 class QDeclarative1BehaviorPrivate : public QObjectPrivate
60 {
61     Q_DECLARE_PUBLIC(QDeclarative1Behavior)
62 public:
63     QDeclarative1BehaviorPrivate() : animation(0), enabled(true), finalized(false)
64       , blockRunningChanged(false) {}
65
66     QDeclarativeProperty property;
67     QVariant currentValue;
68     QVariant targetValue;
69     QDeclarativeGuard<QDeclarative1AbstractAnimation> animation;
70     bool enabled;
71     bool finalized;
72     bool blockRunningChanged;
73 };
74
75 /*!
76     \qmlclass Behavior QDeclarative1Behavior
77     \inqmlmodule QtQuick 1
78     \ingroup qml-animation-transition
79     \since QtQuick 1.0
80     \brief The Behavior element allows you to specify a default animation for a property change.
81
82     A Behavior defines the default animation to be applied whenever a
83     particular property value changes.
84
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:
88
89     \snippet doc/src/snippets/qtquick1/behavior.qml 0
90
91     Note that a property cannot have more than one assigned Behavior. To provide
92     multiple animations within a Behavior, use ParallelAnimation or
93     SequentialAnimation.
94
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}.
99
100     \sa {QML Animation and Transitions}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
101 */
102
103
104 QDeclarative1Behavior::QDeclarative1Behavior(QObject *parent)
105     : QObject(*(new QDeclarative1BehaviorPrivate), parent)
106 {
107 }
108
109 QDeclarative1Behavior::~QDeclarative1Behavior()
110 {
111 }
112
113 /*!
114     \qmlproperty Animation QtQuick1::Behavior::animation
115     \default
116
117     This property holds the animation to run when the behavior is triggered.
118 */
119
120 QDeclarative1AbstractAnimation *QDeclarative1Behavior::animation()
121 {
122     Q_D(QDeclarative1Behavior);
123     return d->animation;
124 }
125
126 void QDeclarative1Behavior::setAnimation(QDeclarative1AbstractAnimation *animation)
127 {
128     Q_D(QDeclarative1Behavior);
129     if (d->animation) {
130         qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
131         return;
132     }
133
134     d->animation = animation;
135     if (d->animation) {
136         d->animation->setDefaultTarget(d->property);
137         d->animation->setDisableUserControl();
138         connect(d->animation->qtAnimation(),
139                 SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
140                 this,
141                 SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
142     }
143 }
144
145
146 void QDeclarative1Behavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
147 {
148     Q_D(QDeclarative1Behavior);
149     if (!d->blockRunningChanged)
150         d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
151 }
152
153
154 /*!
155     \qmlproperty bool QtQuick1::Behavior::enabled
156
157     This property holds whether the behavior will be triggered when the tracked
158     property changes value.
159
160     By default a Behavior is enabled.
161 */
162
163 bool QDeclarative1Behavior::enabled() const
164 {
165     Q_D(const QDeclarative1Behavior);
166     return d->enabled;
167 }
168
169 void QDeclarative1Behavior::setEnabled(bool enabled)
170 {
171     Q_D(QDeclarative1Behavior);
172     if (d->enabled == enabled)
173         return;
174     d->enabled = enabled;
175     emit enabledChanged();
176 }
177
178 void QDeclarative1Behavior::write(const QVariant &value)
179 {
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;
185         return;
186     }
187
188     if (d->animation->isRunning() && value == d->targetValue)
189         return;
190
191     d->currentValue = d->property.read();
192     d->targetValue = value;
193
194     if (d->animation->qtAnimation()->duration() != -1
195             && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
196         d->blockRunningChanged = true;
197         d->animation->qtAnimation()->stop();
198     }
199
200     QDeclarative1StateOperation::ActionList actions;
201     QDeclarative1Action action;
202     action.property = d->property;
203     action.fromValue = d->currentValue;
204     action.toValue = value;
205     actions << action;
206
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);
213 }
214
215 void QDeclarative1Behavior::setTarget(const QDeclarativeProperty &property)
216 {
217     Q_D(QDeclarative1Behavior);
218     d->property = property;
219     d->currentValue = property.read();
220     if (d->animation)
221         d->animation->setDefaultTarget(property);
222
223     QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
224     engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
225 }
226
227 void QDeclarative1Behavior::componentFinalized()
228 {
229     Q_D(QDeclarative1Behavior);
230     d->finalized = true;
231 }
232
233
234
235 QT_END_NAMESPACE