Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickanimationcontroller.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include <QtQml/qqmlinfo.h>
7#include <private/qqmlengine_p.h>
8
10
11
13{
14 Q_DECLARE_PUBLIC(QQuickAnimationController)
15public:
19 void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime) override;
20
21
25 bool finalized:1;
26
27};
28
29void QQuickAnimationControllerPrivate::animationFinished(QAbstractAnimationJob *job)
30{
31 Q_Q(QQuickAnimationController);
32 Q_ASSERT(animationInstance && animationInstance == job);
33 Q_UNUSED(job);
34
35 animationInstance->removeAnimationChangeListener(this, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
36
37 if (animationInstance->direction() == QAbstractAnimationJob::Forward && progress != 1) {
38 progress = 1;
39 emit q->progressChanged();
40 } else if (animationInstance->direction() == QAbstractAnimationJob::Backward && progress != 0) {
41 progress = 0;
42 emit q->progressChanged();
43 }
44
45}
46
47void QQuickAnimationControllerPrivate::animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime)
48{
49 Q_Q(QQuickAnimationController);
50 Q_ASSERT(animationInstance && animationInstance == job);
51 Q_UNUSED(job);
52 const qreal newProgress = currentTime * 1.0 / animationInstance->duration();
53 if (progress != newProgress) {
54 progress = newProgress;
55 emit q->progressChanged();
56 }
57}
58
59/*!
60 \qmltype AnimationController
61 \nativetype QQuickAnimationController
62 \inqmlmodule QtQuick
63 \ingroup qtquick-animation-control
64 \brief Enables manual control of animations.
65
66 Normally animations are driven by an internal timer, but the AnimationController
67 allows the given \a animation to be driven by a \a progress value explicitly.
68*/
69
70
71QQuickAnimationController::QQuickAnimationController(QObject *parent)
72: QObject(*(new QQuickAnimationControllerPrivate), parent)
73{
74}
75
76QQuickAnimationController::~QQuickAnimationController()
77{
78 Q_D(QQuickAnimationController);
79 delete d->animationInstance;
80}
81
82/*!
83 \qmlproperty real QtQuick::AnimationController::progress
84 This property holds the animation progress value.
85
86 The valid \c progress value is 0.0 to 1.0, setting values less than 0 will be converted to 0,
87 setting values great than 1 will be converted to 1.
88*/
89qreal QQuickAnimationController::progress() const
90{
91 Q_D(const QQuickAnimationController);
92 return d->progress;
93}
94
95void QQuickAnimationController::setProgress(qreal progress)
96{
97 Q_D(QQuickAnimationController);
98 progress = qBound(qreal(0), progress, qreal(1));
99
100 if (progress != d->progress) {
101 d->progress = progress;
102 updateProgress();
103 emit progressChanged();
104 }
105}
106
107/*!
108 \qmlproperty Animation QtQuick::AnimationController::animation
109 \qmldefault
110
111 This property holds the animation to be controlled by the AnimationController.
112
113 Note:An animation controlled by AnimationController will always have its
114 \c running and \c paused properties set to true. It can not be manually
115 started or stopped (much like an animation in a Behavior can not be manually started or stopped).
116*/
117QQuickAbstractAnimation *QQuickAnimationController::animation() const
118{
119 Q_D(const QQuickAnimationController);
120 return d->animation;
121}
122
123void QQuickAnimationController::setAnimation(QQuickAbstractAnimation *animation)
124{
125 Q_D(QQuickAnimationController);
126
127 if (animation != d->animation) {
128 if (animation) {
129 if (animation->userControlDisabled()) {
130 qmlWarning(this) << "QQuickAnimationController::setAnimation: the animation is controlled by others, can't be used in AnimationController.";
131 return;
132 }
133 animation->setDisableUserControl();
134 }
135
136 if (d->animation)
137 d->animation->setEnableUserControl();
138
139 d->animation = animation;
140 reload();
141 emit animationChanged();
142 }
143}
144
145/*!
146 \qmlmethod QtQuick::AnimationController::reload()
147 \brief Reloads the animation properties
148
149 If the animation properties changed, calling this method to reload the animation definations.
150*/
151void QQuickAnimationController::reload()
152{
153 Q_D(QQuickAnimationController);
154 if (!d->finalized)
155 return;
156
157 if (!d->animation) {
158 d->animationInstance = nullptr;
159 } else {
160 QQuickStateActions actions;
161 QQmlProperties properties;
162 QAbstractAnimationJob *oldInstance = d->animationInstance;
163 d->animationInstance = d->animation->transition(actions, properties, QQuickAbstractAnimation::Forward);
164 if (oldInstance && oldInstance != d->animationInstance)
165 delete oldInstance;
166 if (d->animationInstance) {
167 d->animationInstance->setLoopCount(1);
168 d->animationInstance->setDisableUserControl();
169 d->animationInstance->start();
170 d->animationInstance->pause();
171 updateProgress();
172 }
173 }
174}
175
176void QQuickAnimationController::updateProgress()
177{
178 Q_D(QQuickAnimationController);
179 if (!d->animationInstance)
180 return;
181
182 d->animationInstance->setDisableUserControl();
183 d->animationInstance->start();
184 QQmlAnimationTimer::instance()->unregisterAnimation(d->animationInstance);
185 d->animationInstance->setCurrentTime(d->progress * d->animationInstance->duration());
186}
187
188void QQuickAnimationController::componentFinalized()
189{
190 Q_D(QQuickAnimationController);
191 d->finalized = true;
192 reload();
193}
194
195/*!
196 \qmlmethod QtQuick::AnimationController::completeToBeginning()
197 \brief Finishes running the controlled animation in a backwards direction.
198
199 After calling this method, the animation runs normally from the current progress point
200 in a backwards direction to the beginning state.
201
202 The animation controller's progress value will be automatically updated while the animation is running.
203
204 \sa completeToEnd(), progress
205*/
206void QQuickAnimationController::completeToBeginning()
207{
208 Q_D(QQuickAnimationController);
209 if (!d->animationInstance)
210 return;
211
212 if (d->progress == 0)
213 return;
214
215 d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
216 d->animationInstance->setDirection(QAbstractAnimationJob::Backward);
217
218 //Disable and then enable user control to trigger the animation instance's state change
219 d->animationInstance->setDisableUserControl();
220 d->animationInstance->setEnableUserControl();
221 d->animationInstance->start();
222}
223
224/*!
225 \qmlmethod QtQuick::AnimationController::completeToEnd()
226 \brief Finishes running the controlled animation in a forwards direction.
227
228 After calling this method, the animation runs normally from the current progress point
229 in a forwards direction to the end state.
230
231 The animation controller's progress value will be automatically updated while the animation is running.
232
233 \sa completeToBeginning(), progress
234*/
235void QQuickAnimationController::completeToEnd()
236{
237 Q_D(QQuickAnimationController);
238 if (!d->animationInstance)
239 return;
240
241 if (d->progress == 1)
242 return;
243
244 d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
245 d->animationInstance->setDirection(QAbstractAnimationJob::Forward);
246
247 //Disable and then enable user control to trigger the animation instance's state change
248 d->animationInstance->setDisableUserControl();
249 d->animationInstance->setEnableUserControl();
250 d->animationInstance->start();
251}
252
253
254
255QT_END_NAMESPACE
256
257
258#include "moc_qquickanimationcontroller_p.cpp"
void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime) override