6
7
8
9
10
11
12
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
83
84
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
296
297
298
299
300
301
302
307#ifndef QT_NO_DEBUG_STREAM
308#include <QtCore/qdebug.h>
309#include <QtCore/qstring.h>
312#ifndef QT_NO_DATASTREAM
313#include <QtCore/qdatastream.h>
316#include <QtCore/qpoint.h>
317#include <QtCore/qlist.h>
323 return (type >= QEasingCurve::InElastic
324 && type <= QEasingCurve::OutInBounce) ||
325 type == QEasingCurve::BezierSpline ||
326 type == QEasingCurve::TCBSpline;
339 return qFuzzyCompare(lhs._point, rhs._point)
340 && QtPrivate::fuzzyCompare(lhs._t, rhs._t)
341 && QtPrivate::fuzzyCompare(lhs._c, rhs._c)
342 && QtPrivate::fuzzyCompare(lhs._b, rhs._b);
349 stream << point._point
358 stream >> point._point
400 if (stream.version() > QDataStream::Qt_5_12) {
401 stream << func->_bezierCurves;
414 if (stream.version() > QDataStream::Qt_5_12) {
415 stream >> func->_bezierCurves;
426 QEasingCurve::EasingFunction func = curveToFunc(_t);
432 return _t == other._t
433 && QtPrivate::fuzzyCompare(_p, other._p)
434 && QtPrivate::fuzzyCompare(_a, other._a)
435 && QtPrivate::fuzzyCompare(_o, other._o)
436 && _bezierCurves == other._bezierCurves
437 && _tcbPoints == other._tcbPoints;
440QT_BEGIN_INCLUDE_NAMESPACE
441#include "../../3rdparty/easing/easing.cpp"
442QT_END_INCLUDE_NAMESPACE
444class QEasingCurvePrivate
447 QEasingCurvePrivate()
448 : type(QEasingCurve::Linear),
452 QEasingCurvePrivate(
const QEasingCurvePrivate &other)
454 config(other.config ? other.config->clone() :
nullptr),
457 ~QEasingCurvePrivate() {
delete config; }
458 void setType_helper(QEasingCurve::Type);
460 QEasingCurve::Type type;
461 QEasingCurveFunction *config;
462 QEasingCurve::EasingFunction func;
486 if (_bezierCurves.constLast() == QPointF(1.0, 1.0)) {
488 _curveCount = _bezierCurves.size() / 3;
491 _intervals[i] = _bezierCurves.at(i * 3 + 2).x();
494 _curves[0].p0x = 0.0;
495 _curves[0].p0y = 0.0;
497 _curves[0].p1x = _bezierCurves.at(0).x();
498 _curves[0].p1y = _bezierCurves.at(0).y();
500 _curves[0].p2x = _bezierCurves.at(1).x();
501 _curves[0].p2y = _bezierCurves.at(1).y();
503 _curves[0].p3x = _bezierCurves.at(2).x();
504 _curves[0].p3y = _bezierCurves.at(2).y();
507 _curves[i].p0x = _bezierCurves.at(_bezierCurves.size() - 4).x();
508 _curves[i].p0y = _bezierCurves.at(_bezierCurves.size() - 4).y();
510 _curves[i].p1x = _bezierCurves.at(_bezierCurves.size() - 3).x();
511 _curves[i].p1y = _bezierCurves.at(_bezierCurves.size() - 3).y();
513 _curves[i].p2x = _bezierCurves.at(_bezierCurves.size() - 2).x();
514 _curves[i].p2y = _bezierCurves.at(_bezierCurves.size() - 2).y();
516 _curves[i].p3x = _bezierCurves.at(_bezierCurves.size() - 1).x();
517 _curves[i].p3y = _bezierCurves.at(_bezierCurves.size() - 1).y();
519 _curves[i].p0x = _bezierCurves.at(i * 3 - 1).x();
520 _curves[i].p0y = _bezierCurves.at(i * 3 - 1).y();
522 _curves[i].p1x = _bezierCurves.at(i * 3).x();
523 _curves[i].p1y = _bezierCurves.at(i * 3).y();
525 _curves[i].p2x = _bezierCurves.at(i * 3 + 1).x();
526 _curves[i].p2y = _bezierCurves.at(i * 3 + 1).y();
528 _curves[i].p3x = _bezierCurves.at(i * 3 + 2).x();
529 _curves[i].p3y = _bezierCurves.at(i * 3 + 2).y();
543 int currentSegment = 0;
546 if (x <= _intervals.data()[currentSegment])
551 singleCubicBezier = &_curves.data()[currentSegment];
557 qreal currentXValue = evaluateForX(singleCubicBezier, t);
559 const qreal newT = t - (currentXValue - x) / evaluateDerivateForX(singleCubicBezier, t);
566 Q_ASSERT(_bezierCurves.size() % 3 == 0);
568 if (_bezierCurves.isEmpty()) {
576 qWarning(
"QEasingCurve: Invalid bezier curve");
587 getBezierSegment(singleCubicBezier, x);
589 return evaluateSegmentForY(*singleCubicBezier, findTForX(*singleCubicBezier, x));
594 const qreal p0 = singleCubicBezier.p0y;
595 const qreal p1 = singleCubicBezier.p1y;
596 const qreal p2 = singleCubicBezier.p2y;
597 const qreal p3 = singleCubicBezier.p3y;
599 const qreal s = 1 - t;
601 const qreal s_squared = s * s;
602 const qreal t_squared = t * t;
604 const qreal s_cubic = s_squared * s;
605 const qreal t_cubic = t_squared * t;
607 return s_cubic * p0 + 3 * s_squared * t * p1 + 3 * s * t_squared * p2 + t_cubic * p3;
612 const qreal p0 = singleCubicBezier.p0x;
613 const qreal p1 = singleCubicBezier.p1x;
614 const qreal p2 = singleCubicBezier.p2x;
615 const qreal p3 = singleCubicBezier.p3x;
617 const qreal s = 1 - t;
619 const qreal s_squared = s * s;
620 const qreal t_squared = t * t;
622 const qreal s_cubic = s_squared * s;
623 const qreal t_cubic = t_squared * t;
625 return s_cubic * p0 + 3 * s_squared * t * p1 + 3 * s * t_squared * p2 + t_cubic * p3;
630 const qreal p0 = singleCubicBezier.p0x;
631 const qreal p1 = singleCubicBezier.p1x;
632 const qreal p2 = singleCubicBezier.p2x;
633 const qreal p3 = singleCubicBezier.p3x;
635 const qreal t_squared = t * t;
637 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;
647 qreal t = _fast_cbrt(d);
650 const qreal t_cubic = t * t * t;
651 const qreal f = t_cubic + t_cubic + d;
653 t = t * (t_cubic + d + d) / f;
657
658
670 const unsigned int B1 = 709921077;
673 ux.i = (ux.i / 3 + B1);
685 const unsigned int B1 = 715094163;
687#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
695 quint32 hx = ux.pt[h0];
696 ut.pt[h0] = hx / 3 + B1;
703 return std::sqrt(1-x)*(1.5707963267948966192313216916398f + x*(-0.213300989f + x*(0.077980478f + x*-0.02164095f)));
708 const qreal pi_times2 = 2 *
M_PI;
709 const qreal pi_neg = -1 *
M_PI;
710 const qreal pi_by2 =
M_PI / 2.0;
719 const qreal a = 0.405284735;
720 const qreal b = 1.27323954;
722 const qreal x_squared = x * x;
725 qreal cos = b * x + a * x_squared;
728 return 0.225 * (cos * -1 * cos - cos) + cos;
729 return 0.225 * (cos * cos - cos) + cos;
732 qreal cos = b * x - a * x_squared;
735 return 0.225 * (cos * 1 * -cos - cos) + cos;
736 return 0.225 * (cos * cos - cos) + cos;
741 return (f >= -0.01 && f <= 1.01);
744 void static inline cosacos(qreal x, qreal &s1, qreal &s2, qreal &s3 )
749 const qreal x_squared = x * x;
750 const qreal x_plus_one_sqrt = qSqrt(1.0 + x);
751 const qreal one_minus_x_sqrt = qSqrt(1.0 - x);
755 s1 = 0.463614 - 0.0347815 * x + 0.00218245 * x_squared + 0.402421 * x_plus_one_sqrt;
759 s3 = 0.463614 + 0.402421 * one_minus_x_sqrt + 0.0347815 * x + 0.00218245 * x_squared;
763 s2 = -0.401644 * one_minus_x_sqrt - 0.0686804 * x + 0.401644 * x_plus_one_sqrt;
774 if (c < 0.000001 && c > -0.000001)
777 const qreal a_by3 = a / 3.0;
779 const qreal a_cubic = a * a * a;
781 const qreal p = b - a * a_by3;
782 const qreal q = 2.0 * a_cubic / 27.0 - a * b / 3.0 + c;
784 const qreal q_squared = q * q;
785 const qreal p_cubic = p * p * p;
786 const qreal D = 0.25 * q_squared + p_cubic / 27.0;
789 const qreal D_sqrt = qSqrt(D);
790 qreal u = _cbrt(-q * 0.5 + D_sqrt);
791 qreal v = _cbrt(-q * 0.5 - D_sqrt);
794 qreal t1 = z1 - a_by3;
799 qreal t2 = z2 - a_by3;
804 const qreal p_minus_sqrt = qSqrt(-p);
807 const qreal f = qSqrt(4.0 / 3.0) * p_minus_sqrt;
810 const qreal sqrtP = -3.0*qSqrt(3.0) / (p_minus_sqrt * p);
813 const qreal g = -q * 0.5 * sqrtP;
819 cosacos(g, s1, s2, s3);
821 qreal z1 = -1 * f * s2;
822 qreal t1 = z1 - a_by3;
827 qreal t2 = z2 - a_by3;
831 qreal z3 = -1 * f * s3;
832 qreal t3 = z3 - a_by3;
840 return value > -1e-3 && value < 1e-3;
845 const qreal p0 = singleCubicBezier.p0x;
846 const qreal p1 = singleCubicBezier.p1x;
847 const qreal p2 = singleCubicBezier.p2x;
848 const qreal p3 = singleCubicBezier.p3x;
850 const qreal factorT3 = p3 - p0 + 3 * p1 - 3 * p2;
851 const qreal factorT2 = 3 * p0 - 6 * p1 + 3 * p2;
852 const qreal factorT1 = -3 * p0 + 3 * p1;
853 const qreal factorT0 = p0 - x;
856 if (almostZero(factorT3)) {
857 if (almostZero(factorT2)) {
858 if (almostZero(factorT1))
861 return -factorT0 / factorT1;
863 const qreal discriminant = factorT1 * factorT1 - 4.0 * factorT2 * factorT0;
864 if (discriminant < 0.0)
867 if (discriminant == 0.0)
868 return -factorT1 / (2.0 * factorT2);
870 const qreal solution1 = (-factorT1 +
std::sqrt(discriminant)) / (2.0 * factorT2);
871 if (solution1 >= 0.0 && solution1 <= 1.0)
874 const qreal solution2 = (-factorT1 -
std::sqrt(discriminant)) / (2.0 * factorT2);
875 if (solution2 >= 0.0 && solution2 <= 1.0)
881 const qreal a = factorT2 / factorT3;
882 const qreal b = factorT1 / factorT3;
883 const qreal c = factorT0 / factorT3;
885 return singleRealSolutionForCubic(a, b, c);
900 Q_ASSERT(_bezierCurves.size() % 3 == 0);
902 if (_bezierCurves.isEmpty()) {
903 qWarning(
"QEasingCurve: Invalid tcb curve");
907 return BezierEase::value(x);
926 qreal p = (_p < 0) ? qreal(0.3) : _p;
927 qreal a = (_a < 0) ? qreal(1.0) : _a;
929 case QEasingCurve::InElastic:
930 return easeInElastic(t, a, p);
931 case QEasingCurve::OutElastic:
932 return easeOutElastic(t, a, p);
933 case QEasingCurve::InOutElastic:
934 return easeInOutElastic(t, a, p);
935 case QEasingCurve::OutInElastic:
936 return easeOutInElastic(t, a, p);
953 qreal a = (_a < 0) ? qreal(1.0) : _a;
955 case QEasingCurve::InBounce:
956 return easeInBounce(t, a);
957 case QEasingCurve::OutBounce:
958 return easeOutBounce(t, a);
959 case QEasingCurve::InOutBounce:
960 return easeInOutBounce(t, a);
961 case QEasingCurve::OutInBounce:
962 return easeOutInBounce(t, a);
984 qreal o = (_o < 0) ? qreal(1.70158) : _o;
986 case QEasingCurve::InBack:
987 return easeInBack(t, o);
988 case QEasingCurve::OutBack:
989 return easeOutBack(t, o);
990 case QEasingCurve::InOutBack:
991 return easeInOutBack(t, o);
992 case QEasingCurve::OutInBack:
993 return easeOutInBack(t, o);
1003 case QEasingCurve::Linear:
1005 case QEasingCurve::InQuad:
1007 case QEasingCurve::OutQuad:
1008 return &easeOutQuad;
1009 case QEasingCurve::InOutQuad:
1010 return &easeInOutQuad;
1011 case QEasingCurve::OutInQuad:
1012 return &easeOutInQuad;
1013 case QEasingCurve::InCubic:
1014 return &easeInCubic;
1015 case QEasingCurve::OutCubic:
1016 return &easeOutCubic;
1017 case QEasingCurve::InOutCubic:
1018 return &easeInOutCubic;
1019 case QEasingCurve::OutInCubic:
1020 return &easeOutInCubic;
1021 case QEasingCurve::InQuart:
1022 return &easeInQuart;
1023 case QEasingCurve::OutQuart:
1024 return &easeOutQuart;
1025 case QEasingCurve::InOutQuart:
1026 return &easeInOutQuart;
1027 case QEasingCurve::OutInQuart:
1028 return &easeOutInQuart;
1029 case QEasingCurve::InQuint:
1030 return &easeInQuint;
1031 case QEasingCurve::OutQuint:
1032 return &easeOutQuint;
1033 case QEasingCurve::InOutQuint:
1034 return &easeInOutQuint;
1035 case QEasingCurve::OutInQuint:
1036 return &easeOutInQuint;
1037 case QEasingCurve::InSine:
1039 case QEasingCurve::OutSine:
1040 return &easeOutSine;
1041 case QEasingCurve::InOutSine:
1042 return &easeInOutSine;
1043 case QEasingCurve::OutInSine:
1044 return &easeOutInSine;
1045 case QEasingCurve::InExpo:
1047 case QEasingCurve::OutExpo:
1048 return &easeOutExpo;
1049 case QEasingCurve::InOutExpo:
1050 return &easeInOutExpo;
1051 case QEasingCurve::OutInExpo:
1052 return &easeOutInExpo;
1053 case QEasingCurve::InCirc:
1055 case QEasingCurve::OutCirc:
1056 return &easeOutCirc;
1057 case QEasingCurve::InOutCirc:
1058 return &easeInOutCirc;
1059 case QEasingCurve::OutInCirc:
1060 return &easeOutInCirc;
1062 case QEasingCurve::InCurve:
1063 return &easeInCurve;
1064 case QEasingCurve::OutCurve:
1065 return &easeOutCurve;
1066 case QEasingCurve::SineCurve:
1067 return &easeSineCurve;
1068 case QEasingCurve::CosineCurve:
1069 return &easeCosineCurve;
1078 case QEasingCurve::InElastic:
1079 case QEasingCurve::OutElastic:
1080 case QEasingCurve::InOutElastic:
1081 case QEasingCurve::OutInElastic:
1082 return new ElasticEase(type);
1083 case QEasingCurve::OutBounce:
1084 case QEasingCurve::InBounce:
1085 case QEasingCurve::OutInBounce:
1086 case QEasingCurve::InOutBounce:
1087 return new BounceEase(type);
1088 case QEasingCurve::InBack:
1089 case QEasingCurve::OutBack:
1090 case QEasingCurve::InOutBack:
1091 case QEasingCurve::OutInBack:
1092 return new BackEase(type);
1093 case QEasingCurve::BezierSpline:
1094 return new BezierEase;
1095 case QEasingCurve::TCBSpline:
1098 return new QEasingCurveFunction(type, qreal(0.3), qreal(1.0), qreal(1.70158));
1105
1106
1107
1108
1109
1110
1111
1114
1115
1116QEasingCurve::QEasingCurve(Type type)
1117 : d_ptr(
new QEasingCurvePrivate)
1123
1124
1125QEasingCurve::QEasingCurve(
const QEasingCurve &other)
1126 : d_ptr(
new QEasingCurvePrivate(*other.d_ptr))
1132
1133
1135QEasingCurve::~QEasingCurve()
1141
1142
1143
1146
1147
1148
1149
1150
1151
1154
1155
1156
1157
1160
1161
1162
1163
1164
1165
1168 bool res = lhs.d_ptr->func == rhs.d_ptr->func
1169 && lhs.d_ptr->type == rhs.d_ptr->type;
1171 if (lhs.d_ptr->config && rhs.d_ptr->config) {
1173 res = lhs.d_ptr->config->fuzzyCompare(*rhs.d_ptr->config);
1174 }
else if (lhs.d_ptr->config || rhs.d_ptr->config) {
1176 res = QtPrivate::fuzzyCompare(lhs.amplitude(), rhs.amplitude())
1177 && QtPrivate::fuzzyCompare(lhs.period(), rhs.period())
1178 && QtPrivate::fuzzyCompare(lhs.overshoot(), rhs.overshoot());
1185
1186
1187
1188
1189
1190
1191
1192
1195
1196
1197
1198
1199
1200
1201qreal QEasingCurve::amplitude()
const
1203 return d_ptr->config ? d_ptr->config->_a : qreal(1.0);
1207
1208
1209
1210
1211
1212
1213void QEasingCurve::setAmplitude(qreal amplitude)
1216 d_ptr->config = curveToFunctionObject(d_ptr->type);
1217 d_ptr->config->_a = amplitude;
1221
1222
1223
1224
1225qreal QEasingCurve::period()
const
1227 return d_ptr->config ? d_ptr->config->_p : qreal(0.3);
1231
1232
1233
1234
1235
1236
1237void QEasingCurve::setPeriod(qreal period)
1240 d_ptr->config = curveToFunctionObject(d_ptr->type);
1241 d_ptr->config->_p = period;
1245
1246
1247
1248
1249qreal QEasingCurve::overshoot()
const
1251 return d_ptr->config ? d_ptr->config->_o : qreal(1.70158);
1255
1256
1257
1258
1259
1260
1261void QEasingCurve::setOvershoot(qreal overshoot)
1264 d_ptr->config = curveToFunctionObject(d_ptr->type);
1265 d_ptr->config->_o = overshoot;
1269
1270
1271
1272
1273
1274
1275
1276void QEasingCurve::addCubicBezierSegment(
const QPointF & c1,
const QPointF & c2,
const QPointF & endPoint)
1279 d_ptr->config = curveToFunctionObject(d_ptr->type);
1280 d_ptr->config->_bezierCurves << c1 << c2 << endPoint;
1285 const int count = tcbPoints.size();
1286 QList<QPointF> bezierPoints;
1287 bezierPoints.reserve(3 * (count - 1));
1289 for (
int i = 1; i < count; i++) {
1290 const qreal t_0 = tcbPoints.at(i - 1)._t;
1291 const qreal c_0 = tcbPoints.at(i - 1)._c;
1294 qreal
const t_1 = tcbPoints.at(i)._t;
1295 qreal
const c_1 = tcbPoints.at(i)._c;
1299 const QPointF c0(tcbPoints.at(i - 1)._point);
1300 const QPointF c3(tcbPoints.at(i)._point);
1304 c_minusOne = tcbPoints.at(i - 2)._point;
1305 b_0 = tcbPoints.at(i - 1)._b;
1308 if (i < (count - 1)) {
1309 c4 = tcbPoints.at(i + 1)._point;
1310 b_1 = tcbPoints.at(i)._b;
1313 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()));
1314 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()));
1316 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()));
1317 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()));
1319 const QPointF d_0 = QPointF(dx_0, dy_0);
1320 const QPointF d_1 = QPointF(dx_1, dy_1);
1322 QPointF c1 = (3 * c0 + d_0) / 3;
1323 QPointF c2 = (3 * c3 - d_1) / 3;
1324 bezierPoints << c1 << c2 << c3;
1326 return bezierPoints;
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343void QEasingCurve::addTCBSegment(
const QPointF &nextPoint, qreal t, qreal c, qreal b)
1346 d_ptr->config = curveToFunctionObject(d_ptr->type);
1348 d_ptr->config->_tcbPoints.append(TCBPoint{nextPoint, t, c, b});
1350 if (nextPoint == QPointF(1.0, 1.0)) {
1351 d_ptr->config->_bezierCurves = tcbToBezier(d_ptr->config->_tcbPoints);
1352 d_ptr->config->_tcbPoints.clear();
1358
1359
1360
1361
1362
1363
1364QList<QPointF> QEasingCurve::toCubicSpline()
const
1366 return d_ptr->config ? d_ptr->config->_bezierCurves : QList<QPointF>();
1370
1371
1372QEasingCurve::Type QEasingCurve::type()
const
1377void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType)
1380 qreal period = -1.0;
1381 qreal overshoot = -1.0;
1382 QList<QPointF> bezierCurves;
1383 QList<TCBPoint> tcbPoints;
1387 period = config->_p;
1388 overshoot = config->_o;
1389 bezierCurves =
std::move(config->_bezierCurves);
1396 if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0) ||
1397 !bezierCurves.isEmpty()) {
1402 config->_p = period;
1403 if (overshoot != -1.0)
1404 config->_o = overshoot;
1405 config->_bezierCurves =
std::move(bezierCurves);
1408 }
else if (newType != QEasingCurve::Custom) {
1409 func = curveToFunc(newType);
1411 Q_ASSERT((func ==
nullptr) == (config !=
nullptr));
1416
1417
1418void QEasingCurve::setType(Type type)
1420 if (d_ptr->type == type)
1422 if (type < Linear || type >= NCurveTypes - 1) {
1423 qWarning(
"QEasingCurve: Invalid curve type %d", type);
1427 d_ptr->setType_helper(type);
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441void QEasingCurve::setCustomType(EasingFunction func)
1444 qWarning(
"Function pointer must not be null");
1448 d_ptr->setType_helper(Custom);
1452
1453
1454
1455
1456QEasingCurve::EasingFunction QEasingCurve::customType()
const
1458 return d_ptr->type == Custom ? d_ptr->func :
nullptr;
1462
1463
1464
1465
1466
1467qreal QEasingCurve::valueForProgress(qreal progress)
const
1469 progress = qBound<qreal>(0, progress, 1);
1471 return d_ptr->func(progress);
1472 else if (d_ptr->config)
1473 return d_ptr->config->value(progress);
1478#ifndef QT_NO_DEBUG_STREAM
1481 QDebugStateSaver saver(debug);
1482 debug <<
"type:" << item.d_ptr->type
1483 <<
"func:" <<
reinterpret_cast<
const void *>(item.d_ptr->func);
1484 if (item.d_ptr->config) {
1485 debug << QString::fromLatin1(
"period:%1").arg(item.d_ptr->config->_p, 0,
'f', 20)
1486 << QString::fromLatin1(
"amp:%1").arg(item.d_ptr->config->_a, 0,
'f', 20)
1487 << QString::fromLatin1(
"overshoot:%1").arg(item.d_ptr->config->_o, 0,
'f', 20);
1493#ifndef QT_NO_DATASTREAM
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1509 if (easing.d_ptr->type == QEasingCurve::Custom) {
1510 qWarning(
"QEasingCurve: Cannot serialize an easing curve with a custom easing function");
1517 static_assert(isConfigFunction(QEasingCurve::InElastic));
1518 stream << QEasingCurve(QEasingCurve::InElastic);
1522 stream << quint8(easing.d_ptr->type);
1524 stream << quint64(0);
1526 bool hasConfig = easing.d_ptr->config;
1527 stream << hasConfig;
1529 stream << easing.d_ptr->config;
1535
1536
1537
1538
1539
1540
1541
1542
1546 QEasingCurve::Type type;
1549 type =
static_cast<QEasingCurve::Type>(int_type);
1550 if (type == QEasingCurve::Custom) {
1551 qWarning(
"QEasingCurve: Cannot deserialize an easing curve with a custom easing function");
1552 stream.setStatus(QDataStream::ReadCorruptData);
1553 type = QEasingCurve::Linear;
1555 easing.setType(type);
1558 [[maybe_unused]] quint64 ptr_func;
1562 stream >> hasConfig;
1563 delete easing.d_ptr->config;
1564 easing.d_ptr->config =
nullptr;
1568 easing.d_ptr->config = config;
1576#include "moc_qeasingcurve.cpp"
virtual ~QEasingCurveFunction()
QEasingCurveFunction(QEasingCurve::Type type, qreal period=0.3, qreal amplitude=1.0, qreal overshoot=1.70158)
virtual qreal value(qreal t)
QList< QPointF > _bezierCurves
bool fuzzyCompare(const QEasingCurveFunction &other) const noexcept
QEasingCurveFunction(const QEasingCurveFunction &)=default
virtual QEasingCurveFunction * clone() const
\inmodule QtCore\reentrant
static QList< QPointF > tcbToBezier(const TCBPoints &tcbPoints)
static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve)
Q_DECLARE_TYPEINFO(TCBPoint, Q_PRIMITIVE_TYPE)
static QT_BEGIN_NAMESPACE constexpr bool isConfigFunction(QEasingCurve::Type type)
QDataStream & operator<<(QDataStream &stream, QEasingCurveFunction *func)
QList< TCBPoint > TCBPoints
QDataStream & operator>>(QDataStream &stream, QEasingCurveFunction *func)
QDataStream & operator>>(QDataStream &stream, TCBPoint &point)
static QEasingCurveFunction * curveToFunctionObject(QEasingCurve::Type type)
QDataStream & operator<<(QDataStream &stream, const TCBPoint &point)
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
QDataStream & operator>>(QDataStream &stream, QImage &image)
qreal value(qreal t) override
BackEase * clone() const override
BackEase(QEasingCurve::Type type)
static float _fast_cbrt(float x)
static qreal evaluateDerivateForX(const SingleCubicBezier &singleCubicBezier, qreal t)
static qreal evaluateForX(const SingleCubicBezier &singleCubicBezier, qreal t)
static qreal _acos(qreal x)
static void cosacos(qreal x, qreal &s1, qreal &s2, qreal &s3)
static qreal _cos(qreal x)
static qreal _cbrt(qreal d)
static qreal newtonIteration(const SingleCubicBezier &singleCubicBezier, qreal t, qreal x)
static qreal evaluateSegmentForY(const SingleCubicBezier &singleCubicBezier, qreal t)
QList< SingleCubicBezier > _curves
static qreal singleRealSolutionForCubic(qreal a, qreal b, qreal c)
qreal value(qreal x) override
void getBezierSegment(SingleCubicBezier *&singleCubicBezier, qreal x)
static qreal findTForX(const SingleCubicBezier &singleCubicBezier, qreal x)
BezierEase(QEasingCurve::Type type=QEasingCurve::BezierSpline)
BezierEase * clone() const override
QList< qreal > _intervals
static double _fast_cbrt(double d)
static bool inRange(qreal f)
static bool almostZero(qreal value)
BounceEase(QEasingCurve::Type type)
BounceEase * clone() const override
qreal value(qreal t) override
ElasticEase * clone() const override
qreal value(qreal t) override
ElasticEase(QEasingCurve::Type type)
TCBEase * clone() const override
qreal value(qreal x) override
friend bool operator==(const TCBPoint &lhs, const TCBPoint &rhs) noexcept