From 2894a3403b76fa794f8a17bbede83b87de3a9d57 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Fri, 8 Jun 2007 05:24:19 +0000 Subject: [PATCH] initial 284LOC sketch of phase/animator. this includes the "null" animator base class, the phase manager and plugin loader. tomorrow: an animator! svn path=/trunk/KDE/kdebase/workspace/lib/plasma/; revision=672771 --- CMakeLists.txt | 44 +++++----- animator.cpp | 86 +++++++++++++++++++ animator.h | 58 +++++++++++++ phase.cpp | 224 +++++++++++++++++++++++++++++++++++++++++++++++++ phase.h | 92 ++++++++++++++++++++ 5 files changed, 484 insertions(+), 20 deletions(-) create mode 100644 animator.cpp create mode 100644 animator.h create mode 100644 phase.cpp create mode 100644 phase.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 128ebfb6d..d6596f66d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,26 +3,28 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ########### next target ############### set(plasma_LIB_SRCS - abstractrunner.cpp - applet.cpp - corona.cpp - dataengine.cpp - dataenginemanager.cpp - datasource.cpp - plasma.cpp - plasma_export.h - svg.cpp - theme.cpp - karambamanager.cpp - widgets/checkbox.cpp - widgets/icon.cpp - widgets/lineedit.cpp - widgets/pushbutton.cpp - widgets/radiobutton.cpp - widgets/widget.cpp - widgets/layout.cpp - widgets/layoutitem.cpp - widgets/vboxlayout.cpp + abstractrunner.cpp + animator.cpp + applet.cpp + corona.cpp + dataengine.cpp + dataenginemanager.cpp + datasource.cpp + phase.cpp + plasma.cpp + plasma_export.h + svg.cpp + theme.cpp + karambamanager.cpp + widgets/checkbox.cpp + widgets/icon.cpp + widgets/lineedit.cpp + widgets/pushbutton.cpp + widgets/radiobutton.cpp + widgets/widget.cpp + widgets/layout.cpp + widgets/layoutitem.cpp + widgets/vboxlayout.cpp ) kde4_automoc(${plasma_LIB_SRCS}) @@ -39,11 +41,13 @@ install(TARGETS plasma DESTINATION ${LIB_INSTALL_DIR} ) install( FILES abstractrunner.h + animator.h applet.h corona.h dataengine.h dataenginemanager.h datasource.h + phase.h plasma.h plasma_export.h svg.h diff --git a/animator.cpp b/animator.cpp new file mode 100644 index 000000000..c436f9aee --- /dev/null +++ b/animator.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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" + +namespace Plasma +{ + +Animator::Animator(QObject *parent, const QStringList& list) + : QObject(parent) +{ + Q_UNUSED(list) +} + +Animator::~Animator() +{ +} + +int Animator::appearFrames() +{ + return 0; +} + +void Animator::appear(int frame, QGraphicsItem* item) +{ + Q_UNUSED(frame) + Q_UNUSED(item) +} + +int Animator::disappearFrames() +{ + return 0; +} + +void Animator::disappear(int frame, QGraphicsItem* item) +{ + Q_UNUSED(frame) + Q_UNUSED(item) +} + +int Animator::activateFrames() +{ + return 0; +} + +void Animator::activate(int frame, QGraphicsItem* item) +{ + Q_UNUSED(frame) + Q_UNUSED(item) +} + +int Animator::frameAppearFrames() +{ + return 0; +} + +void Animator::frameAppear(int frame, QGraphicsItem* item, const QRegion& drawable) +{ + Q_UNUSED(frame) + Q_UNUSED(item) + Q_UNUSED(drawable) +} + +void Animator::renderBackground(QImage& background) +{ + Q_UNUSED(background) +} + +}; // Plasma namespace + +#include "animator.moc" diff --git a/animator.h b/animator.h new file mode 100644 index 000000000..db150f8b2 --- /dev/null +++ b/animator.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 ANIMATOR_H +#define ANIMATOR_H + +#include +#include +#include + +#include + +class QGraphicsItem; + +namespace Plasma +{ + +class PLASMA_EXPORT Animator : public QObject +{ + Q_OBJECT + +public: + explicit Animator(QObject *parent = 0, const QStringList& list = QStringList()); + ~Animator(); + + virtual int appearFrames(); + virtual void appear(int frame, QGraphicsItem* item); + + virtual int disappearFrames(); + virtual void disappear(int frame, QGraphicsItem* item); + + virtual int frameAppearFrames(); + virtual void frameAppear(int frame, QGraphicsItem* item, const QRegion& drawable); + + virtual int activateFrames(); + virtual void activate(int frame, QGraphicsItem* item); + + virtual void renderBackground(QImage& background); +}; + +}; // Plasma namespace + +#endif // multiple inclusion guard diff --git a/phase.cpp b/phase.cpp new file mode 100644 index 000000000..4d6caab3e --- /dev/null +++ b/phase.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 "phase.h" + +#include +#include + +#include +#include +#include +#include + +#include "animator.h" + +namespace Plasma +{ + +struct AnimationState +{ + QGraphicsItem* item; + Phase::Animation animation; +}; + +class Phase::Private +{ + public: + + Private() + : animator(0) + { + } + + ~Private() + { + // delete animator; Animator is a QObject + // TimeLine's are parented to us, and we don't own the items + } + + Animator* animator; + + //TODO: eventually perhaps we should allow multiple animations simulataneously + // which would imply changing this to a QMap > + // and really making the code fun ;) + QMap theAnimated; + QMap animations; +}; + +Phase::Phase(QObject * parent) + : QObject(parent), + d(new Private) +{ + init(); +} + +Phase::~Phase() +{ + delete d; +} + +void Phase::appletDestroyed(QObject* o) +{ + QGraphicsItem* item = dynamic_cast(o); + + if (!item) { + return; + } + + QMap::iterator it = d->theAnimated.find(item); + + if (it == d->theAnimated.end()) { + return; + } + + delete it.value(); + d->animations.erase(d->animations.find(it.value())); + d->theAnimated.erase(it); +} + +void Phase::animate(QGraphicsItem* item, Animation animation) +{ + QMap::iterator it = d->theAnimated.find(item); + + if (it != d->theAnimated.end()) { + delete it.value(); + d->animations.erase(d->animations.find(it.value())); + } + + int frames = 0; + switch (animation) { + case Appear: + frames = d->animator->appearFrames(); + break; + case Disappear: + frames = d->animator->disappearFrames(); + break; + case Activate: + frames = d->animator->activateFrames(); + break; + case FrameAppear: + frames = d->animator->activateFrames(); + break; + } + + if (frames < 1) { + return; + } + + QTimeLine* timeLine = new QTimeLine(300, this); + timeLine->setFrameRange(0, frames); + + AnimationState state; + state.item = item; + state.animation = animation; + d->animations[timeLine] = state; + d->theAnimated[item] = timeLine; + connect(timeLine, SIGNAL(frameChanged(int)), this, SLOT(advanceFrame(int))); + connect(timeLine, SIGNAL(finished()), this, SLOT(animationComplete())); +} + +void Phase::advanceFrame(int frame) +{ + QTimeLine* timeLine = dynamic_cast(sender()); + + if (!timeLine) { + return; + } + + QMap::iterator it = d->animations.find(timeLine); + + if (it == d->animations.end()) { + return; + } + + AnimationState state = it.value(); + + switch (state.animation) { + case Appear: + d->animator->appear(frame, state.item); + break; + case Disappear: + d->animator->disappear(frame, state.item); + break; + case Activate: + d->animator->activate(frame, state.item); + break; + case FrameAppear: + d->animator->frameAppear(frame, state.item, QRegion()); //FIXME: what -is- the frame region? + break; + } +} + +void Phase::animationComplete() +{ + QTimeLine* tl = dynamic_cast(sender()); + + if (!tl) { + return; + } + + QMap::iterator it = d->animations.find(tl); + + if (it == d->animations.end()) { + return; + } + + QMap::iterator animIt = d->theAnimated.find(it.value().item); + + if (animIt != d->theAnimated.end()) { + d->theAnimated.erase(animIt); + } + + d->animations.erase(it); + delete tl; +} + +void Phase::render(QGraphicsItem* item, QImage& image, RenderOp op) +{ + Q_UNUSED(item); + switch (op) { + case RenderBackground: + d->animator->renderBackground(image); + break; + } +} + +void Phase::init() +{ + KConfig c("plasmarc"); + KConfigGroup cg(&c, "Phase"); + QString pluginName = cg.readEntry("animator", QString()); + + 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()) { + d->animator = KService::createInstance(offers.first(), 0, QStringList()); + } + } + + if (!d->animator) { + d->animator = new Animator(this); + } +} + +} // namespace Plasma + +#include diff --git a/phase.h b/phase.h new file mode 100644 index 000000000..977c8a8fc --- /dev/null +++ b/phase.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 PHASE_H +#define PHASE_H + +#include +#include + +#include + +class QGraphicsItem; + +namespace Plasma +{ + +/** + * @short A system for applying effects to Plasma elements + */ +class PLASMA_EXPORT Phase : public QObject +{ + Q_OBJECT + +public: + enum Animation + { + Appear = 0 /*<< When some appears in the Corona */, + Disappear /*<< When something is about to disappear */, + Activate /*<< When something is activated or launched, such as an app icon being clicked */, + FrameAppear /*<< Make a frame appear around an object */ + }; + + enum RenderOp + { + RenderBackground = 0 /*<< Render the background of an item */ + }; + + explicit Phase(QObject * parent = 0); + ~Phase(); + +Q_SIGNALS: + void animationComplete(QGraphicsItem* item, Animation anim); + +public Q_SLOTS: + void animate(QGraphicsItem* item, Animation anim); + void render(QGraphicsItem* item, QImage& image, RenderOp op); + +protected Q_SLOTS: + void appletDestroyed(QObject*); + + /** + * NEVER call this method directly, as it relies on sender() + */ + void advanceFrame(int frame); + + /** + * NEVER call this method directly, as it relies on sender() + */ + void animationComplete(); + +private: + void init(); + + class Private; + Private * const d; +}; + +} // namespace Plasma + +#define K_EXPORT_PLASMA_PHASER(libname, classname) \ + K_EXPORT_COMPONENT_FACTORY( \ + plasma_animator_##libname, \ + KGenericFactory("plasma_animator_" #libname)) + +#endif + +