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
qquickanimator.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
7
8#include <private/qquickitem_p.h>
9
11
12/*!
13 \qmltype Animator
14 \nativetype QQuickAnimator
15 \inqmlmodule QtQuick
16 \since 5.2
17 \ingroup qtquick-transitions-animations
18 \inherits Animation
19 \brief Is the base of all QML animators.
20
21 Animator types are a special type of animation which operate
22 directly on Qt Quick's scene graph, rather than the QML objects and their
23 properties like regular Animation types do. This has the benefit that
24 Animator based animations can animate on the \l
25 {Threaded Render Loop ('threaded')}{scene graph's rendering thread} even when the
26 UI thread is blocked.
27
28 The value of the QML property will be updated after the animation has
29 finished. The property is not updated while the animation is running.
30
31 The Animator types can be used just like any other Animation type.
32
33 \snippet qml/animators.qml mixed
34
35 If all sub-animations of ParallelAnimation and SequentialAnimation
36 are Animator types, the ParallelAnimation and SequentialAnimation will
37 also be treated as an Animator and be run on the scene graph's rendering
38 thread when possible.
39
40 The Animator types can be used for animations during transitions, but
41 they do not support the \l {Transition::reversible}{reversible}
42 property.
43
44 The Animator type cannot be used directly in a QML file. It exists
45 to provide a set of common properties and methods, available across all the
46 other animator types that inherit from it. Attempting to use the Animator
47 type directly will result in an error.
48 */
49
50QQuickAnimator::QQuickAnimator(QQuickAnimatorPrivate &dd, QObject *parent)
51 : QQuickAbstractAnimation(dd, parent)
52{
53}
54
55QQuickAnimator::QQuickAnimator(QObject *parent)
56 : QQuickAbstractAnimation(*new QQuickAnimatorPrivate, parent)
57{
58}
59
60/*!
61 \qmlproperty QtQuick::Item QtQuick::Animator::target
62
63 This property holds the target item of the animator.
64
65 \note Animator targets must be Item based types.
66 */
67
68void QQuickAnimator::setTargetItem(QQuickItem *target)
69{
70 Q_D(QQuickAnimator);
71 if (target == d->target)
72 return;
73 d->target = target;
74 Q_EMIT targetItemChanged(d->target);
75}
76
77QQuickItem *QQuickAnimator::targetItem() const
78{
79 Q_D(const QQuickAnimator);
80 return d->target;
81}
82
83/*!
84 \qmlproperty int QtQuick::Animator::duration
85 This property holds the duration of the animation in milliseconds.
86
87 The default value is 250.
88*/
89void QQuickAnimator::setDuration(int duration)
90{
91 Q_D(QQuickAnimator);
92 if (duration == d->duration)
93 return;
94 d->duration = duration;
95 Q_EMIT durationChanged(duration);
96}
97
98int QQuickAnimator::duration() const
99{
100 Q_D(const QQuickAnimator);
101 return d->duration;
102}
103
104/*!
105 \qmlpropertygroup QtQuick::Animator::easing
106 \qmlproperty enumeration QtQuick::Animator::easing.type
107 \qmlproperty real QtQuick::Animator::easing.amplitude
108 \qmlproperty real QtQuick::Animator::easing.overshoot
109 \qmlproperty real QtQuick::Animator::easing.period
110 \qmlproperty list<real> QtQuick::Animator::easing.bezierCurve
111 \include qquickanimation.cpp propertyanimation.easing
112*/
113
114void QQuickAnimator::setEasing(const QEasingCurve &easing)
115{
116 Q_D(QQuickAnimator);
117 if (easing == d->easing)
118 return;
119 d->easing = easing;
120 Q_EMIT easingChanged(d->easing);
121}
122
123QEasingCurve QQuickAnimator::easing() const
124{
125 Q_D(const QQuickAnimator);
126 return d->easing;
127}
128
129/*!
130 \qmlproperty real QtQuick::Animator::to
131 This property holds the end value for the animation.
132
133 If the Animator is defined within a \l Transition or \l Behavior,
134 this value defaults to the value defined in the end state of the
135 \l Transition, or the value of the property change that triggered the
136 \l Behavior.
137 */
138
139void QQuickAnimator::setTo(qreal to)
140{
141 Q_D(QQuickAnimator);
142 if (to == d->to)
143 return;
144 d->toIsDefined = true;
145 d->to = to;
146 Q_EMIT toChanged(d->to);
147}
148
149qreal QQuickAnimator::to() const
150{
151 Q_D(const QQuickAnimator);
152 return d->to;
153}
154
155/*!
156 \qmlproperty real QtQuick::Animator::from
157 This property holds the starting value for the animation.
158
159 If the Animator is defined within a \l Transition or \l Behavior,
160 this value defaults to the value defined in the starting state of the
161 \l Transition, or the current value of the property at the moment the
162 \l Behavior is triggered.
163
164 \sa {Animation and Transitions in Qt Quick}
165*/
166
167void QQuickAnimator::setFrom(qreal from)
168{
169 Q_D(QQuickAnimator);
170 d->fromIsDefined = true;
171 if (from == d->from)
172 return;
173 d->from = from;
174 Q_EMIT fromChanged(d->from);
175}
176
177qreal QQuickAnimator::from() const
178{
179 Q_D(const QQuickAnimator);
180 return d->from;
181}
182
183void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
184 const QString &propertyName,
185 QQuickStateActions &actions,
186 QQmlProperties &modified,
187 QObject *defaultTarget)
188{
189
190 if (actions.size()) {
191 for (int i=0; i<actions.size(); ++i) {
192 QQuickStateAction &action = actions[i];
193 if (action.property.name() != propertyName)
194 continue;
195 modified << action.property;
196
197 job->setTarget(qobject_cast<QQuickItem *>(action.property.object()));
198
199 if (fromIsDefined)
200 job->setFrom(from);
201 else if (action.fromValue.isValid())
202 job->setFrom(action.fromValue.toReal());
203 else
204 job->setFrom(action.property.read().toReal());
205
206 if (toIsDefined)
207 job->setTo(to);
208 else if (action.toValue.isValid())
209 job->setTo(action.toValue.toReal());
210 else
211 job->setTo(action.property.read().toReal());
212
213 // This magic line is in sync with what PropertyAnimation does
214 // and prevents the animation to end up in the "completeList"
215 // which forces action.toValue to be written directly to
216 // the item when a transition is cancelled.
217 action.fromValue = action.toValue;
218 }
219 }
220
221 if (modified.isEmpty()) {
222 job->setTarget(target);
223 if (fromIsDefined)
224 job->setFrom(from);
225 job->setTo(to);
226 }
227
228 if (!job->target()) {
229 if (defaultProperty.object())
230 job->setTarget(qobject_cast<QQuickItem *>(defaultProperty.object()));
231 else
232 job->setTarget(qobject_cast<QQuickItem *>(defaultTarget));
233 }
234
235 if (modified.isEmpty() && !fromIsDefined && job->target())
236 job->setFrom(job->target()->property(propertyName.toLatin1()).toReal());
237
238 job->setDuration(duration);
239 job->setLoopCount(loopCount);
240 job->setEasingCurve(easing);
241}
242
243QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
244 QQmlProperties &modified,
245 TransitionDirection direction,
246 QObject *defaultTarget)
247{
248 Q_D(QQuickAnimator);
249
250 if (d->defaultProperty.isValid() && propertyName() != d->defaultProperty.name()) {
251 qmlWarning(this) << "property name conflict: \""
252 << propertyName() << "\" != \"" << d->defaultProperty.name() << "\"";
253 return nullptr;
254 }
255
256 // The animation system cannot handle backwards uncontrolled animations.
257 if (direction == Backward)
258 return nullptr;
259
260 QQuickAnimatorJob *job = createJob();
261 if (!job)
262 return nullptr;
263
264 d->apply(job, propertyName(), actions, modified, defaultTarget);
265
266 if (!job->target()) {
267 delete job;
268 return nullptr;
269 }
270
271 return job;
272}
273
274/*!
275 \qmltype XAnimator
276 \nativetype QQuickXAnimator
277 \inqmlmodule QtQuick
278 \since 5.2
279 \ingroup qtquick-transitions-animations
280 \inherits Animator
281 \brief The XAnimator type animates the x position of an Item.
282
283 \l{Animator} types are different from normal Animation types. When
284 using an Animator, the animation can be run in the render thread
285 and the property value will jump to the end when the animation is
286 complete.
287
288 The value of Item::x is updated after the animation has finished.
289
290 The following snippet shows how to use a XAnimator together
291 with a Rectangle item.
292
293 \snippet qml/animators.qml x target
294
295 It is also possible to use the \c on keyword to tie the
296 XAnimator directly to an Item instance.
297
298 \snippet qml/animators.qml x on
299
300
301 */
302
303QQuickXAnimator::QQuickXAnimator(QObject *parent) : QQuickAnimator(parent) {}
304
305QQuickAnimatorJob *QQuickXAnimator::createJob() const { return new QQuickXAnimatorJob(); }
306
307/*!
308 \qmltype YAnimator
309 \nativetype QQuickYAnimator
310 \inqmlmodule QtQuick
311 \since 5.2
312 \ingroup qtquick-transitions-animations
313 \inherits Animator
314 \brief The YAnimator type animates the y position of an Item.
315
316 \l{Animator} types are different from normal Animation types. When
317 using an Animator, the animation can be run in the render thread
318 and the property value will jump to the end when the animation is
319 complete.
320
321 The value of Item::y is updated after the animation has finished.
322
323 The following snippet shows how to use a YAnimator together
324 with a Rectangle item.
325
326 \snippet qml/animators.qml y target
327
328 It is also possible to use the \c on keyword to tie the
329 YAnimator directly to an Item instance.
330
331 \snippet qml/animators.qml y on
332
333
334 */
335
336QQuickYAnimator::QQuickYAnimator(QObject *parent) : QQuickAnimator(parent) {}
337
338QQuickAnimatorJob *QQuickYAnimator::createJob() const { return new QQuickYAnimatorJob(); }
339
340/*!
341 \qmltype ScaleAnimator
342 \nativetype QQuickScaleAnimator
343 \inqmlmodule QtQuick
344 \since 5.2
345 \ingroup qtquick-transitions-animations
346 \inherits Animator
347 \brief The ScaleAnimator type animates the scale factor of an Item.
348
349 \l{Animator} types are different from normal Animation types. When
350 using an Animator, the animation can be run in the render thread
351 and the property value will jump to the end when the animation is
352 complete.
353
354 The value of Item::scale is updated after the animation has finished.
355
356 The following snippet shows how to use a ScaleAnimator together
357 with a Rectangle item.
358
359 \snippet qml/animators.qml scale target
360
361 It is also possible to use the \c on keyword to tie the
362 ScaleAnimator directly to an Item instance.
363
364 \snippet qml/animators.qml scale on
365
366 \sa Item::transformOrigin, RotationAnimator
367 */
368
369QQuickScaleAnimator::QQuickScaleAnimator(QObject *parent) : QQuickAnimator(parent) {}
370
371QQuickAnimatorJob *QQuickScaleAnimator::createJob() const { return new QQuickScaleAnimatorJob(); }
372
373/*!
374 \qmltype OpacityAnimator
375 \nativetype QQuickOpacityAnimator
376 \inqmlmodule QtQuick
377 \since 5.2
378 \ingroup qtquick-transitions-animations
379 \inherits Animator
380 \brief The OpacityAnimator type animates the opacity of an Item.
381
382 \l{Animator} types are different from normal Animation types. When
383 using an Animator, the animation can be run in the render thread
384 and the property value will jump to the end when the animation is
385 complete.
386
387 The value of Item::opacity is updated after the animation has finished.
388
389 The following snippet shows how to use a OpacityAnimator together
390 with a Rectangle item.
391
392 \snippet qml/animators.qml opacity target
393
394 It is also possible to use the \c on keyword to tie the
395 OpacityAnimator directly to an Item instance.
396
397 \snippet qml/animators.qml opacity on
398
399 */
400
401QQuickOpacityAnimator::QQuickOpacityAnimator(QObject *parent) : QQuickAnimator(parent) {}
402
403QQuickAnimatorJob *QQuickOpacityAnimator::createJob() const { return new QQuickOpacityAnimatorJob(); }
404
405/*!
406 \qmltype RotationAnimator
407 \nativetype QQuickRotationAnimator
408 \inqmlmodule QtQuick
409 \since 5.2
410 \ingroup qtquick-transitions-animations
411 \inherits Animator
412 \brief The RotationAnimator type animates the rotation of an Item.
413
414 \l{Animator} types are different from normal Animation types. When
415 using an Animator, the animation can be run in the render thread
416 and the property value will jump to the end when the animation is
417 complete.
418
419 The value of Item::rotation is updated after the animation has finished.
420
421 The following snippet shows how to use a RotationAnimator together
422 with a Rectangle item.
423
424 \snippet qml/animators.qml rotation target
425
426 It is also possible to use the \c on keyword to tie the
427 RotationAnimator directly to the \c rotation property of an Item
428 instance.
429
430 \snippet qml/animators.qml rotation on
431
432 \sa Item::transformOrigin, ScaleAnimator
433 */
434
435QQuickRotationAnimator::QQuickRotationAnimator(QObject *parent)
436 : QQuickAnimator(*new QQuickRotationAnimatorPrivate, parent)
437{
438}
439
440QQuickAnimatorJob *QQuickRotationAnimator::createJob() const {
441 Q_D(const QQuickRotationAnimator);
442 QQuickRotationAnimatorJob *job = new QQuickRotationAnimatorJob();
443 job->setDirection(d->direction);
444 return job;
445}
446
447/*!
448 \qmlproperty enumeration QtQuick::RotationAnimator::direction
449 This property holds the direction of the rotation.
450
451 Possible values are:
452
453 \value RotationAnimator.Numerical
454 (default) Rotate by linearly interpolating between the two numbers.
455 A rotation from 10 to 350 will rotate 340 degrees clockwise.
456 \value RotationAnimator.Clockwise
457 Rotate clockwise between the two values
458 \value RotationAnimator.Counterclockwise
459 Rotate counterclockwise between the two values
460 \value RotationAnimator.Shortest
461 Rotate in the direction that produces the shortest animation path.
462 A rotation from 10 to 350 will rotate 20 degrees counterclockwise.
463*/
464void QQuickRotationAnimator::setDirection(RotationDirection dir)
465{
466 Q_D(QQuickRotationAnimator);
467 if (d->direction == dir)
468 return;
469 d->direction = dir;
470 Q_EMIT directionChanged(d->direction);
471}
472
473QQuickRotationAnimator::RotationDirection QQuickRotationAnimator::direction() const
474{
475 Q_D(const QQuickRotationAnimator);
476 return d->direction;
477}
478
479#if QT_CONFIG(quick_shadereffect)
480/*!
481 \qmltype UniformAnimator
482 \nativetype QQuickUniformAnimator
483 \inqmlmodule QtQuick
484 \since 5.2
485 \ingroup qtquick-transitions-animations
486 \inherits Animator
487 \brief The UniformAnimator type animates a uniform of a ShaderEffect.
488
489 \l{Animator} types are different from normal Animation types. When
490 using an Animator, the animation can be run in the render thread
491 and the property value will jump to the end when the animation is
492 complete.
493
494 The value of the QML property defining the uniform is updated after
495 the animation has finished.
496
497 The following snippet shows how to use a UniformAnimator together
498 with a ShaderEffect item.
499
500 \snippet qml/animators.qml shader target
501
502 It is also possible to use the \c on keyword to tie the
503 UniformAnimator directly to a uniform of a ShaderEffect
504 instance.
505
506 \snippet qml/animators.qml shader on
507
508 \sa ShaderEffect, ShaderEffectSource
509 */
510
511QQuickUniformAnimator::QQuickUniformAnimator(QObject *parent)
512 : QQuickAnimator(*new QQuickUniformAnimatorPrivate, parent)
513{
514}
515
516/*!
517 \qmlproperty string QtQuick::UniformAnimator::uniform
518 This property holds the name of the uniform to animate.
519
520 The value of the uniform must correspond to both a property
521 on the target ShaderEffect and must be a uniform of type
522 \c float in the fragment or vertex shader.
523 */
524void QQuickUniformAnimator::setUniform(const QString &uniform)
525{
526 Q_D(QQuickUniformAnimator);
527 if (d->uniform == uniform)
528 return;
529 d->uniform = uniform;
530 Q_EMIT uniformChanged(d->uniform);
531}
532
533QString QQuickUniformAnimator::uniform() const
534{
535 Q_D(const QQuickUniformAnimator);
536 return d->uniform;
537}
538
539QString QQuickUniformAnimator::propertyName() const
540{
541 Q_D(const QQuickUniformAnimator);
542 if (!d->uniform.isEmpty())
543 return d->uniform;
544 return d->defaultProperty.name();
545}
546
547QQuickAnimatorJob *QQuickUniformAnimator::createJob() const
548{
549 QString u = propertyName();
550 if (u.isEmpty())
551 return nullptr;
552
553 QQuickUniformAnimatorJob *job = new QQuickUniformAnimatorJob();
554 job->setUniform(u.toLatin1());
555 return job;
556}
557#endif
558
559QT_END_NAMESPACE
560
561#include "moc_qquickanimator_p.cpp"
void apply(QQuickAnimatorJob *job, const QString &propertyName, QQuickStateActions &actions, QQmlProperties &modified, QObject *defaultTarget)
QList< QQmlProperty > QQmlProperties
QQuickStateOperation::ActionList QQuickStateActions