* startElementAnimation -> animateElement
* animate -> animateItem * frames -> framesPerSecond * use the curve shape as provided by the animator * get rid of the use of QTimeLine * this cuts down on the number of objects and timer events dramatically in the case of multiple simultaneous animations * all animations now update on the same tick * simplifies the management code a -lot- though now i need to do a lot more of the math TODO: implement interval updating based on the curve shape; otherwise, works pretty well =) svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=679871
This commit is contained in:
parent
1ba292c158
commit
45ee70aa26
386
phase.cpp
386
phase.cpp
@ -19,7 +19,6 @@
|
|||||||
#include "phase.h"
|
#include "phase.h"
|
||||||
|
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <QTimeLine>
|
|
||||||
|
|
||||||
#include <KConfig>
|
#include <KConfig>
|
||||||
#include <KConfigGroup>
|
#include <KConfigGroup>
|
||||||
@ -31,18 +30,25 @@
|
|||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
struct AnimationState
|
struct AnimationState
|
||||||
{
|
{
|
||||||
QGraphicsItem* item;
|
QGraphicsItem* item;
|
||||||
Phase::Animation animation;
|
Phase::Animation animation;
|
||||||
|
Phase::CurveShape curve;
|
||||||
|
int interval;
|
||||||
|
int currentInterval;
|
||||||
int frames;
|
int frames;
|
||||||
|
int currentFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ElementAnimationState
|
struct ElementAnimationState
|
||||||
{
|
{
|
||||||
QGraphicsItem* item;
|
QGraphicsItem* item;
|
||||||
QTimeLine* timeline;
|
Phase::CurveShape curve;
|
||||||
Phase::ElementAnimation animation;
|
Phase::ElementAnimation animation;
|
||||||
|
int interval;
|
||||||
|
int currentInterval;
|
||||||
int frames;
|
int frames;
|
||||||
int currentFrame;
|
int currentFrame;
|
||||||
int id;
|
int id;
|
||||||
@ -55,26 +61,47 @@ class Phase::Private
|
|||||||
|
|
||||||
Private()
|
Private()
|
||||||
: animator(0),
|
: animator(0),
|
||||||
animId(0)
|
animId(0),
|
||||||
|
timerId(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~Private()
|
~Private()
|
||||||
{
|
{
|
||||||
// delete animator; Animator is a QObject
|
qDeleteAll(animatedItems);
|
||||||
// TimeLine's are parented to us, and we don't own the items
|
qDeleteAll(animatedElements);
|
||||||
|
// Animator is a QObject
|
||||||
|
// and we don't own the items
|
||||||
|
}
|
||||||
|
|
||||||
|
void performAnimation(qreal amount, const AnimationState* state)
|
||||||
|
{
|
||||||
|
switch (state->animation) {
|
||||||
|
case Phase::Appear:
|
||||||
|
animator->appear(amount, state->item);
|
||||||
|
break;
|
||||||
|
case Phase::Disappear:
|
||||||
|
animator->disappear(amount, state->item);
|
||||||
|
break;
|
||||||
|
case Phase::Activate:
|
||||||
|
animator->activate(amount, state->item);
|
||||||
|
break;
|
||||||
|
case Phase::FrameAppear:
|
||||||
|
animator->frameAppear(amount, state->item, QRegion()); //FIXME: what -is- the frame region?
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Animator* animator;
|
Animator* animator;
|
||||||
int animId;
|
int animId;
|
||||||
|
int timerId;
|
||||||
|
QTime time;
|
||||||
|
|
||||||
//TODO: eventually perhaps we should allow multiple animations simulataneously
|
//TODO: eventually perhaps we should allow multiple animations simulataneously
|
||||||
// which would imply changing this to a QMap<QGraphicsItem*, QList<QTimeLine*> >
|
// which would imply changing this to a QMap<QGraphicsItem*, QList<QTimeLine*> >
|
||||||
// and really making the code fun ;)
|
// and really making the code fun ;)
|
||||||
QMap<QGraphicsItem*, QTimeLine*> theAnimated;
|
QMap<QGraphicsItem*, AnimationState*> animatedItems;
|
||||||
QMap<QTimeLine*, AnimationState> animations;
|
QMap<Phase::AnimId, ElementAnimationState*> animatedElements;
|
||||||
QMap<Phase::AnimId, ElementAnimationState> theAnimatedElements;
|
|
||||||
QMap<QTimeLine*, Phase::AnimId> elementAnimations;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhaseSingleton
|
class PhaseSingleton
|
||||||
@ -111,133 +138,49 @@ void Phase::appletDestroyed(QObject* o)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QGraphicsItem*, QTimeLine*>::iterator it = d->theAnimated.find(item);
|
QMap<QGraphicsItem*, AnimationState*>::iterator it = d->animatedItems.find(item);
|
||||||
|
if (it != d->animatedItems.end()) {
|
||||||
if (it == d->theAnimated.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->animations.erase(d->animations.find(it.value()));
|
|
||||||
d->theAnimated.erase(it);
|
|
||||||
delete it.value();
|
delete it.value();
|
||||||
|
d->animatedItems.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::animate(QGraphicsItem* item, Animation animation)
|
void Phase::animateItem(QGraphicsItem* item, Animation animation)
|
||||||
{
|
{
|
||||||
QMap<QGraphicsItem*, QTimeLine*>::iterator it = d->theAnimated.find(item);
|
// get rid of any existing animations on this item.
|
||||||
|
//TODO: shoudl we allow multiple anims per item?
|
||||||
if (it != d->theAnimated.end()) {
|
QMap<QGraphicsItem*, AnimationState*>::iterator it = d->animatedItems.find(item);
|
||||||
|
if (it != d->animatedItems.end()) {
|
||||||
delete it.value();
|
delete it.value();
|
||||||
d->animations.erase(d->animations.find(it.value()));
|
d->animatedItems.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: allow the animator to define this?
|
|
||||||
QTimeLine::CurveShape curveShape = QTimeLine::EaseInOutCurve;
|
|
||||||
int frames = d->animator->framesPerSecond(animation);
|
int frames = d->animator->framesPerSecond(animation);
|
||||||
|
|
||||||
if (frames < 1) {
|
if (frames < 1) {
|
||||||
|
// evidently this animator doesn't have an implementation
|
||||||
|
// for this Animation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationState state;
|
AnimationState* state = new AnimationState;
|
||||||
state.item = item;
|
state->item = item;
|
||||||
state.animation = animation;
|
state->animation = animation;
|
||||||
|
state->curve = d->animator->curve(animation);
|
||||||
//TODO: variance in times based on the value of animation
|
//TODO: variance in times based on the value of animation
|
||||||
state.frames = frames / 3;
|
state->frames = frames / 3;
|
||||||
|
state->currentFrame = 0;
|
||||||
|
state->interval = 333 / state->frames;
|
||||||
|
state->interval = (state->interval / 40) * 40;
|
||||||
|
state->currentInterval = state->interval;
|
||||||
|
|
||||||
//TODO: variance in times based on the value of animation
|
d->animatedItems[item] = state;
|
||||||
QTimeLine* timeLine = new QTimeLine(333, this);
|
d->performAnimation(0, state);
|
||||||
timeLine->setFrameRange(0, state.frames);
|
|
||||||
timeLine->setCurveShape(curveShape);
|
|
||||||
|
|
||||||
d->animations[timeLine] = state;
|
if (!d->timerId) {
|
||||||
d->theAnimated[item] = timeLine;
|
d->timerId = startTimer(40);
|
||||||
connect(timeLine, SIGNAL(frameChanged(int)), this, SLOT(advanceFrame(int)));
|
d->time.restart();
|
||||||
connect(timeLine, SIGNAL(finished()), this, SLOT(animationComplete()));
|
|
||||||
timeLine->start();
|
|
||||||
advanceFrame(0, timeLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Phase::advanceFrame(int frame)
|
|
||||||
{
|
|
||||||
QTimeLine* timeLine = dynamic_cast<QTimeLine*>(sender());
|
|
||||||
|
|
||||||
if (!timeLine) {
|
|
||||||
//kDebug() << "Phase::advanceFrame found no timeLine!" << endl;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceFrame(frame, timeLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Phase::advanceFrame(int frame, QTimeLine* timeLine)
|
|
||||||
{
|
|
||||||
QMap<QTimeLine*, AnimationState>::iterator it = d->animations.find(timeLine);
|
|
||||||
|
|
||||||
if (it == d->animations.end()) {
|
|
||||||
//kDebug() << "Phase::advanceFrame found no entry in animations!" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimationState state = it.value();
|
|
||||||
qreal progress = state.frames;
|
|
||||||
progress = frame / progress;
|
|
||||||
|
|
||||||
switch (state.animation) {
|
|
||||||
case Appear:
|
|
||||||
d->animator->appear(progress, state.item);
|
|
||||||
break;
|
|
||||||
case Disappear:
|
|
||||||
d->animator->disappear(progress, state.item);
|
|
||||||
break;
|
|
||||||
case Activate:
|
|
||||||
d->animator->activate(progress, state.item);
|
|
||||||
break;
|
|
||||||
case FrameAppear:
|
|
||||||
d->animator->frameAppear(progress, state.item, QRegion()); //FIXME: what -is- the frame region?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Phase::animationComplete()
|
|
||||||
{
|
|
||||||
QTimeLine* tl = dynamic_cast<QTimeLine*>(sender());
|
|
||||||
|
|
||||||
if (!tl) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QTimeLine*, AnimationState>::iterator it = d->animations.find(tl);
|
|
||||||
|
|
||||||
if (it == d->animations.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimationState state = it.value();
|
|
||||||
|
|
||||||
switch (state.animation) {
|
|
||||||
case Appear:
|
|
||||||
d->animator->appear(1, state.item);
|
|
||||||
break;
|
|
||||||
case Disappear:
|
|
||||||
d->animator->disappear(1, state.item);
|
|
||||||
break;
|
|
||||||
case Activate:
|
|
||||||
d->animator->activate(1, state.item);
|
|
||||||
break;
|
|
||||||
case FrameAppear:
|
|
||||||
d->animator->frameAppear(1, state.item, QRegion()); //FIXME: what -is- the frame region?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QGraphicsItem*, QTimeLine*>::iterator animIt = d->theAnimated.find(state.item);
|
|
||||||
|
|
||||||
if (animIt != d->theAnimated.end()) {
|
|
||||||
d->theAnimated.erase(animIt);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->animations.erase(it);
|
|
||||||
tl->deleteLater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::render(QGraphicsItem* item, QImage& image, RenderOp op)
|
void Phase::render(QGraphicsItem* item, QImage& image, RenderOp op)
|
||||||
@ -250,159 +193,166 @@ void Phase::render(QGraphicsItem* item, QImage& image, RenderOp op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Phase::AnimId Phase::startElementAnimation(QGraphicsItem *item, ElementAnimation animation)
|
Phase::AnimId Phase::animateElement(QGraphicsItem *item, ElementAnimation animation)
|
||||||
{
|
{
|
||||||
//kDebug() << "startElementAnimation(AnimId " << animation << ")" << endl;
|
//kDebug() << "startElementAnimation(AnimId " << animation << ")" << endl;
|
||||||
//TODO: allow the animator to define this?
|
//TODO: allow the animator to define this?
|
||||||
QTimeLine::CurveShape curveShape = QTimeLine::EaseInOutCurve;
|
ElementAnimationState *state = new ElementAnimationState;
|
||||||
|
state->item = item;
|
||||||
ElementAnimationState state;
|
state->curve = d->animator->curve(animation);
|
||||||
state.item = item;
|
state->animation = animation;
|
||||||
state.animation = animation;
|
|
||||||
//TODO: variance in times based on the value of animation
|
//TODO: variance in times based on the value of animation
|
||||||
state.frames = d->animator->framesPerSecond(animation) / 3;
|
state->frames = d->animator->framesPerSecond(animation) / 5;
|
||||||
state.currentFrame = 0;
|
state->currentFrame = 0;
|
||||||
state.id = ++d->animId;
|
state->interval = 200 / state->frames;
|
||||||
|
state->interval = (state->interval / 40) * 40;
|
||||||
|
state->currentInterval = state->interval;
|
||||||
|
state->id = ++d->animId;
|
||||||
|
|
||||||
if (state.frames < 1) {
|
//kDebug() << "animateElement " << animation << ", interval: " << state->interval << ", frames: " << state->frames << endl;
|
||||||
state.frames = 1;
|
bool needTimer = true;
|
||||||
state.currentFrame = 1;
|
if (state->frames < 1) {
|
||||||
state.timeline = 0;
|
state->frames = 1;
|
||||||
} else {
|
state->currentFrame = 1;
|
||||||
//TODO: variance in times based on the value of animation
|
needTimer = false;
|
||||||
state.timeline = new QTimeLine(200, this);
|
|
||||||
state.timeline->setFrameRange(0, state.frames);
|
|
||||||
state.timeline->setCurveShape(curveShape);
|
|
||||||
connect(state.timeline, SIGNAL(frameChanged(int)), this, SLOT(advanceElementFrame(int)));
|
|
||||||
connect(state.timeline, SIGNAL(finished()), this, SLOT(elementAnimationComplete()));
|
|
||||||
state.timeline->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->elementAnimations[state.timeline] = state.id;
|
d->animatedElements[state->id] = state;
|
||||||
d->theAnimatedElements[state.id] = state;
|
state->item->update();
|
||||||
|
|
||||||
//TODO: this is a bit wasteful; perhaps we should pass in state itself?
|
//kDebug() << "startElementAnimation(AnimId " << animation << ") returning " << state->id << endl;
|
||||||
advanceElementFrame(0, state.id);
|
if (needTimer && !d->timerId) {
|
||||||
|
// start a 20fps timer;
|
||||||
|
//TODO: should be started at the maximum frame rate needed only?
|
||||||
|
d->timerId = startTimer(40);
|
||||||
|
d->time.restart();
|
||||||
|
}
|
||||||
|
|
||||||
//kDebug() << "startElementAnimation(AnimId " << animation << ") returning " << state.id << endl;
|
return state->id;
|
||||||
return state.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::stopElementAnimation(AnimId id)
|
void Phase::stopElementAnimation(AnimId id)
|
||||||
{
|
{
|
||||||
//kDebug() << "stopElementAnimation(AnimId " << id << ")" << endl;
|
QMap<AnimId, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
|
||||||
QMap<AnimId, ElementAnimationState>::iterator it = d->theAnimatedElements.find(id);
|
if (it != d->animatedElements.end()) {
|
||||||
|
delete it.value();
|
||||||
if (it == d->theAnimatedElements.end()) {
|
d->animatedElements.erase(it);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (it.value().timeline) {
|
|
||||||
d->elementAnimations.erase(d->elementAnimations.find(it.value().timeline));
|
|
||||||
//delete it.value().timeline;
|
|
||||||
it.value().timeline = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->theAnimatedElements.erase(it);
|
|
||||||
//kDebug() << "stopElementAnimation(AnimId " << id << ") done" << endl;
|
//kDebug() << "stopElementAnimation(AnimId " << id << ") done" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::setAnimationPixmap(AnimId id, const QPixmap &pixmap)
|
void Phase::setAnimationPixmap(AnimId id, const QPixmap &pixmap)
|
||||||
{
|
{
|
||||||
QMap<AnimId, ElementAnimationState>::iterator it = d->theAnimatedElements.find(id);
|
QMap<AnimId, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
|
||||||
|
|
||||||
if (it == d->theAnimatedElements.end()) {
|
if (it == d->animatedElements.end()) {
|
||||||
kDebug() << "Phase::setAnimationPixmap(" << id << ") found no entry for it!" << endl;
|
kDebug() << "Phase::setAnimationPixmap(" << id << ") found no entry for it!" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
it.value().pixmap = pixmap;
|
it.value()->pixmap = pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap Phase::animationResult(AnimId id)
|
QPixmap Phase::animationResult(AnimId id)
|
||||||
{
|
{
|
||||||
QMap<AnimId, ElementAnimationState>::const_iterator it = d->theAnimatedElements.find(id);
|
QMap<AnimId, ElementAnimationState*>::const_iterator it = d->animatedElements.find(id);
|
||||||
|
|
||||||
if (it == d->theAnimatedElements.constEnd()) {
|
if (it == d->animatedElements.constEnd()) {
|
||||||
kDebug() << "Phase::animationResult(" << id << ") found no entry for it!" << endl;
|
kDebug() << "Phase::animationResult(" << id << ") found no entry for it!" << endl;
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal progress = it.value().frames;
|
ElementAnimationState* state = it.value();
|
||||||
|
qreal progress = state->frames;
|
||||||
//kDebug() << "Phase::animationResult(" << id << " at " << progress << endl;
|
//kDebug() << "Phase::animationResult(" << id << " at " << progress << endl;
|
||||||
progress = it.value().currentFrame / progress;
|
progress = state->currentFrame / progress;
|
||||||
|
progress = qMin(1.0, qMax(0.0, progress));
|
||||||
//kDebug() << "Phase::animationResult(" << id << " at " << progress << endl;
|
//kDebug() << "Phase::animationResult(" << id << " at " << progress << endl;
|
||||||
|
|
||||||
switch (it.value().animation) {
|
switch (state->animation) {
|
||||||
case ElementAppear:
|
case ElementAppear:
|
||||||
return d->animator->elementAppear(progress, it.value().pixmap);
|
return d->animator->elementAppear(progress, state->pixmap);
|
||||||
break;
|
break;
|
||||||
case ElementDisappear:
|
case ElementDisappear:
|
||||||
return d->animator->elementDisappear(progress, it.value().pixmap);
|
return d->animator->elementDisappear(progress, state->pixmap);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return it.value().pixmap;
|
return state->pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::advanceElementFrame(int frame)
|
void Phase::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
QTimeLine* timeline = dynamic_cast<QTimeLine*>(sender());
|
Q_UNUSED(event)
|
||||||
|
bool animationsRemain = false;
|
||||||
|
int elapsed = 40;
|
||||||
|
if (d->time.elapsed() > elapsed) {
|
||||||
|
elapsed = d->time.elapsed();
|
||||||
|
}
|
||||||
|
d->time.restart();
|
||||||
|
// kDebug() << "timeEvent, elapsed time: " << elapsed << endl;
|
||||||
|
|
||||||
if (!timeline) {
|
foreach (AnimationState* state, d->animatedItems) {
|
||||||
kDebug() << "Phase::advanceElementFrame found no timeLine!" << endl;
|
if (state->currentInterval <= elapsed) {
|
||||||
return;
|
// we need to step forward!
|
||||||
|
qreal progress = state->frames;
|
||||||
|
progress = state->currentFrame / progress;
|
||||||
|
progress = qMin(1.0, qMax(0.0, progress));
|
||||||
|
d->performAnimation(progress, state);
|
||||||
|
state->currentFrame += qMax(1, elapsed / state->interval);
|
||||||
|
|
||||||
|
if (state->currentFrame < state->frames) {
|
||||||
|
state->currentInterval = state->interval;
|
||||||
|
//TODO: calculate a proper interval based on the curve
|
||||||
|
state->interval *= 1 - progress;
|
||||||
|
animationsRemain = true;
|
||||||
|
} else {
|
||||||
|
d->performAnimation(1, state);
|
||||||
|
d->animatedItems.erase(d->animatedItems.find(state->item));
|
||||||
|
delete state;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state->currentInterval -= elapsed;
|
||||||
|
animationsRemain = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QTimeLine*, Phase::AnimId>::const_iterator it = d->elementAnimations.find(timeline);
|
foreach (ElementAnimationState* state, d->animatedElements) {
|
||||||
|
if (state->currentFrame == state->frames) {
|
||||||
if (it == d->elementAnimations.constEnd()) {
|
// since we keep element animations around until they are
|
||||||
kDebug() << "Phase::advanceElementFrame found no entry in animations!" << endl;
|
// removed, we will end up with finished animations in the queue;
|
||||||
return;
|
// just skip them
|
||||||
|
//TODO: should we move them to a separate QMap?
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceElementFrame(frame, it.value());
|
if (state->currentInterval <= elapsed) {
|
||||||
}
|
// we need to step forward!
|
||||||
|
/* kDebug() << "stepping forwards element anim " << state->id << " from " << state->currentFrame
|
||||||
|
<< " by " << qMax(1, elapsed / state->interval) << " to "
|
||||||
|
<< state->currentFrame + qMax(1, elapsed / state->interval) << endl;*/
|
||||||
|
state->currentFrame += qMax(1, elapsed / state->interval);
|
||||||
|
state->item->update();
|
||||||
|
|
||||||
void Phase::advanceElementFrame(int frame, AnimId id)
|
if (state->currentFrame < state->frames) {
|
||||||
{
|
state->currentInterval = state->interval;
|
||||||
|
//TODO: calculate a proper interval based on the curve
|
||||||
QMap<Phase::AnimId, ElementAnimationState>::iterator it2 = d->theAnimatedElements.find(id);
|
qreal progress = state->frames;
|
||||||
|
progress = state->currentFrame / progress;
|
||||||
if (it2 == d->theAnimatedElements.end()) {
|
progress = qMin(1.0, qMax(0.0, progress));
|
||||||
kDebug() << "Phase::advanceElementFrame found no entry in animations!" << endl;
|
state->interval *= 1 - progress;
|
||||||
return;
|
animationsRemain = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state->currentInterval -= elapsed;
|
||||||
|
animationsRemain = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it2.value().currentFrame = frame;
|
if (!animationsRemain && d->timerId) {
|
||||||
it2.value().item->update();
|
killTimer(d->timerId);
|
||||||
}
|
d->timerId = 0;
|
||||||
|
|
||||||
void Phase::elementAnimationComplete()
|
|
||||||
{
|
|
||||||
QTimeLine* tl = dynamic_cast<QTimeLine*>(sender());
|
|
||||||
|
|
||||||
if (!tl) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QTimeLine*, Phase::AnimId>::iterator it = d->elementAnimations.find(tl);
|
|
||||||
|
|
||||||
if (it == d->elementAnimations.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//kDebug() << "elementAnimationComplete() " << it.value() << endl;
|
|
||||||
|
|
||||||
QMap<Phase::AnimId, ElementAnimationState>::iterator it2 = d->theAnimatedElements.find(it.value());
|
|
||||||
if (it2 != d->theAnimatedElements.end()) {
|
|
||||||
it2.value().timeline = 0;
|
|
||||||
it2.value().currentFrame = it2.value().frames;
|
|
||||||
it2.value().item->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
d->elementAnimations.erase(it);
|
|
||||||
tl->deleteLater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phase::init()
|
void Phase::init()
|
||||||
|
41
phase.h
41
phase.h
@ -48,8 +48,8 @@ public:
|
|||||||
|
|
||||||
enum ElementAnimation
|
enum ElementAnimation
|
||||||
{
|
{
|
||||||
ElementAppear = 0,
|
ElementAppear = 0 /*<< Animate the appearance of an element */,
|
||||||
ElementDisappear
|
ElementDisappear /*<< Animate the disappearance of an element */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RenderOp
|
enum RenderOp
|
||||||
@ -57,6 +57,14 @@ public:
|
|||||||
RenderBackground = 0 /*<< Render the background of an item */
|
RenderBackground = 0 /*<< Render the background of an item */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CurveShape
|
||||||
|
{
|
||||||
|
EaseInCurve = 0,
|
||||||
|
EaseOutCurve,
|
||||||
|
EaseInOutCurve,
|
||||||
|
LinearCurve
|
||||||
|
};
|
||||||
|
|
||||||
typedef int AnimId;
|
typedef int AnimId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +75,10 @@ public:
|
|||||||
explicit Phase(QObject * parent = 0);
|
explicit Phase(QObject * parent = 0);
|
||||||
~Phase();
|
~Phase();
|
||||||
|
|
||||||
AnimId startElementAnimation(QGraphicsItem *obj, ElementAnimation);
|
void animateItem(QGraphicsItem* item, Animation anim);
|
||||||
|
void render(QGraphicsItem* item, QImage& image, RenderOp op);
|
||||||
|
|
||||||
|
AnimId animateElement(QGraphicsItem *obj, ElementAnimation);
|
||||||
void stopElementAnimation(AnimId id);
|
void stopElementAnimation(AnimId id);
|
||||||
void setAnimationPixmap(AnimId id, const QPixmap &pixmap);
|
void setAnimationPixmap(AnimId id, const QPixmap &pixmap);
|
||||||
QPixmap animationResult(AnimId id);
|
QPixmap animationResult(AnimId id);
|
||||||
@ -75,32 +86,12 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void animationComplete(QGraphicsItem *item, Animation anim);
|
void animationComplete(QGraphicsItem *item, Animation anim);
|
||||||
|
|
||||||
public Q_SLOTS:
|
protected:
|
||||||
void animate(QGraphicsItem* item, Animation anim);
|
void timerEvent(QTimerEvent *event);
|
||||||
void render(QGraphicsItem* item, QImage& image, RenderOp op);
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
void appletDestroyed(QObject*);
|
void appletDestroyed(QObject*);
|
||||||
|
|
||||||
void advanceFrame(int frame, QTimeLine* timeLine);
|
|
||||||
void advanceElementFrame(int frame);
|
|
||||||
void advanceElementFrame(int frame, AnimId id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NEVER call this method directly, as it relies on sender()
|
|
||||||
*/
|
|
||||||
void advanceFrame(int frame);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NEVER call this method directly, as it relies on sender()
|
|
||||||
*/
|
|
||||||
void animationComplete();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NEVER call this method directly, as it relies on sender()
|
|
||||||
*/
|
|
||||||
void elementAnimationComplete();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user