KDEUI
kanimatedbutton.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <kanimatedbutton.h>
00022
00023 #include <QAction>
00024 #include <QPixmap>
00025 #include <QTimer>
00026 #include <QImage>
00027 #include <QToolBar>
00028 #include <QPainter>
00029 #include <QMovie>
00030
00031 #include <kdebug.h>
00032 #include <kiconloader.h>
00033
00034 class KAnimatedButtonPrivate
00035 {
00036 public:
00037 KAnimatedButtonPrivate(KAnimatedButton *qq)
00038 : q(qq), movie(0)
00039 {
00040 }
00041
00042 void updateCurrentIcon();
00043 void _k_movieFrameChanged(int number);
00044 void _k_movieFinished();
00045
00046 KAnimatedButton *q;
00047 QMovie *movie;
00048
00049 int frames;
00050 int current_frame;
00051 QPixmap pixmap;
00052 QTimer timer;
00053 QString icon_name;
00054 QVector<QPixmap*> framesCache;
00055
00056
00057 };
00058
00059 KAnimatedButton::KAnimatedButton( QWidget *parent )
00060 : QToolButton(parent), d(new KAnimatedButtonPrivate(this))
00061 {
00062 connect( &d->timer, SIGNAL(timeout()), this, SLOT(slotTimerUpdate()));
00063 }
00064
00065 KAnimatedButton::~KAnimatedButton()
00066 {
00067 d->timer.stop();
00068 qDeleteAll(d->framesCache);
00069 delete d->movie;
00070
00071 delete d;
00072 }
00073
00074 void KAnimatedButton::start()
00075 {
00076 if (d->movie) {
00077 d->movie->start();
00078 } else {
00079 d->current_frame = 0;
00080 d->timer.start(50);
00081 }
00082 }
00083
00084 void KAnimatedButton::stop()
00085 {
00086 if (d->movie) {
00087 d->movie->stop();
00088 d->movie->jumpToFrame(0);
00089 d->_k_movieFrameChanged(0);
00090 } else {
00091 d->current_frame = 0;
00092 d->timer.stop();
00093 d->updateCurrentIcon();
00094 }
00095 }
00096
00097 void KAnimatedButton::setIcons( const QString& icons )
00098 {
00099 if ( d->icon_name == icons )
00100 return;
00101
00102 d->timer.stop();
00103 d->icon_name = icons;
00104 updateIcons();
00105 }
00106
00107 QString KAnimatedButton::icons( ) const
00108 {
00109 return d->icon_name;
00110 }
00111
00112 void KAnimatedButton::slotTimerUpdate()
00113 {
00114 if(!isVisible())
00115 return;
00116
00117 d->current_frame++;
00118 if (d->current_frame == d->frames)
00119 d->current_frame = 0;
00120
00121 d->updateCurrentIcon();
00122 }
00123
00124 void KAnimatedButtonPrivate::updateCurrentIcon()
00125 {
00126 if (pixmap.isNull())
00127 return;
00128
00129 QPixmap* frame = framesCache[current_frame];
00130 if (!frame)
00131 {
00132 const int icon_size = q->iconDimensions();
00133 const int row_size = pixmap.width() / icon_size;
00134 const int row = current_frame / row_size;
00135 const int column = current_frame % row_size;
00136 frame = new QPixmap(icon_size, icon_size);
00137 frame->fill(Qt::transparent);
00138 QPainter p(frame);
00139 p.drawPixmap(QPoint(0, 0), pixmap, QRect(column * icon_size, row * icon_size, icon_size, icon_size));
00140 p.end();
00141 framesCache[current_frame] = frame;
00142 }
00143
00144 q->setIcon(QIcon(*frame));
00145 }
00146
00147 void KAnimatedButtonPrivate::_k_movieFrameChanged(int number)
00148 {
00149 Q_UNUSED(number);
00150 q->setIcon(QIcon(movie->currentPixmap()));
00151 }
00152
00153 void KAnimatedButtonPrivate::_k_movieFinished()
00154 {
00155
00156 if (movie->state() == QMovie::NotRunning) {
00157 movie->start();
00158 }
00159 }
00160
00161 void KAnimatedButton::updateIcons()
00162 {
00163 const int icon_size = iconDimensions();
00164 d->pixmap = QPixmap();
00165 QMovie *movie = KIconLoader::global()->loadMovie(d->icon_name, KIconLoader::NoGroup, -icon_size);
00166 if (movie) {
00167 d->frames = 0;
00168 movie->setCacheMode(QMovie::CacheAll);
00169 connect(movie, SIGNAL(frameChanged(int)), this, SLOT(_k_movieFrameChanged(int)));
00170 connect(movie, SIGNAL(finished()), this, SLOT(_k_movieFinished()));
00171 } else {
00172 const QString path = KIconLoader::global()->iconPath(d->icon_name, -icon_size);
00173 QImage img(path);
00174 if (img.isNull())
00175 return;
00176
00177 if ((img.width() % icon_size != 0) || (img.height() % icon_size != 0))
00178 return;
00179
00180 d->frames = (img.height() / icon_size) * (img.width() / icon_size);
00181 d->pixmap = QPixmap::fromImage(img);
00182 }
00183
00184 d->current_frame = 0;
00185 qDeleteAll(d->framesCache);
00186 d->framesCache.fill(0);
00187 d->framesCache.resize(d->frames);
00188 delete d->movie;
00189 d->movie = movie;
00190
00191 if (d->movie) {
00192 d->movie->jumpToFrame(0);
00193 d->_k_movieFrameChanged(0);
00194 } else {
00195 d->updateCurrentIcon();
00196 }
00197 }
00198
00199 int KAnimatedButton::iconDimensions() const
00200 {
00201 return qMin(iconSize().width(), iconSize().height());
00202 }
00203
00204 #include "kanimatedbutton.moc"