1 /*****************************************************************************
2 * Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com> *
3 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Lesser General Public License as *
7 * published by the Free Software Foundation; either version 2.1 of the *
8 * License, or (at your option) version 3, or any later version accepted *
9 * by the membership of KDE e.V. (or its successor approved by the *
10 * membership of KDE e.V.), which shall act as a proxy defined in *
11 * Section 6 of version 3 of the license. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library. If not, *
20 * see <http://www.gnu.org/licenses/>. *
21 *****************************************************************************/
22 /*
23 based on the window decoration "Plastik":
24 Copyright (C) 2003-2005 Sandro Giessl <sandro@giessl.com>
25
26 based on the window decoration "Web":
27 Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
28 */
29
30 #include "qtcurvebutton.h"
31 #include <QAbstractButton>
32 #include <QStyle>
33 #include <QStyleOption>
34 #include <QBitmap>
35 #include <QPainter>
36 #include <QPixmap>
37 #include <QTimer>
38 #include "qtcurveclient.h"
39 #include <common/common.h>
40
41 namespace QtCurve {
42 namespace KWin {
43
QtCurveButton(ButtonType type,QtCurveClient * parent)44 QtCurveButton::QtCurveButton(ButtonType type, QtCurveClient *parent)
45 : KCommonDecorationButton(type, parent),
46 m_client(parent),
47 m_iconType(NumButtonIcons),
48 m_hover(false)
49 {
50 // setAttribute(Qt::WA_PaintOnScreen, false);
51 setAttribute(Qt::WA_NoSystemBackground, true);
52 setAutoFillBackground(false);
53 // setFocusPolicy(Qt::NoFocus);
54 // setAttribute(Qt::WA_OpaquePaintEvent, false);
55 // setAttribute(Qt::WA_Hover, true);
56 setCursor(Qt::ArrowCursor);
57 reset(DecorationReset);
58 }
59
reset(unsigned long changed)60 void QtCurveButton::reset(unsigned long changed)
61 {
62 if (changed & DecorationReset || changed & ManualReset ||
63 changed & SizeChange || changed & StateChange) {
64 switch (type()) {
65 #if KDE_IS_VERSION(4, 9, 85)
66 case AppMenuButton:
67 m_iconType = MenuIcon;
68 break;
69 #endif
70 // TODO ItemMenuButton?
71 case ItemCloseButton:
72 m_iconType = CloseTabIcon;
73 break;
74 case CloseButton:
75 m_iconType = CloseIcon;
76 break;
77 case HelpButton:
78 m_iconType = HelpIcon;
79 break;
80 case MinButton:
81 m_iconType = MinIcon;
82 break;
83 case MaxButton:
84 m_iconType = isChecked() ? MaxRestoreIcon : MaxIcon;
85 break;
86 case OnAllDesktopsButton:
87 m_iconType = isChecked() ? NotOnAllDesktopsIcon : OnAllDesktopsIcon;
88 break;
89 case ShadeButton:
90 m_iconType = isChecked() ? UnShadeIcon : ShadeIcon;
91 break;
92 case AboveButton:
93 m_iconType = isChecked() ? NoKeepAboveIcon : KeepAboveIcon;
94 break;
95 case BelowButton:
96 m_iconType = isChecked() ? NoKeepBelowIcon : KeepBelowIcon;
97 break;
98 case MenuButton:
99 m_iconType = MenuIcon;
100 break;
101 default:
102 m_iconType = NumButtonIcons; // empty...
103 break;
104 }
105
106 this->update();
107 }
108 }
109
enterEvent(QEvent * e)110 void QtCurveButton::enterEvent(QEvent *e)
111 {
112 m_hover = true;
113 KCommonDecorationButton::enterEvent(e);
114 update();
115 // Hacky NVIDIA fix - sometimes mouseover state gets 'stuck' -
116 // but only for some windows!!!
117 QTimer::singleShot(50, this, SLOT(update()));
118 }
119
leaveEvent(QEvent * e)120 void QtCurveButton::leaveEvent(QEvent *e)
121 {
122 m_hover = false;
123 KCommonDecorationButton::leaveEvent(e);
124 update();
125 // Hacky NVIDIA fix - sometimes mouseover state gets 'stuck' -
126 // but only for some windows!!!
127 QTimer::singleShot(50, this, SLOT(update()));
128 }
129
paintEvent(QPaintEvent * ev)130 void QtCurveButton::paintEvent(QPaintEvent *ev)
131 {
132 if (m_client->compositingActive()) {
133 QPainter p(this);
134 p.setClipRect(rect().intersected(ev->rect()));
135 drawButton(&p);
136 } else {
137 QPixmap pixmap(size());
138 {
139 QPainter p(&pixmap);
140 p.setRenderHints(QPainter::Antialiasing);
141 parentWidget()->render(&p, QPoint(), geometry(),
142 QWidget::DrawWindowBackground);
143 drawButton(&p);
144 }
145 QPainter p(this);
146 p.setClipRect(ev->rect());
147 p.drawPixmap(QPoint(), pixmap);
148 }
149 }
150
drawButton(QPainter * painter)151 void QtCurveButton::drawButton(QPainter *painter)
152 {
153 int flags = Handler()->wStyle()->pixelMetric(
154 (QStyle::PixelMetric)QtC_TitleBarButtons, nullptr, nullptr);
155 bool active(m_client->isActive());
156
157 if (!active && !m_hover && flags & TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW)
158 return;
159
160 QRect r(0, 0, width(), height());
161 int versionHack = 0;
162 bool sunken(isDown());
163 bool drawFrame(!(flags & TITLEBAR_BUTTON_NO_FRAME) &&
164 (m_hover || sunken ||
165 !(flags & TITLEBAR_BUTTON_HOVER_FRAME)));
166 bool drewFrame(false);
167 bool iconForMenu(TITLEBAR_ICON_MENU_BUTTON ==
168 Handler()->wStyle()->pixelMetric(
169 (QStyle::PixelMetric)QtC_TitleBarIcon, nullptr, nullptr));
170 QColor buttonColor(KDecoration::options()->color(KDecoration::ColorTitleBar,
171 active));
172 QPixmap buffer(width(), height());
173 buffer.fill(Qt::transparent);
174 QPainter bP(&buffer);
175 bool isTabClose(ItemCloseButton == type());
176
177 // isItemMenu?
178 if (isTabClose && drawFrame && !(sunken || m_hover))
179 drawFrame = false;
180 // if(CloseButton == type())
181 // buttonColor = midColor(QColor(180,64,32), buttonColor);
182
183 switch (type()) {
184 case HelpButton:
185 versionHack = TBAR_VERSION_HACK + TITLEBAR_HELP;
186 break;
187 case MaxButton:
188 versionHack = TBAR_VERSION_HACK + TITLEBAR_MAX;
189 break;
190 case MinButton:
191 versionHack = TBAR_VERSION_HACK + TITLEBAR_MIN;
192 break;
193 case ItemCloseButton:
194 case CloseButton:
195 versionHack = TBAR_VERSION_HACK + TITLEBAR_CLOSE;
196 break;
197 #if KDE_IS_VERSION(4, 9, 85)
198 case AppMenuButton:
199 #endif
200 case MenuButton:
201 versionHack = TBAR_VERSION_HACK + TITLEBAR_MENU;
202 break;
203 case OnAllDesktopsButton:
204 versionHack = TBAR_VERSION_HACK + TITLEBAR_ALL_DESKTOPS;
205 break;
206 case AboveButton:
207 versionHack = TBAR_VERSION_HACK + TITLEBAR_KEEP_ABOVE;
208 break;
209 case BelowButton:
210 versionHack = TBAR_VERSION_HACK + TITLEBAR_KEEP_BELOW;
211 break;
212 case ShadeButton:
213 versionHack = TBAR_VERSION_HACK + TITLEBAR_SHADE;
214 default:
215 break;
216 }
217
218 if (drawFrame &&
219 (/*!(flags&TITLEBAR_BUTTON_ROUND) || */
220 MenuButton != type() || !iconForMenu)) {
221 QStyleOption opt;
222 int offset = flags & TITLEBAR_BUTTON_ROUND &&
223 !m_client->isToolWindow() ? 1 : 0;
224
225 if (flags & TITLEBAR_BUTTON_SUNKEN_BACKGROUND)
226 // && flags & TITLEBAR_BUTTON_ROUND)
227 offset++;
228 opt.init(this);
229 opt.rect = QRect(offset, offset, width() - (2 * offset),
230 height() - (2 * offset));
231 opt.state |= (isDown() ? QStyle::State_Sunken : QStyle::State_Raised) |
232 (active ? QStyle::State_Active : QStyle::State_None) |
233 (m_hover ? QStyle::State_MouseOver : QStyle::State_None) |
234 QStyle::State_Horizontal | QtC_StateKWin;
235 opt.state &= ~QStyle::State_HasFocus;
236 if (!isEnabled()) {
237 opt.palette.setColor(QPalette::Button, buttonColor);
238 } else {
239 if (!(flags & TITLEBAR_BUTTON_STD_COLOR) ||
240 (flags & TITLEBAR_BUTTON_COLOR_MOUSE_OVER && !m_hover &&
241 !(flags&TITLEBAR_BUTTON_COLOR)))
242 opt.palette.setColor(QPalette::Button, buttonColor);
243 if (flags & TITLEBAR_BUTTON_COLOR &&
244 !(flags & TITLEBAR_BUTTON_COLOR_SYMBOL))
245 opt.version = versionHack;
246 }
247 Handler()->wStyle()->drawPrimitive(QStyle::PE_PanelButtonCommand,
248 &opt, &bP, nullptr);
249 drewFrame = true;
250 }
251
252 if (MenuButton == type() && iconForMenu) {
253 QPixmap menuIcon(m_client->icon().pixmap(
254 style()->pixelMetric(QStyle::PM_SmallIconSize)));
255 if (width() < menuIcon.width() || height() < menuIcon.height())
256 menuIcon = menuIcon.scaled(width(), height());
257
258 int dX(((width() - menuIcon.width()) / 2.0) + 0.5),
259 dY(((height() - menuIcon.height()) / 2.0) + 0.5);
260
261 if (sunken) {
262 dY++;
263 dX++;
264 }
265 bP.drawPixmap(dX, dY, menuIcon);
266 } else if (isEnabled() && (!(flags & TITLEBAR_BUTTON_HOVER_SYMBOL_FULL) ||
267 sunken || m_hover)) {
268 const QBitmap &icon =
269 Handler()->buttonBitmap(m_iconType, size(),
270 decoration()->isToolWindow());
271 bool customCol(false);
272 bool faded(!m_hover && flags & TITLEBAR_BUTTON_HOVER_SYMBOL);
273 QColor col(KDecoration::options()->color(KDecoration::ColorFont, active/* || faded*/));
274 int dX(r.x()+(r.width() - icon.width())/2);
275 int dY(r.y()+(r.height() - icon.height())/2);
276 EEffect effect((EEffect)(style()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarEffect)));
277
278 if(EFFECT_ETCH==effect && drewFrame)
279 effect=EFFECT_SHADOW;
280
281 if(m_hover || !(flags&TITLEBAR_BUTTON_HOVER_SYMBOL))
282 {
283 bool userDefined=flags&TITLEBAR_BUTTON_ICON_COLOR;
284
285 if(userDefined || (flags&TITLEBAR_BUTTON_COLOR && flags&TITLEBAR_BUTTON_COLOR_SYMBOL))
286 {
287 QStyleOption opt;
288
289 opt.init(this);
290 if(userDefined)
291 {
292 versionHack+=NUM_TITLEBAR_BUTTONS;
293 if(!active)
294 versionHack+=NUM_TITLEBAR_BUTTONS;
295 }
296 opt.version=versionHack;
297 col=QColor(QRgb(Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarIconColor, &opt, nullptr)));
298 customCol=true;
299 }
300 }
301
302 if (sunken) {
303 dY++;
304 dX++;
305 } else if (!faded && EFFECT_NONE != effect) {
306 QColor shadow(WINDOW_SHADOW_COLOR(effect));
307
308 shadow.setAlphaF(WINDOW_TEXT_SHADOW_ALPHA(effect));
309 bP.setPen(shadow);
310 bP.drawPixmap(EFFECT_SHADOW==effect ? dX+1 : dX, dY+1, icon);
311 }
312
313 if (m_hover && !sunken && !(flags&TITLEBAR_BUTTON_COLOR) && !customCol) {
314 if (CloseButton == type() || isTabClose) {
315 col = CLOSE_COLOR;
316 } else if(flags&TITLEBAR_BUTTON_USE_HOVER_COLOR) {
317 col = Handler()->hoverCol(active);
318 }
319 }
320
321 if (faded) {
322 col.setAlphaF(HOVER_BUTTON_ALPHA(col));
323 } else {
324 // If dont set an alpha level here, then (at least on intel)
325 // the background colour is used!
326 col.setAlpha(254);
327 }
328
329 bP.setPen(col);
330 bP.drawPixmap(dX, dY, icon);
331 }
332
333 bP.end();
334 painter->drawPixmap(0, 0, buffer);
335 }
336
icon(ButtonIcon icon,int size,QStyle * style)337 QBitmap IconEngine::icon(ButtonIcon icon, int size, QStyle *style)
338 {
339 if (size%2 == 0)
340 --size;
341
342 QBitmap bitmap(size, size);
343 bitmap.fill(Qt::color0);
344 QPainter p(&bitmap);
345
346 p.setPen(Qt::color1);
347
348 QRect r = bitmap.rect();
349
350 // line widths
351 int lwTitleBar = 1;
352 if (r.width() > 16)
353 lwTitleBar = 4;
354 else if (r.width() > 4)
355 lwTitleBar = 2;
356
357 switch (icon) {
358 case CloseTabIcon:
359 r.adjust(1, 1, -1, -1);
360 case CloseIcon: {
361 int lineWidth = 1;
362 if (r.width() > 16) {
363 lineWidth = 3;
364 } else if (r.width() > 4) {
365 lineWidth = 2;
366 }
367
368 drawObject(p, DiagonalLine, r.x(), r.y(), r.width(), lineWidth);
369 drawObject(p, CrossDiagonalLine, r.x(), r.bottom(),
370 r.width(), lineWidth);
371 break;
372 }
373 case MaxIcon:
374 if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, nullptr, nullptr) & TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
375 QStyleOption opt;
376 opt.rect = r;
377 opt.state = QStyle::State_Enabled | QtC_StateKWin;
378 style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, nullptr);
379 } else {
380 int lineWidth2 = 1; // frame
381 if (r.width() > 16) {
382 lineWidth2 = 2;
383 } else if (r.width() > 4) {
384 lineWidth2 = 1;
385 }
386 drawObject(p, HorizontalLine, r.x(), r.top(),
387 r.width(), lwTitleBar);
388 drawObject(p, HorizontalLine, r.x(), r.bottom() - (lineWidth2 - 1),
389 r.width(), lineWidth2);
390 drawObject(p, VerticalLine, r.x(), r.top(), r.height(), lineWidth2);
391 drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1),
392 r.top(), r.height(), lineWidth2);
393 }
394 break;
395 case MaxRestoreIcon:
396 if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, nullptr, nullptr) & TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
397 p.drawLine(r.x() + 1, r.y(), r.x() + r.width() - 2, r.y());
398 p.drawLine(r.x() + 1, r.y() + r.height() - 1,
399 r.x() + r.width() - 2, r.y() + r.height() - 1);
400 p.drawLine(r.x(), r.y() + 1, r.x(), r.y() + r.height() - 2);
401 p.drawLine(r.x() + r.width() - 1, r.y() + 1,
402 r.x() + r.width() - 1, r.y() + r.height() - 2);
403 p.drawRect(r.x() + 1, r.y() + 1, r.width() - 3, r.height() - 3);
404 } else {
405 int lineWidth2 = 1; // frame
406 if (r.width() > 16) {
407 lineWidth2 = 2;
408 } else if (r.width() > 4) {
409 lineWidth2 = 1;
410 }
411 int margin1, margin2;
412 margin1 = margin2 = lineWidth2 * 2 + 1;
413 if (r.width() < 8)
414 margin1 = 1;
415 int margin1h = margin1 - 1;
416 int margin2h = margin2 - 1;
417
418 // background window
419 drawObject(p, HorizontalLine, r.x() + margin1h, r.top(),
420 r.width() - margin1, lwTitleBar);
421 drawObject(p, HorizontalLine, r.right() - margin2h,
422 r.bottom() - (lineWidth2 - 1) - margin1, margin2h,
423 lineWidth2);
424 drawObject(p, VerticalLine, r.x() + margin1h, r.top(), margin2,
425 lineWidth2);
426 drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1),
427 r.top(), r.height() - margin1, lineWidth2);
428
429 // foreground window
430 drawObject(p, HorizontalLine, r.x(), r.top() + margin2,
431 r.width() - margin2h, lwTitleBar);
432 drawObject(p, HorizontalLine, r.x(),
433 r.bottom() - (lineWidth2 - 1), r.width() - margin2h,
434 lineWidth2);
435 drawObject(p, VerticalLine, r.x(), r.top() + margin2, r.height(),
436 lineWidth2);
437 drawObject(p, VerticalLine, r.right() - (lineWidth2 - 1) - margin2h,
438 r.top() + margin2, r.height(), lineWidth2);
439 }
440 break;
441 case MinIcon:
442 if (Handler()->wStyle()->pixelMetric((QStyle::PixelMetric)QtC_TitleBarButtons, nullptr, nullptr)&TITLEBAR_BUTTOM_ARROW_MIN_MAX) {
443 QStyleOption opt;
444
445 opt.rect = r;
446 opt.state = QStyle::State_Enabled | QtC_StateKWin;
447 style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, nullptr);
448 } else {
449 drawObject(p, HorizontalLine, r.x(), r.bottom() - (lwTitleBar - 1),
450 r.width(), lwTitleBar);
451 }
452 break;
453 case HelpIcon: {
454 int center = r.x()+r.width()/2; // -1;
455 int side = r.width()/4;
456
457 // paint a question mark... code is quite messy,
458 // to be cleaned up later...! :o
459 if (r.width() > 16) {
460 int lineWidth = 3;
461
462 // top bar
463 drawObject(p, HorizontalLine, center - side + 3, r.y(),
464 2 * side - 3 - 1, lineWidth);
465 // top bar rounding
466 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 5,
467 6, lineWidth);
468 drawObject(p, DiagonalLine, center + side - 3, r.y(), 5, lineWidth);
469 // right bar
470 drawObject(p, VerticalLine, center + side + 2 - lineWidth,
471 r.y() + 3, r.height() - (2 * lineWidth + side + 2 + 1),
472 lineWidth);
473 // bottom bar
474 drawObject(p, CrossDiagonalLine, center, r.bottom() - 2 * lineWidth,
475 side + 2, lineWidth);
476 drawObject(p, HorizontalLine, center,
477 r.bottom() - 3 * lineWidth + 2, lineWidth, lineWidth);
478 // the dot
479 drawObject(p, HorizontalLine, center, r.bottom() - (lineWidth - 1),
480 lineWidth, lineWidth);
481 } else if (r.width() > 8) {
482 int lineWidth = 2;
483
484 // top bar
485 drawObject(p, HorizontalLine, center - (side - 1), r.y(),
486 2 * side - 1, lineWidth);
487 // top bar rounding
488 if (r.width() > 9)
489 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 3, 3, lineWidth);
490 else
491 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 2, 3, lineWidth);
492 drawObject(p, DiagonalLine, center + side - 1, r.y(), 3, lineWidth);
493 // right bar
494 drawObject(p, VerticalLine, center + side + 2 - lineWidth, r.y() + 2, r.height() - (2*lineWidth + side + 1), lineWidth);
495 // bottom bar
496 drawObject(p, CrossDiagonalLine, center, r.bottom() - 2*lineWidth + 1, side + 2, lineWidth);
497 // the dot
498 drawObject(p, HorizontalLine, center, r.bottom() - (lineWidth - 1), lineWidth, lineWidth);
499 }
500 else
501 {
502 int lineWidth = 1;
503
504 // top bar
505 drawObject(p, HorizontalLine, center - (side - 1), r.y(), 2*side, lineWidth);
506 // top bar rounding
507 drawObject(p, CrossDiagonalLine, center - side - 1, r.y() + 1, 2, lineWidth);
508 // right bar
509 drawObject(p, VerticalLine, center + side + 1, r.y(), r.height() - (side + 2 + 1), lineWidth);
510 // bottom bar
511 drawObject(p, CrossDiagonalLine, center, r.bottom() - 2, side + 2, lineWidth);
512 // the dot
513 drawObject(p, HorizontalLine, center, r.bottom(), 1, 1);
514 }
515
516 break;
517 }
518 case NotOnAllDesktopsIcon:
519 {
520 r.adjust(1, 1, -1, -1);
521
522 int lwMark = (r.width() - 1)/2;
523 if (lwMark < 1)
524 lwMark = 3;
525
526 drawObject(p, HorizontalLine, r.x(), r.y(), lwMark, lwMark);
527 drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark), r.y(), lwMark, lwMark);
528 drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark), r.y() + (r.height() - lwMark), lwMark, lwMark);
529 drawObject(p, HorizontalLine, r.x(), r.y() + (r.height() - lwMark), lwMark, lwMark);
530 break;
531 }
532 case OnAllDesktopsIcon:
533 {
534 int lwMark = r.width() - lwTitleBar*2 - 2;
535 if (lwMark < 1)
536 lwMark = 3;
537
538 drawObject(p, HorizontalLine, r.x() + (r.width() - lwMark)/2, r.y() + (r.height() - lwMark)/2, lwMark, lwMark);
539 break;
540 }
541 case NoKeepAboveIcon:
542 case KeepAboveIcon:
543 {
544 QStyleOption opt;
545
546 opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
547 opt.rect.adjust(2, 2, -2, -2);
548 opt.state=QStyle::State_Enabled|QtC_StateKWin;
549
550 opt.rect.adjust(0, -1, 0, -1);
551 if(NoKeepAboveIcon==icon)
552 {
553 int w=r.width()/3;
554 if(0==w%2)
555 w++;
556 drawObject(p, HorizontalLine, r.x() + (r.width() - w)/2, r.y() + 1, w, 2);
557 }
558 else
559 style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, nullptr);
560 opt.rect.adjust(0, 4, 0, 4);
561 style->drawPrimitive(QStyle::PE_IndicatorArrowUp, &opt, &p, nullptr);
562 break;
563 }
564 case NoKeepBelowIcon:
565 case KeepBelowIcon:
566 {
567 QStyleOption opt;
568
569 opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
570 opt.rect.adjust(2, 2, -2, -2);
571 opt.state=QStyle::State_Enabled|QtC_StateKWin;
572 opt.rect.adjust(0, -1, 0, -1);
573 style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, nullptr);
574 opt.rect.adjust(0, 4, 0, 4);
575 if(NoKeepBelowIcon==icon)
576 {
577 int w=r.width()/3;
578 if(0==w%2)
579 w++;
580 drawObject(p, HorizontalLine, r.x() + (r.width() - w)/2, r.y() + r.height() - 3, w, 2);
581 }
582 else
583 style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, nullptr);
584 break;
585 }
586 case UnShadeIcon:
587 case ShadeIcon: {
588 QStyleOption opt;
589
590 //opt.init(btn);
591 opt.rect=r.adjusted(0, -(1 + lwTitleBar), 0, 0);
592 opt.rect.adjust(2, 2, -2, -2);
593 if(UnShadeIcon==icon)
594 opt.rect.adjust(0, -1, 0, -1);
595 opt.state=QStyle::State_Enabled|QtC_StateKWin;
596
597 //opt.palette.setColor(QPalette::Button, Qt::red);
598 style->drawPrimitive(icon == ShadeIcon ?
599 QStyle::PE_IndicatorArrowDown :
600 QStyle::PE_IndicatorArrowUp,
601 &opt, &p, nullptr);
602 drawObject(p, HorizontalLine, r.x() + 1, r.bottom() - (lwTitleBar - 1),
603 r.width() - 2, lwTitleBar);
604 break;
605 }
606 case MenuIcon: {
607 int offset=(r.height() - 7)/2;
608 for (int i = 0;i < 3;i++)
609 drawObject(p, HorizontalLine, r.x() + 1, r.y() + offset + (i*3), r.width() - 2, 1);
610 break;
611 }
612 default:
613 break;
614 }
615
616 p.end();
617 bitmap.setMask(bitmap);
618
619 return bitmap;
620 }
621
622 void
drawObject(QPainter & p,Object object,int x,int y,int length,int lineWidth)623 IconEngine::drawObject(QPainter &p, Object object, int x, int y,
624 int length, int lineWidth)
625 {
626 switch(object) {
627 case DiagonalLine:
628 if (lineWidth <= 1) {
629 for (int i = 0;i < length;i++) {
630 p.drawPoint(x + i, y + i);
631 }
632 } else if (lineWidth <= 2) {
633 for (int i = 0;i < length;i++) {
634 p.drawPoint(x + i, y + i);
635 }
636 for (int i = 0;i < length - 1;i++) {
637 p.drawPoint(x + 1 + i, y + i);
638 p.drawPoint(x + i, y + 1 + i);
639 }
640 } else {
641 for (int i = 1;i < length - 1;i++) {
642 p.drawPoint(x + i, y + i);
643 }
644 for (int i = 0;i < length - 1;i++) {
645 p.drawPoint(x + 1 + i, y + i);
646 p.drawPoint(x + i, y + 1 + i);
647 }
648 for (int i = 0;i < (length - 2);i++) {
649 p.drawPoint(x + 2 + i, y + i);
650 p.drawPoint(x + i, y + 2 + i);
651 }
652 }
653 break;
654 case CrossDiagonalLine:
655 if (lineWidth <= 1) {
656 for (int i = 0;i < length;i++) {
657 p.drawPoint(x + i, y - i);
658 }
659 } else if (lineWidth <= 2) {
660 for (int i = 0;i < length;i++) {
661 p.drawPoint(x + i, y - i);
662 }
663 for (int i = 0;i < length - 1;i++) {
664 p.drawPoint(x + 1 + i, y - i);
665 p.drawPoint(x + i, y - 1 - i);
666 }
667 } else {
668 for (int i = 1;i < length - 1;i++) {
669 p.drawPoint(x + i, y - i);
670 }
671 for (int i = 0;i < length - 1;i++) {
672 p.drawPoint(x + 1 + i, y - i);
673 p.drawPoint(x + i, y - 1 - i);
674 }
675 for (int i = 0;i < length - 2;i++) {
676 p.drawPoint(x + 2 + i, y - i);
677 p.drawPoint(x + i, y - 2 - i);
678 }
679 }
680 break;
681 case HorizontalLine:
682 for (int i = 0;i < lineWidth;i++) {
683 p.drawLine(x, y + i, x + length - 1, y + i);
684 }
685 break;
686 case VerticalLine:
687 for (int i = 0;i < lineWidth;i++) {
688 p.drawLine(x + i, y, x + i, y + length - 1);
689 }
690 default:
691 break;
692 }
693 }
694
695 }
696 }
697