source: trunk/src/declarative/util/qdeclarativebehavior.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "private/qdeclarativebehavior_p.h"
43
44#include "private/qdeclarativeanimation_p.h"
45#include "private/qdeclarativetransition_p.h"
46
47#include <qdeclarativecontext.h>
48#include <qdeclarativeinfo.h>
49#include <qdeclarativeproperty_p.h>
50#include <qdeclarativeguard_p.h>
51#include <qdeclarativeengine_p.h>
52
53#include <private/qobject_p.h>
54
55QT_BEGIN_NAMESPACE
56
57class QDeclarativeBehaviorPrivate : public QObjectPrivate
58{
59 Q_DECLARE_PUBLIC(QDeclarativeBehavior)
60public:
61 QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
62 , blockRunningChanged(false) {}
63
64 QDeclarativeProperty property;
65 QVariant currentValue;
66 QVariant targetValue;
67 QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
68 bool enabled;
69 bool finalized;
70 bool blockRunningChanged;
71};
72
73/*!
74 \qmlclass Behavior QDeclarativeBehavior
75 \ingroup qml-animation-transition
76 \since 4.7
77 \brief The Behavior element allows you to specify a default animation for a property change.
78
79 A Behavior defines the default animation to be applied whenever a
80 particular property value changes.
81
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:
85
86 \snippet doc/src/snippets/declarative/behavior.qml 0
87
88 Note that a property cannot have more than one assigned Behavior. To provide
89 multiple animations within a Behavior, use ParallelAnimation or
90 SequentialAnimation.
91
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.
95
96 \sa {QML Animation}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
97*/
98
99
100QDeclarativeBehavior::QDeclarativeBehavior(QObject *parent)
101 : QObject(*(new QDeclarativeBehaviorPrivate), parent)
102{
103}
104
105QDeclarativeBehavior::~QDeclarativeBehavior()
106{
107}
108
109/*!
110 \qmlproperty Animation Behavior::animation
111 \default
112
113 This property holds the animation to run when the behavior is triggered.
114*/
115
116QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation()
117{
118 Q_D(QDeclarativeBehavior);
119 return d->animation;
120}
121
122void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation)
123{
124 Q_D(QDeclarativeBehavior);
125 if (d->animation) {
126 qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
127 return;
128 }
129
130 d->animation = animation;
131 if (d->animation) {
132 d->animation->setDefaultTarget(d->property);
133 d->animation->setDisableUserControl();
134 connect(d->animation->qtAnimation(),
135 SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
136 this,
137 SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
138 }
139}
140
141
142void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
143{
144 Q_D(QDeclarativeBehavior);
145 if (!d->blockRunningChanged)
146 d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
147}
148
149
150/*!
151 \qmlproperty bool Behavior::enabled
152
153 This property holds whether the behavior will be triggered when the tracked
154 property changes value.
155
156 By default a Behavior is enabled.
157*/
158
159bool QDeclarativeBehavior::enabled() const
160{
161 Q_D(const QDeclarativeBehavior);
162 return d->enabled;
163}
164
165void QDeclarativeBehavior::setEnabled(bool enabled)
166{
167 Q_D(QDeclarativeBehavior);
168 if (d->enabled == enabled)
169 return;
170 d->enabled = enabled;
171 emit enabledChanged();
172}
173
174void QDeclarativeBehavior::write(const QVariant &value)
175{
176 Q_D(QDeclarativeBehavior);
177 qmlExecuteDeferred(this);
178 if (!d->animation || !d->enabled || !d->finalized) {
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 d->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 = d->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
211void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
212{
213 Q_D(QDeclarativeBehavior);
214 d->property = property;
215 d->currentValue = property.read();
216 if (d->animation)
217 d->animation->setDefaultTarget(property);
218
219 QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
220 engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
221}
222
223void QDeclarativeBehavior::componentFinalized()
224{
225 Q_D(QDeclarativeBehavior);
226 d->finalized = true;
227}
228
229QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.