1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include "qfusionstyle_p.h"
41 #include "qfusionstyle_p_p.h"
42
43 #if QT_CONFIG(style_fusion) || defined(QT_PLUGIN)
44 #include "qcommonstyle_p.h"
45 #if QT_CONFIG(combobox)
46 #include <qcombobox.h>
47 #endif
48 #if QT_CONFIG(pushbutton)
49 #include <qpushbutton.h>
50 #endif
51 #if QT_CONFIG(abstractbutton)
52 #include <qabstractbutton.h>
53 #endif
54 #include <qpainter.h>
55 #include <qpainterpath.h>
56 #include <qdir.h>
57 #include <qstyleoption.h>
58 #include <qapplication.h>
59 #if QT_CONFIG(mainwindow)
60 #include <qmainwindow.h>
61 #endif
62 #include <qfont.h>
63 #if QT_CONFIG(groupbox)
64 #include <qgroupbox.h>
65 #endif
66 #include <qpixmapcache.h>
67 #if QT_CONFIG(scrollbar)
68 #include <qscrollbar.h>
69 #endif
70 #if QT_CONFIG(spinbox)
71 #include <qspinbox.h>
72 #endif
73 #if QT_CONFIG(abstractslider)
74 #include <qabstractslider.h>
75 #endif
76 #if QT_CONFIG(slider)
77 #include <qslider.h>
78 #endif
79 #if QT_CONFIG(splitter)
80 #include <qsplitter.h>
81 #endif
82 #if QT_CONFIG(progressbar)
83 #include <qprogressbar.h>
84 #endif
85 #if QT_CONFIG(wizard)
86 #include <qwizard.h>
87 #endif
88 #include <qdrawutil.h>
89 #include <private/qstylehelper_p.h>
90 #include <private/qdrawhelper_p.h>
91 #include <private/qapplication_p.h>
92 #include <private/qwidget_p.h>
93
94 QT_BEGIN_NAMESPACE
95
96 using namespace QStyleHelper;
97
98 enum Direction {
99 TopDown,
100 FromLeft,
101 BottomUp,
102 FromRight
103 };
104
105 // from windows style
106 static const int windowsItemFrame = 2; // menu item frame width
107 static const int windowsItemHMargin = 3; // menu item hor text margin
108 static const int windowsItemVMargin = 8; // menu item ver text margin
109 static const int windowsRightBorder = 15; // right border on windows
110
111 static const int groupBoxBottomMargin = 0; // space below the groupbox
112 static const int groupBoxTopMargin = 3;
113
114 #if QT_CONFIG(imageformat_xpm)
115 /* XPM */
116 static const char * const dock_widget_close_xpm[] = {
117 "11 13 7 1",
118 " c None",
119 ". c #D5CFCB",
120 "+ c #8F8B88",
121 "@ c #6C6A67",
122 "# c #ABA6A3",
123 "$ c #B5B0AC",
124 "% c #A4A09D",
125 " ",
126 " +@@@@@@@+ ",
127 "+# #+",
128 "@ $@ @$ @",
129 "@ @@@ @@@ @",
130 "@ @@@@@ @",
131 "@ @@@ @",
132 "@ @@@@@ @",
133 "@ @@@ @@@ @",
134 "@ $@ @$ @",
135 "+% #+",
136 " +@@@@@@@+ ",
137 " "};
138
139 static const char * const dock_widget_restore_xpm[] = {
140 "11 13 7 1",
141 " c None",
142 ". c #D5CFCB",
143 "+ c #8F8B88",
144 "@ c #6C6A67",
145 "# c #ABA6A3",
146 "$ c #B5B0AC",
147 "% c #A4A09D",
148 " ",
149 " +@@@@@@@+ ",
150 "+# #+",
151 "@ #@@@# @",
152 "@ @ @ @",
153 "@ #@@@# @ @",
154 "@ @ @ @ @",
155 "@ @ @@@ @",
156 "@ @ @ @",
157 "@ #@@@# @",
158 "+% #+",
159 " +@@@@@@@+ ",
160 " "};
161
162 static const char * const workspace_minimize[] = {
163 "11 13 7 1",
164 " c None",
165 ". c #D5CFCB",
166 "+ c #8F8B88",
167 "@ c #6C6A67",
168 "# c #ABA6A3",
169 "$ c #B5B0AC",
170 "% c #A4A09D",
171 " ",
172 " +@@@@@@@+ ",
173 "+# #+",
174 "@ @",
175 "@ @",
176 "@ @",
177 "@ @@@@@@@ @",
178 "@ @@@@@@@ @",
179 "@ @",
180 "@ @",
181 "+% #+",
182 " +@@@@@@@+ ",
183 " "};
184
185
186 static const char * const qt_titlebar_context_help[] = {
187 "10 10 3 1",
188 " c None",
189 "# c #000000",
190 "+ c #444444",
191 " +####+ ",
192 " ### ### ",
193 " ## ## ",
194 " +##+ ",
195 " +## ",
196 " ## ",
197 " ## ",
198 " ",
199 " ## ",
200 " ## "};
201 #endif // QT_CONFIG(imageformat_xpm)
202
mergedColors(const QColor & colorA,const QColor & colorB,int factor=50)203 static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
204 {
205 const int maxFactor = 100;
206 QColor tmp = colorA;
207 tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
208 tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
209 tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
210 return tmp;
211 }
212
213 // The default button and handle gradient
qt_fusion_gradient(const QRect & rect,const QBrush & baseColor,Direction direction=TopDown)214 static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown)
215 {
216 int x = rect.center().x();
217 int y = rect.center().y();
218 QLinearGradient gradient;
219 switch (direction) {
220 case FromLeft:
221 gradient = QLinearGradient(rect.left(), y, rect.right(), y);
222 break;
223 case FromRight:
224 gradient = QLinearGradient(rect.right(), y, rect.left(), y);
225 break;
226 case BottomUp:
227 gradient = QLinearGradient(x, rect.bottom(), x, rect.top());
228 break;
229 case TopDown:
230 default:
231 gradient = QLinearGradient(x, rect.top(), x, rect.bottom());
232 break;
233 }
234 if (baseColor.gradient())
235 gradient.setStops(baseColor.gradient()->stops());
236 else {
237 QColor gradientStartColor = baseColor.color().lighter(124);
238 QColor gradientStopColor = baseColor.color().lighter(102);
239 gradient.setColorAt(0, gradientStartColor);
240 gradient.setColorAt(1, gradientStopColor);
241 // Uncomment for adding shiny shading
242 // QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55);
243 // QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45);
244 // gradient.setColorAt(0.5, midColor1);
245 // gradient.setColorAt(0.501, midColor2);
246 }
247 return gradient;
248 }
249
qt_fusion_draw_arrow(Qt::ArrowType type,QPainter * painter,const QStyleOption * option,const QRect & rect,const QColor & color)250 static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QStyleOption *option, const QRect &rect, const QColor &color)
251 {
252 if (rect.isEmpty())
253 return;
254
255 const qreal dpi = QStyleHelper::dpi(option);
256 const int arrowWidth = int(QStyleHelper::dpiScaled(14, dpi));
257 const int arrowHeight = int(QStyleHelper::dpiScaled(8, dpi));
258
259 const int arrowMax = qMin(arrowHeight, arrowWidth);
260 const int rectMax = qMin(rect.height(), rect.width());
261 const int size = qMin(arrowMax, rectMax);
262
263 QPixmap cachePixmap;
264 QString cacheKey = QStyleHelper::uniqueName(QLatin1String("fusion-arrow"), option, rect.size())
265 % HexString<uint>(type)
266 % HexString<uint>(color.rgba());
267 if (!QPixmapCache::find(cacheKey, &cachePixmap)) {
268 cachePixmap = styleCachePixmap(rect.size());
269 cachePixmap.fill(Qt::transparent);
270 QPainter cachePainter(&cachePixmap);
271
272 QRectF arrowRect;
273 arrowRect.setWidth(size);
274 arrowRect.setHeight(arrowHeight * size / arrowWidth);
275 if (type == Qt::LeftArrow || type == Qt::RightArrow)
276 arrowRect = arrowRect.transposed();
277 arrowRect.moveTo((rect.width() - arrowRect.width()) / 2.0,
278 (rect.height() - arrowRect.height()) / 2.0);
279
280 QPolygonF triangle;
281 triangle.reserve(3);
282 switch (type) {
283 case Qt::DownArrow:
284 triangle << arrowRect.topLeft() << arrowRect.topRight() << QPointF(arrowRect.center().x(), arrowRect.bottom());
285 break;
286 case Qt::RightArrow:
287 triangle << arrowRect.topLeft() << arrowRect.bottomLeft() << QPointF(arrowRect.right(), arrowRect.center().y());
288 break;
289 case Qt::LeftArrow:
290 triangle << arrowRect.topRight() << arrowRect.bottomRight() << QPointF(arrowRect.left(), arrowRect.center().y());
291 break;
292 default:
293 triangle << arrowRect.bottomLeft() << arrowRect.bottomRight() << QPointF(arrowRect.center().x(), arrowRect.top());
294 break;
295 }
296
297 cachePainter.setPen(Qt::NoPen);
298 cachePainter.setBrush(color);
299 cachePainter.setRenderHint(QPainter::Antialiasing);
300 cachePainter.drawPolygon(triangle);
301
302 QPixmapCache::insert(cacheKey, cachePixmap);
303 }
304
305 painter->drawPixmap(rect, cachePixmap);
306 }
307
qt_fusion_draw_mdibutton(QPainter * painter,const QStyleOptionTitleBar * option,const QRect & tmp,bool hover,bool sunken)308 static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
309 {
310 QColor dark;
311 dark.setHsv(option->palette.button().color().hue(),
312 qMin(255, (int)(option->palette.button().color().saturation())),
313 qMin(255, (int)(option->palette.button().color().value()*0.7)));
314
315 QColor highlight = option->palette.highlight().color();
316
317 bool active = (option->titleBarState & QStyle::State_Active);
318 QColor titleBarHighlight(255, 255, 255, 60);
319
320 if (sunken)
321 painter->fillRect(tmp.adjusted(1, 1, -1, -1), option->palette.highlight().color().darker(120));
322 else if (hover)
323 painter->fillRect(tmp.adjusted(1, 1, -1, -1), QColor(255, 255, 255, 20));
324
325 QColor mdiButtonGradientStartColor;
326 QColor mdiButtonGradientStopColor;
327
328 mdiButtonGradientStartColor = QColor(0, 0, 0, 40);
329 mdiButtonGradientStopColor = QColor(255, 255, 255, 60);
330
331 if (sunken)
332 titleBarHighlight = highlight.darker(130);
333
334 QLinearGradient gradient(tmp.center().x(), tmp.top(), tmp.center().x(), tmp.bottom());
335 gradient.setColorAt(0, mdiButtonGradientStartColor);
336 gradient.setColorAt(1, mdiButtonGradientStopColor);
337 QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110));
338
339 painter->setPen(QPen(mdiButtonBorderColor));
340 const QLine lines[4] = {
341 QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
342 QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
343 QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
344 QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2)
345 };
346 painter->drawLines(lines, 4);
347 const QPoint points[4] = {
348 QPoint(tmp.left() + 1, tmp.top() + 1),
349 QPoint(tmp.right() - 1, tmp.top() + 1),
350 QPoint(tmp.left() + 1, tmp.bottom() - 1),
351 QPoint(tmp.right() - 1, tmp.bottom() - 1)
352 };
353 painter->drawPoints(points, 4);
354
355 painter->setPen(titleBarHighlight);
356 painter->drawLine(tmp.left() + 2, tmp.top() + 1, tmp.right() - 2, tmp.top() + 1);
357 painter->drawLine(tmp.left() + 1, tmp.top() + 2, tmp.left() + 1, tmp.bottom() - 2);
358
359 painter->setPen(QPen(gradient, 1));
360 painter->drawLine(tmp.right() + 1, tmp.top() + 2, tmp.right() + 1, tmp.bottom() - 2);
361 painter->drawPoint(tmp.right() , tmp.top() + 1);
362
363 painter->drawLine(tmp.left() + 2, tmp.bottom() + 1, tmp.right() - 2, tmp.bottom() + 1);
364 painter->drawPoint(tmp.left() + 1, tmp.bottom());
365 painter->drawPoint(tmp.right() - 1, tmp.bottom());
366 painter->drawPoint(tmp.right() , tmp.bottom() - 1);
367 }
368
qt_getWindow(const QWidget * widget)369 static QWindow *qt_getWindow(const QWidget *widget)
370 {
371 return widget ? QWidgetPrivate::get(widget)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest) : nullptr;
372 }
373
374 /*
375 \internal
376 */
QFusionStylePrivate()377 QFusionStylePrivate::QFusionStylePrivate()
378 {
379 animationFps = 60;
380 }
381
382 /*!
383 \class QFusionStyle
384 \brief The QFusionStyle class provides a custom widget style
385
386 \inmodule QtWidgets
387 \internal
388
389 The Fusion style provides a custom look and feel that is not
390 tied to a particular platform.
391 //{Fusion Style Widget Gallery}
392 \sa QWindowsStyle, QWindowsVistaStyle, QMacStyle, QCommonStyle
393 */
394
395 /*!
396 Constructs a QFusionStyle object.
397 */
QFusionStyle()398 QFusionStyle::QFusionStyle() : QCommonStyle(*new QFusionStylePrivate)
399 {
400 setObjectName(QLatin1String("Fusion"));
401 }
402
403 /*!
404 \internal
405
406 Constructs a QFusionStyle object.
407 */
QFusionStyle(QFusionStylePrivate & dd)408 QFusionStyle::QFusionStyle(QFusionStylePrivate &dd) : QCommonStyle(dd)
409 {
410 }
411
412 /*!
413 Destroys the QFusionStyle object.
414 */
~QFusionStyle()415 QFusionStyle::~QFusionStyle()
416 {
417 }
418
419 /*!
420 \fn void QFusionStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette,
421 bool enabled, const QString& text, QPalette::ColorRole textRole) const
422
423 Draws the given \a text in the specified \a rectangle using the
424 provided \a painter and \a palette.
425
426 Text is drawn using the painter's pen. If an explicit \a textRole
427 is specified, then the text is drawn using the \a palette's color
428 for the specified role. The \a enabled value indicates whether or
429 not the item is enabled; when reimplementing, this value should
430 influence how the item is drawn.
431
432 The text is aligned and wrapped according to the specified \a
433 alignment.
434
435 \sa Qt::Alignment
436 */
drawItemText(QPainter * painter,const QRect & rect,int alignment,const QPalette & pal,bool enabled,const QString & text,QPalette::ColorRole textRole) const437 void QFusionStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
438 bool enabled, const QString& text, QPalette::ColorRole textRole) const
439 {
440 if (text.isEmpty())
441 return;
442
443 QPen savedPen = painter->pen();
444 if (textRole != QPalette::NoRole) {
445 painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
446 }
447 if (!enabled) {
448 QPen pen = painter->pen();
449 painter->setPen(pen);
450 }
451 painter->drawText(rect, alignment, text);
452 painter->setPen(savedPen);
453 }
454
455
456 /*!
457 \reimp
458 */
drawPrimitive(PrimitiveElement elem,const QStyleOption * option,QPainter * painter,const QWidget * widget) const459 void QFusionStyle::drawPrimitive(PrimitiveElement elem,
460 const QStyleOption *option,
461 QPainter *painter, const QWidget *widget) const
462 {
463 Q_ASSERT(option);
464 Q_D (const QFusionStyle);
465
466 QRect rect = option->rect;
467 int state = option->state;
468
469 QColor outline = d->outline(option->palette);
470 QColor highlightedOutline = d->highlightedOutline(option->palette);
471
472 QColor tabFrameColor = d->tabFrameColor(option->palette);
473
474 switch (elem) {
475
476 #if QT_CONFIG(groupbox)
477 // No frame drawn
478 case PE_FrameGroupBox:
479 {
480 QPixmap pixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_groupbox.png"));
481 int topMargin = 0;
482 auto control = qobject_cast<const QGroupBox *>(widget);
483 if (control && !control->isCheckable() && control->title().isEmpty()) {
484 // Shrinking the topMargin if Not checkable AND title is empty
485 topMargin = groupBoxTopMargin;
486 } else {
487 topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
488 }
489 QRect frame = option->rect.adjusted(0, topMargin, 0, 0);
490 qDrawBorderPixmap(painter, frame, QMargins(6, 6, 6, 6), pixmap);
491 break;
492 }
493 #endif // QT_CONFIG(groupbox)
494 case PE_IndicatorBranch: {
495 if (!(option->state & State_Children))
496 break;
497 if (option->state & State_Open)
498 drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
499 else {
500 const bool reverse = (option->direction == Qt::RightToLeft);
501 drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget);
502 }
503 break;
504 }
505 #if QT_CONFIG(tabbar)
506 case PE_FrameTabBarBase:
507 if (const QStyleOptionTabBarBase *tbb
508 = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
509 painter->save();
510 painter->setPen(QPen(outline.lighter(110)));
511 switch (tbb->shape) {
512 case QTabBar::RoundedNorth: {
513 QRegion region(tbb->rect);
514 region -= tbb->selectedTabRect;
515 painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
516 painter->setClipRegion(region);
517 painter->setPen(option->palette.light().color());
518 painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1), tbb->rect.topRight() + QPoint(0, 1));
519 }
520 break;
521 case QTabBar::RoundedWest:
522 painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
523 break;
524 case QTabBar::RoundedSouth:
525 painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
526 tbb->rect.right(), tbb->rect.bottom());
527 break;
528 case QTabBar::RoundedEast:
529 painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
530 break;
531 case QTabBar::TriangularNorth:
532 case QTabBar::TriangularEast:
533 case QTabBar::TriangularWest:
534 case QTabBar::TriangularSouth:
535 painter->restore();
536 QCommonStyle::drawPrimitive(elem, option, painter, widget);
537 return;
538 }
539 painter->restore();
540 }
541 return;
542 #endif // QT_CONFIG(tabbar)
543 case PE_PanelScrollAreaCorner: {
544 painter->save();
545 QColor alphaOutline = outline;
546 alphaOutline.setAlpha(180);
547 painter->setPen(alphaOutline);
548 painter->setBrush(option->palette.brush(QPalette::Window));
549 painter->drawRect(option->rect);
550 painter->restore();
551 } break;
552 case PE_IndicatorArrowUp:
553 case PE_IndicatorArrowDown:
554 case PE_IndicatorArrowRight:
555 case PE_IndicatorArrowLeft:
556 {
557 if (option->rect.width() <= 1 || option->rect.height() <= 1)
558 break;
559 QColor arrowColor = option->palette.windowText().color();
560 arrowColor.setAlpha(160);
561 Qt::ArrowType arrow = Qt::UpArrow;
562 switch (elem) {
563 case PE_IndicatorArrowDown:
564 arrow = Qt::DownArrow;
565 break;
566 case PE_IndicatorArrowRight:
567 arrow = Qt::RightArrow;
568 break;
569 case PE_IndicatorArrowLeft:
570 arrow = Qt::LeftArrow;
571 break;
572 default:
573 break;
574 }
575 qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor);
576 }
577 break;
578 case PE_IndicatorItemViewItemCheck:
579 {
580 QStyleOptionButton button;
581 button.QStyleOption::operator=(*option);
582 button.state &= ~State_MouseOver;
583 proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
584 }
585 return;
586 case PE_IndicatorHeaderArrow:
587 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
588 QRect r = header->rect;
589 QColor arrowColor = header->palette.windowText().color();
590 arrowColor.setAlpha(180);
591 QPoint offset = QPoint(0, -2);
592
593 #if defined(Q_OS_LINUX)
594 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
595 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
596 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
597 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
598 }
599 #else
600 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
601 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
602 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
603 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
604 }
605 #endif
606 }
607 break;
608 case PE_IndicatorButtonDropDown:
609 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
610 break;
611
612 case PE_IndicatorToolBarSeparator:
613 {
614 QRect rect = option->rect;
615 const int margin = 6;
616 if (option->state & State_Horizontal) {
617 const int offset = rect.width()/2;
618 painter->setPen(QPen(option->palette.window().color().darker(110)));
619 painter->drawLine(rect.bottomLeft().x() + offset,
620 rect.bottomLeft().y() - margin,
621 rect.topLeft().x() + offset,
622 rect.topLeft().y() + margin);
623 painter->setPen(QPen(option->palette.window().color().lighter(110)));
624 painter->drawLine(rect.bottomLeft().x() + offset + 1,
625 rect.bottomLeft().y() - margin,
626 rect.topLeft().x() + offset + 1,
627 rect.topLeft().y() + margin);
628 } else { //Draw vertical separator
629 const int offset = rect.height()/2;
630 painter->setPen(QPen(option->palette.window().color().darker(110)));
631 painter->drawLine(rect.topLeft().x() + margin ,
632 rect.topLeft().y() + offset,
633 rect.topRight().x() - margin,
634 rect.topRight().y() + offset);
635 painter->setPen(QPen(option->palette.window().color().lighter(110)));
636 painter->drawLine(rect.topLeft().x() + margin ,
637 rect.topLeft().y() + offset + 1,
638 rect.topRight().x() - margin,
639 rect.topRight().y() + offset + 1);
640 }
641 }
642 break;
643 case PE_Frame: {
644 if (widget && widget->inherits("QComboBoxPrivateContainer")){
645 QStyleOption copy = *option;
646 copy.state |= State_Raised;
647 proxy()->drawPrimitive(PE_PanelMenu, ©, painter, widget);
648 break;
649 }
650 painter->save();
651 QPen thePen(outline.lighter(108));
652 thePen.setCosmetic(false);
653 painter->setPen(thePen);
654 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
655 painter->restore(); }
656 break;
657 case PE_FrameMenu:
658 painter->save();
659 {
660 painter->setPen(QPen(outline));
661 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
662 QColor frameLight = option->palette.window().color().lighter(160);
663 QColor frameShadow = option->palette.window().color().darker(110);
664
665 //paint beveleffect
666 QRect frame = option->rect.adjusted(1, 1, -1, -1);
667 painter->setPen(frameLight);
668 painter->drawLine(frame.topLeft(), frame.bottomLeft());
669 painter->drawLine(frame.topLeft(), frame.topRight());
670
671 painter->setPen(frameShadow);
672 painter->drawLine(frame.topRight(), frame.bottomRight());
673 painter->drawLine(frame.bottomLeft(), frame.bottomRight());
674 }
675 painter->restore();
676 break;
677 case PE_FrameDockWidget:
678
679 painter->save();
680 {
681 QColor softshadow = option->palette.window().color().darker(120);
682
683 QRect rect= option->rect;
684 painter->setPen(softshadow);
685 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
686 painter->setPen(QPen(option->palette.light(), 1));
687 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
688 painter->setPen(QPen(option->palette.window().color().darker(120)));
689 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
690 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
691
692 }
693 painter->restore();
694 break;
695 case PE_PanelButtonTool:
696 painter->save();
697 if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) {
698 if (widget && widget->inherits("QDockWidgetTitleButton")) {
699 if (option->state & State_MouseOver)
700 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
701 } else {
702 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
703 }
704 }
705 painter->restore();
706 break;
707 case PE_IndicatorDockWidgetResizeHandle:
708 {
709 QStyleOption dockWidgetHandle = *option;
710 bool horizontal = option->state & State_Horizontal;
711 dockWidgetHandle.state.setFlag(State_Horizontal, !horizontal);
712 proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
713 }
714 break;
715 case PE_FrameWindow:
716 painter->save();
717 {
718 QRect rect= option->rect;
719 painter->setPen(QPen(outline.darker(150)));
720 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
721 painter->setPen(QPen(option->palette.light(), 1));
722 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
723 QPoint(rect.left() + 1, rect.bottom() - 1));
724 painter->setPen(QPen(option->palette.window().color().darker(120)));
725 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
726 QPoint(rect.right() - 2, rect.bottom() - 1));
727 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
728 QPoint(rect.right() - 1, rect.bottom() - 1));
729 }
730 painter->restore();
731 break;
732 case PE_FrameLineEdit:
733 {
734 QRect r = rect;
735 bool hasFocus = option->state & State_HasFocus;
736
737 painter->save();
738
739 painter->setRenderHint(QPainter::Antialiasing, true);
740 // ### highdpi painter bug.
741 painter->translate(0.5, 0.5);
742
743 // Draw Outline
744 painter->setPen( QPen(hasFocus ? highlightedOutline : outline));
745 painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
746
747 if (hasFocus) {
748 QColor softHighlight = highlightedOutline;
749 softHighlight.setAlpha(40);
750 painter->setPen(softHighlight);
751 painter->drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
752 }
753 // Draw inner shadow
754 painter->setPen(d->topShadow());
755 painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
756
757 painter->restore();
758
759 }
760 break;
761 case PE_IndicatorCheckBox:
762 painter->save();
763 if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) {
764 painter->setRenderHint(QPainter::Antialiasing, true);
765 painter->translate(0.5, 0.5);
766 rect = rect.adjusted(0, 0, -1, -1);
767
768 QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
769 painter->setBrush(Qt::NoBrush);
770
771 // Gradient fill
772 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
773 gradient.setColorAt(0, (state & State_Sunken) ? pressedColor : option->palette.base().color().darker(115));
774 gradient.setColorAt(0.15, (state & State_Sunken) ? pressedColor : option->palette.base().color());
775 gradient.setColorAt(1, (state & State_Sunken) ? pressedColor : option->palette.base().color());
776
777 painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient);
778 painter->setPen(QPen(outline.lighter(110)));
779
780 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
781 painter->setPen(QPen(highlightedOutline));
782 painter->drawRect(rect);
783
784 QColor checkMarkColor = option->palette.text().color().darker(120);
785 const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding
786
787 if (checkbox->state & State_NoChange) {
788 gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
789 checkMarkColor.setAlpha(80);
790 gradient.setColorAt(0, checkMarkColor);
791 checkMarkColor.setAlpha(140);
792 gradient.setColorAt(1, checkMarkColor);
793 checkMarkColor.setAlpha(180);
794 painter->setPen(QPen(checkMarkColor, 1));
795 painter->setBrush(gradient);
796 painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
797
798 } else if (checkbox->state & State_On) {
799 const qreal dpi = QStyleHelper::dpi(option);
800 qreal penWidth = QStyleHelper::dpiScaled(1.5, dpi);
801 penWidth = qMax<qreal>(penWidth, 0.13 * rect.height());
802 penWidth = qMin<qreal>(penWidth, 0.20 * rect.height());
803 QPen checkPen = QPen(checkMarkColor, penWidth);
804 checkMarkColor.setAlpha(210);
805 painter->translate(dpiScaled(-0.8, dpi), dpiScaled(0.5, dpi));
806 painter->setPen(checkPen);
807 painter->setBrush(Qt::NoBrush);
808
809 // Draw checkmark
810 QPainterPath path;
811 const qreal rectHeight = rect.height(); // assuming height equals width
812 path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47);
813 path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding);
814 path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding);
815 painter->drawPath(path.translated(rect.topLeft()));
816 }
817 }
818 painter->restore();
819 break;
820 case PE_IndicatorRadioButton:
821 painter->save();
822 {
823 QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
824 painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color());
825 painter->setRenderHint(QPainter::Antialiasing, true);
826 QPainterPath circle;
827 const QPointF circleCenter = rect.center() + QPoint(1, 1);
828 const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1;
829 circle.addEllipse(circleCenter, outlineRadius, outlineRadius);
830 painter->setPen(QPen(option->palette.window().color().darker(150)));
831 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
832 painter->setPen(QPen(highlightedOutline));
833 painter->drawPath(circle);
834
835 if (state & (State_On )) {
836 circle = QPainterPath();
837 const qreal checkmarkRadius = outlineRadius / 2.32;
838 circle.addEllipse(circleCenter, checkmarkRadius, checkmarkRadius);
839 QColor checkMarkColor = option->palette.text().color().darker(120);
840 checkMarkColor.setAlpha(200);
841 painter->setPen(checkMarkColor);
842 checkMarkColor.setAlpha(180);
843 painter->setBrush(checkMarkColor);
844 painter->drawPath(circle);
845 }
846 }
847 painter->restore();
848 break;
849 case PE_IndicatorToolBarHandle:
850 {
851 //draw grips
852 if (option->state & State_Horizontal) {
853 for (int i = -3 ; i < 2 ; i += 3) {
854 for (int j = -8 ; j < 10 ; j += 3) {
855 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
856 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
857 }
858 }
859 } else { //vertical toolbar
860 for (int i = -6 ; i < 12 ; i += 3) {
861 for (int j = -3 ; j < 2 ; j += 3) {
862 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
863 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
864 }
865 }
866 }
867 break;
868 }
869 case PE_FrameDefaultButton:
870 break;
871 case PE_FrameFocusRect:
872 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
873 //### check for d->alt_down
874 if (!(fropt->state & State_KeyboardFocusChange))
875 return;
876 QRect rect = option->rect;
877
878 painter->save();
879 painter->setRenderHint(QPainter::Antialiasing, true);
880 painter->translate(0.5, 0.5);
881 QColor fillcolor = highlightedOutline;
882 fillcolor.setAlpha(80);
883 painter->setPen(fillcolor.darker(120));
884 fillcolor.setAlpha(30);
885 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
886 gradient.setColorAt(0, fillcolor.lighter(160));
887 gradient.setColorAt(1, fillcolor);
888 painter->setBrush(gradient);
889 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
890 painter->restore();
891 }
892 break;
893 case PE_PanelButtonCommand:
894 {
895 bool isDefault = false;
896 bool isFlat = false;
897 bool isDown = (option->state & State_Sunken) || (option->state & State_On);
898 QRect r;
899
900 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) {
901 isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled);
902 isFlat = (button->features & QStyleOptionButton::Flat);
903 }
904
905 if (isFlat && !isDown) {
906 if (isDefault) {
907 r = option->rect.adjusted(0, 1, 0, -1);
908 painter->setPen(QPen(Qt::black));
909 const QLine lines[4] = {
910 QLine(QPoint(r.left() + 2, r.top()),
911 QPoint(r.right() - 2, r.top())),
912 QLine(QPoint(r.left(), r.top() + 2),
913 QPoint(r.left(), r.bottom() - 2)),
914 QLine(QPoint(r.right(), r.top() + 2),
915 QPoint(r.right(), r.bottom() - 2)),
916 QLine(QPoint(r.left() + 2, r.bottom()),
917 QPoint(r.right() - 2, r.bottom()))
918 };
919 painter->drawLines(lines, 4);
920 const QPoint points[4] = {
921 QPoint(r.right() - 1, r.bottom() - 1),
922 QPoint(r.right() - 1, r.top() + 1),
923 QPoint(r.left() + 1, r.bottom() - 1),
924 QPoint(r.left() + 1, r.top() + 1)
925 };
926 painter->drawPoints(points, 4);
927 }
928 return;
929 }
930
931
932 bool isEnabled = option->state & State_Enabled;
933 bool hasFocus = (option->state & State_HasFocus && option->state & State_KeyboardFocusChange);
934 QColor buttonColor = d->buttonColor(option->palette);
935
936 QColor darkOutline = outline;
937 if (hasFocus | isDefault) {
938 darkOutline = highlightedOutline;
939 }
940
941 if (isDefault)
942 buttonColor = mergedColors(buttonColor, highlightedOutline.lighter(130), 90);
943
944 BEGIN_STYLE_PIXMAPCACHE(QStringLiteral("pushbutton-") + buttonColor.name(QColor::HexArgb))
945 r = rect.adjusted(0, 1, -1, 0);
946
947 p->setRenderHint(QPainter::Antialiasing, true);
948 p->translate(0.5, -0.5);
949
950 QLinearGradient gradient = qt_fusion_gradient(rect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
951 p->setPen(Qt::transparent);
952 p->setBrush(isDown ? QBrush(buttonColor.darker(110)) : gradient);
953 p->drawRoundedRect(r, 2.0, 2.0);
954 p->setBrush(Qt::NoBrush);
955
956 // Outline
957 p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline));
958 p->drawRoundedRect(r, 2.0, 2.0);
959
960 p->setPen(d->innerContrastLine());
961 p->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2.0, 2.0);
962
963 END_STYLE_PIXMAPCACHE
964 }
965 break;
966 case PE_FrameTabWidget:
967 painter->save();
968 painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
969 #if QT_CONFIG(tabwidget)
970 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
971 QColor borderColor = outline.lighter(110);
972 QRect rect = option->rect.adjusted(0, 0, -1, -1);
973
974 // Shadow outline
975 if (twf->shape != QTabBar::RoundedSouth) {
976 rect.adjust(0, 0, 0, -1);
977 QColor alphaShadow(Qt::black);
978 alphaShadow.setAlpha(15);
979 painter->setPen(alphaShadow);
980 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->setPen(borderColor);
981 }
982
983 // outline
984 painter->setPen(outline);
985 painter->drawRect(rect);
986
987 // Inner frame highlight
988 painter->setPen(d->innerContrastLine());
989 painter->drawRect(rect.adjusted(1, 1, -1, -1));
990
991 }
992 #endif // QT_CONFIG(tabwidget)
993 painter->restore();
994 break ;
995
996 case PE_FrameStatusBarItem:
997 break;
998 case PE_IndicatorTabClose:
999 {
1000 Q_D(const QFusionStyle);
1001 if (d->tabBarcloseButtonIcon.isNull())
1002 d->tabBarcloseButtonIcon = proxy()->standardIcon(SP_DialogCloseButton, option, widget);
1003 if ((option->state & State_Enabled) && (option->state & State_MouseOver))
1004 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
1005 QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(qt_getWindow(widget), QSize(16, 16), QIcon::Normal, QIcon::On);
1006 proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap);
1007 }
1008 break;
1009 case PE_PanelMenu: {
1010 painter->save();
1011 const QBrush menuBackground = option->palette.base().color().lighter(108);
1012 QColor borderColor = option->palette.window().color().darker(160);
1013 qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground);
1014 painter->restore();
1015 }
1016 break;
1017
1018 default:
1019 QCommonStyle::drawPrimitive(elem, option, painter, widget);
1020 break;
1021 }
1022 }
1023
1024 /*!
1025 \reimp
1026 */
drawControl(ControlElement element,const QStyleOption * option,QPainter * painter,const QWidget * widget) const1027 void QFusionStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
1028 const QWidget *widget) const
1029 {
1030 Q_D (const QFusionStyle);
1031 QRect rect = option->rect;
1032 QColor outline = d->outline(option->palette);
1033 QColor highlightedOutline = d->highlightedOutline(option->palette);
1034 QColor shadow = d->darkShade();
1035
1036 switch (element) {
1037 case CE_ComboBoxLabel:
1038 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
1039 QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
1040 painter->save();
1041 painter->setClipRect(editRect);
1042 if (!cb->currentIcon.isNull()) {
1043 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
1044 : QIcon::Disabled;
1045 QPixmap pixmap = cb->currentIcon.pixmap(qt_getWindow(widget), cb->iconSize, mode);
1046 QRect iconRect(editRect);
1047 iconRect.setWidth(cb->iconSize.width() + 4);
1048 iconRect = alignedRect(cb->direction,
1049 Qt::AlignLeft | Qt::AlignVCenter,
1050 iconRect.size(), editRect);
1051 if (cb->editable)
1052 painter->fillRect(iconRect, cb->palette.brush(QPalette::Base));
1053 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
1054
1055 if (cb->direction == Qt::RightToLeft)
1056 editRect.translate(-4 - cb->iconSize.width(), 0);
1057 else
1058 editRect.translate(cb->iconSize.width() + 4, 0);
1059 }
1060 if (!cb->currentText.isEmpty() && !cb->editable) {
1061 proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
1062 visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
1063 cb->palette, cb->state & State_Enabled, cb->currentText,
1064 cb->editable ? QPalette::Text : QPalette::ButtonText);
1065 }
1066 painter->restore();
1067 }
1068 break;
1069 case CE_Splitter:
1070 {
1071 // Don't draw handle for single pixel splitters
1072 if (option->rect.width() > 1 && option->rect.height() > 1) {
1073 //draw grips
1074 if (option->state & State_Horizontal) {
1075 for (int j = -6 ; j< 12 ; j += 3) {
1076 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 2, 2, d->lightShade());
1077 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 1, 1, d->darkShade());
1078 }
1079 } else {
1080 for (int i = -6; i< 12 ; i += 3) {
1081 painter->fillRect(rect.center().x() + i, rect.center().y(), 2, 2, d->lightShade());
1082 painter->fillRect(rect.center().x() + i, rect.center().y(), 1, 1, d->darkShade());
1083 }
1084 }
1085 }
1086 break;
1087 }
1088 #if QT_CONFIG(rubberband)
1089 case CE_RubberBand:
1090 if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
1091 QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
1092 painter->save();
1093 QColor penColor = highlight.darker(120);
1094 penColor.setAlpha(180);
1095 painter->setPen(penColor);
1096 QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
1097 qMin(highlight.green()/2 + 110, 255),
1098 qMin(highlight.blue()/2 + 110, 255));
1099 dimHighlight.setAlpha(widget && widget->isTopLevel() ? 255 : 80);
1100 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
1101 gradient.setColorAt(0, dimHighlight.lighter(120));
1102 gradient.setColorAt(1, dimHighlight);
1103 painter->setRenderHint(QPainter::Antialiasing, true);
1104 painter->translate(0.5, 0.5);
1105 painter->setBrush(dimHighlight);
1106 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
1107 QColor innerLine = Qt::white;
1108 innerLine.setAlpha(40);
1109 painter->setPen(innerLine);
1110 painter->drawRoundedRect(option->rect.adjusted(1, 1, -2, -2), 1, 1);
1111 painter->restore();
1112 }
1113 break;
1114 #endif //QT_CONFIG(rubberband)
1115 case CE_SizeGrip:
1116 painter->save();
1117 {
1118 //draw grips
1119 for (int i = -6; i< 12 ; i += 3) {
1120 for (int j = -6 ; j< 12 ; j += 3) {
1121 if ((option->direction == Qt::LeftToRight && i > -j) || (option->direction == Qt::RightToLeft && j > i) ) {
1122 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
1123 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
1124 }
1125 }
1126 }
1127 }
1128 painter->restore();
1129 break;
1130 #if QT_CONFIG(toolbar)
1131 case CE_ToolBar:
1132 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
1133 // Reserve the beveled appearance only for mainwindow toolbars
1134 if (widget && !(qobject_cast<const QMainWindow*> (widget->parentWidget())))
1135 break;
1136
1137 // Draws the light line above and the dark line below menu bars and
1138 // tool bars.
1139 QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft());
1140 if (!(option->state & State_Horizontal))
1141 gradient = QLinearGradient(rect.left(), rect.center().y(),
1142 rect.right(), rect.center().y());
1143 gradient.setColorAt(0, option->palette.window().color().lighter(104));
1144 gradient.setColorAt(1, option->palette.window().color());
1145 painter->fillRect(option->rect, gradient);
1146
1147 QColor light = d->lightShade();
1148 QColor shadow = d->darkShade();
1149
1150 QPen oldPen = painter->pen();
1151 if (toolBar->toolBarArea == Qt::TopToolBarArea) {
1152 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1153 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1154 // The end and onlyone top toolbar lines draw a double
1155 // line at the bottom to blend with the central
1156 // widget.
1157 painter->setPen(light);
1158 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1159 painter->setPen(shadow);
1160 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1161 option->rect.right(), option->rect.bottom() - 1);
1162 } else {
1163 // All others draw a single dark line at the bottom.
1164 painter->setPen(shadow);
1165 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1166 }
1167 // All top toolbar lines draw a light line at the top.
1168 painter->setPen(light);
1169 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1170 } else if (toolBar->toolBarArea == Qt::BottomToolBarArea) {
1171 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1172 || toolBar->positionOfLine == QStyleOptionToolBar::Middle) {
1173 // The end and middle bottom tool bar lines draw a dark
1174 // line at the bottom.
1175 painter->setPen(shadow);
1176 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1177 }
1178 if (toolBar->positionOfLine == QStyleOptionToolBar::Beginning
1179 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1180 // The beginning and only one tool bar lines draw a
1181 // double line at the bottom to blend with the
1182 // status bar.
1183 // ### The styleoption could contain whether the
1184 // main window has a menu bar and a status bar, and
1185 // possibly dock widgets.
1186 painter->setPen(shadow);
1187 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1188 option->rect.right(), option->rect.bottom() - 1);
1189 painter->setPen(light);
1190 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1191 }
1192 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1193 painter->setPen(shadow);
1194 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1195 painter->setPen(light);
1196 painter->drawLine(option->rect.left(), option->rect.top() + 1,
1197 option->rect.right(), option->rect.top() + 1);
1198
1199 } else {
1200 // All other bottom toolbars draw a light line at the top.
1201 painter->setPen(light);
1202 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1203 }
1204 }
1205 if (toolBar->toolBarArea == Qt::LeftToolBarArea) {
1206 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1207 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1208 // The middle and left end toolbar lines draw a light
1209 // line to the left.
1210 painter->setPen(light);
1211 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1212 }
1213 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1214 // All other left toolbar lines draw a dark line to the right
1215 painter->setPen(shadow);
1216 painter->drawLine(option->rect.right() - 1, option->rect.top(),
1217 option->rect.right() - 1, option->rect.bottom());
1218 painter->setPen(light);
1219 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1220 } else {
1221 // All other left toolbar lines draw a dark line to the right
1222 painter->setPen(shadow);
1223 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1224 }
1225 } else if (toolBar->toolBarArea == Qt::RightToolBarArea) {
1226 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1227 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1228 // Right middle and end toolbar lines draw the dark right line
1229 painter->setPen(shadow);
1230 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1231 }
1232 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1233 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1234 // The right end and single toolbar draws the dark
1235 // line on its left edge
1236 painter->setPen(shadow);
1237 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1238 // And a light line next to it
1239 painter->setPen(light);
1240 painter->drawLine(option->rect.left() + 1, option->rect.top(),
1241 option->rect.left() + 1, option->rect.bottom());
1242 } else {
1243 // Other right toolbars draw a light line on its left edge
1244 painter->setPen(light);
1245 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1246 }
1247 }
1248 painter->setPen(oldPen);
1249 }
1250 break;
1251 #endif // QT_CONFIG(toolbar)
1252 case CE_DockWidgetTitle:
1253 painter->save();
1254 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
1255 bool verticalTitleBar = dwOpt->verticalTitleBar;
1256
1257 QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget);
1258 if (verticalTitleBar) {
1259 QRect rect = dwOpt->rect;
1260 QRect r = rect.transposed();
1261 titleRect = QRect(r.left() + rect.bottom()
1262 - titleRect.bottom(),
1263 r.top() + titleRect.left() - rect.left(),
1264 titleRect.height(), titleRect.width());
1265
1266 painter->translate(r.left(), r.top() + r.width());
1267 painter->rotate(-90);
1268 painter->translate(-r.left(), -r.top());
1269 }
1270
1271 if (!dwOpt->title.isEmpty()) {
1272 QString titleText
1273 = painter->fontMetrics().elidedText(dwOpt->title,
1274 Qt::ElideRight, titleRect.width());
1275 proxy()->drawItemText(painter,
1276 titleRect,
1277 Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
1278 dwOpt->state & State_Enabled, titleText,
1279 QPalette::WindowText);
1280 }
1281 }
1282 painter->restore();
1283 break;
1284 case CE_HeaderSection:
1285 painter->save();
1286 // Draws the header in tables.
1287 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1288 QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size());
1289 pixmapName += QString::number(- int(header->position));
1290 pixmapName += QString::number(- int(header->orientation));
1291
1292 QPixmap cache;
1293 if (!QPixmapCache::find(pixmapName, &cache)) {
1294 cache = styleCachePixmap(rect.size());
1295 cache.fill(Qt::transparent);
1296 QRect pixmapRect(0, 0, rect.width(), rect.height());
1297 QPainter cachePainter(&cache);
1298 QColor buttonColor = d->buttonColor(option->palette);
1299 QColor gradientStopColor;
1300 QColor gradientStartColor = buttonColor.lighter(104);
1301 gradientStopColor = buttonColor.darker(102);
1302 QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft());
1303
1304 if (option->palette.window().gradient()) {
1305 gradient.setStops(option->palette.window().gradient()->stops());
1306 } else {
1307 QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 60);
1308 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
1309 gradient.setColorAt(0, gradientStartColor);
1310 gradient.setColorAt(0.5, midColor1);
1311 gradient.setColorAt(0.501, midColor2);
1312 gradient.setColorAt(0.92, gradientStopColor);
1313 gradient.setColorAt(1, gradientStopColor.darker(104));
1314 }
1315 cachePainter.fillRect(pixmapRect, gradient);
1316 cachePainter.setPen(d->innerContrastLine());
1317 cachePainter.setBrush(Qt::NoBrush);
1318 cachePainter.drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
1319 cachePainter.setPen(d->outline(option->palette));
1320 cachePainter.drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
1321
1322 if (header->orientation == Qt::Horizontal &&
1323 header->position != QStyleOptionHeader::End &&
1324 header->position != QStyleOptionHeader::OnlyOneSection) {
1325 cachePainter.setPen(QColor(0, 0, 0, 40));
1326 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight() + QPoint(0, -1));
1327 cachePainter.setPen(d->innerContrastLine());
1328 cachePainter.drawLine(pixmapRect.topRight() + QPoint(-1, 0), pixmapRect.bottomRight() + QPoint(-1, -1));
1329 } else if (header->orientation == Qt::Vertical) {
1330 cachePainter.setPen(d->outline(option->palette));
1331 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
1332 }
1333 cachePainter.end();
1334 QPixmapCache::insert(pixmapName, cache);
1335 }
1336 painter->drawPixmap(rect.topLeft(), cache);
1337 }
1338 painter->restore();
1339 break;
1340 case CE_ProgressBarGroove:
1341 painter->save();
1342 {
1343 painter->setRenderHint(QPainter::Antialiasing, true);
1344 painter->translate(0.5, 0.5);
1345
1346 QColor shadowAlpha = Qt::black;
1347 shadowAlpha.setAlpha(16);
1348 painter->setPen(shadowAlpha);
1349 painter->drawLine(rect.topLeft() - QPoint(0, 1), rect.topRight() - QPoint(0, 1));
1350
1351 painter->setBrush(option->palette.base());
1352 painter->setPen(QPen(outline));
1353 painter->drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2);
1354
1355 // Inner shadow
1356 painter->setPen(d->topShadow());
1357 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
1358 QPoint(rect.right() - 1, rect.top() + 1));
1359 }
1360 painter->restore();
1361 break;
1362 case CE_ProgressBarContents:
1363 painter->save();
1364 painter->setRenderHint(QPainter::Antialiasing, true);
1365 painter->translate(0.5, 0.5);
1366 if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1367 bool vertical = false;
1368 bool inverted = false;
1369 bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
1370 bool complete = bar->progress == bar->maximum;
1371
1372 // Get extra style options if version 2
1373 vertical = (bar->orientation == Qt::Vertical);
1374 inverted = bar->invertedAppearance;
1375
1376 // If the orientation is vertical, we use a transform to rotate
1377 // the progress bar 90 degrees clockwise. This way we can use the
1378 // same rendering code for both orientations.
1379 if (vertical) {
1380 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1381 QTransform m = QTransform::fromTranslate(rect.height()-1, -1.0);
1382 m.rotate(90.0);
1383 painter->setTransform(m, true);
1384 }
1385
1386 int maxWidth = rect.width();
1387 const auto progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar
1388 const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum);
1389 const auto progressSteps = qint64(progress) - bar->minimum;
1390 const auto progressBarWidth = progressSteps * maxWidth / totalSteps;
1391 int width = indeterminate ? maxWidth : progressBarWidth;
1392
1393 bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
1394 if (inverted)
1395 reverse = !reverse;
1396
1397 int step = 0;
1398 QRect progressBar;
1399 QColor highlight = d->highlight(option->palette);
1400 QColor highlightedoutline = highlight.darker(140);
1401 if (qGray(outline.rgb()) > qGray(highlightedoutline.rgb()))
1402 outline = highlightedoutline;
1403
1404 if (!indeterminate) {
1405 QColor innerShadow(Qt::black);
1406 innerShadow.setAlpha(35);
1407 painter->setPen(innerShadow);
1408 if (!reverse) {
1409 progressBar.setRect(rect.left(), rect.top(), width - 1, rect.height() - 1);
1410 if (!complete) {
1411 painter->drawLine(progressBar.topRight() + QPoint(2, 1), progressBar.bottomRight() + QPoint(2, 0));
1412 painter->setPen(QPen(highlight.darker(140)));
1413 painter->drawLine(progressBar.topRight() + QPoint(1, 1), progressBar.bottomRight() + QPoint(1, 0));
1414 }
1415 } else {
1416 progressBar.setRect(rect.right() - width - 1, rect.top(), width + 2, rect.height() - 1);
1417 if (!complete) {
1418 painter->drawLine(progressBar.topLeft() + QPoint(-2, 1), progressBar.bottomLeft() + QPoint(-2, 0));
1419 painter->setPen(QPen(highlight.darker(140)));
1420 painter->drawLine(progressBar.topLeft() + QPoint(-1, 1), progressBar.bottomLeft() + QPoint(-1, 0));
1421 }
1422 }
1423 } else {
1424 progressBar.setRect(rect.left(), rect.top(), rect.width() - 1, rect.height() - 1);
1425 }
1426
1427 if (indeterminate || bar->progress > bar->minimum) {
1428
1429 painter->setPen(QPen(outline));
1430
1431 QColor highlightedGradientStartColor = highlight.lighter(120);
1432 QColor highlightedGradientStopColor = highlight;
1433 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
1434 gradient.setColorAt(0, highlightedGradientStartColor);
1435 gradient.setColorAt(1, highlightedGradientStopColor);
1436
1437 painter->setBrush(gradient);
1438
1439 painter->save();
1440 if (!complete && !indeterminate)
1441 painter->setClipRect(progressBar.adjusted(-1, -1, -1, 1));
1442 QRect fillRect = progressBar.adjusted( !indeterminate && !complete && reverse ? -2 : 0, 0,
1443 indeterminate || complete || reverse ? 0 : 2, 0);
1444 painter->drawRoundedRect(fillRect, 2, 2);
1445 painter->restore();
1446
1447 painter->setBrush(Qt::NoBrush);
1448 painter->setPen(QColor(255, 255, 255, 50));
1449 painter->drawRoundedRect(progressBar.adjusted(1, 1, -1, -1), 1, 1);
1450
1451 if (!indeterminate) {
1452 #if QT_CONFIG(animation)
1453 (const_cast<QFusionStylePrivate*>(d))->stopAnimation(option->styleObject);
1454 #endif
1455 } else {
1456 highlightedGradientStartColor.setAlpha(120);
1457 painter->setPen(QPen(highlightedGradientStartColor, 9.0));
1458 painter->setClipRect(progressBar.adjusted(1, 1, -1, -1));
1459 #if QT_CONFIG(animation)
1460 if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(option->styleObject)))
1461 step = animation->animationStep() % 22;
1462 else
1463 (const_cast<QFusionStylePrivate*>(d))->startAnimation(new QProgressStyleAnimation(d->animationFps, option->styleObject));
1464 #endif
1465 for (int x = progressBar.left() - rect.height(); x < rect.right() ; x += 22)
1466 painter->drawLine(x + step, progressBar.bottom() + 1,
1467 x + rect.height() + step, progressBar.top() - 2);
1468 }
1469 }
1470 }
1471 painter->restore();
1472 break;
1473 case CE_ProgressBarLabel:
1474 if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1475 QRect leftRect;
1476 QRect rect = bar->rect;
1477 QColor textColor = option->palette.text().color();
1478 QColor alternateTextColor = d->highlightedText(option->palette);
1479
1480 painter->save();
1481 bool vertical = false, inverted = false;
1482 vertical = (bar->orientation == Qt::Vertical);
1483 inverted = bar->invertedAppearance;
1484 if (vertical)
1485 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1486 const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum);
1487 const auto progressSteps = qint64(bar->progress) - bar->minimum;
1488 const auto progressIndicatorPos = progressSteps * rect.width() / totalSteps;
1489 if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
1490 leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
1491 if (vertical)
1492 leftRect.translate(rect.width() - progressIndicatorPos, 0);
1493
1494 bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
1495 ((bar->direction == Qt::LeftToRight) && inverted)));
1496
1497 QRegion rightRect = rect;
1498 rightRect = rightRect.subtracted(leftRect);
1499 painter->setClipRegion(rightRect);
1500 painter->setPen(flip ? alternateTextColor : textColor);
1501 painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
1502 if (!leftRect.isNull()) {
1503 painter->setPen(flip ? textColor : alternateTextColor);
1504 painter->setClipRect(leftRect);
1505 painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
1506 }
1507 painter->restore();
1508 }
1509 break;
1510 case CE_MenuBarItem:
1511 painter->save();
1512 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
1513 {
1514 QStyleOptionMenuItem item = *mbi;
1515 item.rect = mbi->rect.adjusted(0, 1, 0, -3);
1516 QColor highlightOutline = option->palette.highlight().color().darker(125);
1517 painter->fillRect(rect, option->palette.window());
1518
1519 QCommonStyle::drawControl(element, &item, painter, widget);
1520
1521 bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
1522 bool dis = !(mbi->state & State_Enabled);
1523
1524 QRect r = option->rect;
1525 if (act) {
1526 painter->setBrush(option->palette.highlight().color());
1527 painter->setPen(QPen(highlightOutline));
1528 painter->drawRect(r.adjusted(0, 0, -1, -1));
1529
1530 // painter->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2);
1531
1532 //draw text
1533 QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
1534 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1535 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1536 alignment |= Qt::TextHideMnemonic;
1537 proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
1538 } else {
1539
1540 QColor shadow = mergedColors(option->palette.window().color().darker(120),
1541 outline.lighter(140), 60);
1542 painter->setPen(QPen(shadow));
1543 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1544 }
1545 }
1546 painter->restore();
1547 break;
1548 case CE_MenuItem:
1549 painter->save();
1550 // Draws one item in a popup menu.
1551 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1552 QColor highlightOutline = highlightedOutline;
1553 QColor highlight = option->palette.highlight().color();
1554 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
1555 int w = 0;
1556 const int margin = int(QStyleHelper::dpiScaled(5, option));
1557 if (!menuItem->text.isEmpty()) {
1558 painter->setFont(menuItem->font);
1559 proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0), Qt::AlignLeft | Qt::AlignVCenter,
1560 menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
1561 QPalette::Text);
1562 w = menuItem->fontMetrics.horizontalAdvance(menuItem->text) + margin;
1563 }
1564 painter->setPen(shadow.lighter(106));
1565 bool reverse = menuItem->direction == Qt::RightToLeft;
1566 painter->drawLine(menuItem->rect.left() + margin + (reverse ? 0 : w), menuItem->rect.center().y(),
1567 menuItem->rect.right() - margin - (reverse ? w : 0), menuItem->rect.center().y());
1568 painter->restore();
1569 break;
1570 }
1571 bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
1572 if (selected) {
1573 QRect r = option->rect;
1574 painter->fillRect(r, highlight);
1575 painter->setPen(QPen(highlightOutline));
1576 painter->drawRect(QRectF(r).adjusted(0.5, 0.5, -0.5, -0.5));
1577 }
1578 bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
1579 bool checked = menuItem->checked;
1580 bool sunken = menuItem->state & State_Sunken;
1581 bool enabled = menuItem->state & State_Enabled;
1582
1583 bool ignoreCheckMark = false;
1584 const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
1585 int checkcol = qMax<int>(menuItem->rect.height() * 0.79,
1586 qMax<int>(menuItem->maxIconWidth, dpiScaled(21, option))); // icon checkbox's highlight column width
1587 if (
1588 #if QT_CONFIG(combobox)
1589 qobject_cast<const QComboBox*>(widget) ||
1590 #endif
1591 (option->styleObject && option->styleObject->property("_q_isComboBoxPopupItem").toBool()))
1592 ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
1593
1594 if (!ignoreCheckMark || menuItem->state & (State_On | State_Off)) {
1595 // Check, using qreal and QRectF to avoid error accumulation
1596 const qreal boxMargin = dpiScaled(3.5, option);
1597 const qreal boxWidth = checkcol - 2 * boxMargin;
1598 QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
1599 QRect checkRect = checkRectF.toRect();
1600 checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
1601 checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
1602 if (checkable) {
1603 if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
1604 // Radio button
1605 if (menuItem->state & State_On || checked || sunken) {
1606 painter->setRenderHint(QPainter::Antialiasing);
1607 painter->setPen(Qt::NoPen);
1608
1609 QPalette::ColorRole textRole = !enabled ? QPalette::Text:
1610 selected ? QPalette::HighlightedText : QPalette::ButtonText;
1611 painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
1612 const int adjustment = checkRect.height() * 0.3;
1613 painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment));
1614 }
1615 } else {
1616 // Check box
1617 if (menuItem->icon.isNull()) {
1618 QStyleOptionButton box;
1619 box.QStyleOption::operator=(*option);
1620 box.rect = checkRect;
1621 if (checked || menuItem->state & State_On)
1622 box.state |= State_On;
1623 else
1624 box.state |= State_Off;
1625 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
1626 }
1627 }
1628 }
1629 } else { //ignore checkmark
1630 if (menuItem->icon.isNull())
1631 checkcol = 0;
1632 else
1633 checkcol = menuItem->maxIconWidth;
1634 }
1635
1636 // Text and icon, ripped from windows style
1637 bool dis = !(menuItem->state & State_Enabled);
1638 bool act = menuItem->state & State_Selected;
1639 const QStyleOption *opt = option;
1640 const QStyleOptionMenuItem *menuitem = menuItem;
1641
1642 QPainter *p = painter;
1643 QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
1644 QRect(menuitem->rect.x() + checkColHOffset, menuitem->rect.y(),
1645 checkcol, menuitem->rect.height()));
1646 if (!menuItem->icon.isNull()) {
1647 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1648 if (act && !dis)
1649 mode = QIcon::Active;
1650 QPixmap pixmap;
1651
1652 int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
1653 QSize iconSize(smallIconSize, smallIconSize);
1654 #if QT_CONFIG(combobox)
1655 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
1656 iconSize = combo->iconSize();
1657 #endif
1658 if (checked)
1659 pixmap = menuItem->icon.pixmap(qt_getWindow(widget), iconSize, mode, QIcon::On);
1660 else
1661 pixmap = menuItem->icon.pixmap(qt_getWindow(widget), iconSize, mode);
1662
1663 const int pixw = pixmap.width() / pixmap.devicePixelRatio();
1664 const int pixh = pixmap.height() / pixmap.devicePixelRatio();
1665
1666 QRect pmr(0, 0, pixw, pixh);
1667 pmr.moveCenter(vCheckRect.center());
1668 painter->setPen(menuItem->palette.text().color());
1669 if (!ignoreCheckMark && checkable && checked) {
1670 QStyleOption opt = *option;
1671 if (act) {
1672 QColor activeColor = mergedColors(option->palette.window().color(),
1673 option->palette.highlight().color());
1674 opt.palette.setBrush(QPalette::Button, activeColor);
1675 }
1676 opt.state |= State_Sunken;
1677 opt.rect = vCheckRect;
1678 proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
1679 }
1680 painter->drawPixmap(pmr.topLeft(), pixmap);
1681 }
1682 if (selected) {
1683 painter->setPen(menuItem->palette.highlightedText().color());
1684 } else {
1685 painter->setPen(menuItem->palette.text().color());
1686 }
1687 int x, y, w, h;
1688 menuitem->rect.getRect(&x, &y, &w, &h);
1689 int tab = menuitem->tabWidth;
1690 QColor discol;
1691 if (dis) {
1692 discol = menuitem->palette.text().color();
1693 p->setPen(discol);
1694 }
1695 int xm = checkColHOffset + checkcol + windowsItemHMargin;
1696 int xpos = menuitem->rect.x() + xm;
1697
1698 QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
1699 QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
1700 QStringRef s(&menuitem->text);
1701 if (!s.isEmpty()) { // draw text
1702 p->save();
1703 int t = s.indexOf(QLatin1Char('\t'));
1704 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1705 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1706 text_flags |= Qt::TextHideMnemonic;
1707 text_flags |= Qt::AlignLeft;
1708 if (t >= 0) {
1709 QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
1710 QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1711 const QString textToDraw = s.mid(t + 1).toString();
1712 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
1713 p->setPen(menuitem->palette.light().color());
1714 p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1715 p->setPen(discol);
1716 }
1717 p->drawText(vShortcutRect, text_flags, textToDraw);
1718 s = s.left(t);
1719 }
1720 QFont font = menuitem->font;
1721 // font may not have any "hard" flags set. We override
1722 // the point size so that when it is resolved against the device, this font will win.
1723 // This is mainly to handle cases where someone sets the font on the window
1724 // and then the combo inherits it and passes it onward. At that point the resolve mask
1725 // is very, very weak. This makes it stonger.
1726 font.setPointSizeF(QFontInfo(menuItem->font).pointSizeF());
1727
1728 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1729 font.setBold(true);
1730
1731 p->setFont(font);
1732 const QString textToDraw = s.left(t).toString();
1733 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
1734 p->setPen(menuitem->palette.light().color());
1735 p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1736 p->setPen(discol);
1737 }
1738 p->drawText(vTextRect, text_flags, textToDraw);
1739 p->restore();
1740 }
1741
1742 // Arrow
1743 if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1744 int dim = (menuItem->rect.height() - 4) / 2;
1745 PrimitiveElement arrow;
1746 arrow = option->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1747 int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
1748 QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
1749 QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
1750 QStyleOptionMenuItem newMI = *menuItem;
1751 newMI.rect = vSubMenuRect;
1752 newMI.state = !enabled ? State_None : State_Enabled;
1753 if (selected)
1754 newMI.palette.setColor(QPalette::WindowText,
1755 newMI.palette.highlightedText().color());
1756 proxy()->drawPrimitive(arrow, &newMI, painter, widget);
1757 }
1758 }
1759 painter->restore();
1760 break;
1761 case CE_MenuHMargin:
1762 case CE_MenuVMargin:
1763 break;
1764 case CE_MenuEmptyArea:
1765 break;
1766 case CE_PushButton:
1767 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1768 proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
1769 QStyleOptionButton subopt = *btn;
1770 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
1771 proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
1772 }
1773 break;
1774 case CE_PushButtonLabel:
1775 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1776 QStyleOptionButton b(*button);
1777 // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
1778 b.state &= ~(State_On | State_Sunken);
1779 QCommonStyle::drawControl(element, &b, painter, widget);
1780 }
1781 break;
1782 case CE_MenuBarEmptyArea:
1783 painter->save();
1784 {
1785 painter->fillRect(rect, option->palette.window());
1786 QColor shadow = mergedColors(option->palette.window().color().darker(120),
1787 outline.lighter(140), 60);
1788 painter->setPen(QPen(shadow));
1789 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1790 }
1791 painter->restore();
1792 break;
1793 #if QT_CONFIG(tabbar)
1794 case CE_TabBarTabShape:
1795 painter->save();
1796 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
1797
1798 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1799 && (tab->shape == QTabBar::RoundedNorth
1800 || tab->shape == QTabBar::RoundedSouth));
1801 bool selected = tab->state & State_Selected;
1802 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1803 || (rtlHorTabs
1804 && tab->position == QStyleOptionTab::Beginning));
1805 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1806 int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
1807 rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0);
1808
1809 QRect r2(rect);
1810 int x1 = r2.left();
1811 int x2 = r2.right();
1812 int y1 = r2.top();
1813 int y2 = r2.bottom();
1814
1815 painter->setPen(d->innerContrastLine());
1816
1817 QTransform rotMatrix;
1818 bool flip = false;
1819 painter->setPen(shadow);
1820
1821 switch (tab->shape) {
1822 case QTabBar::RoundedNorth:
1823 break;
1824 case QTabBar::RoundedSouth:
1825 rotMatrix.rotate(180);
1826 rotMatrix.translate(0, -rect.height() + 1);
1827 rotMatrix.scale(-1, 1);
1828 painter->setTransform(rotMatrix, true);
1829 break;
1830 case QTabBar::RoundedWest:
1831 rotMatrix.rotate(180 + 90);
1832 rotMatrix.scale(-1, 1);
1833 flip = true;
1834 painter->setTransform(rotMatrix, true);
1835 break;
1836 case QTabBar::RoundedEast:
1837 rotMatrix.rotate(90);
1838 rotMatrix.translate(0, - rect.width() + 1);
1839 flip = true;
1840 painter->setTransform(rotMatrix, true);
1841 break;
1842 default:
1843 painter->restore();
1844 QCommonStyle::drawControl(element, tab, painter, widget);
1845 return;
1846 }
1847
1848 if (flip) {
1849 QRect tmp = rect;
1850 rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
1851 int temp = x1;
1852 x1 = y1;
1853 y1 = temp;
1854 temp = x2;
1855 x2 = y2;
1856 y2 = temp;
1857 }
1858
1859 painter->setRenderHint(QPainter::Antialiasing, true);
1860 painter->translate(0.5, 0.5);
1861
1862 QColor tabFrameColor = tab->features & QStyleOptionTab::HasFrame ?
1863 d->tabFrameColor(option->palette) :
1864 option->palette.window().color();
1865
1866 QLinearGradient fillGradient(rect.topLeft(), rect.bottomLeft());
1867 QLinearGradient outlineGradient(rect.topLeft(), rect.bottomLeft());
1868 QPen outlinePen = outline.lighter(110);
1869 if (selected) {
1870 fillGradient.setColorAt(0, tabFrameColor.lighter(104));
1871 // QColor highlight = option->palette.highlight().color();
1872 // if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) {
1873 // fillGradient.setColorAt(0, highlight.lighter(130));
1874 // outlineGradient.setColorAt(0, highlight.darker(130));
1875 // fillGradient.setColorAt(0.14, highlight);
1876 // outlineGradient.setColorAt(0.14, highlight.darker(130));
1877 // fillGradient.setColorAt(0.1401, tabFrameColor);
1878 // outlineGradient.setColorAt(0.1401, highlight.darker(130));
1879 // }
1880 fillGradient.setColorAt(1, tabFrameColor);
1881 outlineGradient.setColorAt(1, outline);
1882 outlinePen = QPen(outlineGradient, 1);
1883 } else {
1884 fillGradient.setColorAt(0, tabFrameColor.darker(108));
1885 fillGradient.setColorAt(0.85, tabFrameColor.darker(108));
1886 fillGradient.setColorAt(1, tabFrameColor.darker(116));
1887 }
1888
1889 QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3);
1890 painter->setPen(outlinePen);
1891 painter->save();
1892 painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3));
1893 painter->setBrush(fillGradient);
1894 painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.0, 2.0);
1895 painter->setBrush(Qt::NoBrush);
1896 painter->setPen(d->innerContrastLine());
1897 painter->drawRoundedRect(drawRect.adjusted(1, 1, -2, -1), 2.0, 2.0);
1898 painter->restore();
1899
1900 if (selected) {
1901 painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor);
1902 painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), d->innerContrastLine());
1903 painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), d->innerContrastLine());
1904 painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), d->innerContrastLine());
1905 }
1906 }
1907 painter->restore();
1908 break;
1909 #endif //QT_CONFIG(tabbar)
1910 default:
1911 QCommonStyle::drawControl(element,option,painter,widget);
1912 break;
1913 }
1914 }
1915
1916 extern QPalette qt_fusionPalette();
1917
1918 /*!
1919 \reimp
1920 */
standardPalette() const1921 QPalette QFusionStyle::standardPalette () const
1922 {
1923 return qt_fusionPalette();
1924 }
1925
1926 /*!
1927 \reimp
1928 */
drawComplexControl(ComplexControl control,const QStyleOptionComplex * option,QPainter * painter,const QWidget * widget) const1929 void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
1930 QPainter *painter, const QWidget *widget) const
1931 {
1932
1933 Q_D (const QFusionStyle);
1934
1935 #if QT_CONFIG(spinbox) || QT_CONFIG(slider)
1936 QColor buttonColor = d->buttonColor(option->palette);
1937 QColor gradientStopColor = buttonColor;
1938 #endif
1939 #if QT_CONFIG(slider)
1940 QColor gradientStartColor = buttonColor.lighter(118);
1941 #endif
1942 QColor outline = d->outline(option->palette);
1943
1944 QColor alphaCornerColor;
1945 if (widget) {
1946 // ### backgroundrole/foregroundrole should be part of the style option
1947 alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), outline);
1948 } else {
1949 alphaCornerColor = mergedColors(option->palette.window().color(), outline);
1950 }
1951
1952 switch (control) {
1953 case CC_GroupBox:
1954 painter->save();
1955 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
1956 // Draw frame
1957 QRect textRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
1958 QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
1959
1960 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
1961 QStyleOptionFrame frame;
1962 frame.QStyleOption::operator=(*groupBox);
1963 frame.features = groupBox->features;
1964 frame.lineWidth = groupBox->lineWidth;
1965 frame.midLineWidth = groupBox->midLineWidth;
1966 frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
1967 proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
1968 }
1969
1970 // Draw title
1971 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
1972 // groupBox->textColor gets the incorrect palette here
1973 painter->setPen(QPen(option->palette.windowText(), 1));
1974 int alignment = int(groupBox->textAlignment);
1975 if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
1976 alignment |= Qt::TextHideMnemonic;
1977
1978 proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignLeft | alignment,
1979 groupBox->palette, groupBox->state & State_Enabled, groupBox->text, QPalette::NoRole);
1980
1981 if (groupBox->state & State_HasFocus) {
1982 QStyleOptionFocusRect fropt;
1983 fropt.QStyleOption::operator=(*groupBox);
1984 fropt.rect = textRect.adjusted(-2, -1, 2, 1);
1985 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
1986 }
1987 }
1988
1989 // Draw checkbox
1990 if (groupBox->subControls & SC_GroupBoxCheckBox) {
1991 QStyleOptionButton box;
1992 box.QStyleOption::operator=(*groupBox);
1993 box.rect = checkBoxRect;
1994 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
1995 }
1996 }
1997 painter->restore();
1998 break;
1999 #if QT_CONFIG(spinbox)
2000 case CC_SpinBox:
2001 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
2002 QPixmap cache;
2003 QString pixmapName = QStyleHelper::uniqueName(QLatin1String("spinbox"), spinBox, spinBox->rect.size());
2004 if (!QPixmapCache::find(pixmapName, &cache)) {
2005
2006 cache = styleCachePixmap(spinBox->rect.size());
2007 cache.fill(Qt::transparent);
2008
2009 QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height());
2010 QRect rect = pixmapRect;
2011 QRect r = rect.adjusted(0, 1, 0, -1);
2012 QPainter cachePainter(&cache);
2013 QColor arrowColor = spinBox->palette.windowText().color();
2014 arrowColor.setAlpha(160);
2015
2016 bool isEnabled = (spinBox->state & State_Enabled);
2017 bool hover = isEnabled && (spinBox->state & State_MouseOver);
2018 bool sunken = (spinBox->state & State_Sunken);
2019 bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
2020 bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
2021 bool hasFocus = (option->state & State_HasFocus);
2022
2023 QStyleOptionSpinBox spinBoxCopy = *spinBox;
2024 spinBoxCopy.rect = pixmapRect;
2025 QRect upRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxUp, widget);
2026 QRect downRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxDown, widget);
2027
2028 if (spinBox->frame) {
2029 cachePainter.save();
2030 cachePainter.setRenderHint(QPainter::Antialiasing, true);
2031 cachePainter.translate(0.5, 0.5);
2032
2033 // Fill background
2034 cachePainter.setPen(Qt::NoPen);
2035 cachePainter.setBrush(option->palette.base());
2036 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
2037
2038 // Draw inner shadow
2039 cachePainter.setPen(d->topShadow());
2040 cachePainter.drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
2041
2042 // Draw button gradient
2043 QColor buttonColor = d->buttonColor(option->palette);
2044 QRect updownRect = upRect.adjusted(0, -2, 0, downRect.height() + 2);
2045 QLinearGradient gradient = qt_fusion_gradient(updownRect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
2046
2047 // Draw button gradient
2048 cachePainter.setPen(Qt::NoPen);
2049 cachePainter.setBrush(gradient);
2050
2051 cachePainter.save();
2052 cachePainter.setClipRect(updownRect);
2053 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
2054 cachePainter.setPen(QPen(d->innerContrastLine()));
2055 cachePainter.setBrush(Qt::NoBrush);
2056 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 2, 2);
2057 cachePainter.restore();
2058
2059 if ((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) && upIsActive) {
2060 if (sunken)
2061 cachePainter.fillRect(upRect.adjusted(0, -1, 0, 0), gradientStopColor.darker(110));
2062 else if (hover)
2063 cachePainter.fillRect(upRect.adjusted(0, -1, 0, 0), d->innerContrastLine());
2064 }
2065
2066 if ((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) && downIsActive) {
2067 if (sunken)
2068 cachePainter.fillRect(downRect.adjusted(0, 0, 0, 1), gradientStopColor.darker(110));
2069 else if (hover)
2070 cachePainter.fillRect(downRect.adjusted(0, 0, 0, 1), d->innerContrastLine());
2071 }
2072
2073 cachePainter.setPen(hasFocus ? d->highlightedOutline(option->palette) : outline);
2074 cachePainter.setBrush(Qt::NoBrush);
2075 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
2076 if (hasFocus) {
2077 QColor softHighlight = option->palette.highlight().color();
2078 softHighlight.setAlpha(40);
2079 cachePainter.setPen(softHighlight);
2080 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
2081 }
2082 cachePainter.restore();
2083 }
2084
2085 // outline the up/down buttons
2086 cachePainter.setPen(outline);
2087 if (spinBox->direction == Qt::RightToLeft) {
2088 cachePainter.drawLine(upRect.right(), upRect.top() - 1, upRect.right(), downRect.bottom() + 1);
2089 } else {
2090 cachePainter.drawLine(upRect.left(), upRect.top() - 1, upRect.left(), downRect.bottom() + 1);
2091 }
2092
2093 if (upIsActive && sunken) {
2094 cachePainter.setPen(gradientStopColor.darker(130));
2095 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.right(), downRect.top());
2096 cachePainter.drawLine(upRect.left() + 1, upRect.top(), upRect.left() + 1, upRect.bottom());
2097 cachePainter.drawLine(upRect.left() + 1, upRect.top() - 1, upRect.right(), upRect.top() - 1);
2098 }
2099
2100 if (downIsActive && sunken) {
2101 cachePainter.setPen(gradientStopColor.darker(130));
2102 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.left() + 1, downRect.bottom() + 1);
2103 cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.right(), downRect.top());
2104 cachePainter.setPen(gradientStopColor.darker(110));
2105 cachePainter.drawLine(downRect.left() + 1, downRect.bottom() + 1, downRect.right(), downRect.bottom() + 1);
2106 }
2107
2108 QColor disabledColor = mergedColors(arrowColor, option->palette.button().color());
2109 if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
2110 int centerX = upRect.center().x();
2111 int centerY = upRect.center().y();
2112
2113 // plus/minus
2114 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
2115 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2116 cachePainter.drawLine(centerX + 1, centerY - 2, centerX + 1, centerY + 2);
2117
2118 centerX = downRect.center().x();
2119 centerY = downRect.center().y();
2120 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
2121 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2122
2123 } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows){
2124 // arrows
2125 qt_fusion_draw_arrow(Qt::UpArrow, &cachePainter, option, upRect.adjusted(0, 0, 0, 1),
2126 (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
2127 qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downRect,
2128 (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
2129 }
2130
2131 cachePainter.end();
2132 QPixmapCache::insert(pixmapName, cache);
2133 }
2134 painter->drawPixmap(spinBox->rect.topLeft(), cache);
2135 }
2136 break;
2137 #endif // QT_CONFIG(spinbox)
2138 case CC_TitleBar:
2139 painter->save();
2140 if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
2141 const int buttonMargin = 5;
2142 bool active = (titleBar->titleBarState & State_Active);
2143 QRect fullRect = titleBar->rect;
2144 QPalette palette = option->palette;
2145 QColor highlight = option->palette.highlight().color();
2146
2147 QColor titleBarFrameBorder(active ? highlight.darker(180): outline.darker(110));
2148 QColor titleBarHighlight(active ? highlight.lighter(120): palette.window().color().lighter(120));
2149 QColor textColor(active ? 0xffffff : 0xff000000);
2150 QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
2151
2152 {
2153 // Fill title bar gradient
2154 QColor titlebarColor = QColor(active ? highlight: palette.window().color());
2155 QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
2156 option->rect.center().x(), option->rect.bottom());
2157
2158 gradient.setColorAt(0, titlebarColor.lighter(114));
2159 gradient.setColorAt(0.5, titlebarColor.lighter(102));
2160 gradient.setColorAt(0.51, titlebarColor.darker(104));
2161 gradient.setColorAt(1, titlebarColor);
2162 painter->fillRect(option->rect.adjusted(1, 1, -1, 0), gradient);
2163
2164 // Frame and rounded corners
2165 painter->setPen(titleBarFrameBorder);
2166
2167 // top outline
2168 painter->drawLine(fullRect.left() + 5, fullRect.top(), fullRect.right() - 5, fullRect.top());
2169 painter->drawLine(fullRect.left(), fullRect.top() + 4, fullRect.left(), fullRect.bottom());
2170 const QPoint points[5] = {
2171 QPoint(fullRect.left() + 4, fullRect.top() + 1),
2172 QPoint(fullRect.left() + 3, fullRect.top() + 1),
2173 QPoint(fullRect.left() + 2, fullRect.top() + 2),
2174 QPoint(fullRect.left() + 1, fullRect.top() + 3),
2175 QPoint(fullRect.left() + 1, fullRect.top() + 4)
2176 };
2177 painter->drawPoints(points, 5);
2178
2179 painter->drawLine(fullRect.right(), fullRect.top() + 4, fullRect.right(), fullRect.bottom());
2180 const QPoint points2[5] = {
2181 QPoint(fullRect.right() - 3, fullRect.top() + 1),
2182 QPoint(fullRect.right() - 4, fullRect.top() + 1),
2183 QPoint(fullRect.right() - 2, fullRect.top() + 2),
2184 QPoint(fullRect.right() - 1, fullRect.top() + 3),
2185 QPoint(fullRect.right() - 1, fullRect.top() + 4)
2186 };
2187 painter->drawPoints(points2, 5);
2188
2189 // draw bottomline
2190 painter->drawLine(fullRect.right(), fullRect.bottom(), fullRect.left(), fullRect.bottom());
2191
2192 // top highlight
2193 painter->setPen(titleBarHighlight);
2194 painter->drawLine(fullRect.left() + 6, fullRect.top() + 1, fullRect.right() - 6, fullRect.top() + 1);
2195 }
2196 // draw title
2197 QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
2198 painter->setPen(active? (titleBar->palette.text().color().lighter(120)) :
2199 titleBar->palette.text().color() );
2200 // Note workspace also does elliding but it does not use the correct font
2201 QString title = painter->fontMetrics().elidedText(titleBar->text, Qt::ElideRight, textRect.width() - 14);
2202 painter->drawText(textRect.adjusted(1, 1, 1, 1), title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
2203 painter->setPen(Qt::white);
2204 if (active)
2205 painter->drawText(textRect, title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
2206 // min button
2207 if ((titleBar->subControls & SC_TitleBarMinButton) && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2208 !(titleBar->titleBarState& Qt::WindowMinimized)) {
2209 QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
2210 if (minButtonRect.isValid()) {
2211 bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
2212 bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
2213 qt_fusion_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
2214 QRect minButtonIconRect = minButtonRect.adjusted(buttonMargin ,buttonMargin , -buttonMargin, -buttonMargin);
2215 painter->setPen(textColor);
2216 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 3,
2217 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 3);
2218 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 4,
2219 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 4);
2220 painter->setPen(textAlphaColor);
2221 painter->drawLine(minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 3,
2222 minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 4);
2223 painter->drawLine(minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 3,
2224 minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 4);
2225 }
2226 }
2227 // max button
2228 if ((titleBar->subControls & SC_TitleBarMaxButton) && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2229 !(titleBar->titleBarState & Qt::WindowMaximized)) {
2230 QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
2231 if (maxButtonRect.isValid()) {
2232 bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
2233 bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
2234 qt_fusion_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
2235
2236 QRect maxButtonIconRect = maxButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2237
2238 painter->setPen(textColor);
2239 painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
2240 painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
2241 maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
2242 painter->setPen(textAlphaColor);
2243 const QPoint points[4] = {
2244 maxButtonIconRect.topLeft(),
2245 maxButtonIconRect.topRight(),
2246 maxButtonIconRect.bottomLeft(),
2247 maxButtonIconRect.bottomRight()
2248 };
2249 painter->drawPoints(points, 4);
2250 }
2251 }
2252
2253 // close button
2254 if ((titleBar->subControls & SC_TitleBarCloseButton) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2255 QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
2256 if (closeButtonRect.isValid()) {
2257 bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
2258 bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
2259 qt_fusion_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
2260 QRect closeIconRect = closeButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2261 painter->setPen(textAlphaColor);
2262 const QLine lines[4] = {
2263 QLine(closeIconRect.left() + 1, closeIconRect.top(),
2264 closeIconRect.right(), closeIconRect.bottom() - 1),
2265 QLine(closeIconRect.left(), closeIconRect.top() + 1,
2266 closeIconRect.right() - 1, closeIconRect.bottom()),
2267 QLine(closeIconRect.right() - 1, closeIconRect.top(),
2268 closeIconRect.left(), closeIconRect.bottom() - 1),
2269 QLine(closeIconRect.right(), closeIconRect.top() + 1,
2270 closeIconRect.left() + 1, closeIconRect.bottom())
2271 };
2272 painter->drawLines(lines, 4);
2273 const QPoint points[4] = {
2274 closeIconRect.topLeft(),
2275 closeIconRect.topRight(),
2276 closeIconRect.bottomLeft(),
2277 closeIconRect.bottomRight()
2278 };
2279 painter->drawPoints(points, 4);
2280
2281 painter->setPen(textColor);
2282 painter->drawLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
2283 closeIconRect.right() - 1, closeIconRect.bottom() - 1);
2284 painter->drawLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
2285 closeIconRect.right() - 1, closeIconRect.top() + 1);
2286 }
2287 }
2288
2289 // normalize button
2290 if ((titleBar->subControls & SC_TitleBarNormalButton) &&
2291 (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2292 (titleBar->titleBarState & Qt::WindowMinimized)) ||
2293 ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2294 (titleBar->titleBarState & Qt::WindowMaximized)))) {
2295 QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
2296 if (normalButtonRect.isValid()) {
2297
2298 bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
2299 bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
2300 QRect normalButtonIconRect = normalButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2301 qt_fusion_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
2302
2303 QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
2304 painter->setPen(textColor);
2305 painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
2306 painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
2307 frontWindowRect.right() - 1, frontWindowRect.top() + 1);
2308 painter->setPen(textAlphaColor);
2309 const QPoint points[4] = {
2310 frontWindowRect.topLeft(),
2311 frontWindowRect.topRight(),
2312 frontWindowRect.bottomLeft(),
2313 frontWindowRect.bottomRight()
2314 };
2315 painter->drawPoints(points, 4);
2316
2317 QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
2318 QRegion clipRegion = backWindowRect;
2319 clipRegion -= frontWindowRect;
2320 painter->save();
2321 painter->setClipRegion(clipRegion);
2322 painter->setPen(textColor);
2323 painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
2324 painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
2325 backWindowRect.right() - 1, backWindowRect.top() + 1);
2326 painter->setPen(textAlphaColor);
2327 const QPoint points2[4] = {
2328 backWindowRect.topLeft(),
2329 backWindowRect.topRight(),
2330 backWindowRect.bottomLeft(),
2331 backWindowRect.bottomRight()
2332 };
2333 painter->drawPoints(points2, 4);
2334 painter->restore();
2335 }
2336 }
2337
2338 // context help button
2339 if (titleBar->subControls & SC_TitleBarContextHelpButton
2340 && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
2341 QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
2342 if (contextHelpButtonRect.isValid()) {
2343 bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
2344 bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
2345 qt_fusion_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
2346 #if QT_CONFIG(imageformat_xpm)
2347 QImage image(qt_titlebar_context_help);
2348 QColor alpha = textColor;
2349 alpha.setAlpha(128);
2350 image.setColor(1, textColor.rgba());
2351 image.setColor(2, alpha.rgba());
2352 painter->setRenderHint(QPainter::SmoothPixmapTransform);
2353 painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image);
2354 #endif
2355 }
2356 }
2357
2358 // shade button
2359 if (titleBar->subControls & SC_TitleBarShadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2360 QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
2361 if (shadeButtonRect.isValid()) {
2362 bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
2363 bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
2364 qt_fusion_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
2365 qt_fusion_draw_arrow(Qt::UpArrow, painter, option, shadeButtonRect.adjusted(5, 7, -5, -7), textColor);
2366 }
2367 }
2368
2369 // unshade button
2370 if (titleBar->subControls & SC_TitleBarUnshadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2371 QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
2372 if (unshadeButtonRect.isValid()) {
2373 bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
2374 bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
2375 qt_fusion_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
2376 qt_fusion_draw_arrow(Qt::DownArrow, painter, option, unshadeButtonRect.adjusted(5, 7, -5, -7), textColor);
2377 }
2378 }
2379
2380 if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2381 QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
2382 if (iconRect.isValid()) {
2383 if (!titleBar->icon.isNull()) {
2384 titleBar->icon.paint(painter, iconRect);
2385 } else {
2386 QStyleOption tool = *titleBar;
2387 QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
2388 tool.rect = iconRect;
2389 painter->save();
2390 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
2391 painter->restore();
2392 }
2393 }
2394 }
2395 }
2396 painter->restore();
2397 break;
2398 #if QT_CONFIG(slider)
2399 case CC_ScrollBar:
2400 painter->save();
2401 if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
2402 bool wasActive = false;
2403 qreal expandScale = 1.0;
2404 qreal expandOffset = -1.0;
2405 QObject *styleObject = option->styleObject;
2406 if (styleObject && proxy()->styleHint(SH_ScrollBar_Transient, option, widget)) {
2407 #if QT_CONFIG(animation)
2408 qreal opacity = 0.0;
2409 bool shouldExpand = false;
2410 const qreal maxExpandScale = 13.0 / 9.0;
2411 #endif
2412
2413 int oldPos = styleObject->property("_q_stylepos").toInt();
2414 int oldMin = styleObject->property("_q_stylemin").toInt();
2415 int oldMax = styleObject->property("_q_stylemax").toInt();
2416 QRect oldRect = styleObject->property("_q_stylerect").toRect();
2417 QStyle::State oldState = static_cast<QStyle::State>(qvariant_cast<QStyle::State::Int>(styleObject->property("_q_stylestate")));
2418 uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt();
2419
2420 // a scrollbar is transient when the scrollbar itself and
2421 // its sibling are both inactive (ie. not pressed/hovered/moved)
2422 bool transient = !option->activeSubControls && !(option->state & State_On);
2423
2424 if (!transient ||
2425 oldPos != scrollBar->sliderPosition ||
2426 oldMin != scrollBar->minimum ||
2427 oldMax != scrollBar->maximum ||
2428 oldRect != scrollBar->rect ||
2429 oldState != scrollBar->state ||
2430 oldActiveControls != scrollBar->activeSubControls) {
2431
2432 styleObject->setProperty("_q_stylepos", scrollBar->sliderPosition);
2433 styleObject->setProperty("_q_stylemin", scrollBar->minimum);
2434 styleObject->setProperty("_q_stylemax", scrollBar->maximum);
2435 styleObject->setProperty("_q_stylerect", scrollBar->rect);
2436 styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(scrollBar->state));
2437 styleObject->setProperty("_q_stylecontrols", static_cast<uint>(scrollBar->activeSubControls));
2438
2439 #if QT_CONFIG(animation)
2440 // if the scrollbar is transient or its attributes, geometry or
2441 // state has changed, the opacity is reset back to 100% opaque
2442 opacity = 1.0;
2443
2444 QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
2445 if (transient) {
2446 if (!anim) {
2447 anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Deactivating, styleObject);
2448 d->startAnimation(anim);
2449 } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2450 // the scrollbar was already fading out while the
2451 // state changed -> restart the fade out animation
2452 anim->setCurrentTime(0);
2453 }
2454 } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2455 d->stopAnimation(styleObject);
2456 }
2457 #endif // animation
2458 }
2459
2460 #if QT_CONFIG(animation)
2461 QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
2462 if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
2463 // once a scrollbar was active (hovered/pressed), it retains
2464 // the active look even if it's no longer active while fading out
2465 if (oldActiveControls)
2466 anim->setActive(true);
2467
2468 wasActive = anim->wasActive();
2469 opacity = anim->currentValue();
2470 }
2471
2472 shouldExpand = (option->activeSubControls || wasActive);
2473 if (shouldExpand) {
2474 if (!anim && !oldActiveControls) {
2475 // Start expand animation only once and when entering
2476 anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Activating, styleObject);
2477 d->startAnimation(anim);
2478 }
2479 if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) {
2480 expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue();
2481 expandOffset = 5.5 * anim->currentValue() - 1;
2482 } else {
2483 // Keep expanded state after the animation ends, and when fading out
2484 expandScale = maxExpandScale;
2485 expandOffset = 4.5;
2486 }
2487 }
2488 painter->setOpacity(opacity);
2489 #endif // animation
2490 }
2491
2492 bool transient = proxy()->styleHint(SH_ScrollBar_Transient, option, widget);
2493 bool horizontal = scrollBar->orientation == Qt::Horizontal;
2494 bool sunken = scrollBar->state & State_Sunken;
2495
2496 QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
2497 QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
2498 QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
2499 QRect scrollBarGroove = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
2500
2501 QRect rect = option->rect;
2502 QColor alphaOutline = outline;
2503 alphaOutline.setAlpha(180);
2504
2505 QColor arrowColor = option->palette.windowText().color();
2506 arrowColor.setAlpha(160);
2507
2508 const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget);
2509 const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
2510
2511 if (transient) {
2512 if (horizontal) {
2513 rect.setY(rect.y() + 4.5 - expandOffset);
2514 scrollBarSlider.setY(scrollBarSlider.y() + 4.5 - expandOffset);
2515 scrollBarGroove.setY(scrollBarGroove.y() + 4.5 - expandOffset);
2516
2517 rect.setHeight(rect.height() * expandScale);
2518 scrollBarGroove.setHeight(scrollBarGroove.height() * expandScale);
2519 } else {
2520 rect.setX(rect.x() + 4.5 - expandOffset);
2521 scrollBarSlider.setX(scrollBarSlider.x() + 4.5 - expandOffset);
2522 scrollBarGroove.setX(scrollBarGroove.x() + 4.5 - expandOffset);
2523
2524 rect.setWidth(rect.width() * expandScale);
2525 scrollBarGroove.setWidth(scrollBarGroove.width() * expandScale);
2526 }
2527 }
2528
2529 // Paint groove
2530 if ((!transient || scrollBar->activeSubControls || wasActive) && scrollBar->subControls & SC_ScrollBarGroove) {
2531 QLinearGradient gradient(rect.center().x(), rect.top(),
2532 rect.center().x(), rect.bottom());
2533 if (!horizontal)
2534 gradient = QLinearGradient(rect.left(), rect.center().y(),
2535 rect.right(), rect.center().y());
2536 if (!transient || !isDarkBg) {
2537 gradient.setColorAt(0, buttonColor.darker(107));
2538 gradient.setColorAt(0.1, buttonColor.darker(105));
2539 gradient.setColorAt(0.9, buttonColor.darker(105));
2540 gradient.setColorAt(1, buttonColor.darker(107));
2541 } else {
2542 gradient.setColorAt(0, bgColor.lighter(157));
2543 gradient.setColorAt(0.1, bgColor.lighter(155));
2544 gradient.setColorAt(0.9, bgColor.lighter(155));
2545 gradient.setColorAt(1, bgColor.lighter(157));
2546 }
2547
2548 painter->save();
2549 if (transient)
2550 painter->setOpacity(0.8);
2551 painter->fillRect(rect, gradient);
2552 painter->setPen(Qt::NoPen);
2553 if (transient)
2554 painter->setOpacity(0.4);
2555 painter->setPen(alphaOutline);
2556 if (horizontal)
2557 painter->drawLine(rect.topLeft(), rect.topRight());
2558 else
2559 painter->drawLine(rect.topLeft(), rect.bottomLeft());
2560
2561 QColor subtleEdge = alphaOutline;
2562 subtleEdge.setAlpha(40);
2563 painter->setPen(subtleEdge);
2564 painter->setBrush(Qt::NoBrush);
2565 painter->setClipRect(scrollBarGroove.adjusted(1, 0, -1, -3));
2566 painter->drawRect(scrollBarGroove.adjusted(1, 0, -1, -1));
2567 painter->restore();
2568 }
2569
2570 QRect pixmapRect = scrollBarSlider;
2571 QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
2572 pixmapRect.center().x(), pixmapRect.bottom());
2573 if (!horizontal)
2574 gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
2575 pixmapRect.right(), pixmapRect.center().y());
2576
2577 QLinearGradient highlightedGradient = gradient;
2578
2579 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
2580 gradient.setColorAt(0, d->buttonColor(option->palette).lighter(108));
2581 gradient.setColorAt(1, d->buttonColor(option->palette));
2582
2583 highlightedGradient.setColorAt(0, gradientStartColor.darker(102));
2584 highlightedGradient.setColorAt(1, gradientStopColor.lighter(102));
2585
2586 // Paint slider
2587 if (scrollBar->subControls & SC_ScrollBarSlider) {
2588 if (transient) {
2589 QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1);
2590 painter->setPen(Qt::NoPen);
2591 painter->setBrush(isDarkBg ? d->lightShade() : d->darkShade());
2592 int r = qMin(rect.width(), rect.height()) / 2;
2593
2594 painter->save();
2595 painter->setRenderHint(QPainter::Antialiasing, true);
2596 painter->drawRoundedRect(rect, r, r);
2597 painter->restore();
2598 } else {
2599 QRect pixmapRect = scrollBarSlider;
2600 painter->setPen(QPen(alphaOutline));
2601 if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider)
2602 painter->setBrush(midColor2);
2603 else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider)
2604 painter->setBrush(highlightedGradient);
2605 else
2606 painter->setBrush(gradient);
2607
2608 painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));
2609
2610 painter->setPen(d->innerContrastLine());
2611 painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
2612
2613 // Outer shadow
2614 // painter->setPen(subtleEdge);
2615 // if (horizontal) {
2616 //// painter->drawLine(scrollBarSlider.topLeft() + QPoint(-2, 0), scrollBarSlider.bottomLeft() + QPoint(2, 0));
2617 //// painter->drawLine(scrollBarSlider.topRight() + QPoint(-2, 0), scrollBarSlider.bottomRight() + QPoint(2, 0));
2618 // } else {
2619 //// painter->drawLine(pixmapRect.topLeft() + QPoint(0, -2), pixmapRect.bottomLeft() + QPoint(0, -2));
2620 //// painter->drawLine(pixmapRect.topRight() + QPoint(0, 2), pixmapRect.bottomRight() + QPoint(0, 2));
2621 // }
2622 }
2623 }
2624
2625 // The SubLine (up/left) buttons
2626 if (!transient && scrollBar->subControls & SC_ScrollBarSubLine) {
2627 if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
2628 painter->setBrush(gradientStopColor);
2629 else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
2630 painter->setBrush(highlightedGradient);
2631 else
2632 painter->setBrush(gradient);
2633
2634 painter->setPen(Qt::NoPen);
2635 painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
2636 painter->setPen(QPen(alphaOutline));
2637 if (option->state & State_Horizontal) {
2638 if (option->direction == Qt::RightToLeft) {
2639 pixmapRect.setLeft(scrollBarSubLine.left());
2640 painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
2641 } else {
2642 pixmapRect.setRight(scrollBarSubLine.right());
2643 painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
2644 }
2645 } else {
2646 pixmapRect.setBottom(scrollBarSubLine.bottom());
2647 painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
2648 }
2649
2650 QRect upRect = scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, horizontal ? -2 : -1, horizontal ? -1 : -2);
2651 painter->setBrush(Qt::NoBrush);
2652 painter->setPen(d->innerContrastLine());
2653 painter->drawRect(upRect);
2654
2655 // Arrows
2656 Qt::ArrowType arrowType = Qt::UpArrow;
2657 if (option->state & State_Horizontal)
2658 arrowType = option->direction == Qt::LeftToRight ? Qt::LeftArrow : Qt::RightArrow;
2659 qt_fusion_draw_arrow(arrowType, painter, option, upRect, arrowColor);
2660 }
2661
2662 // The AddLine (down/right) button
2663 if (!transient && scrollBar->subControls & SC_ScrollBarAddLine) {
2664 if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
2665 painter->setBrush(gradientStopColor);
2666 else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
2667 painter->setBrush(midColor2);
2668 else
2669 painter->setBrush(gradient);
2670
2671 painter->setPen(Qt::NoPen);
2672 painter->drawRect(scrollBarAddLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
2673 painter->setPen(QPen(alphaOutline, 1));
2674 if (option->state & State_Horizontal) {
2675 if (option->direction == Qt::LeftToRight) {
2676 pixmapRect.setLeft(scrollBarAddLine.left());
2677 painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
2678 } else {
2679 pixmapRect.setRight(scrollBarAddLine.right());
2680 painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
2681 }
2682 } else {
2683 pixmapRect.setTop(scrollBarAddLine.top());
2684 painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
2685 }
2686
2687 QRect downRect = scrollBarAddLine.adjusted(1, 1, -1, -1);
2688 painter->setPen(d->innerContrastLine());
2689 painter->setBrush(Qt::NoBrush);
2690 painter->drawRect(downRect);
2691
2692 Qt::ArrowType arrowType = Qt::DownArrow;
2693 if (option->state & State_Horizontal)
2694 arrowType = option->direction == Qt::LeftToRight ? Qt::RightArrow : Qt::LeftArrow;
2695 qt_fusion_draw_arrow(arrowType, painter, option, downRect, arrowColor);
2696 }
2697
2698 }
2699 painter->restore();
2700 break;;
2701 #endif // QT_CONFIG(slider)
2702 case CC_ComboBox:
2703 painter->save();
2704 if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
2705 bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange;
2706 bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
2707 bool isEnabled = (comboBox->state & State_Enabled);
2708 QPixmap cache;
2709 QString pixmapName = QStyleHelper::uniqueName(QLatin1String("combobox"), option, comboBox->rect.size());
2710 if (sunken)
2711 pixmapName += QLatin1String("-sunken");
2712 if (comboBox->editable)
2713 pixmapName += QLatin1String("-editable");
2714 if (isEnabled)
2715 pixmapName += QLatin1String("-enabled");
2716 if (!comboBox->frame)
2717 pixmapName += QLatin1String("-frameless");
2718
2719 if (!QPixmapCache::find(pixmapName, &cache)) {
2720 cache = styleCachePixmap(comboBox->rect.size());
2721 cache.fill(Qt::transparent);
2722 QPainter cachePainter(&cache);
2723 QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
2724 QStyleOptionComboBox comboBoxCopy = *comboBox;
2725 comboBoxCopy.rect = pixmapRect;
2726
2727 QRect rect = pixmapRect;
2728 QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
2729 SC_ComboBoxArrow, widget);
2730 // Draw a line edit
2731 if (comboBox->editable) {
2732 QStyleOptionFrame buttonOption;
2733 buttonOption.QStyleOption::operator=(*comboBox);
2734 buttonOption.rect = rect;
2735 buttonOption.state = (comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus))
2736 | State_KeyboardFocusChange; // Always show hig
2737
2738 if (sunken) {
2739 buttonOption.state |= State_Sunken;
2740 buttonOption.state &= ~State_MouseOver;
2741 }
2742
2743 if (comboBox->frame) {
2744 cachePainter.save();
2745 cachePainter.setRenderHint(QPainter::Antialiasing, true);
2746 cachePainter.translate(0.5, 0.5);
2747 cachePainter.setPen(Qt::NoPen);
2748 cachePainter.setBrush(buttonOption.palette.base());
2749 cachePainter.drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2);
2750 cachePainter.restore();
2751 proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget);
2752 }
2753
2754 // Draw button clipped
2755 cachePainter.save();
2756 cachePainter.setClipRect(downArrowRect.adjusted(0, 0, 1, 0));
2757 buttonOption.rect.setLeft(comboBox->direction == Qt::LeftToRight ?
2758 downArrowRect.left() - 6: downArrowRect.right() + 6);
2759 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
2760 cachePainter.restore();
2761 cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 1));
2762
2763 if (!sunken) {
2764 int borderSize = 1;
2765 if (comboBox->direction == Qt::RightToLeft) {
2766 cachePainter.drawLine(QPoint(downArrowRect.right() - 1, downArrowRect.top() + borderSize ),
2767 QPoint(downArrowRect.right() - 1, downArrowRect.bottom() - borderSize));
2768 } else {
2769 cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
2770 QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
2771 }
2772 } else {
2773 if (comboBox->direction == Qt::RightToLeft) {
2774 cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + 2),
2775 QPoint(downArrowRect.right(), downArrowRect.bottom() - 2));
2776
2777 } else {
2778 cachePainter.drawLine(QPoint(downArrowRect.left(), downArrowRect.top() + 2),
2779 QPoint(downArrowRect.left(), downArrowRect.bottom() - 2));
2780 }
2781 }
2782 } else {
2783 QStyleOptionButton buttonOption;
2784 buttonOption.QStyleOption::operator=(*comboBox);
2785 buttonOption.rect = rect;
2786 buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus | State_KeyboardFocusChange);
2787 if (sunken) {
2788 buttonOption.state |= State_Sunken;
2789 buttonOption.state &= ~State_MouseOver;
2790 }
2791 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
2792 }
2793 if (comboBox->subControls & SC_ComboBoxArrow) {
2794 // Draw the up/down arrow
2795 QColor arrowColor = option->palette.buttonText().color();
2796 arrowColor.setAlpha(160);
2797 qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downArrowRect, arrowColor);
2798 }
2799 cachePainter.end();
2800 QPixmapCache::insert(pixmapName, cache);
2801 }
2802 painter->drawPixmap(comboBox->rect.topLeft(), cache);
2803 }
2804 painter->restore();
2805 break;
2806 #if QT_CONFIG(slider)
2807 case CC_Slider:
2808 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
2809 QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
2810 QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
2811
2812 bool horizontal = slider->orientation == Qt::Horizontal;
2813 bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
2814 bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
2815 QColor activeHighlight = d->highlight(option->palette);
2816 QPixmap cache;
2817 QBrush oldBrush = painter->brush();
2818 QPen oldPen = painter->pen();
2819 QColor shadowAlpha(Qt::black);
2820 shadowAlpha.setAlpha(10);
2821 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
2822 outline = d->highlightedOutline(option->palette);
2823
2824
2825 if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
2826 QColor grooveColor;
2827 grooveColor.setHsv(buttonColor.hue(),
2828 qMin(255, (int)(buttonColor.saturation())),
2829 qMin(255, (int)(buttonColor.value()*0.9)));
2830 QString groovePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_groove"), option, groove.size());
2831 QRect pixmapRect(0, 0, groove.width(), groove.height());
2832
2833 // draw background groove
2834 if (!QPixmapCache::find(groovePixmapName, &cache)) {
2835 cache = styleCachePixmap(pixmapRect.size());
2836 cache.fill(Qt::transparent);
2837 QPainter groovePainter(&cache);
2838 groovePainter.setRenderHint(QPainter::Antialiasing, true);
2839 groovePainter.translate(0.5, 0.5);
2840 QLinearGradient gradient;
2841 if (horizontal) {
2842 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
2843 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
2844 }
2845 else {
2846 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
2847 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
2848 }
2849 groovePainter.setPen(QPen(outline));
2850 gradient.setColorAt(0, grooveColor.darker(110));
2851 gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115));
2852 groovePainter.setBrush(gradient);
2853 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
2854 groovePainter.end();
2855 QPixmapCache::insert(groovePixmapName, cache);
2856 }
2857 painter->drawPixmap(groove.topLeft(), cache);
2858
2859 // draw blue groove highlight
2860 QRect clipRect;
2861 groovePixmapName += QLatin1String("_blue");
2862 if (!QPixmapCache::find(groovePixmapName, &cache)) {
2863 cache = styleCachePixmap(pixmapRect.size());
2864 cache.fill(Qt::transparent);
2865 QPainter groovePainter(&cache);
2866 QLinearGradient gradient;
2867 if (horizontal) {
2868 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
2869 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
2870 }
2871 else {
2872 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
2873 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
2874 }
2875 QColor highlight = d->highlight(option->palette);
2876 QColor highlightedoutline = highlight.darker(140);
2877 if (qGray(outline.rgb()) > qGray(highlightedoutline.rgb()))
2878 outline = highlightedoutline;
2879
2880
2881 groovePainter.setRenderHint(QPainter::Antialiasing, true);
2882 groovePainter.translate(0.5, 0.5);
2883 groovePainter.setPen(QPen(outline));
2884 gradient.setColorAt(0, activeHighlight);
2885 gradient.setColorAt(1, activeHighlight.lighter(130));
2886 groovePainter.setBrush(gradient);
2887 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
2888 groovePainter.setPen(d->innerContrastLine());
2889 groovePainter.setBrush(Qt::NoBrush);
2890 groovePainter.drawRoundedRect(pixmapRect.adjusted(2, 2, -3, -3), 1, 1);
2891 groovePainter.end();
2892 QPixmapCache::insert(groovePixmapName, cache);
2893 }
2894 if (horizontal) {
2895 if (slider->upsideDown)
2896 clipRect = QRect(handle.right(), groove.top(), groove.right() - handle.right(), groove.height());
2897 else
2898 clipRect = QRect(groove.left(), groove.top(), handle.left(), groove.height());
2899 } else {
2900 if (slider->upsideDown)
2901 clipRect = QRect(groove.left(), handle.bottom(), groove.width(), groove.height() - handle.bottom());
2902 else
2903 clipRect = QRect(groove.left(), groove.top(), groove.width(), handle.top() - groove.top());
2904 }
2905 painter->save();
2906 painter->setClipRect(clipRect.adjusted(0, 0, 1, 1), Qt::IntersectClip);
2907 painter->drawPixmap(groove.topLeft(), cache);
2908 painter->restore();
2909 }
2910
2911 if (option->subControls & SC_SliderTickmarks) {
2912 painter->setPen(outline);
2913 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
2914 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
2915 int interval = slider->tickInterval;
2916 if (interval <= 0) {
2917 interval = slider->singleStep;
2918 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
2919 available)
2920 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2921 0, available) < 3)
2922 interval = slider->pageStep;
2923 }
2924 if (interval <= 0)
2925 interval = 1;
2926
2927 int v = slider->minimum;
2928 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
2929 while (v <= slider->maximum + 1) {
2930 if (v == slider->maximum + 1 && interval == 1)
2931 break;
2932 const int v_ = qMin(v, slider->maximum);
2933 int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
2934 v_, (horizontal
2935 ? slider->rect.width()
2936 : slider->rect.height()) - len,
2937 slider->upsideDown) + len / 2;
2938 int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
2939
2940 if (horizontal) {
2941 if (ticksAbove) {
2942 painter->drawLine(pos, slider->rect.top() + extra,
2943 pos, slider->rect.top() + tickSize);
2944 }
2945 if (ticksBelow) {
2946 painter->drawLine(pos, slider->rect.bottom() - extra,
2947 pos, slider->rect.bottom() - tickSize);
2948 }
2949 } else {
2950 if (ticksAbove) {
2951 painter->drawLine(slider->rect.left() + extra, pos,
2952 slider->rect.left() + tickSize, pos);
2953 }
2954 if (ticksBelow) {
2955 painter->drawLine(slider->rect.right() - extra, pos,
2956 slider->rect.right() - tickSize, pos);
2957 }
2958 }
2959 // in the case where maximum is max int
2960 int nextInterval = v + interval;
2961 if (nextInterval < v)
2962 break;
2963 v = nextInterval;
2964 }
2965 }
2966 // draw handle
2967 if ((option->subControls & SC_SliderHandle) ) {
2968 QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size());
2969 if (!QPixmapCache::find(handlePixmapName, &cache)) {
2970 cache = styleCachePixmap(handle.size());
2971 cache.fill(Qt::transparent);
2972 QRect pixmapRect(0, 0, handle.width(), handle.height());
2973 QPainter handlePainter(&cache);
2974 QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2);
2975
2976 // gradient fill
2977 QRect r = pixmapRect.adjusted(1, 1, -2, -2);
2978 QLinearGradient gradient = qt_fusion_gradient(gradRect, d->buttonColor(option->palette),horizontal ? TopDown : FromLeft);
2979
2980 handlePainter.setRenderHint(QPainter::Antialiasing, true);
2981 handlePainter.translate(0.5, 0.5);
2982
2983 handlePainter.setPen(Qt::NoPen);
2984 handlePainter.setBrush(QColor(0, 0, 0, 40));
2985 handlePainter.drawRect(r.adjusted(-1, 2, 1, -2));
2986
2987 handlePainter.setPen(QPen(d->outline(option->palette)));
2988 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
2989 handlePainter.setPen(QPen(d->highlightedOutline(option->palette)));
2990
2991 handlePainter.setBrush(gradient);
2992 handlePainter.drawRoundedRect(r, 2, 2);
2993 handlePainter.setBrush(Qt::NoBrush);
2994 handlePainter.setPen(d->innerContrastLine());
2995 handlePainter.drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2);
2996
2997 QColor cornerAlpha = outline.darker(120);
2998 cornerAlpha.setAlpha(80);
2999
3000 //handle shadow
3001 handlePainter.setPen(shadowAlpha);
3002 handlePainter.drawLine(QPoint(r.left() + 2, r.bottom() + 1), QPoint(r.right() - 2, r.bottom() + 1));
3003 handlePainter.drawLine(QPoint(r.right() + 1, r.bottom() - 3), QPoint(r.right() + 1, r.top() + 4));
3004 handlePainter.drawLine(QPoint(r.right() - 1, r.bottom()), QPoint(r.right() + 1, r.bottom() - 2));
3005
3006 handlePainter.end();
3007 QPixmapCache::insert(handlePixmapName, cache);
3008 }
3009
3010 painter->drawPixmap(handle.topLeft(), cache);
3011
3012 }
3013 painter->setBrush(oldBrush);
3014 painter->setPen(oldPen);
3015 }
3016 break;
3017 #endif // QT_CONFIG(slider)
3018 #if QT_CONFIG(dial)
3019 case CC_Dial:
3020 if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
3021 QStyleHelper::drawDial(dial, painter);
3022 break;
3023 #endif
3024 default:
3025 QCommonStyle::drawComplexControl(control, option, painter, widget);
3026 break;
3027 }
3028 }
3029
3030 /*!
3031 \reimp
3032 */
pixelMetric(PixelMetric metric,const QStyleOption * option,const QWidget * widget) const3033 int QFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
3034 {
3035 int val = -1;
3036 switch (metric) {
3037 case PM_SliderTickmarkOffset:
3038 val = 4;
3039 break;
3040 case PM_HeaderMargin:
3041 case PM_ToolTipLabelFrameWidth:
3042 val = 2;
3043 break;
3044 case PM_ButtonDefaultIndicator:
3045 case PM_ButtonShiftHorizontal:
3046 case PM_ButtonShiftVertical:
3047 val = 0;
3048 break;
3049 case PM_MessageBoxIconSize:
3050 val = 48;
3051 break;
3052 case PM_ListViewIconSize:
3053 val = 24;
3054 break;
3055 case PM_DialogButtonsSeparator:
3056 case PM_ScrollBarSliderMin:
3057 val = 26;
3058 break;
3059 case PM_TitleBarHeight:
3060 val = 24;
3061 break;
3062 case PM_ScrollBarExtent:
3063 val = 14;
3064 break;
3065 case PM_SliderThickness:
3066 case PM_SliderLength:
3067 val = 15;
3068 break;
3069 case PM_DockWidgetTitleMargin:
3070 val = 1;
3071 break;
3072 case PM_SpinBoxFrameWidth:
3073 val = 3;
3074 break;
3075 case PM_MenuVMargin:
3076 case PM_MenuHMargin:
3077 case PM_MenuPanelWidth:
3078 val = 0;
3079 break;
3080 case PM_MenuBarItemSpacing:
3081 val = 6;
3082 break;
3083 case PM_MenuBarVMargin:
3084 case PM_MenuBarHMargin:
3085 case PM_MenuBarPanelWidth:
3086 val = 0;
3087 break;
3088 case PM_ToolBarHandleExtent:
3089 val = 9;
3090 break;
3091 case PM_ToolBarItemSpacing:
3092 val = 1;
3093 break;
3094 case PM_ToolBarFrameWidth:
3095 case PM_ToolBarItemMargin:
3096 val = 2;
3097 break;
3098 case PM_SmallIconSize:
3099 case PM_ButtonIconSize:
3100 val = 16;
3101 break;
3102 case PM_DockWidgetTitleBarButtonMargin:
3103 val = 2;
3104 break;
3105 case PM_TitleBarButtonSize:
3106 val = 19;
3107 break;
3108 case PM_MaximumDragDistance:
3109 return -1; // Do not dpi-scale because the value is magic
3110 case PM_TabCloseIndicatorWidth:
3111 case PM_TabCloseIndicatorHeight:
3112 val = 20;
3113 break;
3114 case PM_TabBarTabVSpace:
3115 val = 12;
3116 break;
3117 case PM_TabBarTabOverlap:
3118 val = 1;
3119 break;
3120 case PM_TabBarBaseOverlap:
3121 val = 2;
3122 break;
3123 case PM_SubMenuOverlap:
3124 val = -1;
3125 break;
3126 case PM_DockWidgetHandleExtent:
3127 case PM_SplitterWidth:
3128 val = 4;
3129 break;
3130 case PM_IndicatorHeight:
3131 case PM_IndicatorWidth:
3132 case PM_ExclusiveIndicatorHeight:
3133 case PM_ExclusiveIndicatorWidth:
3134 val = 14;
3135 break;
3136 case PM_ScrollView_ScrollBarSpacing:
3137 val = 0;
3138 break;
3139 case PM_ScrollView_ScrollBarOverlap:
3140 if (proxy()->styleHint(SH_ScrollBar_Transient, option, widget))
3141 return proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
3142 val = 0;
3143 break;
3144 case PM_DefaultFrameWidth:
3145 return 1; // Do not dpi-scale because the drawn frame is always exactly 1 pixel thick
3146 default:
3147 return QCommonStyle::pixelMetric(metric, option, widget);
3148 }
3149 return QStyleHelper::dpiScaled(val, option);
3150 }
3151
3152 /*!
3153 \reimp
3154 */
sizeFromContents(ContentsType type,const QStyleOption * option,const QSize & size,const QWidget * widget) const3155 QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
3156 const QSize &size, const QWidget *widget) const
3157 {
3158 QSize newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
3159 switch (type) {
3160 case CT_PushButton:
3161 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
3162 if (!btn->text.isEmpty() && newSize.width() < 80)
3163 newSize.setWidth(80);
3164 if (!btn->icon.isNull() && btn->iconSize.height() > 16)
3165 newSize -= QSize(0, 2);
3166 }
3167 break;
3168 case CT_GroupBox:
3169 if (option) {
3170 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
3171 newSize += QSize(10, topMargin); // Add some space below the groupbox
3172 }
3173 break;
3174 case CT_RadioButton:
3175 case CT_CheckBox:
3176 newSize += QSize(0, 1);
3177 break;
3178 case CT_ToolButton:
3179 newSize += QSize(2, 2);
3180 break;
3181 case CT_SpinBox:
3182 newSize += QSize(0, -3);
3183 break;
3184 case CT_ComboBox:
3185 newSize += QSize(2, 4);
3186 break;
3187 case CT_LineEdit:
3188 newSize += QSize(0, 4);
3189 break;
3190 case CT_MenuBarItem:
3191 newSize += QSize(8, 5);
3192 break;
3193 case CT_MenuItem:
3194 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
3195 int w = newSize.width();
3196 int maxpmw = menuItem->maxIconWidth;
3197 int tabSpacing = 20;
3198 if (menuItem->text.contains(QLatin1Char('\t')))
3199 w += tabSpacing;
3200 else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
3201 w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin, option);
3202 else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
3203 QFontMetrics fm(menuItem->font);
3204 QFont fontBold = menuItem->font;
3205 fontBold.setBold(true);
3206 QFontMetrics fmBold(fontBold);
3207 w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text);
3208 }
3209 const qreal dpi = QStyleHelper::dpi(option);
3210 const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth, dpi)); // Windows always shows a check column
3211 w += checkcol;
3212 w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10, dpi);
3213 newSize.setWidth(w);
3214 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
3215 if (!menuItem->text.isEmpty()) {
3216 newSize.setHeight(menuItem->fontMetrics.height());
3217 }
3218 }
3219 else if (!menuItem->icon.isNull()) {
3220 #if QT_CONFIG(combobox)
3221 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget)) {
3222 newSize.setHeight(qMax(combo->iconSize().height() + 2, newSize.height()));
3223 }
3224 #endif
3225 }
3226 newSize.setWidth(newSize.width() + int(QStyleHelper::dpiScaled(12, dpi)));
3227 newSize.setWidth(qMax<int>(newSize.width(), int(QStyleHelper::dpiScaled(120, dpi))));
3228 }
3229 break;
3230 case CT_SizeGrip:
3231 newSize += QSize(4, 4);
3232 break;
3233 case CT_MdiControls:
3234 newSize -= QSize(1, 0);
3235 break;
3236 default:
3237 break;
3238 }
3239 return newSize;
3240 }
3241
3242 /*!
3243 \reimp
3244 */
polish(QApplication * app)3245 void QFusionStyle::polish(QApplication *app)
3246 {
3247 QCommonStyle::polish(app);
3248 }
3249
3250 /*!
3251 \reimp
3252 */
polish(QWidget * widget)3253 void QFusionStyle::polish(QWidget *widget)
3254 {
3255 QCommonStyle::polish(widget);
3256 if (false
3257 #if QT_CONFIG(abstractbutton)
3258 || qobject_cast<QAbstractButton*>(widget)
3259 #endif
3260 #if QT_CONFIG(combobox)
3261 || qobject_cast<QComboBox *>(widget)
3262 #endif
3263 #if QT_CONFIG(progressbar)
3264 || qobject_cast<QProgressBar *>(widget)
3265 #endif
3266 #if QT_CONFIG(scrollbar)
3267 || qobject_cast<QScrollBar *>(widget)
3268 #endif
3269 #if QT_CONFIG(splitter)
3270 || qobject_cast<QSplitterHandle *>(widget)
3271 #endif
3272 #if QT_CONFIG(abstractslider)
3273 || qobject_cast<QAbstractSlider *>(widget)
3274 #endif
3275 #if QT_CONFIG(spinbox)
3276 || qobject_cast<QAbstractSpinBox *>(widget)
3277 #endif
3278 || (widget->inherits("QDockSeparator"))
3279 || (widget->inherits("QDockWidgetSeparator"))
3280 ) {
3281 widget->setAttribute(Qt::WA_Hover, true);
3282 widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
3283 }
3284 }
3285
3286 /*!
3287 \reimp
3288 */
polish(QPalette & pal)3289 void QFusionStyle::polish(QPalette &pal)
3290 {
3291 QCommonStyle::polish(pal);
3292 }
3293
3294 /*!
3295 \reimp
3296 */
unpolish(QWidget * widget)3297 void QFusionStyle::unpolish(QWidget *widget)
3298 {
3299 QCommonStyle::unpolish(widget);
3300 if (false
3301 #if QT_CONFIG(abstractbutton)
3302 || qobject_cast<QAbstractButton*>(widget)
3303 #endif
3304 #if QT_CONFIG(combobox)
3305 || qobject_cast<QComboBox *>(widget)
3306 #endif
3307 #if QT_CONFIG(progressbar)
3308 || qobject_cast<QProgressBar *>(widget)
3309 #endif
3310 #if QT_CONFIG(scrollbar)
3311 || qobject_cast<QScrollBar *>(widget)
3312 #endif
3313 #if QT_CONFIG(splitter)
3314 || qobject_cast<QSplitterHandle *>(widget)
3315 #endif
3316 #if QT_CONFIG(abstractslider)
3317 || qobject_cast<QAbstractSlider *>(widget)
3318 #endif
3319 #if QT_CONFIG(spinbox)
3320 || qobject_cast<QAbstractSpinBox *>(widget)
3321 #endif
3322 || (widget->inherits("QDockSeparator"))
3323 || (widget->inherits("QDockWidgetSeparator"))
3324 ) {
3325 widget->setAttribute(Qt::WA_Hover, false);
3326 }
3327 }
3328
3329 /*!
3330 \reimp
3331 */
unpolish(QApplication * app)3332 void QFusionStyle::unpolish(QApplication *app)
3333 {
3334 QCommonStyle::unpolish(app);
3335 }
3336
3337 /*!
3338 \reimp
3339 */
subControlRect(ComplexControl control,const QStyleOptionComplex * option,SubControl subControl,const QWidget * widget) const3340 QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
3341 SubControl subControl, const QWidget *widget) const
3342 {
3343 QRect rect = QCommonStyle::subControlRect(control, option, subControl, widget);
3344
3345 switch (control) {
3346 #if QT_CONFIG(slider)
3347 case CC_Slider:
3348 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
3349 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
3350 switch (subControl) {
3351 case SC_SliderHandle: {
3352 if (slider->orientation == Qt::Horizontal) {
3353 rect.setHeight(proxy()->pixelMetric(PM_SliderThickness, option));
3354 rect.setWidth(proxy()->pixelMetric(PM_SliderLength, option));
3355 int centerY = slider->rect.center().y() - rect.height() / 2;
3356 if (slider->tickPosition & QSlider::TicksAbove)
3357 centerY += tickSize;
3358 if (slider->tickPosition & QSlider::TicksBelow)
3359 centerY -= tickSize;
3360 rect.moveTop(centerY);
3361 } else {
3362 rect.setWidth(proxy()->pixelMetric(PM_SliderThickness, option));
3363 rect.setHeight(proxy()->pixelMetric(PM_SliderLength, option));
3364 int centerX = slider->rect.center().x() - rect.width() / 2;
3365 if (slider->tickPosition & QSlider::TicksAbove)
3366 centerX += tickSize;
3367 if (slider->tickPosition & QSlider::TicksBelow)
3368 centerX -= tickSize;
3369 rect.moveLeft(centerX);
3370 }
3371 }
3372 break;
3373 case SC_SliderGroove: {
3374 QPoint grooveCenter = slider->rect.center();
3375 const int grooveThickness = QStyleHelper::dpiScaled(7, option);
3376 if (slider->orientation == Qt::Horizontal) {
3377 rect.setHeight(grooveThickness);
3378 if (slider->tickPosition & QSlider::TicksAbove)
3379 grooveCenter.ry() += tickSize;
3380 if (slider->tickPosition & QSlider::TicksBelow)
3381 grooveCenter.ry() -= tickSize;
3382 } else {
3383 rect.setWidth(grooveThickness);
3384 if (slider->tickPosition & QSlider::TicksAbove)
3385 grooveCenter.rx() += tickSize;
3386 if (slider->tickPosition & QSlider::TicksBelow)
3387 grooveCenter.rx() -= tickSize;
3388 }
3389 rect.moveCenter(grooveCenter);
3390 break;
3391 }
3392 default:
3393 break;
3394 }
3395 }
3396 break;
3397 #endif // QT_CONFIG(slider)
3398 #if QT_CONFIG(spinbox)
3399 case CC_SpinBox:
3400 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
3401 int center = spinbox->rect.height() / 2;
3402 int fw = spinbox->frame ? 3 : 0; // Is drawn with 3 pixels width in drawComplexControl, independently from PM_SpinBoxFrameWidth
3403 int y = fw;
3404 const int buttonWidth = QStyleHelper::dpiScaled(14, option);
3405 int x, lx, rx;
3406 x = spinbox->rect.width() - y - buttonWidth + 2;
3407 lx = fw;
3408 rx = x - fw;
3409 switch (subControl) {
3410 case SC_SpinBoxUp:
3411 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3412 return QRect();
3413 rect = QRect(x, fw, buttonWidth, center - fw);
3414 break;
3415 case SC_SpinBoxDown:
3416 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3417 return QRect();
3418
3419 rect = QRect(x, center, buttonWidth, spinbox->rect.bottom() - center - fw + 1);
3420 break;
3421 case SC_SpinBoxEditField:
3422 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
3423 rect = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
3424 } else {
3425 rect = QRect(lx, fw, rx - qMax(fw - 1, 0), spinbox->rect.height() - 2*fw);
3426 }
3427 break;
3428 case SC_SpinBoxFrame:
3429 rect = spinbox->rect;
3430 default:
3431 break;
3432 }
3433 rect = visualRect(spinbox->direction, spinbox->rect, rect);
3434 }
3435 break;
3436 #endif // QT_CONFIG(spinbox)
3437 case CC_GroupBox:
3438 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
3439 rect = option->rect;
3440 if (subControl == SC_GroupBoxFrame)
3441 return rect.adjusted(0, 0, 0, 0);
3442 else if (subControl == SC_GroupBoxContents) {
3443 QRect frameRect = option->rect.adjusted(0, 0, 0, -groupBoxBottomMargin);
3444 int margin = 3;
3445 int leftMarginExtension = 0;
3446 const int exclusiveIndicatorHeight = option->subControls.testFlag(SC_GroupBoxCheckBox) ?
3447 pixelMetric(PM_ExclusiveIndicatorHeight) : 0;
3448 const int fontMetricsHeight = groupBox->text.isEmpty() ? 0 :
3449 groupBox->fontMetrics.height();
3450 const int topMargin = qMax(exclusiveIndicatorHeight, fontMetricsHeight) +
3451 groupBoxTopMargin;
3452 return frameRect.adjusted(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBoxBottomMargin);
3453 }
3454
3455 QSize textSize = option->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
3456 int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
3457 int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
3458
3459 const int width = textSize.width()
3460 + (option->subControls & QStyle::SC_GroupBoxCheckBox ? indicatorWidth + 5 : 0);
3461
3462 rect = QRect();
3463
3464 if (option->rect.width() > width) {
3465 switch (groupBox->textAlignment & Qt::AlignHorizontal_Mask) {
3466 case Qt::AlignHCenter:
3467 rect.moveLeft((option->rect.width() - width) / 2);
3468 break;
3469 case Qt::AlignRight:
3470 rect.moveLeft(option->rect.width() - width);
3471 break;
3472 }
3473 }
3474
3475 if (subControl == SC_GroupBoxCheckBox) {
3476 rect.setWidth(indicatorWidth);
3477 rect.setHeight(indicatorHeight);
3478 rect.moveTop(textSize.height() > indicatorHeight ? (textSize.height() - indicatorHeight) / 2 : 0);
3479 rect.translate(1, 0);
3480 } else if (subControl == SC_GroupBoxLabel) {
3481 rect.setSize(textSize);
3482 rect.moveTop(1);
3483 if (option->subControls & QStyle::SC_GroupBoxCheckBox)
3484 rect.translate(indicatorWidth + 5, 0);
3485 }
3486 return visualRect(option->direction, option->rect, rect);
3487 }
3488
3489 return rect;
3490
3491 case CC_ComboBox:
3492 switch (subControl) {
3493 case SC_ComboBoxArrow: {
3494 const qreal dpi = QStyleHelper::dpi(option);
3495 rect = visualRect(option->direction, option->rect, rect);
3496 rect.setRect(rect.right() - int(QStyleHelper::dpiScaled(18, dpi)), rect.top() - 2,
3497 int(QStyleHelper::dpiScaled(19, dpi)), rect.height() + 4);
3498 rect = visualRect(option->direction, option->rect, rect);
3499 }
3500 break;
3501 case SC_ComboBoxEditField: {
3502 int frameWidth = 2;
3503 rect = visualRect(option->direction, option->rect, rect);
3504 rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
3505 option->rect.width() - int(QStyleHelper::dpiScaled(19, option)) - 2 * frameWidth,
3506 option->rect.height() - 2 * frameWidth);
3507 if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
3508 if (!box->editable) {
3509 rect.adjust(2, 0, 0, 0);
3510 if (box->state & (State_Sunken | State_On))
3511 rect.translate(1, 1);
3512 }
3513 }
3514 rect = visualRect(option->direction, option->rect, rect);
3515 break;
3516 }
3517 default:
3518 break;
3519 }
3520 break;
3521 case CC_TitleBar:
3522 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
3523 SubControl sc = subControl;
3524 QRect &ret = rect;
3525 const int indent = 3;
3526 const int controlTopMargin = 3;
3527 const int controlBottomMargin = 3;
3528 const int controlWidthMargin = 2;
3529 const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin ;
3530 const int delta = controlHeight + controlWidthMargin;
3531 int offset = 0;
3532
3533 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3534 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3535
3536 switch (sc) {
3537 case SC_TitleBarLabel:
3538 if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
3539 ret = tb->rect;
3540 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3541 ret.adjust(delta, 0, -delta, 0);
3542 if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3543 ret.adjust(0, 0, -delta, 0);
3544 if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3545 ret.adjust(0, 0, -delta, 0);
3546 if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
3547 ret.adjust(0, 0, -delta, 0);
3548 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3549 ret.adjust(0, 0, -delta, 0);
3550 }
3551 break;
3552 case SC_TitleBarContextHelpButton:
3553 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3554 offset += delta;
3555 Q_FALLTHROUGH();
3556 case SC_TitleBarMinButton:
3557 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3558 offset += delta;
3559 else if (sc == SC_TitleBarMinButton)
3560 break;
3561 Q_FALLTHROUGH();
3562 case SC_TitleBarNormalButton:
3563 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3564 offset += delta;
3565 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3566 offset += delta;
3567 else if (sc == SC_TitleBarNormalButton)
3568 break;
3569 Q_FALLTHROUGH();
3570 case SC_TitleBarMaxButton:
3571 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3572 offset += delta;
3573 else if (sc == SC_TitleBarMaxButton)
3574 break;
3575 Q_FALLTHROUGH();
3576 case SC_TitleBarShadeButton:
3577 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3578 offset += delta;
3579 else if (sc == SC_TitleBarShadeButton)
3580 break;
3581 Q_FALLTHROUGH();
3582 case SC_TitleBarUnshadeButton:
3583 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3584 offset += delta;
3585 else if (sc == SC_TitleBarUnshadeButton)
3586 break;
3587 Q_FALLTHROUGH();
3588 case SC_TitleBarCloseButton:
3589 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3590 offset += delta;
3591 else if (sc == SC_TitleBarCloseButton)
3592 break;
3593 ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
3594 controlHeight, controlHeight);
3595 break;
3596 case SC_TitleBarSysMenu:
3597 if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3598 ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
3599 controlHeight, controlHeight);
3600 }
3601 break;
3602 default:
3603 break;
3604 }
3605 ret = visualRect(tb->direction, tb->rect, ret);
3606 }
3607 break;
3608 default:
3609 break;
3610 }
3611
3612 return rect;
3613 }
3614
3615
3616 /*!
3617 \reimp
3618 */
itemPixmapRect(const QRect & r,int flags,const QPixmap & pixmap) const3619 QRect QFusionStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
3620 {
3621 return QCommonStyle::itemPixmapRect(r, flags, pixmap);
3622 }
3623
3624 /*!
3625 \reimp
3626 */
drawItemPixmap(QPainter * painter,const QRect & rect,int alignment,const QPixmap & pixmap) const3627 void QFusionStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
3628 int alignment, const QPixmap &pixmap) const
3629 {
3630 QCommonStyle::drawItemPixmap(painter, rect, alignment, pixmap);
3631 }
3632
3633 /*!
3634 \reimp
3635 */
hitTestComplexControl(ComplexControl cc,const QStyleOptionComplex * opt,const QPoint & pt,const QWidget * w) const3636 QStyle::SubControl QFusionStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
3637 const QPoint &pt, const QWidget *w) const
3638 {
3639 return QCommonStyle::hitTestComplexControl(cc, opt, pt, w);
3640 }
3641
3642 /*!
3643 \reimp
3644 */
generatedIconPixmap(QIcon::Mode iconMode,const QPixmap & pixmap,const QStyleOption * opt) const3645 QPixmap QFusionStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
3646 const QStyleOption *opt) const
3647 {
3648 return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt);
3649 }
3650
3651 /*!
3652 \reimp
3653 */
styleHint(StyleHint hint,const QStyleOption * option,const QWidget * widget,QStyleHintReturn * returnData) const3654 int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
3655 QStyleHintReturn *returnData) const
3656 {
3657 switch (hint) {
3658 case SH_Slider_SnapToValue:
3659 case SH_PrintDialog_RightAlignButtons:
3660 case SH_FontDialog_SelectAssociatedText:
3661 case SH_MenuBar_AltKeyNavigation:
3662 case SH_ComboBox_ListMouseTracking:
3663 case SH_Slider_StopMouseOverSlider:
3664 case SH_ScrollBar_MiddleClickAbsolutePosition:
3665 case SH_EtchDisabledText:
3666 case SH_TitleBar_AutoRaise:
3667 case SH_TitleBar_NoBorder:
3668 case SH_ItemView_ShowDecorationSelected:
3669 case SH_ItemView_ArrowKeysNavigateIntoChildren:
3670 case SH_ItemView_ChangeHighlightOnFocus:
3671 case SH_MenuBar_MouseTracking:
3672 case SH_Menu_MouseTracking:
3673 case SH_Menu_SupportsSections:
3674 return 1;
3675
3676 #if defined(QT_PLATFORM_UIKIT)
3677 case SH_ComboBox_UseNativePopup:
3678 return 1;
3679 #endif
3680
3681 case SH_ToolBox_SelectedPageTitleBold:
3682 case SH_ScrollView_FrameOnlyAroundContents:
3683 case SH_Menu_AllowActiveAndDisabled:
3684 case SH_MainWindow_SpaceBelowMenuBar:
3685 case SH_MessageBox_CenterButtons:
3686 case SH_RubberBand_Mask:
3687 return 0;
3688
3689 case SH_ComboBox_Popup:
3690 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
3691 return !cmb->editable;
3692 return 0;
3693
3694 case SH_Table_GridLineColor:
3695 return option ? option->palette.window().color().darker(120).rgba() : 0;
3696
3697 case SH_MessageBox_TextInteractionFlags:
3698 return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
3699 #if QT_CONFIG(wizard)
3700 case SH_WizardStyle:
3701 return QWizard::ClassicStyle;
3702 #endif
3703 case SH_Menu_SubMenuPopupDelay:
3704 return 225; // default from GtkMenu
3705
3706 case SH_WindowFrame_Mask:
3707 if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData)) {
3708 //left rounded corner
3709 mask->region = option->rect;
3710 mask->region -= QRect(option->rect.left(), option->rect.top(), 5, 1);
3711 mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 3, 1);
3712 mask->region -= QRect(option->rect.left(), option->rect.top() + 2, 2, 1);
3713 mask->region -= QRect(option->rect.left(), option->rect.top() + 3, 1, 2);
3714
3715 //right rounded corner
3716 mask->region -= QRect(option->rect.right() - 4, option->rect.top(), 5, 1);
3717 mask->region -= QRect(option->rect.right() - 2, option->rect.top() + 1, 3, 1);
3718 mask->region -= QRect(option->rect.right() - 1, option->rect.top() + 2, 2, 1);
3719 mask->region -= QRect(option->rect.right() , option->rect.top() + 3, 1, 2);
3720 return 1;
3721 }
3722 default:
3723 break;
3724 }
3725 return QCommonStyle::styleHint(hint, option, widget, returnData);
3726 }
3727
3728 /*! \reimp */
subElementRect(SubElement sr,const QStyleOption * opt,const QWidget * w) const3729 QRect QFusionStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
3730 {
3731 QRect r = QCommonStyle::subElementRect(sr, opt, w);
3732 switch (sr) {
3733 case SE_ProgressBarLabel:
3734 case SE_ProgressBarContents:
3735 case SE_ProgressBarGroove:
3736 return opt->rect;
3737 case SE_PushButtonFocusRect:
3738 r.adjust(0, 1, 0, -1);
3739 break;
3740 case SE_DockWidgetTitleBarText: {
3741 if (const QStyleOptionDockWidget *titlebar = qstyleoption_cast<const QStyleOptionDockWidget*>(opt)) {
3742 bool verticalTitleBar = titlebar->verticalTitleBar;
3743 if (verticalTitleBar) {
3744 r.adjust(0, 0, 0, -4);
3745 } else {
3746 if (opt->direction == Qt::LeftToRight)
3747 r.adjust(4, 0, 0, 0);
3748 else
3749 r.adjust(0, 0, -4, 0);
3750 }
3751 }
3752
3753 break;
3754 }
3755 default:
3756 break;
3757 }
3758 return r;
3759 }
3760
3761 /*!
3762 \reimp
3763 */
standardIcon(StandardPixmap standardIcon,const QStyleOption * option,const QWidget * widget) const3764 QIcon QFusionStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
3765 const QWidget *widget) const
3766 {
3767 #if QT_CONFIG(imageformat_xpm)
3768 switch (standardIcon) {
3769 case SP_TitleBarNormalButton:
3770 return QIcon(QPixmap(dock_widget_restore_xpm));
3771 case SP_TitleBarMinButton:
3772 return QIcon(QPixmap(workspace_minimize));
3773 case SP_TitleBarCloseButton:
3774 case SP_DockWidgetCloseButton:
3775 return QIcon(QPixmap(dock_widget_close_xpm));
3776 default:
3777 break;
3778 }
3779 #endif // imageformat_xpm
3780 return QCommonStyle::standardIcon(standardIcon, option, widget);
3781 }
3782
3783 /*!
3784 \reimp
3785 */
standardPixmap(StandardPixmap standardPixmap,const QStyleOption * opt,const QWidget * widget) const3786 QPixmap QFusionStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
3787 const QWidget *widget) const
3788 {
3789 #ifndef QT_NO_IMAGEFORMAT_XPM
3790 switch (standardPixmap) {
3791 case SP_TitleBarNormalButton:
3792 return QPixmap(dock_widget_restore_xpm);
3793 case SP_TitleBarMinButton:
3794 return QPixmap(workspace_minimize);
3795 case SP_TitleBarCloseButton:
3796 case SP_DockWidgetCloseButton:
3797 return QPixmap(dock_widget_close_xpm);
3798
3799 default:
3800 break;
3801 }
3802 #endif //QT_NO_IMAGEFORMAT_XPM
3803
3804 return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
3805 }
3806
3807 QT_END_NAMESPACE
3808
3809 #include "moc_qfusionstyle_p.cpp"
3810
3811 #endif // style_fusion|| QT_PLUGIN
3812