1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QABSTRACTANIMATION_P_H
5#define QABSTRACTANIMATION_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API.
12// This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qbasictimer.h>
19#include <QtCore/qdatetime.h>
20#include <QtCore/qtimer.h>
21#include <QtCore/qelapsedtimer.h>
22#include <private/qobject_p.h>
23#include <private/qproperty_p.h>
24#include <qabstractanimation.h>
25
26QT_REQUIRE_CONFIG(animation);
27
28QT_BEGIN_NAMESPACE
29
30class QAnimationGroup;
31class QAbstractAnimation;
32class Q_CORE_EXPORT QAbstractAnimationPrivate : public QObjectPrivate
33{
34public:
35 QAbstractAnimationPrivate();
36 virtual ~QAbstractAnimationPrivate();
37
38 static QAbstractAnimationPrivate *get(QAbstractAnimation *q)
39 {
40 return q->d_func();
41 }
42
43 Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, QAbstractAnimation::State,
44 state, QAbstractAnimation::Stopped)
45 void setState(QAbstractAnimation::State state);
46
47 void setDirection(QAbstractAnimation::Direction direction)
48 {
49 q_func()->setDirection(direction);
50 }
51 void emitDirectionChanged() { Q_EMIT q_func()->directionChanged(direction); }
52 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, QAbstractAnimation::Direction,
53 direction, &QAbstractAnimationPrivate::setDirection,
54 &QAbstractAnimationPrivate::emitDirectionChanged,
55 QAbstractAnimation::Forward)
56
57 void setCurrentTime(int msecs) { q_func()->setCurrentTime(msecs); }
58 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, totalCurrentTime,
59 &QAbstractAnimationPrivate::setCurrentTime, 0)
60 int currentTime = 0;
61
62 Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, loopCount, 1)
63
64 void emitCurrentLoopChanged() { Q_EMIT q_func()->currentLoopChanged(currentLoop); }
65 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractAnimationPrivate, int, currentLoop, nullptr,
66 &QAbstractAnimationPrivate::emitCurrentLoopChanged, 0)
67
68 bool deleteWhenStopped = false;
69 bool hasRegisteredTimer = false;
70 bool isPause = false;
71 bool isGroup = false;
72
73 QAnimationGroup *group = nullptr;
74
75private:
76 Q_DECLARE_PUBLIC(QAbstractAnimation)
77};
78
79
80class QUnifiedTimer;
81class QDefaultAnimationDriver : public QAnimationDriver
82{
83 Q_OBJECT
84public:
85 explicit QDefaultAnimationDriver(QUnifiedTimer *timer);
86 ~QDefaultAnimationDriver() override;
87
88protected:
89 void timerEvent(QTimerEvent *e) override;
90
91private Q_SLOTS:
92 void startTimer();
93 void stopTimer();
94
95private:
96 QBasicTimer m_timer;
97 QUnifiedTimer *m_unified_timer;
98};
99
100class Q_CORE_EXPORT QAnimationDriverPrivate : public QObjectPrivate
101{
102public:
103 QAnimationDriverPrivate();
104 ~QAnimationDriverPrivate() override;
105
106 QElapsedTimer timer;
107 bool running = false;
108};
109
110class Q_CORE_EXPORT QAbstractAnimationTimer : public QObject
111{
112 Q_OBJECT
113public:
114 QAbstractAnimationTimer();
115 ~QAbstractAnimationTimer() override;
116
117 virtual void updateAnimationsTime(qint64 delta) = 0;
118 virtual void restartAnimationTimer() = 0;
119 virtual int runningAnimationCount() = 0;
120
121 bool isRegistered = false;
122 bool isPaused = false;
123 int pauseDuration = 0;
124};
125
126class Q_CORE_EXPORT QUnifiedTimer : public QObject
127{
128 Q_OBJECT
129private:
130 QUnifiedTimer();
131
132public:
133 ~QUnifiedTimer() override;
134
135 static QUnifiedTimer *instance();
136 static QUnifiedTimer *instance(bool create);
137
138 static void startAnimationTimer(QAbstractAnimationTimer *timer);
139 static void stopAnimationTimer(QAbstractAnimationTimer *timer);
140
141 static void pauseAnimationTimer(QAbstractAnimationTimer *timer, int duration);
142 static void resumeAnimationTimer(QAbstractAnimationTimer *timer);
143
144 //defines the timing interval. Default is DEFAULT_TIMER_INTERVAL
145 void setTimingInterval(int interval);
146
147 /*
148 this allows to have a consistent timer interval at each tick from the timer
149 not taking the real time that passed into account.
150 */
151 void setConsistentTiming(bool consistent) { consistentTiming = consistent; }
152
153 //these facilitate fine-tuning of complex animations
154 void setSlowModeEnabled(bool enabled) { slowMode = enabled; }
155 void setSlowdownFactor(qreal factor) { slowdownFactor = factor; }
156
157 void installAnimationDriver(QAnimationDriver *driver);
158 void uninstallAnimationDriver(QAnimationDriver *driver);
159 bool canUninstallAnimationDriver(QAnimationDriver *driver);
160
161 void restart();
162 void maybeUpdateAnimationsToCurrentTime();
163 void updateAnimationTimers();
164
165 //useful for profiling/debugging
166 int runningAnimationCount();
167 void registerProfilerCallback(void (*cb)(qint64));
168
169 void startAnimationDriver();
170 void stopAnimationDriver();
171 qint64 elapsed() const;
172
173protected:
174 void timerEvent(QTimerEvent *) override;
175
176private Q_SLOTS:
177 void startTimers();
178 void stopTimer();
179
180private:
181 friend class QDefaultAnimationDriver;
182 friend class QAnimationDriver;
183
184 QAnimationDriver *driver;
185 QDefaultAnimationDriver defaultDriver;
186
187 QBasicTimer pauseTimer;
188
189 QElapsedTimer time;
190
191 qint64 lastTick;
192 int timingInterval;
193 int currentAnimationIdx;
194 bool insideTick;
195 bool insideRestart;
196 bool consistentTiming;
197 bool slowMode;
198 bool startTimersPending;
199 bool stopTimerPending;
200 bool allowNegativeDelta;
201
202 // This factor will be used to divide the DEFAULT_TIMER_INTERVAL at each tick
203 // when slowMode is enabled. Setting it to 0 or higher than DEFAULT_TIMER_INTERVAL (16)
204 // stops all animations.
205 qreal slowdownFactor;
206
207 QList<QAbstractAnimationTimer*> animationTimers, animationTimersToStart;
208 QList<QAbstractAnimationTimer*> pausedAnimationTimers;
209
210 void localRestart();
211 int closestPausedAnimationTimerTimeToFinish();
212
213 void (*profilerCallback)(qint64);
214
215 qint64 driverStartTime; // The time the animation driver was started
216 qint64 temporalDrift; // The delta between animation driver time and wall time.
217};
218
219class QAnimationTimer : public QAbstractAnimationTimer
220{
221 Q_OBJECT
222private:
223 QAnimationTimer();
224
225public:
226 ~QAnimationTimer() override;
227
228 static QAnimationTimer *instance();
229 static QAnimationTimer *instance(bool create);
230
231 static void registerAnimation(QAbstractAnimation *animation, bool isTopLevel);
232 static void unregisterAnimation(QAbstractAnimation *animation);
233
234 /*
235 this is used for updating the currentTime of all animations in case the pause
236 timer is active or, otherwise, only of the animation passed as parameter.
237 */
238 static void ensureTimerUpdate();
239
240 /*
241 this will evaluate the need of restarting the pause timer in case there is still
242 some pause animations running.
243 */
244 static void updateAnimationTimer();
245
246 void restartAnimationTimer() override;
247 void updateAnimationsTime(qint64 delta) override;
248
249 //useful for profiling/debugging
250 int runningAnimationCount() override { return animations.size(); }
251
252private Q_SLOTS:
253 void startAnimations();
254 void stopTimer();
255
256private:
257 qint64 lastTick;
258 int currentAnimationIdx;
259 bool insideTick;
260 bool startAnimationPending;
261 bool stopTimerPending;
262
263 QList<QAbstractAnimation*> animations, animationsToStart;
264
265 // this is the count of running animations that are not a group neither a pause animation
266 int runningLeafAnimations;
267 QList<QAbstractAnimation*> runningPauseAnimations;
268
269 void registerRunningAnimation(QAbstractAnimation *animation);
270 void unregisterRunningAnimation(QAbstractAnimation *animation);
271
272 int closestPauseAnimationTimeToFinish();
273};
274
275QT_END_NAMESPACE
276
277#endif //QABSTRACTANIMATION_P_H
278

source code of qtbase/src/corelib/animation/qabstractanimation_p.h