Fix some error
[kdeartwork.git] / kwin-styles / glow / glowbutton.cpp
blob5e22a0b6afeebba7b56f99ed4f2eb9bae2a285c9
1 /***************************************************************************
2 glowbutton.cpp - description
3 -------------------
4 begin : Thu Sep 6 2001
5 copyright : (C) 2001 by Henning Burchardt
6 email : h_burchardt@gmx.net
7 ***************************************************************************/
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
18 #include <math.h>
19 #include <iostream>
20 #include <vector>
21 #include <qmap.h>
22 #include <qpixmap.h>
23 #include <qpixmapcache.h>
24 #include <qbitmap.h>
25 #include <qpainter.h>
26 #include <qimage.h>
27 #include <qtimer.h>
28 #include <qtooltip.h>
29 //Added by qt3to4:
30 #include <QMouseEvent>
31 #include <QEvent>
32 #include <QPaintEvent>
33 #include <kdecoration.h>
34 #include <kiconeffect.h>
35 #include "glowbutton.h"
37 namespace Glow
40 //-----------------------------------------------------------------------------
41 // PixmapCache
42 //-----------------------------------------------------------------------------
44 QMap<QString, const QPixmap*> PixmapCache::m_pixmapMap;
46 const QPixmap* PixmapCache::find(const QString& key)
48 QMap<QString, const QPixmap*>::const_iterator it =
49 m_pixmapMap.find(key);
50 if( it != m_pixmapMap.end() )
51 return *it;
52 else
53 return 0;
56 void PixmapCache::insert(const QString& key, const QPixmap *pixmap)
58 m_pixmapMap[key] = pixmap;
61 void PixmapCache::erase(const QString& key)
63 QMap<QString, const QPixmap*>::iterator it =
64 m_pixmapMap.find(key);
65 if (it != m_pixmapMap.end())
67 delete *it;
68 m_pixmapMap.erase(it);
72 void PixmapCache::clear()
74 // delete all pixmaps in the cache
75 QMap<QString, const QPixmap*>::const_iterator it
76 = m_pixmapMap.begin();
77 for(; it != m_pixmapMap.end(); ++it)
78 delete *it;
79 m_pixmapMap.clear();
82 //-----------------------------------------------------------------------------
83 // GlowButton
84 //-----------------------------------------------------------------------------
86 GlowButton::GlowButton(QWidget *parent, const char *name,
87 const QString& tip, const int realizeBtns)
88 : Q3Button(parent, name)
90 m_realizeButtons = realizeBtns;
92 _steps = 0;
93 m_updateTime = 50;
94 m_pixmapName = QString::null;
96 m_timer = new QTimer(this);
97 connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
98 m_pos = 0;
99 m_timerStatus = Stop;
101 setTipText (tip);
102 setCursor(arrowCursor);
105 GlowButton::~GlowButton()
109 void GlowButton::setTipText( const QString& tip )
111 if (KDecoration::options()->showTooltips())
113 QToolTip::remove( this );
114 this->setToolTip( tip );
118 QString GlowButton::getPixmapName() const
120 return m_pixmapName;
123 Qt::ButtonState GlowButton::lastButton() const
125 return _last_button;
128 void GlowButton::setPixmapName(const QString& pixmapName)
130 m_pixmapName = pixmapName;
132 const QPixmap *pixmap = PixmapCache::find(pixmapName);
133 if( ! pixmap )
134 return;
136 // set steps
137 _steps = pixmap->height()/pixmap->width() - 1;
139 repaint(false);
142 void GlowButton::paintEvent( QPaintEvent *e )
144 QWidget::paintEvent(e);
145 const QPixmap *pixmap = PixmapCache::find(m_pixmapName);
146 if( pixmap != 0 )
148 int pos = m_pos>=0?m_pos:-m_pos;
149 QPainter p;
150 QPixmap pm (pixmap->size());
151 p.begin(&pm);
152 const QPixmap * bg_pixmap = PixmapCache::find(
153 QString::number(parentWidget()->winId()));
154 p.drawPixmap (0, 0, *bg_pixmap, x(), y(), width(), height());
155 p.drawPixmap (0, 0, *pixmap, 0, pos*height(), width(), height());
156 p.end();
157 p.begin(this);
158 p.drawPixmap (0, 0, pm);
159 p.end();
163 void GlowButton::enterEvent( QEvent *e )
165 if( m_pos<0 )
166 m_pos=-m_pos;
167 m_timerStatus = Run;
168 if( ! m_timer->isActive() )
169 m_timer->start(m_updateTime);
170 Q3Button::enterEvent(e);
173 void GlowButton::leaveEvent( QEvent *e )
175 m_timerStatus = Stop;
176 if( ! m_timer->isActive() )
177 m_timer->start(m_updateTime);
178 Q3Button::leaveEvent(e);
181 void GlowButton::mousePressEvent( QMouseEvent *e )
183 _last_button = e->button();
184 if( m_timer->isActive() )
185 m_timer->stop();
186 m_pos = _steps;
187 repaint(false);
188 // without pretending LeftButton, clicking on the button with MidButton
189 // or RightButton would cause unwanted titlebar action
190 QMouseEvent me (e->type(), e->pos(), e->globalPos(),
191 (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
192 Q3Button::mousePressEvent(&me);
195 void GlowButton::mouseReleaseEvent( QMouseEvent *e )
197 _last_button = e->button();
198 QPoint p = mapToParent(mapFromGlobal(e->globalPos()));
199 if( ! m_timer->isActive() ) {
200 m_timer->start(m_updateTime);
202 if( ! geometry().contains(p) ) {
203 m_timerStatus = Stop;
205 QMouseEvent me (e->type(), e->pos(), e->globalPos(),
206 (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
207 Q3Button::mouseReleaseEvent(&me);
210 void GlowButton::slotTimeout()
212 repaint(false);
214 if( m_pos>=_steps-1 ) {
215 m_pos = -m_pos;
217 if( m_timerStatus==Stop ) {
218 if( m_pos==0 ) {
219 m_timer->stop();
220 return;
221 } else if( m_pos>0 ) {
222 m_pos = -m_pos;
226 m_pos++;
229 //-----------------------------------------------------------------------------
230 // GlowButtonFactory
231 //-----------------------------------------------------------------------------
233 GlowButtonFactory::GlowButtonFactory()
235 _steps = 20;
238 int GlowButtonFactory::getSteps()
240 return _steps;
243 void GlowButtonFactory::setSteps(int steps)
245 _steps = steps;
248 QPixmap * GlowButtonFactory::createGlowButtonPixmap(
249 const QImage & bg_image,
250 const QImage & fg_image,
251 const QImage & glow_image,
252 const QColor & color,
253 const QColor & glow_color)
255 if (bg_image.size() != fg_image.size()
256 || fg_image.size() != glow_image.size()) {
257 std::cerr << "Image size error" << std::endl;
258 return new QPixmap();
261 QImage colorized_bg_image = bg_image.copy();
262 KIconEffect::colorize (colorized_bg_image, color, 1.0);
264 int w = colorized_bg_image.width();
265 int h = colorized_bg_image.height();
267 QImage image (w, (_steps+1)*h, 32);
268 image.setAlphaBuffer (true);
269 for (int i=0; i<_steps+1; ++i) {
270 for (int y=0; y<h; ++y) {
271 uint * src1_line = (uint*) colorized_bg_image.scanLine (y);
272 uint * src2_line = (uint*) fg_image.scanLine (y);
273 uint * dst_line = (uint*) image.scanLine (i*h+y);
274 for (int x=0; x<w; ++x) {
275 int r = qRed (*(src1_line+x));
276 int g = qGreen (*(src1_line+x));
277 int b = qBlue (*(src1_line+x));
278 int a = QMAX (qAlpha(*(src1_line+x)),qGray(*(src2_line+x)));
279 *(dst_line+x) = qRgba (r, g, b, a);
283 QPixmap * pixmap = new QPixmap (image);
284 QPainter painter (pixmap);
286 bool dark = (qGray(color.rgb()) <= 127);
287 QImage fg_img (w, h, 32);
288 fg_img.setAlphaBuffer (true);
289 for (int y=0; y<h; ++y) {
290 uint * src_line = (uint*) fg_image.scanLine (y);
291 uint * dst_line = (uint*) fg_img.scanLine (y);
292 for (int x=0; x<w; ++x) {
293 int alpha = qGray (*(src_line+x));
294 if (dark)
295 *(dst_line+x) = qRgba (255, 255, 255, alpha);
296 else
297 *(dst_line+x) = qRgba (0, 0, 0, alpha);
301 int r = glow_color.red();
302 int g = glow_color.green();
303 int b = glow_color.blue();
304 QImage glow_img (w, h, 32);
305 glow_img.setAlphaBuffer (true);
306 for (int i=0; i<_steps; ++i) {
307 painter.drawImage (0, i*h, fg_img);
308 for (int y=0; y<h; ++y) {
309 uint * src_line = (uint*) glow_image.scanLine(y);
310 uint * dst_line = (uint*) glow_img.scanLine(y);
311 for (int x=0; x<w; ++x) {
312 int alpha =
313 (int) (qGray (*(src_line+x)) * ((double) i/_steps));
314 *(dst_line+x) = qRgba (r, g, b, alpha);
317 painter.drawImage (0, i*h, glow_img);
319 painter.drawImage (0, _steps*h, fg_img);
320 for (int y=0; y<h; ++y) {
321 uint * src_line = (uint*) glow_image.scanLine (y);
322 uint * dst_line = (uint*) glow_img.scanLine (y);
323 for (int x=0; x<w; ++x) {
324 int alpha = qGray (*(src_line+x));
325 *(dst_line+x) = qRgba (r, g, b, alpha);
328 painter.drawImage (0, _steps*h, glow_img);
330 return pixmap;
333 GlowButton* GlowButtonFactory::createGlowButton(
334 QWidget *parent, const char* name, const QString& tip, const int realizeBtns)
336 GlowButton *glowButton = new GlowButton(parent, name, tip, realizeBtns);
337 return glowButton;
342 #include "glowbutton.moc"