48bool QSequentialAnimationGroupPrivate::atEnd()
const
56 const int animTotalCurrentTime = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
57 return (currentLoop == loopCount - 1
58 && direction == QAbstractAnimation::Forward
59 && currentAnimation == animations.last()
60 && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex));
63int QSequentialAnimationGroupPrivate::animationActualTotalDuration(
int index)
const
65 QAbstractAnimation *anim = animations.at(index);
66 int ret = anim->totalDuration();
67 if (ret == -1 && actualDuration.size() > index)
68 ret = actualDuration.at(index);
72QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForCurrentTime()
const
74 Q_ASSERT(!animations.isEmpty());
79 for (
int i = 0; i < animations.size(); ++i) {
80 duration = animationActualTotalDuration(i);
87 if (duration == -1 || currentTime < (ret.timeOffset + duration)
88 || (currentTime == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) {
94 ret.timeOffset += duration;
100 ret.timeOffset -= duration;
101 ret.index = animations.size() - 1;
105void QSequentialAnimationGroupPrivate::restart()
108 if (direction == QAbstractAnimation::Forward) {
110 if (currentAnimationIndex == 0)
111 activateCurrentAnimation();
113 setCurrentAnimation(0);
115 lastLoop = loopCount - 1;
116 int index = animations.size() - 1;
117 if (currentAnimationIndex == index)
118 activateCurrentAnimation();
120 setCurrentAnimation(index);
130void QSequentialAnimationGroupPrivate::advanceForwards(
const AnimationIndex &newAnimationIndex)
132 if (lastLoop < currentLoop) {
134 for (
int i = currentAnimationIndex; i < animations.size(); ++i) {
135 QAbstractAnimation *anim = animations.at(i);
136 setCurrentAnimation(i,
true);
137 anim->setCurrentTime(animationActualTotalDuration(i));
140 if (animations.size() == 1)
142 activateCurrentAnimation();
144 setCurrentAnimation(0,
true);
148 for (
int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) {
149 QAbstractAnimation *anim = animations.at(i);
150 setCurrentAnimation(i,
true);
151 anim->setCurrentTime(animationActualTotalDuration(i));
162void QSequentialAnimationGroupPrivate::rewindForwards(
const AnimationIndex &newAnimationIndex)
164 if (lastLoop > currentLoop) {
166 for (
int i = currentAnimationIndex; i >= 0 ; --i) {
167 QAbstractAnimation *anim = animations.at(i);
168 setCurrentAnimation(i,
true);
169 anim->setCurrentTime(0);
172 if (animations.size() == 1)
174 activateCurrentAnimation();
176 setCurrentAnimation(animations.size() - 1,
true);
180 for (
int i = currentAnimationIndex; i > newAnimationIndex.index; --i) {
181 QAbstractAnimation *anim = animations.at(i);
182 setCurrentAnimation(i,
true);
183 anim->setCurrentTime(0);
244QPauseAnimation *QSequentialAnimationGroup::insertPause(
int index,
int msecs)
246 Q_D(
const QSequentialAnimationGroup);
248 if (index < 0 || index > d->animations.size()) {
249 qWarning(
"QSequentialAnimationGroup::insertPause: index is out of bounds");
253 QPauseAnimation *pause =
new QPauseAnimation(msecs);
254 insertAnimation(index, pause);
277int QSequentialAnimationGroup::duration()
const
279 Q_D(
const QSequentialAnimationGroup);
282 for (AnimationListConstIt it = d->animations.constBegin(), cend = d->animations.constEnd(); it != cend; ++it) {
283 const int currentDuration = (*it)->totalDuration();
284 if (currentDuration == -1)
287 ret += currentDuration;
296void QSequentialAnimationGroup::updateCurrentTime(
int currentTime)
298 Q_D(QSequentialAnimationGroup);
299 if (!d->currentAnimation)
302 const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForCurrentTime();
305 while (newAnimationIndex.index < d->actualDuration.size())
306 d->actualDuration.removeLast();
309 if (d->lastLoop < d->currentLoop
310 || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) {
312 d->advanceForwards(newAnimationIndex);
313 }
else if (d->lastLoop > d->currentLoop
314 || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) {
316 d->rewindForwards(newAnimationIndex);
319 d->setCurrentAnimation(newAnimationIndex.index);
321 const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;
323 if (d->currentAnimation) {
324 d->currentAnimation->setCurrentTime(newCurrentTime);
327 d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime;
333 Q_ASSERT(d->animations.isEmpty());
338 d->lastLoop = d->currentLoop;
344void QSequentialAnimationGroup::updateState(QAbstractAnimation::State newState,
345 QAbstractAnimation::State oldState)
347 Q_D(QSequentialAnimationGroup);
348 QAnimationGroup::updateState(newState, oldState);
350 if (!d->currentAnimation)
355 d->currentAnimation->stop();
358 if (oldState == d->currentAnimation->state()
359 && oldState == QSequentialAnimationGroup::Running) {
360 d->currentAnimation->pause();
366 if (oldState == d->currentAnimation->state()
367 && oldState == QSequentialAnimationGroup::Paused)
368 d->currentAnimation->start();
394void QSequentialAnimationGroupPrivate::setCurrentAnimation(
int index,
bool intermediate)
396 Q_Q(QSequentialAnimationGroup);
400 index = qMin(index, animations.size() - 1);
403 Q_ASSERT(animations.isEmpty());
404 currentAnimationIndex = -1;
405 currentAnimation =
nullptr;
411 if (index == currentAnimationIndex && animations.at(index) == currentAnimation)
415 if (currentAnimation)
416 currentAnimation->stop();
418 currentAnimationIndex = index;
419 currentAnimation = animations.at(index);
421 emit q->currentAnimationChanged(currentAnimation);
423 activateCurrentAnimation(intermediate);
426void QSequentialAnimationGroupPrivate::activateCurrentAnimation(
bool intermediate)
428 if (!currentAnimation || state == QSequentialAnimationGroup::Stopped)
431 currentAnimation->stop();
434 currentAnimation->setDirection(direction);
437 if (currentAnimation->totalDuration() == -1)
438 connectUncontrolledAnimation(currentAnimation);
440 currentAnimation->start();
441 if (!intermediate && state == QSequentialAnimationGroup::Paused)
442 currentAnimation->pause();
445void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
447 Q_Q(QSequentialAnimationGroup);
448 Q_ASSERT(qobject_cast<QAbstractAnimation *>(q->sender()) == currentAnimation);
451 while (actualDuration.size() < (currentAnimationIndex + 1))
452 actualDuration.append(-1);
453 actualDuration[currentAnimationIndex] = currentAnimation->currentTime();
455 disconnectUncontrolledAnimation(currentAnimation);
457 if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last())
458 || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) {
461 }
else if (direction == QAbstractAnimation::Forward) {
463 setCurrentAnimation(currentAnimationIndex + 1);
466 setCurrentAnimation(currentAnimationIndex - 1);
476void QSequentialAnimationGroupPrivate::animationInsertedAt(qsizetype index)
478 if (currentAnimation ==
nullptr) {
479 setCurrentAnimation(0);
480 Q_ASSERT(currentAnimation);
483 if (currentAnimationIndex == index
484 && currentAnimation->currentTime() == 0 && currentAnimation->currentLoop() == 0) {
486 setCurrentAnimation(index);
490 currentAnimationIndex = animations.indexOf(currentAnimation);
492 if (index < currentAnimationIndex || currentLoop != 0) {
493 qWarning(
"QSequentialGroup::insertAnimation only supports to add animations after the current one.");
504void QSequentialAnimationGroupPrivate::animationRemoved(qsizetype index, QAbstractAnimation *anim)
506 Q_Q(QSequentialAnimationGroup);
507 QAnimationGroupPrivate::animationRemoved(index, anim);
509 if (!currentAnimation)
512 if (actualDuration.size() > index)
513 actualDuration.removeAt(index);
515 const qsizetype currentIndex = animations.indexOf(currentAnimation);
516 if (currentIndex == -1) {
519 disconnectUncontrolledAnimation(currentAnimation);
521 if (index < animations.size())
522 setCurrentAnimation(index);
524 setCurrentAnimation(index - 1);
526 setCurrentAnimation(-1);
527 }
else if (currentAnimationIndex > index) {
528 currentAnimationIndex--;
533 for (qsizetype i = 0; i < currentAnimationIndex; ++i) {
534 const int current = animationActualTotalDuration(i);
535 currentTime += current;
538 if (currentIndex != -1) {
541 currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
545 totalCurrentTime = currentTime + loopCount * q->duration();