• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

animator.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2007 Aaron Seigo <aseigo@kde.org>
00003  *                 2007 Alexis Ménard <darktears31@gmail.com>
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU Library General Public License as
00007  *   published by the Free Software Foundation; either version 2, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details
00014  *
00015  *   You should have received a copy of the GNU Library General Public
00016  *   License along with this program; if not, write to the
00017  *   Free Software Foundation, Inc.,
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 
00021 #include "animator.h"
00022 
00023 #include <QGraphicsItem>
00024 #include <QTimeLine>
00025 
00026 #include <kconfig.h>
00027 #include <kconfiggroup.h>
00028 #include <kservice.h>
00029 #include <kservicetypetrader.h>
00030 #include <kglobalsettings.h>
00031 
00032 #include "animationdriver.h"
00033 
00034 namespace Plasma
00035 {
00036 
00037 static const int MIN_TICK_RATE_INT = 10;
00038 static const qreal MIN_TICK_RATE = 10;
00039 
00040 struct AnimationState
00041 {
00042     QGraphicsItem *item;
00043     QObject *qobj;
00044     Animator::Animation animation;
00045     Animator::CurveShape curve;
00046     int interval;
00047     int currentInterval;
00048     int frames;
00049     int currentFrame;
00050     int id;
00051 };
00052 
00053 struct ElementAnimationState
00054 {
00055     QGraphicsItem *item;
00056     QObject *qobj;
00057     Animator::CurveShape curve;
00058     Animator::Animation animation;
00059     int interval;
00060     int currentInterval;
00061     int frames;
00062     int currentFrame;
00063     int id;
00064     QPixmap pixmap;
00065 };
00066 
00067 struct MovementState
00068 {
00069     QGraphicsItem *item;
00070     QObject *qobj;
00071     Animator::CurveShape curve;
00072     Animator::Movement movement;
00073     int interval;
00074     int currentInterval;
00075     int frames;
00076     int currentFrame;
00077     QPoint start;
00078     QPoint destination;
00079     int id;
00080 };
00081 
00082 struct CustomAnimationState
00083 {
00084     Animator::CurveShape curve;
00085     int frames;
00086     int currentFrame;
00087     int interval;
00088     int currentInterval;
00089     int id;
00090     QObject *receiver;
00091     char *slot;
00092 };
00093 
00094 class AnimatorPrivate
00095 {
00096     public:
00097 
00098         AnimatorPrivate()
00099             : driver(0),
00100               animId(0),
00101               timerId(0)
00102         {
00103         }
00104 
00105         ~AnimatorPrivate()
00106         {
00107             qDeleteAll(animatedItems);
00108             qDeleteAll(animatedElements);
00109             qDeleteAll(movingItems);
00110 
00111             QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
00112             while (it.hasNext()) {
00113                 it.next();
00114                 delete[] it.value()->slot;
00115                 delete it.value();
00116                 it.remove();
00117             }
00118 
00119             // Animator is a QObject
00120             // and we don't own the items
00121         }
00122 
00123         qreal calculateProgress(int time, int duration, Animator::CurveShape curve)
00124         {
00125             if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00126                 return qreal(1.0);
00127             }
00128 
00129             timeline.setCurveShape(static_cast<QTimeLine::CurveShape>(curve));
00130             timeline.setDuration(duration);
00131             qreal progress = timeline.valueForTime(time);
00132             return progress;
00133         }
00134 
00135         void performAnimation(qreal amount, const AnimationState *state)
00136         {
00137             switch (state->animation) {
00138             case Animator::AppearAnimation:
00139                 driver->itemAppear(amount, state->item);
00140                 break;
00141             case Animator::DisappearAnimation:
00142                 driver->itemDisappear(amount, state->item);
00143                 if (amount >= 1) {
00144                     state->item->hide();
00145                 }
00146                 break;
00147             case Animator::ActivateAnimation:
00148                 driver->itemActivated(amount, state->item);
00149                 break;
00150             }
00151         }
00152 
00153         void performMovement(qreal amount, const MovementState *state)
00154         {
00155             switch (state->movement) {
00156                 case Animator::SlideInMovement:
00157                 case Animator::FastSlideInMovement:
00158                     //kDebug() << "performMovement, SlideInMovement";
00159                     driver->itemSlideIn(amount, state->item, state->start, state->destination);
00160                     break;
00161                 case Animator::SlideOutMovement:
00162                 case Animator::FastSlideOutMovement:
00163                     //kDebug() << "performMovement, SlideOutMovement";
00164                     driver->itemSlideOut(amount, state->item, state->start, state->destination);
00165                     break;
00166             }
00167         }
00168 
00169         void init(Animator *q);
00170         void animatedItemDestroyed(QObject*);
00171         void movingItemDestroyed(QObject*);
00172         void animatedElementDestroyed(QObject*);
00173         void customAnimReceiverDestroyed(QObject*);
00174 
00175         AnimationDriver *driver;
00176         int animId;
00177         int timerId;
00178         QTime time;
00179         QTimeLine timeline;
00180 
00181         //TODO: eventually perhaps we should allow multiple animations simulataneously
00182         //      which would imply changing this to a QMap<QGraphicsItem*, QList<QTimeLine*> >
00183         //      and really making the code fun ;)
00184         QMap<QGraphicsItem*, AnimationState*> animatedItems;
00185         QMap<QGraphicsItem*, MovementState*> movingItems;
00186         QMap<int, ElementAnimationState*> animatedElements;
00187         QMap<int, CustomAnimationState*> customAnims;
00188 };
00189 
00190 class AnimatorSingleton
00191 {
00192     public:
00193         Animator self;
00194 };
00195 
00196 K_GLOBAL_STATIC(AnimatorSingleton, privateSelf)
00197 
00198 Animator *Animator::self()
00199 {
00200     return &privateSelf->self;
00201 }
00202 
00203 Animator::Animator(QObject *parent)
00204     : QObject(parent),
00205       d(new AnimatorPrivate)
00206 {
00207     d->init(this);
00208 }
00209 
00210 Animator::~Animator()
00211 {
00212     delete d;
00213 }
00214 
00215 void AnimatorPrivate::animatedItemDestroyed(QObject *o)
00216 {
00217     //kDebug() << "testing for" << (void*)o;
00218     QMutableMapIterator<QGraphicsItem*, AnimationState*> it(animatedItems);
00219     while (it.hasNext()) {
00220         it.next();
00221         //kDebug() << "comparing against" << it.value()->qobj;
00222         if (it.value()->qobj == o) {
00223             kDebug() << "found deleted animated item";
00224             delete it.value();
00225             it.remove();
00226         }
00227     }
00228 }
00229 
00230 void AnimatorPrivate::movingItemDestroyed(QObject *o)
00231 {
00232     QMutableMapIterator<QGraphicsItem*, MovementState*> it(movingItems);
00233     while (it.hasNext()) {
00234         it.next();
00235         if (it.value()->qobj == o) {
00236             delete it.value();
00237             it.remove();
00238         }
00239     }
00240 }
00241 
00242 void AnimatorPrivate::animatedElementDestroyed(QObject *o)
00243 {
00244     QMutableMapIterator<int, ElementAnimationState*> it(animatedElements);
00245     while (it.hasNext()) {
00246         it.next();
00247         if (it.value()->qobj == o) {
00248             delete it.value();
00249             it.remove();
00250         }
00251     }
00252 }
00253 
00254 void AnimatorPrivate::customAnimReceiverDestroyed(QObject *o)
00255 {
00256     QMutableMapIterator<int, CustomAnimationState*> it(customAnims);
00257     while (it.hasNext()) {
00258         if (it.next().value()->receiver == o) {
00259             delete[] it.value()->slot;
00260             delete it.value();
00261             it.remove();
00262         }
00263     }
00264 }
00265 
00266 int Animator::animateItem(QGraphicsItem *item, Animation animation)
00267 {
00268      //kDebug();
00269     // get rid of any existing animations on this item.
00270     //TODO: shoudl we allow multiple anims per item?
00271     QMap<QGraphicsItem*, AnimationState*>::iterator it = d->animatedItems.find(item);
00272     if (it != d->animatedItems.end()) {
00273         delete it.value();
00274         d->animatedItems.erase(it);
00275     }
00276 
00277     int frames = d->driver->animationFps(animation);
00278 
00279     if (frames < 1) {
00280         // evidently this animator doesn't have an implementation
00281         // for this Animation
00282         return -1;
00283     }
00284 
00285     int duration = d->driver->animationDuration(animation);
00286 
00287     AnimationState *state = new AnimationState;
00288     state->id = ++d->animId;
00289     state->item = item;
00290     state->animation = animation;
00291     state->curve = d->driver->animationCurve(animation);
00292     state->frames = qMax(1.0, frames * (duration / 1000.0));
00293     state->currentFrame = 0;
00294     state->interval = d->driver->animationDuration(animation) / qreal(state->frames);
00295     state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
00296     state->currentInterval = state->interval;
00297     state->qobj = dynamic_cast<QObject*>(item);
00298 
00299     if (state->qobj) {
00300         //kDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!! got us an object!";
00301         disconnect(state->qobj, SIGNAL(destroyed(QObject*)),
00302                    this, SLOT(animatedItemDestroyed(QObject*)));
00303         connect(state->qobj, SIGNAL(destroyed(QObject*)),
00304                 this, SLOT(animatedItemDestroyed(QObject*)));
00305     }
00306 
00307     d->animatedItems[item] = state;
00308     d->performAnimation(0, state);
00309 
00310     if (!d->timerId) {
00311         d->timerId = startTimer(MIN_TICK_RATE);
00312         d->time.restart();
00313     }
00314 
00315     return state->id;
00316 }
00317 
00318 int Animator::moveItem(QGraphicsItem *item, Movement movement, const QPoint &destination)
00319 {
00320      //kDebug();
00321      QMap<QGraphicsItem*, MovementState*>::iterator it = d->movingItems.find(item);
00322      if (it != d->movingItems.end()) {
00323           delete it.value();
00324           d->movingItems.erase(it);
00325      }
00326 
00327      int frames = d->driver->movementAnimationFps(movement);
00328      if (frames <= 1) {
00329           // evidently this animator doesn't have an implementation
00330           // for this Animation
00331           return -1;
00332      }
00333 
00334      MovementState *state = new MovementState;
00335      state->id = ++d->animId;
00336      state->destination = destination;
00337      state->start = item->pos().toPoint();
00338      state->item = item;
00339      state->movement = movement;
00340      state->curve = d->driver->movementAnimationCurve(movement);
00341      //TODO: variance in times based on the value of animation
00342      int duration = d->driver->movementAnimationDuration(movement);
00343      state->frames = qMax(1.0, frames * (duration / 1000.0));
00344      state->currentFrame = 0;
00345      state->interval = duration / qreal(state->frames);
00346      state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
00347 //     state->interval = (state->interval / MIN_TICK_RATE) * MIN_TICK_RATE;
00348 //     kDebug() << "interval of" << state->interval << state->frames << duration << frames;
00349      state->currentInterval = state->interval;
00350      state->qobj = dynamic_cast<QObject*>(item);
00351 
00352      if (state->qobj) {
00353         disconnect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
00354         connect(state->qobj, SIGNAL(destroyed(QObject*)), this, SLOT(movingItemDestroyed(QObject*)));
00355      }
00356 
00357      d->movingItems[item] = state;
00358      d->performMovement(0, state);
00359 
00360      if (!d->timerId) {
00361           d->timerId = startTimer(MIN_TICK_RATE);
00362           d->time.restart();
00363      }
00364 
00365      return state->id;
00366 }
00367 
00368 int Animator::customAnimation(int frames, int duration, Animator::CurveShape curve,
00369                               QObject *receiver, const char *slot)
00370 {
00371     if (frames < 1 || duration < 1 || !receiver || !slot) {
00372         return -1;
00373     }
00374 
00375     CustomAnimationState *state = new CustomAnimationState;
00376     state->id = ++d->animId;
00377     state->frames = frames;
00378     state->currentFrame = 0;
00379     state->curve = curve;
00380     state->interval = duration / qreal(state->frames);
00381     state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
00382     state->currentInterval = state->interval;
00383     state->receiver = receiver;
00384     state->slot = qstrdup(slot);
00385 
00386     d->customAnims[state->id] = state;
00387 
00388     disconnect(receiver, SIGNAL(destroyed(QObject*)),
00389                this, SLOT(customAnimReceiverDestroyed(QObject*)));
00390     connect(receiver, SIGNAL(destroyed(QObject*)),
00391             this, SLOT(customAnimReceiverDestroyed(QObject*)));
00392 
00393     // try with only progress as argument
00394     if (!QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0))) {
00395         //try to pass also the animation id
00396         QMetaObject::invokeMethod(receiver, slot, Q_ARG(qreal, 0), Q_ARG(int, state->id));
00397     }
00398 
00399     if (!d->timerId) {
00400         d->timerId = startTimer(MIN_TICK_RATE);
00401         d->time.restart();
00402     }
00403 
00404     return state->id;
00405 }
00406 
00407 void Animator::stopCustomAnimation(int id)
00408 {
00409     QMap<int, CustomAnimationState*>::iterator it = d->customAnims.find(id);
00410     if (it != d->customAnims.end()) {
00411         delete [] it.value()->slot;
00412         delete it.value();
00413         d->customAnims.erase(it);
00414     }
00415     //kDebug() << "stopCustomAnimation(AnimId " << id << ") done";
00416 }
00417 
00418 void Animator::stopItemAnimation(int id)
00419 {
00420     QMutableMapIterator<QGraphicsItem*, AnimationState*> it(d->animatedItems);
00421     while (it.hasNext()) {
00422         it.next();
00423         if (it.value()->id == id) {
00424             delete it.value();
00425             it.remove();
00426             return;
00427         }
00428     }
00429 }
00430 
00431 void Animator::stopItemMovement(int id)
00432 {
00433     QMutableMapIterator<QGraphicsItem*, MovementState*> it(d->movingItems);
00434     while (it.hasNext()) {
00435         it.next();
00436         if (it.value()->id == id) {
00437             delete it.value();
00438             it.remove();
00439             return;
00440         }
00441     }
00442 }
00443 
00444 int Animator::animateElement(QGraphicsItem *item, Animation animation)
00445 {
00446     //kDebug() << "startElementAnimation(AnimId " << animation << ")";
00447     int frames = d->driver->elementAnimationFps(animation);
00448     int duration = d->driver->animationDuration(animation);
00449 
00450     ElementAnimationState *state = new ElementAnimationState;
00451     state->item = item;
00452     state->curve = d->driver->elementAnimationCurve(animation);
00453     state->animation = animation;
00454     state->frames = qMax(1.0, frames * (duration / 1000.0));
00455     state->currentFrame = 0;
00456     state->interval = duration / qreal(state->frames);
00457     state->interval = qMax(MIN_TICK_RATE_INT, state->interval - (state->interval % MIN_TICK_RATE_INT));
00458     state->currentInterval = state->interval;
00459     state->id = ++d->animId;
00460     state->qobj = dynamic_cast<QObject*>(item);
00461 
00462     if (state->qobj) {
00463         disconnect(state->qobj, SIGNAL(destroyed(QObject*)),
00464                    this, SLOT(animatedElementDestroyed(QObject*)));
00465         connect(state->qobj, SIGNAL(destroyed(QObject*)),
00466                 this, SLOT(animatedElementDestroyed(QObject*)));
00467     }
00468 
00469     //kDebug() << "animateElement " << animation << ", interval: "
00470     //         << state->interval << ", frames: " << state->frames;
00471     bool needTimer = true;
00472     if (state->frames < 1) {
00473         state->frames = 1;
00474         state->currentFrame = 1;
00475         needTimer = false;
00476     }
00477 
00478     d->animatedElements[state->id] = state;
00479 
00480     //kDebug() << "startElementAnimation(AnimId " << animation << ") returning " << state->id;
00481     if (needTimer && !d->timerId) {
00482         // start a 20fps timer;
00483         //TODO: should be started at the maximum frame rate needed only?
00484         d->timerId = startTimer(MIN_TICK_RATE);
00485         d->time.restart();
00486     }
00487     return state->id;
00488 }
00489 
00490 void Animator::stopElementAnimation(int id)
00491 {
00492     QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
00493     if (it != d->animatedElements.end()) {
00494         delete it.value();
00495         d->animatedElements.erase(it);
00496     }
00497     //kDebug() << "stopElementAnimation(AnimId " << id << ") done";
00498 }
00499 
00500 void Animator::setInitialPixmap(int id, const QPixmap &pixmap)
00501 {
00502     QMap<int, ElementAnimationState*>::iterator it = d->animatedElements.find(id);
00503 
00504     if (it == d->animatedElements.end()) {
00505         kDebug() << "No entry found for id " << id;
00506         return;
00507     }
00508 
00509     it.value()->pixmap = pixmap;
00510 }
00511 
00512 QPixmap Animator::currentPixmap(int id)
00513 {
00514     QMap<int, ElementAnimationState*>::const_iterator it = d->animatedElements.constFind(id);
00515 
00516     if (it == d->animatedElements.constEnd()) {
00517         //kDebug() << "Animator::currentPixmap(" << id << ") found no entry for it!";
00518         return QPixmap();
00519     }
00520 
00521     ElementAnimationState *state = it.value();
00522     qreal progress = d->calculateProgress(state->currentFrame * state->interval,
00523                                           state->frames *  state->interval,
00524                                           state->curve);
00525     //kDebug() << "Animator::currentPixmap(" << id <<   " at " << progress;
00526 
00527     switch (state->animation) {
00528         case AppearAnimation:
00529             return d->driver->elementAppear(progress, state->pixmap);
00530             break;
00531         case DisappearAnimation:
00532             return d->driver->elementDisappear(progress, state->pixmap);
00533             break;
00534         case ActivateAnimation:
00535             break;
00536     }
00537 
00538     return state->pixmap;
00539 }
00540 
00541 bool Animator::isAnimating() const
00542 {
00543     return (!d->animatedItems.isEmpty() ||
00544             !d->movingItems.isEmpty() ||
00545             !d->animatedElements.isEmpty() ||
00546             !d->customAnims.isEmpty());
00547 }
00548 
00549 void Animator::timerEvent(QTimerEvent *event)
00550 {
00551     Q_UNUSED(event)
00552     bool animationsRemain = false;
00553     int elapsed = MIN_TICK_RATE;
00554     if (d->time.elapsed() > elapsed) {
00555         elapsed = d->time.elapsed();
00556     }
00557     d->time.restart();
00558     //kDebug() << "timeEvent, elapsed time: " << elapsed;
00559 
00560     foreach (AnimationState *state, d->animatedItems) {
00561         if (state->currentInterval <= elapsed) {
00562             // we need to step forward!
00563             state->currentFrame +=
00564                 (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
00565                 qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
00566 
00567             if (state->currentFrame < state->frames) {
00568                 qreal progress = d->calculateProgress(state->currentFrame * state->interval,
00569                                                       state->frames *  state->interval,
00570                                                       state->curve);
00571                 d->performAnimation(progress, state);
00572                 state->currentInterval = state->interval;
00573                 animationsRemain = true;
00574             } else {
00575                 d->performAnimation(1, state);
00576                 d->animatedItems.erase(d->animatedItems.find(state->item));
00577                 emit animationFinished(state->item, state->animation);
00578                 delete state;
00579             }
00580         } else {
00581             state->currentInterval -= elapsed;
00582             animationsRemain = true;
00583         }
00584     }
00585 
00586     foreach (MovementState *state, d->movingItems) {
00587         if (state->currentInterval <= elapsed) {
00588             // we need to step forward!
00589             state->currentFrame +=
00590                 (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
00591                 qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
00592 
00593             if (state->currentFrame < state->frames) {
00594                 //kDebug() << "movement";
00595                 qreal progress = d->calculateProgress(state->currentFrame * state->interval,
00596                                                       state->frames *  state->interval,
00597                                                       state->curve);
00598                 d->performMovement(progress, state);
00599                 animationsRemain = true;
00600             } else {
00601                 //kDebug() << "movement";
00602                 d->performMovement(1, state);
00603                 d->movingItems.erase(d->movingItems.find(state->item));
00604                 emit movementFinished(state->item);
00605                 delete state;
00606             }
00607         } else {
00608             state->currentInterval -= elapsed;
00609             animationsRemain = true;
00610         }
00611     }
00612 
00613     foreach (ElementAnimationState *state, d->animatedElements) {
00614         if (state->currentFrame == state->frames) {
00615             //kDebug() << "skipping" << state->id << "as its already at frame"
00616             //         << state->currentFrame << "of" << state->frames;
00617             // since we keep element animations around until they are
00618             // removed, we will end up with finished animations in the queue;
00619             // just skip them
00620             //TODO: should we move them to a separate QMap?
00621             continue;
00622         }
00623 
00624         if (state->currentInterval <= elapsed) {
00625             // we need to step forward!
00626             /*kDebug() << "stepping forwards element anim " << state->id
00627                        << " from " << state->currentFrame
00628                        << " by " << qMax(1, elapsed / state->interval) << " to "
00629                        << state->currentFrame + qMax(1, elapsed / state->interval) << endl;*/
00630             state->currentFrame +=
00631                 (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
00632                 qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
00633 
00634             state->item->update();
00635             if (state->currentFrame < state->frames) {
00636                 state->currentInterval = state->interval;
00637                 animationsRemain = true;
00638             } else {
00639                 d->animatedElements.remove(state->id);
00640                 emit elementAnimationFinished(state->id);
00641                 delete state;
00642             }
00643         } else {
00644             state->currentInterval -= elapsed;
00645             animationsRemain = true;
00646         }
00647     }
00648 
00649     foreach (CustomAnimationState *state, d->customAnims) {
00650         if (state->currentInterval <= elapsed) {
00651             // advance the frame
00652             state->currentFrame +=
00653                 (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ?
00654                 qMax(1, elapsed / state->interval) : state->frames - state->currentFrame;
00655             /*kDebug() << "custom anim for" << state->receiver
00656                        << "to slot" << state->slot
00657                        << "with interval of" << state->interval
00658                        << "at frame" << state->currentFrame;*/
00659 
00660             if (state->currentFrame < state->frames) {
00661                 //kDebug () << "not the final frame";
00662                 //TODO: calculate a proper interval based on the curve
00663                 state->currentInterval = state->interval;
00664                 animationsRemain = true;
00665                 // signal the object
00666                 // try with only progress as argument
00667                 qreal progress = d->calculateProgress(state->currentFrame * state->interval,
00668                                                       state->frames *  state->interval,
00669                                                       state->curve);
00670                 if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress))) {
00671                 //if fails try to add the animation id
00672                     QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, progress),
00673                                               Q_ARG(int, state->id));
00674                 }
00675             } else {
00676                 if (!QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1))) {
00677                     QMetaObject::invokeMethod(state->receiver, state->slot, Q_ARG(qreal, 1), Q_ARG(int, state->id));
00678                 }
00679                 d->customAnims.erase(d->customAnims.find(state->id));
00680                 emit customAnimationFinished(state->id);
00681                 delete [] state->slot;
00682                 delete state;
00683             }
00684         } else {
00685             state->currentInterval -= elapsed;
00686             animationsRemain = true;
00687         }
00688     }
00689 
00690     if (!animationsRemain && d->timerId) {
00691         killTimer(d->timerId);
00692         d->timerId = 0;
00693     }
00694 }
00695 
00696 void AnimatorPrivate::init(Animator *q)
00697 {
00698     //FIXME: usage between different applications?
00699     KConfig c("plasmarc");
00700     KConfigGroup cg(&c, "Animator");
00701     QString pluginName = cg.readEntry("driver", "default");
00702 
00703     if (!pluginName.isEmpty()) {
00704         QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(pluginName);
00705         KService::List offers = KServiceTypeTrader::self()->query("Plasma/Animator", constraint);
00706 
00707         if (!offers.isEmpty()) {
00708             QString error;
00709 
00710             KPluginLoader plugin(*offers.first());
00711 
00712             if (Plasma::isPluginVersionCompatible(plugin.pluginVersion())) {
00713                 driver = offers.first()->createInstance<Plasma::AnimationDriver>(q, QVariantList(), &error);
00714             }
00715 
00716             if (!driver) {
00717                 kDebug() << "Could not load requested animator "
00718                          << offers.first() << ". Error given: " << error;
00719             }
00720         }
00721     }
00722 
00723     if (!driver) {
00724         driver = new AnimationDriver(q);
00725     }
00726 }
00727 
00728 } // namespace Plasma
00729 
00730 #include <animator.moc>

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal