00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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;
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);
00214 }
00215 } else {
00216 if(animProgress > 0) {
00217 if (PlastikHandler::animateButtons() ) {
00218 animProgress--;
00219 } else {
00220 animProgress = 0;
00221 }
00222 animTmr->start(TIMERINTERVAL, true);
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
00236 }
00237
00238 void PlastikButton::leaveEvent(QEvent *e)
00239 {
00240 QButton::leaveEvent(e);
00241
00242 hover = false;
00243 animate();
00244
00245 }
00246
00247 void PlastikButton::mousePressEvent(QMouseEvent* e)
00248 {
00249 m_lastMouse = e->button();
00250
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
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
00313 bP.drawTiledPixmap(0, 0, width(), width(), backgroundTile);
00314
00315 if (m_type != MenuButton || hover || animProgress != 0) {
00316
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
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
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
00347
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
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 }