Plasma
flashinglabel.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2007 by André Duffeck <duffeck@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 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 Stre 00019 * et, Fifth Floor, Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "flashinglabel.h" 00023 00024 #include <QtCore/QString> 00025 #include <QtCore/QTimeLine> 00026 #include <QtCore/QTimer> 00027 #include <QtCore/QWeakPointer> 00028 #include <QtGui/QPainter> 00029 #include <QtGui/QPixmap> 00030 #include <QtGui/QColor> 00031 00032 #include <kdebug.h> 00033 00034 #include <plasma/animator.h> 00035 #include <plasma/animations/animation.h> 00036 #include <plasma/theme.h> 00037 00038 using namespace Plasma; 00039 00040 class Plasma::FlashingLabelPrivate 00041 { 00042 public: 00043 enum FlashingLabelType { 00044 Text, 00045 Pixmap 00046 }; 00047 enum State { 00048 Visible, 00049 Invisible 00050 }; 00051 00052 FlashingLabelPrivate(FlashingLabel *flash) 00053 : q(flash), 00054 defaultDuration(3000), 00055 type(FlashingLabelPrivate::Text), 00056 color(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor)), 00057 state(FlashingLabelPrivate::Invisible), 00058 autohide(false) 00059 { 00060 fadeOutTimer.setInterval(defaultDuration); 00061 fadeOutTimer.setSingleShot(true); 00062 fadeInTimer.setInterval(0); 00063 fadeInTimer.setSingleShot(true); 00064 QObject::connect(Theme::defaultTheme(), SIGNAL(themeChanged()), q, SLOT(setPalette())); 00065 } 00066 00067 ~FlashingLabelPrivate() { } 00068 00069 void renderPixmap(const QSize &size); 00070 void setupFlash(int duration); 00071 void elementAnimationFinished(); 00072 void setPalette(); 00073 00074 FlashingLabel *q; 00075 int defaultDuration; 00076 FlashingLabelType type; 00077 QTimer fadeInTimer; 00078 QTimer fadeOutTimer; 00079 QString text; 00080 QColor color; 00081 QFont font; 00082 QPixmap pixmap; 00083 00084 QWeakPointer<Plasma::Animation> anim; 00085 QPixmap renderedPixmap; 00086 00087 QTextOption textOption; 00088 Qt::Alignment alignment; 00089 00090 State state; 00091 bool autohide; 00092 }; 00093 00094 FlashingLabel::FlashingLabel(QGraphicsItem *parent) 00095 : QGraphicsWidget(parent), 00096 d(new FlashingLabelPrivate(this)) 00097 { 00098 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); 00099 setCacheMode(NoCache); 00100 connect(&d->fadeOutTimer, SIGNAL(timeout()), this, SLOT(fadeOut())); 00101 connect(&d->fadeInTimer, SIGNAL(timeout()), this, SLOT(fadeIn())); 00102 } 00103 00104 FlashingLabel::~FlashingLabel() 00105 { 00106 delete d; 00107 } 00108 00109 int FlashingLabel::duration() const 00110 { 00111 return d->defaultDuration; 00112 } 00113 00114 void FlashingLabel::setDuration(int duration) 00115 { 00116 if (duration < 1) { 00117 return; 00118 } 00119 00120 d->defaultDuration = duration; 00121 } 00122 00123 QColor FlashingLabel::color() const 00124 { 00125 return d->color; 00126 } 00127 00128 void FlashingLabel::setColor(const QColor &color) 00129 { 00130 d->color = color; 00131 } 00132 00133 QFont FlashingLabel::font() const 00134 { 00135 return d->font; 00136 } 00137 00138 void FlashingLabel::setFont(const QFont &font) 00139 { 00140 d->font = font; 00141 } 00142 00143 void FlashingLabel::flash(const QString &text, int duration, const QTextOption &option) 00144 { 00145 if (text.isEmpty()) { 00146 return; 00147 } 00148 00149 //kDebug() << duration << text; 00150 d->type = FlashingLabelPrivate::Text; 00151 d->text = text; 00152 d->textOption = option; 00153 d->setupFlash(duration); 00154 } 00155 00156 void FlashingLabel::flash(const QPixmap &pixmap, int duration, Qt::Alignment align) 00157 { 00158 if (pixmap.isNull()) { 00159 return; 00160 } 00161 00162 d->type = FlashingLabelPrivate::Pixmap; 00163 d->pixmap = pixmap; 00164 d->alignment = align; 00165 d->setupFlash(duration); 00166 } 00167 00168 void FlashingLabel::setAutohide(bool autohide) 00169 { 00170 d->autohide = autohide; 00171 00172 if (autohide) { 00173 if (d->anim.data()) { 00174 connect(d->anim.data(), SIGNAL(finished()), this, SLOT(elementAnimationFinished())); 00175 } 00176 } else if (d->anim.data()) { 00177 disconnect(d->anim.data(), SIGNAL(finished()), this, SLOT(elementAnimationFinished())); 00178 } 00179 } 00180 00181 bool FlashingLabel::autohide() const 00182 { 00183 return d->autohide; 00184 } 00185 00186 void FlashingLabel::kill() 00187 { 00188 d->fadeInTimer.stop(); 00189 if (d->state == FlashingLabelPrivate::Visible) { 00190 fadeOut(); 00191 } 00192 } 00193 00194 void FlashingLabel::fadeIn() 00195 { 00196 //kDebug(); 00197 if (d->autohide) { 00198 show(); 00199 } 00200 00201 d->state = FlashingLabelPrivate::Visible; 00202 if (!d->anim.data()) { 00203 d->anim = Plasma::Animator::create(Plasma::Animator::PixmapTransitionAnimation); 00204 Plasma::Animation *animation = d->anim.data(); 00205 animation->setProperty("startPixmap", d->renderedPixmap); 00206 animation->setTargetWidget(this); 00207 animation->start(); 00208 } else { 00209 Plasma::Animation *animation = d->anim.data(); 00210 if (animation->state() == QAbstractAnimation::Running) { 00211 animation->stop(); 00212 animation->start(); 00213 } 00214 } 00215 } 00216 00217 void FlashingLabel::fadeOut() 00218 { 00219 if (d->state == FlashingLabelPrivate::Invisible) { 00220 return; // FlashingLabel was already killed - do not animate again 00221 } 00222 00223 d->state = FlashingLabelPrivate::Invisible; 00224 if (d->anim.data()) { 00225 Plasma::Animation *animation = d->anim.data(); 00226 animation->setProperty("direction", QAbstractAnimation::Backward); 00227 animation->start(QAbstractAnimation::DeleteWhenStopped); 00228 } else { 00229 d->anim = Plasma::Animator::create(Plasma::Animator::PixmapTransitionAnimation); 00230 Plasma::Animation *animation = d->anim.data(); 00231 animation->setProperty("direction", QAbstractAnimation::Backward); 00232 animation->setProperty("startPixmap", d->renderedPixmap); 00233 animation->setTargetWidget(this); 00234 animation->start(QAbstractAnimation::DeleteWhenStopped); 00235 } 00236 } 00237 00238 void FlashingLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 00239 { 00240 Q_UNUSED(option) 00241 Q_UNUSED(widget) 00242 00243 if (d->anim.data() && d->anim.data()->state() == QAbstractAnimation::Running) { 00244 Plasma::Animation *animation = d->anim.data(); 00245 painter->drawPixmap(0, 0, qvariant_cast<QPixmap>(animation->property("currentPixmap"))); 00246 } else if (d->state == FlashingLabelPrivate::Visible) { 00247 painter->drawPixmap(0, 0, d->renderedPixmap); 00248 } 00249 } 00250 00251 QSizeF FlashingLabel::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const 00252 { 00253 if (which == Qt::PreferredSize) { 00254 QFontMetrics fm(d->font); 00255 return fm.boundingRect(d->text).size(); 00256 } 00257 return QGraphicsWidget::sizeHint(which, constraint); 00258 } 00259 00260 void FlashingLabelPrivate::renderPixmap(const QSize &size) 00261 { 00262 if (renderedPixmap.size() != size) { 00263 renderedPixmap = QPixmap(size); 00264 } 00265 renderedPixmap.fill(Qt::transparent); 00266 00267 QPainter painter(&renderedPixmap); 00268 if (type == FlashingLabelPrivate::Text) { 00269 painter.setPen(color); 00270 painter.setFont(font); 00271 painter.drawText(QRect(QPoint(0, 0), size), text, textOption); 00272 } else if (type == FlashingLabelPrivate::Pixmap) { 00273 QPoint p; 00274 00275 if(alignment & Qt::AlignLeft) { 00276 p.setX(0); 00277 } else if (alignment & Qt::AlignRight) { 00278 p.setX(size.width() - pixmap.width()); 00279 } else { 00280 p.setX((size.width() - pixmap.width()) / 2); 00281 } 00282 00283 if (alignment & Qt::AlignTop) { 00284 p.setY(0); 00285 } else if (alignment & Qt::AlignRight) { 00286 p.setY(size.height() - pixmap.height()); 00287 } else { 00288 p.setY((size.height() - pixmap.height()) / 2); 00289 } 00290 00291 painter.drawPixmap(p, pixmap); 00292 } 00293 painter.end(); 00294 00295 if (anim.data()) { 00296 Plasma::Animation *animation = anim.data(); 00297 animation->setProperty("startPixmap", renderedPixmap); 00298 } 00299 } 00300 00301 void FlashingLabelPrivate::setupFlash(int duration) 00302 { 00303 fadeOutTimer.stop(); 00304 fadeOutTimer.setInterval(duration > 0 ? duration : defaultDuration); 00305 00306 renderPixmap(q->size().toSize()); 00307 if (state != FlashingLabelPrivate::Visible) { 00308 fadeInTimer.start(); 00309 } else { 00310 q->update(); 00311 } 00312 00313 if (fadeOutTimer.interval() > 0) { 00314 fadeOutTimer.start(); 00315 } 00316 } 00317 00318 void FlashingLabelPrivate::elementAnimationFinished() 00319 { 00320 if (autohide && state == FlashingLabelPrivate::Invisible && anim.data()) { 00321 q->hide(); 00322 } 00323 } 00324 00325 void FlashingLabelPrivate::setPalette() 00326 { 00327 color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); 00328 q->update(); 00329 } 00330 00331 #include "flashinglabel.moc"
KDE 4.6 API Reference