Back to index

kdeartwork  4.3.2
glowbutton.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           glowbutton.cpp  -  description
00003                              -------------------
00004     begin                : Thu Sep 6 2001
00005     copyright            : (C) 2001 by Henning Burchardt
00006     email                : h_burchardt@gmx.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <math.h>
00019 #include <iostream>
00020 #include <vector>
00021 #include <qmap.h>
00022 #include <qpixmap.h>
00023 #include <qpixmapcache.h>
00024 #include <qbitmap.h>
00025 #include <qpainter.h>
00026 #include <qimage.h>
00027 #include <qtimer.h>
00028 #include <qtooltip.h>
00029 //Added by qt3to4:
00030 #include <QMouseEvent>
00031 #include <QEvent>
00032 #include <QPaintEvent>
00033 #include <kdecoration.h>
00034 #include <kiconeffect.h>
00035 #include "glowbutton.h"
00036 
00037 namespace Glow
00038 {
00039 
00040 //-----------------------------------------------------------------------------
00041 // PixmapCache
00042 //-----------------------------------------------------------------------------
00043 
00044 QMap<QString, const QPixmap*> PixmapCache::m_pixmapMap;
00045 
00046 const QPixmap* PixmapCache::find(const QString& key)
00047 {
00048        QMap<QString, const QPixmap*>::const_iterator it =
00049               m_pixmapMap.find(key);
00050        if( it != m_pixmapMap.end() )
00051               return *it;
00052        else
00053               return 0;
00054 }
00055 
00056 void PixmapCache::insert(const QString& key, const QPixmap *pixmap)
00057 {
00058        m_pixmapMap[key] = pixmap;
00059 }
00060 
00061 void PixmapCache::erase(const QString& key)
00062 {
00063        QMap<QString, const QPixmap*>::iterator it =
00064               m_pixmapMap.find(key);
00065        if (it != m_pixmapMap.end())
00066        {
00067               delete *it;
00068               m_pixmapMap.erase(it);
00069        }
00070 }
00071 
00072 void PixmapCache::clear()
00073 {
00074        // delete all pixmaps in the cache
00075        QMap<QString, const QPixmap*>::const_iterator it
00076               = m_pixmapMap.begin();
00077        for(; it != m_pixmapMap.end(); ++it)
00078               delete *it;
00079        m_pixmapMap.clear();
00080 }
00081 
00082 //-----------------------------------------------------------------------------
00083 // GlowButton
00084 //-----------------------------------------------------------------------------
00085 
00086 GlowButton::GlowButton(QWidget *parent, const char *name,
00087        const QString& tip, const int realizeBtns)
00088        : Q3Button(parent, name)
00089 {
00090        m_realizeButtons = realizeBtns;
00091 
00092        _steps = 0;
00093        m_updateTime = 50;
00094        m_pixmapName = QString();
00095 
00096        m_timer = new QTimer(this);
00097        connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
00098        m_pos = 0;
00099        m_timerStatus = Stop;
00100 
00101        setTipText (tip);
00102        setCursor(arrowCursor);
00103 }
00104 
00105 GlowButton::~GlowButton()
00106 {
00107 }
00108 
00109 void GlowButton::setTipText( const QString& tip )
00110 {
00111        if (KDecoration::options()->showTooltips())
00112        {
00113            QToolTip::remove( this );
00114            this->setToolTip( tip );
00115        }
00116 }
00117 
00118 QString GlowButton::getPixmapName() const
00119 {
00120        return m_pixmapName;
00121 }
00122 
00123 Qt::ButtonState GlowButton::lastButton() const
00124 {
00125        return _last_button;
00126 }
00127 
00128 void GlowButton::setPixmapName(const QString& pixmapName)
00129 {
00130        m_pixmapName = pixmapName;
00131 
00132        const QPixmap *pixmap = PixmapCache::find(pixmapName);
00133        if( ! pixmap )
00134               return;
00135 
00136        // set steps
00137        _steps = pixmap->height()/pixmap->width() - 1;
00138 
00139        repaint(false);
00140 }
00141 
00142 void GlowButton::paintEvent( QPaintEvent *e )
00143 {
00144        QWidget::paintEvent(e);
00145        const QPixmap *pixmap = PixmapCache::find(m_pixmapName);
00146        if( pixmap != 0 )
00147        {
00148               int pos = m_pos>=0?m_pos:-m_pos;
00149               QPainter p;
00150               QPixmap pm (pixmap->size());
00151               p.begin(&pm);
00152               const QPixmap * bg_pixmap = PixmapCache::find(
00153                             QString::number(parentWidget()->winId()));
00154               p.drawPixmap (0, 0, *bg_pixmap, x(), y(), width(), height());
00155               p.drawPixmap (0, 0, *pixmap, 0, pos*height(), width(), height());
00156               p.end();
00157               p.begin(this);
00158               p.drawPixmap (0, 0, pm);
00159               p.end();
00160        }
00161 }
00162 
00163 void GlowButton::enterEvent( QEvent *e )
00164 {
00165        if( m_pos<0 )
00166               m_pos=-m_pos;
00167        m_timerStatus = Run;
00168        if( ! m_timer->isActive() )
00169               m_timer->start(m_updateTime);
00170        Q3Button::enterEvent(e);
00171 }
00172 
00173 void GlowButton::leaveEvent( QEvent *e )
00174 {
00175        m_timerStatus = Stop;
00176        if( ! m_timer->isActive() )
00177               m_timer->start(m_updateTime);
00178        Q3Button::leaveEvent(e);
00179 }
00180 
00181 void GlowButton::mousePressEvent( QMouseEvent *e )
00182 {
00183        _last_button = e->button();
00184        if( m_timer->isActive() )
00185               m_timer->stop();
00186        m_pos = _steps;
00187        repaint(false);
00188        // without pretending Qt::LeftButton, clicking on the button with Qt::MidButton
00189        // or Qt::RightButton would cause unwanted titlebar action
00190        QMouseEvent me (e->type(), e->pos(), e->globalPos(),
00191                      (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
00192        Q3Button::mousePressEvent(&me);
00193 }
00194 
00195 void GlowButton::mouseReleaseEvent( QMouseEvent *e )
00196 {
00197        _last_button = e->button();
00198        QPoint p = mapToParent(mapFromGlobal(e->globalPos()));
00199        if( ! m_timer->isActive() ) {
00200               m_timer->start(m_updateTime);
00201        }
00202        if( ! geometry().contains(p) ) {
00203               m_timerStatus = Stop;
00204        }
00205        QMouseEvent me (e->type(), e->pos(), e->globalPos(),
00206                      (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
00207        Q3Button::mouseReleaseEvent(&me);
00208 }
00209 
00210 void GlowButton::slotTimeout()
00211 {
00212        repaint(false);
00213 
00214        if( m_pos>=_steps-1 ) {
00215               m_pos = -m_pos;
00216        }
00217        if( m_timerStatus==Stop ) {
00218               if( m_pos==0 ) {
00219                      m_timer->stop();
00220                      return;
00221               } else if( m_pos>0 ) {
00222                      m_pos = -m_pos;
00223               }
00224        }
00225 
00226        m_pos++;
00227 }
00228 
00229 //-----------------------------------------------------------------------------
00230 // GlowButtonFactory
00231 //-----------------------------------------------------------------------------
00232 
00233 GlowButtonFactory::GlowButtonFactory()
00234 {
00235        _steps = 20;
00236 }
00237 
00238 int GlowButtonFactory::getSteps()
00239 {
00240        return _steps;
00241 }
00242 
00243 void GlowButtonFactory::setSteps(int steps)
00244 {
00245        _steps = steps;
00246 }
00247 
00248 QPixmap * GlowButtonFactory::createGlowButtonPixmap(
00249                             const QImage & bg_image,
00250                             const QImage & fg_image,
00251                             const QImage & glow_image,
00252                             const QColor & color,
00253                             const QColor & glow_color)
00254 {
00255               if (bg_image.size() != fg_image.size()
00256                      || fg_image.size() != glow_image.size()) {
00257                             std::cerr << "Image size error" << std::endl;
00258                             return new QPixmap();
00259               }
00260 
00261               QImage colorized_bg_image = bg_image.copy();
00262               KIconEffect::colorize (colorized_bg_image, color, 1.0);
00263 
00264               int w = colorized_bg_image.width();
00265               int h = colorized_bg_image.height();
00266 
00267               QImage image (w, (_steps+1)*h, 32);
00268               image.setAlphaBuffer (true);
00269               for (int i=0; i<_steps+1; ++i) {
00270                      for (int y=0; y<h; ++y) {
00271                             uint * src1_line = (uint*) colorized_bg_image.scanLine (y);
00272                             uint * src2_line = (uint*) fg_image.scanLine (y);
00273                             uint * dst_line = (uint*) image.scanLine (i*h+y);
00274                             for (int x=0; x<w; ++x) {
00275                                    int r = qRed (*(src1_line+x));
00276                                    int g = qGreen (*(src1_line+x));
00277                                    int b = qBlue (*(src1_line+x));
00278                                    int a = qMax (qAlpha(*(src1_line+x)),qGray(*(src2_line+x)));
00279                                    *(dst_line+x) = qRgba (r, g, b, a);
00280                             }
00281                      }
00282               }
00283               QPixmap * pixmap = new QPixmap (image);
00284               QPainter painter (pixmap);
00285 
00286               bool dark = (qGray(color.rgb()) <= 127);
00287               QImage fg_img (w, h, 32);
00288               fg_img.setAlphaBuffer (true);
00289               for (int y=0; y<h; ++y) {
00290                      uint * src_line = (uint*) fg_image.scanLine (y);
00291                      uint * dst_line = (uint*) fg_img.scanLine (y);
00292                      for (int x=0; x<w; ++x) {
00293                             int alpha = qGray (*(src_line+x));
00294                             if (dark)
00295                                           *(dst_line+x) = qRgba (255, 255, 255, alpha);
00296                             else
00297                                           *(dst_line+x) = qRgba (0, 0, 0, alpha);
00298                      }
00299               }
00300 
00301               int r = glow_color.red();
00302               int g = glow_color.green();
00303               int b = glow_color.blue();
00304               QImage glow_img (w, h, 32);
00305               glow_img.setAlphaBuffer (true);
00306               for (int i=0; i<_steps; ++i) {
00307                      painter.drawImage (0, i*h, fg_img);
00308                      for (int y=0; y<h; ++y) {
00309                             uint * src_line = (uint*) glow_image.scanLine(y);
00310                             uint * dst_line = (uint*) glow_img.scanLine(y);
00311                             for (int x=0; x<w; ++x) {
00312                                    int alpha =
00313                                                  (int) (qGray (*(src_line+x)) * ((double) i/_steps));
00314                                    *(dst_line+x) = qRgba (r, g, b, alpha);
00315                             }
00316                      }
00317                      painter.drawImage (0, i*h, glow_img);
00318               }
00319               painter.drawImage (0, _steps*h, fg_img);
00320               for (int y=0; y<h; ++y) {
00321                             uint * src_line = (uint*) glow_image.scanLine (y);
00322                             uint * dst_line = (uint*) glow_img.scanLine (y);
00323                             for (int x=0; x<w; ++x) {
00324                                    int alpha = qGray (*(src_line+x));
00325                                    *(dst_line+x) = qRgba (r, g, b, alpha);
00326                             }
00327               }
00328               painter.drawImage (0, _steps*h, glow_img);
00329 
00330               return pixmap;
00331 }
00332 
00333 GlowButton* GlowButtonFactory::createGlowButton(
00334        QWidget *parent, const char* name, const QString& tip, const int realizeBtns)
00335 {
00336        GlowButton *glowButton = new GlowButton(parent, name, tip, realizeBtns);
00337        return glowButton;
00338 }
00339 
00340 }
00341 
00342 #include "glowbutton.moc"
00343