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