1 /***************************************************************************
2 glowbutton.cpp - description
5 copyright : (C) 2001 by Henning Burchardt
6 email : h_burchardt@gmx.net
7 ***************************************************************************/
9 /***************************************************************************
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. *
16 ***************************************************************************/
23 #include <qpixmapcache.h>
30 #include <QMouseEvent>
32 #include <QPaintEvent>
33 #include <kdecoration.h>
34 #include <kiconeffect.h>
35 #include "glowbutton.h"
40 //-----------------------------------------------------------------------------
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() )
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())
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
)
82 //-----------------------------------------------------------------------------
84 //-----------------------------------------------------------------------------
86 GlowButton::GlowButton(QWidget
*parent
, const char *name
,
87 const QString
& tip
, const int realizeBtns
)
88 : Q3Button(parent
, name
)
90 m_realizeButtons
= realizeBtns
;
94 m_pixmapName
= QString::null
;
96 m_timer
= new QTimer(this);
97 connect(m_timer
, SIGNAL(timeout()), this, SLOT(slotTimeout()));
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
123 Qt::ButtonState
GlowButton::lastButton() const
128 void GlowButton::setPixmapName(const QString
& pixmapName
)
130 m_pixmapName
= pixmapName
;
132 const QPixmap
*pixmap
= PixmapCache::find(pixmapName
);
137 _steps
= pixmap
->height()/pixmap
->width() - 1;
142 void GlowButton::paintEvent( QPaintEvent
*e
)
144 QWidget::paintEvent(e
);
145 const QPixmap
*pixmap
= PixmapCache::find(m_pixmapName
);
148 int pos
= m_pos
>=0?m_pos
:-m_pos
;
150 QPixmap
pm (pixmap
->size());
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());
158 p
.drawPixmap (0, 0, pm
);
163 void GlowButton::enterEvent( QEvent
*e
)
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() )
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()
214 if( m_pos
>=_steps
-1 ) {
217 if( m_timerStatus
==Stop
) {
221 } else if( m_pos
>0 ) {
229 //-----------------------------------------------------------------------------
231 //-----------------------------------------------------------------------------
233 GlowButtonFactory::GlowButtonFactory()
238 int GlowButtonFactory::getSteps()
243 void GlowButtonFactory::setSteps(int 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
));
295 *(dst_line
+x
) = qRgba (255, 255, 255, alpha
);
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
) {
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
);
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
);
342 #include "glowbutton.moc"