Merging Mehmet Ali Akmanalp new plasma::Animator code. It uses the new and shiny

Qt 4.6 animation API (a.k.a. kinetic) to implement effects.

Current implemented animations: fade, slide, expand, grow (next will be
pulse and rotation).

Further discussion is here:
http://reviewboard.kde.org/r/1512/


svn path=/trunk/KDE/kdelibs/; revision=1035749
This commit is contained in:
Adenilson Cavalcanti Da Silva 2009-10-15 19:36:38 +00:00
parent 277eaeebe0
commit a4b408277c
22 changed files with 2291 additions and 852 deletions

View File

@ -43,7 +43,14 @@ set(plasma_LIB_SRCS
${plasmagik_SRCS}
abstractrunner.cpp
animationdriver.cpp
animator.cpp
animations/abstractanimation.cpp
animations/animation.cpp
animations/animationgroup.cpp
animations/expand.cpp
animations/fade.cpp
animations/grow.cpp
animations/slide.cpp
animations/pulser.cpp
applet.cpp
configloader.cpp
containment.cpp
@ -55,6 +62,7 @@ set(plasma_LIB_SRCS
dataengine.cpp
dataenginemanager.cpp
delegate.cpp
deprecated/animator.cpp
dialog.cpp
extenders/extender.cpp
extenders/extendergroup.cpp
@ -236,6 +244,9 @@ install(FILES ${plasmagik_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/ CO
set(plasma_LIB_INCLUDES
abstractrunner.h
animationdriver.h
animations/abstractanimation.h
animations/animation.h
animations/animationgroup.h
animator.h
applet.h
configloader.h
@ -332,6 +343,18 @@ if(PHONON_FOUND)
DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/widgets COMPONENT Devel)
endif(PHONON_FOUND)
install(FILES
animations/abstractanimation.h
animations/animation.h
animations/animationgroup.h
animations/expand.h
animations/fade.h
animations/grow.h
animations/slide.h
animations/pulser.h
DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/animations COMPONENT Devel)
install(FILES
data/servicetypes/plasma-animator.desktop
data/servicetypes/plasma-applet.desktop

View File

@ -0,0 +1,44 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "abstractanimation.h"
namespace Plasma
{
AbstractAnimation::AbstractAnimation(){
}
AbstractAnimation::~AbstractAnimation(){
}
void AbstractAnimation::setWidget(QGraphicsWidget* receiver){
m_object = receiver;
}
QGraphicsWidget* AbstractAnimation::getAnimatedObject()
{
return m_object;
}
} //namespace Plasma
#include <../abstractanimation.moc>

View File

@ -0,0 +1,85 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the classes for AbstractAnimation, which is the
* abstract base class for all animations.
*/
#ifndef PLASMA_ABSTRACTANIMATION_H
#define PLASMA_ABSTRACTANIMATION_H
#include <QAbstractAnimation>
#include <QGraphicsWidget>
#include <QObject>
#include <plasma/plasma.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* Abstract base class for AnimationGroup and Animation.
*/
class PLASMA_EXPORT AbstractAnimation : public QObject
{
Q_OBJECT
public:
AbstractAnimation();
virtual ~AbstractAnimation() = 0;
/**
* Set the widget on which the animation is to be performed.
* @arg receiver The QGraphicsWidget to be animated.
*/
virtual void setWidget(QGraphicsWidget* receiver);
/**
* Take an AbstractAnimation and turn it into a
* QAbstractAnimation.
*/
virtual QAbstractAnimation* getQtAnimation(QObject* parent) = 0;
public slots:
/**
* Start the animation.
*/
virtual void start() = 0;
protected:
QGraphicsWidget *getAnimatedObject();
private:
/**
* Object the animation(s) should act upon.
*/
QGraphicsWidget* m_object;
};
} //namespace Plasma
#endif

81
animations/animation.cpp Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "animation.h"
#include <QMapIterator>
#include <QObject>
#include <QParallelAnimationGroup>
#include <QSequentialAnimationGroup>
#include <kdebug.h>
#include <kglobalsettings.h>
namespace Plasma
{
Animation::Animation(QObject* parent)
: m_parent(parent),
m_duration(250)
{
}
Animation::~Animation(){}
void Animation::setDuration(int duration){
m_duration = duration;
}
int Animation::duration() const {
return m_duration;
}
void Animation::start(){
QAbstractAnimation* anim = getQtAnimation(m_parent);
if (anim){
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
}
QAbstractAnimation* Animation::getQtAnimation(QObject* parent){
//check if .setObject() was done
if (!getAnimatedObject()){
kDebug() << "Object not set.";
return NULL;
}
//check which parent to use
if (parent){
return render(parent);
} else {
return render(m_parent);
}
}
int Animation::getDuration() {
return m_duration;
}
} //namespace Plasma
#include <../animation.moc>

103
animations/animation.h Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the abstract base class for all singular
* animations.
*/
#ifndef PLASMA_ANIMATION_H
#define PLASMA_ANIMATION_H
#include <QGraphicsWidget>
#include <QObject>
#include <QPropertyAnimation>
#include <plasma/animations/abstractanimation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* Abstract representation of a single animation.
*/
class PLASMA_EXPORT Animation : public AbstractAnimation
{
Q_OBJECT
public:
Animation(QObject* parent = 0);
virtual ~Animation() = 0;
/**
* Get the animation duration.
* @return duration in ms.
*/
virtual int duration() const;
/**
* Start the animation.
*/
virtual void start();
/**
* Take the animation object and turn it into a QPropertyAnimation. Returns
* NULL on error. This function just does some boilerplate checking and then
* calls render().
*/
QAbstractAnimation* getQtAnimation(QObject* parent = 0);
protected:
/**
* Change the animation duration. Default is 1000ms.
* @arg duration The new duration of the animation.
*/
virtual void setDuration(int duration = 250);
/**
* Each individual class must override this function to place their main
* functionality. This function must take the values from the constructor,
* do the appropriate calculations, and return a corresponding
* QPropertyAnimation initialized with the given parent.
*/
virtual QAbstractAnimation* render(QObject* parent = 0) = 0;
int getDuration();
private:
/**
* Parent owner object to use in generated animations.
*/
QObject* m_parent;
/**
* Duration of the animation. Default is 1000ms.
*/
int m_duration;
};
} //namespace Plasma
#endif

View File

@ -0,0 +1,98 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "animationgroup.h"
#include <QMapIterator>
#include <QParallelAnimationGroup>
#include <QSequentialAnimationGroup>
namespace Plasma
{
AnimationGroup::AnimationGroup(QObject* parent)
: m_parent(parent),
m_parallel(false)
{
}
AnimationGroup::~AnimationGroup(){
}
void AnimationGroup::setParallel(bool parallelness){
m_parallel = parallelness;
}
bool AnimationGroup::isParallel() const{
return m_parallel;
}
int AnimationGroup::add(AbstractAnimation* elem){
anims.insert(anims.count(), elem);
return anims.count();
}
AbstractAnimation* AnimationGroup::at(int id) const{
return anims[id];
}
void AnimationGroup::remove(int id){
anims.removeAt(id);
}
void AnimationGroup::start(){
QAbstractAnimation* anim = getQtAnimation(m_parent);
if (anim){
/* FIXME: why to create and delete all the animations
* every single time it runs?
*/
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
}
QAnimationGroup* AnimationGroup::getQtAnimation(QObject* parent){
//if supplied, use parent given in args.
QObject* correctParent;
if (parent){
correctParent = parent;
} else {
correctParent = m_parent;
}
QAnimationGroup* g;
if(m_parallel){
g = new QParallelAnimationGroup(correctParent);
} else {
g = new QSequentialAnimationGroup(correctParent);
}
QListIterator<AbstractAnimation*> it(anims);
while (it.hasNext()) {
//add with group as owner
g->addAnimation(it.next()->getQtAnimation(g));
}
return g;
}
} //namespace Plasma
#include <../animationgroup.moc>

119
animations/animationgroup.h Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the class for animation groups in plasma.
*/
#ifndef PLASMA_ANIMATIONGROUP_H
#define PLASMA_ANIMATIONGROUP_H
#include <QAbstractAnimation>
#include <QAnimationGroup>
#include <QGraphicsWidget>
#include <QList>
#include <QObject>
#include <plasma/animations/abstractanimation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* A group of Animations and / or AnimationGroups.
*/
class PLASMA_EXPORT AnimationGroup : public AbstractAnimation
{
Q_OBJECT
public:
AnimationGroup(QObject* parent = 0);
virtual ~AnimationGroup();
/**
* Start the animation.
*/
virtual void start();
/**
* @arg parallelness whether the animation should be in parallel or not
*/
void setParallel(bool parallelness);
/**
* @return whether the current animation is parallel or not
*/
bool isParallel() const;
/**
* Add an Animation or AnimationGroup to the group
* @arg elem element to add
* @return id of element added
*/
int add(AbstractAnimation* elem);
/**
* Return element with given id
* @return id of element to get
*/
AbstractAnimation* at(int id) const;
/**
* Remove element with given id
* @arg id id of element to remove
*/
void remove(int id);
/**
* Take the animation object and turn it into a QAnimationGroup. More
* specifically, a QSerialAnimation or QParallelAnimation depending on
* the value of m_parallel at the time of invocation. Returns NULL on error.
*/
QAnimationGroup* getQtAnimation(QObject* parent = 0);
private:
/**
* Parent owner object to use in generated animations.
*/
QObject* m_parent;
/**
* Boolean determining if the animation is parallel. Default is false.
*/
bool m_parallel;
/**
* Map of AbstractAnimations to be run, by id.
*/
QList<AbstractAnimation *> anims;
};
} //namespace Plasma
#endif

80
animations/expand.cpp Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "expand.h"
#include <QRect>
#include <kdebug.h>
namespace Plasma
{
ExpandAnimation::ExpandAnimation(AnimationDirection direction, int distance)
: m_direction(direction),
m_distance(distance)
{
}
QAbstractAnimation* ExpandAnimation::render(QObject* parent){
//get current geometry values
QGraphicsWidget *m_object = getAnimatedObject();
QRectF geometry = m_object->geometry();
//compute new geometry values
switch (m_direction){
case MoveUp:
geometry.setTop(geometry.y() - m_distance);
break;
case MoveRight:
geometry.setRight(geometry.x() + geometry.width() - 1 + m_distance);
break;
case MoveDown:
geometry.setBottom(geometry.y() + geometry.height() - 1 + m_distance);
break;
case MoveLeft:
geometry.setLeft(geometry.x() - m_distance);
break;
case MoveUpRight:
case MoveDownRight:
case MoveDownLeft:
case MoveUpLeft:
break;
}
//create animation
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "geometry", parent);
anim->setEndValue(geometry);
anim->setDuration(getDuration());
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
return anim;
}
} //namespace Plasma

59
animations/expand.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the definition for the Expand effect.
*/
#ifndef PLASMA_ANIMATIONS_Expand_H
#define PLASMA_ANIMATIONS_Expand_H
#include <plasma/animations/animation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* @class Expand plasma/animations/expand.h
* @short Expand effect
*
* Effect that grows the object a specific distance in a given direction, on
* one side. The object doesn't "move" except for the side that is expanding.
*/
class PLASMA_EXPORT ExpandAnimation : public Animation
{
Q_OBJECT
public:
ExpandAnimation(AnimationDirection direction, int distance);
virtual ~ExpandAnimation(){};
protected:
virtual QAbstractAnimation* render(QObject* parent = 0);
private:
AnimationDirection m_direction;
int m_distance;
};
}
#endif

56
animations/fade.cpp Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "fade.h"
#include <QRect>
#include <kdebug.h>
namespace Plasma
{
FadeAnimation::FadeAnimation(double factor)
: m_factor(factor)
{
if (m_factor > 1.0){
kDebug() << "Opacity must be between 0 and 1.0. Reducing to 1.0.";
m_factor = 1.0;
} else if(m_factor < 0){
kDebug() << "Opacity must be between 0 and 1.0. Increasing to 0.";
m_factor = 0;
}
}
QAbstractAnimation* FadeAnimation::render(QObject* parent){
//create animation
QGraphicsWidget *m_object = getAnimatedObject();
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "opacity", parent);
anim->setEndValue(m_factor);
anim->setDuration(getDuration());
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
return anim;
}
} //namespace Plasma

57
animations/fade.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the definition for the Fade effect.
*/
#ifndef PLASMA_ANIMATIONS_FADE_H
#define PLASMA_ANIMATIONS_FADE_H
#include <plasma/animations/animation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* @class Fade plasma/animations/fade.h
* @short Fade effect
*
* Effect that slowly transforms the opacity of the object to the given value.
*/
class PLASMA_EXPORT FadeAnimation : public Animation
{
Q_OBJECT
public:
FadeAnimation(double factor);
virtual ~FadeAnimation(){};
protected:
virtual QAbstractAnimation* render(QObject* parent = 0);
private:
qreal m_factor;
};
}
#endif

66
animations/grow.cpp Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "grow.h"
#include <QRect>
#include <kdebug.h>
namespace Plasma
{
GrowAnimation::GrowAnimation(double factor)
: m_factor(factor)
{
}
QAbstractAnimation* GrowAnimation::render(QObject* parent){
//get current geometry values
QGraphicsWidget *m_object = getAnimatedObject();
QRectF geometry = m_object->geometry();
qreal w = geometry.width();
qreal h = geometry.height();
//compute new geometry values
qreal newWidth = w * m_factor;
qreal newHeight = h * m_factor;
//locfactor is factor by which object must move up and left
//to compensate for its growth down and right, to keep the
//center in place.
qreal locfactor = (m_factor - 1) / 2.0;
qreal newX = geometry.x() - w * locfactor;
qreal newY = geometry.y() - h * locfactor;
//create animation
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "geometry", parent);
anim->setEndValue(QRectF(
newX, newY,
newWidth, newHeight));
anim->setDuration(getDuration());
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
return anim;
}
} //namespace Plasma

59
animations/grow.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the definition for the Grow effect.
*/
#ifndef PLASMA_ANIMATIONS_GROW_H
#define PLASMA_ANIMATIONS_GROW_H
#include <plasma/animations/animation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* @class Grow plasma/animations/grow.h
* @short Grow effect
*
* Effect that grows any QGraphicsWidget by a multiple given in the
* constructor. The center of the object stays in place while the sides grow.
*
*/
class PLASMA_EXPORT GrowAnimation : public Animation
{
Q_OBJECT
public:
GrowAnimation(double factor);
virtual ~GrowAnimation(){};
protected:
virtual QAbstractAnimation* render(QObject* parent = 0);
private:
double m_factor;
};
}
#endif

138
animations/pulser.cpp Normal file
View File

@ -0,0 +1,138 @@
/* Copyright (C) 2009 Adenilson Cavalcanti <cavalcantii@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "pulser.h"
#include <QGraphicsWidget>
#include <QEvent>
#include <QAbstractAnimation>
#include <QParallelAnimationGroup>
#include <QDebug>
#include <QPropertyAnimation>
namespace Plasma
{
PulseAnimation::PulseAnimation(): animation(0),
under(0), pulseGeometry(0),
zvalue(0), mscale(0),
anim1(0), anim2(0), anim3(0)
{
}
PulseAnimation::~PulseAnimation()
{
delete animation;
delete pulseGeometry;
}
void PulseAnimation::setCopy(QGraphicsWidget *copy)
{
QGraphicsWidget *target = getAnimatedObject();
under = copy;
under->setParentItem(target);
zvalue = target->zValue();
--zvalue;
under->setOpacity(0);
under->setZValue(zvalue);
mscale = under->scale();
createAnimation();
}
void PulseAnimation::updateGeometry(QRectF updated, qreal zCoordinate, qreal scale)
{
zvalue = zCoordinate;
--zvalue;
under->setGeometry(updated);
under->setPos(0, 0);
under->setOpacity(0);
under->setZValue(zvalue);
/* TODO: move this to a function */
QRectF initial(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);
anim2->setEndValue(end);
anim2->setEndValue(end);
}
void PulseAnimation::resetPulser()
{
under->setGeometry(*pulseGeometry);
under->setOpacity(0);
under->setZValue(zvalue);
under->setScale(mscale);
}
void PulseAnimation::createAnimation(qreal duration, qreal scale)
{
pulseGeometry = new QRectF(under->geometry());
QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
anim1 = new QPropertyAnimation(under, "opacity");
anim1->setDuration(duration);
anim1->setEndValue(0);
group->addAnimation(anim1);
/* TODO: move this to a function */
anim2 = new QPropertyAnimation(under, "geometry");
anim2->setDuration(duration);
QRectF initial(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);
anim2->setEndValue(end);
group->addAnimation(anim2);
anim3 = new QPropertyAnimation(under, "scale");
anim3->setDuration(duration);
anim3->setEndValue(scale);
group->addAnimation(anim3);
animation = group;
connect(animation, SIGNAL(finished()), this, SLOT(resetPulser()));
}
QAbstractAnimation* PulseAnimation::render(QObject* parent)
{
Q_UNUSED(parent);
if (!animation)
createAnimation();
return animation;
}
void PulseAnimation::start()
{
under->setOpacity( 1 );
animation->start();
}
} //namespace Plasma

68
animations/pulser.h Normal file
View File

@ -0,0 +1,68 @@
/* Copyright (C) 2009 Adenilson Cavalcanti <cavalcantii@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_ANIMATIONS_PULSE_H
#define PLASMA_ANIMATIONS_PULSE_H
#include <plasma/animations/animation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
class PLASMA_EXPORT PulseAnimation : public Animation
{
Q_OBJECT
public:
PulseAnimation();
virtual ~PulseAnimation();
void updateGeometry(QRectF updated, qreal zCoordinate = 0, qreal scale = 1.5);
void setCopy(QGraphicsWidget *copy);
public Q_SLOTS:
void start();
void resetPulser();
protected:
virtual QAbstractAnimation* render(QObject* parent = 0);
private:
void createAnimation(qreal _duration = 500, qreal _scale = 1.5);
QAbstractAnimation *animation;
QGraphicsWidget *under;
QRectF *pulseGeometry;
qreal zvalue, mscale;
QPropertyAnimation *anim1, *anim2, *anim3;
};
}
#endif

117
animations/semantic.cache Normal file
View File

@ -0,0 +1,117 @@
;; Object animations/
;; SEMANTICDB Tags save file
(semanticdb-project-database-file "animations/"
:tables (list
(semanticdb-table "abstractanimation.h"
:major-mode 'c-mode
:tags '(("PLASMA_ABSTRACTANIMATION_H" variable (:constant-flag t) nil [989 1018]) ("QAbstractAnimation" include (:system-flag t) (dependency-file none) [1017 1046]) ("QGraphicsWidget" include (:system-flag t) (dependency-file none) [1047 1073]) ("QObject" include (:system-flag t) (dependency-file none) [1074 1092]) ("plasma/plasma.h" include (:system-flag t) (dependency-file none) [1094 1120]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [1121 1154]) ("Plasma" type (:type "namespace") nil [1156 2002]))
:file "abstractanimation.h"
:pointmax 2030
:unmatched-syntax 'nil
)
(semanticdb-table "animation.cpp"
:major-mode 'c++-mode
:tags '(("animation.h" include nil nil [818 840]) ("QMapIterator" include (:system-flag t) nil [842 865]) ("QObject" include (:system-flag t) nil [866 884]) ("QParallelAnimationGroup" include (:system-flag t) nil [885 919]) ("QSequentialAnimationGroup" include (:system-flag t) nil [920 956]) ("kdebug.h" include (:system-flag t) nil [958 977]) ("kglobalsettings.h" include (:system-flag t) nil [978 1006]) ("Plasma" type (:members (("Animation" function (:constructor-flag t :parent "Animation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1049 1065])) :type ("Animation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1028 1115]) ("Animation" function (:destructor-flag t :parent "Animation" :type "void") (reparse-symbol namespacesubparts) [1117 1142]) ("setDuration" function (:parent "Animation" :arguments (("duration" variable (:type "int") (reparse-symbol arg-sub-list) [1172 1185])) :type "void") (reparse-symbol namespacesubparts) [1144 1215]) ("duration" function (:parent "Animation" :type "int") (reparse-symbol namespacesubparts) [1217 1275]) ("start" function (:parent "Animation" :type "void") (reparse-symbol namespacesubparts) [1277 1441]) ("getQtAnimation" function (:pointer 1 :parent "Animation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1489 1505])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1443 1777]) ("getDuration" function (:parent "Animation" :type "int") (reparse-symbol namespacesubparts) [1779 1836])) :type "namespace") nil [1008 1839]) ("../animation.moc" include (:system-flag t) nil [1860 1887]))
:file "animation.cpp"
:pointmax 1888
:unmatched-syntax 'nil
)
(semanticdb-table "abstractanimation.cpp"
:major-mode 'c++-mode
:tags '(("abstractanimation.h" include nil nil [818 848]) ("Plasma" type (:members (("AbstractAnimation" function (:constructor-flag t :parent "AbstractAnimation" :type ("AbstractAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [870 912]) ("AbstractAnimation" function (:destructor-flag t :parent "AbstractAnimation" :type "void") (reparse-symbol namespacesubparts) [914 957]) ("setWidget" function (:parent "AbstractAnimation" :arguments (("receiver" variable (:pointer 1 :type ("QGraphicsWidget" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [993 1019])) :type "void") (reparse-symbol namespacesubparts) [959 1047]) ("getAnimatedObject" function (:pointer 1 :parent "AbstractAnimation" :type ("QGraphicsWidget" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1049 1129])) :type "namespace") nil [850 1132]) ("../abstractanimation.moc" include (:system-flag t) (dependency-file none) [1153 1188]))
:file "abstractanimation.cpp"
:pointmax 1189
:unmatched-syntax 'nil
)
(semanticdb-table "expand.cpp"
:major-mode 'c++-mode
:tags '(("expand.h" include nil nil [818 837]) ("QRect" include (:system-flag t) (dependency-file none) [839 855]) ("kdebug.h" include (:system-flag t) (dependency-file none) [857 876]) ("Plasma" type (:members (("ExpandAnimation" function (:constructor-flag t :parent "ExpandAnimation" :arguments (("direction" variable (:type ("AnimationDirection" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [931 960]) ("distance" variable (:type "int") (reparse-symbol arg-sub-list) [961 974])) :type ("ExpandAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [898 1036]) ("render" function (:pointer 1 :parent "ExpandAnimation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1082 1098])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1038 2152])) :type "namespace") nil [878 2155]))
:file "expand.cpp"
:pointmax 2176
:unmatched-syntax 'nil
)
(semanticdb-table "expand.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATIONS_Expand_H" variable (:constant-flag t) nil [936 965]) ("plasma/animations/animation.h" include (:system-flag t) (dependency-file none) [964 1004]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [1005 1038]) ("Plasma" type (:type "namespace") nil [1040 1618]))
:file "expand.h"
:pointmax 1627
:unmatched-syntax 'nil
)
(semanticdb-table "animation.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATION_H" variable (:constant-flag t) nil [946 967]) ("QGraphicsWidget" include (:system-flag t) (dependency-file none) [966 992]) ("QObject" include (:system-flag t) (dependency-file none) [993 1011]) ("QPropertyAnimation" include (:system-flag t) (dependency-file none) [1012 1041]) ("plasma/animations/abstractanimation.h" include (:system-flag t) (dependency-file none) [1043 1091]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [1092 1125]) ("Plasma" type (:type "namespace") nil [1127 2591]))
:file "animation.h"
:pointmax 2619
:unmatched-syntax 'nil
)
(semanticdb-table "fade.cpp"
:major-mode 'c++-mode
:tags '(("fade.h" include nil nil [818 835]) ("QRect" include (:system-flag t) (dependency-file none) [837 853]) ("kdebug.h" include (:system-flag t) (dependency-file none) [855 874]) ("Plasma" type (:members (("FadeAnimation" function (:constructor-flag t :parent "FadeAnimation" :arguments (("factor" variable (:type "double") (reparse-symbol arg-sub-list) [925 939])) :type ("FadeAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [896 1223]) ("render" function (:pointer 1 :parent "FadeAnimation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1267 1283])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1225 1614])) :type "namespace") nil [876 1617]))
:file "fade.cpp"
:pointmax 1638
:unmatched-syntax 'nil
)
(semanticdb-table "fade.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATIONS_FADE_H" variable (:constant-flag t) nil [932 959]) ("plasma/animations/animation.h" include (:system-flag t) (dependency-file none) [958 998]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [999 1032]) ("Plasma" type (:type "namespace") nil [1034 1459]))
:file "fade.h"
:pointmax 1468
:unmatched-syntax 'nil
)
(semanticdb-table "grow.cpp"
:major-mode 'c++-mode
:tags '(("grow.h" include nil nil [818 835]) ("QRect" include (:system-flag t) (dependency-file none) [837 853]) ("kdebug.h" include (:system-flag t) (dependency-file none) [855 874]) ("Plasma" type (:members (("GrowAnimation" function (:constructor-flag t :parent "GrowAnimation" :arguments (("factor" variable (:type "double") (reparse-symbol arg-sub-list) [925 939])) :type ("GrowAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [896 967]) ("render" function (:pointer 1 :parent "GrowAnimation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1011 1027])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [969 1961])) :type "namespace") nil [876 1964]))
:file "grow.cpp"
:pointmax 1985
)
(semanticdb-table "slide.cpp"
:major-mode 'c++-mode
:tags '(("slide.h" include nil nil [818 836]) ("QPointF" include (:system-flag t) (dependency-file none) [838 856]) ("kdebug.h" include (:system-flag t) (dependency-file none) [858 877]) ("Plasma" type (:members (("SlideAnimation" function (:constructor-flag t :parent "SlideAnimation" :arguments (("direction" variable (:type ("AnimationDirection" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [931 960]) ("distance" variable (:type "int") (reparse-symbol arg-sub-list) [961 974])) :type ("SlideAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [900 1066]) ("render" function (:pointer 1 :parent "SlideAnimation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1111 1127])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1068 2455]) ("setVisibleAtEnd" function (:parent "SlideAnimation" :arguments (("visibility" variable (:type "bool") (reparse-symbol arg-sub-list) [2494 2510])) :type "void") (reparse-symbol namespacesubparts) [2457 2548])) :type "namespace") nil [880 2551]))
:file "slide.cpp"
:pointmax 2572
:unmatched-syntax 'nil
)
(semanticdb-table "slide.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATIONS_SLIDE_H" variable (:constant-flag t) nil [934 962]) ("plasma/animations/animation.h" include (:system-flag t) (dependency-file none) [961 1001]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [1002 1035]) ("Plasma" type (:type "namespace") nil [1037 1862]))
:file "slide.h"
:pointmax 1871
:unmatched-syntax 'nil
)
(semanticdb-table "grow.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATIONS_GROW_H" variable (:constant-flag t) nil [932 959]) ("plasma/animations/animation.h" include (:system-flag t) (dependency-file none) [958 998]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [999 1032]) ("Plasma" type (:type "namespace") nil [1034 1530]))
:file "grow.h"
:pointmax 1539
)
(semanticdb-table "pulser.h"
:major-mode 'c-mode
:tags '(("plasma/animations/animation.h" include (:system-flag t) (dependency-file none) [893 933]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [934 967]) ("Plasma" type (:type "namespace") nil [969 1658]))
:file "pulser.h"
:pointmax 1673
:unmatched-syntax 'nil
)
(semanticdb-table "pulser.cpp"
:major-mode 'c++-mode
:tags '(("pulser.h" include nil nil [824 843]) ("QGraphicsWidget" include (:system-flag t) (dependency-file none) [844 870]) ("QEvent" include (:system-flag t) (dependency-file none) [871 888]) ("QAbstractAnimation" include (:system-flag t) (dependency-file none) [889 918]) ("QParallelAnimationGroup" include (:system-flag t) (dependency-file none) [919 953]) ("QDebug" include (:system-flag t) (dependency-file none) [954 971]) ("QPropertyAnimation" include (:system-flag t) (dependency-file none) [972 1001]) ("Plasma" type (:members (("PulseAnimation" function (:constructor-flag t :parent "PulseAnimation" :type ("PulseAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1023 1154]) ("PulseAnimation" function (:destructor-flag t :parent "PulseAnimation" :type "void") (reparse-symbol namespacesubparts) [1156 1241]) ("setCopy" function (:parent "PulseAnimation" :arguments (("copy" variable (:pointer 1 :type ("QGraphicsWidget" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1272 1294]) ("scale" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1295 1307]) ("duration" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1316 1331])) :type "void") (reparse-symbol namespacesubparts) [1243 1606]) ("updateGeometry" function (:parent "PulseAnimation" :arguments (("updated" variable (:type ("QRectF" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1645 1660]) ("zCoordinate" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1661 1679]) ("scale" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1680 1692])) :type "void") (reparse-symbol namespacesubparts) [1609 2194]) ("resetPulser" function (:parent "PulseAnimation" :type "void") (reparse-symbol namespacesubparts) [2196 2359]) ("createAnimation" function (:parent "PulseAnimation" :arguments (("duration" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [2399 2414]) ("scale" variable (:type ("qreal" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [2415 2427])) :type "void") (reparse-symbol namespacesubparts) [2362 3375]) ("render" function (:pointer 1 :parent "PulseAnimation" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [3420 3436])) :type ("QPropertyAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [3377 3519]) ("start" function (:parent "PulseAnimation" :type "void") (reparse-symbol namespacesubparts) [3521 3605])) :type "namespace") nil [1003 3611]))
:file "pulser.cpp"
:pointmax 3631
:unmatched-syntax 'nil
)
(semanticdb-table "animationgroup.h"
:major-mode 'c-mode
:tags '(("PLASMA_ANIMATIONGROUP_H" variable (:constant-flag t) nil [937 963]) ("QAbstractAnimation" include (:system-flag t) (dependency-file none) [962 991]) ("QAnimationGroup" include (:system-flag t) (dependency-file none) [992 1018]) ("QGraphicsWidget" include (:system-flag t) (dependency-file none) [1019 1045]) ("QList" include (:system-flag t) (dependency-file none) [1046 1062]) ("QObject" include (:system-flag t) (dependency-file none) [1063 1081]) ("plasma/animations/abstractanimation.h" include (:system-flag t) (dependency-file none) [1083 1131]) ("plasma/plasma_export.h" include (:system-flag t) (dependency-file none) [1132 1165]) ("Plasma" type (:type "namespace") nil [1167 2790]))
:file "animationgroup.h"
:pointmax 2818
)
(semanticdb-table "animationgroup.cpp"
:major-mode 'c++-mode
:tags '(("animationgroup.h" include nil nil [818 845]) ("QMapIterator" include (:system-flag t) (dependency-file none) [847 870]) ("QParallelAnimationGroup" include (:system-flag t) (dependency-file none) [871 905]) ("QSequentialAnimationGroup" include (:system-flag t) (dependency-file none) [906 942]) ("Plasma" type (:members (("AnimationGroup" function (:constructor-flag t :parent "AnimationGroup" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [995 1011])) :type ("AnimationGroup" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [964 1063]) ("AnimationGroup" function (:destructor-flag t :parent "AnimationGroup" :type "void") (reparse-symbol namespacesubparts) [1065 1102]) ("setParallel" function (:parent "AnimationGroup" :arguments (("parallelness" variable (:type "bool") (reparse-symbol arg-sub-list) [1137 1155])) :type "void") (reparse-symbol namespacesubparts) [1104 1189]) ("isParallel" function (:parent "AnimationGroup" :type "bool") (reparse-symbol namespacesubparts) [1191 1256]) ("add" function (:parent "AnimationGroup" :arguments (("elem" variable (:pointer 1 :type ("AbstractAnimation" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1282 1306])) :type "int") (reparse-symbol namespacesubparts) [1258 1374]) ("at" function (:pointer 1 :parent "AnimationGroup" :arguments (("id" variable (:type "int") (reparse-symbol arg-sub-list) [1414 1421])) :type ("AbstractAnimation" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1376 1452]) ("remove" function (:parent "AnimationGroup" :arguments (("id" variable (:type "int") (reparse-symbol arg-sub-list) [1482 1489])) :type "void") (reparse-symbol namespacesubparts) [1454 1516]) ("start" function (:parent "AnimationGroup" :type "void") (reparse-symbol namespacesubparts) [1518 1687]) ("getQtAnimation" function (:pointer 1 :parent "AnimationGroup" :arguments (("parent" variable (:pointer 1 :type ("QObject" type (:type "class") nil nil)) (reparse-symbol arg-sub-list) [1737 1753])) :type ("QAnimationGroup" type (:type "class") nil nil)) (reparse-symbol namespacesubparts) [1689 2297])) :type "namespace") nil [944 2300]) ("../animationgroup.moc" include (:system-flag t) (dependency-file none) [2321 2353]))
:file "animationgroup.cpp"
:pointmax 2354
)
)
:file "semantic.cache"
:semantic-tag-version "2.0pre4"
:semanticdb-version "2.0pre4"
)

99
animations/slide.cpp Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "slide.h"
#include <QPointF>
#include <kdebug.h>
namespace Plasma
{
SlideAnimation::SlideAnimation(AnimationDirection direction, int distance)
: m_direction(direction),
m_distance(distance),
m_end_visibility(true)
{
}
QAbstractAnimation* SlideAnimation::render(QObject* parent){
//get current geometry values
QGraphicsWidget *m_object = getAnimatedObject();
qreal x = m_object->x();
qreal y = m_object->y();
qreal newX = x;
qreal newY = y;
//compute new geometry values
switch (m_direction){
case MoveUp:
newY = y - m_distance;
break;
case MoveRight:
newX = x + m_distance;
break;
case MoveDown:
newY = y + m_distance;
break;
case MoveLeft:
newX = x - m_distance;
break;
case MoveUpRight:
case MoveDownRight:
case MoveDownLeft:
case MoveUpLeft:
/* TODO: support compound directions */
kDebug() << "Compound directions (UpRight, DownRight, DownLeft, \
UpLeft) are not supported\n";
break;
}
//create animation
QPropertyAnimation* anim = new QPropertyAnimation(m_object, "pos", parent);
anim->setEndValue(QPointF(newX, newY));
anim->setDuration(getDuration());
//QObject::connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater()));
if(m_end_visibility){
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(show()));
} else {
QObject::connect(anim, SIGNAL(finished()), m_object, SLOT(hide()));
}
return anim;
}
void SlideAnimation::setVisibleAtEnd(bool visibility){
m_end_visibility = visibility;
}
} //namespace Plasma

66
animations/slide.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright 2009 Mehmet Ali Akmanalp <makmanalp@wpi.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file This file contains the definition for the Slide effect.
*/
#ifndef PLASMA_ANIMATIONS_SLIDE_H
#define PLASMA_ANIMATIONS_SLIDE_H
#include <plasma/animations/animation.h>
#include <plasma/plasma_export.h>
namespace Plasma
{
/**
* @class Slide plasma/animations/slide.h
* @short Slide effect
*
* Effect that moves the object a specific distance in a given direction. The
* object is optionally made invisible at the beginning or at the end.
*/
class PLASMA_EXPORT SlideAnimation : public Animation
{
Q_OBJECT
public:
SlideAnimation(AnimationDirection direction, int distance);
virtual ~SlideAnimation(){};
/**
* Set if the widget is visible at the end of the animation (default True).
* @param visibility True for visible, False for not.
*/
void setVisibleAtEnd(bool visibility);
protected:
virtual QAbstractAnimation* render(QObject* parent = 0);
private:
AnimationDirection m_direction;
int m_distance;
//bool m_beginning_visibility;
bool m_end_visibility;
};
}
#endif

View File

@ -1,833 +0,0 @@
/*
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
* 2007 Alexis Ménard <darktears31@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "animator.h"
#include <QGraphicsItem>
#include <QTimeLine>
#include <QTimerEvent>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <kglobalsettings.h>
#include "animationdriver.h"
namespace Plasma
{
static const int MIN_TICK_RATE_INT = 10;
static const qreal MIN_TICK_RATE = 10;
struct AnimationState
{
QGraphicsItem *item;
QObject *qobj;
Animator::Animation animation;
Animator::CurveShape curve;
int interval;
int currentInterval;
int frames;
int currentFrame;
int id;
};
struct ElementAnimationState
{
QGraphicsItem *item;
QObject *qobj;
Animator::CurveShape curve;
Animator::Animation animation;
int interval;
int currentInterval;
int frames;
int currentFrame;
int id;
QPixmap pixmap;
};
struct MovementState
{
QGraphicsItem *item;
QObject *qobj;
Animator::CurveShape curve;
Animator::Movement movement;
int interval;
int currentInterval;
int frames;
int currentFrame;
QPoint start;
QPoint destination;
int id;
};
struct CustomAnimationState
{
Animator::CurveShape curve;
int frames;
int currentFrame;
int frameInterval;
int interval;
int currentInterval;
int id;
QObject *receiver;
char *slot;
};
class AnimatorPrivate
{
public:
AnimatorPrivate()
: driver(0),
animId(0),
timerId(0)
{
}
~AnimatorPrivate()
{
cleanupStates();
qDeleteAll(animatedItems);
qDeleteAll(animatedElements);
qDeleteAll(movingItems);
QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
while (it.hasNext()) {
it.next();
delete[] it.value()->slot;
delete it.value();
it.remove();
}
// Animator is a QObject
// and we don't own the items
}
qreal calculateProgress(int time, int duration, Animator::CurveShape curve)
{
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
return qreal(1.0);
}
timeline.setCurveShape(static_cast<QTimeLine::CurveShape>(curve));
timeline.setDuration(duration);
qreal progress = timeline.valueForTime(time);
return progress;
}
void performAnimation(qreal amount, const AnimationState *state)
{
switch (state->animation) {
case Animator::AppearAnimation:
driver->itemAppear(amount, state->item);
break;
case Animator::DisappearAnimation:
driver->itemDisappear(amount, state->item);
if (amount >= 1) {
state->item->hide();
}
break;
case Animator::ActivateAnimation:
driver->itemActivated(amount, state->item);
break;
}
}
void performMovement(qreal amount, const MovementState *state)
{
switch (state->movement) {
case Animator::SlideInMovement:
case Animator::FastSlideInMovement:
//kDebug() << "performMovement, SlideInMovement";
driver->itemSlideIn(amount, state->item, state->start, state->destination);
break;
case Animator::SlideOutMovement:
case Animator::FastSlideOutMovement:
//kDebug() << "performMovement, SlideOutMovement";
driver->itemSlideOut(amount, state->item, state->start, state->destination);
break;
}
}
void init(Animator *q);
void cleanupStates();
void animatedItemDestroyed(QObject*);
void movingItemDestroyed(QObject*);
void animatedElementDestroyed(QObject*);
void customAnimReceiverDestroyed(QObject*);
AnimationDriver *driver;
int animId;
int timerId;
QTime time;
QTimeLine timeline;
// active items
QMap<QGraphicsItem *, AnimationState *> animatedItems;
QMap<QGraphicsItem *, MovementState *> movingItems;
QMap<int, ElementAnimationState *> animatedElements;
QMap<int, CustomAnimationState *> customAnims;
// items to cull
QSet<AnimationState *> animatedItemsToDelete;
QSet<MovementState *> movingItemsToDelete;
QSet<ElementAnimationState *> animatedElementsToDelete;
QSet<CustomAnimationState *> customAnimsToDelete;
};
class AnimatorSingleton
{
public:
Animator self;
};
K_GLOBAL_STATIC(AnimatorSingleton, privateSelf)
Animator *Animator::self()
{
return &privateSelf->self;
}
Animator::Animator(QObject *parent)
: QObject(parent),
d(new AnimatorPrivate)
{
d->init(this);
}
Animator::~Animator()
{
delete d;
}
void AnimatorPrivate::animatedItemDestroyed(QObject *o)
{
//kDebug() << "testing for" << (void*)o;
QMutableMapIterator<QGraphicsItem*, AnimationState*> it(animatedItems);
while (it.hasNext()) {
it.next();
//kDebug() << "comparing against" << it.value()->qobj;
if (it.value()->qobj == o) {
kDebug() << "found deleted animated item";
if (timerId) {
animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivate::movingItemDestroyed(QObject *o)
{
QMutableMapIterator<QGraphicsItem*, MovementState*> it(movingItems);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
if (timerId) {
movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivate::animatedElementDestroyed(QObject *o)
{
QMutableMapIterator<int, ElementAnimationState*> it(animatedElements);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
if (timerId) {
animatedElementsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivate::customAnimReceiverDestroyed(QObject *o)
{
QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
while (it.hasNext()) {
if (it.next().value()->receiver == o) {
if (timerId) {
customAnimsToDelete.insert(it.value());
} else {
delete[] it.value()->slot;
delete it.value();
}
it.remove();
}
}
}
int Animator::animateItem(QGraphicsItem *item, Animation animation)
{
//kDebug();
// get rid of any existing animations on this item.
//TODO: shoudl we allow multiple anims per item?
QMap<QGraphicsItem*, AnimationState*>::iterator it = d->animatedItems.find(item);
if (it != d->animatedItems.end()) {
if (d->timerId) {
d->animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
d->animatedItems.erase(it);
}
int frames = d->driver->animationFps(animation);
if (frames < 1) {
// evidently this animator doesn't have an implementation
// for this Animation
return -1;
}
int duration = d->driver->animationDuration(animation);
AnimationState *state = new AnimationState;
state->id = ++d->animId;
state->item = item;
state->animation = animation;
state->curve = d->driver->animationCurve(animation);
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = d->driver->animationDuration(animation) / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
state->currentInterval = state->interval;
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
//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;
d->performAnimation(0, state);
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
int Animator::moveItem(QGraphicsItem *item, Movement movement, const QPoint &destination)
{
//kDebug();
QMap<QGraphicsItem*, MovementState*>::iterator it = d->movingItems.find(item);
if (it != d->movingItems.end()) {
if (d->timerId) {
d->movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
d->movingItems.erase(it);
}
int frames = d->driver->movementAnimationFps(movement);
if (frames <= 1) {
// evidently this animator doesn't have an implementation
// for this Animation
return -1;
}
MovementState *state = new MovementState;
state->id = ++d->animId;
state->destination = destination;
state->start = item->pos().toPoint();
state->item = item;
state->movement = movement;
state->curve = d->driver->movementAnimationCurve(movement);
//TODO: variance in times based on the value of animation
int duration = d->driver->movementAnimationDuration(movement);
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = duration / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
// state->interval = (state->interval / MIN_TICK_RATE) * MIN_TICK_RATE;
// kDebug() << "interval of" << state->interval << state->frames << duration << frames;
state->currentInterval = state->interval;
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
}
d->movingItems[item] = state;
d->performMovement(0, state);
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
int Animator::customAnimation(int frames, int duration, Animator::CurveShape curve,
QObject *receiver, const char *slot)
{
if (frames < 1 || duration < 1 || !receiver || !slot) {
return -1;
}
CustomAnimationState *state = new CustomAnimationState;
state->id = ++d->animId;
state->frames = frames;
state->currentFrame = 0;
state->curve = curve;
state->frameInterval = qMax(qreal(1.0), duration / qreal(state->frames));
state->interval = qMax(MIN_TICK_RATE_INT, state->frameInterval - (state->frameInterval % MIN_TICK_RATE_INT));
state->currentInterval = state->interval;
state->receiver = receiver;
state->slot = qstrdup(slot);
d->customAnims[state->id] = state;
disconnect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
connect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
// try with only progress as argument
if (!QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0))) {
//try to pass also the animation id
QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0), Q_ARG(int, state->id));
}
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
void Animator::stopCustomAnimation(int id)
{
QMap<int, CustomAnimationState*>::iterator it = d->customAnims.find(id);
if (it != d->customAnims.end()) {
if (d->timerId) {
d->customAnimsToDelete.insert(it.value());
} else {
delete[] it.value()->slot;
delete it.value();
}
d->customAnims.erase(it);
}
//kDebug() << "stopCustomAnimation(AnimId " << id << ") done";
}
void Animator::stopItemAnimation(int id)
{
QMutableMapIterator<QGraphicsItem*, AnimationState*> it(d->animatedItems);
while (it.hasNext()) {
it.next();
if (it.value()->id == id) {
if (d->timerId) {
d->animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
return;
}
}
}
void Animator::stopItemMovement(int id)
{
QMutableMapIterator<QGraphicsItem*, MovementState*> it(d->movingItems);
while (it.hasNext()) {
it.next();
if (it.value()->id == id) {
if (d->timerId) {
d->movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
return;
}
}
}
int Animator::animateElement(QGraphicsItem *item, Animation animation)
{
//kDebug() << "startElementAnimation(AnimId " << animation << ")";
int frames = d->driver->elementAnimationFps(animation);
int duration = d->driver->animationDuration(animation);
ElementAnimationState *state = new ElementAnimationState;
state->item = item;
state->curve = d->driver->elementAnimationCurve(animation);
state->animation = animation;
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = duration / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
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;
if (state->frames < 1) {
state->frames = 1;
state->currentFrame = 1;
needTimer = false;
}
d->animatedElements[state->id] = state;
//kDebug() << "startElementAnimation(AnimId " << animation << ") returning " << state->id;
if (needTimer && !d->timerId) {
// start a 20fps timer;
//TODO: should be started at the maximum frame rate needed only?
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
void Animator::stopElementAnimation(int id)
{
QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
if (it != d->animatedElements.end()) {
if (d->timerId) {
d->animatedElementsToDelete.insert(it.value());
} else {
delete it.value();
}
d->animatedElements.erase(it);
}
//kDebug() << "stopElementAnimation(AnimId " << id << ") done";
}
void Animator::setInitialPixmap(int id, const QPixmap &pixmap)
{
QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
if (it == d->animatedElements.end()) {
kDebug() << "No entry found for id " << id;
return;
}
it.value()->pixmap = pixmap;
}
QPixmap Animator::currentPixmap(int id)
{
QMap<int, ElementAnimationState*>::const_iterator it = d->animatedElements.constFind(id);
if (it == d->animatedElements.constEnd()) {
//kDebug() << "Animator::currentPixmap(" << id << ") found no entry for it!";
return QPixmap();
}
ElementAnimationState *state = it.value();
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
//kDebug() << "Animator::currentPixmap(" << id << " at " << progress;
switch (state->animation) {
case AppearAnimation:
return d->driver->elementAppear(progress, state->pixmap);
break;
case DisappearAnimation:
return d->driver->elementDisappear(progress, state->pixmap);
break;
case ActivateAnimation:
break;
}
return state->pixmap;
}
bool Animator::isAnimating() const
{
return (!d->animatedItems.isEmpty() ||
!d->movingItems.isEmpty() ||
!d->animatedElements.isEmpty() ||
!d->customAnims.isEmpty());
}
void Animator::timerEvent(QTimerEvent *event)
{
if (event->timerId() != d->timerId) {
QObject::timerEvent(event);
return;
}
Q_UNUSED(event)
bool animationsRemain = false;
int elapsed = MIN_TICK_RATE;
if (d->time.elapsed() > elapsed) {
elapsed = d->time.elapsed();
}
d->time.restart();
//kDebug() << "timeEvent, elapsed time: " << elapsed;
foreach (AnimationState *state, d->animatedItems) {
if (d->animatedItemsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// we need to step forward!
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
if (state->currentFrame < state->frames) {
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
d->performAnimation(progress, state);
state->currentInterval = state->interval;
animationsRemain = true;
} else {
d->performAnimation(1, state);
d->animatedItems.erase(d->animatedItems.find(state->item));
emit animationFinished(state->item, state->animation);
d->animatedItemsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (MovementState *state, d->movingItems) {
if (d->movingItemsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// we need to step forward!
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
if (state->currentFrame < state->frames) {
//kDebug() << "movement";
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
d->performMovement(progress, state);
animationsRemain = true;
} else {
//kDebug() << "movement";
d->performMovement(1, state);
d->movingItems.erase(d->movingItems.find(state->item));
emit movementFinished(state->item);
d->movingItemsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (ElementAnimationState *state, d->animatedElements) {
if (d->animatedElementsToDelete.contains(state)) {
continue;
}
if (state->currentFrame == state->frames) {
//kDebug() << "skipping" << state->id << "as it is already at frame"
// << state->currentFrame << "of" << state->frames;
// since we keep element animations around until they are
// removed, we will end up with finished animations in the queue;
// just skip them
//TODO: should we move them to a separate QMap?
continue;
}
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 +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
state->item->update();
if (state->currentFrame < state->frames) {
state->currentInterval = state->interval;
animationsRemain = true;
} else {
d->animatedElements.remove(state->id);
emit elementAnimationFinished(state->id);
d->animatedElementsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (CustomAnimationState *state, d->customAnims) {
if (d->customAnimsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// advance the frame
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->frameInterval) : state->frames - state->currentFrame;
/*kDebug() << "custom anim for" << state->receiver
<< "to slot" << state->slot
<< "with interval of" << state->interval
<< "at frame" << state->currentFrame;*/
if (state->currentFrame < state->frames) {
//kDebug () << "not the final frame";
//TODO: calculate a proper interval based on the curve
state->currentInterval = state->interval;
animationsRemain = true;
// signal the object
// try with only progress as argument
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress))) {
//if fails try to add the animation id
QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress),
Q_ARG(int, state->id));
}
} else {
if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1))) {
QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1), Q_ARG(int, state->id));
}
d->customAnims.erase(d->customAnims.find(state->id));
emit customAnimationFinished(state->id);
d->customAnimsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
if (!animationsRemain && d->timerId) {
killTimer(d->timerId);
d->timerId = 0;
}
d->cleanupStates();
}
void AnimatorPrivate::init(Animator *q)
{
//FIXME: usage between different applications?
KConfig c("plasmarc");
KConfigGroup cg(&c, "Animator");
QString pluginName = cg.readEntry("driver", "default");
if (!pluginName.isEmpty()) {
QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(pluginName);
KService::List offers = KServiceTypeTrader::self()->query("Plasma/Animator", constraint);
if (!offers.isEmpty()) {
QString error;
KPluginLoader plugin(*offers.first());
if (Plasma::isPluginVersionCompatible(plugin.pluginVersion())) {
driver = offers.first()->createInstance<Plasma::AnimationDriver>(q, QVariantList(), &error);
}
if (!driver) {
kDebug() << "Could not load requested animator "
<< offers.first() << ". Error given: " << error;
}
}
}
if (!driver) {
driver = new AnimationDriver(q);
}
}
void AnimatorPrivate::cleanupStates()
{
/*
kDebug() << animatedItemsToDelete.count() << animatedElementsToDelete.count()
<< movingItemsToDelete.count() << customAnimsToDelete.count();
*/
qDeleteAll(animatedItemsToDelete);
animatedItemsToDelete.clear();
qDeleteAll(animatedElementsToDelete);
animatedElementsToDelete.clear();
qDeleteAll(movingItemsToDelete);
movingItemsToDelete.clear();
QSetIterator<CustomAnimationState*> it(customAnimsToDelete);
while (it.hasNext()) {
CustomAnimationState *state = it.next();
delete[] state->slot;
delete state;
}
customAnimsToDelete.clear();
}
} // namespace Plasma
#include <animator.moc>

View File

@ -32,7 +32,7 @@ class QTimeLine;
namespace Plasma
{
class AnimatorPrivate;
class AnimatorPrivateDeprecated;
/**
* @class Animator plasma/animator.h <Plasma/Animator>
@ -48,21 +48,21 @@ class PLASMA_EXPORT Animator : public QObject
public:
enum Animation {
enum KDE_DEPRECATED Animation {
AppearAnimation = 0, /*<< Animate the appearance of an element */
DisappearAnimation, /*<< Animate the disappearance of an element */
ActivateAnimation /*<< When something is activated or launched,
such as an app icon being clicked */
};
enum CurveShape {
enum KDE_DEPRECATED CurveShape {
EaseInCurve = 0,
EaseOutCurve,
EaseInOutCurve,
LinearCurve
};
enum Movement {
enum KDE_DEPRECATED Movement {
SlideInMovement = 0,
SlideOutMovement,
FastSlideInMovement,
@ -72,7 +72,7 @@ public:
/**
* Singleton accessor
**/
static Animator *self();
static KDE_DEPRECATED Animator *self();
/**
* Starts a standard animation on a QGraphicsItem.
@ -80,8 +80,9 @@ public:
* @arg item the item to animate in some fashion
* @arg anim the type of animation to perform
* @return the id of the animation
* @deprecated use new Animator API with Qt Kinetic
**/
Q_INVOKABLE int animateItem(QGraphicsItem *item, Animation anim);
KDE_DEPRECATED Q_INVOKABLE int animateItem(QGraphicsItem *item,Animation anim);
/**
* Stops an item animation before the animation is complete.
@ -89,8 +90,9 @@ public:
* this on normal completion of the animation.
*
* @arg id the id of the animation as returned by animateItem
* @deprecated use new Animator API with Qt Kinetic
*/
Q_INVOKABLE void stopItemAnimation(int id);
KDE_DEPRECATED Q_INVOKABLE void stopItemAnimation(int id);
/**
* Starts a standard animation on a QGraphicsItem.
@ -98,8 +100,9 @@ public:
* @arg item the item to animate in some fashion
* @arg anim the type of animation to perform
* @return the id of the animation
* @deprecated use new Animator API with Qt Kinetic
**/
Q_INVOKABLE int moveItem(QGraphicsItem *item, Movement movement, const QPoint &destination);
KDE_DEPRECATED Q_INVOKABLE int moveItem(QGraphicsItem *item, Movement movement, const QPoint &destination);
/**
* Stops an item movement before the animation is complete.
@ -107,8 +110,9 @@ public:
* this on normal completion of the animation.
*
* @arg id the id of the animation as returned by moveItem
* @deprecated use new Animator API with Qt Kinetic
*/
Q_INVOKABLE void stopItemMovement(int id);
KDE_DEPRECATED Q_INVOKABLE void stopItemMovement(int id);
/**
* Starts a custom animation, preventing the need to create a timeline
@ -126,9 +130,10 @@ public:
* you want to manage multiple animations with a sigle slot
*
* @return an id that can be used to identify this animation.
* @deprecated use new Animator API with Qt Kinetic
*/
Q_INVOKABLE int customAnimation(int frames, int duration, Animator::CurveShape curve,
QObject *receiver, const char *method);
KDE_DEPRECATED Q_INVOKABLE int customAnimation(int frames, int duration,
Animator::CurveShape curve, QObject *receiver, const char *method);
/**
* Stops a custom animation. Note that it is not necessary to call
@ -136,21 +141,23 @@ public:
* a given QObject are cleaned up automatically on QObject destruction.
*
* @arg id the id of the animation as returned by customAnimation
* @deprecated use new Animator API with Qt Kinetic
*/
Q_INVOKABLE void stopCustomAnimation(int id);
KDE_DEPRECATED Q_INVOKABLE void stopCustomAnimation(int id);
Q_INVOKABLE int animateElement(QGraphicsItem *obj, Animation);
Q_INVOKABLE void stopElementAnimation(int id);
Q_INVOKABLE void setInitialPixmap(int id, const QPixmap &pixmap);
Q_INVOKABLE QPixmap currentPixmap(int id);
KDE_DEPRECATED Q_INVOKABLE int animateElement(QGraphicsItem *obj, Animation);
KDE_DEPRECATED Q_INVOKABLE void stopElementAnimation(int id);
KDE_DEPRECATED Q_INVOKABLE void setInitialPixmap(int id, const QPixmap &pixmap);
KDE_DEPRECATED Q_INVOKABLE QPixmap currentPixmap(int id);
/**
* Can be used to query if there are other animations happening. This way
* heavy operations can be delayed until all animations are finished.
* @return true if there are animations going on.
* @since 4.1
* @deprecated use new Animator API with Qt Kinetic
*/
Q_INVOKABLE bool isAnimating() const;
KDE_DEPRECATED Q_INVOKABLE bool isAnimating() const;
Q_SIGNALS:
void animationFinished(QGraphicsItem *item, Plasma::Animator::Animation anim);
@ -171,7 +178,7 @@ private:
Q_PRIVATE_SLOT(d, void animatedElementDestroyed(QObject*))
Q_PRIVATE_SLOT(d, void customAnimReceiverDestroyed(QObject*))
AnimatorPrivate * const d;
AnimatorPrivateDeprecated * const d;
};
} // namespace Plasma

833
deprecated/animator.cpp Normal file
View File

@ -0,0 +1,833 @@
/*
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
* 2007 Alexis Ménard <darktears31@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "animator.h"
#include <QGraphicsItem>
#include <QTimeLine>
#include <QTimerEvent>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <kglobalsettings.h>
#include "animationdriver.h"
namespace Plasma
{
static const int MIN_TICK_RATE_INT = 10;
static const qreal MIN_TICK_RATE = 10;
struct AnimationState
{
QGraphicsItem *item;
QObject *qobj;
Animator::Animation animation;
Animator::CurveShape curve;
int interval;
int currentInterval;
int frames;
int currentFrame;
int id;
};
struct ElementAnimationState
{
QGraphicsItem *item;
QObject *qobj;
Animator::CurveShape curve;
Animator::Animation animation;
int interval;
int currentInterval;
int frames;
int currentFrame;
int id;
QPixmap pixmap;
};
struct MovementState
{
QGraphicsItem *item;
QObject *qobj;
Animator::CurveShape curve;
Animator::Movement movement;
int interval;
int currentInterval;
int frames;
int currentFrame;
QPoint start;
QPoint destination;
int id;
};
struct CustomAnimationState
{
Animator::CurveShape curve;
int frames;
int currentFrame;
int frameInterval;
int interval;
int currentInterval;
int id;
QObject *receiver;
char *slot;
};
class AnimatorPrivateDeprecated
{
public:
AnimatorPrivateDeprecated()
: driver(0),
animId(0),
timerId(0)
{
}
~AnimatorPrivateDeprecated()
{
cleanupStates();
qDeleteAll(animatedItems);
qDeleteAll(animatedElements);
qDeleteAll(movingItems);
QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
while (it.hasNext()) {
it.next();
delete[] it.value()->slot;
delete it.value();
it.remove();
}
// Animator is a QObject
// and we don't own the items
}
qreal calculateProgress(int time, int duration, Animator::CurveShape curve)
{
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
return qreal(1.0);
}
timeline.setCurveShape(static_cast<QTimeLine::CurveShape>(curve));
timeline.setDuration(duration);
qreal progress = timeline.valueForTime(time);
return progress;
}
void performAnimation(qreal amount, const AnimationState *state)
{
switch (state->animation) {
case Animator::AppearAnimation:
driver->itemAppear(amount, state->item);
break;
case Animator::DisappearAnimation:
driver->itemDisappear(amount, state->item);
if (amount >= 1) {
state->item->hide();
}
break;
case Animator::ActivateAnimation:
driver->itemActivated(amount, state->item);
break;
}
}
void performMovement(qreal amount, const MovementState *state)
{
switch (state->movement) {
case Animator::SlideInMovement:
case Animator::FastSlideInMovement:
//kDebug() << "performMovement, SlideInMovement";
driver->itemSlideIn(amount, state->item, state->start, state->destination);
break;
case Animator::SlideOutMovement:
case Animator::FastSlideOutMovement:
//kDebug() << "performMovement, SlideOutMovement";
driver->itemSlideOut(amount, state->item, state->start, state->destination);
break;
}
}
void init(Animator *q);
void cleanupStates();
void animatedItemDestroyed(QObject*);
void movingItemDestroyed(QObject*);
void animatedElementDestroyed(QObject*);
void customAnimReceiverDestroyed(QObject*);
AnimationDriver *driver;
int animId;
int timerId;
QTime time;
QTimeLine timeline;
// active items
QMap<QGraphicsItem *, AnimationState *> animatedItems;
QMap<QGraphicsItem *, MovementState *> movingItems;
QMap<int, ElementAnimationState *> animatedElements;
QMap<int, CustomAnimationState *> customAnims;
// items to cull
QSet<AnimationState *> animatedItemsToDelete;
QSet<MovementState *> movingItemsToDelete;
QSet<ElementAnimationState *> animatedElementsToDelete;
QSet<CustomAnimationState *> customAnimsToDelete;
};
class AnimatorSingleton
{
public:
Animator self;
};
K_GLOBAL_STATIC(AnimatorSingleton, privateSelf)
Animator *Animator::self()
{
return &privateSelf->self;
}
Animator::Animator(QObject *parent)
: QObject(parent),
d(new AnimatorPrivateDeprecated)
{
d->init(this);
}
Animator::~Animator()
{
delete d;
}
void AnimatorPrivateDeprecated::animatedItemDestroyed(QObject *o)
{
//kDebug() << "testing for" << (void*)o;
QMutableMapIterator<QGraphicsItem*, AnimationState*> it(animatedItems);
while (it.hasNext()) {
it.next();
//kDebug() << "comparing against" << it.value()->qobj;
if (it.value()->qobj == o) {
kDebug() << "found deleted animated item";
if (timerId) {
animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivateDeprecated::movingItemDestroyed(QObject *o)
{
QMutableMapIterator<QGraphicsItem*, MovementState*> it(movingItems);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
if (timerId) {
movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivateDeprecated::animatedElementDestroyed(QObject *o)
{
QMutableMapIterator<int, ElementAnimationState*> it(animatedElements);
while (it.hasNext()) {
it.next();
if (it.value()->qobj == o) {
if (timerId) {
animatedElementsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
}
}
}
void AnimatorPrivateDeprecated::customAnimReceiverDestroyed(QObject *o)
{
QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
while (it.hasNext()) {
if (it.next().value()->receiver == o) {
if (timerId) {
customAnimsToDelete.insert(it.value());
} else {
delete[] it.value()->slot;
delete it.value();
}
it.remove();
}
}
}
int Animator::animateItem(QGraphicsItem *item, Animation animation)
{
//kDebug();
// get rid of any existing animations on this item.
//TODO: shoudl we allow multiple anims per item?
QMap<QGraphicsItem*, AnimationState*>::iterator it = d->animatedItems.find(item);
if (it != d->animatedItems.end()) {
if (d->timerId) {
d->animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
d->animatedItems.erase(it);
}
int frames = d->driver->animationFps(animation);
if (frames < 1) {
// evidently this animator doesn't have an implementation
// for this Animation
return -1;
}
int duration = d->driver->animationDuration(animation);
AnimationState *state = new AnimationState;
state->id = ++d->animId;
state->item = item;
state->animation = animation;
state->curve = d->driver->animationCurve(animation);
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = d->driver->animationDuration(animation) / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
state->currentInterval = state->interval;
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
//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;
d->performAnimation(0, state);
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
int Animator::moveItem(QGraphicsItem *item, Movement movement, const QPoint &destination)
{
//kDebug();
QMap<QGraphicsItem*, MovementState*>::iterator it = d->movingItems.find(item);
if (it != d->movingItems.end()) {
if (d->timerId) {
d->movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
d->movingItems.erase(it);
}
int frames = d->driver->movementAnimationFps(movement);
if (frames <= 1) {
// evidently this animator doesn't have an implementation
// for this Animation
return -1;
}
MovementState *state = new MovementState;
state->id = ++d->animId;
state->destination = destination;
state->start = item->pos().toPoint();
state->item = item;
state->movement = movement;
state->curve = d->driver->movementAnimationCurve(movement);
//TODO: variance in times based on the value of animation
int duration = d->driver->movementAnimationDuration(movement);
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = duration / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
// state->interval = (state->interval / MIN_TICK_RATE) * MIN_TICK_RATE;
// kDebug() << "interval of" << state->interval << state->frames << duration << frames;
state->currentInterval = state->interval;
state->qobj = dynamic_cast<QObject*>(item);
if (state->qobj) {
disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
}
d->movingItems[item] = state;
d->performMovement(0, state);
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
int Animator::customAnimation(int frames, int duration, Animator::CurveShape curve,
QObject *receiver, const char *slot)
{
if (frames < 1 || duration < 1 || !receiver || !slot) {
return -1;
}
CustomAnimationState *state = new CustomAnimationState;
state->id = ++d->animId;
state->frames = frames;
state->currentFrame = 0;
state->curve = curve;
state->frameInterval = qMax(qreal(1.0), duration / qreal(state->frames));
state->interval = qMax(MIN_TICK_RATE_INT, state->frameInterval - (state->frameInterval % MIN_TICK_RATE_INT));
state->currentInterval = state->interval;
state->receiver = receiver;
state->slot = qstrdup(slot);
d->customAnims[state->id] = state;
disconnect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
connect(receiver, SIGNAL(destroyed(QObject*)),
this, SLOT(customAnimReceiverDestroyed(QObject*)));
// try with only progress as argument
if (!QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0))) {
//try to pass also the animation id
QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0), Q_ARG(int, state->id));
}
if (!d->timerId) {
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
void Animator::stopCustomAnimation(int id)
{
QMap<int, CustomAnimationState*>::iterator it = d->customAnims.find(id);
if (it != d->customAnims.end()) {
if (d->timerId) {
d->customAnimsToDelete.insert(it.value());
} else {
delete[] it.value()->slot;
delete it.value();
}
d->customAnims.erase(it);
}
//kDebug() << "stopCustomAnimation(AnimId " << id << ") done";
}
void Animator::stopItemAnimation(int id)
{
QMutableMapIterator<QGraphicsItem*, AnimationState*> it(d->animatedItems);
while (it.hasNext()) {
it.next();
if (it.value()->id == id) {
if (d->timerId) {
d->animatedItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
return;
}
}
}
void Animator::stopItemMovement(int id)
{
QMutableMapIterator<QGraphicsItem*, MovementState*> it(d->movingItems);
while (it.hasNext()) {
it.next();
if (it.value()->id == id) {
if (d->timerId) {
d->movingItemsToDelete.insert(it.value());
} else {
delete it.value();
}
it.remove();
return;
}
}
}
int Animator::animateElement(QGraphicsItem *item, Animation animation)
{
//kDebug() << "startElementAnimation(AnimId " << animation << ")";
int frames = d->driver->elementAnimationFps(animation);
int duration = d->driver->animationDuration(animation);
ElementAnimationState *state = new ElementAnimationState;
state->item = item;
state->curve = d->driver->elementAnimationCurve(animation);
state->animation = animation;
state->frames = qMax(1.0, frames * (duration / 1000.0));
state->currentFrame = 0;
state->interval = duration / qreal(state->frames);
state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
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;
if (state->frames < 1) {
state->frames = 1;
state->currentFrame = 1;
needTimer = false;
}
d->animatedElements[state->id] = state;
//kDebug() << "startElementAnimation(AnimId " << animation << ") returning " << state->id;
if (needTimer && !d->timerId) {
// start a 20fps timer;
//TODO: should be started at the maximum frame rate needed only?
d->timerId = startTimer(MIN_TICK_RATE);
d->time.restart();
}
return state->id;
}
void Animator::stopElementAnimation(int id)
{
QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
if (it != d->animatedElements.end()) {
if (d->timerId) {
d->animatedElementsToDelete.insert(it.value());
} else {
delete it.value();
}
d->animatedElements.erase(it);
}
//kDebug() << "stopElementAnimation(AnimId " << id << ") done";
}
void Animator::setInitialPixmap(int id, const QPixmap &pixmap)
{
QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
if (it == d->animatedElements.end()) {
kDebug() << "No entry found for id " << id;
return;
}
it.value()->pixmap = pixmap;
}
QPixmap Animator::currentPixmap(int id)
{
QMap<int, ElementAnimationState*>::const_iterator it = d->animatedElements.constFind(id);
if (it == d->animatedElements.constEnd()) {
//kDebug() << "Animator::currentPixmap(" << id << ") found no entry for it!";
return QPixmap();
}
ElementAnimationState *state = it.value();
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
//kDebug() << "Animator::currentPixmap(" << id << " at " << progress;
switch (state->animation) {
case AppearAnimation:
return d->driver->elementAppear(progress, state->pixmap);
break;
case DisappearAnimation:
return d->driver->elementDisappear(progress, state->pixmap);
break;
case ActivateAnimation:
break;
}
return state->pixmap;
}
bool Animator::isAnimating() const
{
return (!d->animatedItems.isEmpty() ||
!d->movingItems.isEmpty() ||
!d->animatedElements.isEmpty() ||
!d->customAnims.isEmpty());
}
void Animator::timerEvent(QTimerEvent *event)
{
if (event->timerId() != d->timerId) {
QObject::timerEvent(event);
return;
}
Q_UNUSED(event)
bool animationsRemain = false;
int elapsed = MIN_TICK_RATE;
if (d->time.elapsed() > elapsed) {
elapsed = d->time.elapsed();
}
d->time.restart();
//kDebug() << "timeEvent, elapsed time: " << elapsed;
foreach (AnimationState *state, d->animatedItems) {
if (d->animatedItemsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// we need to step forward!
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
if (state->currentFrame < state->frames) {
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
d->performAnimation(progress, state);
state->currentInterval = state->interval;
animationsRemain = true;
} else {
d->performAnimation(1, state);
d->animatedItems.erase(d->animatedItems.find(state->item));
emit animationFinished(state->item, state->animation);
d->animatedItemsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (MovementState *state, d->movingItems) {
if (d->movingItemsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// we need to step forward!
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
if (state->currentFrame < state->frames) {
//kDebug() << "movement";
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
d->performMovement(progress, state);
animationsRemain = true;
} else {
//kDebug() << "movement";
d->performMovement(1, state);
d->movingItems.erase(d->movingItems.find(state->item));
emit movementFinished(state->item);
d->movingItemsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (ElementAnimationState *state, d->animatedElements) {
if (d->animatedElementsToDelete.contains(state)) {
continue;
}
if (state->currentFrame == state->frames) {
//kDebug() << "skipping" << state->id << "as it is already at frame"
// << state->currentFrame << "of" << state->frames;
// since we keep element animations around until they are
// removed, we will end up with finished animations in the queue;
// just skip them
//TODO: should we move them to a separate QMap?
continue;
}
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 +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
state->item->update();
if (state->currentFrame < state->frames) {
state->currentInterval = state->interval;
animationsRemain = true;
} else {
d->animatedElements.remove(state->id);
emit elementAnimationFinished(state->id);
d->animatedElementsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
foreach (CustomAnimationState *state, d->customAnims) {
if (d->customAnimsToDelete.contains(state)) {
continue;
}
if (state->currentInterval <= elapsed) {
// advance the frame
state->currentFrame +=
(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
qMax(1, elapsed / state->frameInterval) : state->frames - state->currentFrame;
/*kDebug() << "custom anim for" << state->receiver
<< "to slot" << state->slot
<< "with interval of" << state->interval
<< "at frame" << state->currentFrame;*/
if (state->currentFrame < state->frames) {
//kDebug () << "not the final frame";
//TODO: calculate a proper interval based on the curve
state->currentInterval = state->interval;
animationsRemain = true;
// signal the object
// try with only progress as argument
qreal progress = d->calculateProgress(state->currentFrame * state->interval,
state->frames * state->interval,
state->curve);
if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress))) {
//if fails try to add the animation id
QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress),
Q_ARG(int, state->id));
}
} else {
if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1))) {
QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1), Q_ARG(int, state->id));
}
d->customAnims.erase(d->customAnims.find(state->id));
emit customAnimationFinished(state->id);
d->customAnimsToDelete.insert(state);
}
} else {
state->currentInterval -= elapsed;
animationsRemain = true;
}
}
if (!animationsRemain && d->timerId) {
killTimer(d->timerId);
d->timerId = 0;
}
d->cleanupStates();
}
void AnimatorPrivateDeprecated::init(Animator *q)
{
//FIXME: usage between different applications?
KConfig c("plasmarc");
KConfigGroup cg(&c, "Animator");
QString pluginName = cg.readEntry("driver", "default");
if (!pluginName.isEmpty()) {
QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(pluginName);
KService::List offers = KServiceTypeTrader::self()->query("Plasma/Animator", constraint);
if (!offers.isEmpty()) {
QString error;
KPluginLoader plugin(*offers.first());
if (Plasma::isPluginVersionCompatible(plugin.pluginVersion())) {
driver = offers.first()->createInstance<Plasma::AnimationDriver>(q, QVariantList(), &error);
}
if (!driver) {
kDebug() << "Could not load requested animator "
<< offers.first() << ". Error given: " << error;
}
}
}
if (!driver) {
driver = new AnimationDriver(q);
}
}
void AnimatorPrivateDeprecated::cleanupStates()
{
/*
kDebug() << animatedItemsToDelete.count() << animatedElementsToDelete.count()
<< movingItemsToDelete.count() << customAnimsToDelete.count();
*/
qDeleteAll(animatedItemsToDelete);
animatedItemsToDelete.clear();
qDeleteAll(animatedElementsToDelete);
animatedElementsToDelete.clear();
qDeleteAll(movingItemsToDelete);
movingItemsToDelete.clear();
QSetIterator<CustomAnimationState*> it(customAnimsToDelete);
while (it.hasNext()) {
CustomAnimationState *state = it.next();
delete[] state->slot;
delete state;
}
customAnimsToDelete.clear();
}
} // namespace Plasma
#include <../animator.moc>

View File

@ -107,6 +107,20 @@ enum ZoomDirection {
ZoomOut = 1 /**< Zoom out one step */
};
/**
* The movement direction of an animation.
*/
enum AnimationDirection {
MoveUp = 0, /**< Move up */
MoveUpRight, /**< Move up and right */
MoveRight, /**< Move right */
MoveDownRight, /**< Move down and right */
MoveDown, /**< Move down */
MoveDownLeft, /**< Move down and left */
MoveLeft, /**< Move left */
MoveUpLeft /**< Move up and left */
};
/**
* The Location enumeration describes where on screen an element, such as an
* Applet or its managing container, is positioned on the screen.