File indexing completed on 2024-04-28 17:04:37

0001 /*****************************************************************************
0002  *   Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 /*
0023   based on the window decoration "Plastik":
0024   Copyright (C) 2003-2005 Sandro Giessl <sandro@giessl.com>
0025 
0026   based on the window decoration "Web":
0027   Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
0028 */
0029 
0030 #include "qtcurvebutton.h"
0031 #include <QAbstractButton>
0032 #include <QStyle>
0033 #include <QStyleOption>
0034 #include <QBitmap>
0035 #include <QPainter>
0036 #include <QPixmap>
0037 #include <QTimer>
0038 #include "qtcurveclient.h"
0039 #include <common/common.h>
0040 
0041 namespace QtCurve {
0042 namespace KWin {
0043 
0044 QtCurveButton::QtCurveButton(ButtonType type, QtCurveClient *parent)
0045     : KCommonDecorationButton(type, parent),
0046       m_client(parent),
0047       m_iconType(NumButtonIcons),
0048       m_hover(false)
0049 {
0050     // setAttribute(Qt::WA_PaintOnScreen, false);
0051     setAttribute(Qt::WA_NoSystemBackground, true);
0052     setAutoFillBackground(false);
0053     // setFocusPolicy(Qt::NoFocus);
0054     // setAttribute(Qt::WA_OpaquePaintEvent, false);
0055     // setAttribute(Qt::WA_Hover, true);
0056     setCursor(Qt::ArrowCursor);
0057     reset(DecorationReset);
0058 }
0059 
0060 void QtCurveButton::reset(unsigned long changed)
0061 {
0062     if (changed & DecorationReset || changed & ManualReset ||
0063         changed & SizeChange || changed & StateChange) {
0064         switch (type()) {
0065 #if KDE_IS_VERSION(4, 9, 85)
0066         case AppMenuButton:
0067             m_iconType = MenuIcon;
0068             break;
0069 #endif
0070             // TODO ItemMenuButton?
0071         case ItemCloseButton:
0072             m_iconType = CloseTabIcon;
0073             break;
0074         case CloseButton:
0075             m_iconType = CloseIcon;
0076             break;
0077         case HelpButton:
0078             m_iconType = HelpIcon;
0079             break;
0080         case MinButton:
0081             m_iconType = MinIcon;
0082             break;
0083         case MaxButton:
0084             m_iconType = isChecked() ? MaxRestoreIcon : MaxIcon;
0085             break;
0086         case OnAllDesktopsButton:
0087             m_iconType = isChecked() ? NotOnAllDesktopsIcon : OnAllDesktopsIcon;
0088             break;
0089         case ShadeButton:
0090             m_iconType = isChecked() ? UnShadeIcon : ShadeIcon;
0091             break;
0092         case AboveButton:
0093             m_iconType = isChecked() ? NoKeepAboveIcon : KeepAboveIcon;
0094             break;
0095         case BelowButton:
0096             m_iconType = isChecked() ? NoKeepBelowIcon : KeepBelowIcon;
0097             break;
0098         case MenuButton:
0099             m_iconType = MenuIcon;
0100             break;
0101         default:
0102             m_iconType = NumButtonIcons; // empty...
0103             break;
0104         }
0105 
0106         this->update();
0107     }
0108 }
0109 
0110 void QtCurveButton::enterEvent(QEvent *e)
0111 {
0112     m_hover = true;
0113     KCommonDecorationButton::enterEvent(e);
0114     update();
0115     // Hacky NVIDIA fix - sometimes mouseover state gets 'stuck' -
0116     // but only for some windows!!!
0117     QTimer::singleShot(50, this, SLOT(update()));
0118 }
0119 
0120 void QtCurveButton::leaveEvent(QEvent *e)
0121 {
0122     m_hover = false;
0123     KCommonDecorationButton::leaveEvent(e);
0124     update();
0125     // Hacky NVIDIA fix - sometimes mouseover state gets 'stuck' -
0126     // but only for some windows!!!
0127     QTimer::singleShot(50, this, SLOT(update()));
0128 }
0129 
0130 void QtCurveButton::paintEvent(QPaintEvent *ev)
0131 {
0132     if (m_client->compositingActive()) {
0133         QPainter p(this);
0134         p.setClipRect(rect().intersected(ev->rect()));
0135         drawButton(&p);
0136     } else {
0137         QPixmap pixmap(size());
0138         {
0139             QPainter p(&pixmap);
0140             p.setRenderHints(QPainter::Antialiasing);
0141             parentWidget()->render(&p, QPoint(), geometry(),
0142                                    QWidget::DrawWindowBackground);
0143             drawButton(&p);
0144         }
0145         QPainter p(this);
0146         p.setClipRect(ev->rect());
0147         p.drawPixmap(QPoint(), pixmap);
0148     }
0149 }
0150 
0151 void QtCurveButton::drawButton(QPainter *painter)
0152 {
0153     int flags = Handler()->wStyle()->pixelMetric(
0154         (QStyle::PixelMetric)QtC_TitleBarButtons, 0L, 0L);
0155     bool active(m_client->isActive());
0156 
0157     if (!active && !m_hover && flags & TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW)
0158         return;
0159 
0160     QRect r(0, 0, width(), height());
0161     int versionHack = 0;
0162     bool sunken(isDown());
0163     bool drawFrame(!(flags & TITLEBAR_BUTTON_NO_FRAME) &&
0164                    (m_hover || sunken ||
0165                     !(flags & TITLEBAR_BUTTON_HOVER_FRAME)));
0166     bool drewFrame(false);
0167     bool iconForMenu(TITLEBAR_ICON_MENU_BUTTON ==
0168                      Handler()->wStyle()->pixelMetric(
0169                          (QStyle::PixelMetric)QtC_TitleBarIcon, 0L, 0L));
0170     QColor buttonColor(KDecoration::options()->color(KDecoration::ColorTitleBar,
0171                                                      active));
0172     QPixmap buffer(width(), height());
0173     buffer.fill(Qt::transparent);
0174     QPainter bP(&buffer);
0175     bool isTabClose(ItemCloseButton == type());
0176 
0177     // isItemMenu?
0178     if (isTabClose && drawFrame && !(sunken || m_hover))
0179         drawFrame = false;
0180     // if(CloseButton == type())
0181     //     buttonColor = midColor(QColor(180,64,32), buttonColor);
0182 
0183     switch (type()) {
0184     case HelpButton:
0185         versionHack = TBAR_VERSION_HACK + TITLEBAR_HELP;
0186         break;
0187     case MaxButton:
0188         versionHack = TBAR_VERSION_HACK + TITLEBAR_MAX;
0189         break;
0190     case MinButton:
0191         versionHack = TBAR_VERSION_HACK + TITLEBAR_MIN;
0192         break;
0193     case ItemCloseButton:
0194     case CloseButton:
0195         versionHack = TBAR_VERSION_HACK + TITLEBAR_CLOSE;
0196         break;
0197 #if KDE_IS_VERSION(4, 9, 85)
0198     case AppMenuButton:
0199 #endif
0200     case MenuButton:
0201         versionHack = TBAR_VERSION_HACK + TITLEBAR_MENU;
0202         break;
0203     case OnAllDesktopsButton:
0204         versionHack = TBAR_VERSION_HACK + TITLEBAR_ALL_DESKTOPS;
0205         break;
0206     case AboveButton:
0207         versionHack = TBAR_VERSION_HACK + TITLEBAR_KEEP_ABOVE;
0208         break;
0209     case BelowButton:
0210         versionHack = TBAR_VERSION_HACK + TITLEBAR_KEEP_BELOW;
0211         break;
0212     case ShadeButton:
0213         versionHack = TBAR_VERSION_HACK + TITLEBAR_SHADE;
0214     default:
0215         break;
0216     }
0217 
0218     if (drawFrame &&
0219         (/*!(flags&TITLEBAR_BUTTON_ROUND) || */
0220             MenuButton != type() || !iconForMenu)) {
0221         QStyleOption opt;
0222         int offset = flags & TITLEBAR_BUTTON_ROUND &&
0223             !m_client->isToolWindow() ? 1 : 0;
0224 
0225         if (flags & TITLEBAR_BUTTON_SUNKEN_BACKGROUND)
0226             // && flags & TITLEBAR_BUTTON_ROUND)
0227             offset++;
0228         opt.init(this);
0229         opt.rect = QRect(offset, offset, width() - (2 * offset),
0230                          height() - (2 * offset));
0231         opt.state |= (isDown() ? QStyle::State_Sunken : QStyle::State_Raised) |
0232             (active ? QStyle::State_Active : QStyle::State_None) |
0233             (m_hover ? QStyle::State_MouseOver : QStyle::State_None) |
0234             QStyle::State_Horizontal | QtC_StateKWin;
0235         opt.state &= ~QStyle::State_HasFocus;
0236         if (!isEnabled()) {
0237             opt.palette.setColor(QPalette::Button, buttonColor);
0238         } else {
0239             if (!(flags & TITLEBAR_BUTTON_STD_COLOR) ||
0240                 (flags & TITLEBAR_BUTTON_COLOR_MOUSE_OVER && !m_hover &&
0241                  !(flags&TITLEBAR_BUTTON_COLOR)))
0242                 opt.palette.setColor(QPalette::Button, buttonColor);
0243             if (flags & TITLEBAR_BUTTON_COLOR &&
0244                 !(flags & TITLEBAR_BUTTON_COLOR_SYMBOL))
0245                 opt.version = versionHack;
0246         }
0247         Handler()->wStyle()->drawPrimitive(QStyle::PE_PanelButtonCommand,
0248                                            &opt, &bP, 0L);
0249         drewFrame = true;
0250     }
0251 
0252     if (MenuButton == type() && iconForMenu) {
0253         QPixmap menuIcon(m_client->icon().pixmap(
0254                              style()->pixelMetric(QStyle::PM_SmallIconSize)));
0255         if (width() < menuIcon.width() || height() < menuIcon.height())
0256             menuIcon = menuIcon.scaled(width(), height());
0257 
0258         int dX(((width() - menuIcon.width()) / 2.0) + 0.5),
0259                       dY(((height() - menuIcon.height()) / 2.0) + 0.5);
0260 
0261         if (sunken) {
0262             dY++;
0263             dX++;
0264         }
0265         bP.drawPixmap(dX, dY, menuIcon);
0266     } else if (isEnabled() && (!(flags & TITLEBAR_BUTTON_HOVER_SYMBOL_FULL) ||
0267                                sunken || m_hover)) {
0268         const QBitmap &icon =
0269             Handler()->buttonBitmap(m_iconType, size(),
0270                                     decoration()->isToolWindow());
0271         bool customCol(false);
0272         bool faded(!m_hover && flags & TITLEBAR_BUTTON_HOVER_SYMBOL);
0273         QColor col(KDecoration::options()->color(KDecoration::ColorFont, active/* || faded*/));
0274         int dX(r.x()+(r.width() - icon.width())/2);
0275         int dY(r.y()+(r.height() - icon.height())/2);
0276         EEffect effect((EEffect)(style()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarEffect)));
0277 
0278         if(EFFECT_ETCH==effect && drewFrame)
0279             effect=EFFECT_SHADOW;
0280 
0281         if(m_hover || !(flags&TITLEBAR_BUTTON_HOVER_SYMBOL))
0282         {
0283             bool userDefined=flags&TITLEBAR_BUTTON_ICON_COLOR;
0284 
0285             if(userDefined || (flags&TITLEBAR_BUTTON_COLOR && flags&TITLEBAR_BUTTON_COLOR_SYMBOL))
0286             {
0287                 QStyleOption opt;
0288 
0289                 opt.init(this);
0290                 if(userDefined)
0291                 {
0292                     versionHack+=NUM_TITLEBAR_BUTTONS;
0293                     if(!active)
0294                         versionHack+=NUM_TITLEBAR_BUTTONS;
0295                 }
0296                 opt.version=versionHack;
0297                 col=QColor(QRgb(Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarIconColor, &opt, 0L)));
0298                 customCol=true;
0299             }
0300         }
0301 
0302         if (sunken) {
0303             dY++;
0304             dX++;
0305         } else if (!faded && EFFECT_NONE != effect) {
0306             QColor shadow(WINDOW_SHADOW_COLOR(effect));
0307 
0308             shadow.setAlphaF(WINDOW_TEXT_SHADOW_ALPHA(effect));
0309             bP.setPen(shadow);
0310             bP.drawPixmap(EFFECT_SHADOW==effect ? dX+1 : dX, dY+1, icon);
0311         }
0312 
0313         if (m_hover && !sunken && !(flags&TITLEBAR_BUTTON_COLOR) && !customCol) {
0314             if (CloseButton == type() || isTabClose) {
0315                 col = CLOSE_COLOR;
0316             } else if(flags&TITLEBAR_BUTTON_USE_HOVER_COLOR) {
0317                 col = Handler()->hoverCol(active);
0318             }
0319         }
0320 
0321         if (faded) {
0322             col.setAlphaF(HOVER_BUTTON_ALPHA(col));
0323         } else {
0324             // If dont set an alpha level here, then (at least on intel)
0325             // the background colour is used!
0326             col.setAlpha(254);
0327         }
0328 
0329         bP.setPen(col);
0330         bP.drawPixmap(dX, dY, icon);
0331     }
0332 
0333     bP.end();
0334     painter->drawPixmap(0, 0, buffer);
0335 }
0336 
0337 QBitmap IconEngine::icon(ButtonIcon icon, int size, QStyle *style)
0338 {
0339     if (size%2 == 0)
0340         --size;
0341 
0342     QBitmap bitmap(size, size);
0343     bitmap.fill(Qt::color0);
0344     QPainter p(&bitmap);
0345 
0346     p.setPen(Qt::color1);
0347 
0348     QRect r = bitmap.rect();
0349 
0350     // line widths
0351     int lwTitleBar = 1;
0352     if (r.width() > 16)
0353         lwTitleBar = 4;
0354     else if (r.width() > 4)
0355         lwTitleBar = 2;
0356 
0357     switch (icon) {
0358     case CloseTabIcon:
0359         r.adjust(1, 1, -1, -1);
0360     case CloseIcon: {
0361         int lineWidth = 1;
0362         if (r.width() > 16) {
0363             lineWidth = 3;
0364         } else if (r.width() > 4) {
0365             lineWidth = 2;
0366         }
0367 
0368         drawObject(p, DiagonalLine, r.x(), r.y(), r.width(), lineWidth);
0369         drawObject(p, CrossDiagonalLine, r.x(), r.bottom(),
0370                    r.width(), lineWidth);
0371         break;
0372     }
0373     case MaxIcon:
0374         if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, 0L, 0L) & TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
0375             QStyleOption opt;
0376             opt.rect = r;
0377             opt.state = QStyle::State_Enabled | QtC_StateKWin;
0378             style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, 0L);
0379         } else {
0380             int lineWidth2 = 1; // frame
0381             if (r.width() > 16) {
0382                 lineWidth2 = 2;
0383             } else if (r.width() > 4) {
0384                 lineWidth2 = 1;
0385             }
0386             drawObject(p, HorizontalLine, r.x(), r.top(),
0387                        r.width(), lwTitleBar);
0388             drawObject(p, HorizontalLine, r.x(), r.bottom() - (lineWidth2 - 1),
0389                        r.width(), lineWidth2);
0390             drawObject(p, VerticalLine, r.x(), r.top(), r.height(), lineWidth2);
0391             drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1),
0392                        r.top(), r.height(), lineWidth2);
0393         }
0394         break;
0395     case MaxRestoreIcon:
0396         if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, 0L, 0L) & TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
0397             p.drawLine(r.x() + 1, r.y(), r.x() + r.width() - 2, r.y());
0398             p.drawLine(r.x() + 1, r.y() + r.height() - 1,
0399                        r.x() + r.width() - 2, r.y() + r.height() - 1);
0400             p.drawLine(r.x(), r.y() + 1, r.x(), r.y() + r.height() - 2);
0401             p.drawLine(r.x() + r.width() - 1, r.y() + 1,
0402                        r.x() + r.width() - 1, r.y() + r.height() - 2);
0403             p.drawRect(r.x() + 1, r.y() + 1, r.width() - 3, r.height() - 3);
0404         } else {
0405             int lineWidth2 = 1; // frame
0406             if (r.width() > 16) {
0407                 lineWidth2 = 2;
0408             } else if (r.width() > 4) {
0409                 lineWidth2 = 1;
0410             }
0411             int margin1, margin2;
0412             margin1 = margin2 = lineWidth2 * 2 + 1;
0413             if (r.width() < 8)
0414                 margin1 = 1;
0415             int margin1h = margin1 - 1;
0416             int margin2h = margin2 - 1;
0417 
0418             // background window
0419             drawObject(p, HorizontalLine, r.x() + margin1h, r.top(),
0420                        r.width() - margin1, lwTitleBar);
0421             drawObject(p, HorizontalLine, r.right() - margin2h,
0422                        r.bottom() - (lineWidth2 - 1) - margin1, margin2h,
0423                        lineWidth2);
0424             drawObject(p, VerticalLine, r.x() + margin1h, r.top(), margin2,
0425                        lineWidth2);
0426             drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1),
0427                        r.top(), r.height() - margin1, lineWidth2);
0428 
0429             // foreground window
0430             drawObject(p, HorizontalLine, r.x(), r.top() + margin2,
0431                        r.width() - margin2h, lwTitleBar);
0432             drawObject(p, HorizontalLine, r.x(),
0433                        r.bottom() - (lineWidth2 - 1), r.width() - margin2h,
0434                        lineWidth2);
0435             drawObject(p, VerticalLine, r.x(), r.top() + margin2, r.height(),
0436                        lineWidth2);
0437             drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1) - margin2h,
0438                        r.top() + margin2, r.height(), lineWidth2);
0439         }
0440         break;
0441     case MinIcon:
0442         if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, 0L, 0L)&TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
0443             QStyleOption opt;
0444 
0445             opt.rect = r;
0446             opt.state = QStyle::State_Enabled | QtC_StateKWin;
0447             style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, 0L);
0448         } else {
0449             drawObject(p, HorizontalLine, r.x(), r.bottom() - (lwTitleBar - 1),
0450                        r.width(), lwTitleBar);
0451         }
0452         break;
0453     case HelpIcon: {
0454         int center = r.x()+r.width()/2; // -1;
0455         int side = r.width()/4;
0456 
0457         // paint a question mark... code is quite messy,
0458         // to be cleaned up later...! :o
0459         if (r.width() > 16) {
0460             int lineWidth = 3;
0461 
0462             // top bar
0463             drawObject(p, HorizontalLine, center - side + 3, r.y(),
0464                        2 * side - 3 - 1, lineWidth);
0465             // top bar rounding
0466             drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 5,
0467                        6, lineWidth);
0468             drawObject(p, DiagonalLine, center + side - 3, r.y(), 5, lineWidth);
0469             // right bar
0470             drawObject(p, VerticalLine, center + side + 2 - lineWidth,
0471                        r.y() + 3, r.height() - (2 * lineWidth + side + 2 + 1),
0472                        lineWidth);
0473             // bottom bar
0474             drawObject(p, CrossDiagonalLine, center, r.bottom() - 2 * lineWidth,
0475                        side + 2, lineWidth);
0476             drawObject(p, HorizontalLine, center,
0477                        r.bottom() - 3 * lineWidth + 2, lineWidth, lineWidth);
0478             // the dot
0479             drawObject(p, HorizontalLine, center, r.bottom() - (lineWidth - 1),
0480                        lineWidth, lineWidth);
0481         } else if (r.width() > 8) {
0482             int lineWidth = 2;
0483 
0484             // top bar
0485             drawObject(p, HorizontalLine, center - (side - 1), r.y(),
0486                        2 * side - 1, lineWidth);
0487             // top bar rounding
0488             if (r.width() > 9)
0489                 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 3, 3, lineWidth);
0490             else
0491                 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 2, 3, lineWidth);
0492             drawObject(p, DiagonalLine, center + side - 1, r.y(), 3, lineWidth);
0493             // right bar
0494             drawObject(p, VerticalLine, center + side + 2 - lineWidth, r.y() + 2, r.height() - (2*lineWidth + side + 1), lineWidth);
0495             // bottom bar
0496             drawObject(p, CrossDiagonalLine, center, r.bottom() - 2*lineWidth + 1, side + 2, lineWidth);
0497             // the dot
0498             drawObject(p, HorizontalLine, center, r.bottom() - (lineWidth - 1), lineWidth, lineWidth);
0499         }
0500         else
0501         {
0502             int lineWidth = 1;
0503 
0504             // top bar
0505             drawObject(p, HorizontalLine, center - (side - 1), r.y(), 2*side, lineWidth);
0506             // top bar rounding
0507             drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 1, 2, lineWidth);
0508             // right bar
0509             drawObject(p, VerticalLine, center + side + 1, r.y(), r.height() - (side + 2 + 1), lineWidth);
0510             // bottom bar
0511             drawObject(p, CrossDiagonalLine, center, r.bottom() - 2, side + 2, lineWidth);
0512             // the dot
0513             drawObject(p, HorizontalLine, center, r.bottom(), 1, 1);
0514         }
0515 
0516         break;
0517     }
0518     case NotOnAllDesktopsIcon:
0519     {
0520         r.adjust(1, 1, -1, -1);
0521 
0522         int lwMark = (r.width() - 1)/2;
0523         if (lwMark < 1)
0524             lwMark = 3;
0525 
0526         drawObject(p, HorizontalLine, r.x(), r.y(), lwMark, lwMark);
0527         drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark), r.y(), lwMark, lwMark);
0528         drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark), r.y() + (r.height() - lwMark), lwMark, lwMark);
0529         drawObject(p, HorizontalLine, r.x(), r.y() + (r.height() - lwMark), lwMark, lwMark);
0530         break;
0531     }
0532     case OnAllDesktopsIcon:
0533     {
0534         int lwMark = r.width() - lwTitleBar*2 - 2;
0535         if (lwMark < 1)
0536             lwMark = 3;
0537 
0538         drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark)/2, r.y() + (r.height() - lwMark)/2, lwMark, lwMark);
0539         break;
0540     }
0541     case NoKeepAboveIcon:
0542     case KeepAboveIcon:
0543     {
0544         QStyleOption opt;
0545 
0546         opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
0547         opt.rect.adjust(2, 2, -2, -2);
0548         opt.state=QStyle::State_Enabled|QtC_StateKWin;
0549 
0550         opt.rect.adjust(0, -1, 0, -1);
0551         if(NoKeepAboveIcon==icon)
0552         {
0553             int w=r.width()/3;
0554             if(0==w%2)
0555                 w++;
0556             drawObject(p, HorizontalLine, r.x() + (r.width() - w)/2, r.y() + 1, w, 2);
0557         }
0558         else
0559             style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, 0L);
0560         opt.rect.adjust(0, 4, 0, 4);
0561         style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, 0L);
0562         break;
0563     }
0564     case NoKeepBelowIcon:
0565     case KeepBelowIcon:
0566     {
0567         QStyleOption opt;
0568 
0569         opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
0570         opt.rect.adjust(2, 2, -2, -2);
0571         opt.state=QStyle::State_Enabled|QtC_StateKWin;
0572         opt.rect.adjust(0, -1, 0, -1);
0573         style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, 0L);
0574         opt.rect.adjust(0, 4, 0, 4);
0575         if(NoKeepBelowIcon==icon)
0576         {
0577             int w=r.width()/3;
0578             if(0==w%2)
0579                 w++;
0580             drawObject(p, HorizontalLine, r.x() + (r.width() - w)/2, r.y() + r.height() - 3, w, 2);
0581         }
0582         else
0583             style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, 0L);
0584         break;
0585     }
0586     case UnShadeIcon:
0587     case ShadeIcon: {
0588         QStyleOption opt;
0589 
0590         //opt.init(btn);
0591         opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
0592         opt.rect.adjust(2, 2, -2, -2);
0593         if(UnShadeIcon==icon)
0594             opt.rect.adjust(0, -1, 0, -1);
0595         opt.state=QStyle::State_Enabled|QtC_StateKWin;
0596 
0597         //opt.palette.setColor(QPalette::Button, Qt::red);
0598         style->drawPrimitive(ShadeIcon==icon ? QStyle::PE_IndicatorArrowDown
0599                              : QStyle::PE_IndicatorArrowUp,
0600                              &opt, &p, 0L);
0601         drawObject(p, HorizontalLine, r.x() + 1, r.bottom() - (lwTitleBar - 1), r.width() - 2, lwTitleBar);
0602         break;
0603     }
0604     case MenuIcon: {
0605         int offset=(r.height() - 7)/2;
0606         for (int i = 0;i < 3;i++)
0607             drawObject(p, HorizontalLine, r.x() + 1, r.y() + offset + (i*3), r.width() - 2, 1);
0608         break;
0609     }
0610     default:
0611         break;
0612     }
0613 
0614     p.end();
0615     bitmap.setMask(bitmap);
0616 
0617     return bitmap;
0618 }
0619 
0620 void
0621 IconEngine::drawObject(QPainter &p, Object object, int x, int y,
0622                        int length, int lineWidth)
0623 {
0624     switch(object) {
0625     case DiagonalLine:
0626         if (lineWidth <= 1) {
0627             for (int i = 0;i < length;i++) {
0628                 p.drawPoint(x + i, y + i);
0629             }
0630         } else if (lineWidth <= 2) {
0631             for (int i = 0;i < length;i++) {
0632                 p.drawPoint(x + i, y + i);
0633             }
0634             for (int i = 0;i < length - 1;i++) {
0635                 p.drawPoint(x + 1 + i, y + i);
0636                 p.drawPoint(x + i, y + 1 + i);
0637             }
0638         } else {
0639             for (int i = 1;i < length - 1;i++) {
0640                 p.drawPoint(x + i, y + i);
0641             }
0642             for (int i = 0;i < length - 1;i++) {
0643                 p.drawPoint(x + 1 + i, y + i);
0644                 p.drawPoint(x + i, y + 1 + i);
0645             }
0646             for (int i = 0;i < (length - 2);i++) {
0647                 p.drawPoint(x + 2 + i, y + i);
0648                 p.drawPoint(x + i, y + 2 + i);
0649             }
0650         }
0651         break;
0652     case CrossDiagonalLine:
0653         if (lineWidth <= 1) {
0654             for (int i = 0;i < length;i++) {
0655                 p.drawPoint(x + i, y - i);
0656             }
0657         } else if (lineWidth <= 2) {
0658             for (int i = 0;i < length;i++) {
0659                 p.drawPoint(x + i, y - i);
0660             }
0661             for (int i = 0;i < length - 1;i++) {
0662                 p.drawPoint(x + 1 + i, y - i);
0663                 p.drawPoint(x + i, y - 1 - i);
0664             }
0665         } else {
0666             for (int i = 1;i < length - 1;i++) {
0667                 p.drawPoint(x + i, y - i);
0668             }
0669             for (int i = 0;i < length - 1;i++) {
0670                 p.drawPoint(x + 1 + i, y - i);
0671                 p.drawPoint(x + i, y - 1 - i);
0672             }
0673             for (int i = 0;i < length - 2;i++) {
0674                 p.drawPoint(x + 2 + i, y - i);
0675                 p.drawPoint(x + i, y - 2 - i);
0676             }
0677         }
0678         break;
0679     case HorizontalLine:
0680         for (int i = 0;i < lineWidth;i++) {
0681             p.drawLine(x, y + i, x + length - 1, y + i);
0682         }
0683         break;
0684     case VerticalLine:
0685         for (int i = 0;i < lineWidth;i++) {
0686             p.drawLine(x + i, y, x + i, y + length - 1);
0687         }
0688     default:
0689         break;
0690     }
0691 }
0692 
0693 }
0694 }