You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeartwork/kwin-styles/glow/glowbutton.cpp

340 lines
8.6 KiB

/***************************************************************************
glowbutton.cpp - description
-------------------
begin : Thu Sep 6 2001
copyright : (C) 2001 by Henning Burchardt
email : h_burchardt@gmx.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <math.h>
#include <iostream>
#include <vector>
#include <tqmap.h>
#include <tqpixmap.h>
#include <tqpixmapcache.h>
#include <tqbitmap.h>
#include <tqpainter.h>
#include <tqimage.h>
#include <tqtimer.h>
#include <tqtooltip.h>
#include <kdecoration.h>
#include <kiconeffect.h>
#include "glowbutton.h"
namespace Glow
{
//-----------------------------------------------------------------------------
// PixmapCache
//-----------------------------------------------------------------------------
TQMap<TQString, const TQPixmap*> PixmapCache::m_pixmapMap;
const TQPixmap* PixmapCache::find(const TQString& key)
{
TQMap<TQString, const TQPixmap*>::const_iterator it =
m_pixmapMap.find(key);
if( it != m_pixmapMap.end() )
return *it;
else
return 0;
}
void PixmapCache::insert(const TQString& key, const TQPixmap *pixmap)
{
m_pixmapMap[key] = pixmap;
}
void PixmapCache::erase(const TQString& key)
{
TQMap<TQString, const TQPixmap*>::iterator it =
m_pixmapMap.find(key);
if (it != m_pixmapMap.end())
{
delete *it;
m_pixmapMap.erase(it);
}
}
void PixmapCache::clear()
{
// delete all pixmaps in the cache
TQMap<TQString, const TQPixmap*>::const_iterator it
= m_pixmapMap.begin();
for(; it != m_pixmapMap.end(); ++it)
delete *it;
m_pixmapMap.clear();
}
//-----------------------------------------------------------------------------
// GlowButton
//-----------------------------------------------------------------------------
GlowButton::GlowButton(TQWidget *parent, const char *name,
const TQString& tip, const int realizeBtns)
: TQButton(parent, name)
{
m_realizeButtons = realizeBtns;
_steps = 0;
m_updateTime = 50;
m_pixmapName = TQString();
m_timer = new TQTimer(this);
connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout()));
m_pos = 0;
m_timerStatus = Stop;
setTipText (tip);
setCursor(arrowCursor);
}
GlowButton::~GlowButton()
{
}
void GlowButton::setTipText( const TQString& tip )
{
if (KDecoration::options()->showTooltips())
{
TQToolTip::remove( this );
TQToolTip::add( this, tip );
}
}
TQString GlowButton::getPixmapName() const
{
return m_pixmapName;
}
TQt::ButtonState GlowButton::lastButton() const
{
return _last_button;
}
void GlowButton::setPixmapName(const TQString& pixmapName)
{
m_pixmapName = pixmapName;
const TQPixmap *pixmap = PixmapCache::find(pixmapName);
if( ! pixmap )
return;
// set steps
_steps = pixmap->height()/pixmap->width() - 1;
repaint(false);
}
void GlowButton::paintEvent( TQPaintEvent *e )
{
TQWidget::paintEvent(e);
const TQPixmap *pixmap = PixmapCache::find(m_pixmapName);
if( pixmap != 0 )
{
int pos = m_pos>=0?m_pos:-m_pos;
TQPainter p;
TQPixmap pm (pixmap->size());
p.begin(&pm);
const TQPixmap * bg_pixmap = PixmapCache::find(
TQString::number(parentWidget()->winId()));
p.drawPixmap (0, 0, *bg_pixmap, x(), y(), width(), height());
p.drawPixmap (0, 0, *pixmap, 0, pos*height(), width(), height());
p.end();
p.begin(this);
p.drawPixmap (0, 0, pm);
p.end();
}
}
void GlowButton::enterEvent( TQEvent *e )
{
if( m_pos<0 )
m_pos=-m_pos;
m_timerStatus = Run;
if( ! m_timer->isActive() )
m_timer->start(m_updateTime);
TQButton::enterEvent(e);
}
void GlowButton::leaveEvent( TQEvent *e )
{
m_timerStatus = Stop;
if( ! m_timer->isActive() )
m_timer->start(m_updateTime);
TQButton::leaveEvent(e);
}
void GlowButton::mousePressEvent( TQMouseEvent *e )
{
_last_button = e->button();
if( m_timer->isActive() )
m_timer->stop();
m_pos = _steps;
repaint(false);
// without pretending LeftButton, clicking on the button with MidButton
// or RightButton would cause unwanted titlebar action
TQMouseEvent me (e->type(), e->pos(), e->globalPos(),
(e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
TQButton::mousePressEvent(&me);
}
void GlowButton::mouseReleaseEvent( TQMouseEvent *e )
{
_last_button = e->button();
TQPoint p = mapToParent(mapFromGlobal(e->globalPos()));
if( ! m_timer->isActive() ) {
m_timer->start(m_updateTime);
}
if( ! geometry().contains(p) ) {
m_timerStatus = Stop;
}
TQMouseEvent me (e->type(), e->pos(), e->globalPos(),
(e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
TQButton::mouseReleaseEvent(&me);
}
void GlowButton::slotTimeout()
{
repaint(false);
if( m_pos>=_steps-1 ) {
m_pos = -m_pos;
}
if( m_timerStatus==Stop ) {
if( m_pos==0 ) {
m_timer->stop();
return;
} else if( m_pos>0 ) {
m_pos = -m_pos;
}
}
m_pos++;
}
//-----------------------------------------------------------------------------
// GlowButtonFactory
//-----------------------------------------------------------------------------
GlowButtonFactory::GlowButtonFactory()
{
_steps = 20;
}
int GlowButtonFactory::getSteps()
{
return _steps;
}
void GlowButtonFactory::setSteps(int steps)
{
_steps = steps;
}
TQPixmap * GlowButtonFactory::createGlowButtonPixmap(
const TQImage & bg_image,
const TQImage & fg_image,
const TQImage & glow_image,
const TQColor & color,
const TQColor & glow_color)
{
if (bg_image.size() != fg_image.size()
|| fg_image.size() != glow_image.size()) {
std::cerr << "Image size error" << std::endl;
return new TQPixmap();
}
TQImage colorized_bg_image = bg_image.copy();
KIconEffect::colorize (colorized_bg_image, color, 1.0);
int w = colorized_bg_image.width();
int h = colorized_bg_image.height();
TQImage image (w, (_steps+1)*h, 32);
image.setAlphaBuffer (true);
for (int i=0; i<_steps+1; ++i) {
for (int y=0; y<h; ++y) {
uint * src1_line = (uint*) colorized_bg_image.scanLine (y);
uint * src2_line = (uint*) fg_image.scanLine (y);
uint * dst_line = (uint*) image.scanLine (i*h+y);
for (int x=0; x<w; ++x) {
int r = tqRed (*(src1_line+x));
int g = tqGreen (*(src1_line+x));
int b = tqBlue (*(src1_line+x));
int a = TQMAX (tqAlpha(*(src1_line+x)),tqGray(*(src2_line+x)));
*(dst_line+x) = tqRgba (r, g, b, a);
}
}
}
TQPixmap * pixmap = new TQPixmap (image);
TQPainter painter (pixmap);
bool dark = (tqGray(color.rgb()) <= 127);
TQImage fg_img (w, h, 32);
fg_img.setAlphaBuffer (true);
for (int y=0; y<h; ++y) {
uint * src_line = (uint*) fg_image.scanLine (y);
uint * dst_line = (uint*) fg_img.scanLine (y);
for (int x=0; x<w; ++x) {
int alpha = tqGray (*(src_line+x));
if (dark)
*(dst_line+x) = tqRgba (255, 255, 255, alpha);
else
*(dst_line+x) = tqRgba (0, 0, 0, alpha);
}
}
int r = glow_color.red();
int g = glow_color.green();
int b = glow_color.blue();
TQImage glow_img (w, h, 32);
glow_img.setAlphaBuffer (true);
for (int i=0; i<_steps; ++i) {
painter.drawImage (0, i*h, fg_img);
for (int y=0; y<h; ++y) {
uint * src_line = (uint*) glow_image.scanLine(y);
uint * dst_line = (uint*) glow_img.scanLine(y);
for (int x=0; x<w; ++x) {
int alpha =
(int) (tqGray (*(src_line+x)) * ((double) i/_steps));
*(dst_line+x) = tqRgba (r, g, b, alpha);
}
}
painter.drawImage (0, i*h, glow_img);
}
painter.drawImage (0, _steps*h, fg_img);
for (int y=0; y<h; ++y) {
uint * src_line = (uint*) glow_image.scanLine (y);
uint * dst_line = (uint*) glow_img.scanLine (y);
for (int x=0; x<w; ++x) {
int alpha = tqGray (*(src_line+x));
*(dst_line+x) = tqRgba (r, g, b, alpha);
}
}
painter.drawImage (0, _steps*h, glow_img);
return pixmap;
}
GlowButton* GlowButtonFactory::createGlowButton(
TQWidget *parent, const char* name, const TQString& tip, const int realizeBtns)
{
GlowButton *glowButton = new GlowButton(parent, name, tip, realizeBtns);
return glowButton;
}
}
#include "glowbutton.moc"