kwin Library API Documentation

plastikbutton.cpp

00001 /* Plastik KWin window decoration
00002   Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net>
00003 
00004   based on the window decoration "Web":
00005   Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
00006 
00007   This program is free software; you can redistribute it and/or
00008   modify it under the terms of the GNU General Public
00009   License as published by the Free Software Foundation; either
00010   version 2 of the License, or (at your option) any later version.
00011 
00012   This program is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with this program; see the file COPYING.  If not, write to
00019   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020   Boston, MA 02111-1307, USA.
00021  */
00022 
00023 // #include <kwin/options.h>
00024 
00025 #include <qbitmap.h>
00026 #include <qcursor.h>
00027 #include <qimage.h>
00028 #include <qpainter.h>
00029 #include <qpixmap.h>
00030 #include <kpixmap.h>
00031 #include <kpixmapeffect.h>
00032 #include <qtooltip.h>
00033 #include <qtimer.h>
00034 
00035 #include "xpm/close.xpm"
00036 #include "xpm/minimize.xpm"
00037 #include "xpm/maximize.xpm"
00038 #include "xpm/restore.xpm"
00039 #include "xpm/help.xpm"
00040 #include "xpm/sticky.xpm"
00041 #include "xpm/unsticky.xpm"
00042 #include "xpm/shade.xpm"
00043 #include "xpm/unshade.xpm"
00044 #include "xpm/keepabove.xpm"
00045 #include "xpm/notkeepabove.xpm"
00046 #include "xpm/keepbelow.xpm"
00047 #include "xpm/notkeepbelow.xpm"
00048 #include "xpm/empty.xpm"
00049 
00050 #include "plastikbutton.h"
00051 #include "plastikbutton.moc"
00052 #include "plastikclient.h"
00053 #include "misc.h"
00054 #include "shadow.h"
00055 
00056 namespace KWinPlastik
00057 {
00058 
00059 static const uint TIMERINTERVAL = 50; // msec
00060 static const uint ANIMATIONSTEPS = 4;
00061 
00062 PlastikButton::PlastikButton(PlastikClient *parent, const char *name,
00063                              const QString& tip, ButtonType type,
00064                              int size, bool toggle, int btns)
00065     : QButton(parent->widget(), name),
00066     m_client(parent),
00067     m_lastMouse(NoButton),
00068     m_realizeButtons(btns),
00069     m_size(size),
00070     m_type(type),
00071     m_aDecoLight(QImage() ), m_iDecoLight(QImage() ),
00072     m_aDecoDark(QImage() ), m_iDecoDark(QImage() ),
00073     hover(false)
00074 {
00075     QToolTip::add( this, tip );
00076     setCursor(ArrowCursor);
00077 
00078     setBackgroundMode(NoBackground);
00079 
00080     setToggleButton(toggle);
00081 
00082     if(m_size < 10) { m_size = 10; }
00083 
00084     setFixedSize(m_size, m_size);
00085 
00086     setDeco();
00087 
00088     animTmr = new QTimer(this);
00089     connect(animTmr, SIGNAL(timeout() ), this, SLOT(animate() ) );
00090     animProgress = 0;
00091 }
00092 
00093 PlastikButton::~PlastikButton()
00094 {
00095 }
00096 
00097 QSize PlastikButton::sizeHint() const
00098 {
00099     return QSize(m_size, m_size);
00100 }
00101 
00102 void PlastikButton::setSize(int s)
00103 {
00104     m_size = s;
00105     if(m_size < 10) { m_size = 10; }
00106     setFixedSize(m_size, m_size);
00107     setDeco();
00108 }
00109 
00110 void PlastikButton::setOn(bool on)
00111 {
00112     QButton::setOn(on);
00113     setDeco();
00114 }
00115 
00116 void PlastikButton::setDeco()
00117 {
00118     QColor aDecoFgDark = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, true),
00119             Qt::black, 50);
00120     QColor aDecoFgLight = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, true),
00121             Qt::white, 50);
00122     QColor iDecoFgDark = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, false),
00123             Qt::black, 50);
00124     QColor iDecoFgLight = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, false),
00125             Qt::white, 50);
00126 
00127     int reduceW = 0, reduceH = 0;
00128     if(width()>12) {
00129         reduceW = static_cast<int>(2*(width()/3.5) );
00130     }
00131     else
00132         reduceW = 4;
00133     if(height()>12)
00134         reduceH = static_cast<int>(2*(height()/3.5) );
00135     else
00136         reduceH = 4;
00137 
00138     QImage img;
00139     switch (m_type) {
00140         case CloseButton:
00141             img = QImage(close_xpm);
00142             break;
00143         case HelpButton:
00144             img = QImage(help_xpm);
00145             break;
00146         case MinButton:
00147             img = QImage(minimize_xpm);
00148             break;
00149         case MaxButton:
00150             if (isOn()) {
00151                 img = QImage(restore_xpm);
00152             } else {
00153                 img = QImage(maximize_xpm);
00154             }
00155             break;
00156         case OnAllDesktopsButton:
00157             if (isOn()) {
00158                 img = QImage(unsticky_xpm);
00159             } else {
00160                 img = QImage(sticky_xpm);
00161             }
00162             break;
00163         case ShadeButton:
00164             if (isOn()) {
00165                 img = QImage(unshade_xpm);
00166             } else {
00167                 img = QImage(shade_xpm);
00168             }
00169             break;
00170         case AboveButton:
00171             if (isOn()) {
00172                 img = QImage(notkeepabove_xpm);
00173             } else {
00174                 img = QImage(keepabove_xpm);
00175             }
00176             break;
00177         case BelowButton:
00178             if (isOn()) {
00179                 img = QImage(notkeepbelow_xpm);
00180             } else {
00181                 img = QImage(keepbelow_xpm);
00182             }
00183             break;
00184         default:
00185             img = QImage(empty_xpm);
00186             break;
00187     }
00188 
00189     m_aDecoDark = recolorImage(&img, aDecoFgDark).smoothScale(width()-reduceW, height()-reduceH);
00190     m_iDecoDark = recolorImage(&img, iDecoFgDark).smoothScale(width()-reduceW, height()-reduceH);
00191     m_aDecoLight = recolorImage(&img, aDecoFgLight).smoothScale(width()-reduceW, height()-reduceH);
00192     m_iDecoLight = recolorImage(&img, iDecoFgLight).smoothScale(width()-reduceW, height()-reduceH);
00193 
00194     this->update();
00195 }
00196 
00197 void PlastikButton::setTipText(const QString &tip) {
00198     QToolTip::remove(this );
00199     QToolTip::add(this, tip );
00200 }
00201 
00202 void PlastikButton::animate()
00203 {
00204     animTmr->stop();
00205 
00206     if(hover) {
00207         if(animProgress < ANIMATIONSTEPS) {
00208             if (PlastikHandler::animateButtons() ) {
00209                 animProgress++;
00210             } else {
00211                 animProgress = ANIMATIONSTEPS;
00212             }
00213             animTmr->start(TIMERINTERVAL, true); // single-shot
00214         }
00215     } else {
00216         if(animProgress > 0) {
00217             if (PlastikHandler::animateButtons() ) {
00218                 animProgress--;
00219             } else {
00220                 animProgress = 0;
00221             }
00222             animTmr->start(TIMERINTERVAL, true); // single-shot
00223         }
00224     }
00225 
00226     repaint(false);
00227 }
00228 
00229 void PlastikButton::enterEvent(QEvent *e)
00230 {
00231     QButton::enterEvent(e);
00232 
00233     hover = true;
00234     animate();
00235 //     repaint(false);
00236 }
00237 
00238 void PlastikButton::leaveEvent(QEvent *e)
00239 {
00240     QButton::leaveEvent(e);
00241 
00242     hover = false;
00243     animate();
00244 //     repaint(false);
00245 }
00246 
00247 void PlastikButton::mousePressEvent(QMouseEvent* e)
00248 {
00249     m_lastMouse = e->button();
00250     // pass on event after changing button to LeftButton
00251     QMouseEvent me(e->type(), e->pos(), e->globalPos(),
00252                    (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
00253 
00254     QButton::mousePressEvent(&me);
00255 }
00256 
00257 void PlastikButton::mouseReleaseEvent(QMouseEvent* e)
00258 {
00259     m_lastMouse = e->button();
00260     // pass on event after changing button to LeftButton
00261     QMouseEvent me(e->type(), e->pos(), e->globalPos(),
00262                     (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
00263 
00264     QButton::mouseReleaseEvent(&me);
00265 }
00266 
00267 void PlastikButton::drawButton(QPainter *painter)
00268 {
00269     if (!PlastikHandler::initialized())
00270         return;
00271 
00272     QRect r(0,0,width(),height());
00273 
00274     bool active = m_client->isActive();
00275     QPixmap backgroundTile = m_client->getTitleBarTile(active);
00276     KPixmap tempKPixmap;
00277 
00278     QColor highlightColor;
00279     if(m_type == CloseButton) {
00280         highlightColor = QColor(255,64,0);
00281     } else {
00282         highlightColor = Qt::white;
00283     }
00284 
00285     QColor contourTop = alphaBlendColors(PlastikHandler::getColor(TitleGradientFrom, active),
00286             Qt::black, 220);
00287     QColor contourBottom = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, active),
00288             Qt::black, 220);
00289     QColor sourfaceTop = alphaBlendColors(PlastikHandler::getColor(TitleGradientFrom, active),
00290             Qt::white, 220);
00291     QColor sourfaceBottom = alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, active),
00292             Qt::white, 220);
00293 
00294     int highlightAlpha = static_cast<int>(255-((60/static_cast<double>(ANIMATIONSTEPS))*
00295                                           static_cast<double>(animProgress) ) );
00296     contourTop = alphaBlendColors(contourTop, highlightColor, highlightAlpha );
00297     contourBottom = alphaBlendColors(contourBottom, highlightColor, highlightAlpha);
00298     sourfaceTop = alphaBlendColors(sourfaceTop, highlightColor, highlightAlpha);
00299     sourfaceBottom = alphaBlendColors(sourfaceBottom, highlightColor, highlightAlpha);
00300 
00301     if (isDown() ) {
00302         contourTop = alphaBlendColors(contourTop, Qt::black, 200);
00303         contourBottom = alphaBlendColors(contourBottom, Qt::black, 200);
00304         sourfaceTop = alphaBlendColors(sourfaceTop, Qt::black, 200);
00305         sourfaceBottom = alphaBlendColors(sourfaceBottom, Qt::black, 200);
00306     }
00307 
00308     QPixmap buffer;
00309     buffer.resize(width(), height());
00310     QPainter bP(&buffer);
00311 
00312     // fill with the titlebar background
00313     bP.drawTiledPixmap(0, 0, width(), width(), backgroundTile);
00314 
00315     if (m_type != MenuButton || hover || animProgress != 0) {
00316         // contour
00317         bP.setPen(contourTop);
00318         bP.drawLine(r.x()+2, r.y(), r.right()-2, r.y() );
00319         bP.drawPoint(r.x()+1, r.y()+1);
00320         bP.drawPoint(r.right()-1, r.y()+1);
00321         bP.setPen(contourBottom);
00322         bP.drawLine(r.x()+2, r.bottom(), r.right()-2, r.bottom() );
00323         bP.drawPoint(r.x()+1, r.bottom()-1);
00324         bP.drawPoint(r.right()-1, r.bottom()-1);
00325         // sides of the contour
00326         tempKPixmap.resize(1, r.height()-2*2);
00327         KPixmapEffect::gradient(tempKPixmap,
00328                                 contourTop,
00329                                 contourBottom,
00330                                 KPixmapEffect::VerticalGradient);
00331         bP.drawPixmap(r.x(), r.y()+2, tempKPixmap);
00332         bP.drawPixmap(r.right(), r.y()+2, tempKPixmap);
00333         // sort of anti-alias for the contour
00334         bP.setPen(alphaBlendColors(PlastikHandler::getColor(TitleGradientFrom, active),
00335                 contourTop, 150) );
00336         bP.drawPoint(r.x()+1, r.y());
00337         bP.drawPoint(r.right()-1, r.y());
00338         bP.drawPoint(r.x(), r.y()+1);
00339         bP.drawPoint(r.right(), r.y()+1);
00340         bP.setPen(alphaBlendColors(PlastikHandler::getColor(TitleGradientTo, active),
00341                 contourBottom, 150) );
00342         bP.drawPoint(r.x()+1, r.bottom());
00343         bP.drawPoint(r.right()-1, r.bottom());
00344         bP.drawPoint(r.x(), r.bottom()-1);
00345         bP.drawPoint(r.right(), r.bottom()-1);
00346         // sourface
00347         // fill top and bottom
00348         bP.setPen(sourfaceTop);
00349         bP.drawLine(r.x()+2, r.y()+1, r.right()-2, r.y()+1 );
00350         bP.setPen(sourfaceBottom);
00351         bP.drawLine(r.x()+2, r.bottom()-1, r.right()-2, r.bottom()-1 );
00352         // fill the rest! :)
00353         tempKPixmap.resize(1, r.height()-2*2);
00354         KPixmapEffect::gradient(tempKPixmap,
00355                                 sourfaceTop,
00356                                 sourfaceBottom,
00357                                 KPixmapEffect::VerticalGradient);
00358         bP.drawTiledPixmap(r.x()+1, r.y()+2, r.width()-2, r.height()-4, tempKPixmap);
00359     }
00360 
00361     if (m_type == MenuButton)
00362     {
00363         QPixmap menuIcon(m_client->icon().pixmap( QIconSet::Small, QIconSet::Normal));
00364         if (width() < menuIcon.width() || height() < menuIcon.height() ) {
00365             menuIcon.convertFromImage( menuIcon.convertToImage().smoothScale(width(), height()));
00366         }
00367         bP.drawPixmap((width()-menuIcon.width())/2, (height()-menuIcon.height())/2, menuIcon);
00368     }
00369     else
00370     {
00371         int dX,dY;
00372         QImage *deco = 0;
00373         if (isDown() ) {
00374             deco = active?&m_aDecoLight:&m_iDecoLight;
00375         } else {
00376             deco = active?&m_aDecoDark:&m_iDecoDark;
00377         }
00378         dX = r.x()+(r.width()-deco->width())/2;
00379         dY = r.y()+(r.height()-deco->height())/2;
00380         if (isDown() ) {
00381             dY++;
00382         }
00383         bP.drawImage(dX, dY, *deco);
00384     }
00385 
00386     bP.end();
00387     painter->drawPixmap(0, 0, buffer);
00388 }
00389 
00390 } // KWinPlastik
KDE Logo
This file is part of the documentation for kwin Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jun 14 16:47:03 2006 by doxygen 1.4.4 written by Dimitri van Heesch, © 1997-2003