#ifndef KVI_ANIMATEDPIXMAP_H_ #define KVI_ANIMATEDPIXMAP_H_ //============================================================================= // // File : KviAnimatedPixmap.h // Creation date : Wed Jul 30 2008 01:45:21 CEST by Alexey Uzhva // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2008 Alexey Uzhva (wizard at opendoor dot ru) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, 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 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 "kvi_settings.h" #include "KviAnimatedPixmapCache.h" #include #include #include class QPixmap; /** * This class should not be here, because we already have QMovie * with the same functionality. * * But QMovie is really stupid, bacause: * 1) It does not support infinitive animation. * It relies on image metadata to determine loop count. So most of pics will * be played only once. * * 2) It duplicates QPixmap while we calls currentFrame(), that's a very * big overload for us. * * 3) If we try to scale QMovie by using built-in scale mechanism, it will * manually scale each frame each time, we will call currentFrame(). * So if we plan to play movie 10,100,1000 times, it will scale image * 10,100,1000 times too:( * * 4) KviAnimatedPixmap uses internal cache mechanism with KviAnimatedPixmapCache class. * It's managed inside KviAnimatedPixmap and KviAnimatedPixmapCache. No other actions * needed to perform caching. * * So... Here is my workaround. It's working in this way: * You should create new pixmap with constructor KviAnimatedPixmap(QString fileName). * It will automagically look at cache and use it, if possible. * * KviAnimatedPixmap stores animation as a set of QPixmap's, and delays. * when started (see start()) it emits frameChanged() events at the frame change. * * You should use pixmap() methd to access the current frame. * * This class owns all pixmaps. Do not store links to them. */ class KVILIB_API KviAnimatedPixmap : public QObject, public KviAnimatedPixmapInterface { Q_OBJECT protected: QString m_szFileName; KviAnimatedPixmapCache::Data * m_pFrameData; uint m_uCurrentFrameNumber; int m_iStarted; public: /* * Creates KviAnimatedPixmap, and loads data from "fileName". */ KviAnimatedPixmap(QString fileName, int iWidth = 0, int iHeight = 0); virtual ~KviAnimatedPixmap(); /* * Creates new pixmap using "source" as source of images. */ KviAnimatedPixmap(const KviAnimatedPixmap & source); /* * Returns true if animation is started. * Returns false otherways. */ bool isStarted() const { return m_iStarted > 0; } /* * Starts the animation */ void start(); /* * Stops the animation */ void stop(); /* * Returns true if animation has at least one loaded frame. * Returns false otherways. */ bool isValid() const { return (m_pFrameData->count() > 0); } /* * Returns active frame's pixmap. * Never fails. */ QPixmap * pixmap() { if(m_pFrameData->count() > 0) return m_pFrameData->at(m_uCurrentFrameNumber).pixmap; else return KviAnimatedPixmapCache::dummyPixmap(); } /* * Returns active frame number */ uint activeFrameNumber() const { return m_uCurrentFrameNumber; } /* * Returns animation frame count */ uint framesCount() const { return m_pFrameData->count(); } /* * Returns current image size */ const QSize & size() const { return m_pFrameData->size; } /* * Resizes all frames to the newSize size, using "ratioMode" * ratio. */ void resize(QSize newSize, Qt::AspectRatioMode ratioMode); /* * Called when the frame changes */ void nextFrame(bool bEmitSignalAndScheduleNext); signals: /* * Slot, to be connected to m_animationTimer, to receive animation * frame changes. */ void frameChanged(); }; #endif /* KVI_ANIMATEDPIXMAP_H_ */