1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquickcommonstyle.h"
5#include "qquickcommonstyle_p.h"
6#include "qquickcommonstylepixmaps_p.h"
7
8#include "qquickstyleoption.h"
9#include "qquickdrawutil.h"
10#include "qquickstylehelper_p.h"
11
12#include <QtGui/QWindow>
13#include <qfile.h>
14#include <private/qguiapplication_p.h>
15#include <qpa/qplatformtheme.h>
16#include <qbitmap.h>
17#include <qcache.h>
18#include <qmath.h>
19#include <qpainter.h>
20#include <qpaintengine.h>
21#include <qpainterpath.h>
22#include <private/qmath_p.h>
23#include <qdebug.h>
24#include <qtextformat.h>
25#include <qfileinfo.h>
26#include <qdir.h>
27#if QT_CONFIG(settings)
28#include <qsettings.h>
29#endif
30#include <qvariant.h>
31#include <qpixmapcache.h>
32#include <qmatrix4x4.h>
33
34#include <limits.h>
35
36#include <private/qtextengine_p.h>
37#include <QtGui/private/qhexstring_p.h>
38
39QT_BEGIN_NAMESPACE
40
41static inline qreal dpr(const QWindow *w)
42{
43 return w != nullptr ? w->devicePixelRatio() : qApp->devicePixelRatio();
44}
45
46/*!
47 \class QCommonStyle
48 \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI.
49
50 \ingroup appearance
51 \inmodule QtWidgets
52
53 This abstract class implements some of the widget's look and feel
54 that is common to all GUI styles provided and shipped as part of
55 Qt.
56
57 Since QCommonStyle inherits QStyle, all of its functions are fully documented
58 in the QStyle documentation.
59 \omit
60 , although the
61 extra functions that QCommonStyle provides, e.g.
62 drawComplexControl(), drawControl(), drawPrimitive(),
63 hitTestComplexControl(), subControlRect(), sizeFromContents(), and
64 subElementRect() are documented here.
65 \endomit
66
67 \sa QStyle, QProxyStyle
68*/
69
70namespace QQC2 {
71
72QCommonStyle::QCommonStyle()
73 : QStyle(*new QCommonStylePrivate)
74{ }
75
76QCommonStyle::QCommonStyle(QCommonStylePrivate &dd)
77 : QStyle(dd)
78{ }
79
80QCommonStyle::~QCommonStyle()
81{ }
82
83void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const
84{
85 Q_D(const QCommonStyle);
86 switch (pe) {
87 case PE_FrameButtonBevel:
88 case PE_FrameButtonTool:
89 qDrawShadeRect(p, r: opt->rect, pal: opt->palette,
90 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1, midLineWidth: 0);
91 break;
92 case PE_PanelButtonCommand:
93 case PE_PanelButtonBevel:
94 case PE_PanelButtonTool:
95 case PE_IndicatorButtonDropDown:
96 qDrawShadePanel(p, r: opt->rect, pal: opt->palette,
97 sunken: opt->state & (State_Sunken | State_On), lineWidth: 1,
98 fill: &opt->palette.brush(cr: QPalette::Button));
99 break;
100 case PE_IndicatorItemViewItemCheck:
101 proxy()->drawPrimitive(pe: PE_IndicatorCheckBox, opt, p);
102 break;
103 case PE_IndicatorCheckBox:
104 if (opt->state & State_NoChange) {
105 p->setPen(opt->palette.windowText().color());
106 p->fillRect(opt->rect, opt->palette.brush(cr: QPalette::Button));
107 p->drawRect(r: opt->rect);
108 p->drawLine(p1: opt->rect.topLeft(), p2: opt->rect.bottomRight());
109 } else {
110 qDrawShadePanel(p, x: opt->rect.x(), y: opt->rect.y(), w: opt->rect.width(), h: opt->rect.height(),
111 pal: opt->palette, sunken: opt->state & (State_Sunken | State_On), lineWidth: 1,
112 fill: &opt->palette.brush(cr: QPalette::Button));
113 }
114 break;
115 case PE_IndicatorRadioButton: {
116 QRect ir = opt->rect;
117 p->setPen(opt->palette.dark().color());
118 p->drawArc(r: opt->rect, a: 0, alen: 5760);
119 if (opt->state & (State_Sunken | State_On)) {
120 ir.adjust(dx1: 2, dy1: 2, dx2: -2, dy2: -2);
121 p->setBrush(opt->palette.windowText());
122 p->drawEllipse(r: ir);
123 }
124 break; }
125 case PE_FrameFocusRect:
126 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
127 QColor bg = fropt->backgroundColor;
128 QPen oldPen = p->pen();
129 if (bg.isValid()) {
130 int h, s, v;
131 bg.getHsv(h: &h, s: &s, v: &v);
132 if (v >= 128)
133 p->setPen(Qt::black);
134 else
135 p->setPen(Qt::white);
136 } else {
137 p->setPen(opt->palette.windowText().color());
138 }
139 QRect focusRect = opt->rect.adjusted(xp1: 1, yp1: 1, xp2: -1, yp2: -1);
140 p->drawRect(r: focusRect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1)); //draw pen inclusive
141 p->setPen(oldPen);
142 }
143 break;
144 case PE_IndicatorMenuCheckMark: {
145 const int markW = opt->rect.width() > 7 ? 7 : opt->rect.width();
146 const int markH = markW;
147 int posX = opt->rect.x() + (opt->rect.width() - markW)/2 + 1;
148 int posY = opt->rect.y() + (opt->rect.height() - markH)/2;
149
150 QVector<QLineF> a;
151 a.reserve(size: markH);
152
153 int i, xx, yy;
154 xx = posX;
155 yy = 3 + posY;
156 for (i = 0; i < markW/2; ++i) {
157 a << QLineF(xx, yy, xx, yy + 2);
158 ++xx;
159 ++yy;
160 }
161 yy -= 2;
162 for (; i < markH; ++i) {
163 a << QLineF(xx, yy, xx, yy + 2);
164 ++xx;
165 --yy;
166 }
167 if (!(opt->state & State_Enabled) && !(opt->state & State_On)) {
168 p->save();
169 p->translate(dx: 1, dy: 1);
170 p->setPen(opt->palette.light().color());
171 p->drawLines(lines: a);
172 p->restore();
173 }
174 p->setPen((opt->state & State_On) ? opt->palette.highlightedText().color() : opt->palette.text().color());
175 p->drawLines(lines: a);
176 break; }
177 case PE_Frame:
178 case PE_FrameMenu:
179 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
180 if (pe == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
181 qDrawShadePanel(p, r: frame->rect, pal: frame->palette, sunken: frame->state & State_Sunken,
182 lineWidth: frame->lineWidth);
183 } else {
184 qDrawPlainRect(p, r: frame->rect, frame->palette.windowText().color(), lineWidth: frame->lineWidth);
185 }
186 }
187 break;
188 case PE_PanelMenuBar:
189 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)){
190 qDrawShadePanel(p, r: frame->rect, pal: frame->palette, sunken: false, lineWidth: frame->lineWidth,
191 fill: &frame->palette.brush(cr: QPalette::Button));
192
193 }
194 else if (const QStyleOptionToolBar *frame = qstyleoption_cast<const QStyleOptionToolBar *>(opt)){
195 qDrawShadePanel(p, r: frame->rect, pal: frame->palette, sunken: false, lineWidth: frame->lineWidth,
196 fill: &frame->palette.brush(cr: QPalette::Button));
197 }
198
199 break;
200 case PE_PanelMenu:
201 break;
202 case PE_PanelToolBar:
203 break;
204 case PE_IndicatorProgressChunk:
205 {
206 p->fillRect(x: opt->rect.x(), y: opt->rect.y() + 3, w: opt->rect.width() -2, h: opt->rect.height() - 6,
207 b: opt->palette.brush(cr: QPalette::Highlight));
208 }
209 break;
210 case PE_IndicatorBranch: {
211 static const int decoration_size = 9;
212 int mid_h = opt->rect.x() + opt->rect.width() / 2;
213 int mid_v = opt->rect.y() + opt->rect.height() / 2;
214 int bef_h = mid_h;
215 int bef_v = mid_v;
216 int aft_h = mid_h;
217 int aft_v = mid_v;
218 if (opt->state & State_Children) {
219 int delta = decoration_size / 2;
220 bef_h -= delta;
221 bef_v -= delta;
222 aft_h += delta;
223 aft_v += delta;
224 p->drawLine(x1: bef_h + 2, y1: bef_v + 4, x2: bef_h + 6, y2: bef_v + 4);
225 if (!(opt->state & State_Open))
226 p->drawLine(x1: bef_h + 4, y1: bef_v + 2, x2: bef_h + 4, y2: bef_v + 6);
227 QPen oldPen = p->pen();
228 p->setPen(opt->palette.dark().color());
229 p->drawRect(x: bef_h, y: bef_v, w: decoration_size - 1, h: decoration_size - 1);
230 p->setPen(oldPen);
231 }
232 QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern);
233 if (opt->state & State_Item) {
234 if (opt->direction == Qt::RightToLeft)
235 p->fillRect(x: opt->rect.left(), y: mid_v, w: bef_h - opt->rect.left(), h: 1, b: brush);
236 else
237 p->fillRect(x: aft_h, y: mid_v, w: opt->rect.right() - aft_h + 1, h: 1, b: brush);
238 }
239 if (opt->state & State_Sibling)
240 p->fillRect(x: mid_h, y: aft_v, w: 1, h: opt->rect.bottom() - aft_v + 1, b: brush);
241 if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
242 p->fillRect(x: mid_h, y: opt->rect.y(), w: 1, h: bef_v - opt->rect.y(), b: brush);
243 break; }
244 case PE_FrameStatusBarItem:
245 qDrawShadeRect(p, r: opt->rect, pal: opt->palette, sunken: true, lineWidth: 1, midLineWidth: 0, fill: nullptr);
246 break;
247 case PE_IndicatorHeaderArrow:
248 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
249 QPen oldPen = p->pen();
250 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
251 p->setPen(QPen(opt->palette.light(), 0));
252 p->drawLine(x1: opt->rect.x() + opt->rect.width(), y1: opt->rect.y(),
253 x2: opt->rect.x() + opt->rect.width() / 2, y2: opt->rect.y() + opt->rect.height());
254 p->setPen(QPen(opt->palette.dark(), 0));
255 const QPoint points[] = {
256 QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height()),
257 QPoint(opt->rect.x(), opt->rect.y()),
258 QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y()),
259 };
260 p->drawPolyline(points, pointCount: sizeof points / sizeof *points);
261 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
262 p->setPen(QPen(opt->palette.light(), 0));
263 const QPoint points[] = {
264 QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height()),
265 QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y() + opt->rect.height()),
266 QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y()),
267 };
268 p->drawPolyline(points, pointCount: sizeof points / sizeof *points);
269 p->setPen(QPen(opt->palette.dark(), 0));
270 p->drawLine(x1: opt->rect.x(), y1: opt->rect.y() + opt->rect.height(),
271 x2: opt->rect.x() + opt->rect.width() / 2, y2: opt->rect.y());
272 }
273 p->setPen(oldPen);
274 }
275 break;
276 case PE_FrameTabBarBase:
277 if (const QStyleOptionTabBarBase *tbb
278 = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
279 p->save();
280 switch (tbb->shape) {
281 case QStyleOptionTab::RoundedNorth:
282 case QStyleOptionTab::TriangularNorth:
283 p->setPen(QPen(tbb->palette.light(), 0));
284 p->drawLine(p1: tbb->rect.topLeft(), p2: tbb->rect.topRight());
285 break;
286 case QStyleOptionTab::RoundedWest:
287 case QStyleOptionTab::TriangularWest:
288 p->setPen(QPen(tbb->palette.light(), 0));
289 p->drawLine(p1: tbb->rect.topLeft(), p2: tbb->rect.bottomLeft());
290 break;
291 case QStyleOptionTab::RoundedSouth:
292 case QStyleOptionTab::TriangularSouth:
293 p->setPen(QPen(tbb->palette.shadow(), 0));
294 p->drawLine(x1: tbb->rect.left(), y1: tbb->rect.bottom(),
295 x2: tbb->rect.right(), y2: tbb->rect.bottom());
296 p->setPen(QPen(tbb->palette.dark(), 0));
297 p->drawLine(x1: tbb->rect.left(), y1: tbb->rect.bottom() - 1,
298 x2: tbb->rect.right() - 1, y2: tbb->rect.bottom() - 1);
299 break;
300 case QStyleOptionTab::RoundedEast:
301 case QStyleOptionTab::TriangularEast:
302 p->setPen(QPen(tbb->palette.dark(), 0));
303 p->drawLine(p1: tbb->rect.topRight(), p2: tbb->rect.bottomRight());
304 break;
305 }
306 p->restore();
307 }
308 break;
309 case PE_IndicatorTabClose: {
310 if (d->tabBarcloseButtonIcon.isNull()) {
311 d->tabBarcloseButtonIcon.addPixmap(pixmap: QPixmap(
312 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-16.png")),
313 mode: QIcon::Normal, state: QIcon::Off);
314 d->tabBarcloseButtonIcon.addPixmap(pixmap: QPixmap(
315 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-down-16.png")),
316 mode: QIcon::Normal, state: QIcon::On);
317 d->tabBarcloseButtonIcon.addPixmap(pixmap: QPixmap(
318 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-hover-16.png")),
319 mode: QIcon::Active, state: QIcon::Off);
320 }
321
322 int size = proxy()->pixelMetric(metric: QStyle::PM_SmallIconSize);
323 QIcon::Mode mode = opt->state & State_Enabled ?
324 (opt->state & State_Raised ? QIcon::Active : QIcon::Normal)
325 : QIcon::Disabled;
326 if (!(opt->state & State_Raised)
327 && !(opt->state & State_Sunken)
328 && !(opt->state & QStyle::State_Selected))
329 mode = QIcon::Disabled;
330
331 QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off;
332 QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(size: QSize(size, size), devicePixelRatio: dpr(w: opt->window), mode, state);
333 proxy()->drawItemPixmap(painter: p, rect: opt->rect, alignment: Qt::AlignCenter, pixmap);
334 break;
335 }
336 case PE_FrameTabWidget:
337 case PE_FrameWindow:
338 qDrawWinPanel(p, r: opt->rect, pal: opt->palette, sunken: false, fill: nullptr);
339 break;
340 case PE_FrameLineEdit:
341 proxy()->drawPrimitive(pe: PE_Frame, opt, p);
342 break;
343 case PE_FrameGroupBox:
344 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
345 if (frame->features & QStyleOptionFrame::Flat) {
346 QRect fr = frame->rect;
347 QPoint p1(fr.x(), fr.y() + 1);
348 QPoint p2(fr.x() + fr.width(), p1.y());
349 qDrawShadeLine(p, p1, p2, pal: frame->palette, sunken: true,
350 lineWidth: frame->lineWidth, midLineWidth: frame->midLineWidth);
351 } else {
352 qDrawShadeRect(p, x: frame->rect.x(), y: frame->rect.y(), w: frame->rect.width(),
353 h: frame->rect.height(), pal: frame->palette, sunken: true,
354 lineWidth: frame->lineWidth, midLineWidth: frame->midLineWidth);
355 }
356 }
357 break;
358 case PE_FrameDockWidget:
359 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
360 int lw = frame->lineWidth;
361 if (lw <= 0)
362 lw = proxy()->pixelMetric(metric: PM_DockWidgetFrameWidth);
363
364 qDrawShadePanel(p, r: frame->rect, pal: frame->palette, sunken: false, lineWidth: lw);
365 }
366 break;
367 case PE_IndicatorToolBarHandle:
368 p->save();
369 p->translate(dx: opt->rect.x(), dy: opt->rect.y());
370 if (opt->state & State_Horizontal) {
371 int x = opt->rect.width() / 3;
372 if (opt->direction == Qt::RightToLeft)
373 x -= 2;
374 if (opt->rect.height() > 4) {
375 qDrawShadePanel(p, x, y: 2, w: 3, h: opt->rect.height() - 4,
376 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
377 qDrawShadePanel(p, x: x+3, y: 2, w: 3, h: opt->rect.height() - 4,
378 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
379 }
380 } else {
381 if (opt->rect.width() > 4) {
382 int y = opt->rect.height() / 3;
383 qDrawShadePanel(p, x: 2, y, w: opt->rect.width() - 4, h: 3,
384 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
385 qDrawShadePanel(p, x: 2, y: y+3, w: opt->rect.width() - 4, h: 3,
386 pal: opt->palette, sunken: false, lineWidth: 1, fill: nullptr);
387 }
388 }
389 p->restore();
390 break;
391 case PE_IndicatorToolBarSeparator:
392 {
393 QPoint p1, p2;
394 if (opt->state & State_Horizontal) {
395 p1 = QPoint(opt->rect.width()/2, 0);
396 p2 = QPoint(p1.x(), opt->rect.height());
397 } else {
398 p1 = QPoint(0, opt->rect.height()/2);
399 p2 = QPoint(opt->rect.width(), p1.y());
400 }
401 qDrawShadeLine(p, p1, p2, pal: opt->palette, sunken: 1, lineWidth: 1, midLineWidth: 0);
402 break;
403 }
404 case PE_IndicatorSpinPlus:
405 case PE_IndicatorSpinMinus: {
406 QRect r = opt->rect;
407 int fw = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: opt);
408 QRect br = r.adjusted(xp1: fw, yp1: fw, xp2: -fw, yp2: -fw);
409
410 int offset = (opt->state & State_Sunken) ? 1 : 0;
411 int step = (br.width() + 4) / 5;
412 p->fillRect(x: br.x() + offset, y: br.y() + offset +br.height() / 2 - step / 2,
413 w: br.width(), h: step,
414 b: opt->palette.buttonText());
415 if (pe == PE_IndicatorSpinPlus)
416 p->fillRect(x: br.x() + br.width() / 2 - step / 2 + offset, y: br.y() + offset,
417 w: step, h: br.height(),
418 b: opt->palette.buttonText());
419
420 break; }
421 case PE_IndicatorSpinUp:
422 case PE_IndicatorSpinDown: {
423 QRect r = opt->rect;
424 int fw = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: opt);
425 // QRect br = r.adjusted(fw, fw, -fw, -fw);
426 int x = r.x(), y = r.y(), w = r.width(), h = r.height();
427 int sw = w-4;
428 if (sw < 3)
429 break;
430 else if (!(sw & 1))
431 sw--;
432 sw -= (sw / 7) * 2; // Empty border
433 int sh = sw/2 + 2; // Must have empty row at foot of arrow
434
435 int sx = x + w / 2 - sw / 2;
436 int sy = y + h / 2 - sh / 2;
437
438 if (pe == PE_IndicatorSpinUp && fw)
439 --sy;
440
441 int bsx = 0;
442 int bsy = 0;
443 if (opt->state & State_Sunken) {
444 bsx = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal);
445 bsy = proxy()->pixelMetric(metric: PM_ButtonShiftVertical);
446 }
447 p->save();
448 p->translate(dx: sx + bsx, dy: sy + bsy);
449 p->setPen(opt->palette.buttonText().color());
450 p->setBrush(opt->palette.buttonText());
451 if (pe == PE_IndicatorSpinDown) {
452 const QPoint points[] = { QPoint(0, 1), QPoint(sw-1, 1), QPoint(sh-2, sh-1) };
453 p->drawPolygon(points, pointCount: sizeof points / sizeof *points);
454 } else {
455 const QPoint points[] = { QPoint(0, sh-1), QPoint(sw-1, sh-1), QPoint(sh-2, 1) };
456 p->drawPolygon(points, pointCount: sizeof points / sizeof *points);
457 }
458 p->restore();
459 break; }
460 case PE_PanelTipLabel: {
461 const QBrush brush(opt->palette.toolTipBase());
462 qDrawPlainRect(p, r: opt->rect, opt->palette.toolTipText().color(), lineWidth: 1, fill: &brush);
463 break;
464 }
465 case PE_IndicatorTabTear:
466 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
467 bool rtl = tab->direction == Qt::RightToLeft;
468 const bool horizontal = tab->rect.height() > tab->rect.width();
469 const int margin = 4;
470 QPainterPath path;
471
472 if (horizontal) {
473 QRect rect = tab->rect.adjusted(xp1: rtl ? margin : 0, yp1: 0, xp2: rtl ? 1 : -margin, yp2: 0);
474 rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
475 rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
476
477 path.moveTo(p: QPoint(rtl ? rect.right() : rect.left(), rect.top()));
478 int count = 4;
479 for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
480 path.lineTo(p: QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
481 } else {
482 QRect rect = tab->rect.adjusted(xp1: 0, yp1: 0, xp2: 0, yp2: -margin);
483 rect.setLeft(rect.left() + ((tab->state & State_Selected) ? 1 : 3));
484 rect.setRight(rect.right() - ((tab->state & State_Selected) ? 0 : 2));
485
486 path.moveTo(p: QPoint(rect.left(), rect.top()));
487 int count = 4;
488 for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
489 path.lineTo(p: QPoint(rect.left() + jags * rect.width()/count, rtl ? rect.top() : rect.bottom()));
490 }
491
492 p->setPen(QPen(tab->palette.dark(), qreal(.8)));
493 p->setBrush(tab->palette.window());
494 p->setRenderHint(hint: QPainter::Antialiasing);
495 p->drawPath(path);
496 }
497 break;
498 case PE_PanelLineEdit:
499 if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
500 p->fillRect(panel->rect.adjusted(xp1: panel->lineWidth, yp1: panel->lineWidth, xp2: -panel->lineWidth, yp2: -panel->lineWidth),
501 panel->palette.brush(cr: QPalette::Base));
502
503 if (panel->lineWidth > 0)
504 proxy()->drawPrimitive(pe: PE_FrameLineEdit, opt: panel, p);
505 }
506 break;
507#if QT_CONFIG(quick_itemview)
508 case PE_IndicatorColumnViewArrow: {
509 if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
510 bool reverse = (viewOpt->direction == Qt::RightToLeft);
511 p->save();
512 QPainterPath path;
513 int x = viewOpt->rect.x() + 1;
514 int offset = (viewOpt->rect.height() / 3);
515 int height = (viewOpt->rect.height()) - offset * 2;
516 if (height % 2 == 1)
517 --height;
518 int x2 = x + height - 1;
519 if (reverse) {
520 x = viewOpt->rect.x() + viewOpt->rect.width() - 1;
521 x2 = x - height + 1;
522 }
523 path.moveTo(x, y: viewOpt->rect.y() + offset);
524 path.lineTo(x, y: viewOpt->rect.y() + offset + height);
525 path.lineTo(x: x2, y: viewOpt->rect.y() + offset+height/2);
526 path.closeSubpath();
527 if (viewOpt->state & QStyle::State_Selected ) {
528 if (viewOpt->showDecorationSelected) {
529 QColor color = viewOpt->palette.color(cg: QPalette::Active, cr: QPalette::HighlightedText);
530 p->setPen(color);
531 p->setBrush(color);
532 } else {
533 QColor color = viewOpt->palette.color(cg: QPalette::Active, cr: QPalette::WindowText);
534 p->setPen(color);
535 p->setBrush(color);
536 }
537
538 } else {
539 QColor color = viewOpt->palette.color(cg: QPalette::Active, cr: QPalette::Mid);
540 p->setPen(color);
541 p->setBrush(color);
542 }
543 p->drawPath(path);
544
545 // draw the vertical and top triangle line
546 if (!(viewOpt->state & QStyle::State_Selected)) {
547 QPainterPath lines;
548 lines.moveTo(x, y: viewOpt->rect.y() + offset);
549 lines.lineTo(x, y: viewOpt->rect.y() + offset + height);
550 lines.moveTo(x, y: viewOpt->rect.y() + offset);
551 lines.lineTo(x: x2, y: viewOpt->rect.y() + offset+height/2);
552 QColor color = viewOpt->palette.color(cg: QPalette::Active, cr: QPalette::Dark);
553 p->setPen(color);
554 p->drawPath(path: lines);
555 }
556 p->restore();
557 }
558 break; }
559 case PE_IndicatorItemViewItemDrop: {
560 QRect rect = opt->rect;
561 if (opt->rect.height() == 0)
562 p->drawLine(p1: rect.topLeft(), p2: rect.topRight());
563 else
564 p->drawRect(r: rect);
565 break; }
566 case PE_PanelItemViewRow:
567 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
568 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
569 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
570 cg = QPalette::Inactive;
571
572 if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(stylehint: QStyle::SH_ItemView_ShowDecorationSelected, opt))
573 p->fillRect(vopt->rect, vopt->palette.brush(cg, cr: QPalette::Highlight));
574 else if (vopt->features & QStyleOptionViewItem::Alternate)
575 p->fillRect(vopt->rect, vopt->palette.brush(cg, cr: QPalette::AlternateBase));
576 }
577 break;
578 case PE_PanelItemViewItem:
579 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
580 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
581 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
582 cg = QPalette::Inactive;
583
584 if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) {
585 p->fillRect(vopt->rect, vopt->palette.brush(cg, cr: QPalette::Highlight));
586 } else {
587 if (vopt->backgroundBrush.style() != Qt::NoBrush) {
588 QPointF oldBO = p->brushOrigin();
589 p->setBrushOrigin(vopt->rect.topLeft());
590 p->fillRect(vopt->rect, vopt->backgroundBrush);
591 p->setBrushOrigin(oldBO);
592 }
593
594 if (vopt->state & QStyle::State_Selected) {
595 QRect textRect = subElementRect(r: QStyle::SE_ItemViewItemText, opt);
596 p->fillRect(textRect, vopt->palette.brush(cg, cr: QPalette::Highlight));
597 }
598 }
599 }
600 break;
601#endif // QT_CONFIG(quick_itemview)
602 case PE_PanelScrollAreaCorner: {
603 const QBrush brush(opt->palette.brush(cr: QPalette::Window));
604 p->fillRect(opt->rect, brush);
605 } break;
606 case PE_IndicatorArrowUp:
607 case PE_IndicatorArrowDown:
608 case PE_IndicatorArrowRight:
609 case PE_IndicatorArrowLeft:
610 {
611 if (opt->rect.width() <= 1 || opt->rect.height() <= 1)
612 break;
613 QRect r = opt->rect;
614 int size = qMin(a: r.height(), b: r.width());
615 QPixmap pixmap;
616 QString pixmapName = QStyleHelper::uniqueName(key: QLatin1String("$qt_ia-")
617 % QLatin1String(metaObject()->className()), option: opt, size: QSize(size, size))
618 % HexString<uint>(pe);
619 if (!QPixmapCache::find(key: pixmapName, pixmap: &pixmap)) {
620 qreal pixelRatio = p->device()->devicePixelRatioF();
621 int border = qRound(d: pixelRatio*(size/5));
622 int sqsize = qRound(d: pixelRatio*(2*(size/2)));
623 QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
624 image.fill(pixel: 0);
625 QPainter imagePainter(&image);
626
627 QPolygon a;
628 switch (pe) {
629 case PE_IndicatorArrowUp:
630 a.setPoints(nPoints: 3, firstx: border, firsty: sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
631 break;
632 case PE_IndicatorArrowDown:
633 a.setPoints(nPoints: 3, firstx: border, firsty: sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
634 break;
635 case PE_IndicatorArrowRight:
636 a.setPoints(nPoints: 3, firstx: sqsize - border, firsty: sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
637 break;
638 case PE_IndicatorArrowLeft:
639 a.setPoints(nPoints: 3, firstx: border, firsty: sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
640 break;
641 default:
642 break;
643 }
644
645 int bsx = 0;
646 int bsy = 0;
647
648 if (opt->state & State_Sunken) {
649 bsx = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: opt);
650 bsy = proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: opt);
651 }
652
653 QRect bounds = a.boundingRect();
654 int sx = sqsize / 2 - bounds.center().x() - 1;
655 int sy = sqsize / 2 - bounds.center().y() - 1;
656 imagePainter.translate(dx: sx + bsx, dy: sy + bsy);
657 imagePainter.setPen(opt->palette.buttonText().color());
658 imagePainter.setBrush(opt->palette.buttonText());
659
660 if (!(opt->state & State_Enabled)) {
661 imagePainter.translate(dx: 1, dy: 1);
662 imagePainter.setBrush(opt->palette.light().color());
663 imagePainter.setPen(opt->palette.light().color());
664 imagePainter.drawPolygon(polygon: a);
665 imagePainter.translate(dx: -1, dy: -1);
666 imagePainter.setBrush(opt->palette.mid().color());
667 imagePainter.setPen(opt->palette.mid().color());
668 }
669
670 imagePainter.drawPolygon(polygon: a);
671 imagePainter.end();
672 pixmap = QPixmap::fromImage(image: std::move(image));
673 pixmap.setDevicePixelRatio(pixelRatio);
674 QPixmapCache::insert(key: pixmapName, pixmap);
675 }
676 int xOffset = r.x() + (r.width() - size)/2;
677 int yOffset = r.y() + (r.height() - size)/2;
678 p->drawPixmap(x: xOffset, y: yOffset, pm: pixmap);
679 }
680 break;
681 default:
682 break;
683 }
684}
685
686static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
687 const QRect &rect, QPainter *painter)
688{
689 QStyle::PrimitiveElement pe;
690 switch (toolbutton->arrowType) {
691 case Qt::LeftArrow:
692 pe = QStyle::PE_IndicatorArrowLeft;
693 break;
694 case Qt::RightArrow:
695 pe = QStyle::PE_IndicatorArrowRight;
696 break;
697 case Qt::UpArrow:
698 pe = QStyle::PE_IndicatorArrowUp;
699 break;
700 case Qt::DownArrow:
701 pe = QStyle::PE_IndicatorArrowDown;
702 break;
703 default:
704 return;
705 }
706 QStyleOption arrowOpt = *toolbutton;
707 arrowOpt.rect = rect;
708 style->drawPrimitive(pe, opt: &arrowOpt, p: painter);
709}
710
711static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth, int maxHeight = -1, int *lastVisibleLine = nullptr)
712{
713 if (lastVisibleLine)
714 *lastVisibleLine = -1;
715 qreal height = 0;
716 qreal widthUsed = 0;
717 textLayout.beginLayout();
718 int i = 0;
719 while (true) {
720 QTextLine line = textLayout.createLine();
721 if (!line.isValid())
722 break;
723 line.setLineWidth(lineWidth);
724 line.setPosition(QPointF(0, height));
725 height += line.height();
726 widthUsed = qMax(a: widthUsed, b: line.naturalTextWidth());
727 // we assume that the height of the next line is the same as the current one
728 if (maxHeight > 0 && lastVisibleLine && height + line.height() > maxHeight) {
729 const QTextLine nextLine = textLayout.createLine();
730 *lastVisibleLine = nextLine.isValid() ? i : -1;
731 break;
732 }
733 ++i;
734 }
735 textLayout.endLayout();
736 return QSizeF(widthUsed, height);
737}
738
739QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTextOption &textOption,
740 const QFont &font, const QRect &textRect, const Qt::Alignment valign,
741 Qt::TextElideMode textElideMode, int flags,
742 bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const
743{
744 QTextLayout textLayout(text, font);
745 textLayout.setTextOption(textOption);
746
747 // In AlignVCenter mode when more than one line is displayed and the height only allows
748 // some of the lines it makes no sense to display those. From a users perspective it makes
749 // more sense to see the start of the text instead something inbetween.
750 const bool vAlignmentOptimization = paintStartPosition && valign.testFlag(flag: Qt::AlignVCenter);
751
752 int lastVisibleLine = -1;
753 viewItemTextLayout(textLayout, lineWidth: textRect.width(), maxHeight: vAlignmentOptimization ? textRect.height() : -1, lastVisibleLine: &lastVisibleLine);
754
755 const QRectF boundingRect = textLayout.boundingRect();
756 // don't care about LTR/RTL here, only need the height
757 const QRect layoutRect = QStyle::alignedRect(direction: Qt::LayoutDirectionAuto, alignment: valign,
758 size: boundingRect.size().toSize(), rectangle: textRect);
759
760 if (paintStartPosition)
761 *paintStartPosition = QPointF(textRect.x(), layoutRect.top());
762
763 QString ret;
764 qreal height = 0;
765 const int lineCount = textLayout.lineCount();
766 for (int i = 0; i < lineCount; ++i) {
767 const QTextLine line = textLayout.lineAt(i);
768 height += line.height();
769
770 // above visible rect
771 if (height + layoutRect.top() <= textRect.top()) {
772 if (paintStartPosition)
773 paintStartPosition->ry() += line.height();
774 continue;
775 }
776
777 const int start = line.textStart();
778 const int length = line.textLength();
779 const bool drawElided = line.naturalTextWidth() > textRect.width();
780 bool elideLastVisibleLine = lastVisibleLine == i;
781 if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) {
782 const QTextLine nextLine = textLayout.lineAt(i: i + 1);
783 const int nextHeight = height + nextLine.height() / 2;
784 // elide when less than the next half line is visible
785 if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
786 elideLastVisibleLine = true;
787 }
788
789 QString text = textLayout.text().mid(position: start, n: length);
790 if (drawElided || elideLastVisibleLine) {
791 if (elideLastVisibleLine) {
792 if (text.endsWith(c: QChar::LineSeparator))
793 text.chop(n: 1);
794 text += QChar(0x2026);
795 }
796 const QStackTextEngine engine(text, font);
797 ret += engine.elidedText(mode: textElideMode, width: textRect.width(), flags);
798
799 // no newline for the last line (last visible or real)
800 // sometimes drawElided is true but no eliding is done so the text ends
801 // with QChar::LineSeparator - don't add another one. This happened with
802 // arabic text in the testcase for QTBUG-72805
803 if (i < lineCount - 1 &&
804 !ret.endsWith(c: QChar::LineSeparator))
805 ret += QChar::LineSeparator;
806 } else {
807 ret += text;
808 }
809
810 // below visible text, can stop
811 if ((height + layoutRect.top() >= textRect.bottom()) ||
812 (lastVisibleLine >= 0 && lastVisibleLine == i))
813 break;
814 }
815 return ret;
816}
817
818#if QT_CONFIG(quick_itemview)
819QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const
820{
821 switch (role) {
822 case Qt::CheckStateRole:
823 if (option->features & QStyleOptionViewItem::HasCheckIndicator)
824 return QSize(proxyStyle->pixelMetric(metric: QStyle::PM_IndicatorWidth, option),
825 proxyStyle->pixelMetric(metric: QStyle::PM_IndicatorHeight, option));
826 break;
827 case Qt::DisplayRole:
828 if (option->features & QStyleOptionViewItem::HasDisplay) {
829 QTextOption textOption;
830 textOption.setWrapMode(QTextOption::WordWrap);
831 QTextLayout textLayout(option->text, option->font);
832 textLayout.setTextOption(textOption);
833 const bool wrapText = option->features & QStyleOptionViewItem::WrapText;
834 const int textMargin = proxyStyle->pixelMetric(metric: QStyle::PM_FocusFrameHMargin, option) + 1;
835 QRect bounds = option->rect;
836 switch (option->decorationPosition) {
837 case QStyleOptionViewItem::Left:
838 case QStyleOptionViewItem::Right: {
839 if (wrapText && bounds.isValid()) {
840 int width = bounds.width() - 2 * textMargin;
841 if (option->features & QStyleOptionViewItem::HasDecoration)
842 width -= option->decorationSize.width() + 2 * textMargin;
843 bounds.setWidth(width);
844 } else
845 bounds.setWidth(QFIXED_MAX);
846 break;
847 }
848 case QStyleOptionViewItem::Top:
849 case QStyleOptionViewItem::Bottom:
850 if (wrapText)
851 bounds.setWidth(bounds.isValid() ? bounds.width() - 2 * textMargin : option->decorationSize.width());
852 else
853 bounds.setWidth(QFIXED_MAX);
854 break;
855 default:
856 break;
857 }
858
859 if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator)
860 bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(metric: QStyle::PM_IndicatorWidth) - 2 * textMargin);
861
862 const int lineWidth = bounds.width();
863 const QSizeF size = viewItemTextLayout(textLayout, lineWidth);
864 return QSize(qCeil(v: size.width()) + 2 * textMargin, qCeil(v: size.height()));
865 }
866 break;
867 case Qt::DecorationRole:
868 if (option->features & QStyleOptionViewItem::HasDecoration) {
869 return option->decorationSize;
870 }
871 break;
872 default:
873 break;
874 }
875
876 return QSize(0, 0);
877}
878
879void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const
880{
881 const int textMargin = proxyStyle->pixelMetric(metric: QStyle::PM_FocusFrameHMargin, option: nullptr) + 1;
882
883 QRect textRect = rect.adjusted(xp1: textMargin, yp1: 0, xp2: -textMargin, yp2: 0); // remove width padding
884 const bool wrapText = option->features & QStyleOptionViewItem::WrapText;
885 QTextOption textOption;
886 textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
887 textOption.setTextDirection(option->direction);
888 textOption.setAlignment(QStyle::visualAlignment(direction: option->direction, alignment: option->displayAlignment));
889
890 QPointF paintPosition;
891 const QString newText = calculateElidedText(text: option->text, textOption,
892 font: option->font, textRect, valign: option->displayAlignment,
893 textElideMode: option->textElideMode, flags: 0,
894 lastVisibleLineShouldBeElided: true, paintStartPosition: &paintPosition);
895
896 QTextLayout textLayout(newText, option->font);
897 textLayout.setTextOption(textOption);
898 viewItemTextLayout(textLayout, lineWidth: textRect.width());
899 textLayout.draw(p, pos: paintPosition);
900}
901
902/*! \internal
903 compute the position for the different component of an item (pixmap, text, checkbox)
904
905 Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore
906 opt->rect and return rectangles in infinite space
907
908 Code duplicated in QItemDelegate::doLayout
909*/
910void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect,
911 QRect *pixmapRect, QRect *textRect, bool sizehint) const
912{
913 Q_ASSERT(checkRect && pixmapRect && textRect);
914 *pixmapRect = QRect(QPoint(0, 0), viewItemSize(option: opt, role: Qt::DecorationRole));
915 *textRect = QRect(QPoint(0, 0), viewItemSize(option: opt, role: Qt::DisplayRole));
916 *checkRect = QRect(QPoint(0, 0), viewItemSize(option: opt, role: Qt::CheckStateRole));
917
918 const bool hasCheck = checkRect->isValid();
919 const bool hasPixmap = pixmapRect->isValid();
920 const bool hasText = textRect->isValid();
921 const bool hasMargin = (hasText | hasPixmap | hasCheck);
922 const int frameHMargin = hasMargin ?
923 proxyStyle->pixelMetric(metric: QStyle::PM_FocusFrameHMargin, option: opt) + 1 : 0;
924 const int textMargin = hasText ? frameHMargin : 0;
925 const int pixmapMargin = hasPixmap ? frameHMargin : 0;
926 const int checkMargin = hasCheck ? frameHMargin : 0;
927 const int x = opt->rect.left();
928 const int y = opt->rect.top();
929 int w, h;
930
931 if (textRect->height() == 0 && (!hasPixmap || !sizehint)) {
932 //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
933 textRect->setHeight(opt->fontMetrics.height());
934 }
935
936 QSize pm(0, 0);
937 if (hasPixmap) {
938 pm = pixmapRect->size();
939 pm.rwidth() += 2 * pixmapMargin;
940 }
941 if (sizehint) {
942 h = qMax(a: checkRect->height(), b: qMax(a: textRect->height(), b: pm.height()));
943 if (opt->decorationPosition == QStyleOptionViewItem::Left
944 || opt->decorationPosition == QStyleOptionViewItem::Right) {
945 w = textRect->width() + pm.width();
946 } else {
947 w = qMax(a: textRect->width(), b: pm.width());
948 }
949 } else {
950 w = opt->rect.width();
951 h = opt->rect.height();
952 }
953
954 int cw = 0;
955 QRect check;
956 if (hasCheck) {
957 cw = checkRect->width() + 2 * checkMargin;
958 if (sizehint) w += cw;
959 if (opt->direction == Qt::RightToLeft) {
960 check.setRect(ax: x + w - cw, ay: y, aw: cw, ah: h);
961 } else {
962 check.setRect(ax: x, ay: y, aw: cw, ah: h);
963 }
964 }
965
966 QRect display;
967 QRect decoration;
968 switch (opt->decorationPosition) {
969 case QStyleOptionViewItem::Top: {
970 if (hasPixmap)
971 pm.setHeight(pm.height() + pixmapMargin); // add space
972 h = sizehint ? textRect->height() : h - pm.height();
973
974 if (opt->direction == Qt::RightToLeft) {
975 decoration.setRect(ax: x, ay: y, aw: w - cw, ah: pm.height());
976 display.setRect(ax: x, ay: y + pm.height(), aw: w - cw, ah: h);
977 } else {
978 decoration.setRect(ax: x + cw, ay: y, aw: w - cw, ah: pm.height());
979 display.setRect(ax: x + cw, ay: y + pm.height(), aw: w - cw, ah: h);
980 }
981 break; }
982 case QStyleOptionViewItem::Bottom: {
983 if (hasText)
984 textRect->setHeight(textRect->height() + textMargin); // add space
985 h = sizehint ? textRect->height() + pm.height() : h;
986
987 if (opt->direction == Qt::RightToLeft) {
988 display.setRect(ax: x, ay: y, aw: w - cw, ah: textRect->height());
989 decoration.setRect(ax: x, ay: y + textRect->height(), aw: w - cw, ah: h - textRect->height());
990 } else {
991 display.setRect(ax: x + cw, ay: y, aw: w - cw, ah: textRect->height());
992 decoration.setRect(ax: x + cw, ay: y + textRect->height(), aw: w - cw, ah: h - textRect->height());
993 }
994 break; }
995 case QStyleOptionViewItem::Left: {
996 if (opt->direction == Qt::LeftToRight) {
997 decoration.setRect(ax: x + cw, ay: y, aw: pm.width(), ah: h);
998 display.setRect(ax: decoration.right() + 1, ay: y, aw: w - pm.width() - cw, ah: h);
999 } else {
1000 display.setRect(ax: x, ay: y, aw: w - pm.width() - cw, ah: h);
1001 decoration.setRect(ax: display.right() + 1, ay: y, aw: pm.width(), ah: h);
1002 }
1003 break; }
1004 case QStyleOptionViewItem::Right: {
1005 if (opt->direction == Qt::LeftToRight) {
1006 display.setRect(ax: x + cw, ay: y, aw: w - pm.width() - cw, ah: h);
1007 decoration.setRect(ax: display.right() + 1, ay: y, aw: pm.width(), ah: h);
1008 } else {
1009 decoration.setRect(ax: x, ay: y, aw: pm.width(), ah: h);
1010 display.setRect(ax: decoration.right() + 1, ay: y, aw: w - pm.width() - cw, ah: h);
1011 }
1012 break; }
1013 default:
1014 qWarning(msg: "doLayout: decoration position is invalid");
1015 decoration = *pixmapRect;
1016 break;
1017 }
1018
1019 if (!sizehint) { // we only need to do the internal layout if we are going to paint
1020 *checkRect = QStyle::alignedRect(direction: opt->direction, alignment: Qt::AlignCenter,
1021 size: checkRect->size(), rectangle: check);
1022 *pixmapRect = QStyle::alignedRect(direction: opt->direction, alignment: opt->decorationAlignment,
1023 size: pixmapRect->size(), rectangle: decoration);
1024 // the text takes up all available space, unless the decoration is not shown as selected
1025 if (opt->showDecorationSelected)
1026 *textRect = display;
1027 else
1028 *textRect = QStyle::alignedRect(direction: opt->direction, alignment: opt->displayAlignment,
1029 size: textRect->size().boundedTo(otherSize: display.size()), rectangle: display);
1030 } else {
1031 *checkRect = check;
1032 *pixmapRect = decoration;
1033 *textRect = display;
1034 }
1035}
1036#endif // QT_CONFIG(quick_itemview)
1037
1038QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option,
1039 const QRect &textRect, int flags) const
1040{
1041 if (option->fontMetrics.horizontalAdvance(option->text) <= textRect.width())
1042 return option->text;
1043
1044 QString text = option->text;
1045 text.replace(before: QLatin1Char('\n'), after: QChar::LineSeparator);
1046 QTextOption textOption;
1047 textOption.setWrapMode(QTextOption::ManualWrap);
1048 textOption.setTextDirection(option->direction);
1049
1050 return calculateElidedText(text, textOption,
1051 font: option->font, textRect, valign: Qt::AlignTop,
1052 textElideMode: Qt::ElideMiddle, flags,
1053 lastVisibleLineShouldBeElided: false, paintStartPosition: nullptr);
1054}
1055
1056/*! \internal
1057 Compute the textRect and the pixmapRect from the opt rect
1058
1059 Uses the same computation than in QTabBar::tabSizeHint
1060 */
1061void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, QRect *textRect, QRect *iconRect) const
1062{
1063 Q_ASSERT(textRect);
1064 Q_ASSERT(iconRect);
1065 QRect tr = opt->rect;
1066 bool verticalTabs = opt->shape == QStyleOptionTab::RoundedEast
1067 || opt->shape == QStyleOptionTab::RoundedWest
1068 || opt->shape == QStyleOptionTab::TriangularEast
1069 || opt->shape == QStyleOptionTab::TriangularWest;
1070 if (verticalTabs)
1071 tr.setRect(ax: 0, ay: 0, aw: tr.height(), ah: tr.width()); // 0, 0 as we will have a translate transform
1072
1073 int verticalShift = proxyStyle->pixelMetric(metric: QStyle::PM_TabBarTabShiftVertical, option: opt);
1074 int horizontalShift = proxyStyle->pixelMetric(metric: QStyle::PM_TabBarTabShiftHorizontal, option: opt);
1075 int hpadding = proxyStyle->pixelMetric(metric: QStyle::PM_TabBarTabHSpace, option: opt) / 2;
1076 int vpadding = proxyStyle->pixelMetric(metric: QStyle::PM_TabBarTabVSpace, option: opt) / 2;
1077 if (opt->shape == QStyleOptionTab::RoundedSouth || opt->shape == QStyleOptionTab::TriangularSouth)
1078 verticalShift = -verticalShift;
1079 tr.adjust(dx1: hpadding, dy1: verticalShift - vpadding, dx2: horizontalShift - hpadding, dy2: vpadding);
1080 bool selected = opt->state & QStyle::State_Selected;
1081 if (selected) {
1082 tr.setTop(tr.top() - verticalShift);
1083 tr.setRight(tr.right() - horizontalShift);
1084 }
1085
1086 // left widget
1087 if (!opt->leftButtonSize.isEmpty()) {
1088 tr.setLeft(tr.left() + 4 +
1089 (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width()));
1090 }
1091 // right widget
1092 if (!opt->rightButtonSize.isEmpty()) {
1093 tr.setRight(tr.right() - 4 -
1094 (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width()));
1095 }
1096
1097 // icon
1098 if (!opt->icon.isNull()) {
1099 QSize iconSize = opt->iconSize;
1100 if (!iconSize.isValid()) {
1101 int iconExtent = proxyStyle->pixelMetric(metric: QStyle::PM_SmallIconSize);
1102 iconSize = QSize(iconExtent, iconExtent);
1103 }
1104 QSize tabIconSize = opt->icon.actualSize(size: iconSize,
1105 mode: (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
1106 state: (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off);
1107 // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
1108 tabIconSize = QSize(qMin(a: tabIconSize.width(), b: iconSize.width()), qMin(a: tabIconSize.height(), b: iconSize.height()));
1109
1110 const int offsetX = (iconSize.width() - tabIconSize.width()) / 2;
1111 *iconRect = QRect(tr.left() + offsetX, tr.center().y() - tabIconSize.height() / 2,
1112 tabIconSize.width(), tabIconSize.height());
1113 if (!verticalTabs)
1114 *iconRect = QStyle::visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: *iconRect);
1115 tr.setLeft(tr.left() + tabIconSize.width() + 4);
1116 }
1117
1118 if (!verticalTabs)
1119 tr = QStyle::visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: tr);
1120
1121 *textRect = tr;
1122}
1123
1124/*!
1125 \reimp
1126*/
1127void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const
1128{
1129 Q_D(const QCommonStyle);
1130
1131 // TODO: Set opt->window manually for now before calling any of the drawing functions. opt->window is
1132 // pulled of the widget is QStyle. But now that we have no widget, we need some other
1133 // solution.
1134 Q_ASSERT(opt->window);
1135
1136 switch (element) {
1137
1138 case CE_PushButton:
1139 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1140 proxy()->drawControl(element: CE_PushButtonBevel, opt: btn, p);
1141 QStyleOptionButton subopt = *btn;
1142 subopt.rect = subElementRect(r: SE_PushButtonContents, opt: btn);
1143 proxy()->drawControl(element: CE_PushButtonLabel, opt: &subopt, p);
1144 }
1145 break;
1146 case CE_PushButtonBevel:
1147 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1148 QRect br = btn->rect;
1149 int dbi = proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn);
1150 if (btn->features & QStyleOptionButton::DefaultButton)
1151 proxy()->drawPrimitive(pe: PE_FrameDefaultButton, opt, p);
1152 if (btn->features & QStyleOptionButton::AutoDefaultButton)
1153 br.setCoords(xp1: br.left() + dbi, yp1: br.top() + dbi, xp2: br.right() - dbi, yp2: br.bottom() - dbi);
1154 if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton))
1155 || btn->state & (State_Sunken | State_On)
1156 || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) {
1157 QStyleOptionButton tmpBtn = *btn;
1158 tmpBtn.rect = br;
1159 proxy()->drawPrimitive(pe: PE_PanelButtonCommand, opt: &tmpBtn, p);
1160 }
1161 if (btn->features & QStyleOptionButton::HasMenu) {
1162 int mbi = proxy()->pixelMetric(metric: PM_MenuButtonIndicator, option: btn);
1163 QRect ir = btn->rect;
1164 QStyleOptionButton newBtn = *btn;
1165 newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6);
1166 proxy()->drawPrimitive(pe: PE_IndicatorArrowDown, opt: &newBtn, p);
1167 }
1168 if (btn->state & State_HasFocus) {
1169 QStyleOptionFocusRect fropt;
1170 fropt.QStyleOption::operator=(other: *btn);
1171 fropt.rect = subElementRect(r: SE_PushButtonFocusRect, opt: btn);
1172 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p);
1173 }
1174 }
1175 break;
1176 case CE_PushButtonLabel:
1177 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1178 QRect textRect = button->rect;
1179 uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
1180 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: button))
1181 tf |= Qt::TextHideMnemonic;
1182
1183 if (!button->icon.isNull()) {
1184 //Center both icon and text
1185 QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
1186 if (mode == QIcon::Normal && button->state & State_HasFocus)
1187 mode = QIcon::Active;
1188 QIcon::State state = QIcon::Off;
1189 if (button->state & State_On)
1190 state = QIcon::On;
1191
1192 QPixmap pixmap = button->icon.pixmap(size: button->iconSize, devicePixelRatio: dpr(w: opt->window), mode, state);
1193 int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
1194 int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
1195 int labelWidth = pixmapWidth;
1196 int labelHeight = pixmapHeight;
1197 int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
1198 if (!button->text.isEmpty()) {
1199 int textWidth = button->fontMetrics.boundingRect(r: opt->rect, flags: tf, text: button->text).width();
1200 labelWidth += (textWidth + iconSpacing);
1201 }
1202
1203 QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
1204 textRect.y() + (textRect.height() - labelHeight) / 2,
1205 pixmapWidth, pixmapHeight);
1206
1207 iconRect = visualRect(direction: button->direction, boundingRect: textRect, logicalRect: iconRect);
1208
1209 if (button->direction == Qt::RightToLeft) {
1210 tf |= Qt::AlignRight;
1211 textRect.setRight(iconRect.left() - iconSpacing);
1212 } else {
1213 tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
1214 textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
1215 }
1216
1217 if (button->state & (State_On | State_Sunken))
1218 iconRect.translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: opt),
1219 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: opt));
1220 p->drawPixmap(r: iconRect, pm: pixmap);
1221 } else {
1222 tf |= Qt::AlignHCenter;
1223 }
1224 if (button->state & (State_On | State_Sunken))
1225 textRect.translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: opt),
1226 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: opt));
1227
1228 if (button->features & QStyleOptionButton::HasMenu) {
1229 int indicatorSize = proxy()->pixelMetric(metric: PM_MenuButtonIndicator, option: button);
1230 if (button->direction == Qt::LeftToRight)
1231 textRect = textRect.adjusted(xp1: 0, yp1: 0, xp2: -indicatorSize, yp2: 0);
1232 else
1233 textRect = textRect.adjusted(xp1: indicatorSize, yp1: 0, xp2: 0, yp2: 0);
1234 }
1235 proxy()->drawItemText(painter: p, rect: textRect, flags: tf, pal: button->palette, enabled: (button->state & State_Enabled),
1236 text: button->text, textRole: QPalette::ButtonText);
1237 }
1238 break;
1239 case CE_RadioButton:
1240 case CE_CheckBox:
1241 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1242 bool isRadio = (element == CE_RadioButton);
1243 QStyleOptionButton subopt = *btn;
1244 subopt.rect = subElementRect(r: isRadio ? SE_RadioButtonIndicator
1245 : SE_CheckBoxIndicator, opt: btn);
1246 proxy()->drawPrimitive(pe: isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
1247 opt: &subopt, p);
1248 subopt.rect = subElementRect(r: isRadio ? SE_RadioButtonContents
1249 : SE_CheckBoxContents, opt: btn);
1250 proxy()->drawControl(element: isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, opt: &subopt, p);
1251 if (btn->state & State_HasFocus) {
1252 QStyleOptionFocusRect fropt;
1253 fropt.QStyleOption::operator=(other: *btn);
1254 fropt.rect = subElementRect(r: isRadio ? SE_RadioButtonFocusRect
1255 : SE_CheckBoxFocusRect, opt: btn);
1256 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p);
1257 }
1258 }
1259 break;
1260 case CE_RadioButtonLabel:
1261 case CE_CheckBoxLabel:
1262 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1263 uint alignment = visualAlignment(direction: btn->direction, alignment: Qt::AlignLeft | Qt::AlignVCenter);
1264
1265 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: btn))
1266 alignment |= Qt::TextHideMnemonic;
1267 QPixmap pix;
1268 QRect textRect = btn->rect;
1269 if (!btn->icon.isNull()) {
1270 pix = btn->icon.pixmap(size: btn->iconSize, devicePixelRatio: dpr(w: opt->window), mode: btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
1271 proxy()->drawItemPixmap(painter: p, rect: btn->rect, alignment, pixmap: pix);
1272 if (btn->direction == Qt::RightToLeft)
1273 textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
1274 else
1275 textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
1276 }
1277 if (!btn->text.isEmpty()){
1278 proxy()->drawItemText(painter: p, rect: textRect, flags: alignment | Qt::TextShowMnemonic,
1279 pal: btn->palette, enabled: btn->state & State_Enabled, text: btn->text, textRole: QPalette::WindowText);
1280 }
1281 }
1282 break;
1283 case CE_MenuScroller: {
1284 QStyleOption arrowOpt = *opt;
1285 arrowOpt.state |= State_Enabled;
1286 proxy()->drawPrimitive(pe: ((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp), opt: &arrowOpt, p);
1287 break; }
1288 case CE_MenuTearoff:
1289 if (opt->state & State_Selected)
1290 p->fillRect(opt->rect, opt->palette.brush(cr: QPalette::Highlight));
1291 else
1292 p->fillRect(opt->rect, opt->palette.brush(cr: QPalette::Button));
1293 p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
1294 p->drawLine(x1: opt->rect.x() + 2, y1: opt->rect.y() + opt->rect.height() / 2 - 1,
1295 x2: opt->rect.x() + opt->rect.width() - 4,
1296 y2: opt->rect.y() + opt->rect.height() / 2 - 1);
1297 p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
1298 p->drawLine(x1: opt->rect.x() + 2, y1: opt->rect.y() + opt->rect.height() / 2,
1299 x2: opt->rect.x() + opt->rect.width() - 4, y2: opt->rect.y() + opt->rect.height() / 2);
1300 break;
1301 case CE_MenuBarItem:
1302 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1303 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
1304 | Qt::TextSingleLine;
1305 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt: mbi))
1306 alignment |= Qt::TextHideMnemonic;
1307 int iconExtent = proxy()->pixelMetric(metric: PM_SmallIconSize);
1308 QPixmap pix = mbi->icon.pixmap(size: QSize(iconExtent, iconExtent), devicePixelRatio: dpr(w: opt->window),
1309 mode: mbi->state.testFlag(flag: State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1310 if (!pix.isNull())
1311 proxy()->drawItemPixmap(painter: p,rect: mbi->rect, alignment, pixmap: pix);
1312 else
1313 proxy()->drawItemText(painter: p, rect: mbi->rect, flags: alignment, pal: mbi->palette, enabled: mbi->state & State_Enabled,
1314 text: mbi->text, textRole: QPalette::ButtonText);
1315 }
1316 break;
1317 case CE_MenuBarEmptyArea:
1318 break;
1319 case CE_ProgressBar:
1320 if (const QStyleOptionProgressBar *pb
1321 = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1322 QStyleOptionProgressBar subopt = *pb;
1323 subopt.rect = subElementRect(r: SE_ProgressBarGroove, opt: pb);
1324 proxy()->drawControl(element: CE_ProgressBarGroove, opt: &subopt, p);
1325 subopt.rect = subElementRect(r: SE_ProgressBarContents, opt: pb);
1326 proxy()->drawControl(element: CE_ProgressBarContents, opt: &subopt, p);
1327 if (pb->textVisible) {
1328 subopt.rect = subElementRect(r: SE_ProgressBarLabel, opt: pb);
1329 proxy()->drawControl(element: CE_ProgressBarLabel, opt: &subopt, p);
1330 }
1331 }
1332 break;
1333 case CE_ProgressBarGroove:
1334 if (opt->rect.isValid())
1335 qDrawShadePanel(p, r: opt->rect, pal: opt->palette, sunken: true, lineWidth: 1,
1336 fill: &opt->palette.brush(cr: QPalette::Window));
1337 break;
1338 case CE_ProgressBarLabel:
1339 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1340 QPalette::ColorRole textRole = QPalette::NoRole;
1341 if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
1342 && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) {
1343 textRole = QPalette::HighlightedText;
1344 //Draw text shadow, This will increase readability when the background of same color
1345 QRect shadowRect(pb->rect);
1346 shadowRect.translate(dx: 1,dy: 1);
1347 QColor shadowColor = (pb->palette.color(cr: textRole).value() <= 128)
1348 ? QColor(255,255,255,160) : QColor(0,0,0,160);
1349 QPalette shadowPalette = pb->palette;
1350 shadowPalette.setColor(acr: textRole, acolor: shadowColor);
1351 proxy()->drawItemText(painter: p, rect: shadowRect, flags: Qt::AlignCenter | Qt::TextSingleLine, pal: shadowPalette,
1352 enabled: pb->state & State_Enabled, text: pb->text, textRole);
1353 }
1354 proxy()->drawItemText(painter: p, rect: pb->rect, flags: Qt::AlignCenter | Qt::TextSingleLine, pal: pb->palette,
1355 enabled: pb->state & State_Enabled, text: pb->text, textRole);
1356 }
1357 break;
1358 case CE_ProgressBarContents:
1359 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1360
1361 QRect rect = pb->rect;
1362 const bool inverted = pb->invertedAppearance;
1363 qint64 minimum = qint64(pb->minimum);
1364 qint64 maximum = qint64(pb->maximum);
1365 qint64 progress = qint64(pb->progress);
1366
1367 QPalette pal2 = pb->palette;
1368 // Correct the highlight color if it is the same as the background
1369 if (pal2.highlight() == pal2.window())
1370 pal2.setColor(acr: QPalette::Highlight, acolor: pb->palette.color(cg: QPalette::Active,
1371 cr: QPalette::Highlight));
1372 bool reverse = pb->direction == Qt::RightToLeft;
1373 if (inverted)
1374 reverse = !reverse;
1375 int w = rect.width();
1376 if (pb->minimum == 0 && pb->maximum == 0) {
1377 // draw busy indicator
1378 int x = (progress - minimum) % (w * 2);
1379 if (x > w)
1380 x = 2 * w - x;
1381 x = reverse ? rect.right() - x : x + rect.x();
1382 p->setPen(QPen(pal2.highlight().color(), 4));
1383 p->drawLine(x1: x, y1: rect.y(), x2: x, y2: rect.height());
1384 } else {
1385 const int unit_width = proxy()->pixelMetric(metric: PM_ProgressBarChunkWidth, option: pb);
1386 if (!unit_width)
1387 return;
1388
1389 int u;
1390 if (unit_width > 1)
1391 u = ((rect.width() + unit_width) / unit_width);
1392 else
1393 u = w / unit_width;
1394 qint64 p_v = progress - minimum;
1395 qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1);
1396
1397 if (u > 0 && p_v >= INT_MAX / u && t_s >= u) {
1398 // scale down to something usable.
1399 p_v /= u;
1400 t_s /= u;
1401 }
1402
1403 // nu < tnu, if last chunk is only a partial chunk
1404 int tnu, nu;
1405 tnu = nu = p_v * u / t_s;
1406
1407 if (nu * unit_width > w)
1408 --nu;
1409
1410 // Draw nu units out of a possible u of unit_width
1411 // width, each a rectangle bordered by background
1412 // color, all in a sunken panel with a percentage text
1413 // display at the end.
1414 int x = 0;
1415 int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
1416 : rect.x();
1417
1418 QStyleOptionProgressBar pbBits = *pb;
1419 pbBits.rect = rect;
1420 pbBits.palette = pal2;
1421 int myY = pbBits.rect.y();
1422 int myHeight = pbBits.rect.height();
1423 pbBits.state = State_Horizontal;
1424 for (int i = 0; i < nu; ++i) {
1425 pbBits.rect.setRect(ax: x0 + x, ay: myY, aw: unit_width, ah: myHeight);
1426 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p);
1427 x += reverse ? -unit_width : unit_width;
1428 }
1429
1430 // Draw the last partial chunk to fill up the
1431 // progress bar entirely
1432 if (nu < tnu) {
1433 int pixels_left = w - (nu * unit_width);
1434 int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x;
1435 pbBits.rect.setRect(ax: offset, ay: myY, aw: pixels_left, ah: myHeight);
1436 proxy()->drawPrimitive(pe: PE_IndicatorProgressChunk, opt: &pbBits, p);
1437 }
1438 }
1439 }
1440 break;
1441 case CE_HeaderLabel:
1442 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1443 QRect rect = header->rect;
1444 if (!header->icon.isNull()) {
1445 int iconExtent = proxy()->pixelMetric(metric: PM_SmallIconSize);
1446 QPixmap pixmap
1447 = header->icon.pixmap(size: QSize(iconExtent, iconExtent), devicePixelRatio: dpr(w: opt->window),
1448 mode: header->state.testFlag(flag: State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1449 int pixw = pixmap.width() / pixmap.devicePixelRatio();
1450
1451 QRect aligned = alignedRect(direction: header->direction, alignment: QFlag(header->iconAlignment), size: pixmap.size() / pixmap.devicePixelRatio(), rectangle: rect);
1452 QRect inter = aligned.intersected(other: rect);
1453 p->drawPixmap(x: inter.x(), y: inter.y(), pm: pixmap,
1454 sx: inter.x() - aligned.x(), sy: inter.y() - aligned.y(),
1455 sw: aligned.width() * pixmap.devicePixelRatio(),
1456 sh: pixmap.height() * pixmap.devicePixelRatio());
1457
1458 const int margin = proxy()->pixelMetric(metric: QStyle::PM_HeaderMargin, option: opt);
1459 if (header->direction == Qt::LeftToRight)
1460 rect.setLeft(rect.left() + pixw + margin);
1461 else
1462 rect.setRight(rect.right() - pixw - margin);
1463 }
1464 if (header->state & QStyle::State_On) {
1465 QFont fnt = p->font();
1466 fnt.setBold(true);
1467 p->setFont(fnt);
1468 }
1469 proxy()->drawItemText(painter: p, rect, flags: header->textAlignment, pal: header->palette,
1470 enabled: (header->state & State_Enabled), text: header->text, textRole: QPalette::ButtonText);
1471 }
1472 break;
1473 case CE_ToolButtonLabel:
1474 if (const QStyleOptionToolButton *toolbutton
1475 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
1476 QRect rect = toolbutton->rect;
1477 int shiftX = 0;
1478 int shiftY = 0;
1479 if (toolbutton->state & (State_Sunken | State_On)) {
1480 shiftX = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: toolbutton);
1481 shiftY = proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: toolbutton);
1482 }
1483 // Arrow type always overrules and is always shown
1484 bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
1485 if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
1486 || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
1487 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1488 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt))
1489 alignment |= Qt::TextHideMnemonic;
1490 rect.translate(dx: shiftX, dy: shiftY);
1491 p->setFont(toolbutton->font);
1492 proxy()->drawItemText(painter: p, rect, flags: alignment, pal: toolbutton->palette,
1493 enabled: opt->state & State_Enabled, text: toolbutton->text,
1494 textRole: QPalette::ButtonText);
1495 } else {
1496 QPixmap pm;
1497 QSize pmSize = toolbutton->iconSize;
1498 if (!toolbutton->icon.isNull()) {
1499 QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
1500 QIcon::Mode mode;
1501 if (!(toolbutton->state & State_Enabled))
1502 mode = QIcon::Disabled;
1503 else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise))
1504 mode = QIcon::Active;
1505 else
1506 mode = QIcon::Normal;
1507 pm = toolbutton->icon.pixmap(size: toolbutton->rect.size().boundedTo(otherSize: toolbutton->iconSize),
1508 devicePixelRatio: dpr(w: opt->window), mode, state);
1509 pmSize = pm.size() / pm.devicePixelRatio();
1510 }
1511
1512 if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
1513 p->setFont(toolbutton->font);
1514 QRect pr = rect,
1515 tr = rect;
1516 int alignment = Qt::TextShowMnemonic;
1517 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt))
1518 alignment |= Qt::TextHideMnemonic;
1519
1520 if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
1521 pr.setHeight(pmSize.height() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1522 tr.adjust(dx1: 0, dy1: pr.height() - 1, dx2: 0, dy2: -1);
1523 pr.translate(dx: shiftX, dy: shiftY);
1524 if (!hasArrow) {
1525 proxy()->drawItemPixmap(painter: p, rect: pr, alignment: Qt::AlignCenter, pixmap: pm);
1526 } else {
1527 drawArrow(style: proxy(), toolbutton, rect: pr, painter: p);
1528 }
1529 alignment |= Qt::AlignCenter;
1530 } else {
1531 pr.setWidth(pmSize.width() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1532 tr.adjust(dx1: pr.width(), dy1: 0, dx2: 0, dy2: 0);
1533 pr.translate(dx: shiftX, dy: shiftY);
1534 if (!hasArrow) {
1535 proxy()->drawItemPixmap(painter: p, rect: QStyle::visualRect(direction: opt->direction, boundingRect: rect, logicalRect: pr), alignment: Qt::AlignCenter, pixmap: pm);
1536 } else {
1537 drawArrow(style: proxy(), toolbutton, rect: pr, painter: p);
1538 }
1539 alignment |= Qt::AlignLeft | Qt::AlignVCenter;
1540 }
1541 tr.translate(dx: shiftX, dy: shiftY);
1542 const QString text = d->toolButtonElideText(option: toolbutton, textRect: tr, flags: alignment);
1543 proxy()->drawItemText(painter: p, rect: QStyle::visualRect(direction: opt->direction, boundingRect: rect, logicalRect: tr), flags: alignment, pal: toolbutton->palette,
1544 enabled: toolbutton->state & State_Enabled, text,
1545 textRole: QPalette::ButtonText);
1546 } else {
1547 rect.translate(dx: shiftX, dy: shiftY);
1548 if (hasArrow) {
1549 drawArrow(style: proxy(), toolbutton, rect, painter: p);
1550 } else {
1551 proxy()->drawItemPixmap(painter: p, rect, alignment: Qt::AlignCenter, pixmap: pm);
1552 }
1553 }
1554 }
1555 }
1556 break;
1557 case CE_ToolBoxTab:
1558 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1559 proxy()->drawControl(element: CE_ToolBoxTabShape, opt: tb, p);
1560 proxy()->drawControl(element: CE_ToolBoxTabLabel, opt: tb, p);
1561 }
1562 break;
1563 case CE_ToolBoxTabShape:
1564 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1565 p->setPen(tb->palette.mid().color().darker(f: 150));
1566 int d = 20 + tb->rect.height() - 3;
1567 if (tb->direction != Qt::RightToLeft) {
1568 const QPoint points[] = {
1569 QPoint(-1, tb->rect.height() + 1),
1570 QPoint(-1, 1),
1571 QPoint(tb->rect.width() - d, 1),
1572 QPoint(tb->rect.width() - 20, tb->rect.height() - 2),
1573 QPoint(tb->rect.width() - 1, tb->rect.height() - 2),
1574 QPoint(tb->rect.width() - 1, tb->rect.height() + 1),
1575 QPoint(-1, tb->rect.height() + 1),
1576 };
1577 p->drawPolygon(points, pointCount: sizeof points / sizeof *points);
1578 } else {
1579 const QPoint points[] = {
1580 QPoint(tb->rect.width(), tb->rect.height() + 1),
1581 QPoint(tb->rect.width(), 1),
1582 QPoint(d - 1, 1),
1583 QPoint(20 - 1, tb->rect.height() - 2),
1584 QPoint(0, tb->rect.height() - 2),
1585 QPoint(0, tb->rect.height() + 1),
1586 QPoint(tb->rect.width(), tb->rect.height() + 1),
1587 };
1588 p->drawPolygon(points, pointCount: sizeof points / sizeof *points);
1589 }
1590 p->setPen(tb->palette.light().color());
1591 if (tb->direction != Qt::RightToLeft) {
1592 p->drawLine(x1: 0, y1: 2, x2: tb->rect.width() - d, y2: 2);
1593 p->drawLine(x1: tb->rect.width() - d - 1, y1: 2, x2: tb->rect.width() - 21, y2: tb->rect.height() - 1);
1594 p->drawLine(x1: tb->rect.width() - 20, y1: tb->rect.height() - 1,
1595 x2: tb->rect.width(), y2: tb->rect.height() - 1);
1596 } else {
1597 p->drawLine(x1: tb->rect.width() - 1, y1: 2, x2: d - 1, y2: 2);
1598 p->drawLine(x1: d, y1: 2, x2: 20, y2: tb->rect.height() - 1);
1599 p->drawLine(x1: 19, y1: tb->rect.height() - 1,
1600 x2: -1, y2: tb->rect.height() - 1);
1601 }
1602 p->setBrush(Qt::NoBrush);
1603 }
1604 break;
1605 case CE_TabBarTab:
1606 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1607 proxy()->drawControl(element: CE_TabBarTabShape, opt: tab, p);
1608 proxy()->drawControl(element: CE_TabBarTabLabel, opt: tab, p);
1609 }
1610 break;
1611 case CE_TabBarTabShape:
1612 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1613 p->save();
1614
1615 QRect rect(tab->rect);
1616 bool selected = tab->state & State_Selected;
1617 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1618 int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(metric: PM_TabBarTabOverlap, option: opt);
1619
1620 if (!selected) {
1621 switch (tab->shape) {
1622 case QStyleOptionTab::TriangularNorth:
1623 rect.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -tabOverlap);
1624 if(!selected)
1625 rect.adjust(dx1: 1, dy1: 1, dx2: -1, dy2: 0);
1626 break;
1627 case QStyleOptionTab::TriangularSouth:
1628 rect.adjust(dx1: 0, dy1: tabOverlap, dx2: 0, dy2: 0);
1629 if(!selected)
1630 rect.adjust(dx1: 1, dy1: 0, dx2: -1, dy2: -1);
1631 break;
1632 case QStyleOptionTab::TriangularEast:
1633 rect.adjust(dx1: tabOverlap, dy1: 0, dx2: 0, dy2: 0);
1634 if(!selected)
1635 rect.adjust(dx1: 0, dy1: 1, dx2: -1, dy2: -1);
1636 break;
1637 case QStyleOptionTab::TriangularWest:
1638 rect.adjust(dx1: 0, dy1: 0, dx2: -tabOverlap, dy2: 0);
1639 if(!selected)
1640 rect.adjust(dx1: 1, dy1: 1, dx2: 0, dy2: -1);
1641 break;
1642 default:
1643 break;
1644 }
1645 }
1646
1647 p->setPen(QPen(tab->palette.windowText(), 0));
1648 if (selected) {
1649 p->setBrush(tab->palette.base());
1650 } else {
1651 p->setBrush(tab->palette.window());
1652 }
1653
1654 int y;
1655 int x;
1656 QPolygon a(10);
1657 switch (tab->shape) {
1658 case QStyleOptionTab::TriangularNorth:
1659 case QStyleOptionTab::TriangularSouth: {
1660 a.setPoint(index: 0, x: 0, y: -1);
1661 a.setPoint(index: 1, x: 0, y: 0);
1662 y = rect.height() - 2;
1663 x = y / 3;
1664 a.setPoint(index: 2, x: x++, y: y - 1);
1665 ++x;
1666 a.setPoint(index: 3, x: x++, y: y++);
1667 a.setPoint(index: 4, x, y);
1668
1669 int i;
1670 int right = rect.width() - 1;
1671 for (i = 0; i < 5; ++i)
1672 a.setPoint(index: 9 - i, x: right - a.point(index: i).x(), y: a.point(index: i).y());
1673 if (tab->shape == QStyleOptionTab::TriangularNorth)
1674 for (i = 0; i < 10; ++i)
1675 a.setPoint(index: i, x: a.point(index: i).x(), y: rect.height() - 1 - a.point(index: i).y());
1676
1677 a.translate(dx: rect.left(), dy: rect.top());
1678 p->setRenderHint(hint: QPainter::Antialiasing);
1679 p->translate(dx: 0, dy: 0.5);
1680
1681 QPainterPath path;
1682 path.addPolygon(polygon: a);
1683 p->drawPath(path);
1684 break; }
1685 case QStyleOptionTab::TriangularEast:
1686 case QStyleOptionTab::TriangularWest: {
1687 a.setPoint(index: 0, x: -1, y: 0);
1688 a.setPoint(index: 1, x: 0, y: 0);
1689 x = rect.width() - 2;
1690 y = x / 3;
1691 a.setPoint(index: 2, x: x - 1, y: y++);
1692 ++y;
1693 a.setPoint(index: 3, x: x++, y: y++);
1694 a.setPoint(index: 4, x, y);
1695 int i;
1696 int bottom = rect.height() - 1;
1697 for (i = 0; i < 5; ++i)
1698 a.setPoint(index: 9 - i, x: a.point(index: i).x(), y: bottom - a.point(index: i).y());
1699 if (tab->shape == QStyleOptionTab::TriangularWest)
1700 for (i = 0; i < 10; ++i)
1701 a.setPoint(index: i, x: rect.width() - 1 - a.point(index: i).x(), y: a.point(index: i).y());
1702 a.translate(dx: rect.left(), dy: rect.top());
1703 p->setRenderHint(hint: QPainter::Antialiasing);
1704 p->translate(dx: 0.5, dy: 0);
1705 QPainterPath path;
1706 path.addPolygon(polygon: a);
1707 p->drawPath(path);
1708 break; }
1709 default:
1710 break;
1711 }
1712 p->restore();
1713 }
1714 break;
1715 case CE_ToolBoxTabLabel:
1716 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1717 bool enabled = tb->state & State_Enabled;
1718 bool selected = tb->state & State_Selected;
1719 int iconExtent = proxy()->pixelMetric(metric: QStyle::PM_SmallIconSize, option: tb);
1720 QPixmap pm = tb->icon.pixmap(size: QSize(iconExtent, iconExtent), devicePixelRatio: dpr(w: opt->window),
1721 mode: enabled ? QIcon::Normal : QIcon::Disabled);
1722
1723 QRect cr = subElementRect(r: QStyle::SE_ToolBoxTabContents, opt: tb);
1724 QRect tr, ir;
1725 int ih = 0;
1726 if (pm.isNull()) {
1727 tr = cr;
1728 tr.adjust(dx1: 4, dy1: 0, dx2: -8, dy2: 0);
1729 } else {
1730 int iw = pm.width() / pm.devicePixelRatio() + 4;
1731 ih = pm.height()/ pm.devicePixelRatio();
1732 ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
1733 tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
1734 }
1735
1736 if (selected && proxy()->styleHint(stylehint: QStyle::SH_ToolBox_SelectedPageTitleBold, opt: tb)) {
1737 QFont f(p->font());
1738 f.setBold(true);
1739 p->setFont(f);
1740 }
1741
1742 QString txt = tb->fontMetrics.elidedText(text: tb->text, mode: Qt::ElideRight, width: tr.width());
1743
1744 if (ih)
1745 p->drawPixmap(x: ir.left(), y: (tb->rect.height() - ih) / 2, pm);
1746
1747 int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
1748 if (!proxy()->styleHint(stylehint: QStyle::SH_UnderlineShortcut, opt: tb))
1749 alignment |= Qt::TextHideMnemonic;
1750 proxy()->drawItemText(painter: p, rect: tr, flags: alignment, pal: tb->palette, enabled, text: txt, textRole: QPalette::ButtonText);
1751
1752 if (!txt.isEmpty() && opt->state & State_HasFocus) {
1753 QStyleOptionFocusRect opt;
1754 opt.rect = tr;
1755 opt.palette = tb->palette;
1756 opt.state = QStyle::State_None;
1757 proxy()->drawPrimitive(pe: QStyle::PE_FrameFocusRect, opt: &opt, p);
1758 }
1759 }
1760 break;
1761 case CE_TabBarTabLabel:
1762 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1763 QRect tr = tab->rect;
1764 bool verticalTabs = tab->shape == QStyleOptionTab::RoundedEast
1765 || tab->shape == QStyleOptionTab::RoundedWest
1766 || tab->shape == QStyleOptionTab::TriangularEast
1767 || tab->shape == QStyleOptionTab::TriangularWest;
1768
1769 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1770 if (!proxy()->styleHint(stylehint: SH_UnderlineShortcut, opt))
1771 alignment |= Qt::TextHideMnemonic;
1772
1773 if (verticalTabs) {
1774 p->save();
1775 int newX, newY, newRot;
1776 if (tab->shape == QStyleOptionTab::RoundedEast || tab->shape == QStyleOptionTab::TriangularEast) {
1777 newX = tr.width() + tr.x();
1778 newY = tr.y();
1779 newRot = 90;
1780 } else {
1781 newX = tr.x();
1782 newY = tr.y() + tr.height();
1783 newRot = -90;
1784 }
1785 QTransform m = QTransform::fromTranslate(dx: newX, dy: newY);
1786 m.rotate(a: newRot);
1787 p->setTransform(transform: m, combine: true);
1788 }
1789 QRect iconRect;
1790 d->tabLayout(opt: tab, textRect: &tr, iconRect: &iconRect);
1791 tr = proxy()->subElementRect(subElement: SE_TabBarTabText, option: opt); //we compute tr twice because the style may override subElementRect
1792
1793 if (!tab->icon.isNull()) {
1794 QPixmap tabIcon = tab->icon.pixmap(size: tab->iconSize, devicePixelRatio: dpr(w: opt->window),
1795 mode: (tab->state & State_Enabled) ? QIcon::Normal
1796 : QIcon::Disabled,
1797 state: (tab->state & State_Selected) ? QIcon::On
1798 : QIcon::Off);
1799 p->drawPixmap(x: iconRect.x(), y: iconRect.y(), pm: tabIcon);
1800 }
1801
1802 proxy()->drawItemText(painter: p, rect: tr, flags: alignment, pal: tab->palette, enabled: tab->state & State_Enabled, text: tab->text, textRole: QPalette::WindowText);
1803 if (verticalTabs)
1804 p->restore();
1805
1806 if (tab->state & State_HasFocus) {
1807 const int OFFSET = 1 + pixelMetric(m: PM_DefaultFrameWidth);
1808
1809 int x1, x2;
1810 x1 = tab->rect.left();
1811 x2 = tab->rect.right() - 1;
1812
1813 QStyleOptionFocusRect fropt;
1814 fropt.QStyleOption::operator=(other: *tab);
1815 fropt.rect.setRect(ax: x1 + 1 + OFFSET, ay: tab->rect.y() + OFFSET,
1816 aw: x2 - x1 - 2*OFFSET, ah: tab->rect.height() - 2*OFFSET);
1817 drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p);
1818 }
1819 }
1820 break;
1821 case CE_SizeGrip: {
1822 p->save();
1823 int x, y, w, h;
1824 opt->rect.getRect(ax: &x, ay: &y, aw: &w, ah: &h);
1825
1826 int sw = qMin(a: h, b: w);
1827 if (h > w)
1828 p->translate(dx: 0, dy: h - w);
1829 else
1830 p->translate(dx: w - h, dy: 0);
1831
1832 int sx = x;
1833 int sy = y;
1834 int s = sw / 3;
1835
1836 Qt::Corner corner;
1837 if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt))
1838 corner = sgOpt->corner;
1839 else if (opt->direction == Qt::RightToLeft)
1840 corner = Qt::BottomLeftCorner;
1841 else
1842 corner = Qt::BottomRightCorner;
1843
1844 if (corner == Qt::BottomLeftCorner) {
1845 sx = x + sw;
1846 for (int i = 0; i < 4; ++i) {
1847 p->setPen(QPen(opt->palette.light().color(), 1));
1848 p->drawLine(x1: x, y1: sy - 1 , x2: sx + 1, y2: sw);
1849 p->setPen(QPen(opt->palette.dark().color(), 1));
1850 p->drawLine(x1: x, y1: sy, x2: sx, y2: sw);
1851 p->setPen(QPen(opt->palette.dark().color(), 1));
1852 p->drawLine(x1: x, y1: sy + 1, x2: sx - 1, y2: sw);
1853 sx -= s;
1854 sy += s;
1855 }
1856 } else if (corner == Qt::BottomRightCorner) {
1857 for (int i = 0; i < 4; ++i) {
1858 p->setPen(QPen(opt->palette.light().color(), 1));
1859 p->drawLine(x1: sx - 1, y1: sw, x2: sw, y2: sy - 1);
1860 p->setPen(QPen(opt->palette.dark().color(), 1));
1861 p->drawLine(x1: sx, y1: sw, x2: sw, y2: sy);
1862 p->setPen(QPen(opt->palette.dark().color(), 1));
1863 p->drawLine(x1: sx + 1, y1: sw, x2: sw, y2: sy + 1);
1864 sx += s;
1865 sy += s;
1866 }
1867 } else if (corner == Qt::TopRightCorner) {
1868 sy = y + sw;
1869 for (int i = 0; i < 4; ++i) {
1870 p->setPen(QPen(opt->palette.light().color(), 1));
1871 p->drawLine(x1: sx - 1, y1: y, x2: sw, y2: sy + 1);
1872 p->setPen(QPen(opt->palette.dark().color(), 1));
1873 p->drawLine(x1: sx, y1: y, x2: sw, y2: sy);
1874 p->setPen(QPen(opt->palette.dark().color(), 1));
1875 p->drawLine(x1: sx + 1, y1: y, x2: sw, y2: sy - 1);
1876 sx += s;
1877 sy -= s;
1878 }
1879 } else if (corner == Qt::TopLeftCorner) {
1880 for (int i = 0; i < 4; ++i) {
1881 p->setPen(QPen(opt->palette.light().color(), 1));
1882 p->drawLine(x1: x, y1: sy - 1, x2: sx - 1, y2: y);
1883 p->setPen(QPen(opt->palette.dark().color(), 1));
1884 p->drawLine(x1: x, y1: sy, x2: sx, y2: y);
1885 p->setPen(QPen(opt->palette.dark().color(), 1));
1886 p->drawLine(x1: x, y1: sy + 1, x2: sx + 1, y2: y);
1887 sx += s;
1888 sy += s;
1889 }
1890 }
1891 p->restore();
1892 break; }
1893 case CE_RubberBand: {
1894 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
1895 QPixmap tiledPixmap(16, 16);
1896 QPainter pixmapPainter(&tiledPixmap);
1897 pixmapPainter.setPen(Qt::NoPen);
1898 pixmapPainter.setBrush(Qt::Dense4Pattern);
1899 pixmapPainter.setBackground(QBrush(opt->palette.base()));
1900 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
1901 pixmapPainter.drawRect(x: 0, y: 0, w: tiledPixmap.width(), h: tiledPixmap.height());
1902 pixmapPainter.end();
1903 // ### workaround for borked XRENDER
1904 tiledPixmap = QPixmap::fromImage(image: tiledPixmap.toImage());
1905
1906 p->save();
1907 QRect r = opt->rect;
1908 QStyleHintReturnMask mask;
1909 if (proxy()->styleHint(stylehint: QStyle::SH_RubberBand_Mask, opt, returnData: &mask))
1910 p->setClipRegion(mask.region);
1911 p->drawTiledPixmap(x: r.x(), y: r.y(), w: r.width(), h: r.height(), pm: tiledPixmap);
1912 p->setPen(opt->palette.color(cg: QPalette::Active, cr: QPalette::WindowText));
1913 p->setBrush(Qt::NoBrush);
1914 p->drawRect(r: r.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1));
1915 if (rbOpt->shape == QStyleOptionRubberBand::Rectangle)
1916 p->drawRect(r: r.adjusted(xp1: 3, yp1: 3, xp2: -4, yp2: -4));
1917 p->restore();
1918 }
1919 break; }
1920 case CE_DockWidgetTitle:
1921 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
1922 QRect r = dwOpt->rect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1);
1923 if (dwOpt->movable) {
1924 p->setPen(dwOpt->palette.color(cr: QPalette::Dark));
1925 p->drawRect(r);
1926 }
1927
1928 if (!dwOpt->title.isEmpty()) {
1929 const bool verticalTitleBar = dwOpt->verticalTitleBar;
1930
1931 if (verticalTitleBar) {
1932 r = r.transposed();
1933
1934 p->save();
1935 p->translate(dx: r.left(), dy: r.top() + r.width());
1936 p->rotate(a: -90);
1937 p->translate(dx: -r.left(), dy: -r.top());
1938 }
1939
1940 const int indent = p->fontMetrics().descent();
1941 proxy()->drawItemText(painter: p, rect: r.adjusted(xp1: indent + 1, yp1: 1, xp2: -indent - 1, yp2: -1),
1942 flags: Qt::AlignLeft | Qt::AlignVCenter, pal: dwOpt->palette,
1943 enabled: dwOpt->state & State_Enabled, text: dwOpt->title,
1944 textRole: QPalette::WindowText);
1945
1946 if (verticalTitleBar)
1947 p->restore();
1948 }
1949 }
1950 break;
1951 case CE_Header:
1952 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1953 QRegion clipRegion = p->clipRegion();
1954 p->setClipRect(opt->rect);
1955 proxy()->drawControl(element: CE_HeaderSection, opt: header, p);
1956 QStyleOptionHeader subopt = *header;
1957 subopt.rect = subElementRect(r: SE_HeaderLabel, opt: header);
1958 if (subopt.rect.isValid())
1959 proxy()->drawControl(element: CE_HeaderLabel, opt: &subopt, p);
1960 if (header->sortIndicator != QStyleOptionHeader::None) {
1961 subopt.rect = subElementRect(r: SE_HeaderArrow, opt);
1962 proxy()->drawPrimitive(pe: PE_IndicatorHeaderArrow, opt: &subopt, p);
1963 }
1964 p->setClipRegion(clipRegion);
1965 }
1966 break;
1967 case CE_FocusFrame:
1968 p->fillRect(opt->rect, opt->palette.windowText());
1969 break;
1970 case CE_HeaderSection:
1971 qDrawShadePanel(p, r: opt->rect, pal: opt->palette,
1972 sunken: opt->state & State_Sunken, lineWidth: 1,
1973 fill: &opt->palette.brush(cr: QPalette::Button));
1974 break;
1975 case CE_HeaderEmptyArea:
1976 p->fillRect(opt->rect, opt->palette.window());
1977 break;
1978 case CE_ComboBoxLabel:
1979 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1980 QRect editRect = proxy()->subControlRect(cc: CC_ComboBox, opt: cb, sc: SC_ComboBoxEditField);
1981 p->save();
1982 p->setClipRect(editRect);
1983 if (!cb->currentIcon.isNull()) {
1984 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
1985 : QIcon::Disabled;
1986 QPixmap pixmap = cb->currentIcon.pixmap(size: cb->iconSize, devicePixelRatio: dpr(w: opt->window), mode);
1987 QRect iconRect(editRect);
1988 iconRect.setWidth(cb->iconSize.width() + 4);
1989 iconRect = alignedRect(direction: cb->direction,
1990 alignment: Qt::AlignLeft | Qt::AlignVCenter,
1991 size: iconRect.size(), rectangle: editRect);
1992 if (cb->editable)
1993 p->fillRect(iconRect, opt->palette.brush(cr: QPalette::Base));
1994 proxy()->drawItemPixmap(painter: p, rect: iconRect, alignment: Qt::AlignCenter, pixmap);
1995
1996 if (cb->direction == Qt::RightToLeft)
1997 editRect.translate(dx: -4 - cb->iconSize.width(), dy: 0);
1998 else
1999 editRect.translate(dx: cb->iconSize.width() + 4, dy: 0);
2000 }
2001 if (!cb->currentText.isEmpty() && !cb->editable) {
2002 proxy()->drawItemText(painter: p, rect: editRect.adjusted(xp1: 1, yp1: 0, xp2: -1, yp2: 0),
2003 flags: visualAlignment(direction: cb->direction, alignment: Qt::AlignLeft | Qt::AlignVCenter),
2004 pal: cb->palette, enabled: cb->state & State_Enabled, text: cb->currentText);
2005 }
2006 p->restore();
2007 }
2008 break;
2009 case CE_ToolBar:
2010 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
2011 // Compatibility with styles that use PE_PanelToolBar
2012 QStyleOptionFrame frame;
2013 frame.QStyleOption::operator=(other: *toolBar);
2014 frame.lineWidth = toolBar->lineWidth;
2015 frame.midLineWidth = toolBar->midLineWidth;
2016 proxy()->drawPrimitive(pe: PE_PanelToolBar, opt, p);
2017
2018 qDrawShadePanel(p, r: toolBar->rect, pal: toolBar->palette, sunken: false, lineWidth: toolBar->lineWidth,
2019 fill: &toolBar->palette.brush(cr: QPalette::Button));
2020 }
2021 break;
2022 case CE_ColumnViewGrip: {
2023 // draw background gradients
2024 QLinearGradient g(0, 0, opt->rect.width(), 0);
2025 g.setColorAt(pos: 0, color: opt->palette.color(cg: QPalette::Active, cr: QPalette::Mid));
2026 g.setColorAt(pos: 0.5, color: Qt::white);
2027 p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g);
2028
2029 // draw the two lines
2030 QPen pen(p->pen());
2031 pen.setWidth(opt->rect.width()/20);
2032 pen.setColor(opt->palette.color(cg: QPalette::Active, cr: QPalette::Dark));
2033 p->setPen(pen);
2034
2035 int line1starting = opt->rect.width()*8 / 20;
2036 int line2starting = opt->rect.width()*13 / 20;
2037 int top = opt->rect.height()*20/75;
2038 int bottom = opt->rect.height() - 1 - top;
2039 p->drawLine(x1: line1starting, y1: top, x2: line1starting, y2: bottom);
2040 p->drawLine(x1: line2starting, y1: top, x2: line2starting, y2: bottom);
2041 }
2042 break;
2043#if QT_CONFIG(quick_itemview)
2044 case CE_ItemViewItem:
2045 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
2046 p->save();
2047 p->setClipRect(opt->rect);
2048
2049 QRect checkRect = proxy()->subElementRect(subElement: SE_ItemViewItemCheckIndicator, option: vopt);
2050 QRect iconRect = proxy()->subElementRect(subElement: SE_ItemViewItemDecoration, option: vopt);
2051 QRect textRect = proxy()->subElementRect(subElement: SE_ItemViewItemText, option: vopt);
2052
2053 // draw the background
2054 proxy()->drawPrimitive(pe: PE_PanelItemViewItem, opt, p);
2055
2056 // draw the check mark
2057 if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
2058 QStyleOptionViewItem option(*vopt);
2059 option.rect = checkRect;
2060 option.state = option.state & ~QStyle::State_HasFocus;
2061
2062 switch (vopt->checkState) {
2063 case Qt::Unchecked:
2064 option.state |= QStyle::State_Off;
2065 break;
2066 case Qt::PartiallyChecked:
2067 option.state |= QStyle::State_NoChange;
2068 break;
2069 case Qt::Checked:
2070 option.state |= QStyle::State_On;
2071 break;
2072 }
2073 proxy()->drawPrimitive(pe: QStyle::PE_IndicatorItemViewItemCheck, opt: &option, p);
2074 }
2075
2076 // draw the icon
2077 QIcon::Mode mode = QIcon::Normal;
2078 if (!(vopt->state & QStyle::State_Enabled))
2079 mode = QIcon::Disabled;
2080 else if (vopt->state & QStyle::State_Selected)
2081 mode = QIcon::Selected;
2082 QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
2083 vopt->icon.paint(painter: p, rect: iconRect, alignment: vopt->decorationAlignment, mode, state);
2084
2085 // draw the text
2086 if (!vopt->text.isEmpty()) {
2087 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
2088 ? QPalette::Normal : QPalette::Disabled;
2089 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
2090 cg = QPalette::Inactive;
2091
2092 if (vopt->state & QStyle::State_Selected) {
2093 p->setPen(vopt->palette.color(cg, cr: QPalette::HighlightedText));
2094 } else {
2095 p->setPen(vopt->palette.color(cg, cr: QPalette::Text));
2096 }
2097 if (vopt->state & QStyle::State_Editing) {
2098 p->setPen(vopt->palette.color(cg, cr: QPalette::Text));
2099 p->drawRect(r: textRect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1));
2100 }
2101
2102 d->viewItemDrawText(p, option: vopt, rect: textRect);
2103 }
2104
2105 // draw the focus rect
2106 if (vopt->state & QStyle::State_HasFocus) {
2107 QStyleOptionFocusRect o;
2108 o.QStyleOption::operator=(other: *vopt);
2109 o.rect = proxy()->subElementRect(subElement: SE_ItemViewItemFocusRect, option: vopt);
2110 o.state |= QStyle::State_KeyboardFocusChange;
2111 o.state |= QStyle::State_Item;
2112 QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled)
2113 ? QPalette::Normal : QPalette::Disabled;
2114 o.backgroundColor = vopt->palette.color(cg, cr: (vopt->state & QStyle::State_Selected)
2115 ? QPalette::Highlight : QPalette::Window);
2116 proxy()->drawPrimitive(pe: QStyle::PE_FrameFocusRect, opt: &o, p);
2117 }
2118
2119 p->restore();
2120 }
2121 break;
2122#endif // QT_CONFIG(quick_itemview)
2123 case CE_ShapedFrame:
2124 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2125 int frameShape = f->frameShape;
2126 int frameShadow = QStyleOptionFrame::Plain;
2127 if (f->state & QStyle::State_Sunken) {
2128 frameShadow = QStyleOptionFrame::Sunken;
2129 } else if (f->state & QStyle::State_Raised) {
2130 frameShadow = QStyleOptionFrame::Raised;
2131 }
2132
2133 int lw = f->lineWidth;
2134 int mlw = f->midLineWidth;
2135 QPalette::ColorRole foregroundRole = QPalette::WindowText;
2136
2137 switch (frameShape) {
2138 case QStyleOptionFrame::Box:
2139 if (frameShadow == QStyleOptionFrame::Plain) {
2140 qDrawPlainRect(p, r: f->rect, f->palette.color(cr: foregroundRole), lineWidth: lw);
2141 } else {
2142 qDrawShadeRect(p, r: f->rect, pal: f->palette, sunken: frameShadow == QStyleOptionFrame::Sunken, lineWidth: lw, midLineWidth: mlw);
2143 }
2144 break;
2145 case QStyleOptionFrame::StyledPanel:
2146 proxy()->drawPrimitive(pe: QStyle::PE_Frame, opt, p);
2147 break;
2148 case QStyleOptionFrame::Panel:
2149 if (frameShadow == QStyleOptionFrame::Plain) {
2150 qDrawPlainRect(p, r: f->rect, f->palette.color(cr: foregroundRole), lineWidth: lw);
2151 } else {
2152 qDrawShadePanel(p, r: f->rect, pal: f->palette, sunken: frameShadow == QStyleOptionFrame::Sunken, lineWidth: lw);
2153 }
2154 break;
2155 case QStyleOptionFrame::WinPanel:
2156 if (frameShadow == QStyleOptionFrame::Plain) {
2157 qDrawPlainRect(p, r: f->rect, f->palette.color(cr: foregroundRole), lineWidth: lw);
2158 } else {
2159 qDrawWinPanel(p, r: f->rect, pal: f->palette, sunken: frameShadow == QStyleOptionFrame::Sunken);
2160 }
2161 break;
2162 case QStyleOptionFrame::HLine:
2163 case QStyleOptionFrame::VLine: {
2164 QPoint p1, p2;
2165 if (frameShape == QStyleOptionFrame::HLine) {
2166 p1 = QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height() / 2);
2167 p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y());
2168 } else {
2169 p1 = QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
2170 p2 = QPoint(p1.x(), p1.y() + opt->rect.height());
2171 }
2172 if (frameShadow == QStyleOptionFrame::Plain) {
2173 QPen oldPen = p->pen();
2174 p->setPen(QPen(opt->palette.brush(cr: foregroundRole), lw));
2175 p->drawLine(p1, p2);
2176 p->setPen(oldPen);
2177 } else {
2178 qDrawShadeLine(p, p1, p2, pal: f->palette, sunken: frameShadow == QStyleOptionFrame::Sunken, lineWidth: lw, midLineWidth: mlw);
2179 }
2180 break;
2181 }
2182 }
2183 }
2184 break;
2185 default:
2186 break;
2187 }
2188}
2189
2190QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt) const
2191{
2192 Q_D(const QCommonStyle);
2193 QRect r;
2194 switch (sr) {
2195 case SE_PushButtonContents:
2196 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2197 int dx1, dx2;
2198 dx1 = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: btn);
2199 if (btn->features & QStyleOptionButton::AutoDefaultButton)
2200 dx1 += proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn);
2201 dx2 = dx1 * 2;
2202 r.setRect(ax: opt->rect.x() + dx1, ay: opt->rect.y() + dx1, aw: opt->rect.width() - dx2,
2203 ah: opt->rect.height() - dx2);
2204 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2205 }
2206 break;
2207 case SE_PushButtonFocusRect:
2208 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2209 int dbw1 = 0, dbw2 = 0;
2210 if (btn->features & QStyleOptionButton::AutoDefaultButton){
2211 dbw1 = proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn);
2212 dbw2 = dbw1 * 2;
2213 }
2214
2215 int dfw1 = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: btn) + 1,
2216 dfw2 = dfw1 * 2;
2217
2218 r.setRect(ax: btn->rect.x() + dfw1 + dbw1, ay: btn->rect.y() + dfw1 + dbw1,
2219 aw: btn->rect.width() - dfw2 - dbw2, ah: btn->rect.height()- dfw2 - dbw2);
2220 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2221 }
2222 break;
2223 case SE_CheckBoxIndicator:
2224 {
2225 int h = proxy()->pixelMetric(metric: PM_IndicatorHeight, option: opt);
2226 r.setRect(ax: opt->rect.x(), ay: opt->rect.y() + ((opt->rect.height() - h) / 2),
2227 aw: proxy()->pixelMetric(metric: PM_IndicatorWidth, option: opt), ah: h);
2228 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2229 }
2230 break;
2231
2232 case SE_CheckBoxContents:
2233 {
2234 // Deal with the logical first, then convert it back to screen coords.
2235 QRect ir = visualRect(direction: opt->direction, boundingRect: opt->rect,
2236 logicalRect: subElementRect(sr: SE_CheckBoxIndicator, opt));
2237 int spacing = proxy()->pixelMetric(metric: PM_CheckBoxLabelSpacing, option: opt);
2238 r.setRect(ax: ir.right() + spacing, ay: opt->rect.y(), aw: opt->rect.width() - ir.width() - spacing,
2239 ah: opt->rect.height());
2240 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2241 }
2242 break;
2243
2244 case SE_CheckBoxFocusRect:
2245 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2246 if (btn->icon.isNull() && btn->text.isEmpty()) {
2247 r = subElementRect(sr: SE_CheckBoxIndicator, opt);
2248 r.adjust(dx1: 1, dy1: 1, dx2: -1, dy2: -1);
2249 break;
2250 }
2251 // As above, deal with the logical first, then convert it back to screen coords.
2252 QRect cr = visualRect(direction: btn->direction, boundingRect: btn->rect, logicalRect: subElementRect(sr: SE_CheckBoxContents, opt: btn));
2253
2254 QRect iconRect, textRect;
2255 if (!btn->text.isEmpty()) {
2256 textRect = itemTextRect(fm: opt->fontMetrics, r: cr, flags: Qt::AlignAbsolute | Qt::AlignLeft
2257 | Qt::AlignVCenter | Qt::TextShowMnemonic,
2258 enabled: btn->state & State_Enabled, text: btn->text);
2259 }
2260 if (!btn->icon.isNull()) {
2261 iconRect = itemPixmapRect(r: cr, flags: Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2262 | Qt::TextShowMnemonic,
2263 pixmap: btn->icon.pixmap(size: btn->iconSize, devicePixelRatio: dpr(w: opt->window), mode: QIcon::Normal));
2264 if (!textRect.isEmpty())
2265 textRect.translate(dx: iconRect.right() + 4, dy: 0);
2266 }
2267 r = iconRect | textRect;
2268 r.adjust(dx1: -3, dy1: -2, dx2: 3, dy2: 2);
2269 r = r.intersected(other: btn->rect);
2270 r = visualRect(direction: btn->direction, boundingRect: btn->rect, logicalRect: r);
2271 }
2272 break;
2273
2274 case SE_RadioButtonIndicator:
2275 {
2276 int h = proxy()->pixelMetric(metric: PM_ExclusiveIndicatorHeight, option: opt);
2277 r.setRect(ax: opt->rect.x(), ay: opt->rect.y() + ((opt->rect.height() - h) / 2),
2278 aw: proxy()->pixelMetric(metric: PM_ExclusiveIndicatorWidth, option: opt), ah: h);
2279 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2280 }
2281 break;
2282
2283 case SE_RadioButtonContents:
2284 {
2285 QRect ir = visualRect(direction: opt->direction, boundingRect: opt->rect,
2286 logicalRect: subElementRect(sr: SE_RadioButtonIndicator, opt));
2287 int spacing = proxy()->pixelMetric(metric: PM_RadioButtonLabelSpacing, option: opt);
2288 r.setRect(ax: ir.left() + ir.width() + spacing, ay: opt->rect.y(), aw: opt->rect.width() - ir.width() - spacing,
2289 ah: opt->rect.height());
2290 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2291 break;
2292 }
2293
2294 case SE_RadioButtonFocusRect:
2295 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2296 if (btn->icon.isNull() && btn->text.isEmpty()) {
2297 r = subElementRect(sr: SE_RadioButtonIndicator, opt);
2298 r.adjust(dx1: 1, dy1: 1, dx2: -1, dy2: -1);
2299 break;
2300 }
2301 QRect cr = visualRect(direction: btn->direction, boundingRect: btn->rect, logicalRect: subElementRect(sr: SE_RadioButtonContents, opt));
2302
2303 QRect iconRect, textRect;
2304 if (!btn->text.isEmpty()){
2305 textRect = itemTextRect(fm: opt->fontMetrics, r: cr, flags: Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2306 | Qt::TextShowMnemonic, enabled: btn->state & State_Enabled, text: btn->text);
2307 }
2308 if (!btn->icon.isNull()) {
2309 iconRect = itemPixmapRect(r: cr, flags: Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
2310 pixmap: btn->icon.pixmap(size: btn->iconSize, devicePixelRatio: dpr(w: opt->window), mode: QIcon::Normal));
2311 if (!textRect.isEmpty())
2312 textRect.translate(dx: iconRect.right() + 4, dy: 0);
2313 }
2314 r = iconRect | textRect;
2315 r.adjust(dx1: -3, dy1: -2, dx2: 3, dy2: 2);
2316 r = r.intersected(other: btn->rect);
2317 r = visualRect(direction: btn->direction, boundingRect: btn->rect, logicalRect: r);
2318 }
2319 break;
2320 case SE_SliderFocusRect:
2321 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2322 int tickOffset = proxy()->pixelMetric(metric: PM_SliderTickmarkOffset, option: slider);
2323 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: slider);
2324 if (slider->orientation == Qt::Horizontal)
2325 r.setRect(ax: 0, ay: tickOffset - 1, aw: slider->rect.width(), ah: thickness + 2);
2326 else
2327 r.setRect(ax: tickOffset - 1, ay: 0, aw: thickness + 2, ah: slider->rect.height());
2328 r = r.intersected(other: slider->rect);
2329 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2330 }
2331 break;
2332 case SE_ProgressBarGroove:
2333 case SE_ProgressBarContents:
2334 case SE_ProgressBarLabel:
2335 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
2336 int textw = 0;
2337 if (pb->textVisible)
2338 textw = qMax(a: pb->fontMetrics.horizontalAdvance(pb->text), b: pb->fontMetrics.horizontalAdvance(QLatin1String("100%"))) + 6;
2339
2340 if ((pb->textAlignment & Qt::AlignCenter) == 0) {
2341 if (sr != SE_ProgressBarLabel)
2342 r.setCoords(xp1: pb->rect.left(), yp1: pb->rect.top(),
2343 xp2: pb->rect.right() - textw, yp2: pb->rect.bottom());
2344 else
2345 r.setCoords(xp1: pb->rect.right() - textw, yp1: pb->rect.top(),
2346 xp2: pb->rect.right(), yp2: pb->rect.bottom());
2347 } else {
2348 r = pb->rect;
2349 }
2350 r = visualRect(direction: pb->direction, boundingRect: pb->rect, logicalRect: r);
2351 }
2352 break;
2353 case SE_ComboBoxFocusRect:
2354 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2355 int margin = cb->frame ? 3 : 0;
2356 r.setRect(ax: opt->rect.left() + margin, ay: opt->rect.top() + margin,
2357 aw: opt->rect.width() - 2*margin - 16, ah: opt->rect.height() - 2*margin);
2358 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2359 }
2360 break;
2361 case SE_ToolBoxTabContents:
2362 r = opt->rect;
2363 r.adjust(dx1: 0, dy1: 0, dx2: -30, dy2: 0);
2364 break;
2365 case SE_HeaderLabel: {
2366 int margin = proxy()->pixelMetric(metric: QStyle::PM_HeaderMargin, option: opt);
2367 r.setRect(ax: opt->rect.x() + margin, ay: opt->rect.y() + margin,
2368 aw: opt->rect.width() - margin * 2, ah: opt->rect.height() - margin * 2);
2369
2370 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2371 // Subtract width needed for arrow, if there is one
2372 if (header->sortIndicator != QStyleOptionHeader::None) {
2373 if (opt->state & State_Horizontal)
2374 r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2));
2375 else
2376 r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2));
2377 }
2378 }
2379 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2380 break; }
2381 case SE_HeaderArrow: {
2382 int h = opt->rect.height();
2383 int w = opt->rect.width();
2384 int x = opt->rect.x();
2385 int y = opt->rect.y();
2386 int margin = proxy()->pixelMetric(metric: QStyle::PM_HeaderMargin, option: opt);
2387
2388 if (opt->state & State_Horizontal) {
2389 int horiz_size = h / 2;
2390 r.setRect(ax: x + w - margin * 2 - horiz_size, ay: y + 5,
2391 aw: horiz_size, ah: h - margin * 2 - 5);
2392 } else {
2393 int vert_size = w / 2;
2394 r.setRect(ax: x + 5, ay: y + h - margin * 2 - vert_size,
2395 aw: w - margin * 2 - 5, ah: vert_size);
2396 }
2397 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2398 break; }
2399
2400 case SE_RadioButtonClickRect:
2401 r = subElementRect(sr: SE_RadioButtonFocusRect, opt);
2402 r |= subElementRect(sr: SE_RadioButtonIndicator, opt);
2403 break;
2404 case SE_CheckBoxClickRect:
2405 r = subElementRect(sr: SE_CheckBoxFocusRect, opt);
2406 r |= subElementRect(sr: SE_CheckBoxIndicator, opt);
2407 break;
2408 case SE_TabWidgetTabBar:
2409 if (const QStyleOptionTabWidgetFrame *twf
2410 = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2411 r.setSize(twf->tabBarSize);
2412 const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter;
2413 switch (twf->shape) {
2414 case QStyleOptionTab::RoundedNorth:
2415 case QStyleOptionTab::TriangularNorth:
2416 // Constrain the size now, otherwise, center could get off the page
2417 // This of course repeated for all the other directions
2418 r.setWidth(qMin(a: r.width(), b: twf->rect.width()
2419 - twf->leftCornerWidgetSize.width()
2420 - twf->rightCornerWidgetSize.width()));
2421 switch (proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: twf) & alingMask) {
2422 default:
2423 case Qt::AlignLeft:
2424 r.moveTopLeft(p: QPoint(twf->leftCornerWidgetSize.width(), 0));
2425 break;
2426 case Qt::AlignHCenter:
2427 r.moveTopLeft(p: QPoint(twf->rect.center().x() - qRound(f: r.width() / 2.0f)
2428 + (twf->leftCornerWidgetSize.width() / 2)
2429 - (twf->rightCornerWidgetSize.width() / 2), 0));
2430 break;
2431 case Qt::AlignRight:
2432 r.moveTopLeft(p: QPoint(twf->rect.width() - twf->tabBarSize.width()
2433 - twf->rightCornerWidgetSize.width(), 0));
2434 break;
2435 }
2436 r = visualRect(direction: twf->direction, boundingRect: twf->rect, logicalRect: r);
2437 break;
2438 case QStyleOptionTab::RoundedSouth:
2439 case QStyleOptionTab::TriangularSouth:
2440 r.setWidth(qMin(a: r.width(), b: twf->rect.width()
2441 - twf->leftCornerWidgetSize.width()
2442 - twf->rightCornerWidgetSize.width()));
2443 switch (proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: twf) & alingMask) {
2444 default:
2445 case Qt::AlignLeft:
2446 r.moveTopLeft(p: QPoint(twf->leftCornerWidgetSize.width(),
2447 twf->rect.height() - twf->tabBarSize.height()));
2448 break;
2449 case Qt::AlignHCenter:
2450 r.moveTopLeft(p: QPoint(twf->rect.center().x() - qRound(f: r.width() / 2.0f)
2451 + (twf->leftCornerWidgetSize.width() / 2)
2452 - (twf->rightCornerWidgetSize.width() / 2),
2453 twf->rect.height() - twf->tabBarSize.height()));
2454 break;
2455 case Qt::AlignRight:
2456 r.moveTopLeft(p: QPoint(twf->rect.width() - twf->tabBarSize.width()
2457 - twf->rightCornerWidgetSize.width(),
2458 twf->rect.height() - twf->tabBarSize.height()));
2459 break;
2460 }
2461 r = visualRect(direction: twf->direction, boundingRect: twf->rect, logicalRect: r);
2462 break;
2463 case QStyleOptionTab::RoundedEast:
2464 case QStyleOptionTab::TriangularEast:
2465 r.setHeight(qMin(a: r.height(), b: twf->rect.height()
2466 - twf->leftCornerWidgetSize.height()
2467 - twf->rightCornerWidgetSize.height()));
2468 switch (proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: twf) & alingMask) {
2469 default:
2470 case Qt::AlignLeft:
2471 r.moveTopLeft(p: QPoint(twf->rect.width() - twf->tabBarSize.width(),
2472 twf->leftCornerWidgetSize.height()));
2473 break;
2474 case Qt::AlignHCenter:
2475 r.moveTopLeft(p: QPoint(twf->rect.width() - twf->tabBarSize.width(),
2476 twf->rect.center().y() - r.height() / 2));
2477 break;
2478 case Qt::AlignRight:
2479 r.moveTopLeft(p: QPoint(twf->rect.width() - twf->tabBarSize.width(),
2480 twf->rect.height() - twf->tabBarSize.height()
2481 - twf->rightCornerWidgetSize.height()));
2482 break;
2483 }
2484 break;
2485 case QStyleOptionTab::RoundedWest:
2486 case QStyleOptionTab::TriangularWest:
2487 r.setHeight(qMin(a: r.height(), b: twf->rect.height()
2488 - twf->leftCornerWidgetSize.height()
2489 - twf->rightCornerWidgetSize.height()));
2490 switch (proxy()->styleHint(stylehint: SH_TabBar_Alignment, opt: twf) & alingMask) {
2491 default:
2492 case Qt::AlignLeft:
2493 r.moveTopLeft(p: QPoint(0, twf->leftCornerWidgetSize.height()));
2494 break;
2495 case Qt::AlignHCenter:
2496 r.moveTopLeft(p: QPoint(0, twf->rect.center().y() - r.height() / 2));
2497 break;
2498 case Qt::AlignRight:
2499 r.moveTopLeft(p: QPoint(0, twf->rect.height() - twf->tabBarSize.height()
2500 - twf->rightCornerWidgetSize.height()));
2501 break;
2502 }
2503 break;
2504 }
2505 }
2506 break;
2507 case SE_TabWidgetTabPane:
2508 case SE_TabWidgetTabContents:
2509 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2510 QStyleOptionTab tabopt;
2511 tabopt.shape = twf->shape;
2512 int overlap = proxy()->pixelMetric(metric: PM_TabBarBaseOverlap, option: &tabopt);
2513 if (twf->lineWidth == 0)
2514 overlap = 0;
2515 switch (twf->shape) {
2516 case QStyleOptionTab::RoundedNorth:
2517 case QStyleOptionTab::TriangularNorth:
2518 r = QRect(QPoint(0,qMax(a: twf->tabBarSize.height() - overlap, b: 0)),
2519 QSize(twf->rect.width(), qMin(a: twf->rect.height() - twf->tabBarSize.height() + overlap, b: twf->rect.height())));
2520 break;
2521 case QStyleOptionTab::RoundedSouth:
2522 case QStyleOptionTab::TriangularSouth:
2523 r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(a: twf->rect.height() - twf->tabBarSize.height() + overlap, b: twf->rect.height())));
2524 break;
2525 case QStyleOptionTab::RoundedEast:
2526 case QStyleOptionTab::TriangularEast:
2527 r = QRect(QPoint(0, 0), QSize(qMin(a: twf->rect.width() - twf->tabBarSize.width() + overlap, b: twf->rect.width()), twf->rect.height()));
2528 break;
2529 case QStyleOptionTab::RoundedWest:
2530 case QStyleOptionTab::TriangularWest:
2531 r = QRect(QPoint(qMax(a: twf->tabBarSize.width() - overlap, b: 0), 0),
2532 QSize(qMin(a: twf->rect.width() - twf->tabBarSize.width() + overlap, b: twf->rect.width()), twf->rect.height()));
2533 break;
2534 }
2535 if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0)
2536 r.adjust(dx1: 2, dy1: 2, dx2: -2, dy2: -2);
2537 }
2538 break;
2539 case SE_TabWidgetLeftCorner:
2540 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2541 QRect paneRect = subElementRect(sr: SE_TabWidgetTabPane, opt: twf);
2542 switch (twf->shape) {
2543 case QStyleOptionTab::RoundedNorth:
2544 case QStyleOptionTab::TriangularNorth:
2545 r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()),
2546 twf->leftCornerWidgetSize);
2547 break;
2548 case QStyleOptionTab::RoundedSouth:
2549 case QStyleOptionTab::TriangularSouth:
2550 r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
2551 break;
2552 default:
2553 break;
2554 }
2555 r = visualRect(direction: twf->direction, boundingRect: twf->rect, logicalRect: r);
2556 }
2557 break;
2558 case SE_TabWidgetRightCorner:
2559 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2560 QRect paneRect = subElementRect(sr: SE_TabWidgetTabPane, opt: twf);
2561 switch (twf->shape) {
2562 case QStyleOptionTab::RoundedNorth:
2563 case QStyleOptionTab::TriangularNorth:
2564 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2565 paneRect.y() - twf->rightCornerWidgetSize.height()),
2566 twf->rightCornerWidgetSize);
2567 break;
2568 case QStyleOptionTab::RoundedSouth:
2569 case QStyleOptionTab::TriangularSouth:
2570 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2571 paneRect.height()), twf->rightCornerWidgetSize);
2572 break;
2573 default:
2574 break;
2575 }
2576 r = visualRect(direction: twf->direction, boundingRect: twf->rect, logicalRect: r);
2577 }
2578 break;
2579 case SE_TabBarTabText:
2580 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2581 QRect dummyIconRect;
2582 d->tabLayout(opt: tab, textRect: &r, iconRect: &dummyIconRect);
2583 }
2584 break;
2585 case SE_TabBarTabLeftButton:
2586 case SE_TabBarTabRightButton:
2587 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2588 bool selected = tab->state & State_Selected;
2589 int verticalShift = proxy()->pixelMetric(metric: QStyle::PM_TabBarTabShiftVertical, option: tab);
2590 int horizontalShift = proxy()->pixelMetric(metric: QStyle::PM_TabBarTabShiftHorizontal, option: tab);
2591 int hpadding = proxy()->pixelMetric(metric: QStyle::PM_TabBarTabHSpace, option: opt) / 2;
2592 hpadding = qMax(a: hpadding, b: 4); //workaround KStyle returning 0 because they workaround an old bug in Qt
2593
2594 bool verticalTabs = tab->shape == QStyleOptionTab::RoundedEast
2595 || tab->shape == QStyleOptionTab::RoundedWest
2596 || tab->shape == QStyleOptionTab::TriangularEast
2597 || tab->shape == QStyleOptionTab::TriangularWest;
2598
2599 QRect tr = tab->rect;
2600 if (tab->shape == QStyleOptionTab::RoundedSouth || tab->shape == QStyleOptionTab::TriangularSouth)
2601 verticalShift = -verticalShift;
2602 if (verticalTabs) {
2603 qSwap(value1&: horizontalShift, value2&: verticalShift);
2604 horizontalShift *= -1;
2605 verticalShift *= -1;
2606 }
2607 if (tab->shape == QStyleOptionTab::RoundedWest || tab->shape == QStyleOptionTab::TriangularWest)
2608 horizontalShift = -horizontalShift;
2609
2610 tr.adjust(dx1: 0, dy1: 0, dx2: horizontalShift, dy2: verticalShift);
2611 if (selected)
2612 {
2613 tr.setBottom(tr.bottom() - verticalShift);
2614 tr.setRight(tr.right() - horizontalShift);
2615 }
2616
2617 QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
2618 int w = size.width();
2619 int h = size.height();
2620 int midHeight = static_cast<int>(qCeil(v: float(tr.height() - h) / 2));
2621 int midWidth = ((tr.width() - w) / 2);
2622
2623 bool atTheTop = true;
2624 switch (tab->shape) {
2625 case QStyleOptionTab::RoundedWest:
2626 case QStyleOptionTab::TriangularWest:
2627 atTheTop = (sr == SE_TabBarTabLeftButton);
2628 break;
2629 case QStyleOptionTab::RoundedEast:
2630 case QStyleOptionTab::TriangularEast:
2631 atTheTop = (sr == SE_TabBarTabRightButton);
2632 break;
2633 default:
2634 if (sr == SE_TabBarTabLeftButton)
2635 r = QRect(tab->rect.x() + hpadding, midHeight, w, h);
2636 else
2637 r = QRect(tab->rect.right() - w - hpadding, midHeight, w, h);
2638 r = visualRect(direction: tab->direction, boundingRect: tab->rect, logicalRect: r);
2639 }
2640 if (verticalTabs) {
2641 if (atTheTop)
2642 r = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h);
2643 else
2644 r = QRect(midWidth, tr.y() + hpadding, w, h);
2645 }
2646 }
2647
2648 break;
2649 case SE_TabBarTearIndicator:
2650 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2651 switch (tab->shape) {
2652 case QStyleOptionTab::RoundedNorth:
2653 case QStyleOptionTab::TriangularNorth:
2654 case QStyleOptionTab::RoundedSouth:
2655 case QStyleOptionTab::TriangularSouth:
2656 r.setRect(ax: tab->rect.left(), ay: tab->rect.top(), aw: 8, ah: opt->rect.height());
2657 break;
2658 case QStyleOptionTab::RoundedWest:
2659 case QStyleOptionTab::TriangularWest:
2660 case QStyleOptionTab::RoundedEast:
2661 case QStyleOptionTab::TriangularEast:
2662 r.setRect(ax: tab->rect.left(), ay: tab->rect.top(), aw: opt->rect.width(), ah: 8);
2663 break;
2664 default:
2665 break;
2666 }
2667 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2668 }
2669 break;
2670 case SE_TabBarScrollLeftButton: {
2671 const bool vertical = opt->rect.width() < opt->rect.height();
2672 const Qt::LayoutDirection ld = opt->direction;
2673 const int buttonWidth = proxy()->pixelMetric(metric: QStyle::PM_TabBarScrollButtonWidth, option: nullptr);
2674 const int buttonOverlap = proxy()->pixelMetric(metric: QStyle::PM_TabBar_ScrollButtonOverlap, option: nullptr);
2675
2676 r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth)
2677 : QStyle::visualRect(direction: ld, boundingRect: opt->rect, logicalRect: QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height()));
2678 break; }
2679 case SE_TabBarScrollRightButton: {
2680 const bool vertical = opt->rect.width() < opt->rect.height();
2681 const Qt::LayoutDirection ld = opt->direction;
2682 const int buttonWidth = proxy()->pixelMetric(metric: QStyle::PM_TabBarScrollButtonWidth, option: nullptr);
2683
2684 r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth)
2685 : QStyle::visualRect(direction: ld, boundingRect: opt->rect, logicalRect: QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()));
2686 break; }
2687 case SE_TreeViewDisclosureItem:
2688 r = opt->rect;
2689 break;
2690 case SE_LineEditContents:
2691 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2692 r = f->rect.adjusted(xp1: f->lineWidth, yp1: f->lineWidth, xp2: -f->lineWidth, yp2: -f->lineWidth);
2693 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2694 }
2695 break;
2696 case SE_FrameContents:
2697 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2698 int fw = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: f);
2699 r = opt->rect.adjusted(xp1: fw, yp1: fw, xp2: -fw, yp2: -fw);
2700 r = visualRect(direction: opt->direction, boundingRect: opt->rect, logicalRect: r);
2701 }
2702 break;
2703 case SE_ShapedFrameContents:
2704 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2705 int frameShape = f->frameShape;
2706 int frameShadow = QStyleOptionFrame::Plain;
2707 if (f->state & QStyle::State_Sunken) {
2708 frameShadow = QStyleOptionFrame::Sunken;
2709 } else if (f->state & QStyle::State_Raised) {
2710 frameShadow = QStyleOptionFrame::Raised;
2711 }
2712
2713 int frameWidth = 0;
2714
2715 switch (frameShape) {
2716 case QStyleOptionFrame::NoFrame:
2717 frameWidth = 0;
2718 break;
2719
2720 case QStyleOptionFrame::Box:
2721 case QStyleOptionFrame::HLine:
2722 case QStyleOptionFrame::VLine:
2723 switch (frameShadow) {
2724 case QStyleOptionFrame::Plain:
2725 frameWidth = f->lineWidth;
2726 break;
2727 case QStyleOptionFrame::Raised:
2728 case QStyleOptionFrame::Sunken:
2729 frameWidth = (short)(f->lineWidth*2 + f->midLineWidth);
2730 break;
2731 }
2732 break;
2733
2734 case QStyleOptionFrame::StyledPanel:
2735 //keep the compatibility with Qt 4.4 if there is a proxy style.
2736 //be sure to call drawPrimitive(QStyle::SE_FrameContents) on the proxy style
2737 return subElementRect(sr: QStyle::SE_FrameContents, opt);
2738
2739 case QStyleOptionFrame::WinPanel:
2740 frameWidth = 2;
2741 break;
2742
2743 case QStyleOptionFrame::Panel:
2744 switch (frameShadow) {
2745 case QStyleOptionFrame::Plain:
2746 case QStyleOptionFrame::Raised:
2747 case QStyleOptionFrame::Sunken:
2748 frameWidth = f->lineWidth;
2749 break;
2750 }
2751 break;
2752 }
2753 r = f->rect.adjusted(xp1: frameWidth, yp1: frameWidth, xp2: -frameWidth, yp2: -frameWidth);
2754 }
2755 break;
2756 case SE_DockWidgetCloseButton:
2757 case SE_DockWidgetFloatButton:
2758 case SE_DockWidgetTitleBarText:
2759 case SE_DockWidgetIcon: {
2760 int iconSize = proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt);
2761 int buttonMargin = proxy()->pixelMetric(metric: PM_DockWidgetTitleBarButtonMargin, option: opt);
2762 QRect rect = opt->rect;
2763
2764 const QStyleOptionDockWidget *dwOpt
2765 = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
2766 bool canClose = dwOpt == nullptr ? true : dwOpt->closable;
2767 bool canFloat = dwOpt == nullptr ? false : dwOpt->floatable;
2768
2769 const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
2770
2771 // If this is a vertical titlebar, we transpose and work as if it was
2772 // horizontal, then transpose again.
2773
2774 if (verticalTitleBar)
2775 rect = rect.transposed();
2776
2777 do {
2778 int right = rect.right();
2779 int left = rect.left();
2780
2781 QRect closeRect;
2782 if (canClose) {
2783 QSize sz = proxy()->standardIcon(standardIcon: QStyle::SP_TitleBarCloseButton,
2784 option: opt).actualSize(size: QSize(iconSize, iconSize));
2785 sz += QSize(buttonMargin, buttonMargin);
2786 if (verticalTitleBar)
2787 sz = sz.transposed();
2788 closeRect = QRect(right - sz.width(),
2789 rect.center().y() - sz.height()/2,
2790 sz.width(), sz.height());
2791 right = closeRect.left() - 1;
2792 }
2793 if (sr == SE_DockWidgetCloseButton) {
2794 r = closeRect;
2795 break;
2796 }
2797
2798 QRect floatRect;
2799 if (canFloat) {
2800 QSize sz = proxy()->standardIcon(standardIcon: QStyle::SP_TitleBarNormalButton,
2801 option: opt).actualSize(size: QSize(iconSize, iconSize));
2802 sz += QSize(buttonMargin, buttonMargin);
2803 if (verticalTitleBar)
2804 sz = sz.transposed();
2805 floatRect = QRect(right - sz.width(),
2806 rect.center().y() - sz.height()/2,
2807 sz.width(), sz.height());
2808 right = floatRect.left() - 1;
2809 }
2810 if (sr == SE_DockWidgetFloatButton) {
2811 r = floatRect;
2812 break;
2813 }
2814
2815 QRect iconRect;
2816 if (sr == SE_DockWidgetIcon) {
2817 r = iconRect;
2818 break;
2819 }
2820
2821 QRect textRect = QRect(left, rect.top(),
2822 right - left, rect.height());
2823 if (sr == SE_DockWidgetTitleBarText) {
2824 r = textRect;
2825 break;
2826 }
2827
2828 } while (false);
2829
2830 if (verticalTitleBar) {
2831 r = QRect(rect.left() + r.top() - rect.top(),
2832 rect.top() + rect.right() - r.right(),
2833 r.height(), r.width());
2834 } else {
2835 r = visualRect(direction: opt->direction, boundingRect: rect, logicalRect: r);
2836 }
2837 break;
2838 }
2839#if QT_CONFIG(quick_itemview)
2840 case SE_ItemViewItemCheckIndicator:
2841 if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
2842 r = subElementRect(sr: SE_CheckBoxIndicator, opt);
2843 break;
2844 }
2845 Q_FALLTHROUGH();
2846 case SE_ItemViewItemDecoration:
2847 case SE_ItemViewItemText:
2848 case SE_ItemViewItemFocusRect:
2849 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
2850 if (!d->isViewItemCached(option: *vopt)) {
2851 d->viewItemLayout(opt: vopt, checkRect: &d->checkRect, pixmapRect: &d->decorationRect, textRect: &d->displayRect, sizehint: false);
2852 if (d->cachedOption) {
2853 delete d->cachedOption;
2854 d->cachedOption = nullptr;
2855 }
2856 d->cachedOption = new QStyleOptionViewItem(*vopt);
2857 }
2858 if (sr == SE_ItemViewItemCheckIndicator)
2859 r = d->checkRect;
2860 else if (sr == SE_ItemViewItemDecoration)
2861 r = d->decorationRect;
2862 else if (sr == SE_ItemViewItemText || sr == SE_ItemViewItemFocusRect)
2863 r = d->displayRect;
2864 }
2865 break;
2866#endif // QT_CONFIG(quick_itemview)
2867 case SE_ToolBarHandle:
2868 if (const QStyleOptionToolBar *tbopt = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
2869 if (tbopt->features & QStyleOptionToolBar::Movable) {
2870 ///we need to access the widget here because the style option doesn't
2871 //have all the information we need (ie. the layout's margin)
2872 const QMargins margins(2, 2, 2, 2);
2873 const int handleExtent = proxy()->pixelMetric(metric: QStyle::PM_ToolBarHandleExtent, option: opt);
2874 if (tbopt->state & QStyle::State_Horizontal) {
2875 r = QRect(margins.left(), margins.top(),
2876 handleExtent,
2877 tbopt->rect.height() - (margins.top() + margins.bottom()));
2878 r = QStyle::visualRect(direction: tbopt->direction, boundingRect: tbopt->rect, logicalRect: r);
2879 } else {
2880 r = QRect(margins.left(), margins.top(),
2881 tbopt->rect.width() - (margins.left() + margins.right()),
2882 handleExtent);
2883 }
2884 }
2885 }
2886 break;
2887 default:
2888 break;
2889 }
2890 return r;
2891}
2892
2893// in lieu of std::array, minimal API
2894template <int N>
2895struct StaticPolygonF
2896{
2897 QPointF data[N];
2898
2899 Q_DECL_CONSTEXPR int size() const { return N; }
2900 Q_DECL_CONSTEXPR const QPointF *cbegin() const { return data; }
2901 Q_DECL_CONSTEXPR const QPointF &operator[](int idx) const { return data[idx]; }
2902};
2903
2904static StaticPolygonF<3> calcArrow(const QStyleOptionSlider *dial, qreal &a)
2905{
2906 int width = dial->rect.width();
2907 int height = dial->rect.height();
2908 int r = qMin(a: width, b: height) / 2;
2909 int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
2910
2911 qreal startAngle = (90. - dial->startAngle) * Q_PI / 180.;
2912 qreal spanAngle = (dial->endAngle - dial->startAngle) * Q_PI / 180.;
2913 if (dial->maximum == dial->minimum)
2914 a = Q_PI / 2;
2915 else
2916 a = (startAngle - (currentSliderPosition - dial->minimum) * spanAngle
2917 / (dial->maximum - dial->minimum));
2918
2919 int xc = width / 2;
2920 int yc = height / 2;
2921
2922 int len = r - QStyleHelper::calcBigLineSize(radius: r) - 5;
2923 if (len < 5)
2924 len = 5;
2925 int back = len / 2;
2926
2927 StaticPolygonF<3> arrow = {.data: {
2928 QPointF(0.5 + xc + len * qCos(v: a),
2929 0.5 + yc - len * qSin(v: a)),
2930 QPointF(0.5 + xc + back * qCos(v: a + Q_PI * 5 / 6),
2931 0.5 + yc - back * qSin(v: a + Q_PI * 5 / 6)),
2932 QPointF(0.5 + xc + back * qCos(v: a - Q_PI * 5 / 6),
2933 0.5 + yc - back * qSin(v: a - Q_PI * 5 / 6)),
2934 }};
2935 return arrow;
2936}
2937
2938void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const
2939{
2940 switch (cc) {
2941 case CC_Slider:
2942 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2943 if (slider->subControls == SC_SliderTickmarks) {
2944 int tickOffset = proxy()->pixelMetric(metric: PM_SliderTickmarkOffset, option: slider);
2945 int ticks = slider->tickPosition;
2946 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: slider);
2947 int len = proxy()->pixelMetric(metric: PM_SliderLength, option: slider);
2948 int available = proxy()->pixelMetric(metric: PM_SliderSpaceAvailable, option: slider);
2949 int interval = slider->tickInterval;
2950 if (interval <= 0) {
2951 interval = slider->singleStep;
2952 if (QStyle::sliderPositionFromValue(min: slider->minimum, max: slider->maximum, val: interval,
2953 space: available)
2954 - QStyle::sliderPositionFromValue(min: slider->minimum, max: slider->maximum,
2955 val: 0, space: available) < 3)
2956 interval = slider->pageStep;
2957 }
2958 if (!interval)
2959 interval = 1;
2960 int fudge = len / 2;
2961 int pos;
2962 // Since there is no subrect for tickmarks do a translation here.
2963 p->save();
2964 p->translate(dx: slider->rect.x(), dy: slider->rect.y());
2965 p->setPen(slider->palette.windowText().color());
2966 int v = slider->minimum;
2967 while (v <= slider->maximum + 1) {
2968 if (v == slider->maximum + 1 && interval == 1)
2969 break;
2970 const int v_ = qMin(a: v, b: slider->maximum);
2971 pos = QStyle::sliderPositionFromValue(min: slider->minimum, max: slider->maximum,
2972 val: v_, space: available) + fudge;
2973 if (slider->orientation == Qt::Horizontal) {
2974 if (ticks & QStyleOptionSlider::TicksAbove)
2975 p->drawLine(x1: pos, y1: 0, x2: pos, y2: tickOffset - 2);
2976 if (ticks & QStyleOptionSlider::TicksBelow)
2977 p->drawLine(x1: pos, y1: tickOffset + thickness + 1, x2: pos,
2978 y2: slider->rect.height()-1);
2979 } else {
2980 if (ticks & QStyleOptionSlider::TicksAbove)
2981 p->drawLine(x1: 0, y1: pos, x2: tickOffset - 2, y2: pos);
2982 if (ticks & QStyleOptionSlider::TicksBelow)
2983 p->drawLine(x1: tickOffset + thickness + 1, y1: pos,
2984 x2: slider->rect.width()-1, y2: pos);
2985 }
2986 // in the case where maximum is max int
2987 int nextInterval = v + interval;
2988 if (nextInterval < v)
2989 break;
2990 v = nextInterval;
2991 }
2992 p->restore();
2993 }
2994 }
2995 break;
2996 case CC_ScrollBar:
2997 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2998 // Make a copy here and reset it for each primitive.
2999 QStyleOptionSlider newScrollbar = *scrollbar;
3000 State saveFlags = scrollbar->state;
3001
3002 if (scrollbar->subControls & SC_ScrollBarSubLine) {
3003 newScrollbar.state = saveFlags;
3004 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarSubLine);
3005 if (newScrollbar.rect.isValid()) {
3006 if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
3007 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3008 proxy()->drawControl(element: CE_ScrollBarSubLine, opt: &newScrollbar, p);
3009 }
3010 }
3011 if (scrollbar->subControls & SC_ScrollBarAddLine) {
3012 newScrollbar.rect = scrollbar->rect;
3013 newScrollbar.state = saveFlags;
3014 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarAddLine);
3015 if (newScrollbar.rect.isValid()) {
3016 if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
3017 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3018 proxy()->drawControl(element: CE_ScrollBarAddLine, opt: &newScrollbar, p);
3019 }
3020 }
3021 if (scrollbar->subControls & SC_ScrollBarSubPage) {
3022 newScrollbar.rect = scrollbar->rect;
3023 newScrollbar.state = saveFlags;
3024 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarSubPage);
3025 if (newScrollbar.rect.isValid()) {
3026 if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage))
3027 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3028 proxy()->drawControl(element: CE_ScrollBarSubPage, opt: &newScrollbar, p);
3029 }
3030 }
3031 if (scrollbar->subControls & SC_ScrollBarAddPage) {
3032 newScrollbar.rect = scrollbar->rect;
3033 newScrollbar.state = saveFlags;
3034 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarAddPage);
3035 if (newScrollbar.rect.isValid()) {
3036 if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage))
3037 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3038 proxy()->drawControl(element: CE_ScrollBarAddPage, opt: &newScrollbar, p);
3039 }
3040 }
3041 if (scrollbar->subControls & SC_ScrollBarFirst) {
3042 newScrollbar.rect = scrollbar->rect;
3043 newScrollbar.state = saveFlags;
3044 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarFirst);
3045 if (newScrollbar.rect.isValid()) {
3046 if (!(scrollbar->activeSubControls & SC_ScrollBarFirst))
3047 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3048 proxy()->drawControl(element: CE_ScrollBarFirst, opt: &newScrollbar, p);
3049 }
3050 }
3051 if (scrollbar->subControls & SC_ScrollBarLast) {
3052 newScrollbar.rect = scrollbar->rect;
3053 newScrollbar.state = saveFlags;
3054 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarLast);
3055 if (newScrollbar.rect.isValid()) {
3056 if (!(scrollbar->activeSubControls & SC_ScrollBarLast))
3057 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3058 proxy()->drawControl(element: CE_ScrollBarLast, opt: &newScrollbar, p);
3059 }
3060 }
3061 if (scrollbar->subControls & SC_ScrollBarSlider) {
3062 newScrollbar.rect = scrollbar->rect;
3063 newScrollbar.state = saveFlags;
3064 newScrollbar.rect = proxy()->subControlRect(cc, opt: &newScrollbar, sc: SC_ScrollBarSlider);
3065 if (newScrollbar.rect.isValid()) {
3066 if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
3067 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3068 proxy()->drawControl(element: CE_ScrollBarSlider, opt: &newScrollbar, p);
3069
3070 if (scrollbar->state & State_HasFocus) {
3071 QStyleOptionFocusRect fropt;
3072 fropt.QStyleOption::operator=(other: newScrollbar);
3073 fropt.rect.setRect(ax: newScrollbar.rect.x() + 2, ay: newScrollbar.rect.y() + 2,
3074 aw: newScrollbar.rect.width() - 5,
3075 ah: newScrollbar.rect.height() - 5);
3076 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p);
3077 }
3078 }
3079 }
3080 }
3081 break;
3082 case CC_SpinBox:
3083 if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
3084 QStyleOptionSpinBox copy = *sb;
3085 PrimitiveElement pe;
3086
3087 if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
3088 QRect r = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxFrame);
3089 qDrawWinPanel(p, r, pal: sb->palette, sunken: true);
3090 }
3091
3092 if (sb->subControls & SC_SpinBoxUp) {
3093 copy.subControls = SC_SpinBoxUp;
3094 QPalette pal2 = sb->palette;
3095 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepUpEnabled)) {
3096 pal2.setCurrentColorGroup(QPalette::Disabled);
3097 copy.state &= ~State_Enabled;
3098 }
3099
3100 copy.palette = pal2;
3101
3102 if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
3103 copy.state |= State_On;
3104 copy.state |= State_Sunken;
3105 } else {
3106 copy.state |= State_Raised;
3107 copy.state &= ~State_Sunken;
3108 }
3109 pe = (sb->buttonSymbols == QStyleOptionSpinBox::PlusMinus ? PE_IndicatorSpinPlus
3110 : PE_IndicatorSpinUp);
3111
3112 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxUp);
3113 proxy()->drawPrimitive(pe: PE_PanelButtonBevel, opt: &copy, p);
3114 copy.rect.adjust(dx1: 3, dy1: 0, dx2: -4, dy2: 0);
3115 proxy()->drawPrimitive(pe, opt: &copy, p);
3116 }
3117
3118 if (sb->subControls & SC_SpinBoxDown) {
3119 copy.subControls = SC_SpinBoxDown;
3120 copy.state = sb->state;
3121 QPalette pal2 = sb->palette;
3122 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepDownEnabled)) {
3123 pal2.setCurrentColorGroup(QPalette::Disabled);
3124 copy.state &= ~State_Enabled;
3125 }
3126 copy.palette = pal2;
3127
3128 if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
3129 copy.state |= State_On;
3130 copy.state |= State_Sunken;
3131 } else {
3132 copy.state |= State_Raised;
3133 copy.state &= ~State_Sunken;
3134 }
3135 pe = (sb->buttonSymbols == QStyleOptionSpinBox::PlusMinus ? PE_IndicatorSpinMinus
3136 : PE_IndicatorSpinDown);
3137
3138 copy.rect = proxy()->subControlRect(cc: CC_SpinBox, opt: sb, sc: SC_SpinBoxDown);
3139 proxy()->drawPrimitive(pe: PE_PanelButtonBevel, opt: &copy, p);
3140 copy.rect.adjust(dx1: 3, dy1: 0, dx2: -4, dy2: 0);
3141 proxy()->drawPrimitive(pe, opt: &copy, p);
3142 }
3143 }
3144 break;
3145 case CC_ToolButton:
3146 if (const QStyleOptionToolButton *toolbutton
3147 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3148 QRect button, menuarea;
3149 button = proxy()->subControlRect(cc, opt: toolbutton, sc: SC_ToolButton);
3150 menuarea = proxy()->subControlRect(cc, opt: toolbutton, sc: SC_ToolButtonMenu);
3151
3152 State bflags = toolbutton->state & ~State_Sunken;
3153
3154 if (bflags & State_AutoRaise) {
3155 if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
3156 bflags &= ~State_Raised;
3157 }
3158 }
3159 State mflags = bflags;
3160 if (toolbutton->state & State_Sunken) {
3161 if (toolbutton->activeSubControls & SC_ToolButton)
3162 bflags |= State_Sunken;
3163 mflags |= State_Sunken;
3164 }
3165
3166 QStyleOption tool = *toolbutton;
3167 if (toolbutton->subControls & SC_ToolButton) {
3168 if (bflags & (State_Sunken | State_On | State_Raised)) {
3169 tool.rect = button;
3170 tool.state = bflags;
3171 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3172 }
3173 }
3174
3175 if (toolbutton->state & State_HasFocus) {
3176 QStyleOptionFocusRect fr;
3177 fr.QStyleOption::operator=(other: *toolbutton);
3178 fr.rect.adjust(dx1: 3, dy1: 3, dx2: -3, dy2: -3);
3179 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
3180 fr.rect.adjust(dx1: 0, dy1: 0, dx2: -proxy()->pixelMetric(metric: QStyle::PM_MenuButtonIndicator,
3181 option: toolbutton), dy2: 0);
3182 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fr, p);
3183 }
3184 QStyleOptionToolButton label = *toolbutton;
3185 label.state = bflags;
3186 int fw = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: opt);
3187 label.rect = button.adjusted(xp1: fw, yp1: fw, xp2: -fw, yp2: -fw);
3188 proxy()->drawControl(element: CE_ToolButtonLabel, opt: &label, p);
3189
3190 if (toolbutton->subControls & SC_ToolButtonMenu) {
3191 tool.rect = menuarea;
3192 tool.state = mflags;
3193 if (mflags & (State_Sunken | State_On | State_Raised))
3194 proxy()->drawPrimitive(pe: PE_IndicatorButtonDropDown, opt: &tool, p);
3195 proxy()->drawPrimitive(pe: PE_IndicatorArrowDown, opt: &tool, p);
3196 } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
3197 int mbi = proxy()->pixelMetric(metric: PM_MenuButtonIndicator, option: toolbutton);
3198 QRect ir = toolbutton->rect;
3199 QStyleOptionToolButton newBtn = *toolbutton;
3200 newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6);
3201 newBtn.rect = visualRect(direction: toolbutton->direction, boundingRect: button, logicalRect: newBtn.rect);
3202 proxy()->drawPrimitive(pe: PE_IndicatorArrowDown, opt: &newBtn, p);
3203 }
3204 }
3205 break;
3206 case CC_TitleBar:
3207 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
3208 QRect ir;
3209 if (opt->subControls & SC_TitleBarLabel) {
3210 QColor left = tb->palette.highlight().color();
3211 QColor right = tb->palette.base().color();
3212
3213 QBrush fillBrush(left);
3214 if (left != right) {
3215 QPoint p1(tb->rect.x(), tb->rect.top() + tb->rect.height()/2);
3216 QPoint p2(tb->rect.right(), tb->rect.top() + tb->rect.height()/2);
3217 QLinearGradient lg(p1, p2);
3218 lg.setColorAt(pos: 0, color: left);
3219 lg.setColorAt(pos: 1, color: right);
3220 fillBrush = lg;
3221 }
3222
3223 p->fillRect(opt->rect, fillBrush);
3224
3225 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarLabel);
3226
3227 p->setPen(tb->palette.highlightedText().color());
3228 p->drawText(x: ir.x() + 2, y: ir.y(), w: ir.width() - 2, h: ir.height(),
3229 flags: Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, str: tb->text);
3230 }
3231
3232 bool down = false;
3233 QPixmap pm;
3234
3235 QStyleOption tool = *tb;
3236 if (tb->subControls & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3237 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarCloseButton);
3238 down = tb->activeSubControls & SC_TitleBarCloseButton && (opt->state & State_Sunken);
3239 if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
3240 pm = proxy()->standardIcon(standardIcon: SP_DockWidgetCloseButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3241 else
3242 pm = proxy()->standardIcon(standardIcon: SP_TitleBarCloseButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3243 tool.rect = ir;
3244 tool.state = down ? State_Sunken : State_Raised;
3245 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3246
3247 p->save();
3248 if (down)
3249 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3250 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3251 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3252 p->restore();
3253 }
3254
3255 if (tb->subControls & SC_TitleBarMaxButton
3256 && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
3257 && !(tb->titleBarState & Qt::WindowMaximized)) {
3258 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarMaxButton);
3259
3260 down = tb->activeSubControls & SC_TitleBarMaxButton && (opt->state & State_Sunken);
3261 pm = proxy()->standardIcon(standardIcon: SP_TitleBarMaxButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3262 tool.rect = ir;
3263 tool.state = down ? State_Sunken : State_Raised;
3264 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3265
3266 p->save();
3267 if (down)
3268 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3269 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3270 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3271 p->restore();
3272 }
3273
3274 if (tb->subControls & SC_TitleBarMinButton
3275 && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
3276 && !(tb->titleBarState & Qt::WindowMinimized)) {
3277 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarMinButton);
3278 down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken);
3279 pm = proxy()->standardIcon(standardIcon: SP_TitleBarMinButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3280 tool.rect = ir;
3281 tool.state = down ? State_Sunken : State_Raised;
3282 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3283
3284 p->save();
3285 if (down)
3286 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3287 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3288 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3289 p->restore();
3290 }
3291
3292 bool drawNormalButton = (tb->subControls & SC_TitleBarNormalButton)
3293 && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3294 && (tb->titleBarState & Qt::WindowMinimized))
3295 || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3296 && (tb->titleBarState & Qt::WindowMaximized)));
3297
3298 if (drawNormalButton) {
3299 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarNormalButton);
3300 down = tb->activeSubControls & SC_TitleBarNormalButton && (opt->state & State_Sunken);
3301 pm = proxy()->standardIcon(standardIcon: SP_TitleBarNormalButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3302 tool.rect = ir;
3303 tool.state = down ? State_Sunken : State_Raised;
3304 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3305
3306 p->save();
3307 if (down)
3308 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3309 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3310 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3311 p->restore();
3312 }
3313
3314 if (tb->subControls & SC_TitleBarShadeButton
3315 && tb->titleBarFlags & Qt::WindowShadeButtonHint
3316 && !(tb->titleBarState & Qt::WindowMinimized)) {
3317 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarShadeButton);
3318 down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken));
3319 pm = proxy()->standardIcon(standardIcon: SP_TitleBarShadeButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3320 tool.rect = ir;
3321 tool.state = down ? State_Sunken : State_Raised;
3322 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3323 p->save();
3324 if (down)
3325 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3326 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3327 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3328 p->restore();
3329 }
3330
3331 if (tb->subControls & SC_TitleBarUnshadeButton
3332 && tb->titleBarFlags & Qt::WindowShadeButtonHint
3333 && tb->titleBarState & Qt::WindowMinimized) {
3334 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarUnshadeButton);
3335
3336 down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken);
3337 pm = proxy()->standardIcon(standardIcon: SP_TitleBarUnshadeButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3338 tool.rect = ir;
3339 tool.state = down ? State_Sunken : State_Raised;
3340 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3341 p->save();
3342 if (down)
3343 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3344 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3345 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3346 p->restore();
3347 }
3348 if (tb->subControls & SC_TitleBarContextHelpButton
3349 && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
3350 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarContextHelpButton);
3351
3352 down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken);
3353 pm = proxy()->standardIcon(standardIcon: SP_TitleBarContextHelpButton, option: &tool).pixmap(size: QSize(10, 10), devicePixelRatio: dpr(w: opt->window));
3354 tool.rect = ir;
3355 tool.state = down ? State_Sunken : State_Raised;
3356 proxy()->drawPrimitive(pe: PE_PanelButtonTool, opt: &tool, p);
3357 p->save();
3358 if (down)
3359 p->translate(dx: proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal, option: tb),
3360 dy: proxy()->pixelMetric(metric: PM_ButtonShiftVertical, option: tb));
3361 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3362 p->restore();
3363 }
3364 if (tb->subControls & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3365 ir = proxy()->subControlRect(cc: CC_TitleBar, opt: tb, sc: SC_TitleBarSysMenu);
3366 if (!tb->icon.isNull()) {
3367 tb->icon.paint(painter: p, rect: ir);
3368 } else {
3369 int iconSize = proxy()->pixelMetric(metric: PM_SmallIconSize, option: tb);
3370 pm = proxy()->standardIcon(standardIcon: SP_TitleBarMenuButton, option: &tool).pixmap(size: QSize(iconSize, iconSize), devicePixelRatio: dpr(w: opt->window));
3371 tool.rect = ir;
3372 p->save();
3373 proxy()->drawItemPixmap(painter: p, rect: ir, alignment: Qt::AlignCenter, pixmap: pm);
3374 p->restore();
3375 }
3376 }
3377 }
3378 break;
3379 case CC_Dial:
3380 if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3381 // OK, this is more a port of things over
3382 p->save();
3383
3384 // avoid dithering
3385 if (p->paintEngine()->hasFeature(feature: QPaintEngine::Antialiasing))
3386 p->setRenderHint(hint: QPainter::Antialiasing);
3387
3388 int width = dial->rect.width();
3389 int height = dial->rect.height();
3390 qreal r = qMin(a: width, b: height) / 2;
3391 qreal d_ = r / 6;
3392 qreal dx = dial->rect.x() + d_ + (width - 2 * r) / 2 + 1;
3393 qreal dy = dial->rect.y() + d_ + (height - 2 * r) / 2 + 1;
3394 QRect br = QRect(int(dx), int(dy), int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2));
3395
3396 QPalette pal = opt->palette;
3397 // draw notches
3398 if (dial->subControls & QStyle::SC_DialTickmarks) {
3399 p->setPen(pal.windowText().color());
3400 p->drawLines(pointPairs: QStyleHelper::calcLines(dial));
3401 }
3402
3403 if (dial->state & State_Enabled) {
3404 p->setBrush(pal.brush(cr: QPalette::ColorRole(proxy()->styleHint(stylehint: SH_Dial_BackgroundRole, opt: dial))));
3405 p->setPen(Qt::NoPen);
3406 p->drawEllipse(r: br);
3407 p->setBrush(Qt::NoBrush);
3408 }
3409 p->setPen(QPen(pal.dark().color()));
3410 p->drawArc(r: br, a: 60 * 16, alen: 180 * 16);
3411 p->setPen(QPen(pal.light().color()));
3412 p->drawArc(r: br, a: 240 * 16, alen: 180 * 16);
3413
3414 qreal a;
3415 const StaticPolygonF<3> arrow = calcArrow(dial, a);
3416
3417 p->setPen(Qt::NoPen);
3418 p->setBrush(pal.button());
3419 p->drawPolygon(points: arrow.cbegin(), pointCount: arrow.size());
3420
3421 a = QStyleHelper::angle(p1: QPointF(width / 2, height / 2), p2: arrow[0]);
3422 p->setBrush(Qt::NoBrush);
3423
3424 if (a <= 0 || a > 200) {
3425 p->setPen(pal.light().color());
3426 p->drawLine(p1: arrow[2], p2: arrow[0]);
3427 p->drawLine(p1: arrow[1], p2: arrow[2]);
3428 p->setPen(pal.dark().color());
3429 p->drawLine(p1: arrow[0], p2: arrow[1]);
3430 } else if (a > 0 && a < 45) {
3431 p->setPen(pal.light().color());
3432 p->drawLine(p1: arrow[2], p2: arrow[0]);
3433 p->setPen(pal.dark().color());
3434 p->drawLine(p1: arrow[1], p2: arrow[2]);
3435 p->drawLine(p1: arrow[0], p2: arrow[1]);
3436 } else if (a >= 45 && a < 135) {
3437 p->setPen(pal.dark().color());
3438 p->drawLine(p1: arrow[2], p2: arrow[0]);
3439 p->drawLine(p1: arrow[1], p2: arrow[2]);
3440 p->setPen(pal.light().color());
3441 p->drawLine(p1: arrow[0], p2: arrow[1]);
3442 } else if (a >= 135 && a < 200) {
3443 p->setPen(pal.dark().color());
3444 p->drawLine(p1: arrow[2], p2: arrow[0]);
3445 p->setPen(pal.light().color());
3446 p->drawLine(p1: arrow[0], p2: arrow[1]);
3447 p->drawLine(p1: arrow[1], p2: arrow[2]);
3448 }
3449
3450 // draw focus rect around the dial
3451 QStyleOptionFocusRect fropt;
3452 fropt.rect = dial->rect;
3453 fropt.state = dial->state;
3454 fropt.palette = dial->palette;
3455 if (fropt.state & QStyle::State_HasFocus) {
3456 br.adjust(dx1: 0, dy1: 0, dx2: 2, dy2: 2);
3457 if (dial->subControls & SC_DialTickmarks) {
3458 int r = qMin(a: width, b: height) / 2;
3459 br.translate(dx: -r / 6, dy: - r / 6);
3460 br.setWidth(br.width() + r / 3);
3461 br.setHeight(br.height() + r / 3);
3462 }
3463 fropt.rect = br.adjusted(xp1: -2, yp1: -2, xp2: 2, yp2: 2);
3464 proxy()->drawPrimitive(pe: QStyle::PE_FrameFocusRect, opt: &fropt, p);
3465 }
3466 p->restore();
3467 }
3468 break;
3469 case CC_GroupBox:
3470 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
3471 // Draw frame
3472 QRect textRect = proxy()->subControlRect(cc: CC_GroupBox, opt, sc: SC_GroupBoxLabel);
3473 QRect checkBoxRect = proxy()->subControlRect(cc: CC_GroupBox, opt, sc: SC_GroupBoxCheckBox);
3474 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
3475 QStyleOptionFrame frame;
3476 frame.QStyleOption::operator=(other: *groupBox);
3477 frame.features = groupBox->features;
3478 frame.lineWidth = groupBox->lineWidth;
3479 frame.midLineWidth = groupBox->midLineWidth;
3480 frame.rect = proxy()->subControlRect(cc: CC_GroupBox, opt, sc: SC_GroupBoxFrame);
3481 p->save();
3482 QRegion region(groupBox->rect);
3483 if (!groupBox->text.isEmpty()) {
3484 bool ltr = groupBox->direction == Qt::LeftToRight;
3485 QRect finalRect;
3486 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
3487 finalRect = checkBoxRect.united(r: textRect);
3488 finalRect.adjust(dx1: ltr ? -4 : 0, dy1: 0, dx2: ltr ? 0 : 4, dy2: 0);
3489 } else {
3490 finalRect = textRect;
3491 }
3492 region -= finalRect;
3493 }
3494 p->setClipRegion(region);
3495 proxy()->drawPrimitive(pe: PE_FrameGroupBox, opt: &frame, p);
3496 p->restore();
3497 }
3498
3499 // Draw title
3500 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
3501 QColor textColor = groupBox->textColor;
3502 if (textColor.isValid())
3503 p->setPen(textColor);
3504 int alignment = int(groupBox->textAlignment);
3505 if (!proxy()->styleHint(stylehint: QStyle::SH_UnderlineShortcut, opt))
3506 alignment |= Qt::TextHideMnemonic;
3507
3508 proxy()->drawItemText(painter: p, rect: textRect, flags: Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
3509 pal: groupBox->palette, enabled: groupBox->state & State_Enabled, text: groupBox->text,
3510 textRole: textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
3511
3512 if (groupBox->state & State_HasFocus) {
3513 QStyleOptionFocusRect fropt;
3514 fropt.QStyleOption::operator=(other: *groupBox);
3515 fropt.rect = textRect;
3516 proxy()->drawPrimitive(pe: PE_FrameFocusRect, opt: &fropt, p);
3517 }
3518 }
3519
3520 // Draw checkbox
3521 if (groupBox->subControls & SC_GroupBoxCheckBox) {
3522 QStyleOptionButton box;
3523 box.QStyleOption::operator=(other: *groupBox);
3524 box.rect = checkBoxRect;
3525 proxy()->drawPrimitive(pe: PE_IndicatorCheckBox, opt: &box, p);
3526 }
3527 }
3528 break;
3529 case CC_MdiControls:
3530 {
3531 QStyleOptionButton btnOpt;
3532 btnOpt.QStyleOption::operator=(other: *opt);
3533 btnOpt.state &= ~State_MouseOver;
3534 int bsx = 0;
3535 int bsy = 0;
3536 const int buttonIconMetric = proxy()->pixelMetric(metric: PM_TitleBarButtonIconSize, option: &btnOpt);
3537 const QSize buttonIconSize(buttonIconMetric, buttonIconMetric);
3538 if (opt->subControls & QStyle::SC_MdiCloseButton) {
3539 if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) {
3540 btnOpt.state |= State_Sunken;
3541 btnOpt.state &= ~State_Raised;
3542 bsx = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal);
3543 bsy = proxy()->pixelMetric(metric: PM_ButtonShiftVertical);
3544 } else {
3545 btnOpt.state |= State_Raised;
3546 btnOpt.state &= ~State_Sunken;
3547 bsx = 0;
3548 bsy = 0;
3549 }
3550 btnOpt.rect = proxy()->subControlRect(cc: CC_MdiControls, opt, sc: SC_MdiCloseButton);
3551 proxy()->drawPrimitive(pe: PE_PanelButtonCommand, opt: &btnOpt, p);
3552 QPixmap pm = proxy()->standardIcon(standardIcon: SP_TitleBarCloseButton).pixmap(size: buttonIconSize, devicePixelRatio: dpr(w: opt->window));
3553 proxy()->drawItemPixmap(painter: p, rect: btnOpt.rect.translated(dx: bsx, dy: bsy), alignment: Qt::AlignCenter, pixmap: pm);
3554 }
3555 if (opt->subControls & QStyle::SC_MdiNormalButton) {
3556 if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) {
3557 btnOpt.state |= State_Sunken;
3558 btnOpt.state &= ~State_Raised;
3559 bsx = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal);
3560 bsy = proxy()->pixelMetric(metric: PM_ButtonShiftVertical);
3561 } else {
3562 btnOpt.state |= State_Raised;
3563 btnOpt.state &= ~State_Sunken;
3564 bsx = 0;
3565 bsy = 0;
3566 }
3567 btnOpt.rect = proxy()->subControlRect(cc: CC_MdiControls, opt, sc: SC_MdiNormalButton);
3568 proxy()->drawPrimitive(pe: PE_PanelButtonCommand, opt: &btnOpt, p);
3569 QPixmap pm = proxy()->standardIcon(standardIcon: SP_TitleBarNormalButton).pixmap(size: buttonIconSize, devicePixelRatio: dpr(w: opt->window));
3570 proxy()->drawItemPixmap(painter: p, rect: btnOpt.rect.translated(dx: bsx, dy: bsy), alignment: Qt::AlignCenter, pixmap: pm);
3571 }
3572 if (opt->subControls & QStyle::SC_MdiMinButton) {
3573 if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) {
3574 btnOpt.state |= State_Sunken;
3575 btnOpt.state &= ~State_Raised;
3576 bsx = proxy()->pixelMetric(metric: PM_ButtonShiftHorizontal);
3577 bsy = proxy()->pixelMetric(metric: PM_ButtonShiftVertical);
3578 } else {
3579 btnOpt.state |= State_Raised;
3580 btnOpt.state &= ~State_Sunken;
3581 bsx = 0;
3582 bsy = 0;
3583 }
3584 btnOpt.rect = proxy()->subControlRect(cc: CC_MdiControls, opt, sc: SC_MdiMinButton);
3585 proxy()->drawPrimitive(pe: PE_PanelButtonCommand, opt: &btnOpt, p);
3586 QPixmap pm = proxy()->standardIcon(standardIcon: SP_TitleBarMinButton).pixmap(size: buttonIconSize, devicePixelRatio: dpr(w: opt->window));
3587 proxy()->drawItemPixmap(painter: p, rect: btnOpt.rect.translated(dx: bsx, dy: bsy), alignment: Qt::AlignCenter, pixmap: pm);
3588 }
3589 }
3590 break;
3591 default:
3592 qWarning(msg: "QCommonStyle::drawComplexControl: Control %d not handled", cc);
3593 }
3594}
3595
3596/*!
3597 \reimp
3598*/
3599QStyle::SubControl QCommonStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const
3600{
3601 SubControl sc = SC_None;
3602 switch (cc) {
3603 case CC_Slider:
3604 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3605 QRect r = proxy()->subControlRect(cc, opt: slider, sc: SC_SliderHandle);
3606 if (r.isValid() && r.contains(p: pt)) {
3607 sc = SC_SliderHandle;
3608 } else {
3609 r = proxy()->subControlRect(cc, opt: slider, sc: SC_SliderGroove);
3610 if (r.isValid() && r.contains(p: pt))
3611 sc = SC_SliderGroove;
3612 }
3613 }
3614 break;
3615 case CC_ScrollBar:
3616 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3617 QRect r;
3618 uint ctrl = SC_ScrollBarAddLine;
3619 while (ctrl <= SC_ScrollBarGroove) {
3620 r = proxy()->subControlRect(cc, opt: scrollbar, sc: QStyle::SubControl(ctrl));
3621 if (r.isValid() && r.contains(p: pt)) {
3622 sc = QStyle::SubControl(ctrl);
3623 break;
3624 }
3625 ctrl <<= 1;
3626 }
3627 }
3628 break;
3629 case CC_ToolButton:
3630 if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3631 QRect r;
3632 uint ctrl = SC_ToolButton;
3633 while (ctrl <= SC_ToolButtonMenu) {
3634 r = proxy()->subControlRect(cc, opt: toolbutton, sc: QStyle::SubControl(ctrl));
3635 if (r.isValid() && r.contains(p: pt)) {
3636 sc = QStyle::SubControl(ctrl);
3637 break;
3638 }
3639 ctrl <<= 1;
3640 }
3641 }
3642 break;
3643 case CC_SpinBox:
3644 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
3645 QRect r;
3646 uint ctrl = SC_SpinBoxUp;
3647 while (ctrl <= SC_SpinBoxEditField) {
3648 r = proxy()->subControlRect(cc, opt: spinbox, sc: QStyle::SubControl(ctrl));
3649 if (r.isValid() && r.contains(p: pt)) {
3650 sc = QStyle::SubControl(ctrl);
3651 break;
3652 }
3653 ctrl <<= 1;
3654 }
3655 }
3656 break;
3657 case CC_TitleBar:
3658 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
3659 QRect r;
3660 uint ctrl = SC_TitleBarSysMenu;
3661
3662 while (ctrl <= SC_TitleBarLabel) {
3663 r = proxy()->subControlRect(cc, opt: tb, sc: QStyle::SubControl(ctrl));
3664 if (r.isValid() && r.contains(p: pt)) {
3665 sc = QStyle::SubControl(ctrl);
3666 break;
3667 }
3668 ctrl <<= 1;
3669 }
3670 }
3671 break;
3672 case CC_ComboBox:
3673 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
3674 QRect r;
3675 uint ctrl = SC_ComboBoxArrow; // Start here and go down.
3676 while (ctrl > 0) {
3677 r = proxy()->subControlRect(cc, opt: cb, sc: QStyle::SubControl(ctrl));
3678 if (r.isValid() && r.contains(p: pt)) {
3679 sc = QStyle::SubControl(ctrl);
3680 break;
3681 }
3682 ctrl >>= 1;
3683 }
3684 }
3685 break;
3686 case CC_GroupBox:
3687 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
3688 QRect r;
3689 uint ctrl = SC_GroupBoxCheckBox;
3690 while (ctrl <= SC_GroupBoxFrame) {
3691 r = proxy()->subControlRect(cc, opt: groupBox, sc: QStyle::SubControl(ctrl));
3692 if (r.isValid() && r.contains(p: pt)) {
3693 sc = QStyle::SubControl(ctrl);
3694 break;
3695 }
3696 ctrl <<= 1;
3697 }
3698 }
3699 break;
3700 case CC_MdiControls:
3701 {
3702 QRect r;
3703 uint ctrl = SC_MdiMinButton;
3704 while (ctrl <= SC_MdiCloseButton) {
3705 r = proxy()->subControlRect(cc: CC_MdiControls, opt, sc: QStyle::SubControl(ctrl));
3706 if (r.isValid() && r.contains(p: pt) && (opt->subControls & ctrl)) {
3707 sc = QStyle::SubControl(ctrl);
3708 return sc;
3709 }
3710 ctrl <<= 1;
3711 }
3712 }
3713 break;
3714 default:
3715 qWarning(msg: "QCommonStyle::hitTestComplexControl: Case %d not handled", cc);
3716 }
3717 return sc;
3718}
3719
3720/*!
3721 \reimp
3722*/
3723QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const
3724{
3725 QRect ret;
3726 switch (cc) {
3727 case CC_Slider:
3728 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3729 int tickOffset = proxy()->pixelMetric(metric: PM_SliderTickmarkOffset, option: slider);
3730 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: slider);
3731
3732 switch (sc) {
3733 case SC_SliderHandle: {
3734 int sliderPos = 0;
3735 int len = proxy()->pixelMetric(metric: PM_SliderLength, option: slider);
3736 bool horizontal = slider->orientation == Qt::Horizontal;
3737 sliderPos = sliderPositionFromValue(min: slider->minimum, max: slider->maximum,
3738 val: slider->sliderPosition,
3739 space: (horizontal ? slider->rect.width()
3740 : slider->rect.height()) - len,
3741 upsideDown: slider->upsideDown);
3742 if (horizontal)
3743 ret.setRect(ax: slider->rect.x() + sliderPos, ay: slider->rect.y() + tickOffset, aw: len, ah: thickness);
3744 else
3745 ret.setRect(ax: slider->rect.x() + tickOffset, ay: slider->rect.y() + sliderPos, aw: thickness, ah: len);
3746 break; }
3747 case SC_SliderGroove:
3748 if (slider->orientation == Qt::Horizontal)
3749 ret.setRect(ax: slider->rect.x(), ay: slider->rect.y() + tickOffset,
3750 aw: slider->rect.width(), ah: thickness);
3751 else
3752 ret.setRect(ax: slider->rect.x() + tickOffset, ay: slider->rect.y(),
3753 aw: thickness, ah: slider->rect.height());
3754 break;
3755 default:
3756 break;
3757 }
3758 ret = visualRect(direction: slider->direction, boundingRect: slider->rect, logicalRect: ret);
3759 }
3760 break;
3761 case CC_ScrollBar:
3762 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3763 const QRect scrollBarRect = scrollbar->rect;
3764 int sbextent = 0;
3765 if (!proxy()->styleHint(stylehint: SH_ScrollBar_Transient, opt: scrollbar))
3766 sbextent = proxy()->pixelMetric(metric: PM_ScrollBarExtent, option: scrollbar);
3767 int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
3768 scrollBarRect.width() : scrollBarRect.height()) - (sbextent * 2);
3769 int sliderlen;
3770
3771 // calculate slider length
3772 if (scrollbar->maximum != scrollbar->minimum) {
3773 uint range = scrollbar->maximum - scrollbar->minimum;
3774 sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep);
3775
3776 int slidermin = proxy()->pixelMetric(metric: PM_ScrollBarSliderMin, option: scrollbar);
3777 if (sliderlen < slidermin || range > INT_MAX / 2)
3778 sliderlen = slidermin;
3779 if (sliderlen > maxlen)
3780 sliderlen = maxlen;
3781 } else {
3782 sliderlen = maxlen;
3783 }
3784
3785 int sliderstart = sbextent + sliderPositionFromValue(min: scrollbar->minimum,
3786 max: scrollbar->maximum,
3787 val: scrollbar->sliderPosition,
3788 space: maxlen - sliderlen,
3789 upsideDown: scrollbar->upsideDown);
3790
3791 switch (sc) {
3792 case SC_ScrollBarSubLine: // top/left button
3793 if (scrollbar->orientation == Qt::Horizontal) {
3794 int buttonWidth = qMin(a: scrollBarRect.width() / 2, b: sbextent);
3795 ret.setRect(ax: 0, ay: 0, aw: buttonWidth, ah: scrollBarRect.height());
3796 } else {
3797 int buttonHeight = qMin(a: scrollBarRect.height() / 2, b: sbextent);
3798 ret.setRect(ax: 0, ay: 0, aw: scrollBarRect.width(), ah: buttonHeight);
3799 }
3800 break;
3801 case SC_ScrollBarAddLine: // bottom/right button
3802 if (scrollbar->orientation == Qt::Horizontal) {
3803 int buttonWidth = qMin(a: scrollBarRect.width()/2, b: sbextent);
3804 ret.setRect(ax: scrollBarRect.width() - buttonWidth, ay: 0, aw: buttonWidth, ah: scrollBarRect.height());
3805 } else {
3806 int buttonHeight = qMin(a: scrollBarRect.height()/2, b: sbextent);
3807 ret.setRect(ax: 0, ay: scrollBarRect.height() - buttonHeight, aw: scrollBarRect.width(), ah: buttonHeight);
3808 }
3809 break;
3810 case SC_ScrollBarSubPage: // between top/left button and slider
3811 if (scrollbar->orientation == Qt::Horizontal)
3812 ret.setRect(ax: sbextent, ay: 0, aw: sliderstart - sbextent, ah: scrollBarRect.height());
3813 else
3814 ret.setRect(ax: 0, ay: sbextent, aw: scrollBarRect.width(), ah: sliderstart - sbextent);
3815 break;
3816 case SC_ScrollBarAddPage: // between bottom/right button and slider
3817 if (scrollbar->orientation == Qt::Horizontal)
3818 ret.setRect(ax: sliderstart + sliderlen, ay: 0,
3819 aw: maxlen - sliderstart - sliderlen + sbextent, ah: scrollBarRect.height());
3820 else
3821 ret.setRect(ax: 0, ay: sliderstart + sliderlen, aw: scrollBarRect.width(),
3822 ah: maxlen - sliderstart - sliderlen + sbextent);
3823 break;
3824 case SC_ScrollBarGroove:
3825 if (scrollbar->orientation == Qt::Horizontal)
3826 ret.setRect(ax: sbextent, ay: 0, aw: scrollBarRect.width() - sbextent * 2,
3827 ah: scrollBarRect.height());
3828 else
3829 ret.setRect(ax: 0, ay: sbextent, aw: scrollBarRect.width(),
3830 ah: scrollBarRect.height() - sbextent * 2);
3831 break;
3832 case SC_ScrollBarSlider:
3833 if (scrollbar->orientation == Qt::Horizontal)
3834 ret.setRect(ax: sliderstart, ay: 0, aw: sliderlen, ah: scrollBarRect.height());
3835 else
3836 ret.setRect(ax: 0, ay: sliderstart, aw: scrollBarRect.width(), ah: sliderlen);
3837 break;
3838 default:
3839 break;
3840 }
3841 ret = visualRect(direction: scrollbar->direction, boundingRect: scrollBarRect, logicalRect: ret);
3842 }
3843 break;
3844 case CC_SpinBox:
3845 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
3846 QSize bs;
3847 int fw = spinbox->frame ? proxy()->pixelMetric(metric: PM_SpinBoxFrameWidth, option: spinbox) : 0;
3848 bs.setHeight(qMax(a: 8, b: spinbox->rect.height()/2 - fw));
3849 // 1.6 -approximate golden mean
3850 bs.setWidth(qMax(a: 16, b: qMin(a: bs.height() * 8 / 5, b: spinbox->rect.width() / 4)));
3851 int y = fw + spinbox->rect.y();
3852 int x, lx, rx;
3853 x = spinbox->rect.x() + spinbox->rect.width() - fw - bs.width();
3854 lx = fw;
3855 rx = x - fw;
3856 switch (sc) {
3857 case SC_SpinBoxUp:
3858 if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons)
3859 return QRect();
3860 ret = QRect(x, y, bs.width(), bs.height());
3861 break;
3862 case SC_SpinBoxDown:
3863 if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons)
3864 return QRect();
3865
3866 ret = QRect(x, y + bs.height(), bs.width(), bs.height());
3867 break;
3868 case SC_SpinBoxEditField:
3869 if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons) {
3870 ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
3871 } else {
3872 ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw);
3873 }
3874 break;
3875 case SC_SpinBoxFrame:
3876 ret = spinbox->rect;
3877 break;
3878 default:
3879 break;
3880 }
3881 ret = visualRect(direction: spinbox->direction, boundingRect: spinbox->rect, logicalRect: ret);
3882 }
3883 break;
3884 case CC_ToolButton:
3885 if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3886 int mbi = proxy()->pixelMetric(metric: PM_MenuButtonIndicator, option: tb);
3887 ret = tb->rect;
3888 switch (sc) {
3889 case SC_ToolButton:
3890 if ((tb->features
3891 & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
3892 == QStyleOptionToolButton::MenuButtonPopup)
3893 ret.adjust(dx1: 0, dy1: 0, dx2: -mbi, dy2: 0);
3894 break;
3895 case SC_ToolButtonMenu:
3896 if ((tb->features
3897 & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
3898 == QStyleOptionToolButton::MenuButtonPopup)
3899 ret.adjust(dx1: ret.width() - mbi, dy1: 0, dx2: 0, dy2: 0);
3900 break;
3901 default:
3902 break;
3903 }
3904 ret = visualRect(direction: tb->direction, boundingRect: tb->rect, logicalRect: ret);
3905 }
3906 break;
3907 case CC_ComboBox:
3908 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
3909 const qreal dpi = QStyleHelper::dpi(option: opt);
3910 const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
3911 const int margin = cb->frame ? qRound(d: QStyleHelper::dpiScaled(value: 3, dpi)) : 0;
3912 const int bmarg = cb->frame ? qRound(d: QStyleHelper::dpiScaled(value: 2, dpi)) : 0;
3913 const int xpos = x + wi - bmarg - qRound(d: QStyleHelper::dpiScaled(value: 16, dpi));
3914
3915
3916 switch (sc) {
3917 case SC_ComboBoxFrame:
3918 ret = cb->rect;
3919 break;
3920 case SC_ComboBoxArrow:
3921 ret.setRect(ax: xpos, ay: y + bmarg, aw: qRound(d: QStyleHelper::dpiScaled(value: 16, option: opt)), ah: he - 2*bmarg);
3922 break;
3923 case SC_ComboBoxEditField:
3924 ret.setRect(ax: x + margin, ay: y + margin, aw: wi - 2 * margin - qRound(d: QStyleHelper::dpiScaled(value: 16, dpi)), ah: he - 2 * margin);
3925 break;
3926 case SC_ComboBoxListBoxPopup:
3927 ret = cb->rect;
3928 break;
3929 default:
3930 break;
3931 }
3932 ret = visualRect(direction: cb->direction, boundingRect: cb->rect, logicalRect: ret);
3933 }
3934 break;
3935 case CC_TitleBar:
3936 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
3937 const int controlMargin = 2;
3938 const int controlHeight = tb->rect.height() - controlMargin *2;
3939 const int delta = controlHeight + controlMargin;
3940 int offset = 0;
3941
3942 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3943 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3944
3945 switch (sc) {
3946 case SC_TitleBarLabel:
3947 if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
3948 ret = tb->rect;
3949 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3950 ret.adjust(dx1: delta, dy1: 0, dx2: -delta, dy2: 0);
3951 if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3952 ret.adjust(dx1: 0, dy1: 0, dx2: -delta, dy2: 0);
3953 if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3954 ret.adjust(dx1: 0, dy1: 0, dx2: -delta, dy2: 0);
3955 if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
3956 ret.adjust(dx1: 0, dy1: 0, dx2: -delta, dy2: 0);
3957 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3958 ret.adjust(dx1: 0, dy1: 0, dx2: -delta, dy2: 0);
3959 }
3960 break;
3961 case SC_TitleBarContextHelpButton:
3962 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3963 offset += delta;
3964 Q_FALLTHROUGH();
3965 case SC_TitleBarMinButton:
3966 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3967 offset += delta;
3968 else if (sc == SC_TitleBarMinButton)
3969 break;
3970 Q_FALLTHROUGH();
3971 case SC_TitleBarNormalButton:
3972 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3973 offset += delta;
3974 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3975 offset += delta;
3976 else if (sc == SC_TitleBarNormalButton)
3977 break;
3978 Q_FALLTHROUGH();
3979 case SC_TitleBarMaxButton:
3980 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3981 offset += delta;
3982 else if (sc == SC_TitleBarMaxButton)
3983 break;
3984 Q_FALLTHROUGH();
3985 case SC_TitleBarShadeButton:
3986 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3987 offset += delta;
3988 else if (sc == SC_TitleBarShadeButton)
3989 break;
3990 Q_FALLTHROUGH();
3991 case SC_TitleBarUnshadeButton:
3992 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3993 offset += delta;
3994 else if (sc == SC_TitleBarUnshadeButton)
3995 break;
3996 Q_FALLTHROUGH();
3997 case SC_TitleBarCloseButton:
3998 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3999 offset += delta;
4000 else if (sc == SC_TitleBarCloseButton)
4001 break;
4002 ret.setRect(ax: tb->rect.right() - offset, ay: tb->rect.top() + controlMargin,
4003 aw: controlHeight, ah: controlHeight);
4004 break;
4005 case SC_TitleBarSysMenu:
4006 if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
4007 ret.setRect(ax: tb->rect.left() + controlMargin, ay: tb->rect.top() + controlMargin,
4008 aw: controlHeight, ah: controlHeight);
4009 }
4010 break;
4011 default:
4012 break;
4013 }
4014 ret = visualRect(direction: tb->direction, boundingRect: tb->rect, logicalRect: ret);
4015 }
4016 break;
4017 case CC_GroupBox: {
4018 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
4019 switch (sc) {
4020 case SC_GroupBoxFrame:
4021 case SC_GroupBoxContents: {
4022 int topMargin = 0;
4023 int topHeight = 0;
4024 int verticalAlignment = proxy()->styleHint(stylehint: SH_GroupBox_TextLabelVerticalAlignment, opt: groupBox);
4025 bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
4026 if (groupBox->text.size() || hasCheckBox) {
4027 int checkBoxHeight = hasCheckBox ? proxy()->pixelMetric(metric: PM_IndicatorHeight, option: groupBox) : 0;
4028 topHeight = qMax(a: groupBox->fontMetrics.height(), b: checkBoxHeight);
4029 if (verticalAlignment & Qt::AlignVCenter)
4030 topMargin = topHeight / 2;
4031 else if (verticalAlignment & Qt::AlignTop)
4032 topMargin = topHeight;
4033 }
4034
4035 QRect frameRect = groupBox->rect;
4036 frameRect.setTop(topMargin);
4037
4038 if (sc == SC_GroupBoxFrame) {
4039 ret = frameRect;
4040 break;
4041 }
4042
4043 int frameWidth = 0;
4044 if ((groupBox->features & QStyleOptionFrame::Flat) == 0)
4045 frameWidth = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: groupBox);
4046 ret = frameRect.adjusted(xp1: frameWidth, yp1: frameWidth + topHeight - topMargin,
4047 xp2: -frameWidth, yp2: -frameWidth);
4048 break;
4049 }
4050 case SC_GroupBoxCheckBox:
4051 case SC_GroupBoxLabel: {
4052 QFontMetrics fontMetrics = groupBox->fontMetrics;
4053 int th = fontMetrics.height();
4054 int tw = fontMetrics.size(flags: Qt::TextShowMnemonic, str: groupBox->text + QLatin1Char(' ')).width();
4055 int marg = (groupBox->features & QStyleOptionFrame::Flat) ? 0 : 8;
4056 ret = groupBox->rect.adjusted(xp1: marg, yp1: 0, xp2: -marg, yp2: 0);
4057
4058 int indicatorWidth = proxy()->pixelMetric(metric: PM_IndicatorWidth, option: opt);
4059 int indicatorHeight = proxy()->pixelMetric(metric: PM_IndicatorHeight, option: opt);
4060 int indicatorSpace = proxy()->pixelMetric(metric: PM_CheckBoxLabelSpacing, option: opt) - 1;
4061 bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
4062 int checkBoxWidth = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
4063 int checkBoxHeight = hasCheckBox ? indicatorHeight : 0;
4064
4065 int h = qMax(a: th, b: checkBoxHeight);
4066 ret.setHeight(h);
4067
4068 // Adjusted rect for label + indicatorWidth + indicatorSpace
4069 QRect totalRect = alignedRect(direction: groupBox->direction, alignment: groupBox->textAlignment,
4070 size: QSize(tw + checkBoxWidth, h), rectangle: ret);
4071
4072 // Adjust totalRect if checkbox is set
4073 if (hasCheckBox) {
4074 bool ltr = groupBox->direction == Qt::LeftToRight;
4075 int left = 0;
4076 // Adjust for check box
4077 if (sc == SC_GroupBoxCheckBox) {
4078 left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
4079 int top = totalRect.top() + (h - checkBoxHeight) / 2;
4080 totalRect.setRect(ax: left, ay: top, aw: indicatorWidth, ah: indicatorHeight);
4081 // Adjust for label
4082 } else {
4083 left = ltr ? (totalRect.left() + checkBoxWidth - 2) : totalRect.left();
4084 int top = totalRect.top() + (h - th) / 2;
4085 totalRect.setRect(ax: left, ay: top, aw: totalRect.width() - checkBoxWidth, ah: th);
4086 }
4087 }
4088 ret = totalRect;
4089 break;
4090 }
4091 default:
4092 break;
4093 }
4094 }
4095 break;
4096 }
4097 case CC_MdiControls:
4098 {
4099 int numSubControls = 0;
4100 if (opt->subControls & SC_MdiCloseButton)
4101 ++numSubControls;
4102 if (opt->subControls & SC_MdiMinButton)
4103 ++numSubControls;
4104 if (opt->subControls & SC_MdiNormalButton)
4105 ++numSubControls;
4106 if (numSubControls == 0)
4107 break;
4108
4109 int buttonWidth = opt->rect.width() / numSubControls - 1;
4110 int offset = 0;
4111 switch (sc) {
4112 case SC_MdiCloseButton:
4113 // Only one sub control, no offset needed.
4114 if (numSubControls == 1)
4115 break;
4116 offset += buttonWidth + 2;
4117 Q_FALLTHROUGH();
4118 case SC_MdiNormalButton:
4119 // No offset needed if
4120 // 1) There's only one sub control
4121 // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
4122 if (numSubControls == 1 || (numSubControls == 2 && !(opt->subControls & SC_MdiMinButton)))
4123 break;
4124 if (opt->subControls & SC_MdiNormalButton)
4125 offset += buttonWidth;
4126 break;
4127 default:
4128 break;
4129 }
4130
4131 // Subtract one pixel if we only have one sub control. At this point
4132 // buttonWidth is the actual width + 1 pixel margin, but we don't want the
4133 // margin when there are no other controllers.
4134 if (numSubControls == 1)
4135 --buttonWidth;
4136 ret = QRect(offset, 0, buttonWidth, opt->rect.height());
4137 break; }
4138 default:
4139 qWarning(msg: "QCommonStyle::subControlRect: Case %d not handled", cc);
4140 }
4141
4142 return ret;
4143}
4144
4145int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt) const
4146{
4147 int ret;
4148
4149 switch (m) {
4150 case PM_FocusFrameVMargin:
4151 case PM_FocusFrameHMargin:
4152 ret = 2;
4153 break;
4154 case PM_MenuBarVMargin:
4155 case PM_MenuBarHMargin:
4156 ret = 0;
4157 break;
4158 case PM_DialogButtonsSeparator:
4159 ret = int(QStyleHelper::dpiScaled(value: 5, option: opt));
4160 break;
4161 case PM_DialogButtonsButtonWidth:
4162 ret = int(QStyleHelper::dpiScaled(value: 70, option: opt));
4163 break;
4164 case PM_DialogButtonsButtonHeight:
4165 ret = int(QStyleHelper::dpiScaled(value: 30, option: opt));
4166 break;
4167 case PM_TitleBarHeight: {
4168 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
4169 if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) {
4170 ret = qMax(a: opt->fontMetrics.height(), b: 16);
4171 } else {
4172 ret = qMax(a: opt->fontMetrics.height(), b: 18);
4173 }
4174 } else {
4175 ret = int(QStyleHelper::dpiScaled(value: 18., option: opt));
4176 }
4177
4178 break; }
4179 case PM_TitleBarButtonSize:
4180 ret = int(QStyleHelper::dpiScaled(value: 16., option: opt));
4181 break;
4182 case PM_TitleBarButtonIconSize:
4183 ret = int(QStyleHelper::dpiScaled(value: 16., option: opt));
4184 break;
4185
4186 case PM_ScrollBarSliderMin:
4187 ret = int(QStyleHelper::dpiScaled(value: 9., option: opt));
4188 break;
4189
4190 case PM_ButtonMargin:
4191 ret = int(QStyleHelper::dpiScaled(value: 6., option: opt));
4192 break;
4193
4194 case PM_DockWidgetTitleBarButtonMargin:
4195 ret = int(QStyleHelper::dpiScaled(value: 2., option: opt));
4196 break;
4197
4198 case PM_ButtonDefaultIndicator:
4199 ret = 0;
4200 break;
4201
4202 case PM_MenuButtonIndicator:
4203 ret = int(QStyleHelper::dpiScaled(value: 12, option: opt));
4204 break;
4205
4206 case PM_ButtonShiftHorizontal:
4207 case PM_ButtonShiftVertical:
4208
4209 case PM_DefaultFrameWidth:
4210 ret = 2;
4211 break;
4212
4213 case PM_ComboBoxFrameWidth:
4214 case PM_SpinBoxFrameWidth:
4215 case PM_MenuPanelWidth:
4216 case PM_TabBarBaseOverlap:
4217 case PM_TabBarBaseHeight:
4218 ret = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: opt);
4219 break;
4220 case PM_MdiSubWindowFrameWidth:
4221 ret = int(QStyleHelper::dpiScaled(value: 4, option: opt));
4222 break;
4223 case PM_MdiSubWindowMinimizedWidth:
4224 ret = int(QStyleHelper::dpiScaled(value: 196, option: opt));
4225 break;
4226 case PM_ScrollBarExtent:
4227 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4228 break;
4229 case PM_MaximumDragDistance:
4230 ret = QGuiApplicationPrivate::platformTheme()->themeHint(hint: QPlatformTheme::MaximumScrollBarDragDistance).toInt();
4231 break;
4232 case PM_SliderThickness:
4233 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4234 break;
4235 case PM_SliderTickmarkOffset:
4236 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4237 int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height()
4238 : sl->rect.width();
4239 int thickness = proxy()->pixelMetric(metric: PM_SliderControlThickness, option: sl);
4240 int ticks = sl->tickPosition;
4241
4242 if (ticks == QStyleOptionSlider::TicksBothSides)
4243 ret = (space - thickness) / 2;
4244 else if (ticks == QStyleOptionSlider::TicksAbove)
4245 ret = space - thickness;
4246 else
4247 ret = 0;
4248 } else {
4249 ret = 0;
4250 }
4251 break;
4252 case PM_SliderSpaceAvailable:
4253 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4254 if (sl->orientation == Qt::Horizontal)
4255 ret = sl->rect.width() - proxy()->pixelMetric(metric: PM_SliderLength, option: sl);
4256 else
4257 ret = sl->rect.height() - proxy()->pixelMetric(metric: PM_SliderLength, option: sl);
4258 } else {
4259 ret = 0;
4260 }
4261 break;
4262 case PM_DockWidgetSeparatorExtent:
4263 ret = int(QStyleHelper::dpiScaled(value: 6, option: opt));
4264 break;
4265
4266 case PM_DockWidgetHandleExtent:
4267 ret = int(QStyleHelper::dpiScaled(value: 8, option: opt));
4268 break;
4269 case PM_DockWidgetTitleMargin:
4270 ret = 0;
4271 break;
4272 case PM_DockWidgetFrameWidth:
4273 ret = 1;
4274 break;
4275 case PM_SpinBoxSliderHeight:
4276 case PM_MenuBarPanelWidth:
4277 ret = 2;
4278 break;
4279 case PM_MenuBarItemSpacing:
4280 ret = 0;
4281 break;
4282 case PM_ToolBarFrameWidth:
4283 ret = 1;
4284 break;
4285
4286 case PM_ToolBarItemMargin:
4287 ret = 0;
4288 break;
4289
4290 case PM_ToolBarItemSpacing:
4291 ret = int(QStyleHelper::dpiScaled(value: 4, option: opt));
4292 break;
4293
4294 case PM_ToolBarHandleExtent:
4295 ret = int(QStyleHelper::dpiScaled(value: 8, option: opt));
4296 break;
4297
4298 case PM_ToolBarSeparatorExtent:
4299 ret = int(QStyleHelper::dpiScaled(value: 6, option: opt));
4300 break;
4301
4302 case PM_ToolBarExtensionExtent:
4303 ret = int(QStyleHelper::dpiScaled(value: 12, option: opt));
4304 break;
4305
4306 case PM_TabBarTabOverlap:
4307 ret = 3;
4308 break;
4309
4310 case PM_TabBarTabHSpace:
4311 ret = int(QStyleHelper::dpiScaled(value: 24, option: opt));
4312 break;
4313
4314 case PM_TabBarTabShiftHorizontal:
4315 ret = 0;
4316 break;
4317
4318 case PM_TabBarTabShiftVertical:
4319 ret = 2;
4320 break;
4321
4322 case PM_TabBarTabVSpace: {
4323 const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt);
4324 if (tb && (tb->shape == QStyleOptionTab::RoundedNorth || tb->shape == QStyleOptionTab::RoundedSouth
4325 || tb->shape == QStyleOptionTab::RoundedWest || tb->shape == QStyleOptionTab::RoundedEast))
4326 ret = 8;
4327 else
4328 if(tb && (tb->shape == QStyleOptionTab::TriangularWest || tb->shape == QStyleOptionTab::TriangularEast))
4329 ret = 3;
4330 else
4331 ret = 2;
4332 break; }
4333
4334 case PM_ProgressBarChunkWidth:
4335 ret = 9;
4336 break;
4337
4338 case PM_IndicatorWidth:
4339 ret = int(QStyleHelper::dpiScaled(value: 13, option: opt));
4340 break;
4341
4342 case PM_IndicatorHeight:
4343 ret = int(QStyleHelper::dpiScaled(value: 13, option: opt));
4344 break;
4345
4346 case PM_ExclusiveIndicatorWidth:
4347 ret = int(QStyleHelper::dpiScaled(value: 12, option: opt));
4348 break;
4349
4350 case PM_ExclusiveIndicatorHeight:
4351 ret = int(QStyleHelper::dpiScaled(value: 12, option: opt));
4352 break;
4353
4354 case PM_MenuTearoffHeight:
4355 ret = int(QStyleHelper::dpiScaled(value: 10, option: opt));
4356 break;
4357
4358 case PM_MenuScrollerHeight:
4359 ret = int(QStyleHelper::dpiScaled(value: 10, option: opt));
4360 break;
4361
4362 case PM_MenuDesktopFrameWidth:
4363 case PM_MenuHMargin:
4364 case PM_MenuVMargin:
4365 ret = 0;
4366 break;
4367
4368 case PM_HeaderMargin:
4369 ret = int(QStyleHelper::dpiScaled(value: 4, option: opt));
4370 break;
4371 case PM_HeaderMarkSize:
4372 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4373 break;
4374 case PM_HeaderGripMargin:
4375 ret = int(QStyleHelper::dpiScaled(value: 4, option: opt));
4376 break;
4377 case PM_HeaderDefaultSectionSizeHorizontal:
4378 ret = int(QStyleHelper::dpiScaled(value: 100, option: opt));
4379 break;
4380 case PM_HeaderDefaultSectionSizeVertical:
4381 ret = int(QStyleHelper::dpiScaled(value: 30, option: opt));
4382 break;
4383 case PM_TabBarScrollButtonWidth:
4384 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4385 break;
4386 case PM_LayoutLeftMargin:
4387 case PM_LayoutTopMargin:
4388 case PM_LayoutRightMargin:
4389 case PM_LayoutBottomMargin:
4390 {
4391 bool isWindow = opt ? (opt->state & State_Window) : false;
4392 ret = proxy()->pixelMetric(metric: isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin);
4393 }
4394 break;
4395 case PM_LayoutHorizontalSpacing:
4396 case PM_LayoutVerticalSpacing:
4397 ret = proxy()->pixelMetric(metric: PM_DefaultLayoutSpacing);
4398 break;
4399
4400 case PM_DefaultTopLevelMargin:
4401 ret = int(QStyleHelper::dpiScaled(value: 11, option: opt));
4402 break;
4403 case PM_DefaultChildMargin:
4404 ret = int(QStyleHelper::dpiScaled(value: 9, option: opt));
4405 break;
4406 case PM_DefaultLayoutSpacing:
4407 ret = int(QStyleHelper::dpiScaled(value: 6, option: opt));
4408 break;
4409
4410 case PM_ToolBarIconSize:
4411 ret = 0;
4412 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4413 ret = theme->themeHint(hint: QPlatformTheme::ToolBarIconSize).toInt();
4414 if (ret <= 0)
4415 ret = int(QStyleHelper::dpiScaled(value: 24, option: opt));
4416 break;
4417
4418 case PM_TabBarIconSize:
4419 case PM_ListViewIconSize:
4420 ret = proxy()->pixelMetric(metric: PM_SmallIconSize, option: opt);
4421 break;
4422
4423 case PM_ButtonIconSize:
4424 case PM_SmallIconSize:
4425 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4426 break;
4427 case PM_IconViewIconSize:
4428 ret = proxy()->pixelMetric(metric: PM_LargeIconSize, option: opt);
4429 break;
4430
4431 case PM_LargeIconSize:
4432 ret = int(QStyleHelper::dpiScaled(value: 32, option: opt));
4433 break;
4434
4435 case PM_ToolTipLabelFrameWidth:
4436 ret = 1;
4437 break;
4438 case PM_CheckBoxLabelSpacing:
4439 case PM_RadioButtonLabelSpacing:
4440 ret = int(QStyleHelper::dpiScaled(value: 6, option: opt));
4441 break;
4442 case PM_SizeGripSize:
4443 ret = int(QStyleHelper::dpiScaled(value: 13, option: opt));
4444 break;
4445 case PM_MessageBoxIconSize:
4446#ifdef Q_OS_APPLE
4447 if (QGuiApplication::desktopSettingsAware()) {
4448 ret = 64; // No DPI scaling, it's handled elsewhere.
4449 } else
4450#endif
4451 {
4452 ret = int(QStyleHelper::dpiScaled(value: 32, option: opt));
4453 }
4454 break;
4455 case PM_TextCursorWidth:
4456 ret = QGuiApplicationPrivate::platformTheme()->themeHint(hint: QPlatformTheme::TextCursorWidth).toInt();
4457 break;
4458 case PM_TabBar_ScrollButtonOverlap:
4459 ret = 1;
4460 break;
4461 case PM_TabCloseIndicatorWidth:
4462 case PM_TabCloseIndicatorHeight:
4463 ret = int(QStyleHelper::dpiScaled(value: 16, option: opt));
4464 break;
4465 case PM_ScrollView_ScrollBarSpacing:
4466 ret = 2 * proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: opt);
4467 break;
4468 case PM_ScrollView_ScrollBarOverlap:
4469 ret = 0;
4470 break;
4471 case PM_SubMenuOverlap:
4472 ret = -proxy()->pixelMetric(metric: QStyle::PM_MenuPanelWidth, option: opt);
4473 break;
4474 case PM_TreeViewIndentation:
4475 ret = int(QStyleHelper::dpiScaled(value: 20, option: opt));
4476 break;
4477 default:
4478 ret = 0;
4479 break;
4480 }
4481
4482 return ret;
4483}
4484
4485QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const
4486{
4487 QSize sz(!csz.isEmpty() ? csz : QSize(0,0));
4488
4489 switch (ct) {
4490 case CT_PushButton:
4491 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4492 int w = sz.width(),
4493 h = sz.height(),
4494 bm = proxy()->pixelMetric(metric: PM_ButtonMargin, option: btn),
4495 fw = proxy()->pixelMetric(metric: PM_DefaultFrameWidth, option: btn) * 2;
4496 w += bm + fw;
4497 h += bm + fw;
4498 if (btn->features & QStyleOptionButton::AutoDefaultButton){
4499 int dbw = proxy()->pixelMetric(metric: PM_ButtonDefaultIndicator, option: btn) * 2;
4500 w += dbw;
4501 h += dbw;
4502 }
4503 sz = QSize(w, h);
4504 }
4505 break;
4506 case CT_RadioButton:
4507 case CT_CheckBox:
4508 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4509 bool isRadio = (ct == CT_RadioButton);
4510
4511 int w = proxy()->pixelMetric(metric: isRadio ? PM_ExclusiveIndicatorWidth
4512 : PM_IndicatorWidth, option: btn);
4513 int h = proxy()->pixelMetric(metric: isRadio ? PM_ExclusiveIndicatorHeight
4514 : PM_IndicatorHeight, option: btn);
4515
4516 int margins = 0;
4517 // we add 4 pixels for label margins
4518 if (!btn->icon.isNull() || !btn->text.isEmpty())
4519 margins = 4 + proxy()->pixelMetric(metric: isRadio ? PM_RadioButtonLabelSpacing
4520 : PM_CheckBoxLabelSpacing, option: opt);
4521 sz += QSize(w + margins, 4);
4522 sz.setHeight(qMax(a: sz.height(), b: h));
4523 }
4524 break;
4525 case CT_MenuItem:
4526 if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
4527 bool checkable = mi->menuHasCheckableItems;
4528 int maxpmw = mi->maxIconWidth;
4529 int w = sz.width(), h = sz.height();
4530 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
4531 w = 10;
4532 h = 2;
4533 } else {
4534 h = mi->fontMetrics.height() + 8;
4535 if (!mi->icon.isNull()) {
4536 int iconExtent = proxy()->pixelMetric(metric: PM_SmallIconSize);
4537 h = qMax(a: h, b: mi->icon.actualSize(size: QSize(iconExtent, iconExtent)).height() + 4);
4538 }
4539 }
4540 if (mi->text.contains(c: QLatin1Char('\t')))
4541 w += 12;
4542 if (maxpmw > 0)
4543 w += maxpmw + 6;
4544 if (checkable && maxpmw < 20)
4545 w += 20 - maxpmw;
4546 if (checkable || maxpmw > 0)
4547 w += 2;
4548 w += 12;
4549 sz = QSize(w, h);
4550 }
4551 break;
4552 case CT_ToolButton:
4553 sz = QSize(sz.width() + 6, sz.height() + 5);
4554 break;
4555 case CT_ComboBox:
4556 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
4557 int fw = cmb->frame ? proxy()->pixelMetric(metric: PM_ComboBoxFrameWidth, option: opt) * 2 : 0;
4558 const int textMargins = 2*(proxy()->pixelMetric(metric: PM_FocusFrameHMargin) + 1);
4559 // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
4560 int other = qMax(a: 23, b: 2*textMargins + proxy()->pixelMetric(metric: QStyle::PM_ScrollBarExtent, option: opt));
4561 sz = QSize(sz.width() + fw + other, sz.height() + fw);
4562 }
4563 break;
4564 case CT_HeaderSection:
4565 if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
4566 bool nullIcon = hdr->icon.isNull();
4567 int margin = proxy()->pixelMetric(metric: QStyle::PM_HeaderMargin, option: hdr);
4568 int iconSize = nullIcon ? 0 : proxy()->pixelMetric(metric: QStyle::PM_SmallIconSize, option: hdr);
4569 QSize txt = hdr->fontMetrics.size(flags: 0, str: hdr->text);
4570 sz.setHeight(margin + qMax(a: iconSize, b: txt.height()) + margin);
4571 sz.setWidth((nullIcon ? 0 : margin) + iconSize
4572 + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
4573 if (hdr->sortIndicator != QStyleOptionHeader::None) {
4574 int margin = proxy()->pixelMetric(metric: QStyle::PM_HeaderMargin, option: hdr);
4575 if (hdr->orientation == Qt::Horizontal)
4576 sz.rwidth() += sz.height() + margin;
4577 else
4578 sz.rheight() += sz.width() + margin;
4579 }
4580 }
4581 break;
4582 case CT_TabWidget:
4583 sz += QSize(4, 4);
4584 break;
4585 case CT_LineEdit:
4586 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
4587 const int borderSize = 2 * f->lineWidth;
4588 sz += QSize(borderSize, borderSize);
4589 const int minSize = 10;
4590 if (sz.width() < minSize)
4591 sz.rwidth() = minSize;
4592 if (sz.height() < minSize)
4593 sz.rheight() = minSize;
4594 }
4595 break;
4596 case CT_GroupBox:
4597 if (const QStyleOptionGroupBox *styleOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
4598 if (sz.isEmpty())
4599 sz = QSize(20, 20);
4600 sz += QSize(styleOpt->features.testFlag(flag: QStyleOptionFrame::Flat) ? 0 : 16, 0);
4601 }
4602 break;
4603 case CT_MdiControls:
4604 if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
4605 const int buttonSize = proxy()->pixelMetric(metric: PM_TitleBarButtonSize, option: styleOpt);
4606 int width = 1;
4607 if (styleOpt->subControls & SC_MdiMinButton)
4608 width += buttonSize + 1;
4609 if (styleOpt->subControls & SC_MdiNormalButton)
4610 width += buttonSize + 1;
4611 if (styleOpt->subControls & SC_MdiCloseButton)
4612 width += buttonSize + 1;
4613 sz = QSize(width, buttonSize);
4614 } else {
4615 const int buttonSize = proxy()->pixelMetric(metric: PM_TitleBarButtonSize, option: opt);
4616 sz = QSize(1 + 3 * (buttonSize + 1), buttonSize);
4617 }
4618 break;
4619#if QT_CONFIG(quick_itemview)
4620 case CT_ItemViewItem:
4621 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
4622 Q_D(const QCommonStyle);
4623 QRect decorationRect, displayRect, checkRect;
4624 d->viewItemLayout(opt: vopt, checkRect: &checkRect, pixmapRect: &decorationRect, textRect: &displayRect, sizehint: true);
4625 sz = (decorationRect|displayRect|checkRect).size();
4626 if (decorationRect.isValid() && sz.height() == decorationRect.height())
4627 sz.rheight() += 2; // Prevent icons from overlapping.
4628 }
4629 break;
4630#endif // QT_CONFIG(quick_itemview)
4631 case CT_SpinBox:
4632 if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
4633 // Add button + frame widths
4634 if (vopt->subControls == SC_SpinBoxFrame) {
4635 const qreal dpi = QStyleHelper::dpi(option: opt);
4636 const bool hasButtons = (vopt->buttonSymbols != QStyleOptionSpinBox::NoButtons);
4637 const int buttonWidth = hasButtons ? qRound(d: QStyleHelper::dpiScaled(value: 16, dpi)) : 0;
4638 const int fw = vopt->frame ? proxy()->pixelMetric(metric: PM_SpinBoxFrameWidth, option: vopt) : 0;
4639 sz += QSize(buttonWidth + 2*fw, 1 + 2*fw);
4640 } else {
4641 const QSize buttonSize = proxy()->subControlRect(cc: CC_SpinBox, opt: vopt, sc: SC_SpinBoxUp).size();
4642 const int upAndDownTogetherHeight = buttonSize.height() * 2;
4643 sz += QSize(buttonSize.width(), upAndDownTogetherHeight);
4644 }
4645 }
4646 break;
4647 case CT_Slider:
4648 if (const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(opt))
4649 sz = subControlRect(cc: QStyle::CC_Slider, opt: option, sc: QStyle::SC_SliderHandle).size();
4650 break;
4651 case CT_Dial:
4652 sz = QSize(20, 20);
4653 break;
4654 case CT_Frame:
4655 if (const QStyleOptionFrame *option = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
4656 const int ninePatchSplit = 1;
4657 int w = qMax(a: 10, b: (option->lineWidth * 2) + ninePatchSplit);
4658 sz = QSize(w, w);
4659 }
4660 break;
4661 case CT_ProgressBar:
4662 if (sz.isNull()) {
4663 // Special case: return minimum nine patch image size
4664 sz = QSize(10, 10);
4665 }
4666 break;
4667 case CT_ScrollBar:
4668 case CT_MenuBar:
4669 case CT_Menu:
4670 case CT_MenuBarItem:
4671 case CT_TabBarTab:
4672 // just return the contentsSize for now
4673 Q_FALLTHROUGH();
4674 default:
4675 break;
4676 }
4677 return sz;
4678}
4679
4680QFont QCommonStyle::font(QStyle::ControlElement element, const QStyle::State state) const
4681{
4682 Q_UNUSED(element);
4683 Q_UNUSED(state);
4684 return QGuiApplication::font();
4685}
4686
4687QMargins QCommonStyle::ninePatchMargins(QStyle::ControlElement /*ce*/, const QStyleOption * /*opt*/, const QSize &imageSize) const
4688{
4689 // By default, we just divide the image at the center
4690 int w = imageSize.width() / 2;
4691 int h = imageSize.height() / 2;
4692 return QMargins(w, h, w, h);
4693}
4694
4695QMargins QCommonStyle::ninePatchMargins(QStyle::ComplexControl /*cc*/, const QStyleOptionComplex * /*opt*/, const QSize &imageSize) const
4696{
4697 // By default, we just divide the image at the center
4698 int w = imageSize.width() / 2;
4699 int h = imageSize.height() / 2;
4700 return QMargins(w, h, w, h);
4701}
4702
4703int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintReturn *hret) const
4704{
4705 int ret = 0;
4706
4707 switch (sh) {
4708 case SH_Menu_KeyboardSearch:
4709 ret = false;
4710 break;
4711 case SH_Slider_AbsoluteSetButtons:
4712 ret = Qt::MiddleButton;
4713 break;
4714 case SH_Slider_PageSetButtons:
4715 ret = Qt::LeftButton;
4716 break;
4717 case SH_ScrollBar_ContextMenu:
4718 ret = true;
4719 break;
4720 case SH_GroupBox_TextLabelVerticalAlignment:
4721 ret = Qt::AlignVCenter;
4722 break;
4723 case SH_GroupBox_TextLabelColor:
4724 ret = opt ? int(opt->palette.color(cr: QPalette::Text).rgba()) : 0;
4725 break;
4726
4727 case SH_ListViewExpand_SelectMouseType:
4728 case SH_TabBar_SelectMouseType:
4729 ret = QEvent::MouseButtonPress;
4730 break;
4731
4732 case SH_TabBar_Alignment:
4733 ret = Qt::AlignLeft;
4734 break;
4735
4736 case SH_Header_ArrowAlignment:
4737 ret = Qt::AlignRight | Qt::AlignVCenter;
4738 break;
4739
4740 case SH_TitleBar_AutoRaise:
4741 ret = false;
4742 break;
4743
4744 case SH_Menu_SubMenuPopupDelay:
4745 ret = 256;
4746 break;
4747
4748 case SH_Menu_SloppySubMenus:
4749 ret = true;
4750 break;
4751
4752 case SH_Menu_SubMenuUniDirection:
4753 ret = false;
4754 break;
4755 case SH_Menu_SubMenuUniDirectionFailCount:
4756 ret = 1;
4757 break;
4758 case SH_Menu_SubMenuSloppySelectOtherActions:
4759 ret = true;
4760 break;
4761 case SH_Menu_SubMenuSloppyCloseTimeout:
4762 ret = 1000;
4763 break;
4764 case SH_Menu_SubMenuResetWhenReenteringParent:
4765 ret = false;
4766 break;
4767 case SH_Menu_SubMenuDontStartSloppyOnLeave:
4768 ret = false;
4769 break;
4770
4771 case SH_ProgressDialog_TextLabelAlignment:
4772 ret = Qt::AlignCenter;
4773 break;
4774
4775 case SH_BlinkCursorWhenTextSelected:
4776#if defined(Q_OS_DARWIN)
4777 ret = 0;
4778#else
4779 ret = 1;
4780#endif
4781 break;
4782
4783 case SH_Table_GridLineColor:
4784 if (opt)
4785 ret = opt->palette.color(cr: QPalette::Mid).rgba();
4786 else
4787 ret = -1;
4788 break;
4789 case SH_LineEdit_PasswordCharacter: {
4790 const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
4791 const QPlatformTheme::ThemeHint hintType = QPlatformTheme::PasswordMaskCharacter;
4792 const QVariant hint = theme ? theme->themeHint(hint: hintType) : QPlatformTheme::defaultThemeHint(hint: hintType);
4793 ret = hint.toChar().unicode();
4794 break;
4795 }
4796 case SH_LineEdit_PasswordMaskDelay:
4797 ret = QGuiApplicationPrivate::platformTheme()->themeHint(hint: QPlatformTheme::PasswordMaskDelay).toInt();
4798 break;
4799 case SH_ToolBox_SelectedPageTitleBold:
4800 ret = 1;
4801 break;
4802
4803 case SH_UnderlineShortcut:
4804 ret = 1;
4805 break;
4806
4807 case SH_SpinBox_ClickAutoRepeatRate:
4808 ret = 150;
4809 break;
4810
4811 case SH_SpinBox_ClickAutoRepeatThreshold:
4812 ret = 500;
4813 break;
4814
4815 case SH_SpinBox_KeyPressAutoRepeatRate:
4816 ret = 75;
4817 break;
4818
4819 case SH_Menu_SelectionWrap:
4820 ret = true;
4821 break;
4822
4823 case SH_Menu_FillScreenWithScroll:
4824 ret = true;
4825 break;
4826
4827 case SH_ToolTipLabel_Opacity:
4828 ret = 255;
4829 break;
4830
4831 case SH_Button_FocusPolicy:
4832 ret = Qt::StrongFocus;
4833 break;
4834
4835 case SH_MessageBox_UseBorderForButtonSpacing:
4836 ret = 0;
4837 break;
4838
4839 case SH_ToolButton_PopupDelay:
4840 ret = 600;
4841 break;
4842
4843 case SH_FocusFrame_Mask:
4844 ret = 1;
4845 break;
4846 case SH_RubberBand_Mask:
4847 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
4848 ret = 0;
4849 if (rbOpt->shape == QStyleOptionRubberBand::Rectangle) {
4850 ret = true;
4851 if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hint: hret)) {
4852 mask->region = opt->rect;
4853 int margin = proxy()->pixelMetric(metric: PM_DefaultFrameWidth) * 2;
4854 mask->region -= opt->rect.adjusted(xp1: margin, yp1: margin, xp2: -margin, yp2: -margin);
4855 }
4856 }
4857 }
4858 break;
4859 case SH_SpinControls_DisableOnBounds:
4860 ret = 1;
4861 break;
4862
4863 case SH_Dial_BackgroundRole:
4864 ret = QPalette::Window;
4865 break;
4866
4867 case SH_ComboBox_LayoutDirection:
4868 ret = opt ? opt->direction : Qt::LeftToRight;
4869 break;
4870
4871 case SH_ItemView_EllipsisLocation:
4872 ret = Qt::AlignTrailing;
4873 break;
4874
4875 case SH_ItemView_ShowDecorationSelected:
4876 ret = false;
4877 break;
4878
4879 case SH_ItemView_ActivateItemOnSingleClick:
4880 ret = 0;
4881 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4882 ret = theme->themeHint(hint: QPlatformTheme::ItemViewActivateItemOnSingleClick).toBool() ? 1 : 0;
4883 break;
4884 case SH_TitleBar_ModifyNotification:
4885 ret = true;
4886 break;
4887 case SH_ScrollBar_RollBetweenButtons:
4888 ret = false;
4889 break;
4890 case SH_TabBar_ElideMode:
4891 ret = Qt::ElideNone;
4892 break;
4893 case SH_DialogButtonLayout:
4894 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4895 ret = theme->themeHint(hint: QPlatformTheme::DialogButtonBoxLayout).toInt();
4896 break;
4897 case SH_ComboBox_PopupFrameStyle:
4898 ret = QStyleOptionFrame::StyledPanel | QStyleOptionFrame::Plain;
4899 break;
4900 case SH_MessageBox_TextInteractionFlags:
4901 ret = Qt::LinksAccessibleByMouse;
4902 break;
4903 case SH_DialogButtonBox_ButtonsHaveIcons:
4904 ret = 0;
4905 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4906 ret = theme->themeHint(hint: QPlatformTheme::DialogButtonBoxButtonsHaveIcons).toBool() ? 1 : 0;
4907 break;
4908 case SH_SpellCheckUnderlineStyle:
4909 ret = QTextCharFormat::WaveUnderline;
4910 break;
4911 case SH_MessageBox_CenterButtons:
4912 ret = true;
4913 break;
4914 case SH_ItemView_MovementWithoutUpdatingSelection:
4915 ret = true;
4916 break;
4917 case SH_FocusFrame_AboveWidget:
4918 ret = false;
4919 break;
4920 case SH_TabWidget_DefaultTabPosition:
4921 ret = QStyleOptionTabBarBase::North;
4922 break;
4923 case SH_ToolBar_Movable:
4924 ret = true;
4925 break;
4926 case SH_TextControl_FocusIndicatorTextCharFormat:
4927 ret = true;
4928 if (QStyleHintReturnVariant *vret = qstyleoption_cast<QStyleHintReturnVariant*>(hint: hret)) {
4929 QPen outline(opt->palette.color(cr: QPalette::Text), 1, Qt::DotLine);
4930 QTextCharFormat fmt;
4931 fmt.setProperty(propertyId: QTextFormat::OutlinePen, value: outline);
4932 vret->variant = fmt;
4933 }
4934 break;
4935 case SH_WizardStyle:
4936 break;
4937 case SH_FormLayoutWrapPolicy:
4938 break;
4939 case SH_FormLayoutFieldGrowthPolicy:
4940 break;
4941 case SH_FormLayoutFormAlignment:
4942 ret = Qt::AlignLeft | Qt::AlignTop;
4943 break;
4944 case SH_FormLayoutLabelAlignment:
4945 ret = Qt::AlignLeft;
4946 break;
4947 case SH_ItemView_ArrowKeysNavigateIntoChildren:
4948 ret = false;
4949 break;
4950 case SH_ItemView_DrawDelegateFrame:
4951 ret = 0;
4952 break;
4953 case SH_TabBar_CloseButtonPosition:
4954 ret = QStyleOptionTabBarBase::RightSide;
4955 break;
4956 case SH_TabBar_ChangeCurrentDelay:
4957 ret = 500;
4958 break;
4959 case SH_DockWidget_ButtonsHaveFrame:
4960 ret = true;
4961 break;
4962 case SH_ToolButtonStyle:
4963 ret = 0;
4964 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4965 ret = theme->themeHint(hint: QPlatformTheme::ToolButtonStyle).toInt();
4966 break;
4967 case SH_RequestSoftwareInputPanel:
4968 ret = RSIP_OnMouseClick;
4969 break;
4970 case SH_ScrollBar_Transient:
4971 ret = false;
4972 break;
4973 case SH_Menu_SupportsSections:
4974 ret = false;
4975 break;
4976 case SH_ToolTip_WakeUpDelay:
4977 ret = 700;
4978 break;
4979 case SH_ToolTip_FallAsleepDelay:
4980 ret = 2000;
4981 break;
4982 case SH_Widget_Animate:
4983 ret = true;
4984 break;
4985 case SH_Splitter_OpaqueResize:
4986 ret = true;
4987 break;
4988#if QT_CONFIG(quick_itemview)
4989 case SH_ItemView_ScrollMode:
4990 ret = QStyleOptionViewItem::ScrollPerItem;
4991 break;
4992#endif // QT_CONFIG(quick_itemview)
4993 case SH_TitleBar_ShowToolTipsOnButtons:
4994 ret = true;
4995 break;
4996 case SH_Widget_Animation_Duration:
4997 ret = styleHint(sh: SH_Widget_Animate, opt, hret) ? 200 : 0;
4998 break;
4999 case SH_ComboBox_AllowWheelScrolling:
5000 ret = true;
5001 break;
5002 case SH_SpinBox_ButtonsInsideFrame:
5003 ret = true;
5004 break;
5005 case SH_SpinBox_StepModifier:
5006 ret = Qt::ControlModifier;
5007 break;
5008 default:
5009 ret = 0;
5010 break;
5011 }
5012
5013 return ret;
5014}
5015
5016#if QT_CONFIG(imageformat_xpm)
5017static QPixmap cachedPixmapFromXPM(const char * const *xpm)
5018{
5019 QPixmap result;
5020 const QString tag = QString::asprintf(format: "xpm:0x%p", static_cast<const void*>(xpm));
5021 if (!QPixmapCache::find(key: tag, pixmap: &result)) {
5022 result = QPixmap(xpm);
5023 QPixmapCache::insert(key: tag, pixmap: result);
5024 }
5025 return result;
5026}
5027
5028static inline QPixmap titleBarMenuCachedPixmapFromXPM() { return cachedPixmapFromXPM(xpm: qt_menu_xpm); }
5029#endif
5030
5031static inline QString clearText16IconPath()
5032{
5033 return QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png");
5034}
5035
5036#if defined(Q_OS_WIN) || QT_CONFIG(imageformat_png)
5037static QIcon clearTextIcon(bool rtl)
5038{
5039 const QString directionalThemeName = rtl
5040 ? QStringLiteral("edit-clear-locationbar-ltr") : QStringLiteral("edit-clear-locationbar-rtl");
5041 if (QIcon::hasThemeIcon(name: directionalThemeName))
5042 return QIcon::fromTheme(name: directionalThemeName);
5043 const QString themeName = QStringLiteral("edit-clear");
5044 if (QIcon::hasThemeIcon(name: themeName))
5045 return QIcon::fromTheme(name: themeName);
5046
5047 QIcon icon;
5048#ifndef QT_NO_IMAGEFORMAT_PNG
5049 QPixmap clearText16(clearText16IconPath());
5050 Q_ASSERT(!clearText16.size().isEmpty());
5051 icon.addPixmap(pixmap: clearText16);
5052 QPixmap clearText32(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-32.png"));
5053 Q_ASSERT(!clearText32.size().isEmpty());
5054 icon.addPixmap(pixmap: clearText32);
5055 clearText32.setDevicePixelRatio(2); // The 32x32 pixmap can also be used for 16x16/devicePixelRatio=2
5056 icon.addPixmap(pixmap: clearText32);
5057#endif // !QT_NO_IMAGEFORMAT_PNG
5058 return icon;
5059}
5060#endif
5061
5062QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option) const
5063{
5064 const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft());
5065#if QT_CONFIG(imageformat_png)
5066 QPixmap pixmap;
5067
5068 if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
5069 switch (sp) {
5070 case SP_DialogYesButton:
5071 case SP_DialogOkButton:
5072 pixmap = QIcon::fromTheme(name: QLatin1String("dialog-ok")).pixmap(extent: 16);
5073 break;
5074 case SP_DialogApplyButton:
5075 pixmap = QIcon::fromTheme(name: QLatin1String("dialog-ok-apply")).pixmap(extent: 16);
5076 break;
5077 case SP_DialogDiscardButton:
5078 pixmap = QIcon::fromTheme(name: QLatin1String("edit-delete")).pixmap(extent: 16);
5079 break;
5080 case SP_DialogCloseButton:
5081 pixmap = QIcon::fromTheme(name: QLatin1String("dialog-close")).pixmap(extent: 16);
5082 break;
5083 case SP_DirHomeIcon:
5084 pixmap = QIcon::fromTheme(name: QLatin1String("user-home")).pixmap(extent: 16);
5085 break;
5086 case SP_MessageBoxInformation:
5087 pixmap = QIcon::fromTheme(name: QLatin1String("messagebox_info")).pixmap(extent: 16);
5088 break;
5089 case SP_MessageBoxWarning:
5090 pixmap = QIcon::fromTheme(name: QLatin1String("messagebox_warning")).pixmap(extent: 16);
5091 break;
5092 case SP_MessageBoxCritical:
5093 pixmap = QIcon::fromTheme(name: QLatin1String("messagebox_critical")).pixmap(extent: 16);
5094 break;
5095 case SP_MessageBoxQuestion:
5096 pixmap = QIcon::fromTheme(name: QLatin1String("help")).pixmap(extent: 16);
5097 break;
5098 case SP_DialogOpenButton:
5099 case SP_DirOpenIcon:
5100 pixmap = QIcon::fromTheme(name: QLatin1String("folder-open")).pixmap(extent: 16);
5101 break;
5102 case SP_FileIcon:
5103 pixmap = QIcon::fromTheme(name: QLatin1String("text-x-generic"),
5104 fallback: QIcon::fromTheme(name: QLatin1String("empty"))).pixmap(extent: 16);
5105 break;
5106 case SP_DirClosedIcon:
5107 case SP_DirIcon:
5108 pixmap = QIcon::fromTheme(name: QLatin1String("folder")).pixmap(extent: 16);
5109 break;
5110 case SP_DriveFDIcon:
5111 pixmap = QIcon::fromTheme(name: QLatin1String("media-floppy"),
5112 fallback: QIcon::fromTheme(name: QLatin1String("3floppy_unmount"))).pixmap(extent: 16);
5113 break;
5114 case SP_ComputerIcon:
5115 pixmap = QIcon::fromTheme(name: QLatin1String("computer"),
5116 fallback: QIcon::fromTheme(name: QLatin1String("system"))).pixmap(extent: 16);
5117 break;
5118 case SP_DesktopIcon:
5119 pixmap = QIcon::fromTheme(name: QLatin1String("user-desktop"),
5120 fallback: QIcon::fromTheme(name: QLatin1String("desktop"))).pixmap(extent: 16);
5121 break;
5122 case SP_TrashIcon:
5123 pixmap = QIcon::fromTheme(name: QLatin1String("user-trash"),
5124 fallback: QIcon::fromTheme(name: QLatin1String("trashcan_empty"))).pixmap(extent: 16);
5125 break;
5126 case SP_DriveCDIcon:
5127 case SP_DriveDVDIcon:
5128 pixmap = QIcon::fromTheme(name: QLatin1String("media-optical"),
5129 fallback: QIcon::fromTheme(name: QLatin1String("cdrom_unmount"))).pixmap(extent: 16);
5130 break;
5131 case SP_DriveHDIcon:
5132 pixmap = QIcon::fromTheme(name: QLatin1String("drive-harddisk"),
5133 fallback: QIcon::fromTheme(name: QLatin1String("hdd_unmount"))).pixmap(extent: 16);
5134 break;
5135 case SP_FileDialogToParent:
5136 pixmap = QIcon::fromTheme(name: QLatin1String("go-up"),
5137 fallback: QIcon::fromTheme(name: QLatin1String("up"))).pixmap(extent: 16);
5138 break;
5139 case SP_FileDialogNewFolder:
5140 pixmap = QIcon::fromTheme(name: QLatin1String("folder_new")).pixmap(extent: 16);
5141 break;
5142 case SP_ArrowUp:
5143 pixmap = QIcon::fromTheme(name: QLatin1String("go-up"),
5144 fallback: QIcon::fromTheme(name: QLatin1String("up"))).pixmap(extent: 16);
5145 break;
5146 case SP_ArrowDown:
5147 pixmap = QIcon::fromTheme(name: QLatin1String("go-down"),
5148 fallback: QIcon::fromTheme(name: QLatin1String("down"))).pixmap(extent: 16);
5149 break;
5150 case SP_ArrowRight:
5151 pixmap = QIcon::fromTheme(name: QLatin1String("go-next"),
5152 fallback: QIcon::fromTheme(name: QLatin1String("forward"))).pixmap(extent: 16);
5153 break;
5154 case SP_ArrowLeft:
5155 pixmap = QIcon::fromTheme(name: QLatin1String("go-previous"),
5156 fallback: QIcon::fromTheme(name: QLatin1String("back"))).pixmap(extent: 16);
5157 break;
5158 case SP_FileDialogDetailedView:
5159 pixmap = QIcon::fromTheme(name: QLatin1String("view_detailed")).pixmap(extent: 16);
5160 break;
5161 case SP_FileDialogListView:
5162 pixmap = QIcon::fromTheme(name: QLatin1String("view_icon")).pixmap(extent: 16);
5163 break;
5164 case SP_BrowserReload:
5165 pixmap = QIcon::fromTheme(name: QLatin1String("reload")).pixmap(extent: 16);
5166 break;
5167 case SP_BrowserStop:
5168 pixmap = QIcon::fromTheme(name: QLatin1String("process-stop")).pixmap(extent: 16);
5169 break;
5170 case SP_MediaPlay:
5171 pixmap = QIcon::fromTheme(name: QLatin1String("media-playback-start")).pixmap(extent: 16);
5172 break;
5173 case SP_MediaPause:
5174 pixmap = QIcon::fromTheme(name: QLatin1String("media-playback-pause")).pixmap(extent: 16);
5175 break;
5176 case SP_MediaStop:
5177 pixmap = QIcon::fromTheme(name: QLatin1String("media-playback-stop")).pixmap(extent: 16);
5178 break;
5179 case SP_MediaSeekForward:
5180 pixmap = QIcon::fromTheme(name: QLatin1String("media-seek-forward")).pixmap(extent: 16);
5181 break;
5182 case SP_MediaSeekBackward:
5183 pixmap = QIcon::fromTheme(name: QLatin1String("media-seek-backward")).pixmap(extent: 16);
5184 break;
5185 case SP_MediaSkipForward:
5186 pixmap = QIcon::fromTheme(name: QLatin1String("media-skip-forward")).pixmap(extent: 16);
5187 break;
5188 case SP_MediaSkipBackward:
5189 pixmap = QIcon::fromTheme(name: QLatin1String("media-skip-backward")).pixmap(extent: 16);
5190 break;
5191 case SP_DialogResetButton:
5192 pixmap = QIcon::fromTheme(name: QLatin1String("edit-clear")).pixmap(extent: 24);
5193 break;
5194 case SP_DialogHelpButton:
5195 pixmap = QIcon::fromTheme(name: QLatin1String("help-contents")).pixmap(extent: 24);
5196 break;
5197 case SP_DialogNoButton:
5198 case SP_DialogCancelButton:
5199 pixmap = QIcon::fromTheme(name: QLatin1String("dialog-cancel"),
5200 fallback: QIcon::fromTheme(name: QLatin1String("process-stop"))).pixmap(extent: 24);
5201 break;
5202 case SP_DialogSaveButton:
5203 pixmap = QIcon::fromTheme(name: QLatin1String("document-save")).pixmap(extent: 24);
5204 break;
5205 case SP_FileLinkIcon:
5206 pixmap = QIcon::fromTheme(name: QLatin1String("emblem-symbolic-link")).pixmap(extent: 16);
5207 if (!pixmap.isNull()) {
5208 QPixmap fileIcon = QIcon::fromTheme(name: QLatin1String("text-x-generic")).pixmap(extent: 16);
5209 if (fileIcon.isNull())
5210 fileIcon = QIcon::fromTheme(name: QLatin1String("empty")).pixmap(extent: 16);
5211 if (!fileIcon.isNull()) {
5212 QPainter painter(&fileIcon);
5213 painter.drawPixmap(x: 0, y: 0, w: 16, h: 16, pm: pixmap);
5214 return fileIcon;
5215 }
5216 }
5217 break;
5218 case SP_DirLinkIcon:
5219 pixmap = QIcon::fromTheme(name: QLatin1String("emblem-symbolic-link")).pixmap(extent: 16);
5220 if (!pixmap.isNull()) {
5221 QPixmap dirIcon = QIcon::fromTheme(name: QLatin1String("folder")).pixmap(extent: 16);
5222 if (!dirIcon.isNull()) {
5223 QPainter painter(&dirIcon);
5224 painter.drawPixmap(x: 0, y: 0, w: 16, h: 16, pm: pixmap);
5225 return dirIcon;
5226 }
5227 }
5228 break;
5229 case SP_LineEditClearButton:
5230 pixmap = clearTextIcon(rtl).pixmap(extent: 16);
5231 break;
5232 default:
5233 break;
5234 }
5235 }
5236
5237 if (!pixmap.isNull())
5238 return pixmap;
5239#endif // QT_CONFIG(imageformat_png)
5240 switch (sp) {
5241#ifndef QT_NO_IMAGEFORMAT_XPM
5242 case SP_ToolBarHorizontalExtensionButton:
5243 if (rtl) {
5244 QImage im(tb_extension_arrow_h_xpm);
5245 im = std::move(im).convertToFormat(f: QImage::Format_ARGB32).mirrored(horizontally: true, vertically: false);
5246 return QPixmap::fromImage(image: std::move(im));
5247 }
5248 return cachedPixmapFromXPM(xpm: tb_extension_arrow_h_xpm);
5249 case SP_ToolBarVerticalExtensionButton:
5250 return cachedPixmapFromXPM(xpm: tb_extension_arrow_v_xpm);
5251 case SP_FileDialogStart:
5252 return cachedPixmapFromXPM(xpm: filedialog_start_xpm);
5253 case SP_FileDialogEnd:
5254 return cachedPixmapFromXPM(xpm: filedialog_end_xpm);
5255#endif
5256#ifndef QT_NO_IMAGEFORMAT_PNG
5257 case SP_CommandLink:
5258 case SP_ArrowForward:
5259 if (rtl)
5260 return proxy()->standardPixmap(standardPixmap: SP_ArrowLeft, opt: option);
5261 return proxy()->standardPixmap(standardPixmap: SP_ArrowRight, opt: option);
5262 case SP_ArrowBack:
5263 if (rtl)
5264 return proxy()->standardPixmap(standardPixmap: SP_ArrowRight, opt: option);
5265 return proxy()->standardPixmap(standardPixmap: SP_ArrowLeft, opt: option);
5266 case SP_ArrowLeft:
5267 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"));
5268 case SP_ArrowRight:
5269 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"));
5270 case SP_ArrowUp:
5271 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"));
5272 case SP_ArrowDown:
5273 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"));
5274 case SP_FileDialogToParent:
5275 return proxy()->standardPixmap(standardPixmap: SP_ArrowUp, opt: option);
5276 case SP_FileDialogNewFolder:
5277 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"));
5278 case SP_FileDialogDetailedView:
5279 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"));
5280 case SP_FileDialogInfoView:
5281 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"));
5282 case SP_FileDialogContentsView:
5283 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"));
5284 case SP_FileDialogListView:
5285 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"));
5286 case SP_FileDialogBack:
5287 return proxy()->standardPixmap(standardPixmap: SP_ArrowBack, opt: option);
5288 case SP_DriveHDIcon:
5289 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/harddrive-16.png"));
5290 case SP_TrashIcon:
5291 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"));
5292 case SP_DriveFDIcon:
5293 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/floppy-16.png"));
5294 case SP_DriveNetIcon:
5295 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/networkdrive-16.png"));
5296 case SP_DesktopIcon:
5297 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/desktop-16.png"));
5298 case SP_ComputerIcon:
5299 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/computer-16.png"));
5300 case SP_DriveCDIcon:
5301 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"));
5302 case SP_DriveDVDIcon:
5303 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"));
5304 case SP_DirHomeIcon:
5305 case SP_DirOpenIcon:
5306 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"));
5307 case SP_DirIcon:
5308 case SP_DirClosedIcon:
5309 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"));
5310 case SP_DirLinkIcon:
5311 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirlink-16.png"));
5312 case SP_FileIcon:
5313 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
5314 case SP_FileLinkIcon:
5315 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"));
5316 case SP_DialogOkButton:
5317 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"));
5318 case SP_DialogCancelButton:
5319 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"));
5320 case SP_DialogHelpButton:
5321 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"));
5322 case SP_DialogOpenButton:
5323 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"));
5324 case SP_DialogSaveButton:
5325 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"));
5326 case SP_DialogCloseButton:
5327 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"));
5328 case SP_DialogApplyButton:
5329 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"));
5330 case SP_DialogResetButton:
5331 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"));
5332 case SP_DialogDiscardButton:
5333 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"));
5334 case SP_DialogYesButton:
5335 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"));
5336 case SP_DialogNoButton:
5337 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"));
5338 case SP_BrowserReload:
5339 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"));
5340 case SP_BrowserStop:
5341 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"));
5342 case SP_MediaPlay:
5343 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"));
5344 case SP_MediaPause:
5345 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"));
5346 case SP_MediaStop:
5347 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"));
5348 case SP_MediaSeekForward:
5349 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"));
5350 case SP_MediaSeekBackward:
5351 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"));
5352 case SP_MediaSkipForward:
5353 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"));
5354 case SP_MediaSkipBackward:
5355 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"));
5356 case SP_MediaVolume:
5357 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"));
5358 case SP_MediaVolumeMuted:
5359 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"));
5360 case SP_LineEditClearButton:
5361 return QPixmap(clearText16IconPath());
5362#endif // QT_NO_IMAGEFORMAT_PNG
5363 default:
5364 break;
5365 }
5366
5367#ifndef QT_NO_IMAGEFORMAT_XPM
5368 switch (sp) {
5369 case SP_TitleBarMenuButton:
5370 return titleBarMenuCachedPixmapFromXPM();
5371 case SP_TitleBarShadeButton:
5372 return cachedPixmapFromXPM(xpm: qt_shade_xpm);
5373 case SP_TitleBarUnshadeButton:
5374 return cachedPixmapFromXPM(xpm: qt_unshade_xpm);
5375 case SP_TitleBarNormalButton:
5376 return cachedPixmapFromXPM(xpm: qt_normalizeup_xpm);
5377 case SP_TitleBarMinButton:
5378 return cachedPixmapFromXPM(xpm: qt_minimize_xpm);
5379 case SP_TitleBarMaxButton:
5380 return cachedPixmapFromXPM(xpm: qt_maximize_xpm);
5381 case SP_TitleBarCloseButton:
5382 return cachedPixmapFromXPM(xpm: qt_close_xpm);
5383 case SP_TitleBarContextHelpButton:
5384 return cachedPixmapFromXPM(xpm: qt_help_xpm);
5385 case SP_DockWidgetCloseButton:
5386 return cachedPixmapFromXPM(xpm: dock_widget_close_xpm);
5387 case SP_MessageBoxInformation:
5388 return cachedPixmapFromXPM(xpm: information_xpm);
5389 case SP_MessageBoxWarning:
5390 return cachedPixmapFromXPM(xpm: warning_xpm);
5391 case SP_MessageBoxCritical:
5392 return cachedPixmapFromXPM(xpm: critical_xpm);
5393 case SP_MessageBoxQuestion:
5394 return cachedPixmapFromXPM(xpm: question_xpm);
5395 default:
5396 break;
5397 }
5398#endif //QT_NO_IMAGEFORMAT_XPM
5399
5400#if !QT_CONFIG(imageformat_png) && !QT_CONFIG(imageformat_xpm)
5401 Q_UNUSED(rtl);
5402#endif
5403
5404 return QPixmap();
5405}
5406
5407#if QT_CONFIG(imageformat_png)
5408static inline QString iconResourcePrefix() { return QStringLiteral(":/qt-project.org/styles/commonstyle/images/"); }
5409static inline QString iconPngSuffix() { return QStringLiteral(".png"); }
5410
5411static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon)
5412{
5413 for (size_t i = 0; i < count; ++i)
5414 icon.addFile(fileName: prefix + QString::number(sizes[i]) + iconPngSuffix());
5415}
5416
5417static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64};
5418static const int titleBarSizes[] = {16, 32, 48};
5419static const int toolBarExtHSizes[] = {8, 16, 32};
5420static const int toolBarExtVSizes[] = {5, 10, 20};
5421#endif // imageformat_png
5422
5423/*!
5424 \internal
5425*/
5426QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option) const
5427{
5428 QIcon icon;
5429 const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft());
5430
5431#ifdef Q_OS_WIN
5432 switch (standardIcon) {
5433 case SP_DriveCDIcon:
5434 case SP_DriveDVDIcon:
5435 case SP_DriveNetIcon:
5436 case SP_DriveHDIcon:
5437 case SP_DriveFDIcon:
5438 case SP_FileIcon:
5439 case SP_FileLinkIcon:
5440 case SP_DesktopIcon:
5441 case SP_ComputerIcon:
5442 case SP_VistaShield:
5443 case SP_MessageBoxInformation:
5444 case SP_MessageBoxWarning:
5445 case SP_MessageBoxCritical:
5446 case SP_MessageBoxQuestion:
5447 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
5448 QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
5449 for (int size = 16 ; size <= 32 ; size += 16) {
5450 QPixmap pixmap = theme->standardPixmap(sp, QSizeF(size, size));
5451 icon.addPixmap(pixmap, QIcon::Normal);
5452 }
5453 }
5454 break;
5455 case SP_DirIcon:
5456 case SP_DirLinkIcon:
5457 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
5458 QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
5459 QPlatformTheme::StandardPixmap spOn = standardIcon == SP_DirIcon ? QPlatformTheme::DirOpenIcon :
5460 QPlatformTheme::DirLinkOpenIcon;
5461 for (int size = 16 ; size <= 32 ; size += 16) {
5462 QSizeF pixSize(size, size);
5463 QPixmap pixmap = theme->standardPixmap(spOff, pixSize);
5464 icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
5465 pixmap = theme->standardPixmap(spOn, pixSize);
5466 icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
5467 }
5468 }
5469 break;
5470 case SP_LineEditClearButton:
5471 icon = clearTextIcon(rtl);
5472 break;
5473 default:
5474 break;
5475 }
5476 if (!icon.isNull())
5477 return icon;
5478
5479#endif
5480
5481 if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
5482 switch (standardIcon) {
5483 case SP_DirHomeIcon:
5484 icon = QIcon::fromTheme(name: QLatin1String("user-home"));
5485 break;
5486 case SP_MessageBoxInformation:
5487 icon = QIcon::fromTheme(name: QLatin1String("dialog-information"));
5488 break;
5489 case SP_MessageBoxWarning:
5490 icon = QIcon::fromTheme(name: QLatin1String("dialog-warning"));
5491 break;
5492 case SP_MessageBoxCritical:
5493 icon = QIcon::fromTheme(name: QLatin1String("dialog-error"));
5494 break;
5495 case SP_MessageBoxQuestion:
5496 icon = QIcon::fromTheme(name: QLatin1String("dialog-question"));
5497 break;
5498 case SP_DialogOpenButton:
5499 case SP_DirOpenIcon:
5500 icon = QIcon::fromTheme(name: QLatin1String("folder-open"));
5501 break;
5502 case SP_DialogSaveButton:
5503 icon = QIcon::fromTheme(name: QLatin1String("document-save"));
5504 break;
5505 case SP_DialogApplyButton:
5506 icon = QIcon::fromTheme(name: QLatin1String("dialog-ok-apply"));
5507 break;
5508 case SP_DialogYesButton:
5509 case SP_DialogOkButton:
5510 icon = QIcon::fromTheme(name: QLatin1String("dialog-ok"));
5511 break;
5512 case SP_DialogDiscardButton:
5513 icon = QIcon::fromTheme(name: QLatin1String("edit-delete"));
5514 break;
5515 case SP_DialogResetButton:
5516 icon = QIcon::fromTheme(name: QLatin1String("edit-clear"));
5517 break;
5518 case SP_DialogHelpButton:
5519 icon = QIcon::fromTheme(name: QLatin1String("help-contents"));
5520 break;
5521 case SP_FileIcon:
5522 icon = QIcon::fromTheme(name: QLatin1String("text-x-generic"));
5523 break;
5524 case SP_DirClosedIcon:
5525 case SP_DirIcon:
5526 icon = QIcon::fromTheme(name: QLatin1String("folder"));
5527 break;
5528 case SP_DriveFDIcon:
5529 icon = QIcon::fromTheme(name: QLatin1String("floppy_unmount"));
5530 break;
5531 case SP_ComputerIcon:
5532 icon = QIcon::fromTheme(name: QLatin1String("computer"),
5533 fallback: QIcon::fromTheme(name: QLatin1String("system")));
5534 break;
5535 case SP_DesktopIcon:
5536 icon = QIcon::fromTheme(name: QLatin1String("user-desktop"));
5537 break;
5538 case SP_TrashIcon:
5539 icon = QIcon::fromTheme(name: QLatin1String("user-trash"));
5540 break;
5541 case SP_DriveCDIcon:
5542 case SP_DriveDVDIcon:
5543 icon = QIcon::fromTheme(name: QLatin1String("media-optical"));
5544 break;
5545 case SP_DriveHDIcon:
5546 icon = QIcon::fromTheme(name: QLatin1String("drive-harddisk"));
5547 break;
5548 case SP_FileDialogToParent:
5549 icon = QIcon::fromTheme(name: QLatin1String("go-up"));
5550 break;
5551 case SP_FileDialogNewFolder:
5552 icon = QIcon::fromTheme(name: QLatin1String("folder-new"));
5553 break;
5554 case SP_ArrowUp:
5555 icon = QIcon::fromTheme(name: QLatin1String("go-up"));
5556 break;
5557 case SP_ArrowDown:
5558 icon = QIcon::fromTheme(name: QLatin1String("go-down"));
5559 break;
5560 case SP_ArrowRight:
5561 icon = QIcon::fromTheme(name: QLatin1String("go-next"));
5562 break;
5563 case SP_ArrowLeft:
5564 icon = QIcon::fromTheme(name: QLatin1String("go-previous"));
5565 break;
5566 case SP_DialogNoButton:
5567 case SP_DialogCancelButton:
5568 icon = QIcon::fromTheme(name: QLatin1String("dialog-cancel"),
5569 fallback: QIcon::fromTheme(name: QLatin1String("process-stop")));
5570 break;
5571 case SP_DialogCloseButton:
5572 icon = QIcon::fromTheme(name: QLatin1String("window-close"));
5573 break;
5574 case SP_FileDialogDetailedView:
5575 icon = QIcon::fromTheme(name: QLatin1String("view-list-details"));
5576 break;
5577 case SP_FileDialogListView:
5578 icon = QIcon::fromTheme(name: QLatin1String("view-list-icons"));
5579 break;
5580 case SP_BrowserReload:
5581 icon = QIcon::fromTheme(name: QLatin1String("view-refresh"));
5582 break;
5583 case SP_BrowserStop:
5584 icon = QIcon::fromTheme(name: QLatin1String("process-stop"));
5585 break;
5586 case SP_MediaPlay:
5587 icon = QIcon::fromTheme(name: QLatin1String("media-playback-start"));
5588 break;
5589 case SP_MediaPause:
5590 icon = QIcon::fromTheme(name: QLatin1String("media-playback-pause"));
5591 break;
5592 case SP_MediaStop:
5593 icon = QIcon::fromTheme(name: QLatin1String("media-playback-stop"));
5594 break;
5595 case SP_MediaSeekForward:
5596 icon = QIcon::fromTheme(name: QLatin1String("media-seek-forward"));
5597 break;
5598 case SP_MediaSeekBackward:
5599 icon = QIcon::fromTheme(name: QLatin1String("media-seek-backward"));
5600 break;
5601 case SP_MediaSkipForward:
5602 icon = QIcon::fromTheme(name: QLatin1String("media-skip-forward"));
5603 break;
5604 case SP_MediaSkipBackward:
5605 icon = QIcon::fromTheme(name: QLatin1String("media-skip-backward"));
5606 break;
5607 case SP_MediaVolume:
5608 icon = QIcon::fromTheme(name: QLatin1String("audio-volume-medium"));
5609 break;
5610 case SP_MediaVolumeMuted:
5611 icon = QIcon::fromTheme(name: QLatin1String("audio-volume-muted"));
5612 break;
5613 case SP_ArrowForward:
5614 if (rtl)
5615 return QCommonStyle::standardIcon(standardIcon: SP_ArrowLeft, option);
5616 return QCommonStyle::standardIcon(standardIcon: SP_ArrowRight, option);
5617 case SP_ArrowBack:
5618 if (rtl)
5619 return QCommonStyle::standardIcon(standardIcon: SP_ArrowRight, option);
5620 return QCommonStyle::standardIcon(standardIcon: SP_ArrowLeft, option);
5621 case SP_FileLinkIcon:
5622 {
5623 QIcon linkIcon = QIcon::fromTheme(name: QLatin1String("emblem-symbolic-link"));
5624 if (!linkIcon.isNull()) {
5625 QIcon baseIcon = QCommonStyle::standardIcon(standardIcon: SP_FileIcon, option);
5626 const QList<QSize> sizes = baseIcon.availableSizes(mode: QIcon::Normal, state: QIcon::Off);
5627 const qreal devicePixelRatio = option ? dpr(w: option->window) : 1.;
5628 for (int i = 0 ; i < sizes.size() ; ++i) {
5629 int size = sizes[i].width();
5630 QPixmap basePixmap = baseIcon.pixmap(size: QSize(size, size), devicePixelRatio);
5631 QPixmap linkPixmap = linkIcon.pixmap(size: QSize(size / 2, size / 2), devicePixelRatio);
5632 QPainter painter(&basePixmap);
5633 painter.drawPixmap(x: size/2, y: size/2, pm: linkPixmap);
5634 icon.addPixmap(pixmap: basePixmap);
5635 }
5636 }
5637 }
5638 break;
5639 case SP_DirLinkIcon:
5640 {
5641 QIcon linkIcon = QIcon::fromTheme(name: QLatin1String("emblem-symbolic-link"));
5642 if (!linkIcon.isNull()) {
5643 QIcon baseIcon = QCommonStyle::standardIcon(standardIcon: SP_DirIcon, option);
5644 const QList<QSize> sizes = baseIcon.availableSizes(mode: QIcon::Normal, state: QIcon::Off);
5645 const qreal devicePixelRatio = option ? dpr(w: option->window) : 1.;
5646 for (int i = 0 ; i < sizes.size() ; ++i) {
5647 int size = sizes[i].width();
5648 QPixmap basePixmap = baseIcon.pixmap(size: QSize(size, size), devicePixelRatio);
5649 QPixmap linkPixmap = linkIcon.pixmap(size: QSize(size / 2, size / 2), devicePixelRatio);
5650 QPainter painter(&basePixmap);
5651 painter.drawPixmap(x: size/2, y: size/2, pm: linkPixmap);
5652 icon.addPixmap(pixmap: basePixmap);
5653 }
5654 }
5655 }
5656 break;
5657 default:
5658 break;
5659 }
5660 } // if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
5661
5662 if (!icon.isNull())
5663 return icon;
5664
5665#if defined(Q_OS_MACOS)
5666 if (QGuiApplication::desktopSettingsAware()) {
5667 switch (standardIcon) {
5668 case SP_DirIcon: {
5669 // A rather special case
5670 QIcon closeIcon = QCommonStyle::standardIcon(SP_DirClosedIcon, option);
5671 QIcon openIcon = QCommonStyle::standardIcon(SP_DirOpenIcon, option);
5672 closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
5673 closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
5674 closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
5675 closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
5676 return closeIcon;
5677 }
5678
5679 case SP_TitleBarNormalButton:
5680 case SP_TitleBarCloseButton: {
5681 QIcon titleBarIcon;
5682 if (standardIcon == SP_TitleBarCloseButton) {
5683 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-16.png"));
5684 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
5685 } else {
5686 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-16.png"));
5687 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
5688 }
5689 return titleBarIcon;
5690 }
5691
5692 case SP_MessageBoxQuestion:
5693 case SP_MessageBoxInformation:
5694 case SP_MessageBoxWarning:
5695 case SP_MessageBoxCritical:
5696 case SP_DesktopIcon:
5697 case SP_TrashIcon:
5698 case SP_ComputerIcon:
5699 case SP_DriveFDIcon:
5700 case SP_DriveHDIcon:
5701 case SP_DriveCDIcon:
5702 case SP_DriveDVDIcon:
5703 case SP_DriveNetIcon:
5704 case SP_DirOpenIcon:
5705 case SP_DirClosedIcon:
5706 case SP_DirLinkIcon:
5707 case SP_FileLinkIcon:
5708 case SP_FileIcon:
5709 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
5710 QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
5711 QIcon retIcon;
5712 const QList<QSize> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<QSize> >();
5713 for (const QSize &size : sizes) {
5714 QPixmap mainIcon;
5715 const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size.width());
5716 if (standardIcon >= QStyle::SP_CustomBase) {
5717 mainIcon = theme->standardPixmap(sp, QSizeF(size));
5718 } else if (QPixmapCache::find(cacheKey, &mainIcon) == false) {
5719 mainIcon = theme->standardPixmap(sp, QSizeF(size));
5720 QPixmapCache::insert(cacheKey, mainIcon);
5721 }
5722
5723 retIcon.addPixmap(mainIcon);
5724 }
5725 if (!retIcon.isNull())
5726 return retIcon;
5727 }
5728
5729 default:
5730 break;
5731 }
5732 } // if (QGuiApplication::desktopSettingsAware())
5733#endif // Q_OS_MACOS
5734
5735 switch (standardIcon) {
5736#ifndef QT_NO_IMAGEFORMAT_PNG
5737 case SP_TitleBarMinButton:
5738 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("titlebar-min-"),
5739 sizes: titleBarSizes, count: sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
5740 break;
5741 case SP_TitleBarMaxButton:
5742 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("titlebar-max-"),
5743 sizes: titleBarSizes, count: sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
5744 break;
5745 case SP_TitleBarShadeButton:
5746 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("titlebar-shade-"),
5747 sizes: titleBarSizes, count: sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
5748
5749 break;
5750 case SP_TitleBarUnshadeButton:
5751 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("titlebar-unshade-"),
5752 sizes: titleBarSizes, count: sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
5753 break;
5754 case SP_TitleBarContextHelpButton:
5755 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"),
5756 sizes: titleBarSizes, count: sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
5757 break;
5758 case SP_FileDialogNewFolder:
5759 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), size: QSize(16, 16));
5760 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), size: QSize(32, 32));
5761 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-128.png"), size: QSize(128, 128));
5762 break;
5763 case SP_FileDialogBack:
5764 return QCommonStyle::standardIcon(standardIcon: SP_ArrowBack, option);
5765 case SP_FileDialogToParent:
5766 return QCommonStyle::standardIcon(standardIcon: SP_ArrowUp, option);
5767 case SP_FileDialogDetailedView:
5768 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"), size: QSize(16, 16));
5769 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-32.png"), size: QSize(32, 32));
5770 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-128.png"), size: QSize(128, 128));
5771 break;
5772 case SP_FileDialogInfoView:
5773 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"), size: QSize(16, 16));
5774 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-32.png"), size: QSize(32, 32));
5775 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-128.png"), size: QSize(128, 128));
5776 break;
5777 case SP_FileDialogContentsView:
5778 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"), size: QSize(16, 16));
5779 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-32.png"), size: QSize(32, 32));
5780 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-128.png"), size: QSize(128, 128));
5781 break;
5782 case SP_FileDialogListView:
5783 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"), size: QSize(16, 16));
5784 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-32.png"), size: QSize(32, 32));
5785 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-128.png"), size: QSize(128, 128));
5786 break;
5787 case SP_DialogOkButton:
5788 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"), size: QSize(16, 16));
5789 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-32.png"), size: QSize(32, 32));
5790 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-128.png"), size: QSize(128, 128));
5791 break;
5792 case SP_DialogCancelButton:
5793 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"), size: QSize(16, 16));
5794 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-32.png"), size: QSize(32, 32));
5795 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-128.png"), size: QSize(128, 128));
5796 break;
5797 case SP_DialogHelpButton:
5798 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"), size: QSize(16, 16));
5799 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-32.png"), size: QSize(32, 32));
5800 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-128.png"), size: QSize(128, 128));
5801 break;
5802 case SP_DialogOpenButton:
5803 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"), size: QSize(16, 16));
5804 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png"), size: QSize(32, 32));
5805 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png"), size: QSize(128, 128));
5806 break;
5807 case SP_DialogSaveButton:
5808 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"), size: QSize(16, 16));
5809 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png"), size: QSize(32, 32));
5810 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png"), size: QSize(128, 128));
5811 break;
5812 case SP_DialogCloseButton:
5813 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"), size: QSize(16, 16));
5814 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-32.png"), size: QSize(32, 32));
5815 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-128.png"), size: QSize(128, 128));
5816 break;
5817 case SP_DialogApplyButton:
5818 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"), size: QSize(16, 16));
5819 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-32.png"), size: QSize(32, 32));
5820 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-128.png"), size: QSize(128, 128));
5821 break;
5822 case SP_DialogResetButton:
5823 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"), size: QSize(16, 16));
5824 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-32.png"), size: QSize(32, 32));
5825 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-128.png"), size: QSize(128, 128));
5826 break;
5827 case SP_DialogDiscardButton:
5828 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"), size: QSize(16, 16));
5829 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-32.png"), size: QSize(32, 32));
5830 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-128.png"), size: QSize(128, 128));
5831 break;
5832 case SP_DialogYesButton:
5833 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"), size: QSize(16, 16));
5834 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-32.png"), size: QSize(32, 32));
5835 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-128.png"), size: QSize(128, 128));
5836 break;
5837 case SP_DialogNoButton:
5838 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"), size: QSize(16, 16));
5839 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-32.png"), size: QSize(32, 32));
5840 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-128.png"), size: QSize(128, 128));
5841 break;
5842 case SP_ArrowForward:
5843 if (rtl)
5844 return QCommonStyle::standardIcon(standardIcon: SP_ArrowLeft, option);
5845 return QCommonStyle::standardIcon(standardIcon: SP_ArrowRight, option);
5846 case SP_ArrowBack:
5847 if (rtl)
5848 return QCommonStyle::standardIcon(standardIcon: SP_ArrowRight, option);
5849 return QCommonStyle::standardIcon(standardIcon: SP_ArrowLeft, option);
5850 case SP_ArrowLeft:
5851 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"), size: QSize(16, 16));
5852 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/left-32.png"), size: QSize(32, 32));
5853 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/left-128.png"), size: QSize(128, 128));
5854 break;
5855 case SP_ArrowRight:
5856 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"), size: QSize(16, 16));
5857 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/right-32.png"), size: QSize(32, 32));
5858 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/right-128.png"), size: QSize(128, 128));
5859 break;
5860 case SP_ArrowUp:
5861 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"), size: QSize(16, 16));
5862 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/up-32.png"), size: QSize(32, 32));
5863 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/up-128.png"), size: QSize(128, 128));
5864 break;
5865 case SP_ArrowDown:
5866 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"), size: QSize(16, 16));
5867 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/down-32.png"), size: QSize(32, 32));
5868 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/down-128.png"), size: QSize(128, 128));
5869 break;
5870 case SP_DirHomeIcon:
5871 case SP_DirIcon:
5872 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"),
5873 size: QSize(), mode: QIcon::Normal, state: QIcon::Off);
5874 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"),
5875 size: QSize(), mode: QIcon::Normal, state: QIcon::On);
5876 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-32.png"),
5877 size: QSize(32, 32), mode: QIcon::Normal, state: QIcon::Off);
5878 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-32.png"),
5879 size: QSize(32, 32), mode: QIcon::Normal, state: QIcon::On);
5880 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-128.png"),
5881 size: QSize(128, 128), mode: QIcon::Normal, state: QIcon::Off);
5882 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-128.png"),
5883 size: QSize(128, 128), mode: QIcon::Normal, state: QIcon::On);
5884 break;
5885 case SP_DriveCDIcon:
5886 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"), size: QSize(16, 16));
5887 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-32.png"), size: QSize(32, 32));
5888 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-128.png"), size: QSize(128, 128));
5889 break;
5890 case SP_DriveDVDIcon:
5891 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"), size: QSize(16, 16));
5892 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-32.png"), size: QSize(32, 32));
5893 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-128.png"), size: QSize(128, 128));
5894 break;
5895 case SP_FileIcon:
5896 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"), size: QSize(16, 16));
5897 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/file-32.png"), size: QSize(32, 32));
5898 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/file-128.png"), size: QSize(128, 128));
5899 break;
5900 case SP_FileLinkIcon:
5901 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"), size: QSize(16, 16));
5902 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-32.png"), size: QSize(32, 32));
5903 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-128.png"), size: QSize(128, 128));
5904 break;
5905 case SP_TrashIcon:
5906 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"), size: QSize(16, 16));
5907 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-32.png"), size: QSize(32, 32));
5908 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-128.png"), size: QSize(128, 128));
5909 break;
5910 case SP_BrowserReload:
5911 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"), size: QSize(24, 24));
5912 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-32.png"), size: QSize(32, 32));
5913 break;
5914 case SP_BrowserStop:
5915 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"), size: QSize(24, 24));
5916 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-32.png"), size: QSize(32, 32));
5917 break;
5918 case SP_MediaPlay:
5919 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-16.png"), size: QSize(16, 16));
5920 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"), size: QSize(32, 32));
5921 break;
5922 case SP_MediaPause:
5923 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-16.png"), size: QSize(16, 16));
5924 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"), size: QSize(32, 32));
5925 break;
5926 case SP_MediaStop:
5927 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-16.png"), size: QSize(16, 16));
5928 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"), size: QSize(32, 32));
5929 break;
5930 case SP_MediaSeekForward:
5931 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-16.png"), size: QSize(16, 16));
5932 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"), size: QSize(32, 32));
5933 break;
5934 case SP_MediaSeekBackward:
5935 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-16.png"), size: QSize(16, 16));
5936 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"), size: QSize(32, 32));
5937 break;
5938 case SP_MediaSkipForward:
5939 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-16.png"), size: QSize(16, 16));
5940 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"), size: QSize(32, 32));
5941 break;
5942 case SP_MediaSkipBackward:
5943 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-16.png"), size: QSize(16, 16));
5944 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"), size: QSize(32, 32));
5945 break;
5946 case SP_MediaVolume:
5947 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"), size: QSize(16, 16));
5948 break;
5949 case SP_MediaVolumeMuted:
5950 icon.addFile(fileName: QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"), size: QSize(16, 16));
5951 break;
5952 case SP_TitleBarCloseButton:
5953 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("closedock-"),
5954 sizes: dockTitleIconSizes, count: sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
5955 break;
5956 case SP_TitleBarMenuButton:
5957# ifndef QT_NO_IMAGEFORMAT_XPM
5958 icon.addPixmap(pixmap: titleBarMenuCachedPixmapFromXPM());
5959# endif
5960 icon.addFile(fileName: QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png"));
5961 break;
5962 case SP_TitleBarNormalButton:
5963 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("normalizedockup-"),
5964 sizes: dockTitleIconSizes, count: sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
5965 break;
5966 case SP_ToolBarHorizontalExtensionButton: {
5967 QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-");
5968 if (rtl)
5969 prefix += QStringLiteral("rtl-");
5970 addIconFiles(prefix, sizes: toolBarExtHSizes, count: sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon);
5971 }
5972 break;
5973 case SP_ToolBarVerticalExtensionButton:
5974 addIconFiles(prefix: iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"),
5975 sizes: toolBarExtVSizes, count: sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon);
5976 break;
5977#endif // QT_NO_IMAGEFORMAT_PNG
5978 default:
5979 icon.addPixmap(pixmap: proxy()->standardPixmap(standardPixmap: standardIcon, opt: option));
5980 break;
5981 }
5982 return icon;
5983}
5984
5985static inline uint qt_intensity(uint r, uint g, uint b)
5986{
5987 // 30% red, 59% green, 11% blue
5988 return (77 * r + 150 * g + 28 * b) / 255;
5989}
5990
5991/*! \reimp */
5992QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
5993 const QStyleOption *opt) const
5994{
5995 switch (iconMode) {
5996 case QIcon::Disabled: {
5997 QImage im = pixmap.toImage().convertToFormat(f: QImage::Format_ARGB32);
5998
5999 // Create a colortable based on the background (black -> bg -> white)
6000 const QColor bg = opt->palette.color(cg: QPalette::Disabled, cr: QPalette::Window).toRgb();
6001 int red = bg.red();
6002 int green = bg.green();
6003 int blue = bg.blue();
6004 uchar reds[256], greens[256], blues[256];
6005 for (int i=0; i<128; ++i) {
6006 reds[i] = uchar((red * (i<<1)) >> 8);
6007 greens[i] = uchar((green * (i<<1)) >> 8);
6008 blues[i] = uchar((blue * (i<<1)) >> 8);
6009 }
6010 for (int i=0; i<128; ++i) {
6011 reds[i+128] = uchar(qMin(a: red + (i << 1), b: 255));
6012 greens[i+128] = uchar(qMin(a: green + (i << 1), b: 255));
6013 blues[i+128] = uchar(qMin(a: blue + (i << 1), b: 255));
6014 }
6015
6016 int intensity = qt_intensity(r: red, g: green, b: blue);
6017 const int factor = 191;
6018
6019 // High intensity colors needs dark shifting in the color table, while
6020 // low intensity colors needs light shifting. This is to increase the
6021 // perceived contrast.
6022 if ((red - factor > green && red - factor > blue)
6023 || (green - factor > red && green - factor > blue)
6024 || (blue - factor > red && blue - factor > green))
6025 intensity = qMin(a: 255, b: intensity + 91);
6026 else if (intensity <= 128)
6027 intensity -= 51;
6028
6029 for (int y=0; y<im.height(); ++y) {
6030 QRgb *scanLine = (QRgb*)im.scanLine(y);
6031 for (int x=0; x<im.width(); ++x) {
6032 QRgb pixel = *scanLine;
6033 // Calculate color table index, taking intensity adjustment
6034 // and a magic offset into account.
6035 uint ci = uint(qGray(rgb: pixel)/3 + (130 - intensity / 3));
6036 *scanLine = qRgba(r: reds[ci], g: greens[ci], b: blues[ci], a: qAlpha(rgb: pixel));
6037 ++scanLine;
6038 }
6039 }
6040
6041 return QPixmap::fromImage(image: std::move(im));
6042 }
6043 case QIcon::Selected: {
6044 QImage img = pixmap.toImage().convertToFormat(f: QImage::Format_ARGB32_Premultiplied);
6045 QColor color = opt->palette.color(cg: QPalette::Normal, cr: QPalette::Highlight);
6046 color.setAlphaF(0.3f);
6047 QPainter painter(&img);
6048 painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
6049 painter.fillRect(x: 0, y: 0, w: img.width(), h: img.height(), b: color);
6050 painter.end();
6051 return QPixmap::fromImage(image: std::move(img)); }
6052 case QIcon::Active:
6053 return pixmap;
6054 default:
6055 break;
6056 }
6057 return pixmap;
6058}
6059
6060} // namespace QQC2
6061
6062QT_END_NAMESPACE
6063
6064#include "moc_qquickcommonstyle.cpp"
6065

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/quicknativestyle/qstyle/qquickcommonstyle.cpp