1673 lines
60 KiB
C++
1673 lines
60 KiB
C++
|
/****************************************************************************
|
||
|
**
|
||
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||
|
** All rights reserved.
|
||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||
|
**
|
||
|
** This file is part of the test suite of the Qt Toolkit.
|
||
|
**
|
||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||
|
** No Commercial Usage
|
||
|
** This file contains pre-release code and may not be distributed.
|
||
|
** You may use this file in accordance with the terms and conditions
|
||
|
** contained in the Technology Preview License Agreement accompanying
|
||
|
** this package.
|
||
|
**
|
||
|
** GNU Lesser General Public License Usage
|
||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||
|
** General Public License version 2.1 as published by the Free Software
|
||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||
|
** packaging of this file. Please review the following information to
|
||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||
|
**
|
||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||
|
**
|
||
|
** If you have questions regarding the use of this file, please contact
|
||
|
** Nokia at qt-info@nokia.com.
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
**
|
||
|
** $QT_END_LICENSE$
|
||
|
**
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include <QtTest/QtTest>
|
||
|
#include "../../shared/util.h"
|
||
|
|
||
|
#include <QtCore/qanimationgroup.h>
|
||
|
#include <QtCore/qsequentialanimationgroup.h>
|
||
|
|
||
|
//TESTED_CLASS=QSequentialAnimationGroup
|
||
|
//TESTED_FILES=
|
||
|
|
||
|
Q_DECLARE_METATYPE(QAbstractAnimation::State)
|
||
|
Q_DECLARE_METATYPE(QAbstractAnimation*)
|
||
|
|
||
|
class tst_QSequentialAnimationGroup : public QObject
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public:
|
||
|
tst_QSequentialAnimationGroup();
|
||
|
virtual ~tst_QSequentialAnimationGroup();
|
||
|
|
||
|
public Q_SLOTS:
|
||
|
void init();
|
||
|
void cleanup();
|
||
|
|
||
|
private slots:
|
||
|
void construction();
|
||
|
void setCurrentTime();
|
||
|
void setCurrentTimeWithUncontrolledAnimation();
|
||
|
void seekingForwards();
|
||
|
void seekingBackwards();
|
||
|
void pauseAndResume();
|
||
|
void restart();
|
||
|
void looping();
|
||
|
void startDelay();
|
||
|
void clearGroup();
|
||
|
void groupWithZeroDurationAnimations();
|
||
|
void propagateGroupUpdateToChildren();
|
||
|
void updateChildrenWithRunningGroup();
|
||
|
void deleteChildrenWithRunningGroup();
|
||
|
void startChildrenWithStoppedGroup();
|
||
|
void stopGroupWithRunningChild();
|
||
|
void startGroupWithRunningChild();
|
||
|
void zeroDurationAnimation();
|
||
|
void stopUncontrolledAnimations();
|
||
|
void finishWithUncontrolledAnimation();
|
||
|
void addRemoveAnimation();
|
||
|
void currentAnimation();
|
||
|
void currentAnimationWithZeroDuration();
|
||
|
void insertAnimation();
|
||
|
void clear();
|
||
|
void pauseResume();
|
||
|
};
|
||
|
|
||
|
tst_QSequentialAnimationGroup::tst_QSequentialAnimationGroup()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
tst_QSequentialAnimationGroup::~tst_QSequentialAnimationGroup()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::init()
|
||
|
{
|
||
|
qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State");
|
||
|
qRegisterMetaType<QAbstractAnimation*>("QAbstractAnimation*");
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::cleanup()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::construction()
|
||
|
{
|
||
|
QSequentialAnimationGroup animationgroup;
|
||
|
}
|
||
|
|
||
|
class AnimationObject : public QObject
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
Q_PROPERTY(int value READ value WRITE setValue)
|
||
|
public:
|
||
|
AnimationObject(int startValue = 0)
|
||
|
: v(startValue)
|
||
|
{ }
|
||
|
|
||
|
int value() const { return v; }
|
||
|
void setValue(int value) { v = value; }
|
||
|
|
||
|
int v;
|
||
|
};
|
||
|
|
||
|
class TestAnimation : public QVariantAnimation
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public:
|
||
|
virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
|
||
|
virtual void updateState(QAbstractAnimation::State newState,
|
||
|
QAbstractAnimation::State oldState)
|
||
|
{
|
||
|
Q_UNUSED(oldState)
|
||
|
Q_UNUSED(newState)
|
||
|
};
|
||
|
};
|
||
|
|
||
|
class DummyPropertyAnimation : public QPropertyAnimation
|
||
|
{
|
||
|
public:
|
||
|
DummyPropertyAnimation(QObject *parent = 0) : QPropertyAnimation(parent)
|
||
|
{
|
||
|
setTargetObject(&o);
|
||
|
this->setPropertyName("value");
|
||
|
setEndValue(0);
|
||
|
}
|
||
|
|
||
|
AnimationObject o;
|
||
|
};
|
||
|
|
||
|
class UncontrolledAnimation : public QPropertyAnimation
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public:
|
||
|
UncontrolledAnimation(QObject *target, QObject *parent = 0)
|
||
|
: QPropertyAnimation(target, "value", parent)
|
||
|
{
|
||
|
setDuration(250);
|
||
|
setEndValue(0);
|
||
|
}
|
||
|
|
||
|
int duration() const { return -1; /* not time driven */ }
|
||
|
|
||
|
protected:
|
||
|
void updateCurrentTime(int currentTime)
|
||
|
{
|
||
|
QPropertyAnimation::updateCurrentTime(currentTime);
|
||
|
if (currentTime >= QPropertyAnimation::duration())
|
||
|
stop();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::setCurrentTime()
|
||
|
{
|
||
|
// sequence operating on same object/property
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
|
||
|
a2_s_o1->setLoopCount(3);
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a2_s_o1);
|
||
|
sequence->addAnimation(a3_s_o1);
|
||
|
|
||
|
// sequence operating on different object/properties
|
||
|
QAnimationGroup *sequence2 = new QSequentialAnimationGroup();
|
||
|
QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
|
||
|
sequence2->addAnimation(a1_s_o2);
|
||
|
sequence2->addAnimation(a1_s_o3);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
group.addAnimation(sequence2);
|
||
|
|
||
|
// Current time = 1
|
||
|
group.setCurrentTime(1);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(group.currentLoopTime(), 1);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 1);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 250
|
||
|
group.setCurrentTime(250);
|
||
|
QCOMPARE(group.currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 251
|
||
|
group.setCurrentTime(251);
|
||
|
QCOMPARE(group.currentLoopTime(), 251);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 251);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 1);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 750
|
||
|
group.setCurrentTime(750);
|
||
|
QCOMPARE(group.currentLoopTime(), 750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 750);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1000
|
||
|
group.setCurrentTime(1000);
|
||
|
QCOMPARE(group.currentLoopTime(), 1000);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1000);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1010
|
||
|
group.setCurrentTime(1010);
|
||
|
QCOMPARE(group.currentLoopTime(), 1010);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1010);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 10);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1250
|
||
|
group.setCurrentTime(1250);
|
||
|
QCOMPARE(group.currentLoopTime(), 1250);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1500
|
||
|
group.setCurrentTime(1500);
|
||
|
QCOMPARE(group.currentLoopTime(), 1500);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1750
|
||
|
group.setCurrentTime(1750);
|
||
|
QCOMPARE(group.currentLoopTime(), 1750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 250);
|
||
|
|
||
|
// Current time = 2000
|
||
|
group.setCurrentTime(2000);
|
||
|
QCOMPARE(group.currentLoopTime(), 1750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 250);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation()
|
||
|
{
|
||
|
AnimationObject t_o1;
|
||
|
|
||
|
// sequence operating on different object/properties
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QPropertyAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QPropertyAnimation *a1_s_o2 = new DummyPropertyAnimation;
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a1_s_o2);
|
||
|
|
||
|
QPropertyAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1);
|
||
|
QCOMPARE(notTimeDriven->totalDuration(), -1);
|
||
|
|
||
|
QAbstractAnimation *loopsForever = new DummyPropertyAnimation;
|
||
|
loopsForever->setLoopCount(-1);
|
||
|
QCOMPARE(loopsForever->totalDuration(), -1);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
group.addAnimation(notTimeDriven);
|
||
|
group.addAnimation(loopsForever);
|
||
|
group.start();
|
||
|
group.pause(); // this allows the group to listen for the finish signal of its children
|
||
|
|
||
|
// Current time = 1
|
||
|
group.setCurrentTime(1);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(group.currentLoopTime(), 1);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 1);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 0);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 250
|
||
|
group.setCurrentTime(250);
|
||
|
QCOMPARE(group.currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 0);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 500
|
||
|
group.setCurrentTime(500);
|
||
|
QCOMPARE(group.currentLoopTime(), 500);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 0);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation *>(notTimeDriven));
|
||
|
|
||
|
// Current time = 505
|
||
|
group.setCurrentTime(505);
|
||
|
QCOMPARE(group.currentLoopTime(), 505);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 5);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation *>(notTimeDriven));
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
// Current time = 750 (end of notTimeDriven animation)
|
||
|
group.setCurrentTime(750);
|
||
|
QCOMPARE(group.currentLoopTime(), 750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 250);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), loopsForever);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(loopsForever->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
// Current time = 800 (as notTimeDriven was finished at 750, loopsforever should still run)
|
||
|
group.setCurrentTime(800);
|
||
|
QCOMPARE(group.currentLoopTime(), 800);
|
||
|
QCOMPARE(group.currentAnimation(), loopsForever);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(notTimeDriven->currentLoopTime(), 250);
|
||
|
QCOMPARE(loopsForever->currentLoopTime(), 50);
|
||
|
|
||
|
loopsForever->stop(); // this should stop the group
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::seekingForwards()
|
||
|
{
|
||
|
|
||
|
// sequence operating on same object/property
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup;
|
||
|
QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
|
||
|
a2_s_o1->setLoopCount(3);
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a2_s_o1);
|
||
|
sequence->addAnimation(a3_s_o1);
|
||
|
|
||
|
// sequence operating on different object/properties
|
||
|
QAnimationGroup *sequence2 = new QSequentialAnimationGroup;
|
||
|
QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
|
||
|
sequence2->addAnimation(a1_s_o2);
|
||
|
sequence2->addAnimation(a1_s_o3);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
group.addAnimation(sequence2);
|
||
|
|
||
|
// Current time = 1
|
||
|
group.setCurrentTime(1);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(group.currentLoopTime(), 1);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 1);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// Current time = 1500
|
||
|
group.setCurrentTime(1500);
|
||
|
QCOMPARE(group.currentLoopTime(), 1500);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
// this will restart the group
|
||
|
group.start();
|
||
|
group.pause();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
// Current time = 1750
|
||
|
group.setCurrentTime(1750);
|
||
|
QCOMPARE(group.currentLoopTime(), 1750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 250);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::seekingBackwards()
|
||
|
{
|
||
|
// sequence operating on same object/property
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
|
||
|
a2_s_o1->setLoopCount(3);
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a2_s_o1);
|
||
|
sequence->addAnimation(a3_s_o1);
|
||
|
|
||
|
// sequence operating on different object/properties
|
||
|
QAnimationGroup *sequence2 = new QSequentialAnimationGroup();
|
||
|
QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
|
||
|
sequence2->addAnimation(a1_s_o2);
|
||
|
sequence2->addAnimation(a1_s_o3);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
group.addAnimation(sequence2);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
// Current time = 1600
|
||
|
group.setCurrentTime(1600);
|
||
|
QCOMPARE(group.currentLoopTime(), 1600);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 350);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 100);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Running);
|
||
|
|
||
|
// Seeking backwards, current time = 1
|
||
|
group.setCurrentTime(1);
|
||
|
QCOMPARE(group.currentLoopTime(), 1);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 1);
|
||
|
|
||
|
QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
|
||
|
"hence they don't reset from their current animation", Continue);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 0);
|
||
|
QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
|
||
|
"hence they don't reset from their current animation", Continue);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 0);
|
||
|
QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
|
||
|
"hence they don't reset from their current animation", Continue);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 0);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 0);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
// Current time = 2000
|
||
|
group.setCurrentTime(2000);
|
||
|
QCOMPARE(group.currentLoopTime(), 1750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1250);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 2);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(sequence2->currentLoopTime(), 500);
|
||
|
QCOMPARE(a1_s_o2->currentLoopTime(), 250);
|
||
|
QCOMPARE(a1_s_o3->currentLoopTime(), 250);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
typedef QList<QAbstractAnimation::State> StateList;
|
||
|
|
||
|
static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates)
|
||
|
{
|
||
|
bool equals = true;
|
||
|
for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
|
||
|
if (i >= spy.count() || i >= expectedStates.count()) {
|
||
|
equals = false;
|
||
|
break;
|
||
|
}
|
||
|
QList<QVariant> args = spy.at(i);
|
||
|
QAbstractAnimation::State st = expectedStates.at(i);
|
||
|
QAbstractAnimation::State actual = qVariantValue<QAbstractAnimation::State>(args.first());
|
||
|
if (equals && actual != st) {
|
||
|
equals = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!equals) {
|
||
|
const char *stateStrings[] = {"Stopped", "Paused", "Running"};
|
||
|
QString e,a;
|
||
|
for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
|
||
|
if (i < expectedStates.count()) {
|
||
|
int exp = int(expectedStates.at(i));
|
||
|
if (!e.isEmpty())
|
||
|
e += QLatin1String(", ");
|
||
|
e += QLatin1String(stateStrings[exp]);
|
||
|
}
|
||
|
if (i < spy.count()) {
|
||
|
QList<QVariant> args = spy.at(i);
|
||
|
QAbstractAnimation::State actual = qVariantValue<QAbstractAnimation::State>(args.value(1));
|
||
|
if (!a.isEmpty())
|
||
|
a += QLatin1String(", ");
|
||
|
if (int(actual) >= 0 && int(actual) <= 2) {
|
||
|
a += QLatin1String(stateStrings[int(actual)]);
|
||
|
} else {
|
||
|
a += QLatin1String("NaN");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
qDebug("\n"
|
||
|
"expected (count == %d): %s\n"
|
||
|
"actual (count == %d): %s\n", expectedStates.count(), qPrintable(e), spy.count(), qPrintable(a));
|
||
|
}
|
||
|
return equals;
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::pauseAndResume()
|
||
|
{
|
||
|
// sequence operating on same object/property
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
|
||
|
QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
|
||
|
a2_s_o1->setLoopCount(2);
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a2_s_o1);
|
||
|
sequence->addAnimation(a3_s_o1);
|
||
|
sequence->setLoopCount(2);
|
||
|
|
||
|
QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
|
||
|
group.start();
|
||
|
group.pause();
|
||
|
|
||
|
// Current time = 1751
|
||
|
group.setCurrentTime(1751);
|
||
|
QCOMPARE(group.currentLoopTime(), 1751);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 751);
|
||
|
QCOMPARE(sequence->currentLoop(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 1);
|
||
|
QCOMPARE(a3_s_o1->currentLoop(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 1);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
QCOMPARE(a1StateChangedSpy.count(), 5); // Running,Paused,Stopped,Running,Stopped
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 2); // Running,Paused
|
||
|
|
||
|
QVERIFY(compareStates(a1StateChangedSpy, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Stopped)));
|
||
|
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(1).first()),
|
||
|
QAnimationGroup::Paused);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(2).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(3).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(4).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).first()),
|
||
|
QAnimationGroup::Paused);
|
||
|
|
||
|
group.resume();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Running);
|
||
|
|
||
|
QVERIFY(group.currentLoopTime() >= 1751);
|
||
|
QVERIFY(sequence->currentLoopTime() >= 751);
|
||
|
QCOMPARE(sequence->currentLoop(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 1);
|
||
|
QCOMPARE(a3_s_o1->currentLoop(), 0);
|
||
|
QVERIFY(a3_s_o1->currentLoopTime() >= 1);
|
||
|
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 3); // Running,Paused,Running
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(2).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
|
||
|
group.pause();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
QVERIFY(group.currentLoopTime() >= 1751);
|
||
|
QVERIFY(sequence->currentLoopTime() >= 751);
|
||
|
QCOMPARE(sequence->currentLoop(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 1);
|
||
|
QCOMPARE(a3_s_o1->currentLoop(), 0);
|
||
|
QVERIFY(a3_s_o1->currentLoopTime() >= 1);
|
||
|
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 4); // Running,Paused,Running,Paused
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(3).first()),
|
||
|
QAnimationGroup::Paused);
|
||
|
|
||
|
group.stop();
|
||
|
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 5); // Running,Paused,Running,Paused,Stopped
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(4).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::restart()
|
||
|
{
|
||
|
// sequence operating on same object/property
|
||
|
QAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QSignalSpy seqCurrentAnimChangedSpy(sequence, SIGNAL(currentAnimationChanged(QAbstractAnimation*)));
|
||
|
QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
QVariantAnimation *anims[3];
|
||
|
QSignalSpy *animsStateChanged[3];
|
||
|
|
||
|
for (int i = 0; i < 3; i++) {
|
||
|
anims[i] = new DummyPropertyAnimation;
|
||
|
anims[i]->setDuration(100);
|
||
|
animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
}
|
||
|
|
||
|
anims[1]->setLoopCount(2);
|
||
|
sequence->addAnimation(anims[0]);
|
||
|
sequence->addAnimation(anims[1]);
|
||
|
sequence->addAnimation(anims[2]);
|
||
|
sequence->setLoopCount(2);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addAnimation(sequence);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QTest::qWait(500);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
|
||
|
QTest::qWait(300);
|
||
|
QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
for (int i = 0; i < 3; i++) {
|
||
|
QCOMPARE(animsStateChanged[i]->count(), 4);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(1).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(2).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(3).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 2);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(seqCurrentAnimChangedSpy.count(), 6);
|
||
|
for(int i=0; i<seqCurrentAnimChangedSpy.count(); i++)
|
||
|
QCOMPARE(static_cast<QAbstractAnimation*>(anims[i%3]), qVariantValue<QAbstractAnimation*>(seqCurrentAnimChangedSpy.at(i).at(0)));
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(animsStateChanged[0]->count(), 5);
|
||
|
QCOMPARE(animsStateChanged[1]->count(), 4);
|
||
|
QCOMPARE(animsStateChanged[2]->count(), 4);
|
||
|
QCOMPARE(seqStateChangedSpy.count(), 3);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::looping()
|
||
|
{
|
||
|
// sequence operating on same object/property
|
||
|
QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup();
|
||
|
QAbstractAnimation *a1_s_o1 = new DummyPropertyAnimation;
|
||
|
QAbstractAnimation *a2_s_o1 = new DummyPropertyAnimation;
|
||
|
QAbstractAnimation *a3_s_o1 = new DummyPropertyAnimation;
|
||
|
|
||
|
QSignalSpy a1Spy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy a2Spy(a2_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
a2_s_o1->setLoopCount(2);
|
||
|
sequence->addAnimation(a1_s_o1);
|
||
|
sequence->addAnimation(a2_s_o1);
|
||
|
sequence->addAnimation(a3_s_o1);
|
||
|
sequence->setLoopCount(2);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
group.addAnimation(sequence);
|
||
|
group.setLoopCount(2);
|
||
|
|
||
|
group.start();
|
||
|
group.pause();
|
||
|
|
||
|
// Current time = 1750
|
||
|
group.setCurrentTime(1750);
|
||
|
QCOMPARE(group.currentLoopTime(), 1750);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 750);
|
||
|
QCOMPARE(sequence->currentLoop(), 1);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 1);
|
||
|
// this animation is at the beginning because it is the current one inside sequence
|
||
|
QCOMPARE(a3_s_o1->currentLoop(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 0);
|
||
|
QCOMPARE(sequence->currentAnimation(), a3_s_o1);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
QCOMPARE(a1Spy.count(), 5); // Running,Paused,Stopped,Running,Stopped
|
||
|
QVERIFY(compareStates(a1Spy, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Stopped)));
|
||
|
|
||
|
QCOMPARE(a2Spy.count(), 4); // Running,Stopped,Running,Stopped
|
||
|
QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused)));
|
||
|
|
||
|
QCOMPARE(seqSpy.count(), 2); // Running,Paused
|
||
|
QCOMPARE(groupSpy.count(), 2); // Running,Paused
|
||
|
|
||
|
// Looping, current time = duration + 1
|
||
|
group.setCurrentTime(group.duration() + 1);
|
||
|
QCOMPARE(group.currentLoopTime(), 1);
|
||
|
QCOMPARE(group.currentLoop(), 1);
|
||
|
QCOMPARE(sequence->currentLoopTime(), 1);
|
||
|
QCOMPARE(sequence->currentLoop(), 0);
|
||
|
QCOMPARE(a1_s_o1->currentLoopTime(), 1);
|
||
|
QCOMPARE(a2_s_o1->currentLoopTime(), 250);
|
||
|
QCOMPARE(a2_s_o1->currentLoop(), 1);
|
||
|
// this animation is at the end because it was run on the previous loop
|
||
|
QCOMPARE(a3_s_o1->currentLoop(), 0);
|
||
|
QCOMPARE(a3_s_o1->currentLoopTime(), 250);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(sequence->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(a1Spy.count(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped
|
||
|
QCOMPARE(a2Spy.count(), 4); // Running, Stopped, Running, Stopped
|
||
|
QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused
|
||
|
<< QAbstractAnimation::Stopped)));
|
||
|
QVERIFY(compareStates(seqSpy, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused)));
|
||
|
QCOMPARE(groupSpy.count(), 2);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::startDelay()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.addPause(250);
|
||
|
group.addPause(125);
|
||
|
QCOMPARE(group.totalDuration(), 375);
|
||
|
|
||
|
group.start();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
|
||
|
QTest::qWait(500);
|
||
|
|
||
|
QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QVERIFY(group.currentLoopTime() == 375);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::clearGroup()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
static const int animationCount = 20;
|
||
|
|
||
|
for (int i = 0; i < animationCount/2; ++i) {
|
||
|
QSequentialAnimationGroup *subGroup = new QSequentialAnimationGroup(&group);
|
||
|
group.addPause(100);
|
||
|
subGroup->addPause(10);
|
||
|
}
|
||
|
|
||
|
QCOMPARE(group.animationCount(), animationCount);
|
||
|
|
||
|
QPointer<QAbstractAnimation> children[animationCount];
|
||
|
for (int i = 0; i < animationCount; ++i) {
|
||
|
QVERIFY(group.animationAt(i) != 0);
|
||
|
children[i] = group.animationAt(i);
|
||
|
}
|
||
|
|
||
|
group.clear();
|
||
|
QCOMPARE(group.animationCount(), 0);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
for (int i = 0; i < animationCount; ++i)
|
||
|
QVERIFY(children[i].isNull());
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations()
|
||
|
{
|
||
|
QObject o;
|
||
|
QObject o2;
|
||
|
|
||
|
o.setProperty("myProperty", 42);
|
||
|
o.setProperty("myOtherProperty", 13);
|
||
|
o2.setProperty("myProperty", 42);
|
||
|
o2.setProperty("myOtherProperty", 13);
|
||
|
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
QVariantAnimation *a1 = new QPropertyAnimation(&o, "myProperty");
|
||
|
a1->setDuration(0);
|
||
|
a1->setEndValue(43);
|
||
|
group.addAnimation(a1);
|
||
|
|
||
|
//this should just run fine and change nothing
|
||
|
group.setCurrentTime(0);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(a1));
|
||
|
|
||
|
QVariantAnimation *a2 = new QPropertyAnimation(&o2, "myOtherProperty");
|
||
|
a2->setDuration(500);
|
||
|
a2->setEndValue(31);
|
||
|
group.addAnimation(a2);
|
||
|
|
||
|
QVariantAnimation *a3 = new QPropertyAnimation(&o, "myProperty");
|
||
|
a3->setDuration(0);
|
||
|
a3->setEndValue(44);
|
||
|
group.addAnimation(a3);
|
||
|
|
||
|
QVariantAnimation *a4 = new QPropertyAnimation(&o, "myOtherProperty");
|
||
|
a4->setDuration(250);
|
||
|
a4->setEndValue(75);
|
||
|
group.addAnimation(a4);
|
||
|
|
||
|
QVariantAnimation *a5 = new QPropertyAnimation(&o2, "myProperty");
|
||
|
a5->setDuration(0);
|
||
|
a5->setEndValue(12);
|
||
|
group.addAnimation(a5);
|
||
|
|
||
|
QCOMPARE(o.property("myProperty").toInt(), 42);
|
||
|
QCOMPARE(o.property("myOtherProperty").toInt(), 13);
|
||
|
QCOMPARE(o2.property("myProperty").toInt(), 42);
|
||
|
QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
|
||
|
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(o.property("myProperty").toInt(), 43);
|
||
|
QCOMPARE(o.property("myOtherProperty").toInt(), 13);
|
||
|
QCOMPARE(o2.property("myProperty").toInt(), 42);
|
||
|
QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
|
||
|
|
||
|
QTest::qWait(100);
|
||
|
|
||
|
int o2val = o2.property("myOtherProperty").toInt();
|
||
|
QVERIFY(o2val > 13);
|
||
|
QVERIFY(o2val < 31);
|
||
|
QCOMPARE(o.property("myProperty").toInt(), 43);
|
||
|
QCOMPARE(o.property("myOtherProperty").toInt(), 13);
|
||
|
|
||
|
QTest::qWait(500);
|
||
|
|
||
|
QTRY_COMPARE(o.property("myProperty").toInt(), 44);
|
||
|
QCOMPARE(o2.property("myProperty").toInt(), 42);
|
||
|
QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
|
||
|
QCOMPARE(a1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a4->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(a5->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QTest::qWait(500);
|
||
|
|
||
|
QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(o.property("myProperty").toInt(), 44);
|
||
|
QCOMPARE(o.property("myOtherProperty").toInt(), 75);
|
||
|
QCOMPARE(o2.property("myProperty").toInt(), 12);
|
||
|
QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
|
||
|
QCOMPARE(a1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a2->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a3->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a4->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(a5->state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::propagateGroupUpdateToChildren()
|
||
|
{
|
||
|
// this test verifies if group state changes are updating its children correctly
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
QObject o;
|
||
|
o.setProperty("ole", 42);
|
||
|
QCOMPARE(o.property("ole").toInt(), 42);
|
||
|
|
||
|
QPropertyAnimation anim1(&o, "ole");
|
||
|
anim1.setEndValue(43);
|
||
|
anim1.setDuration(100);
|
||
|
QVERIFY(!anim1.currentValue().isValid());
|
||
|
QCOMPARE(anim1.currentValue().toInt(), 0);
|
||
|
QCOMPARE(o.property("ole").toInt(), 42);
|
||
|
|
||
|
TestAnimation anim2;
|
||
|
anim2.setStartValue(0);
|
||
|
anim2.setEndValue(100);
|
||
|
anim2.setDuration(200);
|
||
|
|
||
|
QVERIFY(anim2.currentValue().isValid());
|
||
|
QCOMPARE(anim2.currentValue().toInt(), 0);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.addAnimation(&anim1);
|
||
|
group.addAnimation(&anim2);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.pause();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
|
||
|
{
|
||
|
// assert that its possible to modify a child's state directly while their group is running
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
TestAnimation anim;
|
||
|
anim.setStartValue(0);
|
||
|
anim.setEndValue(100);
|
||
|
anim.setDuration(200);
|
||
|
|
||
|
QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
QCOMPARE(groupStateChangedSpy.count(), 0);
|
||
|
QCOMPARE(childStateChangedSpy.count(), 0);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.addAnimation(&anim);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim.state(), QAnimationGroup::Running);
|
||
|
|
||
|
QCOMPARE(groupStateChangedSpy.count(), 1);
|
||
|
QCOMPARE(childStateChangedSpy.count(), 1);
|
||
|
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(groupStateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(childStateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
|
||
|
// starting directly a running child will not have any effect
|
||
|
anim.start();
|
||
|
|
||
|
QCOMPARE(groupStateChangedSpy.count(), 1);
|
||
|
QCOMPARE(childStateChangedSpy.count(), 1);
|
||
|
|
||
|
anim.pause();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim.state(), QAnimationGroup::Paused);
|
||
|
|
||
|
// in the animation stops directly, the group will still be running
|
||
|
anim.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim.state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::deleteChildrenWithRunningGroup()
|
||
|
{
|
||
|
// test if children can be activated when their group is stopped
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
QVariantAnimation *anim1 = new TestAnimation;
|
||
|
anim1->setStartValue(0);
|
||
|
anim1->setEndValue(100);
|
||
|
anim1->setDuration(200);
|
||
|
group.addAnimation(anim1);
|
||
|
|
||
|
QCOMPARE(group.duration(), anim1->duration());
|
||
|
|
||
|
group.start();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Running);
|
||
|
|
||
|
QTest::qWait(100);
|
||
|
QTRY_VERIFY(group.currentLoopTime() > 0);
|
||
|
|
||
|
delete anim1;
|
||
|
QCOMPARE(group.animationCount(), 0);
|
||
|
QCOMPARE(group.duration(), 0);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(group.currentLoopTime(), 0); //that's the invariant
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::startChildrenWithStoppedGroup()
|
||
|
{
|
||
|
// test if children can be activated when their group is stopped
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
TestAnimation anim1;
|
||
|
anim1.setStartValue(0);
|
||
|
anim1.setEndValue(100);
|
||
|
anim1.setDuration(200);
|
||
|
|
||
|
TestAnimation anim2;
|
||
|
anim2.setStartValue(0);
|
||
|
anim2.setEndValue(100);
|
||
|
anim2.setDuration(200);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.addAnimation(&anim1);
|
||
|
group.addAnimation(&anim2);
|
||
|
|
||
|
group.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
anim1.start();
|
||
|
anim2.start();
|
||
|
anim2.pause();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Paused);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::stopGroupWithRunningChild()
|
||
|
{
|
||
|
// children that started independently will not be affected by a group stop
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
TestAnimation anim1;
|
||
|
anim1.setStartValue(0);
|
||
|
anim1.setEndValue(100);
|
||
|
anim1.setDuration(200);
|
||
|
|
||
|
TestAnimation anim2;
|
||
|
anim2.setStartValue(0);
|
||
|
anim2.setEndValue(100);
|
||
|
anim2.setDuration(200);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.addAnimation(&anim1);
|
||
|
group.addAnimation(&anim2);
|
||
|
|
||
|
anim1.start();
|
||
|
anim2.start();
|
||
|
anim2.pause();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Paused);
|
||
|
|
||
|
group.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Paused);
|
||
|
|
||
|
anim1.stop();
|
||
|
anim2.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::startGroupWithRunningChild()
|
||
|
{
|
||
|
// as the group has precedence over its children, starting a group will restart all the children
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
TestAnimation *anim1 = new TestAnimation();
|
||
|
anim1->setStartValue(0);
|
||
|
anim1->setEndValue(100);
|
||
|
anim1->setDuration(200);
|
||
|
|
||
|
TestAnimation *anim2 = new TestAnimation();
|
||
|
anim2->setStartValue(0);
|
||
|
anim2->setEndValue(100);
|
||
|
anim2->setDuration(200);
|
||
|
|
||
|
QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
QCOMPARE(stateChangedSpy1.count(), 0);
|
||
|
QCOMPARE(stateChangedSpy2.count(), 0);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
group.addAnimation(anim1);
|
||
|
group.addAnimation(anim2);
|
||
|
|
||
|
anim1->start();
|
||
|
anim2->start();
|
||
|
anim2->pause();
|
||
|
|
||
|
QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running)));
|
||
|
|
||
|
QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused)));
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Stopped
|
||
|
<< QAbstractAnimation::Running)));
|
||
|
QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
|
||
|
<< QAbstractAnimation::Paused)));
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Paused);
|
||
|
|
||
|
QTest::qWait(300);
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Running);
|
||
|
|
||
|
QCOMPARE(stateChangedSpy2.count(), 4);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(2).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(3).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
|
||
|
group.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::zeroDurationAnimation()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
TestAnimation *anim1 = new TestAnimation();
|
||
|
anim1->setStartValue(0);
|
||
|
anim1->setEndValue(100);
|
||
|
anim1->setDuration(0);
|
||
|
|
||
|
TestAnimation *anim2 = new TestAnimation();
|
||
|
anim2->setStartValue(0);
|
||
|
anim2->setEndValue(100);
|
||
|
anim2->setDuration(100);
|
||
|
|
||
|
DummyPropertyAnimation *anim3 = new DummyPropertyAnimation;
|
||
|
anim3->setEndValue(100);
|
||
|
anim3->setDuration(0);
|
||
|
|
||
|
QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
group.addAnimation(anim1);
|
||
|
group.addAnimation(anim2);
|
||
|
group.addAnimation(anim3);
|
||
|
group.setLoopCount(2);
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(stateChangedSpy.count(), 2);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(0).first()),
|
||
|
QAnimationGroup::Running);
|
||
|
QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(1).first()),
|
||
|
QAnimationGroup::Stopped);
|
||
|
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
|
||
|
//now let's try to seek to the next loop
|
||
|
group.setCurrentTime(group.duration() + 1);
|
||
|
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim2->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim3->state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim3->o.value(), 100); //anim3 should have been run
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::stopUncontrolledAnimations()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
AnimationObject o1;
|
||
|
UncontrolledAnimation notTimeDriven(&o1);
|
||
|
QCOMPARE(notTimeDriven.totalDuration(), -1);
|
||
|
|
||
|
TestAnimation loopsForever;
|
||
|
loopsForever.setStartValue(0);
|
||
|
loopsForever.setEndValue(100);
|
||
|
loopsForever.setDuration(100);
|
||
|
loopsForever.setLoopCount(-1);
|
||
|
|
||
|
group.addAnimation(¬TimeDriven);
|
||
|
group.addAnimation(&loopsForever);
|
||
|
|
||
|
group.start();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
|
||
|
|
||
|
notTimeDriven.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(loopsForever.state(), QAnimationGroup::Running);
|
||
|
|
||
|
loopsForever.stop();
|
||
|
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation()
|
||
|
{
|
||
|
AnimationObject o1;
|
||
|
|
||
|
//1st case:
|
||
|
//first we test a group with one uncontrolled animation
|
||
|
QSequentialAnimationGroup group;
|
||
|
UncontrolledAnimation notTimeDriven(&o1, &group);
|
||
|
QSignalSpy spy(&group, SIGNAL(finished()));
|
||
|
|
||
|
group.start();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QCOMPARE(notTimeDriven.currentLoopTime(), 0);
|
||
|
|
||
|
QTest::qWait(300); //wait for the end of notTimeDriven
|
||
|
QTRY_COMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
|
||
|
const int actualDuration = notTimeDriven.currentLoopTime();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(group.currentLoopTime(), actualDuration);
|
||
|
QCOMPARE(spy.count(), 1);
|
||
|
|
||
|
//2nd case:
|
||
|
// lets make sure the seeking will work again
|
||
|
spy.clear();
|
||
|
DummyPropertyAnimation anim(&group);
|
||
|
QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
|
||
|
group.setCurrentTime(300);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(notTimeDriven.currentLoopTime(), actualDuration);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
|
||
|
|
||
|
//3rd case:
|
||
|
//now let's add a perfectly defined animation at the end
|
||
|
QCOMPARE(animStateChangedSpy.count(), 0);
|
||
|
group.start();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QCOMPARE(notTimeDriven.currentLoopTime(), 0);
|
||
|
|
||
|
QCOMPARE(animStateChangedSpy.count(), 0);
|
||
|
|
||
|
QTest::qWait(300); //wait for the end of notTimeDriven
|
||
|
QTRY_COMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
|
||
|
QCOMPARE(animStateChangedSpy.count(), 1);
|
||
|
QTest::qWait(300); //wait for the end of anim
|
||
|
|
||
|
QTRY_COMPARE(anim.state(), QAnimationGroup::Stopped);
|
||
|
QCOMPARE(anim.currentLoopTime(), anim.duration());
|
||
|
|
||
|
//we should simply be at the end
|
||
|
QCOMPARE(spy.count(), 1);
|
||
|
QCOMPARE(animStateChangedSpy.count(), 2);
|
||
|
QCOMPARE(group.currentLoopTime(), notTimeDriven.currentLoopTime() + anim.currentLoopTime());
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::addRemoveAnimation()
|
||
|
{
|
||
|
//this test is specific to the sequential animation group
|
||
|
QSequentialAnimationGroup group;
|
||
|
|
||
|
QCOMPARE(group.duration(), 0);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QAbstractAnimation *anim1 = new QPropertyAnimation;
|
||
|
group.addAnimation(anim1);
|
||
|
QCOMPARE(group.duration(), 250);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), anim1);
|
||
|
|
||
|
//let's append an animation
|
||
|
QAbstractAnimation *anim2 = new QPropertyAnimation;
|
||
|
group.addAnimation(anim2);
|
||
|
QCOMPARE(group.duration(), 500);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), anim1);
|
||
|
|
||
|
//let's prepend an animation
|
||
|
QAbstractAnimation *anim0 = new QPropertyAnimation;
|
||
|
group.insertAnimation(0, anim0);
|
||
|
QCOMPARE(group.duration(), 750);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
QCOMPARE(group.currentAnimation(), anim0); //anim0 has become the new currentAnimation
|
||
|
|
||
|
group.setCurrentTime(300); //anim0 | anim1 | anim2
|
||
|
QCOMPARE(group.currentLoopTime(), 300);
|
||
|
QCOMPARE(group.currentAnimation(), anim1);
|
||
|
QCOMPARE(anim1->currentLoopTime(), 50);
|
||
|
|
||
|
group.removeAnimation(anim0); //anim1 | anim2
|
||
|
QCOMPARE(group.currentLoopTime(), 50);
|
||
|
QCOMPARE(group.currentAnimation(), anim1);
|
||
|
QCOMPARE(anim1->currentLoopTime(), 50);
|
||
|
|
||
|
group.setCurrentTime(0);
|
||
|
group.insertAnimation(0, anim0); //anim0 | anim1 | anim2
|
||
|
group.setCurrentTime(300);
|
||
|
QCOMPARE(group.currentLoopTime(), 300);
|
||
|
QCOMPARE(group.currentAnimation(), anim1);
|
||
|
QCOMPARE(anim1->currentLoopTime(), 50);
|
||
|
|
||
|
group.removeAnimation(anim1); //anim0 | anim2
|
||
|
QCOMPARE(group.currentLoopTime(), 250);
|
||
|
QCOMPARE(group.currentAnimation(), anim2);
|
||
|
QCOMPARE(anim0->currentLoopTime(), 250);
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::currentAnimation()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
QVERIFY(group.currentAnimation() == 0);
|
||
|
|
||
|
QPropertyAnimation anim;
|
||
|
anim.setDuration(0);
|
||
|
group.addAnimation(&anim);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
QVERIFY(group.currentAnimation() == 0);
|
||
|
|
||
|
QPropertyAnimation zero1;
|
||
|
zero1.setDuration(0);
|
||
|
QPropertyAnimation zero2;
|
||
|
zero2.setDuration(0);
|
||
|
|
||
|
QPropertyAnimation anim;
|
||
|
|
||
|
QPropertyAnimation zero3;
|
||
|
zero3.setDuration(0);
|
||
|
QPropertyAnimation zero4;
|
||
|
zero4.setDuration(0);
|
||
|
|
||
|
|
||
|
group.addAnimation(&zero1);
|
||
|
group.addAnimation(&zero2);
|
||
|
group.addAnimation(&anim);
|
||
|
group.addAnimation(&zero3);
|
||
|
group.addAnimation(&zero4);
|
||
|
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
|
||
|
|
||
|
group.setCurrentTime(0);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
|
||
|
|
||
|
group.setCurrentTime(group.duration());
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero4));
|
||
|
|
||
|
group.setDirection(QAbstractAnimation::Backward);
|
||
|
|
||
|
group.setCurrentTime(0);
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
|
||
|
|
||
|
group.setCurrentTime(group.duration());
|
||
|
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::insertAnimation()
|
||
|
{
|
||
|
QSequentialAnimationGroup group;
|
||
|
group.setLoopCount(2);
|
||
|
QPropertyAnimation *anim = new DummyPropertyAnimation(&group);
|
||
|
QCOMPARE(group.duration(), anim->duration());
|
||
|
group.setCurrentTime(300);
|
||
|
QCOMPARE(group.currentLoop(), 1);
|
||
|
|
||
|
//this will crash if the sequential group calls duration on the created animation
|
||
|
new QPropertyAnimation(&group);
|
||
|
}
|
||
|
|
||
|
|
||
|
class SequentialAnimationGroup : public QSequentialAnimationGroup
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public slots:
|
||
|
void clear()
|
||
|
{
|
||
|
QSequentialAnimationGroup::clear();
|
||
|
}
|
||
|
|
||
|
void refill()
|
||
|
{
|
||
|
stop();
|
||
|
clear();
|
||
|
new DummyPropertyAnimation(this);
|
||
|
start();
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::clear()
|
||
|
{
|
||
|
SequentialAnimationGroup group;
|
||
|
QPointer<QAbstractAnimation> anim1 = new DummyPropertyAnimation(&group);
|
||
|
group.connect(anim1, SIGNAL(finished()), SLOT(clear()));
|
||
|
new DummyPropertyAnimation(&group);
|
||
|
QCOMPARE(group.animationCount(), 2);
|
||
|
|
||
|
group.start();
|
||
|
QTest::qWait(anim1->duration() + 100);
|
||
|
QTRY_COMPARE(group.animationCount(), 0);
|
||
|
QCOMPARE(group.state(), QAbstractAnimation::Stopped);
|
||
|
QCOMPARE(group.currentLoopTime(), 0);
|
||
|
|
||
|
anim1 = new DummyPropertyAnimation(&group);
|
||
|
group.connect(anim1, SIGNAL(finished()), SLOT(refill()));
|
||
|
group.start();
|
||
|
QTest::qWait(anim1->duration() + 100);
|
||
|
QTRY_COMPARE(group.state(), QAbstractAnimation::Running);
|
||
|
QVERIFY(anim1 == 0); //anim1 should have been deleted
|
||
|
}
|
||
|
|
||
|
void tst_QSequentialAnimationGroup::pauseResume()
|
||
|
{
|
||
|
QObject dummy;
|
||
|
dummy.setProperty("foo", 0);
|
||
|
QParallelAnimationGroup group;
|
||
|
QPropertyAnimation *anim = new QPropertyAnimation(&dummy, "foo", &group);
|
||
|
anim->setDuration(250);
|
||
|
anim->setEndValue(250);
|
||
|
QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
|
||
|
QCOMPARE(group.duration(), 250);
|
||
|
group.start();
|
||
|
QTest::qWait(100);
|
||
|
QTRY_COMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(spy.count(), 1);
|
||
|
spy.clear();
|
||
|
const int currentTime = group.currentLoopTime();
|
||
|
QCOMPARE(anim->currentLoopTime(), currentTime);
|
||
|
|
||
|
group.pause();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(group.currentLoopTime(), currentTime);
|
||
|
QCOMPARE(anim->state(), QAnimationGroup::Paused);
|
||
|
QCOMPARE(anim->currentLoopTime(), currentTime);
|
||
|
QCOMPARE(spy.count(), 1);
|
||
|
spy.clear();
|
||
|
|
||
|
group.resume();
|
||
|
QCOMPARE(group.state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(group.currentLoopTime(), currentTime);
|
||
|
QCOMPARE(anim->state(), QAnimationGroup::Running);
|
||
|
QCOMPARE(anim->currentLoopTime(), currentTime);
|
||
|
QCOMPARE(spy.count(), 1);
|
||
|
}
|
||
|
|
||
|
QTEST_MAIN(tst_QSequentialAnimationGroup)
|
||
|
#include "tst_qsequentialanimationgroup.moc"
|