consistent signals at the end of all animations and ties QObject lifespan (when available) to all the animations including elementAnimation. Also prevents multiple connections to the destroyed slots (harmless, just cycle wasting) and mutes some remaining debug statements.

RB:131

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=775010
This commit is contained in:
Aaron J. Seigo 2008-02-14 17:09:00 +00:00
parent 87018e9b9e
commit 78b83142ad
2 changed files with 44 additions and 14 deletions

View File

@ -50,6 +50,7 @@ struct AnimationState
struct ElementAnimationState
{
QGraphicsItem *item;
QObject *qobj;
Phase::CurveShape curve;
Phase::ElementAnimation animation;
int interval;
@ -165,7 +166,7 @@ class Phase::Private
// and really making the code fun ;)
QMap<QGraphicsItem*, AnimationState*> animatedItems;
QMap<QGraphicsItem*, MovementState*> movingItems;
QMap<Phase::AnimId, ElementAnimationState*> animatedElements;
QMap<AnimId, ElementAnimationState*> animatedElements;
QMap<AnimId, CustomAnimationState*> customAnims;
};
@ -195,7 +196,7 @@ Phase::~Phase()
delete d;
}
void Phase::objectDestroyed(QObject* o)
void Phase::animatedItemDestroyed(QObject* o)
{
//kDebug() << "testing for" << (void*)o;
QMutableMapIterator<QGraphicsItem*, AnimationState*> it(d->animatedItems);
@ -208,13 +209,28 @@ void Phase::objectDestroyed(QObject* o)
it.remove();
}
}
}
QMutableMapIterator<QGraphicsItem*, MovementState*> it2(d->movingItems);
while (it2.hasNext()) {
void Phase::movingItemDestroyed(QObject* o)
{
QMutableMapIterator<QGraphicsItem*, MovementState*> it(d->movingItems);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
delete it2.value();
it2.remove();
delete it.value();
it.remove();
}
}
}
void Phase::animatedElementDestroyed(QObject* o)
{
QMutableMapIterator<AnimId, ElementAnimationState*> it(d->animatedElements);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
delete it.value();
it.remove();
}
}
}
@ -263,10 +279,9 @@ void Phase::animateItem(QGraphicsItem* item, Animation animation)
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
kDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!! got us an object!";
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
} else {
kDebug() << "???????????????????????? no oject *wheep*";
//kDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!! got us an object!";
disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(animatedItemDestroyed(QObject*)));
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(animatedItemDestroyed(QObject*)));
}
d->animatedItems[item] = state;
@ -309,7 +324,8 @@ void Phase::moveItem(QGraphicsItem* item, Movement movement, const QPoint &desti
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
}
d->movingItems[item] = state;
@ -342,6 +358,8 @@ Phase::AnimId Phase::customAnimation(int frames, int duration, Phase::CurveShape
d->customAnims[state->id] = state;
disconnect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
connect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
@ -380,6 +398,12 @@ Phase::AnimId Phase::animateElement(QGraphicsItem *item, ElementAnimation animat
state->interval = (state->interval / MIN_TICK_RATE) * MIN_TICK_RATE;
state->currentInterval = state->interval;
state->id = ++d->animId;
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(animatedElementDestroyed(QObject*)));
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(animatedElementDestroyed(QObject*)));
}
//kDebug() << "animateElement " << animation << ", interval: " << state->interval << ", frames: " << state->frames;
bool needTimer = true;
@ -540,14 +564,15 @@ void Phase::timerEvent(QTimerEvent *event)
} else {
state->item->update();
}
if (state->currentFrame < state->frames) {
state->currentInterval = state->interval;
//TODO: calculate a proper interval based on the curve
state->interval *= 1 - d->calculateProgress(state->frames, state->currentFrame);
animationsRemain = true;
} else {
d->animatedElements.remove( state->id );
d->animatedElements.remove(state->id);
emit elementAnimationComplete(state->id);
delete state;
}
} else {
@ -575,6 +600,7 @@ void Phase::timerEvent(QTimerEvent *event)
} else {
QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1));
d->customAnims.erase(d->customAnims.find(state->id));
emit customAnimationComplete(state->id);
delete [] state->slot;
delete state;
}

View File

@ -119,12 +119,16 @@ public:
Q_SIGNALS:
void animationComplete(QGraphicsItem *item, Plasma::Phase::Animation anim);
void movementComplete(QGraphicsItem *item);
void elementAnimationComplete(AnimId id);
void customAnimationComplete(AnimId id);
protected:
void timerEvent(QTimerEvent *event);
protected Q_SLOTS:
void objectDestroyed(QObject*);
void animatedItemDestroyed(QObject*);
void movingItemDestroyed(QObject*);
void animatedElementDestroyed(QObject*);
void customAnimReceiverDestroyed(QObject*);
private: