Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/util/qquicksmoothedanimation.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 "qquicksmoothedanimation_p.h" | - | ||||||||||||
41 | #include "qquicksmoothedanimation_p_p.h" | - | ||||||||||||
42 | - | |||||||||||||
43 | #include "qquickanimation_p_p.h" | - | ||||||||||||
44 | #include "private/qcontinuinganimationgroupjob_p.h" | - | ||||||||||||
45 | - | |||||||||||||
46 | #include <qmath.h> | - | ||||||||||||
47 | #include <qqmlproperty.h> | - | ||||||||||||
48 | #include <private/qqmlproperty_p.h> | - | ||||||||||||
49 | - | |||||||||||||
50 | #include <private/qqmlglobal_p.h> | - | ||||||||||||
51 | - | |||||||||||||
52 | #include <QtCore/qdebug.h> | - | ||||||||||||
53 | - | |||||||||||||
54 | - | |||||||||||||
55 | #define DELAY_STOP_TIMER_INTERVAL 32 | - | ||||||||||||
56 | - | |||||||||||||
57 | QT_BEGIN_NAMESPACE | - | ||||||||||||
58 | - | |||||||||||||
59 | - | |||||||||||||
60 | QSmoothedAnimationTimer::QSmoothedAnimationTimer(QSmoothedAnimation *animation, QObject *parent) | - | ||||||||||||
61 | : QTimer(parent) | - | ||||||||||||
62 | , m_animation(animation) | - | ||||||||||||
63 | { | - | ||||||||||||
64 | connect(this, SIGNAL(timeout()), this, SLOT(stopAnimation())); | - | ||||||||||||
65 | } executed 10652 times by 13 tests: end of block Executed by:
| 10652 | ||||||||||||
66 | - | |||||||||||||
67 | QSmoothedAnimationTimer::~QSmoothedAnimationTimer() | - | ||||||||||||
68 | { | - | ||||||||||||
69 | } | - | ||||||||||||
70 | - | |||||||||||||
71 | void QSmoothedAnimationTimer::stopAnimation() | - | ||||||||||||
72 | { | - | ||||||||||||
73 | m_animation->stop(); | - | ||||||||||||
74 | } executed 195 times by 4 tests: end of block Executed by:
| 195 | ||||||||||||
75 | - | |||||||||||||
76 | QSmoothedAnimation::QSmoothedAnimation(QQuickSmoothedAnimationPrivate *priv) | - | ||||||||||||
77 | : QAbstractAnimationJob(), to(0), velocity(200), userDuration(-1), maximumEasingTime(-1), | - | ||||||||||||
78 | reversingMode(QQuickSmoothedAnimation::Eased), initialVelocity(0), | - | ||||||||||||
79 | trackVelocity(0), initialValue(0), invert(false), finalDuration(-1), lastTime(0), | - | ||||||||||||
80 | skipUpdate(false), delayedStopTimer(new QSmoothedAnimationTimer(this)), animationTemplate(priv) | - | ||||||||||||
81 | { | - | ||||||||||||
82 | delayedStopTimer->setInterval(DELAY_STOP_TIMER_INTERVAL); | - | ||||||||||||
83 | delayedStopTimer->setSingleShot(true); | - | ||||||||||||
84 | } executed 10652 times by 13 tests: end of block Executed by:
| 10652 | ||||||||||||
85 | - | |||||||||||||
86 | QSmoothedAnimation::~QSmoothedAnimation() | - | ||||||||||||
87 | { | - | ||||||||||||
88 | delete delayedStopTimer; | - | ||||||||||||
89 | if (animationTemplate) {
| 24-10612 | ||||||||||||
90 | if (target.object()) {
| 0-24 | ||||||||||||
91 | QHash<QQmlProperty, QSmoothedAnimation* >::iterator it = | - | ||||||||||||
92 | animationTemplate->activeAnimations.find(target); | - | ||||||||||||
93 | if (it != animationTemplate->activeAnimations.end() && it.value() == this)
| 0 | ||||||||||||
94 | animationTemplate->activeAnimations.erase(it); never executed: animationTemplate->activeAnimations.erase(it); | 0 | ||||||||||||
95 | } else { never executed: end of block | 0 | ||||||||||||
96 | //target is no longer valid, need to search linearly | - | ||||||||||||
97 | QHash<QQmlProperty, QSmoothedAnimation* >::iterator it; | - | ||||||||||||
98 | for (it = animationTemplate->activeAnimations.begin(); it != animationTemplate->activeAnimations.end(); ++it) {
| 0-24 | ||||||||||||
99 | if (it.value() == this) {
| 0-24 | ||||||||||||
100 | animationTemplate->activeAnimations.erase(it); | - | ||||||||||||
101 | break; executed 24 times by 3 tests: break; Executed by:
| 24 | ||||||||||||
102 | } | - | ||||||||||||
103 | } never executed: end of block | 0 | ||||||||||||
104 | } executed 24 times by 3 tests: end of block Executed by:
| 24 | ||||||||||||
105 | } | - | ||||||||||||
106 | } executed 10636 times by 12 tests: end of block Executed by:
| 10636 | ||||||||||||
107 | - | |||||||||||||
108 | void QSmoothedAnimation::restart() | - | ||||||||||||
109 | { | - | ||||||||||||
110 | initialVelocity = trackVelocity; | - | ||||||||||||
111 | if (isRunning())
| 9164-41531 | ||||||||||||
112 | init(); executed 9164 times by 4 tests: init(); Executed by:
| 9164 | ||||||||||||
113 | else | - | ||||||||||||
114 | start(); executed 41531 times by 11 tests: start(); Executed by:
| 41531 | ||||||||||||
115 | } | - | ||||||||||||
116 | - | |||||||||||||
117 | void QSmoothedAnimation::prepareForRestart() | - | ||||||||||||
118 | { | - | ||||||||||||
119 | initialVelocity = trackVelocity; | - | ||||||||||||
120 | if (isRunning()) {
| 15-50 | ||||||||||||
121 | //we are joining a new wrapper group while running, our times need to be restarted | - | ||||||||||||
122 | skipUpdate = true; | - | ||||||||||||
123 | init(); | - | ||||||||||||
124 | lastTime = 0; | - | ||||||||||||
125 | } else { executed 50 times by 2 tests: end of block Executed by:
| 50 | ||||||||||||
126 | skipUpdate = false; | - | ||||||||||||
127 | //we'll be started when the group starts, which will force an init() | - | ||||||||||||
128 | } executed 15 times by 2 tests: end of block Executed by:
| 15 | ||||||||||||
129 | } | - | ||||||||||||
130 | - | |||||||||||||
131 | void QSmoothedAnimation::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State /*oldState*/) | - | ||||||||||||
132 | { | - | ||||||||||||
133 | if (newState == QAbstractAnimationJob::Running)
| 40292-41572 | ||||||||||||
134 | init(); executed 41572 times by 13 tests: init(); Executed by:
| 41572 | ||||||||||||
135 | } executed 81864 times by 13 tests: end of block Executed by:
| 81864 | ||||||||||||
136 | - | |||||||||||||
137 | void QSmoothedAnimation::delayedStop() | - | ||||||||||||
138 | { | - | ||||||||||||
139 | if (!delayedStopTimer->isActive())
| 577-678 | ||||||||||||
140 | delayedStopTimer->start(); executed 678 times by 4 tests: delayedStopTimer->start(); Executed by:
| 678 | ||||||||||||
141 | } executed 1255 times by 4 tests: end of block Executed by:
| 1255 | ||||||||||||
142 | - | |||||||||||||
143 | int QSmoothedAnimation::duration() const | - | ||||||||||||
144 | { | - | ||||||||||||
145 | return -1; executed 49139 times by 13 tests: return -1; Executed by:
| 49139 | ||||||||||||
146 | } | - | ||||||||||||
147 | - | |||||||||||||
148 | bool QSmoothedAnimation::recalc() | - | ||||||||||||
149 | { | - | ||||||||||||
150 | s = to - initialValue; | - | ||||||||||||
151 | vi = initialVelocity; | - | ||||||||||||
152 | - | |||||||||||||
153 | s = (invert? -1.0: 1.0) * s;
| 4038-6910 | ||||||||||||
154 | - | |||||||||||||
155 | if (userDuration >= 0 && velocity > 0) {
| 4-6075 | ||||||||||||
156 | tf = s / velocity; | - | ||||||||||||
157 | if (tf > (userDuration / 1000.)) tf = (userDuration / 1000.); executed 5374 times by 3 tests: tf = (userDuration / 1000.); Executed by:
| 697-5374 | ||||||||||||
158 | } else if (userDuration >= 0) { executed 6071 times by 3 tests: end of block Executed by:
| 4-6071 | ||||||||||||
159 | tf = userDuration / 1000.; | - | ||||||||||||
160 | } else if (velocity > 0) { executed 4 times by 1 test: end of block Executed by:
| 0-4873 | ||||||||||||
161 | tf = s / velocity; | - | ||||||||||||
162 | } else { executed 4873 times by 4 tests: end of block Executed by:
| 4873 | ||||||||||||
163 | return false; never executed: return false; | 0 | ||||||||||||
164 | } | - | ||||||||||||
165 | - | |||||||||||||
166 | finalDuration = qCeil(tf * 1000.0); | - | ||||||||||||
167 | - | |||||||||||||
168 | if (maximumEasingTime == 0) {
| 0-10948 | ||||||||||||
169 | a = 0; | - | ||||||||||||
170 | d = 0; | - | ||||||||||||
171 | tp = 0; | - | ||||||||||||
172 | td = tf; | - | ||||||||||||
173 | vp = velocity; | - | ||||||||||||
174 | sp = 0; | - | ||||||||||||
175 | sd = s; | - | ||||||||||||
176 | } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) { never executed: end of block
| 0-10948 | ||||||||||||
177 | qreal met = maximumEasingTime / 1000.; | - | ||||||||||||
178 | /* tp| |td | - | ||||||||||||
179 | * vp_ _______ | - | ||||||||||||
180 | * / \ | - | ||||||||||||
181 | * vi_ / \ | - | ||||||||||||
182 | * \ | - | ||||||||||||
183 | * \ _ 0 | - | ||||||||||||
184 | * |ta| |ta| | - | ||||||||||||
185 | */ | - | ||||||||||||
186 | qreal ta = met / 2.; | - | ||||||||||||
187 | a = (s - (vi * tf - 0.5 * vi * ta)) / (tf * ta - ta * ta); | - | ||||||||||||
188 | - | |||||||||||||
189 | vp = vi + a * ta; | - | ||||||||||||
190 | d = vp / ta; | - | ||||||||||||
191 | tp = ta; | - | ||||||||||||
192 | sp = vi * ta + 0.5 * a * tp * tp; | - | ||||||||||||
193 | sd = sp + vp * (tf - 2 * ta); | - | ||||||||||||
194 | td = tf - ta; | - | ||||||||||||
195 | } else { never executed: end of block | 0 | ||||||||||||
196 | qreal c1 = 0.25 * tf * tf; | - | ||||||||||||
197 | qreal c2 = 0.5 * vi * tf - s; | - | ||||||||||||
198 | qreal c3 = -0.25 * vi * vi; | - | ||||||||||||
199 | - | |||||||||||||
200 | qreal a1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); | - | ||||||||||||
201 | - | |||||||||||||
202 | qreal tp1 = 0.5 * tf - 0.5 * vi / a1; | - | ||||||||||||
203 | qreal vp1 = a1 * tp1 + vi; | - | ||||||||||||
204 | - | |||||||||||||
205 | qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1; | - | ||||||||||||
206 | - | |||||||||||||
207 | a = a1; | - | ||||||||||||
208 | d = a1; | - | ||||||||||||
209 | tp = tp1; | - | ||||||||||||
210 | td = tp1; | - | ||||||||||||
211 | vp = vp1; | - | ||||||||||||
212 | sp = sp1; | - | ||||||||||||
213 | sd = sp1; | - | ||||||||||||
214 | } executed 10948 times by 6 tests: end of block Executed by:
| 10948 | ||||||||||||
215 | return true; executed 10948 times by 6 tests: return true; Executed by:
| 10948 | ||||||||||||
216 | } | - | ||||||||||||
217 | - | |||||||||||||
218 | qreal QSmoothedAnimation::easeFollow(qreal time_seconds) | - | ||||||||||||
219 | { | - | ||||||||||||
220 | qreal value; | - | ||||||||||||
221 | if (time_seconds < tp) {
| 2798-5931 | ||||||||||||
222 | trackVelocity = vi + time_seconds * a; | - | ||||||||||||
223 | value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds; | - | ||||||||||||
224 | } else if (time_seconds < td) { executed 5931 times by 6 tests: end of block Executed by:
| 0-5931 | ||||||||||||
225 | time_seconds -= tp; | - | ||||||||||||
226 | trackVelocity = vp; | - | ||||||||||||
227 | value = sp + time_seconds * vp; | - | ||||||||||||
228 | } else if (time_seconds < tf) { never executed: end of block
| 0-1543 | ||||||||||||
229 | time_seconds -= td; | - | ||||||||||||
230 | trackVelocity = vp - time_seconds * a; | - | ||||||||||||
231 | value = sd - 0.5 * d * time_seconds * time_seconds + vp * time_seconds; | - | ||||||||||||
232 | } else { executed 1543 times by 4 tests: end of block Executed by:
| 1543 | ||||||||||||
233 | trackVelocity = 0; | - | ||||||||||||
234 | value = s; | - | ||||||||||||
235 | delayedStop(); | - | ||||||||||||
236 | } executed 1255 times by 4 tests: end of block Executed by:
| 1255 | ||||||||||||
237 | - | |||||||||||||
238 | // to normalize 's' between [0..1], divide 'value' by 's' | - | ||||||||||||
239 | return value; executed 8729 times by 6 tests: return value; Executed by:
| 8729 | ||||||||||||
240 | } | - | ||||||||||||
241 | - | |||||||||||||
242 | void QSmoothedAnimation::updateCurrentTime(int t) | - | ||||||||||||
243 | { | - | ||||||||||||
244 | if (skipUpdate) {
| 50-8729 | ||||||||||||
245 | skipUpdate = false; | - | ||||||||||||
246 | return; executed 50 times by 2 tests: return; Executed by:
| 50 | ||||||||||||
247 | } | - | ||||||||||||
248 | - | |||||||||||||
249 | if (!isRunning() && !isPaused()) // This can happen if init() stops the animation in some cases
| 0-8727 | ||||||||||||
250 | return; never executed: return; | 0 | ||||||||||||
251 | - | |||||||||||||
252 | qreal time_seconds = qreal(t - lastTime) / 1000.; | - | ||||||||||||
253 | - | |||||||||||||
254 | qreal value = easeFollow(time_seconds); | - | ||||||||||||
255 | value *= (invert? -1.0: 1.0);
| 3199-5530 | ||||||||||||
256 | QQmlPropertyPrivate::write(target, initialValue + value, | - | ||||||||||||
257 | QQmlPropertyData::BypassInterceptor | - | ||||||||||||
258 | | QQmlPropertyData::DontRemoveBinding); | - | ||||||||||||
259 | } executed 8729 times by 6 tests: end of block Executed by:
| 8729 | ||||||||||||
260 | - | |||||||||||||
261 | void QSmoothedAnimation::init() | - | ||||||||||||
262 | { | - | ||||||||||||
263 | if (velocity == 0) {
| 0-50786 | ||||||||||||
264 | stop(); | - | ||||||||||||
265 | return; never executed: return; | 0 | ||||||||||||
266 | } | - | ||||||||||||
267 | - | |||||||||||||
268 | if (delayedStopTimer->isActive())
| 256-50530 | ||||||||||||
269 | delayedStopTimer->stop(); executed 256 times by 3 tests: delayedStopTimer->stop(); Executed by:
| 256 | ||||||||||||
270 | - | |||||||||||||
271 | initialValue = target.read().toReal(); | - | ||||||||||||
272 | lastTime = this->currentTime(); | - | ||||||||||||
273 | - | |||||||||||||
274 | if (to == initialValue) {
| 10948-39838 | ||||||||||||
275 | stop(); | - | ||||||||||||
276 | return; executed 39838 times by 11 tests: return; Executed by:
| 39838 | ||||||||||||
277 | } | - | ||||||||||||
278 | - | |||||||||||||
279 | bool hasReversed = trackVelocity != 0. &&
| 2697-8251 | ||||||||||||
280 | ((!invert) == ((initialValue - to) > 0));
| 180-2517 | ||||||||||||
281 | - | |||||||||||||
282 | if (hasReversed) {
| 180-10768 | ||||||||||||
283 | switch (reversingMode) { | - | ||||||||||||
284 | default: never executed: default: | 0 | ||||||||||||
285 | case QQuickSmoothedAnimation::Eased: executed 180 times by 2 tests: case QQuickSmoothedAnimation::Eased: Executed by:
| 180 | ||||||||||||
286 | initialVelocity = -trackVelocity; | - | ||||||||||||
287 | break; executed 180 times by 2 tests: break; Executed by:
| 180 | ||||||||||||
288 | case QQuickSmoothedAnimation::Sync: never executed: case QQuickSmoothedAnimation::Sync: | 0 | ||||||||||||
289 | QQmlPropertyPrivate::write(target, to, | - | ||||||||||||
290 | QQmlPropertyData::BypassInterceptor | - | ||||||||||||
291 | | QQmlPropertyData::DontRemoveBinding); | - | ||||||||||||
292 | trackVelocity = 0; | - | ||||||||||||
293 | stop(); | - | ||||||||||||
294 | return; never executed: return; | 0 | ||||||||||||
295 | case QQuickSmoothedAnimation::Immediate: never executed: case QQuickSmoothedAnimation::Immediate: | 0 | ||||||||||||
296 | initialVelocity = 0; | - | ||||||||||||
297 | break; never executed: break; | 0 | ||||||||||||
298 | } | - | ||||||||||||
299 | } | - | ||||||||||||
300 | - | |||||||||||||
301 | trackVelocity = initialVelocity; | - | ||||||||||||
302 | - | |||||||||||||
303 | invert = (to < initialValue); | - | ||||||||||||
304 | - | |||||||||||||
305 | if (!recalc()) {
| 0-10948 | ||||||||||||
306 | QQmlPropertyPrivate::write(target, to, | - | ||||||||||||
307 | QQmlPropertyData::BypassInterceptor | - | ||||||||||||
308 | | QQmlPropertyData::DontRemoveBinding); | - | ||||||||||||
309 | stop(); | - | ||||||||||||
310 | return; never executed: return; | 0 | ||||||||||||
311 | } | - | ||||||||||||
312 | } executed 10948 times by 6 tests: end of block Executed by:
| 10948 | ||||||||||||
313 | - | |||||||||||||
314 | void QSmoothedAnimation::debugAnimation(QDebug d) const | - | ||||||||||||
315 | { | - | ||||||||||||
316 | d << "SmoothedAnimationJob(" << hex << (const void *) this << dec << ")" << "duration:" << userDuration | - | ||||||||||||
317 | << "velocity:" << velocity << "target:" << target.object() << "property:" << target.name() | - | ||||||||||||
318 | << "to:" << to << "current velocity:" << trackVelocity; | - | ||||||||||||
319 | } never executed: end of block | 0 | ||||||||||||
320 | - | |||||||||||||
321 | /*! | - | ||||||||||||
322 | \qmltype SmoothedAnimation | - | ||||||||||||
323 | \instantiates QQuickSmoothedAnimation | - | ||||||||||||
324 | \inqmlmodule QtQuick | - | ||||||||||||
325 | \ingroup qtquick-transitions-animations | - | ||||||||||||
326 | \inherits NumberAnimation | - | ||||||||||||
327 | \brief Allows a property to smoothly track a value. | - | ||||||||||||
328 | - | |||||||||||||
329 | A SmoothedAnimation animates a property's value to a set target value | - | ||||||||||||
330 | using an ease in/out quad easing curve. When the target value changes, | - | ||||||||||||
331 | the easing curves used to animate between the old and new target values | - | ||||||||||||
332 | are smoothly spliced together to create a smooth movement to the new | - | ||||||||||||
333 | target value that maintains the current velocity. | - | ||||||||||||
334 | - | |||||||||||||
335 | The follow example shows one \l Rectangle tracking the position of another | - | ||||||||||||
336 | using SmoothedAnimation. The green rectangle's \c x and \c y values are | - | ||||||||||||
337 | bound to those of the red rectangle. Whenever these values change, the | - | ||||||||||||
338 | green rectangle smoothly animates to its new position: | - | ||||||||||||
339 | - | |||||||||||||
340 | \snippet qml/smoothedanimation.qml 0 | - | ||||||||||||
341 | - | |||||||||||||
342 | A SmoothedAnimation can be configured by setting the \l velocity at which the | - | ||||||||||||
343 | animation should occur, or the \l duration that the animation should take. | - | ||||||||||||
344 | If both the \l velocity and \l duration are specified, the one that results in | - | ||||||||||||
345 | the quickest animation is chosen for each change in the target value. | - | ||||||||||||
346 | - | |||||||||||||
347 | For example, animating from 0 to 800 will take 4 seconds if a velocity | - | ||||||||||||
348 | of 200 is set, will take 8 seconds with a duration of 8000 set, and will | - | ||||||||||||
349 | take 4 seconds with both a velocity of 200 and a duration of 8000 set. | - | ||||||||||||
350 | Animating from 0 to 20000 will take 10 seconds if a velocity of 200 is set, | - | ||||||||||||
351 | will take 8 seconds with a duration of 8000 set, and will take 8 seconds | - | ||||||||||||
352 | with both a velocity of 200 and a duration of 8000 set. | - | ||||||||||||
353 | - | |||||||||||||
354 | The default velocity of SmoothedAnimation is 200 units/second. Note that if the range of the | - | ||||||||||||
355 | value being animated is small, then the velocity will need to be adjusted | - | ||||||||||||
356 | appropriately. For example, the opacity of an item ranges from 0 - 1.0. | - | ||||||||||||
357 | To enable a smooth animation in this range the velocity will need to be | - | ||||||||||||
358 | set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity | - | ||||||||||||
359 | of 0.5 will take 2000 ms to complete. | - | ||||||||||||
360 | - | |||||||||||||
361 | Like any other animation type, a SmoothedAnimation can be applied in a | - | ||||||||||||
362 | number of ways, including transitions, behaviors and property value | - | ||||||||||||
363 | sources. The \l {Animation and Transitions in Qt Quick} documentation shows a | - | ||||||||||||
364 | variety of methods for creating animations. | - | ||||||||||||
365 | - | |||||||||||||
366 | \sa SpringAnimation, NumberAnimation, {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation} | - | ||||||||||||
367 | */ | - | ||||||||||||
368 | - | |||||||||||||
369 | QQuickSmoothedAnimation::QQuickSmoothedAnimation(QObject *parent) | - | ||||||||||||
370 | : QQuickNumberAnimation(*(new QQuickSmoothedAnimationPrivate), parent) | - | ||||||||||||
371 | { | - | ||||||||||||
372 | } executed 42 times by 3 tests: end of block Executed by:
| 42 | ||||||||||||
373 | - | |||||||||||||
374 | QQuickSmoothedAnimation::~QQuickSmoothedAnimation() | - | ||||||||||||
375 | { | - | ||||||||||||
376 | - | |||||||||||||
377 | } | - | ||||||||||||
378 | - | |||||||||||||
379 | QQuickSmoothedAnimationPrivate::QQuickSmoothedAnimationPrivate() | - | ||||||||||||
380 | : anim(new QSmoothedAnimation) | - | ||||||||||||
381 | { | - | ||||||||||||
382 | } executed 42 times by 3 tests: end of block Executed by:
| 42 | ||||||||||||
383 | - | |||||||||||||
384 | QQuickSmoothedAnimationPrivate::~QQuickSmoothedAnimationPrivate() | - | ||||||||||||
385 | { | - | ||||||||||||
386 | typedef QHash<QQmlProperty, QSmoothedAnimation* >::iterator ActiveAnimationsHashIt; | - | ||||||||||||
387 | - | |||||||||||||
388 | delete anim; | - | ||||||||||||
389 | for (ActiveAnimationsHashIt it = activeAnimations.begin(), end = activeAnimations.end(); it != end; ++it)
| 0-40 | ||||||||||||
390 | it.value()->clearTemplate(); never executed: it.value()->clearTemplate(); | 0 | ||||||||||||
391 | } executed 40 times by 3 tests: end of block Executed by:
| 40 | ||||||||||||
392 | - | |||||||||||||
393 | void QQuickSmoothedAnimationPrivate::updateRunningAnimations() | - | ||||||||||||
394 | { | - | ||||||||||||
395 | for (QSmoothedAnimation *ease : qAsConst(activeAnimations)) { | - | ||||||||||||
396 | ease->maximumEasingTime = anim->maximumEasingTime; | - | ||||||||||||
397 | ease->reversingMode = anim->reversingMode; | - | ||||||||||||
398 | ease->velocity = anim->velocity; | - | ||||||||||||
399 | ease->userDuration = anim->userDuration; | - | ||||||||||||
400 | ease->init(); | - | ||||||||||||
401 | } never executed: end of block | 0 | ||||||||||||
402 | } executed 34 times by 2 tests: end of block Executed by:
| 34 | ||||||||||||
403 | - | |||||||||||||
404 | QAbstractAnimationJob* QQuickSmoothedAnimation::transition(QQuickStateActions &actions, | - | ||||||||||||
405 | QQmlProperties &modified, | - | ||||||||||||
406 | TransitionDirection direction, | - | ||||||||||||
407 | QObject *defaultTarget) | - | ||||||||||||
408 | { | - | ||||||||||||
409 | Q_UNUSED(direction); | - | ||||||||||||
410 | Q_D(QQuickSmoothedAnimation); | - | ||||||||||||
411 | - | |||||||||||||
412 | const QQuickStateActions dataActions = QQuickPropertyAnimation::createTransitionActions(actions, modified, defaultTarget); | - | ||||||||||||
413 | - | |||||||||||||
414 | QContinuingAnimationGroupJob *wrapperGroup = new QContinuingAnimationGroupJob(); | - | ||||||||||||
415 | - | |||||||||||||
416 | if (!dataActions.isEmpty()) {
| 2-91 | ||||||||||||
417 | QSet<QAbstractAnimationJob*> anims; | - | ||||||||||||
418 | for (int i = 0; i < dataActions.size(); i++) {
| 91 | ||||||||||||
419 | QSmoothedAnimation *ease; | - | ||||||||||||
420 | bool isActive; | - | ||||||||||||
421 | if (!d->activeAnimations.contains(dataActions[i].property)) {
| 26-65 | ||||||||||||
422 | ease = new QSmoothedAnimation(d); | - | ||||||||||||
423 | d->activeAnimations.insert(dataActions[i].property, ease); | - | ||||||||||||
424 | ease->target = dataActions[i].property; | - | ||||||||||||
425 | isActive = false; | - | ||||||||||||
426 | } else { executed 26 times by 3 tests: end of block Executed by:
| 26 | ||||||||||||
427 | ease = d->activeAnimations.value(dataActions[i].property); | - | ||||||||||||
428 | isActive = true; | - | ||||||||||||
429 | } executed 65 times by 3 tests: end of block Executed by:
| 65 | ||||||||||||
430 | wrapperGroup->appendAnimation(initInstance(ease)); | - | ||||||||||||
431 | - | |||||||||||||
432 | ease->to = dataActions[i].toValue.toReal(); | - | ||||||||||||
433 | - | |||||||||||||
434 | // copying public members from main value holder animation | - | ||||||||||||
435 | ease->maximumEasingTime = d->anim->maximumEasingTime; | - | ||||||||||||
436 | ease->reversingMode = d->anim->reversingMode; | - | ||||||||||||
437 | ease->velocity = d->anim->velocity; | - | ||||||||||||
438 | ease->userDuration = d->anim->userDuration; | - | ||||||||||||
439 | - | |||||||||||||
440 | ease->initialVelocity = ease->trackVelocity; | - | ||||||||||||
441 | - | |||||||||||||
442 | if (isActive)
| 26-65 | ||||||||||||
443 | ease->prepareForRestart(); executed 65 times by 3 tests: ease->prepareForRestart(); Executed by:
| 65 | ||||||||||||
444 | anims.insert(ease); | - | ||||||||||||
445 | } executed 91 times by 3 tests: end of block Executed by:
| 91 | ||||||||||||
446 | - | |||||||||||||
447 | const auto copy = d->activeAnimations; | - | ||||||||||||
448 | for (QSmoothedAnimation *ease : copy) { | - | ||||||||||||
449 | if (!anims.contains(ease)) {
| 0-91 | ||||||||||||
450 | ease->clearTemplate(); | - | ||||||||||||
451 | d->activeAnimations.remove(ease->target); | - | ||||||||||||
452 | } never executed: end of block | 0 | ||||||||||||
453 | } executed 91 times by 3 tests: end of block Executed by:
| 91 | ||||||||||||
454 | } executed 91 times by 3 tests: end of block Executed by:
| 91 | ||||||||||||
455 | return wrapperGroup; executed 93 times by 3 tests: return wrapperGroup; Executed by:
| 93 | ||||||||||||
456 | } | - | ||||||||||||
457 | - | |||||||||||||
458 | /*! | - | ||||||||||||
459 | \qmlproperty enumeration QtQuick::SmoothedAnimation::reversingMode | - | ||||||||||||
460 | - | |||||||||||||
461 | Sets how the SmoothedAnimation behaves if an animation direction is reversed. | - | ||||||||||||
462 | - | |||||||||||||
463 | Possible values are: | - | ||||||||||||
464 | - | |||||||||||||
465 | \list | - | ||||||||||||
466 | \li SmoothedAnimation.Eased (default) - the animation will smoothly decelerate, and then reverse direction | - | ||||||||||||
467 | \li SmoothedAnimation.Immediate - the animation will immediately begin accelerating in the reverse direction, beginning with a velocity of 0 | - | ||||||||||||
468 | \li SmoothedAnimation.Sync - the property is immediately set to the target value | - | ||||||||||||
469 | \endlist | - | ||||||||||||
470 | */ | - | ||||||||||||
471 | QQuickSmoothedAnimation::ReversingMode QQuickSmoothedAnimation::reversingMode() const | - | ||||||||||||
472 | { | - | ||||||||||||
473 | Q_D(const QQuickSmoothedAnimation); | - | ||||||||||||
474 | return (QQuickSmoothedAnimation::ReversingMode) d->anim->reversingMode; executed 6 times by 1 test: return (QQuickSmoothedAnimation::ReversingMode) d->anim->reversingMode; Executed by:
| 6 | ||||||||||||
475 | } | - | ||||||||||||
476 | - | |||||||||||||
477 | void QQuickSmoothedAnimation::setReversingMode(ReversingMode m) | - | ||||||||||||
478 | { | - | ||||||||||||
479 | Q_D(QQuickSmoothedAnimation); | - | ||||||||||||
480 | if (d->anim->reversingMode == m)
| 0-4 | ||||||||||||
481 | return; never executed: return; | 0 | ||||||||||||
482 | - | |||||||||||||
483 | d->anim->reversingMode = m; | - | ||||||||||||
484 | emit reversingModeChanged(); | - | ||||||||||||
485 | d->updateRunningAnimations(); | - | ||||||||||||
486 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||
487 | - | |||||||||||||
488 | /*! | - | ||||||||||||
489 | \qmlproperty int QtQuick::SmoothedAnimation::duration | - | ||||||||||||
490 | - | |||||||||||||
491 | This property holds the animation duration, in msecs, used when tracking the source. | - | ||||||||||||
492 | - | |||||||||||||
493 | Setting this to -1 (the default) disables the duration value. | - | ||||||||||||
494 | - | |||||||||||||
495 | If the velocity value and the duration value are both enabled, then the animation will | - | ||||||||||||
496 | use whichever gives the shorter duration. | - | ||||||||||||
497 | */ | - | ||||||||||||
498 | int QQuickSmoothedAnimation::duration() const | - | ||||||||||||
499 | { | - | ||||||||||||
500 | Q_D(const QQuickSmoothedAnimation); | - | ||||||||||||
501 | return d->anim->userDuration; executed 6 times by 1 test: return d->anim->userDuration; Executed by:
| 6 | ||||||||||||
502 | } | - | ||||||||||||
503 | - | |||||||||||||
504 | void QQuickSmoothedAnimation::setDuration(int duration) | - | ||||||||||||
505 | { | - | ||||||||||||
506 | Q_D(QQuickSmoothedAnimation); | - | ||||||||||||
507 | if (duration != -1)
| 0-10 | ||||||||||||
508 | QQuickNumberAnimation::setDuration(duration); executed 10 times by 2 tests: QQuickNumberAnimation::setDuration(duration); Executed by:
| 10 | ||||||||||||
509 | if(duration == d->anim->userDuration)
| 0-10 | ||||||||||||
510 | return; never executed: return; | 0 | ||||||||||||
511 | d->anim->userDuration = duration; | - | ||||||||||||
512 | d->updateRunningAnimations(); | - | ||||||||||||
513 | } executed 10 times by 2 tests: end of block Executed by:
| 10 | ||||||||||||
514 | - | |||||||||||||
515 | qreal QQuickSmoothedAnimation::velocity() const | - | ||||||||||||
516 | { | - | ||||||||||||
517 | Q_D(const QQuickSmoothedAnimation); | - | ||||||||||||
518 | return d->anim->velocity; executed 6 times by 1 test: return d->anim->velocity; Executed by:
| 6 | ||||||||||||
519 | } | - | ||||||||||||
520 | - | |||||||||||||
521 | /*! | - | ||||||||||||
522 | \qmlproperty real QtQuick::SmoothedAnimation::velocity | - | ||||||||||||
523 | - | |||||||||||||
524 | This property holds the average velocity allowed when tracking the 'to' value. | - | ||||||||||||
525 | - | |||||||||||||
526 | The default velocity of SmoothedAnimation is 200 units/second. | - | ||||||||||||
527 | - | |||||||||||||
528 | Setting this to -1 disables the velocity value. | - | ||||||||||||
529 | - | |||||||||||||
530 | If the velocity value and the duration value are both enabled, then the animation will | - | ||||||||||||
531 | use whichever gives the shorter duration. | - | ||||||||||||
532 | */ | - | ||||||||||||
533 | void QQuickSmoothedAnimation::setVelocity(qreal v) | - | ||||||||||||
534 | { | - | ||||||||||||
535 | Q_D(QQuickSmoothedAnimation); | - | ||||||||||||
536 | if (d->anim->velocity == v)
| 6-18 | ||||||||||||
537 | return; executed 6 times by 1 test: return; Executed by:
| 6 | ||||||||||||
538 | - | |||||||||||||
539 | d->anim->velocity = v; | - | ||||||||||||
540 | emit velocityChanged(); | - | ||||||||||||
541 | d->updateRunningAnimations(); | - | ||||||||||||
542 | } executed 18 times by 2 tests: end of block Executed by:
| 18 | ||||||||||||
543 | - | |||||||||||||
544 | /*! | - | ||||||||||||
545 | \qmlproperty int QtQuick::SmoothedAnimation::maximumEasingTime | - | ||||||||||||
546 | - | |||||||||||||
547 | This property specifies the maximum time, in msecs, any "eases" during the follow should take. | - | ||||||||||||
548 | Setting this property causes the velocity to "level out" after at a time. Setting | - | ||||||||||||
549 | a negative value reverts to the normal mode of easing over the entire animation | - | ||||||||||||
550 | duration. | - | ||||||||||||
551 | - | |||||||||||||
552 | The default value is -1. | - | ||||||||||||
553 | */ | - | ||||||||||||
554 | int QQuickSmoothedAnimation::maximumEasingTime() const | - | ||||||||||||
555 | { | - | ||||||||||||
556 | Q_D(const QQuickSmoothedAnimation); | - | ||||||||||||
557 | return d->anim->maximumEasingTime; executed 6 times by 1 test: return d->anim->maximumEasingTime; Executed by:
| 6 | ||||||||||||
558 | } | - | ||||||||||||
559 | - | |||||||||||||
560 | void QQuickSmoothedAnimation::setMaximumEasingTime(int v) | - | ||||||||||||
561 | { | - | ||||||||||||
562 | Q_D(QQuickSmoothedAnimation); | - | ||||||||||||
563 | if(v == d->anim->maximumEasingTime)
| 0-2 | ||||||||||||
564 | return; never executed: return; | 0 | ||||||||||||
565 | d->anim->maximumEasingTime = v; | - | ||||||||||||
566 | emit maximumEasingTimeChanged(); | - | ||||||||||||
567 | d->updateRunningAnimations(); | - | ||||||||||||
568 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||
569 | - | |||||||||||||
570 | QT_END_NAMESPACE | - | ||||||||||||
571 | - | |||||||||||||
572 | #include "moc_qquicksmoothedanimation_p.cpp" | - | ||||||||||||
Source code | Switch to Preprocessed file |