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.
twin-style-crystal/client/crystalbutton.cpp

338 lines
10 KiB

/***************************************************************************
* Copyright (C) 2006 by Sascha Hlusiak *
* Spam84@gmx.de *
* *
* 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. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <tqimage.h>
#include <tqtooltip.h>
#include <tqpainter.h>
#include "crystalclient.h"
#include "crystalbutton.h"
#include "buttonimage.h"
#include "imageholder.h"
CrystalButton::CrystalButton(CrystalClient *parent, const char *name,
const TQString& tip, ButtonType type,
ButtonImage *vimage)
: TQButton(parent->widget(), name), client_(parent), type_(type), image(vimage), lastmouse_(0)
{
setBackgroundMode(NoBackground);
resetSize(false);
setCursor(arrowCursor);
hover=first=last=false;
animation=0.0;
TQToolTip::add(this, tip);
connect ( &animation_timer,TQ_SIGNAL(timeout()),this,TQ_SLOT(animate()));
}
CrystalButton::~CrystalButton()
{
}
void CrystalButton::resetSize(bool FullSize)
{
if (FullSize || (image && image->drawMode==1))
{
setFixedSize(buttonSizeH(),factory->titlesize);
}else setFixedSize(buttonSizeH(),buttonSizeV());
}
void CrystalButton::setBitmap(ButtonImage *newimage)
{
image=newimage;
repaint(false);
}
TQSize CrystalButton::sizeHint() const
{
return TQSize(buttonSizeH(),buttonSizeV());
}
int CrystalButton::buttonSizeH() const
{
int w=image?image->image_width:DEFAULT_IMAGE_SIZE;
int h=image?image->image_height:DEFAULT_IMAGE_SIZE;
int vS=image?image->vSpace:2;
int hS=image?image->hSpace:2;
return (factory->titlesize-1-vS>=h)?
w+hS*2:
(int)(((float)buttonSizeV()/(float)h)*(float)w)+hS;
}
int CrystalButton::buttonSizeV() const
{
int h=image?image->image_height:DEFAULT_IMAGE_SIZE;
int vS=image?image->vSpace:2;
return (factory->titlesize-1-vS>h)?h:factory->titlesize-1-vS;
}
void CrystalButton::enterEvent(TQEvent *e)
{
hover=true;
if (factory->hovereffect)repaint(false);
if (factory->animateHover)animation_timer.start(60);
TQButton::enterEvent(e);
}
void CrystalButton::leaveEvent(TQEvent *e)
{
hover=false;
if (factory->hovereffect)repaint(false);
if (factory->animateHover)animation_timer.start(80);
TQButton::leaveEvent(e);
}
void CrystalButton::mousePressEvent(TQMouseEvent* e)
{
lastmouse_ = e->button();
int button;
switch(e->button())
{
case TQt::LeftButton:
button=TQt::LeftButton;
break;
case TQt::RightButton:
if ((type_ == ButtonMax) || (type_ == ButtonMin) || (type_ == ButtonMenu) || (type_ == ButtonClose))
button=TQt::LeftButton; else button=TQt::NoButton;
break;
case TQt::MidButton:
if ((type_ == ButtonMax) || (type_ == ButtonMin))
button=TQt::LeftButton; else button=TQt::NoButton;
break;
default:button=TQt::NoButton;
break;
}
TQMouseEvent me(e->type(), e->pos(), e->globalPos(),button, e->state());
TQButton::mousePressEvent(&me);
}
void CrystalButton::mouseReleaseEvent(TQMouseEvent* e)
{
lastmouse_ = e->button();
int button;
switch(e->button())
{
case TQt::LeftButton:
button=TQt::LeftButton;
break;
case TQt::RightButton:
if ((type_ == ButtonMax) || (type_ == ButtonMin) || (type_ == ButtonMenu) || (type_==ButtonClose))
button=TQt::LeftButton; else button=TQt::NoButton;
break;
case TQt::MidButton:
if ((type_ == ButtonMax) || (type_ == ButtonMin))
button=TQt::LeftButton; else button=TQt::NoButton;
break;
default:button=TQt::NoButton;
break;
}
TQMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state());
TQButton::mouseReleaseEvent(&me);
}
void CrystalButton::drawButton(TQPainter *painter)
{
if (!CrystalFactory::initialized()) return;
TQColorGroup group;
float dx, dy;
int dm=0;
TQPixmap pufferPixmap;
pufferPixmap.resize(width(), height());
TQPainter pufferPainter(&pufferPixmap);
CrystalFactory *f=((CrystalFactory*)client_->factory());
TQPixmap *background;
if (f->transparency)background=f->image_holder->image(client_->isActive());
else background=NULL;
WND_CONFIG *wndcfg=client_->isActive()?&f->active:&f->inactive;
if (background && !background->isNull())
{
TQRect r=rect();
TQPoint p=mapToGlobal(TQPoint(0,0));
r.moveBy(p.x(),p.y());
pufferPainter.drawPixmap(TQPoint(0,0),*background,r);
}else{
group = client_->options()->colorGroup(KDecoration::ColorTitleBar, client_->isActive());
pufferPainter.fillRect(rect(), group.background());
}
if (!wndcfg->overlay.isNull())
{
pufferPainter.drawTiledPixmap(rect(),wndcfg->overlay,TQPoint(x(),y()));
}
dm=0;
if (image && (image->drawMode==1))dm=1;
if (wndcfg->outlineMode)
{
// outline the frame
pufferPainter.setPen(wndcfg->frameColor);
if (wndcfg->outlineMode==2)pufferPainter.setPen(wndcfg->frameColor.dark(150));
if (wndcfg->outlineMode==3)pufferPainter.setPen(wndcfg->frameColor.light(150));
// top
if ((client_->FullMax && client_->isShade() && (dm==0)) ||
((dm==1)&&(!client_->FullMax || client_->isShade()))) pufferPainter.drawLine(0,0,width(),0);
// left
if (first && client_->FullMax && client_->isShade())pufferPainter.drawLine(0,0,0,height());
if (wndcfg->outlineMode==2)pufferPainter.setPen(wndcfg->frameColor.light(150));
if (wndcfg->outlineMode==3)pufferPainter.setPen(wndcfg->frameColor.dark(150));
// bottom
if (client_->isShade() && ((dm==1)||(client_->FullMax)))pufferPainter.drawLine(0,height()-1,width(),height()-1);
// right
if (last && client_->FullMax && client_->isShade())pufferPainter.drawLine(width()-1,0,width()-1,height());
}
if (wndcfg->inlineMode && (client_->FullMax||dm==1) && !client_->isShade())
{
// inline the frame
if (wndcfg->inlineMode==1)pufferPainter.setPen(wndcfg->inlineColor);
if (wndcfg->inlineMode==2)pufferPainter.setPen(wndcfg->inlineColor.dark(150));
if (wndcfg->inlineMode==3)pufferPainter.setPen(wndcfg->inlineColor.light(150));
// buttons just need to draw the bottom line
pufferPainter.drawLine(0,height()-1,width(),height()-1);
}
if (type_ == ButtonMenu && (!::factory->menuImage || image==NULL || (image!=NULL && !image->initialized()))) {
// we paint the mini icon (which is 16 pixels high)
dx = float(width() - 16) / 2.0;
dy = float(height() - 16) / 2.0;
if (dx<1 || dy<=1)
{
int m=(rect().width()-2<rect().height())?rect().width()-2:rect().height();
TQRect r((rect().width()-m)/2,(rect().height()-m)/2,m,m);
// if (isDown()) { r.moveBy(1,1); }
pufferPainter.drawPixmap(r, client_->icon().pixmap(TQIconSet::Small,
TQIconSet::Normal));
}else{
// if (isDown()) { dx++; dy++; }
pufferPainter.drawPixmap((int)dx, (int)dy, client_->icon().pixmap(TQIconSet::Small,
TQIconSet::Normal));
}
} else if (image && image->initialized()) {
// otherwise we paint the deco
dx = float(width() - image->image_width) / 2.0;
dy = float(height() - image->image_height) / 2.0;
TQImage *img=image->normal;
if (::factory->hovereffect)
{
if (hover)
{
img=image->hovered;
}
if (::factory->animateHover)
{
img=image->getAnimated(animation);
}
}
if (isDown())
{
img=image->pressed;
}
if (img)
if (dx<image->hSpace/2 || dy<0)
{ // Deco size is smaller than image, we need to stretch it
int w,h;
if (rect().width()-image->hSpace<rect().height())
{
w=rect().width()-image->hSpace;
h=(int)((float)w*(float)image->image_height/(float)image->image_width);
}else{
h=rect().height();
w=(int)((float)h*(float)image->image_width/(float)image->image_height);
}
TQRect r((rect().width()-w)/2,(rect().height()-h)/2,w,h);
pufferPainter.drawImage(r,*img);
if (type_ == ButtonMenu) drawMenuImage(&pufferPainter, r);
}else{
// Otherwise we just paint it
if (image->drawMode==1)dy=0;
pufferPainter.drawImage(TQPoint((int)dx,(int)dy),*img);
if (type_ == ButtonMenu) drawMenuImage(&pufferPainter,
TQRect((int)dx,(int)dy,image->image_width,image->image_height));
}
}
pufferPainter.end();
painter->drawPixmap(0,0, pufferPixmap);
}
void CrystalButton::drawMenuImage(TQPainter* painter, TQRect r)
{
if (type_ != ButtonMenu) return;
// we paint the mini icon (which is 16 pixels high)
r.setTop(r.top()+1);
r.setBottom(r.bottom()-1);
float dx = float(r.width() - 16) / 2.0;
float dy = float(r.height() - 16) / 2.0;
if (dx<1 || dy<=1)
{
int m=(r.width()-2<r.height())?r.width()-2:r.height();
TQRect r2(r.left()+(r.width()-m)/2,r.top()+(r.height()-m)/2,m,m);
painter->drawPixmap(r2, client_->icon().pixmap(TQIconSet::Small,
TQIconSet::Normal));
}else{
painter->drawPixmap(r.left()+(int)dx, r.top()+(int)dy, client_->icon().pixmap(TQIconSet::Small,
TQIconSet::Normal));
}
}
void CrystalButton::animate()
{
if (hover)
{
animation+=0.25;
if (animation>1.0)
{
animation=1.0;
animation_timer.stop();
}
}else{
animation-=0.15;
if (animation<0.0)
{
animation=0.0;
animation_timer.stop();
}
}
repaint(false);
}
#include "crystalbutton.moc"