First step to improve new animations memory model.
Now the QAbstractAnimations will be cached when running an animation (instead of creating and destroying them everytime the animation runs). The next step is to cache *also* the configuration parameters (as aseigo suggested, by having an event filter to detect changes in the animated widgets and reseting the animation parameters as needed). svn path=/trunk/KDE/kdelibs/; revision=1039531
This commit is contained in:
parent
042ed56b39
commit
1049afdab6
@ -48,6 +48,10 @@ AbstractAnimation::~AbstractAnimation()
|
||||
void AbstractAnimation::setWidgetToAnimate(QGraphicsWidget* receiver)
|
||||
{
|
||||
d->animObject = receiver;
|
||||
/* Changed the object, delete the animation */
|
||||
delete d->animation.data();
|
||||
d->animation.clear();
|
||||
|
||||
}
|
||||
|
||||
QGraphicsWidget* AbstractAnimation::widgetToAnimate()
|
||||
@ -105,13 +109,23 @@ bool AbstractAnimation::isVisible() const
|
||||
return d->animVisible;
|
||||
}
|
||||
|
||||
QAbstractAnimation* AbstractAnimation::animation()
|
||||
{
|
||||
return d->animation.data();
|
||||
}
|
||||
|
||||
void AbstractAnimation::setAnimation(QAbstractAnimation *obj)
|
||||
{
|
||||
d->animation = obj;
|
||||
}
|
||||
|
||||
void AbstractAnimation::start()
|
||||
{
|
||||
QAbstractAnimation* anim = toQAbstractAnimation(parent());
|
||||
if (anim) {
|
||||
anim->setDirection(d->forwards ? QAbstractAnimation::Forward :
|
||||
QAbstractAnimation::Backward);
|
||||
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
anim->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ class PLASMA_EXPORT AbstractAnimation : public QObject
|
||||
Q_PROPERTY(bool isVisible READ isVisible WRITE setVisible)
|
||||
Q_PROPERTY(QGraphicsWidget *widgetToAnimate READ widgetToAnimate WRITE setWidgetToAnimate)
|
||||
Q_PROPERTY(bool forwards READ forwards WRITE setForwards)
|
||||
Q_PROPERTY(QAbstractAnimation* animation READ animation WRITE setAnimation)
|
||||
|
||||
public:
|
||||
|
||||
@ -139,6 +140,18 @@ public:
|
||||
*/
|
||||
bool isVisible() const;
|
||||
|
||||
/**
|
||||
* Access the QAbstractAnimation of this plasma::Animation object.
|
||||
*/
|
||||
QAbstractAnimation *animation();
|
||||
|
||||
/**
|
||||
* Access the QAbstractAnimation of this plasma::Animation object.
|
||||
* @arg obj An animation pointer (it will be cleared by the object)
|
||||
*/
|
||||
void setAnimation(QAbstractAnimation *obj);
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
|
@ -63,13 +63,15 @@ QAbstractAnimation* ExpandAnimation::render(QObject* parent)
|
||||
break;
|
||||
}
|
||||
|
||||
//create animation
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "geometry", parent);
|
||||
//Recreate only if needed
|
||||
QPropertyAnimation *anim = dynamic_cast<QPropertyAnimation* >(animation());
|
||||
if (!anim) {
|
||||
anim = new QPropertyAnimation(m_object, "geometry", parent);
|
||||
setAnimation(anim);
|
||||
}
|
||||
anim->setEndValue(geometry);
|
||||
anim->setDuration(duration());
|
||||
|
||||
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,12 @@ void FadeAnimation::setWidgetToAnimate(QGraphicsWidget *widget)
|
||||
QAbstractAnimation* FadeAnimation::render(QObject* parent)
|
||||
{
|
||||
//create animation
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(m_opacityEffect.data(), "opacity", parent);
|
||||
QPropertyAnimation* anim = dynamic_cast<QPropertyAnimation* >(animation());
|
||||
if (!anim) {
|
||||
anim = new QPropertyAnimation(m_opacityEffect.data(), "opacity", parent);
|
||||
setAnimation(anim);
|
||||
}
|
||||
|
||||
anim->setStartValue(m_startOpacity);
|
||||
anim->setEndValue(m_targetOpacity);
|
||||
anim->setDuration(duration());
|
||||
|
@ -59,8 +59,13 @@ QAbstractAnimation* GrowAnimation::render(QObject* parent){
|
||||
qreal newX = geometry.x() - w * locfactor;
|
||||
qreal newY = geometry.y() - h * locfactor;
|
||||
|
||||
//create animation
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "geometry", parent);
|
||||
//Recreate only if needed
|
||||
QPropertyAnimation *anim = dynamic_cast<QPropertyAnimation* >(animation());
|
||||
if (!anim) {
|
||||
anim = new QPropertyAnimation(m_object, "geometry", parent);
|
||||
setAnimation(anim);
|
||||
}
|
||||
|
||||
anim->setEndValue(QRectF(
|
||||
newX, newY,
|
||||
newWidth, newHeight));
|
||||
|
@ -31,8 +31,14 @@ PauseAnimation::PauseAnimation(QObject *parent)
|
||||
|
||||
QAbstractAnimation* PauseAnimation::render(QObject* parent)
|
||||
{
|
||||
//create animation
|
||||
return new QPauseAnimation(duration(), parent);
|
||||
//Recreate only if needed
|
||||
QPauseAnimation *anim = dynamic_cast<QPauseAnimation* >(animation());
|
||||
if (!anim) {
|
||||
anim = new QPauseAnimation(duration(), parent);
|
||||
setAnimation(anim);
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
} //namespace Plasma
|
||||
|
@ -50,6 +50,7 @@ public :
|
||||
|
||||
QAbstractAnimation *animation;
|
||||
QGraphicsWidget *under;
|
||||
/* FIXME: clean up this guy */
|
||||
QRectF *pulseGeometry;
|
||||
qreal zvalue, mscale, mopacity;
|
||||
QPropertyAnimation *opacityAnimation;
|
||||
@ -88,25 +89,6 @@ void PulseAnimation::setCopy(QGraphicsWidget *copy)
|
||||
d->mscale = d->under->scale();
|
||||
}
|
||||
|
||||
void PulseAnimation::updateGeometry(QRectF updated, qreal zCoordinate, qreal scale)
|
||||
{
|
||||
d->zvalue = zCoordinate;
|
||||
--d->zvalue;
|
||||
d->under->setGeometry(updated);
|
||||
d->under->setPos(0, 0);
|
||||
d->under->setOpacity(0);
|
||||
d->under->setZValue(d->zvalue);
|
||||
|
||||
/* TODO: move this to a function */
|
||||
QRectF initial(d->under->geometry());
|
||||
qreal W = initial.width() * scale * 0.33;
|
||||
qreal H = initial.height() * scale * 0.33;
|
||||
QRectF end(initial.x() - W, initial.y() - H, initial.width() * scale,
|
||||
initial.height() * scale);
|
||||
d->geometryAnimation->setEndValue(end);
|
||||
}
|
||||
|
||||
|
||||
void PulseAnimation::resetPulser()
|
||||
{
|
||||
d->under->setGeometry(*d->pulseGeometry);
|
||||
@ -118,6 +100,7 @@ void PulseAnimation::resetPulser()
|
||||
|
||||
void PulseAnimation::createAnimation(qreal duration, qreal scale)
|
||||
{
|
||||
bool dirty = false;
|
||||
QGraphicsWidget *target = widgetToAnimate();
|
||||
/* Fallback to parent widget if we don't have one 'shadow' widget */
|
||||
if (!d->under) {
|
||||
@ -128,34 +111,53 @@ void PulseAnimation::createAnimation(qreal duration, qreal scale)
|
||||
setCopy(d->under);
|
||||
}
|
||||
|
||||
d->pulseGeometry = new QRectF(d->under->geometry());
|
||||
QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
|
||||
d->opacityAnimation = new QPropertyAnimation(d->under, "opacity");
|
||||
d->opacityAnimation->setDuration(duration);
|
||||
d->opacityAnimation->setEndValue(0);
|
||||
group->addAnimation(d->opacityAnimation);
|
||||
|
||||
/* TODO: move this to a function */
|
||||
d->geometryAnimation = new QPropertyAnimation(d->under, "geometry");
|
||||
d->geometryAnimation->setDuration(duration);
|
||||
QRectF initial(d->under->geometry());
|
||||
qreal W = initial.width() * scale * 0.33;
|
||||
qreal H = initial.height() * scale * 0.33;
|
||||
QRectF end(initial.x() - W, initial.y() - H, initial.width() * scale,
|
||||
initial.height() * scale);
|
||||
d->geometryAnimation->setEndValue(end);
|
||||
group->addAnimation(d->geometryAnimation);
|
||||
QParallelAnimationGroup *anim = dynamic_cast<QParallelAnimationGroup* >(animation());
|
||||
if (!anim) {
|
||||
d->pulseGeometry = new QRectF(d->under->geometry());
|
||||
QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
|
||||
d->opacityAnimation = new QPropertyAnimation(d->under, "opacity");
|
||||
d->opacityAnimation->setDuration(duration);
|
||||
d->opacityAnimation->setEndValue(0);
|
||||
group->addAnimation(d->opacityAnimation);
|
||||
|
||||
d->scaleAnimation = new QPropertyAnimation(d->under, "scale");
|
||||
d->scaleAnimation->setDuration(duration);
|
||||
d->scaleAnimation->setEndValue(scale);
|
||||
group->addAnimation(d->scaleAnimation);
|
||||
/* TODO: move this to a function */
|
||||
d->geometryAnimation = new QPropertyAnimation(d->under, "geometry");
|
||||
d->geometryAnimation->setDuration(duration);
|
||||
QRectF initial(d->under->geometry());
|
||||
qreal W = initial.width() * scale * 0.33;
|
||||
qreal H = initial.height() * scale * 0.33;
|
||||
QRectF end(initial.x() - W, initial.y() - H, initial.width() * scale,
|
||||
initial.height() * scale);
|
||||
d->geometryAnimation->setEndValue(end);
|
||||
group->addAnimation(d->geometryAnimation);
|
||||
|
||||
d->animation = group;
|
||||
d->scaleAnimation = new QPropertyAnimation(d->under, "scale");
|
||||
d->scaleAnimation->setDuration(duration);
|
||||
d->scaleAnimation->setEndValue(scale);
|
||||
/* The group takes ownership of all animations */
|
||||
group->addAnimation(d->scaleAnimation);
|
||||
d->animation = group;
|
||||
setAnimation(d->animation);
|
||||
dirty = true;
|
||||
|
||||
//This makes sure that if there is *not* a shadow widget, the
|
||||
//parent widget will still remain visible
|
||||
connect(d->animation, SIGNAL(finished()), this, SLOT(resetPulser()));
|
||||
} else {
|
||||
*(d->pulseGeometry) = d->under->geometry();
|
||||
d->opacityAnimation->setEndValue(0);
|
||||
QRectF initial(d->under->geometry());
|
||||
qreal W = initial.width() * scale * 0.33;
|
||||
qreal H = initial.height() * scale * 0.33;
|
||||
QRectF end(initial.x() - W, initial.y() - H, initial.width() * scale,
|
||||
initial.height() * scale);
|
||||
d->geometryAnimation->setEndValue(end);
|
||||
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
//This makes sure that if there is *not* a shadow widget, the
|
||||
//parent widget will still remain visible
|
||||
connect(d->animation, SIGNAL(finished()), this, SLOT(resetPulser()));
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractAnimation* PulseAnimation::render(QObject* parent)
|
||||
|
@ -143,7 +143,12 @@ QPropertyAnimation *RotationAnimation::render(QObject *parent)
|
||||
transformation.append(d->rotation);
|
||||
m_object->setTransformations(transformation);
|
||||
|
||||
QPropertyAnimation *rotationAnimation= new QPropertyAnimation(d->rotation, "angle", m_object);
|
||||
QPropertyAnimation *rotationAnimation = dynamic_cast<QPropertyAnimation* >(animation());
|
||||
if (!rotationAnimation) {
|
||||
rotationAnimation = new QPropertyAnimation(d->rotation, "angle", m_object);
|
||||
setAnimation(rotationAnimation);
|
||||
}
|
||||
|
||||
rotationAnimation->setStartValue(0);
|
||||
rotationAnimation->setEndValue(angle());
|
||||
rotationAnimation->setDuration(duration());
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <QGraphicsRotation>
|
||||
#include <QSequentialAnimationGroup>
|
||||
#include <kdebug.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
@ -51,6 +52,9 @@ RotationStackedAnimation::RotationStackedAnimation(QObject *parent)
|
||||
|
||||
RotationStackedAnimation::~RotationStackedAnimation()
|
||||
{
|
||||
/* XXX: do we need to delete the layout if the 'parent' layout is
|
||||
* deleted too ?
|
||||
*/
|
||||
delete d->sLayout;
|
||||
delete d;
|
||||
}
|
||||
@ -88,13 +92,26 @@ QGraphicsLayoutItem *RotationStackedAnimation::layout()
|
||||
QAbstractAnimation *RotationStackedAnimation::render(QObject *parent)
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
||||
bool dirty = false;
|
||||
QPair<QGraphicsWidget *,QGraphicsWidget *> widgets = qMakePair(widgetToAnimate(), d->backWidget);
|
||||
QPropertyAnimation *frontAnim, *backAnim;
|
||||
QSequentialAnimationGroup *groupAnim = dynamic_cast<QSequentialAnimationGroup* >(animation());
|
||||
if (!groupAnim) {
|
||||
|
||||
QSequentialAnimationGroup *groupAnim = new QSequentialAnimationGroup(parent);
|
||||
|
||||
QPropertyAnimation *frontAnim = new QPropertyAnimation(d->frontRotation, "angle", groupAnim);
|
||||
QPropertyAnimation *backAnim = new QPropertyAnimation(d->backRotation, "angle", groupAnim);
|
||||
groupAnim = new QSequentialAnimationGroup(parent);
|
||||
frontAnim = new QPropertyAnimation(d->frontRotation, "angle", groupAnim);
|
||||
backAnim = new QPropertyAnimation(d->backRotation, "angle", groupAnim);
|
||||
setAnimation(groupAnim);
|
||||
dirty = true;
|
||||
} else {
|
||||
if (groupAnim->animationCount() == 2) {
|
||||
frontAnim = dynamic_cast<QPropertyAnimation* >(groupAnim->animationAt(0));
|
||||
backAnim = dynamic_cast<QPropertyAnimation* >(groupAnim->animationAt(1));
|
||||
} else {
|
||||
kDebug() << "_ Where are my little animations? Duh!";
|
||||
return groupAnim;
|
||||
}
|
||||
}
|
||||
|
||||
const qreal widgetFrontWidth = widgets.first->size().width();
|
||||
const qreal widgetFrontHeight = widgets.first->size().height();
|
||||
@ -137,10 +154,11 @@ QAbstractAnimation *RotationStackedAnimation::render(QObject *parent)
|
||||
frontAnim->setDuration(duration()/2);
|
||||
backAnim->setDuration(duration()/2);
|
||||
|
||||
connect(frontAnim, SIGNAL(finished()), this, SLOT(rotateBackWidget()));
|
||||
|
||||
groupAnim->addAnimation(frontAnim);
|
||||
groupAnim->addAnimation(backAnim);
|
||||
if (dirty) {
|
||||
connect(frontAnim, SIGNAL(finished()), this, SLOT(rotateBackWidget()));
|
||||
groupAnim->addAnimation(frontAnim);
|
||||
groupAnim->addAnimation(backAnim);
|
||||
}
|
||||
|
||||
return groupAnim;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ SlideAnimation::SlideAnimation(AnimationDirection direction, qreal distance)
|
||||
|
||||
QAbstractAnimation* SlideAnimation::render(QObject* parent)
|
||||
{
|
||||
bool dirty = false;
|
||||
QGraphicsWidget *m_object = widgetToAnimate();
|
||||
qreal x = m_object->x();
|
||||
qreal y = m_object->y();
|
||||
@ -67,18 +68,25 @@ QAbstractAnimation* SlideAnimation::render(QObject* parent)
|
||||
break;
|
||||
}
|
||||
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "pos", parent);
|
||||
//Recreate only if needed
|
||||
QPropertyAnimation* anim = dynamic_cast<QPropertyAnimation* >(animation());
|
||||
if (!anim) {
|
||||
anim = new QPropertyAnimation(m_object, "pos", parent);
|
||||
setAnimation(anim);
|
||||
dirty = true;
|
||||
}
|
||||
anim->setEndValue(QPointF(newX, newY));
|
||||
anim->setDuration(duration());
|
||||
|
||||
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
|
||||
|
||||
if (isVisible()) {
|
||||
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(show()));
|
||||
} else {
|
||||
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(hide()));
|
||||
if (dirty) {
|
||||
if (isVisible()) {
|
||||
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(show()));
|
||||
} else {
|
||||
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(hide()));
|
||||
}
|
||||
}
|
||||
|
||||
return anim;
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <QEasingCurve>
|
||||
#include <QWeakPointer>
|
||||
class QAbstractAnimation;
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
@ -37,6 +38,11 @@ public:
|
||||
*/
|
||||
QWeakPointer<QGraphicsWidget> animObject;
|
||||
|
||||
/**
|
||||
* All animations will have *at least* one animation property
|
||||
*/
|
||||
QWeakPointer<QAbstractAnimation> animation;
|
||||
|
||||
/**
|
||||
* Animation direction: where the animation will move.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user