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