KDEUI
kpixmapsequenceoverlaypainter.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2009 Sebastian Trueg <trueg@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2.1 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kpixmapsequenceoverlaypainter.h" 00021 #include "kpixmapsequence.h" 00022 00023 #include <QtGui/QWidget> 00024 #include <QtCore/QPoint> 00025 #include <QtCore/QRect> 00026 #include <QtGui/QPainter> 00027 #include <QtCore/QTimer> 00028 #include <QtCore/QEvent> 00029 #include <QtCore/QPointer> 00030 #include <QtCore/QCoreApplication> 00031 00032 #include <kdebug.h> 00033 00034 00035 class KPixmapSequenceOverlayPainter::Private 00036 { 00037 public: 00038 void _k_timeout(); 00039 void paintFrame(); 00040 00041 KPixmapSequence& sequence(); 00042 00043 QRect pixmapRect(); 00044 00045 KPixmapSequence m_sequence; 00046 QPointer<QWidget> m_widget; 00047 Qt::Alignment m_alignment; 00048 QPoint m_offset; 00049 QRect m_rect; 00050 00051 QTimer m_timer; 00052 int m_counter; 00053 00054 bool m_started; 00055 00056 KPixmapSequenceOverlayPainter *q; 00057 }; 00058 00059 00060 void KPixmapSequenceOverlayPainter::Private::_k_timeout() 00061 { 00062 ++m_counter; 00063 m_counter %= sequence().frameCount(); 00064 if (m_widget) 00065 m_widget->update(pixmapRect()); 00066 } 00067 00068 00069 void KPixmapSequenceOverlayPainter::Private::paintFrame() 00070 { 00071 QPainter p(m_widget); 00072 p.drawPixmap(pixmapRect(), sequence().frameAt(m_counter), QRect(QPoint(0, 0), sequence().frameSize())); 00073 } 00074 00075 00076 KPixmapSequence& KPixmapSequenceOverlayPainter::Private::sequence() 00077 { 00078 // make sure we have a valid default sequence 00079 if(m_sequence.isEmpty()) 00080 m_sequence = KPixmapSequence("process-working", 22); 00081 00082 return m_sequence; 00083 } 00084 00085 00086 QRect KPixmapSequenceOverlayPainter::Private::pixmapRect() 00087 { 00088 QRect rect(m_rect); 00089 if(!rect.isValid()) 00090 rect = m_widget->rect(); 00091 00092 QPoint pos(rect.topLeft()); 00093 if (m_alignment & Qt::AlignHCenter) 00094 pos.setX(rect.center().x() - (sequence().frameSize().width() / 2)); 00095 else if (m_alignment & Qt::AlignRight) 00096 pos.setX(rect.right() - sequence().frameSize().width()); 00097 00098 if (m_alignment & Qt::AlignVCenter) 00099 pos.setY(rect.center().y() - (sequence().frameSize().height() / 2)); 00100 else if (m_alignment & Qt::AlignBottom) 00101 pos.setY(rect.bottom() - sequence().frameSize().height()); 00102 00103 pos += m_offset; 00104 00105 return QRect( pos, sequence().frameSize()); 00106 } 00107 00108 00109 KPixmapSequenceOverlayPainter::KPixmapSequenceOverlayPainter(QObject *parent) 00110 : QObject(parent), 00111 d(new Private) 00112 { 00113 d->q = this; 00114 d->m_widget = 0; 00115 d->m_alignment = Qt::AlignCenter; 00116 d->m_started = false; 00117 setInterval(200); 00118 connect(&d->m_timer, SIGNAL(timeout()), this, SLOT(_k_timeout())); 00119 } 00120 00121 00122 KPixmapSequenceOverlayPainter::~KPixmapSequenceOverlayPainter() 00123 { 00124 stop(); 00125 delete d; 00126 } 00127 00128 00129 KPixmapSequence KPixmapSequenceOverlayPainter::sequence() const 00130 { 00131 return d->sequence(); 00132 } 00133 00134 00135 int KPixmapSequenceOverlayPainter::interval() const 00136 { 00137 return d->m_timer.interval(); 00138 } 00139 00140 00141 QRect KPixmapSequenceOverlayPainter::rect() const 00142 { 00143 if(d->m_rect.isValid()) { 00144 return d->m_rect; 00145 } 00146 else if(d->m_widget) { 00147 return d->m_widget->rect(); 00148 } 00149 else { 00150 return QRect(); 00151 } 00152 } 00153 00154 00155 Qt::Alignment KPixmapSequenceOverlayPainter::alignment() const 00156 { 00157 return d->m_alignment; 00158 } 00159 00160 00161 QPoint KPixmapSequenceOverlayPainter::offset() const 00162 { 00163 return d->m_offset; 00164 } 00165 00166 00167 void KPixmapSequenceOverlayPainter::setSequence(const KPixmapSequence &seq) 00168 { 00169 bool restart = d->m_started; 00170 stop(); 00171 d->m_sequence = seq; 00172 if(restart) start(); 00173 } 00174 00175 00176 void KPixmapSequenceOverlayPainter::setInterval(int msecs) 00177 { 00178 d->m_timer.setInterval(msecs); 00179 } 00180 00181 00182 void KPixmapSequenceOverlayPainter::setWidget(QWidget *w) 00183 { 00184 stop(); 00185 d->m_widget = w; 00186 } 00187 00188 00189 void KPixmapSequenceOverlayPainter::setRect(const QRect &rect) 00190 { 00191 bool restart = d->m_started; 00192 stop(); 00193 d->m_rect = rect; 00194 if(restart) start(); 00195 } 00196 00197 00198 void KPixmapSequenceOverlayPainter::setAlignment(Qt::Alignment align) 00199 { 00200 bool restart = d->m_started; 00201 stop(); 00202 d->m_alignment = align; 00203 if(restart) start(); 00204 } 00205 00206 00207 void KPixmapSequenceOverlayPainter::setOffset(const QPoint &offset) 00208 { 00209 bool restart = d->m_started; 00210 stop(); 00211 d->m_offset = offset; 00212 if(restart) start(); 00213 } 00214 00215 00216 void KPixmapSequenceOverlayPainter::start() 00217 { 00218 if (d->m_widget) { 00219 stop(); 00220 00221 d->m_counter = 0; 00222 d->m_started = true; 00223 d->m_widget->installEventFilter(this); 00224 if(d->m_widget->isVisible()) { 00225 d->m_timer.start(); 00226 d->m_widget->update(d->pixmapRect()); 00227 } 00228 } 00229 } 00230 00231 00232 void KPixmapSequenceOverlayPainter::stop() 00233 { 00234 d->m_timer.stop(); 00235 if (d->m_widget) { 00236 d->m_started = false; 00237 d->m_widget->removeEventFilter(this); 00238 d->m_widget->update(d->pixmapRect()); 00239 } 00240 } 00241 00242 00243 bool KPixmapSequenceOverlayPainter::eventFilter(QObject *obj, QEvent *event) 00244 { 00245 if (obj == d->m_widget ) { 00246 switch (event->type()) { 00247 case QEvent::Paint: 00248 // make sure we paint after everyone else including other event filters 00249 obj->removeEventFilter(this); // don't recurse... 00250 QCoreApplication::sendEvent(obj, event); 00251 d->paintFrame(); 00252 obj->installEventFilter(this); // catch on... 00253 return true; 00254 break; 00255 case QEvent::Hide: 00256 d->m_timer.stop(); 00257 break; 00258 case QEvent::Show: 00259 if(d->m_started) { 00260 d->m_timer.start(); 00261 d->m_widget->update(d->pixmapRect()); 00262 } 00263 break; 00264 default: 00265 break; 00266 } 00267 } 00268 00269 return false; 00270 } 00271 00272 #include "kpixmapsequenceoverlaypainter.moc"
KDE 4.6 API Reference