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