plasma-framework/animations/rotationstacked.cpp
Adenilson Cavalcanti Da Silva 1049afdab6 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
2009-10-23 18:39:57 +00:00

172 lines
5.5 KiB
C++

/***********************************************************************/
/* rotationstacked.h */
/* */
/* Copyright(C) 2009 Igor Trindade Oliveira <igor.oliveira@indt.org.br>*/
/* */
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation; either */
/* version 2.1 of the License, or (at your option) any later version. */
/* */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
/* Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public */
/* License along with this library; if not, write to the Free Software */
/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA */
/* 02110-1301 USA */
/***********************************************************************/
#include "rotationstacked.h"
#include "stackedlayout.h"
#include <QGraphicsRotation>
#include <QSequentialAnimationGroup>
#include <kdebug.h>
namespace Plasma
{
class RotationStackedAnimationPrivate {
public:
QGraphicsRotation *backRotation;
QGraphicsRotation *frontRotation;
AbstractAnimation::Reference reference;
QGraphicsWidget *backWidget;
StackedLayout *sLayout;
};
RotationStackedAnimation::RotationStackedAnimation(QObject *parent)
: d(new RotationStackedAnimationPrivate)
{
d->backRotation = new QGraphicsRotation(this);
d->frontRotation = new QGraphicsRotation(this);
d->sLayout = new StackedLayout;
}
RotationStackedAnimation::~RotationStackedAnimation()
{
/* XXX: do we need to delete the layout if the 'parent' layout is
* deleted too ?
*/
delete d->sLayout;
delete d;
}
void RotationStackedAnimation::setReference(AbstractAnimation::Reference reference)
{
d->reference = reference;
}
AbstractAnimation::Reference RotationStackedAnimation::reference()
{
return d->reference;
}
QGraphicsWidget *RotationStackedAnimation::backWidget()
{
return d->backWidget;
}
void RotationStackedAnimation::setBackWidget(QGraphicsWidget *backWidget)
{
d->backWidget = backWidget;
if(widgetToAnimate()) {
d->sLayout->addWidget(widgetToAnimate());
d->sLayout->addWidget(backWidget);
}
}
QGraphicsLayoutItem *RotationStackedAnimation::layout()
{
return d->sLayout;
}
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) {
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();
const qreal widgetBackWidth = widgets.second->size().width();
const qreal widgetBackHeight = widgets.second->size().height();
QPair<QVector3D, QVector3D> vector;
if(reference() == Center) {
vector.first = QVector3D(widgetFrontWidth/2, widgetFrontHeight/2, 0);
vector.second = QVector3D(widgetBackWidth/2, widgetBackHeight/2, 0);
if(direction() == MoveLeft || direction() == MoveRight) {
d->frontRotation->setAxis(Qt::YAxis);
d->backRotation->setAxis(Qt::YAxis);
if(direction() == MoveLeft) {
} else {
d->backRotation->setAngle(265);
backAnim->setEndValue(360);
frontAnim->setEndValue(90);
}
}
}
d->frontRotation->setOrigin(vector.first);
d->backRotation->setOrigin(vector.second);
QList<QGraphicsTransform *> backTransformation;
QList<QGraphicsTransform *> frontTransformation;
frontTransformation.append(d->frontRotation);
backTransformation.append(d->backRotation);
widgets.first->setTransformations(frontTransformation);
widgets.second->setTransformations(backTransformation);
frontAnim->setDuration(duration()/2);
backAnim->setDuration(duration()/2);
if (dirty) {
connect(frontAnim, SIGNAL(finished()), this, SLOT(rotateBackWidget()));
groupAnim->addAnimation(frontAnim);
groupAnim->addAnimation(backAnim);
}
return groupAnim;
}
void RotationStackedAnimation::rotateBackWidget()
{
d->sLayout->setCurrentWidgetIndex(1);
}
}