Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qabstractanimation.cpp
Go to the documentation of this file.
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
108#include "qabstractanimation.h"
109#include "qanimationgroup.h"
110
111#include <QtCore/qdebug.h>
112
113#include "qabstractanimation_p.h"
114
115#include <QtCore/qmath.h>
116#include <QtCore/qcoreevent.h>
117#include <QtCore/qpointer.h>
118#include <QtCore/qscopedvaluerollback.h>
119
120#define DEFAULT_TIMER_INTERVAL 16
121#define PAUSE_TIMER_COARSE_THRESHOLD 2000
122
124
127
180QUnifiedTimer::QUnifiedTimer() :
181 QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
182 currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false),
183 startTimersPending(false), stopTimerPending(false), allowNegativeDelta(false),
184 slowdownFactor(5.0f), profilerCallback(nullptr),
185 driverStartTime(0), temporalDrift(0)
186{
187 time.invalidate();
188 driver = &defaultDriver;
189}
190
192 = default;
193
195{
196 QUnifiedTimer *inst;
197 static thread_local std::unique_ptr<QUnifiedTimer> unifiedTimer;
198 if (create && !unifiedTimer) {
199 inst = new QUnifiedTimer;
200 unifiedTimer.reset(inst);
201 } else {
202 inst = unifiedTimer.get();
203 }
204 return inst;
205}
206
208{
209 return instance(true);
210}
211
213{
214 if (elapsed() - lastTick > 50)
216}
217
219{
220 if (driver->isRunning())
221 return driverStartTime + driver->elapsed();
222 else if (time.isValid())
223 return time.elapsed() + temporalDrift;
224
225 // Reaching here would normally indicate that the function is called
226 // under the wrong circumstances as neither pauses nor actual animations
227 // are running and there should be no need to query for elapsed().
228 return 0;
229}
230
232{
233 if (driver->isRunning()) {
234 qWarning("QUnifiedTimer::startAnimationDriver: driver is already running...");
235 return;
236 }
237 // Set the start time to the currently elapsed() value before starting.
238 // This means we get the animation system time including the temporal drift
239 // which is what we want.
240 driverStartTime = elapsed();
241 driver->start();
242}
243
245{
246 if (!driver->isRunning()) {
247 qWarning("QUnifiedTimer::stopAnimationDriver: driver is not running");
248 return;
249 }
250 // Update temporal drift. Since the driver is running, elapsed() will
251 // return the total animation time in driver-time. Subtract the current
252 // wall time to get the delta.
253 temporalDrift = elapsed() - time.elapsed();
254 driver->stop();
255}
256
258{
259 //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
260 if (insideTick)
261 return;
262
263 const qint64 totalElapsed = elapsed();
264
265 // ignore consistentTiming in case the pause timer is active
266 qint64 delta = (consistentTiming && !pauseTimer.isActive()) ?
267 timingInterval : totalElapsed - lastTick;
268 if (slowMode) {
269 if (slowdownFactor > 0)
270 delta = qRound(delta / slowdownFactor);
271 else
272 delta = 0;
273 }
274
275 lastTick = totalElapsed;
276
277 //we make sure we only call update time if the time has actually advanced
278 //* it might happen in some cases that the time doesn't change because events are delayed
279 // when the CPU load is high
280 //* it might happen in some cases that the delta is negative because the animation driver
281 // advances faster than time.elapsed()
282 if (delta != 0 && (allowNegativeDelta || delta > 0)) {
283 QScopedValueRollback<bool> guard(insideTick, true);
284 if (profilerCallback)
285 profilerCallback(delta);
286 for (currentAnimationIdx = 0; currentAnimationIdx < animationTimers.size(); ++currentAnimationIdx) {
287 QAbstractAnimationTimer *animation = animationTimers.at(currentAnimationIdx);
288 animation->updateAnimationsTime(delta);
289 }
290 currentAnimationIdx = 0;
291 }
292}
293
295{
296 int count = 0;
297 for (int i = 0; i < animationTimers.size(); ++i)
298 count += animationTimers.at(i)->runningAnimationCount();
299 return count;
300}
301
303{
304 profilerCallback = cb;
305}
306
307void QUnifiedTimer::localRestart()
308{
309 if (insideRestart)
310 return;
311
312 if (!pausedAnimationTimers.isEmpty() && (animationTimers.size() + animationTimersToStart.size() == pausedAnimationTimers.size())) {
313 driver->stop();
314 int closestTimeToFinish = closestPausedAnimationTimerTimeToFinish();
315 // use a precise timer if the pause will be short
317 pauseTimer.start(closestTimeToFinish, timerType, this);
318 } else if (!driver->isRunning()) {
319 if (pauseTimer.isActive())
320 pauseTimer.stop();
322 }
323
324}
325
327{
328 {
329 QScopedValueRollback<bool> guard(insideRestart, true);
330 for (int i = 0; i < animationTimers.size(); ++i)
331 animationTimers.at(i)->restartAnimationTimer();
332 }
333
334 localRestart();
335}
336
338{
339 timingInterval = interval;
340
341 if (driver->isRunning() && !pauseTimer.isActive()) {
342 //we changed the timing interval
345 }
346}
347
348void QUnifiedTimer::startTimers()
349{
350 startTimersPending = false;
351
352 //we transfer the waiting animations into the "really running" state
353 animationTimers += animationTimersToStart;
354 animationTimersToStart.clear();
355 if (!animationTimers.isEmpty()) {
356 if (!time.isValid()) {
357 lastTick = 0;
358 time.start();
359 temporalDrift = 0;
360 driverStartTime = 0;
361 }
362 localRestart();
363 }
364}
365
366void QUnifiedTimer::stopTimer()
367{
368 stopTimerPending = false;
369 if (animationTimers.isEmpty()) {
371 pauseTimer.stop();
372 // invalidate the start reference time
373 time.invalidate();
374 }
375}
376
378{
379 //in the case of consistent timing we make sure the order in which events come is always the same
380 //for that purpose we do as if the startstoptimer would always fire before the animation timer
381 if (consistentTiming) {
382 if (stopTimerPending)
383 stopTimer();
384 if (startTimersPending)
385 startTimers();
386 }
387
388 if (event->timerId() == pauseTimer.timerId()) {
389 // update current time on all timers
391 restart();
392 }
393}
394
396{
397 if (timer->isRegistered)
398 return;
399 timer->isRegistered = true;
400
401 QUnifiedTimer *inst = instance(true); //we create the instance if needed
402 inst->animationTimersToStart << timer;
403 if (!inst->startTimersPending) {
404 inst->startTimersPending = true;
406 }
407}
408
410{
412 if (inst) {
413 //at this point the unified timer should have been created
414 //but it might also have been already destroyed in case the application is shutting down
415
416 if (!timer->isRegistered)
417 return;
418 timer->isRegistered = false;
419
420 int idx = inst->animationTimers.indexOf(timer);
421 if (idx != -1) {
422 inst->animationTimers.removeAt(idx);
423 // this is needed if we unregister an animation while its running
424 if (idx <= inst->currentAnimationIdx)
425 --inst->currentAnimationIdx;
426
427 if (inst->animationTimers.isEmpty() && !inst->stopTimerPending) {
428 inst->stopTimerPending = true;
430 }
431 } else {
432 inst->animationTimersToStart.removeOne(timer);
433 }
434 }
435}
436
438{
440 if (!timer->isRegistered)
442
443 bool timerWasPaused = timer->isPaused;
444 timer->isPaused = true;
445 timer->pauseDuration = duration;
446 if (!timerWasPaused)
447 inst->pausedAnimationTimers << timer;
448 inst->localRestart();
449}
450
452{
453 if (!timer->isPaused)
454 return;
455
456 timer->isPaused = false;
458 inst->pausedAnimationTimers.removeOne(timer);
459 inst->localRestart();
460}
461
462int QUnifiedTimer::closestPausedAnimationTimerTimeToFinish()
463{
464 int closestTimeToFinish = INT_MAX;
465 for (TimerListConstIt it = pausedAnimationTimers.constBegin(), cend = pausedAnimationTimers.constEnd(); it != cend; ++it) {
466 const int timeToFinish = (*it)->pauseDuration;
467 if (timeToFinish < closestTimeToFinish)
468 closestTimeToFinish = timeToFinish;
469 }
470 return closestTimeToFinish;
471}
472
474{
475 if (driver != &defaultDriver) {
476 qWarning("QUnifiedTimer: animation driver already installed...");
477 return;
478 }
479
480 bool running = driver->isRunning();
481 if (running)
483 driver = d;
484 if (driver)
485 allowNegativeDelta = driver->property("allowNegativeDelta").toBool();
486 if (running)
488}
489
491{
492 if (driver != d) {
493 qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed...");
494 return;
495 }
496
497 bool running = driver->isRunning();
498 if (running)
500 driver = &defaultDriver;
501 allowNegativeDelta = false;
502 if (running)
504}
505
511{
512 return d == driver && driver != &defaultDriver;
513}
514
515QAnimationTimer::QAnimationTimer() :
516 QAbstractAnimationTimer(), lastTick(0),
517 currentAnimationIdx(0), insideTick(false),
518 startAnimationPending(false), stopTimerPending(false),
519 runningLeafAnimations(0)
520{
521}
522
524 = default;
525
527{
528 QAnimationTimer *inst;
529#if QT_CONFIG(thread)
530 static thread_local std::unique_ptr<QAnimationTimer> animationTimer;
531 if (create && !animationTimer) {
532 inst = new QAnimationTimer;
533 animationTimer.reset(inst);
534 } else {
535 inst = animationTimer.get();
536 }
537#else
539 static QAnimationTimer animationTimer;
540 inst = &animationTimer;
541#endif
542 return inst;
543}
544
546{
547 return instance(true);
548}
549
551{
554 if (instU && inst && inst->isPaused)
555 instU->updateAnimationTimers();
556}
557
559{
560 //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
561 if (insideTick)
562 return;
563
564 lastTick += delta;
565
566 //we make sure we only call update time if the time has actually changed
567 //it might happen in some cases that the time doesn't change because events are delayed
568 //when the CPU load is high
569 if (delta) {
570 QScopedValueRollback<bool> guard(insideTick, true);
571 for (currentAnimationIdx = 0; currentAnimationIdx < animations.size(); ++currentAnimationIdx) {
572 QAbstractAnimation *animation = animations.at(currentAnimationIdx);
573 int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime
574 + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta);
576 }
577 currentAnimationIdx = 0;
578 }
579}
580
582{
584 if (inst)
585 inst->restartAnimationTimer();
586}
587
589{
590 if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty())
591 QUnifiedTimer::pauseAnimationTimer(this, closestPauseAnimationTimeToFinish());
592 else if (isPaused)
594 else if (!isRegistered)
596}
597
598void QAnimationTimer::startAnimations()
599{
600 if (!startAnimationPending)
601 return;
602 startAnimationPending = false;
603
604 //force timer to update, which prevents large deltas for our newly added animations
606
607 //we transfer the waiting animations into the "really running" state
608 animations += animationsToStart;
609 animationsToStart.clear();
610 if (!animations.isEmpty())
612}
613
614void QAnimationTimer::stopTimer()
615{
616 stopTimerPending = false;
617 bool pendingStart = startAnimationPending && animationsToStart.size() > 0;
618 if (animations.isEmpty() && !pendingStart) {
621 // invalidate the start reference time
622 lastTick = 0;
623 }
624}
625
627{
628 QAnimationTimer *inst = instance(true); //we create the instance if needed
629 inst->registerRunningAnimation(animation);
630 if (isTopLevel) {
633 inst->animationsToStart << animation;
634 if (!inst->startAnimationPending) {
635 inst->startAnimationPending = true;
636 QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection);
637 }
638 }
639}
640
642{
644 if (inst) {
645 //at this point the unified timer should have been created
646 //but it might also have been already destroyed in case the application is shutting down
647
648 inst->unregisterRunningAnimation(animation);
649
650 if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
651 return;
652
653 int idx = inst->animations.indexOf(animation);
654 if (idx != -1) {
655 inst->animations.removeAt(idx);
656 // this is needed if we unregister an animation while its running
657 if (idx <= inst->currentAnimationIdx)
658 --inst->currentAnimationIdx;
659
660 if (inst->animations.isEmpty() && !inst->stopTimerPending) {
661 inst->stopTimerPending = true;
663 }
664 } else {
665 inst->animationsToStart.removeOne(animation);
666 }
667 }
669}
670
671void QAnimationTimer::registerRunningAnimation(QAbstractAnimation *animation)
672{
674 return;
675
677 runningPauseAnimations << animation;
678 } else
679 runningLeafAnimations++;
680}
681
682void QAnimationTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
683{
685 return;
686
688 runningPauseAnimations.removeOne(animation);
689 else
690 runningLeafAnimations--;
691 Q_ASSERT(runningLeafAnimations >= 0);
692}
693
694int QAnimationTimer::closestPauseAnimationTimeToFinish()
695{
696 int closestTimeToFinish = INT_MAX;
697 for (AnimationListConstIt it = runningPauseAnimations.constBegin(), cend = runningPauseAnimations.constEnd(); it != cend; ++it) {
699 int timeToFinish;
700
702 timeToFinish = animation->duration() - animation->currentLoopTime();
703 else
704 timeToFinish = animation->currentLoopTime();
705
706 if (timeToFinish < closestTimeToFinish)
707 closestTimeToFinish = timeToFinish;
708 }
709 return closestTimeToFinish;
710}
711
727{
728}
729
731 : QObject(dd, parent)
732{
733}
734
736{
738 if (timer && timer->canUninstallAnimationDriver(this))
739 uninstall();
740}
741
751{
753
754 // update current time on all top level animations
755 instance->updateAnimationTimers();
756 instance->restart();
757}
758
759
760
767{
769}
770
771
772
779{
781 timer->installAnimationDriver(this);
782}
783
784
785
791{
793 timer->uninstallAnimationDriver(this);
794}
795
797{
798 return d_func()->running;
799}
800
801
803{
804 Q_D(QAnimationDriver);
805 if (!d->running) {
806 d->running = true;
807 d->timer.start();
808 emit started();
809 }
810}
811
812
814{
815 Q_D(QAnimationDriver);
816 if (d->running) {
817 d->running = false;
818 emit stopped();
819 }
820}
821
822
830{
831 Q_D(const QAnimationDriver);
832 return d->running ? d->timer.elapsed() : 0;
833}
834
857 : QAnimationDriver(nullptr), m_unified_timer(timer)
858{
859 connect(this, SIGNAL(started()), this, SLOT(startTimer()));
860 connect(this, SIGNAL(stopped()), this, SLOT(stopTimer()));
861}
862
864 = default;
865
867{
868 Q_ASSERT(e->timerId() == m_timer.timerId());
869 Q_UNUSED(e); // if the assertions are disabled
870 advance();
871}
872
873void QDefaultAnimationDriver::startTimer()
874{
875 // always use a precise timer to drive animations
876 m_timer.start(m_unified_timer->timingInterval, Qt::PreciseTimer, this);
877}
878
879void QDefaultAnimationDriver::stopTimer()
880{
881 m_timer.stop();
882}
883
885 = default;
886
888 = default;
889
891 = default;
892
894 = default;
895
897 = default;
898
900
901void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState)
902{
904 if (state == newState)
905 return;
906
907 if (loopCount == 0)
908 return;
909
911 int oldCurrentTime = currentTime;
912 int oldCurrentLoop = currentLoop;
914
915 // check if we should Rewind
917 && oldState == QAbstractAnimation::Stopped) {
918 const int oldTotalCurrentTime = totalCurrentTime;
919 //here we reset the time if needed
920 //we don't call setCurrentTime because this might change the way the animation
921 //behaves: changing the state or changing the current value
922 totalCurrentTime = currentTime = (direction == QAbstractAnimation::Forward) ?
923 0 : (loopCount == -1 ? q->duration() : q->totalDuration());
924 if (totalCurrentTime != oldTotalCurrentTime)
925 totalCurrentTime.notify();
926 }
927
928 state.setValueBypassingBindings(newState);
930
931 //(un)registration of the animation must always happen before calls to
932 //virtual function (updateState) to ensure a correct state of the timer
933 bool isTopLevel = !group || group->state() == QAbstractAnimation::Stopped;
934 if (oldState == QAbstractAnimation::Running) {
937 //the animation, is not running any more
941 }
942
943 q->updateState(newState, oldState);
944 if (!guard || newState != state) //this is to be safe if updateState changes the state
945 return;
946
947 // Notify state change
948 state.notify();
949 emit q->stateChanged(newState, oldState);
950 if (!guard || newState != state) //this is to be safe if updateState changes the state
951 return;
952
953 switch (state) {
955 break;
957 {
958
959 // this ensures that the value is updated now that the animation is running
960 if (oldState == QAbstractAnimation::Stopped) {
961 if (isTopLevel) {
962 // currentTime needs to be updated if pauseTimer is active
964 q->setCurrentTime(totalCurrentTime);
965 }
966 }
967 }
968 break;
970 // Leave running state.
971 int dura = q->duration();
972
973 if (deleteWhenStopped)
974 q->deleteLater();
975
976 if (dura == -1 || loopCount < 0
977 || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount))
978 || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) {
979 emit q->finished();
980 }
981 break;
982 }
983}
984
993{
994 // Allow auto-add on reparent
996}
997
1002 : QObject(dd, nullptr)
1003{
1004 // Allow auto-add on reparent
1006}
1007
1014{
1015 Q_D(QAbstractAnimation);
1016 //we can't call stop here. Otherwise we get pure virtual calls
1017 if (d->state != Stopped) {
1018 QAbstractAnimation::State oldState = d->state;
1019 d->state = Stopped;
1020 d->state.notify();
1021 emit stateChanged(d->state, oldState);
1022 if (oldState == QAbstractAnimation::Running)
1024 }
1025 if (d->group)
1026 d->group->removeAnimation(this);
1027}
1028
1043{
1044 Q_D(const QAbstractAnimation);
1045 return d->state;
1046}
1047
1049{
1050 Q_D(const QAbstractAnimation);
1051 return &d->state;
1052}
1053
1061{
1062 Q_D(const QAbstractAnimation);
1063 return d->group;
1064}
1065
1112{
1113 Q_D(const QAbstractAnimation);
1114 return d->direction;
1115}
1117{
1118 Q_D(QAbstractAnimation);
1119 if (d->direction == direction) {
1120 d->direction.removeBindingUnlessInWrapper();
1121 return;
1122 }
1123
1124 const QScopedPropertyUpdateGroup guard;
1125 const int oldCurrentLoop = d->currentLoop;
1126 if (state() == Stopped) {
1127 if (direction == Backward) {
1128 d->currentTime = duration();
1129 d->currentLoop = d->loopCount - 1;
1130 } else {
1131 d->currentTime = 0;
1132 d->currentLoop = 0;
1133 }
1134 }
1135
1136 // the commands order below is important: first we need to setCurrentTime with the old direction,
1137 // then update the direction on this and all children and finally restart the pauseTimer if needed
1138 if (d->hasRegisteredTimer)
1140
1141 d->direction = direction;
1143
1144 if (d->hasRegisteredTimer)
1145 // needed to update the timer interval in case of a pause animation
1147
1148 if (d->currentLoop != oldCurrentLoop)
1149 d->currentLoop.notify();
1150 d->direction.notify();
1151}
1152
1154{
1155 Q_D(QAbstractAnimation);
1156 return &d->direction;
1157}
1158
1181{
1182 Q_D(const QAbstractAnimation);
1183 return d->loopCount;
1184}
1186{
1187 Q_D(QAbstractAnimation);
1188 d->loopCount = loopCount;
1189}
1190
1192{
1193 Q_D(QAbstractAnimation);
1194 return &d->loopCount;
1195}
1196
1211{
1212 Q_D(const QAbstractAnimation);
1213 return d->currentLoop;
1214}
1215
1217{
1218 Q_D(const QAbstractAnimation);
1219 return &d->currentLoop;
1220}
1221
1247{
1248 int dura = duration();
1249 if (dura <= 0)
1250 return dura;
1251 int loopcount = loopCount();
1252 if (loopcount < 0)
1253 return -1;
1254 return dura * loopcount;
1255}
1256
1264{
1265 Q_D(const QAbstractAnimation);
1266 return d->currentTime;
1267}
1268
1287{
1288 Q_D(const QAbstractAnimation);
1289 return d->totalCurrentTime;
1290}
1291
1293{
1294 Q_D(QAbstractAnimation);
1295 return &d->totalCurrentTime;
1296}
1297
1299{
1300 Q_D(QAbstractAnimation);
1301 msecs = qMax(msecs, 0);
1302
1303 // Calculate new time and loop.
1304 int dura = duration();
1305 int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
1306 if (totalDura != -1)
1307 msecs = qMin(totalDura, msecs);
1308
1309 const int oldCurrentTime = d->totalCurrentTime;
1310 d->totalCurrentTime = msecs;
1311
1312 // Update new values.
1313 int oldLoop = d->currentLoop;
1314 d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
1315 if (d->currentLoop == d->loopCount) {
1316 //we're at the end
1317 d->currentTime = qMax(0, dura);
1318 d->currentLoop = qMax(0, d->loopCount - 1);
1319 } else {
1320 if (d->direction == Forward) {
1321 d->currentTime = (dura <= 0) ? msecs : (msecs % dura);
1322 } else {
1323 d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
1324 if (d->currentTime == dura)
1325 d->currentLoop = d->currentLoop - 1;
1326 }
1327 }
1328
1329 updateCurrentTime(d->currentTime);
1330 if (d->currentLoop != oldLoop)
1331 d->currentLoop.notify();
1332
1333 /* Notify before calling stop: As seen in tst_QSequentialAnimationGroup::clear
1334 * we might delete the animation when stop is called. Thus after stop no member
1335 * of the object must be used anymore.
1336 */
1337 if (oldCurrentTime != d->totalCurrentTime)
1338 d->totalCurrentTime.notify();
1339 // All animations are responsible for stopping the animation when their
1340 // own end state is reached; in this case the animation is time driven,
1341 // and has reached the end.
1342 if ((d->direction == Forward && d->totalCurrentTime == totalDura)
1343 || (d->direction == Backward && d->totalCurrentTime == 0)) {
1344 stop();
1345 }
1346}
1347
1365{
1366 Q_D(QAbstractAnimation);
1367 if (d->state == Running)
1368 return;
1369 d->deleteWhenStopped = policy;
1370 d->setState(Running);
1371}
1372
1384{
1385 Q_D(QAbstractAnimation);
1386
1387 if (d->state == Stopped)
1388 return;
1389
1390 d->setState(Stopped);
1391}
1392
1401{
1402 Q_D(QAbstractAnimation);
1403 if (d->state == Stopped) {
1404 qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation");
1405 return;
1406 }
1407
1408 d->setState(Paused);
1409}
1410
1419{
1420 Q_D(QAbstractAnimation);
1421 if (d->state != Paused) {
1422 qWarning("QAbstractAnimation::resume: "
1423 "Cannot resume an animation that is not paused");
1424 return;
1425 }
1426
1427 d->setState(Running);
1428}
1429
1437{
1438 if (paused)
1439 pause();
1440 else
1441 resume();
1442}
1443
1444
1449{
1450 return QObject::event(event);
1451}
1452
1470{
1471 Q_UNUSED(oldState);
1473}
1474
1482{
1484}
1485
1486
1488
1489#include "moc_qabstractanimation.cpp"
1490#include "moc_qabstractanimation_p.cpp"
static QAbstractAnimationPrivate * get(QAbstractAnimation *q)
virtual void restartAnimationTimer()=0
~QAbstractAnimationTimer() override
virtual int runningAnimationCount()=0
State state
state of the animation.
Direction direction
the direction of the animation when it is in \l Running state.
State
This enum describes the state of the animation.
void resume()
Resumes the animation after it was paused.
QBindable< Direction > bindableDirection()
void setPaused(bool)
If paused is true, the animation is paused.
void stop()
Stops the animation.
DeletionPolicy
\value KeepWhenStopped The animation will not be deleted when stopped.
virtual void updateCurrentTime(int currentTime)=0
This pure virtual function is called every time the animation's currentTime changes.
void start(QAbstractAnimation::DeletionPolicy policy=KeepWhenStopped)
Starts the animation.
bool event(QEvent *event) override
\reimp
int loopCount
the loop count of the animation
QAbstractAnimation(QObject *parent=nullptr)
Constructs the QAbstractAnimation base class, and passes parent to QObject's constructor.
int totalDuration() const
Returns the total and effective duration of the animation, including the loop count.
void setLoopCount(int loopCount)
QBindable< int > bindableCurrentLoop() const
int currentLoopTime() const
Returns the current time inside the current loop.
void setDirection(Direction direction)
int currentLoop
the current loop of the animation
virtual void updateDirection(QAbstractAnimation::Direction direction)
This virtual function is called by QAbstractAnimation when the direction of the animation is changed.
int currentTime
the current time and progress of the animation
void setCurrentTime(int msecs)
virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
This virtual function is called by QAbstractAnimation when the state of the animation is changed from...
Direction
This enum describes the direction of the animation when in \l Running state.
QBindable< QAbstractAnimation::State > bindableState() const
QBindable< int > bindableCurrentTime()
void pause()
Pauses the animation.
void stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
QAbstractAnimation emits this signal whenever the state of the animation has changed from oldState to...
virtual ~QAbstractAnimation()
Stops the animation if it's running, then destroys the QAbstractAnimation.
QBindable< int > bindableLoopCount()
QAnimationGroup * group() const
If this animation is part of a QAnimationGroup, this function returns a pointer to the group; otherwi...
int duration
the duration of the animation.
~QAnimationDriverPrivate() override
\inmodule QtCore
void install()
Installs this animation driver.
virtual qint64 elapsed() const
Returns the number of milliseconds since the animations was started.
void started()
This signal is emitted by the animation framework to notify the driver that continuous animation has ...
virtual void advance()
Advances the animation.
void advanceAnimation()
Advances the animation.
QAnimationDriver(QObject *parent=nullptr)
void stopped()
This signal is emitted by the animation framework to notify the driver that continuous animation has ...
void uninstall()
Uninstalls this animation driver.
\inmodule QtCore
static void unregisterAnimation(QAbstractAnimation *animation)
static void updateAnimationTimer()
void updateAnimationsTime(qint64 delta) override
~QAnimationTimer() override
void restartAnimationTimer() override
static void ensureTimerUpdate()
static void registerAnimation(QAbstractAnimation *animation, bool isTopLevel)
static QAnimationTimer * instance()
void start(int msec, QObject *obj)
\obsolete Use chrono overload instead.
int timerId() const noexcept
Returns the timer's ID.
Definition qbasictimer.h:35
void stop()
Stops the timer.
bool isActive() const noexcept
Returns true if the timer is running and has not been stopped; otherwise returns false.
Definition qbasictimer.h:34
\inmodule QtCore
Definition qproperty.h:809
~QDefaultAnimationDriver() override
QDefaultAnimationDriver(QUnifiedTimer *timer)
The default animation driver just spins the timer...
void timerEvent(QTimerEvent *e) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
void invalidate() noexcept
Marks this QElapsedTimer object as invalid.
qint64 elapsed() const noexcept
Returns the number of milliseconds since this QElapsedTimer was last started.
void start() noexcept
Starts this timer.
bool isValid() const noexcept
Returns false if the timer has never been started or invalidated by a call to invalidate().
\inmodule QtCore
Definition qcoreevent.h:45
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
void removeAt(qsizetype i)
Definition qlist.h:573
bool removeOne(const AT &t)
Definition qlist.h:581
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
const_iterator constBegin() const noexcept
Definition qlist.h:615
const_iterator constEnd() const noexcept
Definition qlist.h:616
void clear()
Definition qlist.h:417
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2142
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4187
\inmodule QtCore
Definition qpointer.h:18
RAII class around Qt::beginPropertyUpdateGroup()/Qt::endPropertyUpdateGroup().
Definition qproperty.h:57
\inmodule QtCore
Definition qcoreevent.h:359
\inmodule QtCore
static void stopAnimationTimer(QAbstractAnimationTimer *timer)
void installAnimationDriver(QAnimationDriver *driver)
void setTimingInterval(int interval)
static void startAnimationTimer(QAbstractAnimationTimer *timer)
qint64 elapsed() const
void maybeUpdateAnimationsToCurrentTime()
void registerProfilerCallback(void(*cb)(qint64))
static void resumeAnimationTimer(QAbstractAnimationTimer *timer)
bool canUninstallAnimationDriver(QAnimationDriver *driver)
Returns true if d is the currently installed animation driver and is not the default animation driver...
void timerEvent(QTimerEvent *) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
~QUnifiedTimer() override
static QUnifiedTimer * instance()
static void pauseAnimationTimer(QAbstractAnimationTimer *timer, int duration)
void uninstallAnimationDriver(QAnimationDriver *driver)
int duration
the duration of the animation
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
#define this
Definition dialogs.cpp:9
double e
QSet< QString >::iterator it
direction
else opt state
[0]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
const PluginKeyMapConstIterator cend
Combined button and popup list for selecting options.
TimerType
@ CoarseTimer
@ PreciseTimer
@ QueuedConnection
#define DEFAULT_TIMER_INTERVAL
QT_BEGIN_NAMESPACE typedef QList< QAbstractAnimationTimer * >::ConstIterator TimerListConstIt
QList< QAbstractAnimation * >::ConstIterator AnimationListConstIt
#define PAUSE_TIMER_COARSE_THRESHOLD
static Q_CONSTINIT QBasicAtomicInt running
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLenum GLenum GLsizei count
GLboolean GLuint group
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
static double elapsed(qint64 after, qint64 before)
#define emit
#define Q_UNUSED(x)
long long qint64
Definition qtypes.h:55
static double currentTime()
QObject::connect nullptr
QTimer * timer
[3]
QPropertyAnimation animation
[0]
QSizePolicy policy
view create()
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:955
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent