diff options
Diffstat (limited to 'client/crystalbutton.cpp')
-rw-r--r-- | client/crystalbutton.cpp | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/client/crystalbutton.cpp b/client/crystalbutton.cpp new file mode 100644 index 0000000..8566e41 --- /dev/null +++ b/client/crystalbutton.cpp @@ -0,0 +1,337 @@ +/*************************************************************************** + * Copyright (C) 2006 by Sascha Hlusiak * + * [email protected] * + * * + * 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 <qimage.h> +#include <qtooltip.h> +#include <qpainter.h> + +#include "crystalclient.h" +#include "crystalbutton.h" +#include "buttonimage.h" +#include "imageholder.h" + + +CrystalButton::CrystalButton(CrystalClient *parent, const char *name, + const QString& tip, ButtonType type, + ButtonImage *vimage) +: QButton(parent->widget(), name), client_(parent), type_(type), image(vimage), lastmouse_(0) +{ + setBackgroundMode(NoBackground); + resetSize(false); + setCursor(arrowCursor); + + hover=first=last=false; + animation=0.0; + QToolTip::add(this, tip); + connect ( &animation_timer,SIGNAL(timeout()),this,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); +} + +QSize CrystalButton::sizeHint() const +{ + return QSize(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(QEvent *e) +{ + hover=true; + if (factory->hovereffect)repaint(false); + if (factory->animateHover)animation_timer.start(60); + QButton::enterEvent(e); +} + +void CrystalButton::leaveEvent(QEvent *e) +{ + hover=false; + if (factory->hovereffect)repaint(false); + if (factory->animateHover)animation_timer.start(80); + QButton::leaveEvent(e); +} + +void CrystalButton::mousePressEvent(QMouseEvent* e) +{ + lastmouse_ = e->button(); + int button; + switch(e->button()) + { + case LeftButton: + button=LeftButton; + break; + case RightButton: + if ((type_ == ButtonMax) || (type_ == ButtonMin) || (type_ == ButtonMenu) || (type_ == ButtonClose)) + button=LeftButton; else button=NoButton; + break; + case MidButton: + if ((type_ == ButtonMax) || (type_ == ButtonMin)) + button=LeftButton; else button=NoButton; + break; + + default:button=NoButton; + break; + } + QMouseEvent me(e->type(), e->pos(), e->globalPos(),button, e->state()); + QButton::mousePressEvent(&me); +} + +void CrystalButton::mouseReleaseEvent(QMouseEvent* e) +{ + lastmouse_ = e->button(); + int button; + switch(e->button()) + { + case LeftButton: + button=LeftButton; + break; + case RightButton: + if ((type_ == ButtonMax) || (type_ == ButtonMin) || (type_ == ButtonMenu) || (type_==ButtonClose)) + button=LeftButton; else button=NoButton; + break; + case MidButton: + if ((type_ == ButtonMax) || (type_ == ButtonMin)) + button=LeftButton; else button=NoButton; + break; + + default:button=NoButton; + break; + } + QMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state()); + QButton::mouseReleaseEvent(&me); +} + +void CrystalButton::drawButton(QPainter *painter) +{ + if (!CrystalFactory::initialized()) return; + + QColorGroup group; + float dx, dy; + int dm=0; + + QPixmap pufferPixmap; + pufferPixmap.resize(width(), height()); + QPainter pufferPainter(&pufferPixmap); + + CrystalFactory *f=((CrystalFactory*)client_->factory()); + QPixmap *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()) + { + QRect r=rect(); + QPoint p=mapToGlobal(QPoint(0,0)); + r.moveBy(p.x(),p.y()); + + pufferPainter.drawPixmap(QPoint(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,QPoint(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(); + QRect r((rect().width()-m)/2,(rect().height()-m)/2,m,m); +// if (isDown()) { r.moveBy(1,1); } + pufferPainter.drawPixmap(r, client_->icon().pixmap(QIconSet::Small, + QIconSet::Normal)); + }else{ +// if (isDown()) { dx++; dy++; } + pufferPainter.drawPixmap((int)dx, (int)dy, client_->icon().pixmap(QIconSet::Small, + QIconSet::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; + + QImage *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); + } + + QRect 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(QPoint((int)dx,(int)dy),*img); + + if (type_ == ButtonMenu) drawMenuImage(&pufferPainter, + QRect((int)dx,(int)dy,image->image_width,image->image_height)); + } + } + + pufferPainter.end(); + painter->drawPixmap(0,0, pufferPixmap); +} + +void CrystalButton::drawMenuImage(QPainter* painter, QRect 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(); + QRect r2(r.left()+(r.width()-m)/2,r.top()+(r.height()-m)/2,m,m); + painter->drawPixmap(r2, client_->icon().pixmap(QIconSet::Small, + QIconSet::Normal)); + }else{ + painter->drawPixmap(r.left()+(int)dx, r.top()+(int)dy, client_->icon().pixmap(QIconSet::Small, + QIconSet::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" |