qeasingcurve.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/tools/qeasingcurve.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtCore 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/*-
41-
42| *property* | *Used for type* |-
43| period | QEasingCurve::{In,Out,InOut,OutIn}Elastic |-
44| amplitude | QEasingCurve::{In,Out,InOut,OutIn}Bounce, QEasingCurve::{In,Out,InOut,OutIn}Elastic |-
45| overshoot | QEasingCurve::{In,Out,InOut,OutIn}Back |-
46-
47*/-
48-
49-
50-
51-
52/*!-
53 \class QEasingCurve-
54 \inmodule QtCore-
55 \since 4.6-
56 \ingroup animation-
57 \brief The QEasingCurve class provides easing curves for controlling animation.-
58-
59 Easing curves describe a function that controls how the speed of the interpolation-
60 between 0 and 1 should be. Easing curves allow transitions from-
61 one value to another to appear more natural than a simple constant speed would allow.-
62 The QEasingCurve class is usually used in conjunction with the QVariantAnimation and-
63 QPropertyAnimation classes but can be used on its own. It is usually used to accelerate-
64 the interpolation from zero velocity (ease in) or decelerate to zero velocity (ease out).-
65 Ease in and ease out can also be combined in the same easing curve.-
66-
67 To calculate the speed of the interpolation, the easing curve provides the function-
68 valueForProgress(), where the \a progress argument specifies the progress of the-
69 interpolation: 0 is the start value of the interpolation, 1 is the end value of the-
70 interpolation. The returned value is the effective progress of the interpolation.-
71 If the returned value is the same as the input value for all input values the easing-
72 curve is a linear curve. This is the default behaviour.-
73-
74 For example,-
75 \code-
76 QEasingCurve easing(QEasingCurve::InOutQuad);-
77-
78 for(qreal t = 0.0; t < 1.0; t+=0.1)-
79 qWarning() << "Effective progress" << t << " is-
80 << easing.valueForProgress(t);-
81 \endcode-
82 will print the effective progress of the interpolation between 0 and 1.-
83-
84 When using a QPropertyAnimation, the associated easing curve will be used to control the-
85 progress of the interpolation between startValue and endValue:-
86 \code-
87 QPropertyAnimation animation;-
88 animation.setStartValue(0);-
89 animation.setEndValue(1000);-
90 animation.setDuration(1000);-
91 animation.setEasingCurve(QEasingCurve::InOutQuad);-
92 \endcode-
93-
94 The ability to set an amplitude, overshoot, or period depends on-
95 the QEasingCurve type. Amplitude access is available to curves-
96 that behave as springs such as elastic and bounce curves. Changing-
97 the amplitude changes the height of the curve. Period access is-
98 only available to elastic curves and setting a higher period slows-
99 the rate of bounce. Only curves that have "boomerang" behaviors-
100 such as the InBack, OutBack, InOutBack, and OutInBack have-
101 overshoot settings. These curves will interpolate beyond the end-
102 points and return to the end point, acting similar to a boomerang.-
103-
104 The \l{Easing Curves Example} contains samples of QEasingCurve-
105 types and lets you change the curve settings.-
106-
107 */-
108-
109/*!-
110 \enum QEasingCurve::Type-
111-
112 The type of easing curve.-
113-
114 \value Linear \image qeasingcurve-linear.png-
115 \caption Easing curve for a linear (t) function:-
116 velocity is constant.-
117 \value InQuad \image qeasingcurve-inquad.png-
118 \caption Easing curve for a quadratic (t^2) function:-
119 accelerating from zero velocity.-
120 \value OutQuad \image qeasingcurve-outquad.png-
121 \caption Easing curve for a quadratic (t^2) function:-
122 decelerating to zero velocity.-
123 \value InOutQuad \image qeasingcurve-inoutquad.png-
124 \caption Easing curve for a quadratic (t^2) function:-
125 acceleration until halfway, then deceleration.-
126 \value OutInQuad \image qeasingcurve-outinquad.png-
127 \caption Easing curve for a quadratic (t^2) function:-
128 deceleration until halfway, then acceleration.-
129 \value InCubic \image qeasingcurve-incubic.png-
130 \caption Easing curve for a cubic (t^3) function:-
131 accelerating from zero velocity.-
132 \value OutCubic \image qeasingcurve-outcubic.png-
133 \caption Easing curve for a cubic (t^3) function:-
134 decelerating to zero velocity.-
135 \value InOutCubic \image qeasingcurve-inoutcubic.png-
136 \caption Easing curve for a cubic (t^3) function:-
137 acceleration until halfway, then deceleration.-
138 \value OutInCubic \image qeasingcurve-outincubic.png-
139 \caption Easing curve for a cubic (t^3) function:-
140 deceleration until halfway, then acceleration.-
141 \value InQuart \image qeasingcurve-inquart.png-
142 \caption Easing curve for a quartic (t^4) function:-
143 accelerating from zero velocity.-
144 \value OutQuart \image qeasingcurve-outquart.png-
145 \caption-
146 Easing curve for a quartic (t^4) function:-
147 decelerating to zero velocity.-
148 \value InOutQuart \image qeasingcurve-inoutquart.png-
149 \caption-
150 Easing curve for a quartic (t^4) function:-
151 acceleration until halfway, then deceleration.-
152 \value OutInQuart \image qeasingcurve-outinquart.png-
153 \caption-
154 Easing curve for a quartic (t^4) function:-
155 deceleration until halfway, then acceleration.-
156 \value InQuint \image qeasingcurve-inquint.png-
157 \caption-
158 Easing curve for a quintic (t^5) easing-
159 in: accelerating from zero velocity.-
160 \value OutQuint \image qeasingcurve-outquint.png-
161 \caption-
162 Easing curve for a quintic (t^5) function:-
163 decelerating to zero velocity.-
164 \value InOutQuint \image qeasingcurve-inoutquint.png-
165 \caption-
166 Easing curve for a quintic (t^5) function:-
167 acceleration until halfway, then deceleration.-
168 \value OutInQuint \image qeasingcurve-outinquint.png-
169 \caption-
170 Easing curve for a quintic (t^5) function:-
171 deceleration until halfway, then acceleration.-
172 \value InSine \image qeasingcurve-insine.png-
173 \caption-
174 Easing curve for a sinusoidal (sin(t)) function:-
175 accelerating from zero velocity.-
176 \value OutSine \image qeasingcurve-outsine.png-
177 \caption-
178 Easing curve for a sinusoidal (sin(t)) function:-
179 decelerating to zero velocity.-
180 \value InOutSine \image qeasingcurve-inoutsine.png-
181 \caption-
182 Easing curve for a sinusoidal (sin(t)) function:-
183 acceleration until halfway, then deceleration.-
184 \value OutInSine \image qeasingcurve-outinsine.png-
185 \caption-
186 Easing curve for a sinusoidal (sin(t)) function:-
187 deceleration until halfway, then acceleration.-
188 \value InExpo \image qeasingcurve-inexpo.png-
189 \caption-
190 Easing curve for an exponential (2^t) function:-
191 accelerating from zero velocity.-
192 \value OutExpo \image qeasingcurve-outexpo.png-
193 \caption-
194 Easing curve for an exponential (2^t) function:-
195 decelerating to zero velocity.-
196 \value InOutExpo \image qeasingcurve-inoutexpo.png-
197 \caption-
198 Easing curve for an exponential (2^t) function:-
199 acceleration until halfway, then deceleration.-
200 \value OutInExpo \image qeasingcurve-outinexpo.png-
201 \caption-
202 Easing curve for an exponential (2^t) function:-
203 deceleration until halfway, then acceleration.-
204 \value InCirc \image qeasingcurve-incirc.png-
205 \caption-
206 Easing curve for a circular (sqrt(1-t^2)) function:-
207 accelerating from zero velocity.-
208 \value OutCirc \image qeasingcurve-outcirc.png-
209 \caption-
210 Easing curve for a circular (sqrt(1-t^2)) function:-
211 decelerating to zero velocity.-
212 \value InOutCirc \image qeasingcurve-inoutcirc.png-
213 \caption-
214 Easing curve for a circular (sqrt(1-t^2)) function:-
215 acceleration until halfway, then deceleration.-
216 \value OutInCirc \image qeasingcurve-outincirc.png-
217 \caption-
218 Easing curve for a circular (sqrt(1-t^2)) function:-
219 deceleration until halfway, then acceleration.-
220 \value InElastic \image qeasingcurve-inelastic.png-
221 \caption-
222 Easing curve for an elastic-
223 (exponentially decaying sine wave) function:-
224 accelerating from zero velocity. The peak amplitude-
225 can be set with the \e amplitude parameter, and the-
226 period of decay by the \e period parameter.-
227 \value OutElastic \image qeasingcurve-outelastic.png-
228 \caption-
229 Easing curve for an elastic-
230 (exponentially decaying sine wave) function:-
231 decelerating to zero velocity. The peak amplitude-
232 can be set with the \e amplitude parameter, and the-
233 period of decay by the \e period parameter.-
234 \value InOutElastic \image qeasingcurve-inoutelastic.png-
235 \caption-
236 Easing curve for an elastic-
237 (exponentially decaying sine wave) function:-
238 acceleration until halfway, then deceleration.-
239 \value OutInElastic \image qeasingcurve-outinelastic.png-
240 \caption-
241 Easing curve for an elastic-
242 (exponentially decaying sine wave) function:-
243 deceleration until halfway, then acceleration.-
244 \value InBack \image qeasingcurve-inback.png-
245 \caption-
246 Easing curve for a back (overshooting-
247 cubic function: (s+1)*t^3 - s*t^2) easing in:-
248 accelerating from zero velocity.-
249 \value OutBack \image qeasingcurve-outback.png-
250 \caption-
251 Easing curve for a back (overshooting-
252 cubic function: (s+1)*t^3 - s*t^2) easing out:-
253 decelerating to zero velocity.-
254 \value InOutBack \image qeasingcurve-inoutback.png-
255 \caption-
256 Easing curve for a back (overshooting-
257 cubic function: (s+1)*t^3 - s*t^2) easing in/out:-
258 acceleration until halfway, then deceleration.-
259 \value OutInBack \image qeasingcurve-outinback.png-
260 \caption-
261 Easing curve for a back (overshooting-
262 cubic easing: (s+1)*t^3 - s*t^2) easing out/in:-
263 deceleration until halfway, then acceleration.-
264 \value InBounce \image qeasingcurve-inbounce.png-
265 \caption-
266 Easing curve for a bounce (exponentially-
267 decaying parabolic bounce) function: accelerating-
268 from zero velocity.-
269 \value OutBounce \image qeasingcurve-outbounce.png-
270 \caption-
271 Easing curve for a bounce (exponentially-
272 decaying parabolic bounce) function: decelerating-
273 from zero velocity.-
274 \value InOutBounce \image qeasingcurve-inoutbounce.png-
275 \caption-
276 Easing curve for a bounce (exponentially-
277 decaying parabolic bounce) function easing in/out:-
278 acceleration until halfway, then deceleration.-
279 \value OutInBounce \image qeasingcurve-outinbounce.png-
280 \caption-
281 Easing curve for a bounce (exponentially-
282 decaying parabolic bounce) function easing out/in:-
283 deceleration until halfway, then acceleration.-
284 \omitvalue InCurve-
285 \omitvalue OutCurve-
286 \omitvalue SineCurve-
287 \omitvalue CosineCurve-
288 \value BezierSpline Allows defining a custom easing curve using a cubic bezier spline-
289 \sa addCubicBezierSegment()-
290 \value TCBSpline Allows defining a custom easing curve using a TCB spline-
291 \sa addTCBSegment()-
292 \value Custom This is returned if the user specified a custom curve type with-
293 setCustomType(). Note that you cannot call setType() with this value,-
294 but type() can return it.-
295 \omitvalue NCurveTypes-
296*/-
297-
298/*!-
299 \typedef QEasingCurve::EasingFunction-
300-
301 This is a typedef for a pointer to a function with the following-
302 signature:-
303-
304 \snippet code/src_corelib_tools_qeasingcurve.cpp 0-
305*/-
306-
307#include "qeasingcurve.h"-
308#include <cmath>-
309-
310#ifndef QT_NO_DEBUG_STREAM-
311#include <QtCore/qdebug.h>-
312#include <QtCore/qstring.h>-
313#endif-
314-
315#ifndef QT_NO_DATASTREAM-
316#include <QtCore/qdatastream.h>-
317#endif-
318-
319#include <QtCore/qpoint.h>-
320#include <QtCore/qvector.h>-
321-
322QT_BEGIN_NAMESPACE-
323-
324static bool isConfigFunction(QEasingCurve::Type type)-
325{-
326 return (type >= QEasingCurve::InElastic-
327 && type <= QEasingCurve::OutInBounce) ||-
328 type == QEasingCurve::BezierSpline ||-
329 type == QEasingCurve::TCBSpline;-
330}-
331-
332struct TCBPoint {-
333 QPointF _point;-
334 qreal _t;-
335 qreal _c;-
336 qreal _b;-
337-
338 TCBPoint() {}-
339 TCBPoint(QPointF point, qreal t, qreal c, qreal b) : _point(point), _t(t), _c(c), _b(b) {}-
340-
341 bool operator==(const TCBPoint &other) const-
342 {-
343 return _point == other._point &&-
344 qFuzzyCompare(_t, other._t) &&-
345 qFuzzyCompare(_c, other._c) &&-
346 qFuzzyCompare(_b, other._b);-
347 }-
348};-
349Q_DECLARE_TYPEINFO(TCBPoint, Q_PRIMITIVE_TYPE);-
350-
351-
352typedef QVector<TCBPoint> TCBPoints;-
353-
354class QEasingCurveFunction-
355{-
356public:-
357 QEasingCurveFunction(QEasingCurve::Type type, qreal period = 0.3, qreal amplitude = 1.0,-
358 qreal overshoot = 1.70158)-
359 : _t(type), _p(period), _a(amplitude), _o(overshoot)-
360 { }-
361 virtual ~QEasingCurveFunction() {}-
362 virtual qreal value(qreal t);-
363 virtual QEasingCurveFunction *copy() const;-
364 bool operator==(const QEasingCurveFunction &other) const;-
365-
366 QEasingCurve::Type _t;-
367 qreal _p;-
368 qreal _a;-
369 qreal _o;-
370 QVector<QPointF> _bezierCurves;-
371 TCBPoints _tcbPoints;-
372-
373};-
374-
375static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve);-
376-
377qreal QEasingCurveFunction::value(qreal t)-
378{-
379 QEasingCurve::EasingFunction func = curveToFunc(_t);-
380 return func(t);-
381}-
382-
383QEasingCurveFunction *QEasingCurveFunction::copy() const-
384{-
385 QEasingCurveFunction *rv = new QEasingCurveFunction(_t, _p, _a, _o);-
386 rv->_bezierCurves = _bezierCurves;-
387 rv->_tcbPoints = _tcbPoints;-
388 return rv;-
389}-
390-
391bool QEasingCurveFunction::operator==(const QEasingCurveFunction &other) const-
392{-
393 return _t == other._t &&-
394 qFuzzyCompare(_p, other._p) &&-
395 qFuzzyCompare(_a, other._a) &&-
396 qFuzzyCompare(_o, other._o) &&-
397 _bezierCurves == other._bezierCurves &&-
398 _tcbPoints == other._tcbPoints;-
399}-
400-
401QT_BEGIN_INCLUDE_NAMESPACE-
402#include "../../3rdparty/easing/easing.cpp"-
403QT_END_INCLUDE_NAMESPACE-
404-
405class QEasingCurvePrivate-
406{-
407public:-
408 QEasingCurvePrivate()-
409 : type(QEasingCurve::Linear),-
410 config(0),-
411 func(&easeNone)-
412 { }-
413 QEasingCurvePrivate(const QEasingCurvePrivate &other)-
414 : type(other.type),-
415 config(other.config ? other.config->copy() : 0),-
416 func(other.func)-
417 { }-
418 ~QEasingCurvePrivate() { delete config; }-
419 void setType_helper(QEasingCurve::Type);-
420-
421 QEasingCurve::Type type;-
422 QEasingCurveFunction *config;-
423 QEasingCurve::EasingFunction func;-
424};-
425-
426struct BezierEase : public QEasingCurveFunction-
427{-
428 struct SingleCubicBezier {-
429 qreal p0x, p0y;-
430 qreal p1x, p1y;-
431 qreal p2x, p2y;-
432 qreal p3x, p3y;-
433 };-
434-
435 QVector<SingleCubicBezier> _curves;-
436 QVector<qreal> _intervals;-
437 int _curveCount;-
438 bool _init;-
439 bool _valid;-
440-
441 BezierEase(QEasingCurve::Type type = QEasingCurve::BezierSpline)-
442 : QEasingCurveFunction(type), _curves(10), _intervals(10), _init(false), _valid(false)-
443 { }-
444-
445 void init()-
446 {-
447 if (_bezierCurves.lastconstLast() == QPointF(1.0, 1.0)) {
_bezierCurves....intF(1.0, 1.0)Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEnever evaluated
0-7
448 _init = true;-
449 _curveCount = _bezierCurves.count() / 3;-
450-
451 for (int i=0; i < _curveCount; i++) {
i < _curveCountDescription
TRUEevaluated 19 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 7 times by 1 test
Evaluated by:
  • tst_QEasingCurve
7-19
452 _intervals[i] = _bezierCurves.at(i * 3 + 2).x();-
453-
454 if (i == 0) {
i == 0Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 12 times by 1 test
Evaluated by:
  • tst_QEasingCurve
7-12
455 _curves[0].p0x = 0.0;-
456 _curves[0].p0y = 0.0;-
457-
458 _curves[0].p1x = _bezierCurves.at(0).x();-
459 _curves[0].p1y = _bezierCurves.at(0).y();-
460-
461 _curves[0].p2x = _bezierCurves.at(1).x();-
462 _curves[0].p2y = _bezierCurves.at(1).y();-
463-
464 _curves[0].p3x = _bezierCurves.at(2).x();-
465 _curves[0].p3y = _bezierCurves.at(2).y();-
466-
467 } else if (i == (_curveCount - 1)) {
executed 7 times by 1 test: end of block
Executed by:
  • tst_QEasingCurve
i == (_curveCount - 1)Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 5 times by 1 test
Evaluated by:
  • tst_QEasingCurve
5-7
468 _curves[i].p0x = _bezierCurves.at(_bezierCurves.count() - 4).x();-
469 _curves[i].p0y = _bezierCurves.at(_bezierCurves.count() - 4).y();-
470-
471 _curves[i].p1x = _bezierCurves.at(_bezierCurves.count() - 3).x();-
472 _curves[i].p1y = _bezierCurves.at(_bezierCurves.count() - 3).y();-
473-
474 _curves[i].p2x = _bezierCurves.at(_bezierCurves.count() - 2).x();-
475 _curves[i].p2y = _bezierCurves.at(_bezierCurves.count() - 2).y();-
476-
477 _curves[i].p3x = _bezierCurves.at(_bezierCurves.count() - 1).x();-
478 _curves[i].p3y = _bezierCurves.at(_bezierCurves.count() - 1).y();-
479 } else {
executed 7 times by 1 test: end of block
Executed by:
  • tst_QEasingCurve
7
480 _curves[i].p0x = _bezierCurves.at(i * 3 - 1).x();-
481 _curves[i].p0y = _bezierCurves.at(i * 3 - 1).y();-
482-
483 _curves[i].p1x = _bezierCurves.at(i * 3).x();-
484 _curves[i].p1y = _bezierCurves.at(i * 3).y();-
485-
486 _curves[i].p2x = _bezierCurves.at(i * 3 + 1).x();-
487 _curves[i].p2y = _bezierCurves.at(i * 3 + 1).y();-
488-
489 _curves[i].p3x = _bezierCurves.at(i * 3 + 2).x();-
490 _curves[i].p3y = _bezierCurves.at(i * 3 + 2).y();-
491 }
executed 5 times by 1 test: end of block
Executed by:
  • tst_QEasingCurve
5
492 }-
493 _valid = true;-
494 } else {
executed 7 times by 1 test: end of block
Executed by:
  • tst_QEasingCurve
7
495 _valid = false;-
496 }
never executed: end of block
0
497 }-
498-
499 QEasingCurveFunction *copy() const Q_DECL_OVERRIDE-
500 {-
501 BezierEase *rv = new BezierEase();-
502 rv->_t = _t;-
503 rv->_p = _p;-
504 rv->_a = _a;-
505 rv->_o = _o;-
506 rv->_bezierCurves = _bezierCurves;-
507 rv->_tcbPoints = _tcbPoints;-
508 return rv;-
509 }-
510-
511 void getBezierSegment(SingleCubicBezier * &singleCubicBezier, qreal x)-
512 {-
513-
514 int currentSegment = 0;-
515-
516 while (currentSegment < _curveCount) {-
517 if (x <= _intervals.data()[currentSegment])-
518 break;-
519 currentSegment++;-
520 }-
521-
522 singleCubicBezier = &_curves.data()[currentSegment];-
523 }-
524-
525-
526 qreal static inline newtonIteration(const SingleCubicBezier &singleCubicBezier, qreal t, qreal x)-
527 {-
528 qreal currentXValue = evaluateForX(singleCubicBezier, t);-
529-
530 const qreal newT = t - (currentXValue - x) / evaluateDerivateForX(singleCubicBezier, t);-
531-
532 return newT;-
533 }-
534-
535 qreal value(qreal x) Q_DECL_OVERRIDE-
536 {-
537 Q_ASSERT(_bezierCurves.count() % 3 == 0);-
538-
539 if (_bezierCurves.isEmpty()) {-
540 return x;-
541 }-
542-
543 if (!_init)-
544 init();-
545-
546 if (!_valid) {-
547 qWarning("QEasingCurve: Invalid bezier curve");-
548 return x;-
549 }-
550 SingleCubicBezier *singleCubicBezier = 0;-
551 getBezierSegment(singleCubicBezier, x);-
552-
553 return evaluateSegmentForY(*singleCubicBezier, findTForX(*singleCubicBezier, x));-
554 }-
555-
556 qreal static inline evaluateSegmentForY(const SingleCubicBezier &singleCubicBezier, qreal t)-
557 {-
558 const qreal p0 = singleCubicBezier.p0y;-
559 const qreal p1 = singleCubicBezier.p1y;-
560 const qreal p2 = singleCubicBezier.p2y;-
561 const qreal p3 = singleCubicBezier.p3y;-
562-
563 const qreal s = 1 - t;-
564-
565 const qreal s_squared = s*s;-
566 const qreal t_squared = t*t;-
567-
568 const qreal s_cubic = s_squared * s;-
569 const qreal t_cubic = t_squared * t;-
570-
571 return s_cubic * p0 + 3 * s_squared * t * p1 + 3 * s * t_squared * p2 + t_cubic * p3;-
572 }-
573-
574 qreal static inline evaluateForX(const SingleCubicBezier &singleCubicBezier, qreal t)-
575 {-
576 const qreal p0 = singleCubicBezier.p0x;-
577 const qreal p1 = singleCubicBezier.p1x;-
578 const qreal p2 = singleCubicBezier.p2x;-
579 const qreal p3 = singleCubicBezier.p3x;-
580-
581 const qreal s = 1 - t;-
582-
583 const qreal s_squared = s*s;-
584 const qreal t_squared = t*t;-
585-
586 const qreal s_cubic = s_squared * s;-
587 const qreal t_cubic = t_squared * t;-
588-
589 return s_cubic * p0 + 3 * s_squared * t * p1 + 3 * s * t_squared * p2 + t_cubic * p3;-
590 }-
591-
592 qreal static inline evaluateDerivateForX(const SingleCubicBezier &singleCubicBezier, qreal t)-
593 {-
594 const qreal p0 = singleCubicBezier.p0x;-
595 const qreal p1 = singleCubicBezier.p1x;-
596 const qreal p2 = singleCubicBezier.p2x;-
597 const qreal p3 = singleCubicBezier.p3x;-
598-
599 const qreal t_squared = t*t;-
600-
601 return -3*p0 + 3*p1 + 6*p0*t - 12*p1*t + 6*p2*t + 3*p3*t_squared - 3*p0*t_squared + 9*p1*t_squared - 9*p2*t_squared;-
602 }-
603-
604 qreal static inline _cbrt(qreal d)-
605 {-
606 qreal sign = 1;-
607 if (d < 0)-
608 sign = -1;-
609 d = d * sign;-
610-
611 qreal t = _fast_cbrt(d);-
612-
613 //one step of Halley's Method to get a better approximation-
614 const qreal t_cubic = t * t * t;-
615 const qreal f = t_cubic + t_cubic + d;-
616 if (f != qreal(0.0))-
617 t = t * (t_cubic + d + d) / f;-
618-
619 //another step-
620 /*qreal t_i = t;-
621 t_i_cubic = pow(t_i, 3);-
622 t = t_i * (t_i_cubic + d + d) / (t_i_cubic + t_i_cubic + d);*/-
623-
624 return t * sign;-
625 }-
626-
627 float static inline _fast_cbrt(float x)-
628 {-
629 union {-
630 float f;-
631 quint32 i;-
632 } ux;-
633-
634 const unsigned int B1 = 709921077;-
635-
636 ux.f = x;-
637 ux.i = (ux.i / 3 + B1);-
638-
639 return ux.f;-
640 }-
641-
642 double static inline _fast_cbrt(double d)-
643 {-
644 union {-
645 double d;-
646 quint32 pt[2];-
647 } ut, ux;-
648-
649 const unsigned int B1 = 715094163;-
650-
651#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN-
652 const int h0 = 1;-
653#else-
654 const int h0 = 0;-
655#endif-
656 ut.d = 0.0;-
657 ux.d = d;-
658-
659 quint32 hx = ux.pt[h0]; //high word of d-
660 ut.pt[h0] = hx / 3 + B1;-
661-
662 return ut.d;-
663 }-
664-
665 qreal static inline _acos(qreal x)-
666 {-
667 return std::sqrt(1-x)*(1.5707963267948966192313216916398f + x*(-0.213300989f + x*(0.077980478f + x*-0.02164095f)));-
668 }-
669-
670 qreal static inline _cos(qreal x) //super fast _cos-
671 {-
672 const qreal pi_times2 = 2 * M_PI;-
673 const qreal pi_neg = -1 * M_PI;-
674 const qreal pi_by2 = M_PI / 2.0;-
675-
676 x += pi_by2; //the polynom is for sin-
677-
678 if (x < pi_neg)-
679 x += pi_times2;-
680 else if (x > M_PI)-
681 x -= pi_times2;-
682-
683 const qreal a = 0.405284735;-
684 const qreal b = 1.27323954;-
685-
686 const qreal x_squared = x * x;-
687-
688 if (x < 0) {-
689 qreal cos = b * x + a * x_squared;-
690-
691 if (cos < 0)-
692 return 0.225 * (cos * -1 * cos - cos) + cos;-
693 return 0.225 * (cos * cos - cos) + cos;-
694 } //else-
695-
696 qreal cos = b * x - a * x_squared;-
697-
698 if (cos < 0)-
699 return 0.225 * (cos * 1 *-cos - cos) + cos;-
700 return 0.225 * (cos * cos - cos) + cos;-
701 }-
702-
703 bool static inline inRange(qreal f)-
704 {-
705 return (f >= -0.01 && f <= 1.01);-
706 }-
707-
708 void static inline cosacos(qreal x, qreal &s1, qreal &s2, qreal &s3 )-
709 {-
710 //This function has no proper algebraic representation in real numbers.-
711 //We use approximations instead-
712-
713 const qreal x_squared = x * x;-
714 const qreal x_plus_one_sqrt = qSqrt(1.0 + x);-
715 const qreal one_minus_x_sqrt = qSqrt(1.0 - x);-
716-
717 //cos(acos(x) / 3)-
718 //s1 = _cos(_acos(x) / 3);-
719 s1 = 0.463614 - 0.0347815 * x + 0.00218245 * x_squared + 0.402421 * x_plus_one_sqrt;-
720-
721 //cos(acos((x) - M_PI) / 3)-
722 //s3 = _cos((_acos(x) - M_PI) / 3);-
723 s3 = 0.463614 + 0.402421 * one_minus_x_sqrt + 0.0347815 * x + 0.00218245 * x_squared;-
724-
725 //cos((acos(x) + M_PI) / 3)-
726 //s2 = _cos((_acos(x) + M_PI) / 3);-
727 s2 = -0.401644 * one_minus_x_sqrt - 0.0686804 * x + 0.401644 * x_plus_one_sqrt;-
728 }-
729-
730 qreal static inline singleRealSolutionForCubic(qreal a, qreal b, qreal c)-
731 {-
732 //returns the real solutiuon in [0..1]-
733 //We use the Cardano formula-
734-
735 //substituiton: x = z - a/3-
736 // z^3+pz+q=0-
737-
738 if (c < 0.000001 && c > -0.000001)-
739 return 0;-
740-
741 const qreal a_by3 = a / 3.0;-
742-
743 const qreal a_cubic = a * a * a;-
744-
745 const qreal p = b - a * a_by3;-
746 const qreal q = 2.0 * a_cubic / 27.0 - a * b / 3.0 + c;-
747-
748 const qreal q_squared = q * q;-
749 const qreal p_cubic = p * p * p;-
750 const qreal D = 0.25 * q_squared + p_cubic / 27.0;-
751-
752 if (D >= 0) {-
753 const qreal D_sqrt = qSqrt(D);-
754 qreal u = _cbrt( -q * 0.5 + D_sqrt);-
755 qreal v = _cbrt( -q * 0.5 - D_sqrt);-
756 qreal z1 = u + v;-
757-
758 qreal t1 = z1 - a_by3;-
759-
760 if (inRange(t1))-
761 return t1;-
762 qreal z2 = -1 *u;-
763 qreal t2 = z2 - a_by3;-
764 return t2;-
765 }-
766-
767 //casus irreducibilis-
768 const qreal p_minus_sqrt = qSqrt(-p);-
769-
770 //const qreal f = sqrt(4.0 / 3.0 * -p);-
771 const qreal f = qSqrt(4.0 / 3.0) * p_minus_sqrt;-
772-
773 //const qreal sqrtP = sqrt(27.0 / -p_cubic);-
774 const qreal sqrtP = -3.0*qSqrt(3.0) / (p_minus_sqrt * p);-
775-
776-
777 const qreal g = -q * 0.5 * sqrtP;-
778-
779 qreal s1;-
780 qreal s2;-
781 qreal s3;-
782-
783 cosacos(g, s1, s2, s3);-
784-
785 qreal z1 = -1* f * s2;-
786 qreal t1 = z1 - a_by3;-
787 if (inRange(t1))-
788 return t1;-
789-
790 qreal z2 = f * s1;-
791 qreal t2 = z2 - a_by3;-
792 if (inRange(t2))-
793 return t2;-
794-
795 qreal z3 = -1 * f * s3;-
796 qreal t3 = z3 - a_by3;-
797 return t3;-
798 }-
799-
800 qreal static inline findTForX(const SingleCubicBezier &singleCubicBezier, qreal x)-
801 {-
802 const qreal p0 = singleCubicBezier.p0x;-
803 const qreal p1 = singleCubicBezier.p1x;-
804 const qreal p2 = singleCubicBezier.p2x;-
805 const qreal p3 = singleCubicBezier.p3x;-
806-
807 const qreal factorT3 = p3 - p0 + 3 * p1 - 3 * p2;-
808 const qreal factorT2 = 3 * p0 - 6 * p1 + 3 * p2;-
809 const qreal factorT1 = -3 * p0 + 3 * p1;-
810 const qreal factorT0 = p0 - x;-
811-
812 const qreal a = factorT2 / factorT3;-
813 const qreal b = factorT1 / factorT3;-
814 const qreal c = factorT0 / factorT3;-
815-
816 return singleRealSolutionForCubic(a, b, c);-
817-
818 //one new iteration to increase numeric stability-
819 //return newtonIteration(singleCubicBezier, t, x);-
820 }-
821};-
822-
823struct TCBEase : public BezierEase-
824{-
825 TCBEase()-
826 : BezierEase(QEasingCurve::TCBSpline)-
827 { }-
828-
829 qreal value(qreal x) Q_DECL_OVERRIDE-
830 {-
831 Q_ASSERT(_bezierCurves.count() % 3 == 0);-
832-
833 if (_bezierCurves.isEmpty()) {-
834 qWarning("QEasingCurve: Invalid tcb curve");-
835 return x;-
836 }-
837-
838 return BezierEase::value(x);-
839 }-
840-
841};-
842-
843struct ElasticEase : public QEasingCurveFunction-
844{-
845 ElasticEase(QEasingCurve::Type type)-
846 : QEasingCurveFunction(type, qreal(0.3), qreal(1.0))-
847 { }-
848-
849 QEasingCurveFunction *copy() const Q_DECL_OVERRIDE-
850 {-
851 ElasticEase *rv = new ElasticEase(_t);-
852 rv->_p = _p;-
853 rv->_a = _a;-
854 rv->_bezierCurves = _bezierCurves;-
855 rv->_tcbPoints = _tcbPoints;-
856 return rv;-
857 }-
858-
859 qreal value(qreal t) Q_DECL_OVERRIDE-
860 {-
861 qreal p = (_p < 0) ? qreal(0.3) : _p;-
862 qreal a = (_a < 0) ? qreal(1.0) : _a;-
863 switch(_t) {-
864 case QEasingCurve::InElastic:-
865 return easeInElastic(t, a, p);-
866 case QEasingCurve::OutElastic:-
867 return easeOutElastic(t, a, p);-
868 case QEasingCurve::InOutElastic:-
869 return easeInOutElastic(t, a, p);-
870 case QEasingCurve::OutInElastic:-
871 return easeOutInElastic(t, a, p);-
872 default:-
873 return t;-
874 }-
875 }-
876};-
877-
878struct BounceEase : public QEasingCurveFunction-
879{-
880 BounceEase(QEasingCurve::Type type)-
881 : QEasingCurveFunction(type, qreal(0.3), qreal(1.0))-
882 { }-
883-
884 QEasingCurveFunction *copy() const Q_DECL_OVERRIDE-
885 {-
886 BounceEase *rv = new BounceEase(_t);-
887 rv->_a = _a;-
888 rv->_bezierCurves = _bezierCurves;-
889 rv->_tcbPoints = _tcbPoints;-
890 return rv;-
891 }-
892-
893 qreal value(qreal t) Q_DECL_OVERRIDE-
894 {-
895 qreal a = (_a < 0) ? qreal(1.0) : _a;-
896 switch(_t) {-
897 case QEasingCurve::InBounce:-
898 return easeInBounce(t, a);-
899 case QEasingCurve::OutBounce:-
900 return easeOutBounce(t, a);-
901 case QEasingCurve::InOutBounce:-
902 return easeInOutBounce(t, a);-
903 case QEasingCurve::OutInBounce:-
904 return easeOutInBounce(t, a);-
905 default:-
906 return t;-
907 }-
908 }-
909};-
910-
911struct BackEase : public QEasingCurveFunction-
912{-
913 BackEase(QEasingCurve::Type type)-
914 : QEasingCurveFunction(type, qreal(0.3), qreal(1.0), qreal(1.70158))-
915 { }-
916-
917 QEasingCurveFunction *copy() const Q_DECL_OVERRIDE-
918 {-
919 BackEase *rv = new BackEase(_t);-
920 rv->_o = _o;-
921 rv->_bezierCurves = _bezierCurves;-
922 rv->_tcbPoints = _tcbPoints;-
923 return rv;-
924 }-
925-
926 qreal value(qreal t) Q_DECL_OVERRIDE-
927 {-
928 qreal o = (_o < 0) ? qreal(1.70158) : _o;-
929 switch(_t) {-
930 case QEasingCurve::InBack:-
931 return easeInBack(t, o);-
932 case QEasingCurve::OutBack:-
933 return easeOutBack(t, o);-
934 case QEasingCurve::InOutBack:-
935 return easeInOutBack(t, o);-
936 case QEasingCurve::OutInBack:-
937 return easeOutInBack(t, o);-
938 default:-
939 return t;-
940 }-
941 }-
942};-
943-
944static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve)-
945{-
946 switch(curve) {-
947 case QEasingCurve::Linear:-
948 return &easeNone;-
949 case QEasingCurve::InQuad:-
950 return &easeInQuad;-
951 case QEasingCurve::OutQuad:-
952 return &easeOutQuad;-
953 case QEasingCurve::InOutQuad:-
954 return &easeInOutQuad;-
955 case QEasingCurve::OutInQuad:-
956 return &easeOutInQuad;-
957 case QEasingCurve::InCubic:-
958 return &easeInCubic;-
959 case QEasingCurve::OutCubic:-
960 return &easeOutCubic;-
961 case QEasingCurve::InOutCubic:-
962 return &easeInOutCubic;-
963 case QEasingCurve::OutInCubic:-
964 return &easeOutInCubic;-
965 case QEasingCurve::InQuart:-
966 return &easeInQuart;-
967 case QEasingCurve::OutQuart:-
968 return &easeOutQuart;-
969 case QEasingCurve::InOutQuart:-
970 return &easeInOutQuart;-
971 case QEasingCurve::OutInQuart:-
972 return &easeOutInQuart;-
973 case QEasingCurve::InQuint:-
974 return &easeInQuint;-
975 case QEasingCurve::OutQuint:-
976 return &easeOutQuint;-
977 case QEasingCurve::InOutQuint:-
978 return &easeInOutQuint;-
979 case QEasingCurve::OutInQuint:-
980 return &easeOutInQuint;-
981 case QEasingCurve::InSine:-
982 return &easeInSine;-
983 case QEasingCurve::OutSine:-
984 return &easeOutSine;-
985 case QEasingCurve::InOutSine:-
986 return &easeInOutSine;-
987 case QEasingCurve::OutInSine:-
988 return &easeOutInSine;-
989 case QEasingCurve::InExpo:-
990 return &easeInExpo;-
991 case QEasingCurve::OutExpo:-
992 return &easeOutExpo;-
993 case QEasingCurve::InOutExpo:-
994 return &easeInOutExpo;-
995 case QEasingCurve::OutInExpo:-
996 return &easeOutInExpo;-
997 case QEasingCurve::InCirc:-
998 return &easeInCirc;-
999 case QEasingCurve::OutCirc:-
1000 return &easeOutCirc;-
1001 case QEasingCurve::InOutCirc:-
1002 return &easeInOutCirc;-
1003 case QEasingCurve::OutInCirc:-
1004 return &easeOutInCirc;-
1005 // Internal for, compatibility with QTimeLine only ??-
1006 case QEasingCurve::InCurve:-
1007 return &easeInCurve;-
1008 case QEasingCurve::OutCurve:-
1009 return &easeOutCurve;-
1010 case QEasingCurve::SineCurve:-
1011 return &easeSineCurve;-
1012 case QEasingCurve::CosineCurve:-
1013 return &easeCosineCurve;-
1014 default:-
1015 return 0;-
1016 };-
1017}-
1018-
1019static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type)-
1020{-
1021 switch(type) {-
1022 case QEasingCurve::InElastic:-
1023 case QEasingCurve::OutElastic:-
1024 case QEasingCurve::InOutElastic:-
1025 case QEasingCurve::OutInElastic:-
1026 return new ElasticEase(type);-
1027 case QEasingCurve::OutBounce:-
1028 case QEasingCurve::InBounce:-
1029 case QEasingCurve::OutInBounce:-
1030 case QEasingCurve::InOutBounce:-
1031 return new BounceEase(type);-
1032 case QEasingCurve::InBack:-
1033 case QEasingCurve::OutBack:-
1034 case QEasingCurve::InOutBack:-
1035 case QEasingCurve::OutInBack:-
1036 return new BackEase(type);-
1037 case QEasingCurve::BezierSpline:-
1038 return new BezierEase;-
1039 case QEasingCurve::TCBSpline:-
1040 return new TCBEase;-
1041 default:-
1042 return new QEasingCurveFunction(type, qreal(0.3), qreal(1.0), qreal(1.70158));-
1043 }-
1044-
1045 return 0;
dead code: return 0;
-
1046}-
1047-
1048/*!-
1049 \fn QEasingCurve::QEasingCurve(QEasingCurve &&other)-
1050-
1051 Move-constructs a QEasingCurve instance, making it point at the same-
1052 object that \a other was pointing to.-
1053-
1054 \since 5.2-
1055*/-
1056-
1057/*!-
1058 Constructs an easing curve of the given \a type.-
1059 */-
1060QEasingCurve::QEasingCurve(Type type)-
1061 : d_ptr(new QEasingCurvePrivate)-
1062{-
1063 setType(type);-
1064}-
1065-
1066/*!-
1067 Construct a copy of \a other.-
1068 */-
1069QEasingCurve::QEasingCurve(const QEasingCurve &other)-
1070 : d_ptr(new QEasingCurvePrivate(*other.d_ptr))-
1071{-
1072 // ### non-atomic, requires malloc on shallow copy-
1073}-
1074-
1075/*!-
1076 Destructor.-
1077 */-
1078-
1079QEasingCurve::~QEasingCurve()-
1080{-
1081 delete d_ptr;-
1082}-
1083-
1084/*!-
1085 \fn QEasingCurve &QEasingCurve::operator=(const QEasingCurve &other)-
1086 Copy \a other.-
1087 */-
1088-
1089/*!-
1090 \fn QEasingCurve &QEasingCurve::operator=(QEasingCurve &&other)-
1091-
1092 Move-assigns \a other to this QEasingCurve instance.-
1093-
1094 \since 5.2-
1095*/-
1096-
1097/*!-
1098 \fn void QEasingCurve::swap(QEasingCurve &other)-
1099 \since 5.0-
1100-
1101 Swaps curve \a other with this curve. This operation is very-
1102 fast and never fails.-
1103*/-
1104-
1105/*!-
1106 Compare this easing curve with \a other and returns \c true if they are-
1107 equal. It will also compare the properties of a curve.-
1108 */-
1109bool QEasingCurve::operator==(const QEasingCurve &other) const-
1110{-
1111 bool res = d_ptr->func == other.d_ptr->func-
1112 && d_ptr->type == other.d_ptr->type;-
1113 if (res) {-
1114 if (d_ptr->config && other.d_ptr->config) {-
1115 // catch the config content-
1116 res = d_ptr->config->operator==(*(other.d_ptr->config));-
1117-
1118 } else if (d_ptr->config || other.d_ptr->config) {-
1119 // one one has a config object, which could contain default values-
1120 res = qFuzzyCompare(amplitude(), other.amplitude()) &&-
1121 qFuzzyCompare(period(), other.period()) &&-
1122 qFuzzyCompare(overshoot(), other.overshoot());-
1123 }-
1124 }-
1125 return res;-
1126}-
1127-
1128/*!-
1129 \fn bool QEasingCurve::operator!=(const QEasingCurve &other) const-
1130 Compare this easing curve with \a other and returns \c true if they are not equal.-
1131 It will also compare the properties of a curve.-
1132-
1133 \sa operator==()-
1134*/-
1135-
1136/*!-
1137 Returns the amplitude. This is not applicable for all curve types.-
1138 It is only applicable for bounce and elastic curves (curves of type()-
1139 QEasingCurve::InBounce, QEasingCurve::OutBounce, QEasingCurve::InOutBounce,-
1140 QEasingCurve::OutInBounce, QEasingCurve::InElastic, QEasingCurve::OutElastic,-
1141 QEasingCurve::InOutElastic or QEasingCurve::OutInElastic).-
1142 */-
1143qreal QEasingCurve::amplitude() const-
1144{-
1145 return d_ptr->config ? d_ptr->config->_a : qreal(1.0);-
1146}-
1147-
1148/*!-
1149 Sets the amplitude to \a amplitude.-
1150-
1151 This will set the amplitude of the bounce or the amplitude of the-
1152 elastic "spring" effect. The higher the number, the higher the amplitude.-
1153 \sa amplitude()-
1154*/-
1155void QEasingCurve::setAmplitude(qreal amplitude)-
1156{-
1157 if (!d_ptr->config)-
1158 d_ptr->config = curveToFunctionObject(d_ptr->type);-
1159 d_ptr->config->_a = amplitude;-
1160}-
1161-
1162/*!-
1163 Returns the period. This is not applicable for all curve types.-
1164 It is only applicable if type() is QEasingCurve::InElastic, QEasingCurve::OutElastic,-
1165 QEasingCurve::InOutElastic or QEasingCurve::OutInElastic.-
1166 */-
1167qreal QEasingCurve::period() const-
1168{-
1169 return d_ptr->config ? d_ptr->config->_p : qreal(0.3);-
1170}-
1171-
1172/*!-
1173 Sets the period to \a period.-
1174 Setting a small period value will give a high frequency of the curve. A-
1175 large period will give it a small frequency.-
1176-
1177 \sa period()-
1178*/-
1179void QEasingCurve::setPeriod(qreal period)-
1180{-
1181 if (!d_ptr->config)-
1182 d_ptr->config = curveToFunctionObject(d_ptr->type);-
1183 d_ptr->config->_p = period;-
1184}-
1185-
1186/*!-
1187 Returns the overshoot. This is not applicable for all curve types.-
1188 It is only applicable if type() is QEasingCurve::InBack, QEasingCurve::OutBack,-
1189 QEasingCurve::InOutBack or QEasingCurve::OutInBack.-
1190 */-
1191qreal QEasingCurve::overshoot() const-
1192{-
1193 return d_ptr->config ? d_ptr->config->_o : qreal(1.70158) ;-
1194}-
1195-
1196/*!-
1197 Sets the overshoot to \a overshoot.-
1198-
1199 0 produces no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent.-
1200-
1201 \sa overshoot()-
1202*/-
1203void QEasingCurve::setOvershoot(qreal overshoot)-
1204{-
1205 if (!d_ptr->config)-
1206 d_ptr->config = curveToFunctionObject(d_ptr->type);-
1207 d_ptr->config->_o = overshoot;-
1208}-
1209-
1210/*!-
1211 Adds a segment of a cubic bezier spline to define a custom easing curve.-
1212 It is only applicable if type() is QEasingCurve::BezierSpline.-
1213 Note that the spline implicitly starts at (0.0, 0.0) and has to end at (1.0, 1.0) to-
1214 be a valid easing curve.-
1215 \a c1 and \a c2 are the control points used for drawing the curve.-
1216 \a endPoint is the endpoint of the curve.-
1217 */-
1218void QEasingCurve::addCubicBezierSegment(const QPointF & c1, const QPointF & c2, const QPointF & endPoint)-
1219{-
1220 if (!d_ptr->config)-
1221 d_ptr->config = curveToFunctionObject(d_ptr->type);-
1222 d_ptr->config->_bezierCurves << c1 << c2 << endPoint;-
1223}-
1224-
1225QVector<QPointF> static inline tcbToBezier(const TCBPoints &tcbPoints)-
1226{-
1227 const int count = tcbPoints.count();-
1228 QVector<QPointF> bezierPoints;-
1229 bezierPoints.reserve(3 * (count - 1));-
1230-
1231 for (int i = 1; i < count; i++) {-
1232 const qreal t_0 = tcbPoints.at(i - 1)._t;-
1233 const qreal c_0 = tcbPoints.at(i - 1)._c;-
1234 qreal b_0 = -1;-
1235-
1236 qreal const t_1 = tcbPoints.at(i)._t;-
1237 qreal const c_1 = tcbPoints.at(i)._c;-
1238 qreal b_1 = 1;-
1239-
1240 QPointF c_minusOne; //P1 last segment - not available for the first point-
1241 const QPointF c0(tcbPoints.at(i - 1)._point); //P0 Hermite/TBC-
1242 const QPointF c3(tcbPoints.at(i)._point); //P1 Hermite/TBC-
1243 QPointF c4; //P0 next segment - not available for the last point-
1244-
1245 if (i > 1) { //first point no left tangent-
1246 c_minusOne = tcbPoints.at(i - 2)._point;-
1247 b_0 = tcbPoints.at(i - 1)._b;-
1248 }-
1249-
1250 if (i < (count - 1)) { //last point no right tangent-
1251 c4 = tcbPoints.at(i + 1)._point;-
1252 b_1 = tcbPoints.at(i)._b;-
1253 }-
1254-
1255 const qreal dx_0 = 0.5 * (1-t_0) * ((1 + b_0) * (1 + c_0) * (c0.x() - c_minusOne.x()) + (1- b_0) * (1 - c_0) * (c3.x() - c0.x()));-
1256 const qreal dy_0 = 0.5 * (1-t_0) * ((1 + b_0) * (1 + c_0) * (c0.y() - c_minusOne.y()) + (1- b_0) * (1 - c_0) * (c3.y() - c0.y()));-
1257-
1258 const qreal dx_1 = 0.5 * (1-t_1) * ((1 + b_1) * (1 - c_1) * (c3.x() - c0.x()) + (1 - b_1) * (1 + c_1) * (c4.x() - c3.x()));-
1259 const qreal dy_1 = 0.5 * (1-t_1) * ((1 + b_1) * (1 - c_1) * (c3.y() - c0.y()) + (1 - b_1) * (1 + c_1) * (c4.y() - c3.y()));-
1260-
1261 const QPointF d_0 = QPointF(dx_0, dy_0);-
1262 const QPointF d_1 = QPointF(dx_1, dy_1);-
1263-
1264 QPointF c1 = (3 * c0 + d_0) / 3;-
1265 QPointF c2 = (3 * c3 - d_1) / 3;-
1266 bezierPoints << c1 << c2 << c3;-
1267 }-
1268 return bezierPoints;-
1269}-
1270-
1271/*!-
1272 Adds a segment of a TCB bezier spline to define a custom easing curve.-
1273 It is only applicable if type() is QEasingCurve::TCBSpline.-
1274 The spline has to start explitly at (0.0, 0.0) and has to end at (1.0, 1.0) to-
1275 be a valid easing curve.-
1276 The tension \a t changes the length of the tangent vector.-
1277 The continuity \a c changes the sharpness in change between the tangents.-
1278 The bias \a b changes the direction of the tangent vector.-
1279 \a nextPoint is the sample position.-
1280 All three parameters are valid between -1 and 1 and define the-
1281 tangent of the control point.-
1282 If all three parameters are 0 the resulting spline is a Catmull-Rom spline.-
1283 The begin and endpoint always have a bias of -1 and 1, since the outer tangent is not defined.-
1284 */-
1285void QEasingCurve::addTCBSegment(const QPointF &nextPoint, qreal t, qreal c, qreal b)-
1286{-
1287 if (!d_ptr->config)-
1288 d_ptr->config = curveToFunctionObject(d_ptr->type);-
1289-
1290 d_ptr->config->_tcbPoints.append(TCBPoint(nextPoint, t, c ,b));-
1291-
1292 if (nextPoint == QPointF(1.0, 1.0)) {-
1293 d_ptr->config->_bezierCurves = tcbToBezier(d_ptr->config->_tcbPoints);-
1294 d_ptr->config->_tcbPoints.clear();-
1295 }-
1296-
1297}-
1298-
1299/*!-
1300 \fn QList<QPointF> QEasingCurve::cubicBezierSpline() const-
1301 \obsolete Use toCubicSpline() instead.-
1302 */-
1303-
1304/*!-
1305 \since 5.0-
1306-
1307 Returns the cubicBezierSpline that defines a custom easing curve.-
1308 If the easing curve does not have a custom bezier easing curve the list-
1309 is empty.-
1310*/-
1311QVector<QPointF> QEasingCurve::toCubicSpline() const-
1312{-
1313 return d_ptr->config ? d_ptr->config->_bezierCurves : QVector<QPointF>();-
1314}-
1315-
1316/*!-
1317 Returns the type of the easing curve.-
1318*/-
1319QEasingCurve::Type QEasingCurve::type() const-
1320{-
1321 return d_ptr->type;-
1322}-
1323-
1324void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType)-
1325{-
1326 qreal amp = -1.0;-
1327 qreal period = -1.0;-
1328 qreal overshoot = -1.0;-
1329 QVector<QPointF> bezierCurves;-
1330 QVector<TCBPoint> tcbPoints;-
1331-
1332 if (config) {
configDescription
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 1836 times by 43 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QMetaType
  • tst_QPrinter
  • ...
10-1836
1333 amp = config->_a;-
1334 period = config->_p;-
1335 overshoot = config->_o;-
1336 bezierCurves = std::move(config->_bezierCurves;);-
1337 tcbPoints = std::move(config->_tcbPoints;);-
1338-
1339 delete config;-
1340 config = 0;-
1341 }
executed 10 times by 1 test: end of block
Executed by:
  • tst_QEasingCurve
10
1342-
1343 if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0) ||
isConfigFunction(newType)Description
TRUEevaluated 86 times by 3 tests
Evaluated by:
  • tst_QDataStream
  • tst_QEasingCurve
  • tst_QMetaType
FALSEevaluated 1760 times by 42 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QPropertyAnimation
  • ...
(amp != -1.0)Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 1755 times by 42 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QPropertyAnimation
  • ...
(period != -1.0)Description
TRUEnever evaluated
FALSEevaluated 1755 times by 42 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QPropertyAnimation
  • ...
(overshoot != -1.0)Description
TRUEnever evaluated
FALSEevaluated 1755 times by 42 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QPropertyAnimation
  • ...
0-1760
1344 !bezierCurves.isEmpty()) {
!bezierCurves.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 1755 times by 42 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QPropertyAnimation
  • ...
0-1755
1345 config = curveToFunctionObject(newType);-
1346 if (amp != -1.0)
amp != -1.0Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 81 times by 3 tests
Evaluated by:
  • tst_QDataStream
  • tst_QEasingCurve
  • tst_QMetaType
10-81
1347 config->_a = amp;
executed 10 times by 1 test: config->_a = amp;
Executed by:
  • tst_QEasingCurve
10
1348 if (period != -1.0)
period != -1.0Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 81 times by 3 tests
Evaluated by:
  • tst_QDataStream
  • tst_QEasingCurve
  • tst_QMetaType
10-81
1349 config->_p = period;
executed 10 times by 1 test: config->_p = period;
Executed by:
  • tst_QEasingCurve
10
1350 if (overshoot != -1.0)
overshoot != -1.0Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tst_QEasingCurve
FALSEevaluated 81 times by 3 tests
Evaluated by:
  • tst_QDataStream
  • tst_QEasingCurve
  • tst_QMetaType
10-81
1351 config->_o = overshoot;
executed 10 times by 1 test: config->_o = overshoot;
Executed by:
  • tst_QEasingCurve
10
1352 config->_bezierCurves = std::move(bezierCurves;);-
1353 config->_tcbPoints = std::move(tcbPoints;);-
1354 func = 0;-
1355 } else if (newType != QEasingCurve::Custom) {
executed 91 times by 3 tests: end of block
Executed by:
  • tst_QDataStream
  • tst_QEasingCurve
  • tst_QMetaType
newType != QEa...gCurve::CustomDescription
TRUEevaluated 1748 times by 41 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QScroller
  • ...
FALSEevaluated 7 times by 2 tests
Evaluated by:
  • tst_QEasingCurve
  • tst_QPropertyAnimation
7-1748
1356 func = curveToFunc(newType);-
1357 }
executed 1748 times by 41 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QPrinter
  • tst_QScroller
  • ...
1748
1358 Q_ASSERT((func == 0) == (config != 0));-
1359 type = newType;-
1360}
executed 1846 times by 43 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_QAbstractItemView
  • tst_QAccessibility
  • tst_QColumnView
  • tst_QComboBox
  • tst_QDataStream
  • tst_QDirModel
  • tst_QDockWidget
  • tst_QEasingCurve
  • tst_QFileDialog2
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QGraphicsItemAnimation
  • tst_QGraphicsLayout
  • tst_QGraphicsProxyWidget
  • tst_QHeaderView
  • tst_QItemModel
  • tst_QItemView
  • tst_QMainWindow
  • tst_QMdiArea
  • tst_QMdiSubWindow
  • tst_QMenu
  • tst_QMetaType
  • tst_QPrinter
  • ...
1846
1361-
1362/*!-
1363 Sets the type of the easing curve to \a type.-
1364*/-
1365void QEasingCurve::setType(Type type)-
1366{-
1367 if (d_ptr->type == type)-
1368 return;-
1369 if (type < Linear || type >= NCurveTypes - 1) {-
1370 qWarning("QEasingCurve: Invalid curve type %d", type);-
1371 return;-
1372 }-
1373-
1374 d_ptr->setType_helper(type);-
1375}-
1376-
1377/*!-
1378 Sets a custom easing curve that is defined by the user in the function \a func.-
1379 The signature of the function is qreal myEasingFunction(qreal progress),-
1380 where \e progress and the return value are considered to be normalized between 0 and 1.-
1381 (In some cases the return value can be outside that range)-
1382 After calling this function type() will return QEasingCurve::Custom.-
1383 \a func cannot be zero.-
1384-
1385 \sa customType()-
1386 \sa valueForProgress()-
1387*/-
1388void QEasingCurve::setCustomType(EasingFunction func)-
1389{-
1390 if (!func) {-
1391 qWarning("Function pointer must not be null");-
1392 return;-
1393 }-
1394 d_ptr->func = func;-
1395 d_ptr->setType_helper(Custom);-
1396}-
1397-
1398/*!-
1399 Returns the function pointer to the custom easing curve.-
1400 If type() does not return QEasingCurve::Custom, this function-
1401 will return 0.-
1402*/-
1403QEasingCurve::EasingFunction QEasingCurve::customType() const-
1404{-
1405 return d_ptr->type == Custom ? d_ptr->func : 0;-
1406}-
1407-
1408/*!-
1409 Return the effective progress for the easing curve at \a progress.-
1410 Whereas \a progress must be between 0 and 1, the returned effective progress-
1411 can be outside those bounds. For example, QEasingCurve::InBack will-
1412 return negative values in the beginning of the function.-
1413 */-
1414qreal QEasingCurve::valueForProgress(qreal progress) const-
1415{-
1416 progress = qBound<qreal>(0, progress, 1);-
1417 if (d_ptr->func)-
1418 return d_ptr->func(progress);-
1419 else if (d_ptr->config)-
1420 return d_ptr->config->value(progress);-
1421 else-
1422 return progress;-
1423}-
1424-
1425#ifndef QT_NO_DEBUG_STREAM-
1426QDebug operator<<(QDebug debug, const QEasingCurve &item)-
1427{-
1428 QDebugStateSaver saver(debug);-
1429 debug << "type:" << item.d_ptr->type-
1430 << "func:" << item.d_ptr->func;-
1431 if (item.d_ptr->config) {-
1432 debug << QString::fromLatin1("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20)-
1433 << QString::fromLatin1("amp:%1").arg(item.d_ptr->config->_a, 0, 'f', 20)-
1434 << QString::fromLatin1("overshoot:%1").arg(item.d_ptr->config->_o, 0, 'f', 20);-
1435 }-
1436 return debug;-
1437}-
1438#endif // QT_NO_DEBUG_STREAM-
1439-
1440#ifndef QT_NO_DATASTREAM-
1441/*!-
1442 \fn QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)-
1443 \relates QEasingCurve-
1444-
1445 Writes the given \a easing curve to the given \a stream and returns a-
1446 reference to the stream.-
1447-
1448 \sa {Serializing Qt Data Types}-
1449*/-
1450-
1451QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)-
1452{-
1453 stream << quint8(easing.d_ptr->type);-
1454 stream << quint64(quintptr(easing.d_ptr->func));-
1455-
1456 bool hasConfig = easing.d_ptr->config;-
1457 stream << hasConfig;-
1458 if (hasConfig) {-
1459 stream << easing.d_ptr->config->_p;-
1460 stream << easing.d_ptr->config->_a;-
1461 stream << easing.d_ptr->config->_o;-
1462 }-
1463 return stream;-
1464}-
1465-
1466/*!-
1467 \fn QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)-
1468 \relates QEasingCurve-
1469-
1470 Reads an easing curve from the given \a stream into the given \a-
1471 easing curve and returns a reference to the stream.-
1472-
1473 \sa {Serializing Qt Data Types}-
1474*/-
1475-
1476QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)-
1477{-
1478 QEasingCurve::Type type;-
1479 quint8 int_type;-
1480 stream >> int_type;-
1481 type = static_cast<QEasingCurve::Type>(int_type);-
1482 easing.setType(type);-
1483-
1484 quint64 ptr_func;-
1485 stream >> ptr_func;-
1486 easing.d_ptr->func = QEasingCurve::EasingFunction(quintptr(ptr_func));-
1487-
1488 bool hasConfig;-
1489 stream >> hasConfig;-
1490 delete easing.d_ptr->config;-
1491 easing.d_ptr->config = Q_NULLPTR;-
1492 if (hasConfig) {-
1493 QEasingCurveFunction *config = curveToFunctionObject(type);-
1494 stream >> config->_p;-
1495 stream >> config->_a;-
1496 stream >> config->_o;-
1497 easing.d_ptr->config = config;-
1498 }-
1499 return stream;-
1500}-
1501#endif // QT_NO_DATASTREAM-
1502-
1503QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9