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 if (sequence().isEmpty()) { 00063 return; 00064 } 00065 ++m_counter; 00066 m_counter %= sequence().frameCount(); 00067 if (m_widget) 00068 m_widget->update(pixmapRect()); 00069 } 00070 00071 00072 void KPixmapSequenceOverlayPainter::Private::paintFrame() 00073 { 00074 if (m_counter >= sequence().frameCount()) { 00075 return; 00076 } 00077 QPainter p(m_widget); 00078 p.drawPixmap(pixmapRect(), sequence().frameAt(m_counter), QRect(QPoint(0, 0), sequence().frameSize())); 00079 } 00080 00081 00082 KPixmapSequence& KPixmapSequenceOverlayPainter::Private::sequence() 00083 { 00084 // make sure we have a valid default sequence 00085 if(m_sequence.isEmpty()) 00086 m_sequence = KPixmapSequence("process-working", 22); 00087 00088 return m_sequence; 00089 } 00090 00091 00092 QRect KPixmapSequenceOverlayPainter::Private::pixmapRect() 00093 { 00094 QRect rect(m_rect); 00095 if(!rect.isValid()) 00096 rect = m_widget->rect(); 00097 00098 QPoint pos(rect.topLeft()); 00099 if (m_alignment & Qt::AlignHCenter) 00100 pos.setX(rect.center().x() - (sequence().frameSize().width() / 2)); 00101 else if (m_alignment & Qt::AlignRight) 00102 pos.setX(rect.right() - sequence().frameSize().width()); 00103 00104 if (m_alignment & Qt::AlignVCenter) 00105 pos.setY(rect.center().y() - (sequence().frameSize().height() / 2)); 00106 else if (m_alignment & Qt::AlignBottom) 00107 pos.setY(rect.bottom() - sequence().frameSize().height()); 00108 00109 pos += m_offset; 00110 00111 return QRect( pos, sequence().frameSize()); 00112 } 00113 00114 00115 KPixmapSequenceOverlayPainter::KPixmapSequenceOverlayPainter(QObject *parent) 00116 : QObject(parent), 00117 d(new Private) 00118 { 00119 d->q = this; 00120 d->m_widget = 0; 00121 d->m_alignment = Qt::AlignCenter; 00122 d->m_started = false; 00123 setInterval(200); 00124 connect(&d->m_timer, SIGNAL(timeout()), this, SLOT(_k_timeout())); 00125 } 00126 00127 00128 KPixmapSequenceOverlayPainter::~KPixmapSequenceOverlayPainter() 00129 { 00130 stop(); 00131 delete d; 00132 } 00133 00134 00135 KPixmapSequence KPixmapSequenceOverlayPainter::sequence() const 00136 { 00137 return d->sequence(); 00138 } 00139 00140 00141 int KPixmapSequenceOverlayPainter::interval() const 00142 { 00143 return d->m_timer.interval(); 00144 } 00145 00146 00147 QRect KPixmapSequenceOverlayPainter::rect() const 00148 { 00149 if(d->m_rect.isValid()) { 00150 return d->m_rect; 00151 } 00152 else if(d->m_widget) { 00153 return d->m_widget->rect(); 00154 } 00155 else { 00156 return QRect(); 00157 } 00158 } 00159 00160 00161 Qt::Alignment KPixmapSequenceOverlayPainter::alignment() const 00162 { 00163 return d->m_alignment; 00164 } 00165 00166 00167 QPoint KPixmapSequenceOverlayPainter::offset() const 00168 { 00169 return d->m_offset; 00170 } 00171 00172 00173 void KPixmapSequenceOverlayPainter::setSequence(const KPixmapSequence &seq) 00174 { 00175 bool restart = d->m_started; 00176 stop(); 00177 d->m_sequence = seq; 00178 if(restart) start(); 00179 } 00180 00181 00182 void KPixmapSequenceOverlayPainter::setInterval(int msecs) 00183 { 00184 d->m_timer.setInterval(msecs); 00185 } 00186 00187 00188 void KPixmapSequenceOverlayPainter::setWidget(QWidget *w) 00189 { 00190 stop(); 00191 d->m_widget = w; 00192 } 00193 00194 00195 void KPixmapSequenceOverlayPainter::setRect(const QRect &rect) 00196 { 00197 bool restart = d->m_started; 00198 stop(); 00199 d->m_rect = rect; 00200 if(restart) start(); 00201 } 00202 00203 00204 void KPixmapSequenceOverlayPainter::setAlignment(Qt::Alignment align) 00205 { 00206 bool restart = d->m_started; 00207 stop(); 00208 d->m_alignment = align; 00209 if(restart) start(); 00210 } 00211 00212 00213 void KPixmapSequenceOverlayPainter::setOffset(const QPoint &offset) 00214 { 00215 bool restart = d->m_started; 00216 stop(); 00217 d->m_offset = offset; 00218 if(restart) start(); 00219 } 00220 00221 00222 void KPixmapSequenceOverlayPainter::start() 00223 { 00224 if (d->m_widget) { 00225 stop(); 00226 00227 d->m_counter = 0; 00228 d->m_started = true; 00229 d->m_widget->installEventFilter(this); 00230 if(d->m_widget->isVisible()) { 00231 d->m_timer.start(); 00232 d->m_widget->update(d->pixmapRect()); 00233 } 00234 } 00235 } 00236 00237 00238 void KPixmapSequenceOverlayPainter::stop() 00239 { 00240 d->m_timer.stop(); 00241 if (d->m_widget) { 00242 d->m_started = false; 00243 d->m_widget->removeEventFilter(this); 00244 d->m_widget->update(d->pixmapRect()); 00245 } 00246 } 00247 00248 00249 bool KPixmapSequenceOverlayPainter::eventFilter(QObject *obj, QEvent *event) 00250 { 00251 if (obj == d->m_widget ) { 00252 switch (event->type()) { 00253 case QEvent::Paint: 00254 // make sure we paint after everyone else including other event filters 00255 obj->removeEventFilter(this); // don't recurse... 00256 QCoreApplication::sendEvent(obj, event); 00257 d->paintFrame(); 00258 obj->installEventFilter(this); // catch on... 00259 return true; 00260 break; 00261 case QEvent::Hide: 00262 d->m_timer.stop(); 00263 break; 00264 case QEvent::Show: 00265 if(d->m_started) { 00266 d->m_timer.start(); 00267 d->m_widget->update(d->pixmapRect()); 00268 } 00269 break; 00270 default: 00271 break; 00272 } 00273 } 00274 00275 return false; 00276 } 00277 00278 #include "kpixmapsequenceoverlaypainter.moc"
KDE 4.7 API Reference