1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Controls module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickstyleitem_p.h"
41
42#include <qstringbuilder.h>
43#include <qpainter.h>
44#include <qpixmapcache.h>
45#include <qstyle.h>
46#include <qstyleoption.h>
47#include <qapplication.h>
48#include <qquickwindow.h>
49#include "private/qguiapplication_p.h"
50#include <QtQuick/private/qquickwindow_p.h>
51#include <QtQuick/private/qquickitem_p.h>
52#include <QtGui/qpa/qplatformtheme.h>
53#include <QtQuick/qsgninepatchnode.h>
54#include "../qquickmenuitem_p.h"
55
56QT_BEGIN_NAMESPACE
57
58#ifdef Q_OS_OSX
59#include <Carbon/Carbon.h>
60
61static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
62{
63 return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
64 convertRect.width() - rect.width(), convertRect.height() - rect.height());
65}
66
67/*! \internal
68
69 Returns the CoreGraphics CGContextRef of the paint device. 0 is
70 returned if it can't be obtained. It is the caller's responsibility to
71 CGContextRelease the context when finished using it.
72
73 \warning This function is only available on \macos.
74 \warning This function is duplicated in qmacstyle_mac.mm
75*/
76CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
77{
78
79 if (pdev->devType() == QInternal::Image) {
80 const QImage *i = static_cast<const QImage*>(pdev);
81 QImage *image = const_cast< QImage*>(i);
82 CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
83 uint flags = kCGImageAlphaPremultipliedFirst;
84 flags |= kCGBitmapByteOrder32Host;
85 CGContextRef ret = 0;
86
87 ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
88 8, image->bytesPerLine(), colorspace, flags);
89
90 CGContextTranslateCTM(ret, 0, image->height());
91 CGContextScaleCTM(ret, 1, -1);
92 return ret;
93 }
94 return 0;
95}
96
97#endif
98
99QQuickStyleItem1::QQuickStyleItem1(QQuickItem *parent)
100 : QQuickItem(parent),
101 m_styleoption(0),
102 m_itemType(Undefined),
103 m_sunken(false),
104 m_raised(false),
105 m_active(true),
106 m_selected(false),
107 m_focus(false),
108 m_hover(false),
109 m_on(false),
110 m_horizontal(true),
111 m_transient(false),
112 m_sharedWidget(false),
113 m_minimum(0),
114 m_maximum(100),
115 m_value(0),
116 m_step(0),
117 m_paintMargins(0),
118 m_contentWidth(0),
119 m_contentHeight(0),
120 m_textureWidth(0),
121 m_textureHeight(0)
122{
123 m_font = qApp->font();
124 setFlag(flag: QQuickItem::ItemHasContents, enabled: true);
125 setSmooth(false);
126
127 connect(sender: this, SIGNAL(visibleChanged()), receiver: this, SLOT(updateItem()));
128 connect(sender: this, SIGNAL(widthChanged()), receiver: this, SLOT(updateItem()));
129 connect(sender: this, SIGNAL(heightChanged()), receiver: this, SLOT(updateItem()));
130 connect(sender: this, SIGNAL(enabledChanged()), receiver: this, SLOT(updateItem()));
131 connect(sender: this, SIGNAL(infoChanged()), receiver: this, SLOT(updateItem()));
132 connect(sender: this, SIGNAL(onChanged()), receiver: this, SLOT(updateItem()));
133 connect(sender: this, SIGNAL(selectedChanged()), receiver: this, SLOT(updateItem()));
134 connect(sender: this, SIGNAL(activeChanged()), receiver: this, SLOT(updateItem()));
135 connect(sender: this, SIGNAL(textChanged()), receiver: this, SLOT(updateSizeHint()));
136 connect(sender: this, SIGNAL(textChanged()), receiver: this, SLOT(updateItem()));
137 connect(sender: this, SIGNAL(activeChanged()), receiver: this, SLOT(updateItem()));
138 connect(sender: this, SIGNAL(raisedChanged()), receiver: this, SLOT(updateItem()));
139 connect(sender: this, SIGNAL(sunkenChanged()), receiver: this, SLOT(updateItem()));
140 connect(sender: this, SIGNAL(hoverChanged()), receiver: this, SLOT(updateItem()));
141 connect(sender: this, SIGNAL(maximumChanged()), receiver: this, SLOT(updateItem()));
142 connect(sender: this, SIGNAL(minimumChanged()), receiver: this, SLOT(updateItem()));
143 connect(sender: this, SIGNAL(valueChanged()), receiver: this, SLOT(updateItem()));
144 connect(sender: this, SIGNAL(horizontalChanged()), receiver: this, SLOT(updateItem()));
145 connect(sender: this, SIGNAL(transientChanged()), receiver: this, SLOT(updateItem()));
146 connect(sender: this, SIGNAL(activeControlChanged()), receiver: this, SLOT(updateItem()));
147 connect(sender: this, SIGNAL(hasFocusChanged()), receiver: this, SLOT(updateItem()));
148 connect(sender: this, SIGNAL(activeControlChanged()), receiver: this, SLOT(updateItem()));
149 connect(sender: this, SIGNAL(hintChanged()), receiver: this, SLOT(updateItem()));
150 connect(sender: this, SIGNAL(propertiesChanged()), receiver: this, SLOT(updateSizeHint()));
151 connect(sender: this, SIGNAL(propertiesChanged()), receiver: this, SLOT(updateItem()));
152 connect(sender: this, SIGNAL(elementTypeChanged()), receiver: this, SLOT(updateItem()));
153 connect(sender: this, SIGNAL(contentWidthChanged(int)), receiver: this, SLOT(updateSizeHint()));
154 connect(sender: this, SIGNAL(contentHeightChanged(int)), receiver: this, SLOT(updateSizeHint()));
155 connect(sender: this, SIGNAL(widthChanged()), receiver: this, SLOT(updateRect()));
156 connect(sender: this, SIGNAL(heightChanged()), receiver: this, SLOT(updateRect()));
157
158 connect(sender: this, SIGNAL(heightChanged()), receiver: this, SLOT(updateBaselineOffset()));
159 connect(sender: this, SIGNAL(contentHeightChanged(int)), receiver: this, SLOT(updateBaselineOffset()));
160}
161
162QQuickStyleItem1::~QQuickStyleItem1()
163{
164 if (const QStyleOptionButton *aux = qstyleoption_cast<const QStyleOptionButton*>(opt: m_styleoption))
165 delete aux;
166#if QT_CONFIG(itemviews)
167 else if (const QStyleOptionViewItem *aux = qstyleoption_cast<const QStyleOptionViewItem*>(opt: m_styleoption))
168 delete aux;
169#endif
170 else if (const QStyleOptionHeader *aux = qstyleoption_cast<const QStyleOptionHeader*>(opt: m_styleoption))
171 delete aux;
172 else if (const QStyleOptionToolButton *aux = qstyleoption_cast<const QStyleOptionToolButton*>(opt: m_styleoption))
173 delete aux;
174#if QT_CONFIG(toolbar)
175 else if (const QStyleOptionToolBar *aux = qstyleoption_cast<const QStyleOptionToolBar*>(opt: m_styleoption))
176 delete aux;
177#endif
178#if QT_CONFIG(tabbar)
179 else if (const QStyleOptionTab *aux = qstyleoption_cast<const QStyleOptionTab*>(opt: m_styleoption))
180 delete aux;
181#endif
182 else if (const QStyleOptionFrame *aux = qstyleoption_cast<const QStyleOptionFrame*>(opt: m_styleoption))
183 delete aux;
184 else if (const QStyleOptionFocusRect *aux = qstyleoption_cast<const QStyleOptionFocusRect*>(opt: m_styleoption))
185 delete aux;
186#if QT_CONFIG(tabwidget)
187 else if (const QStyleOptionTabWidgetFrame *aux = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(opt: m_styleoption))
188 delete aux;
189#endif
190 else if (const QStyleOptionMenuItem *aux = qstyleoption_cast<const QStyleOptionMenuItem*>(opt: m_styleoption))
191 delete aux;
192 else if (const QStyleOptionComboBox *aux = qstyleoption_cast<const QStyleOptionComboBox*>(opt: m_styleoption))
193 delete aux;
194#if QT_CONFIG(spinbox)
195 else if (const QStyleOptionSpinBox *aux = qstyleoption_cast<const QStyleOptionSpinBox*>(opt: m_styleoption))
196 delete aux;
197#endif
198#if QT_CONFIG(slider)
199 else if (const QStyleOptionSlider *aux = qstyleoption_cast<const QStyleOptionSlider*>(opt: m_styleoption))
200 delete aux;
201#endif
202 else if (const QStyleOptionProgressBar *aux = qstyleoption_cast<const QStyleOptionProgressBar*>(opt: m_styleoption))
203 delete aux;
204 else if (const QStyleOptionGroupBox *aux = qstyleoption_cast<const QStyleOptionGroupBox*>(opt: m_styleoption))
205 delete aux;
206 else
207 delete m_styleoption;
208
209 m_styleoption = 0;
210}
211
212void QQuickStyleItem1::initStyleOption()
213{
214 if (m_styleoption)
215 m_styleoption->state = {};
216
217 QString sizeHint = m_hints.value(QStringLiteral("size")).toString();
218 QPlatformTheme::Font platformFont = (sizeHint == QLatin1String("mini")) ? QPlatformTheme::MiniFont :
219 (sizeHint == QLatin1String("small")) ? QPlatformTheme::SmallFont :
220 QPlatformTheme::SystemFont;
221
222 bool needsResolvePalette = true;
223
224 switch (m_itemType) {
225 case Button: {
226 if (!m_styleoption)
227 m_styleoption = new QStyleOptionButton();
228
229 QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(opt: m_styleoption);
230 opt->text = text();
231 opt->icon = m_properties[QStringLiteral("icon")].value<QIcon>();
232 int e = qApp->style()->pixelMetric(metric: QStyle::PM_ButtonIconSize, option: m_styleoption, widget: 0);
233 opt->iconSize = QSize(e, e);
234 opt->features = activeControl() == QLatin1String("default") ?
235 QStyleOptionButton::DefaultButton :
236 QStyleOptionButton::None;
237 if (platformFont == QPlatformTheme::SystemFont)
238 platformFont = QPlatformTheme::PushButtonFont;
239 const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: platformFont);
240 if (font)
241 opt->fontMetrics = QFontMetrics(*font);
242 QObject * menu = m_properties[QStringLiteral("menu")].value<QObject *>();
243 if (menu) {
244 opt->features |= QStyleOptionButton::HasMenu;
245#ifdef Q_OS_OSX
246 if (style() == QLatin1String("mac")) {
247 if (platformFont == QPlatformTheme::PushButtonFont)
248 menu->setProperty("__xOffset", 12);
249 else
250 menu->setProperty("__xOffset", 11);
251 if (platformFont == QPlatformTheme::MiniFont)
252 menu->setProperty("__yOffset", 5);
253 else if (platformFont == QPlatformTheme::SmallFont)
254 menu->setProperty("__yOffset", 6);
255 else
256 menu->setProperty("__yOffset", 3);
257 if (font)
258 menu->setProperty("__font", *font);
259 }
260#endif
261 }
262 }
263 break;
264#if QT_CONFIG(itemviews)
265 case ItemRow: {
266 if (!m_styleoption)
267 m_styleoption = new QStyleOptionViewItem();
268
269 QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(opt: m_styleoption);
270 opt->features = {};
271 if (activeControl() == QLatin1String("alternate"))
272 opt->features |= QStyleOptionViewItem::Alternate;
273 }
274 break;
275#endif // QT_CONFIG(itemviews)
276 case Splitter: {
277 if (!m_styleoption) {
278 m_styleoption = new QStyleOption;
279 }
280 }
281 break;
282#if QT_CONFIG(itemviews)
283 case Item: {
284 if (!m_styleoption) {
285 m_styleoption = new QStyleOptionViewItem();
286 }
287 QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(opt: m_styleoption);
288 opt->features = QStyleOptionViewItem::HasDisplay;
289 opt->text = text();
290 opt->textElideMode = Qt::ElideRight;
291 opt->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
292 opt->decorationAlignment = Qt::AlignCenter;
293 resolvePalette();
294 needsResolvePalette = false;
295 QPalette pal = m_styleoption->palette;
296 pal.setBrush(acr: QPalette::Base, abrush: Qt::NoBrush);
297 m_styleoption->palette = pal;
298 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: QPlatformTheme::ItemViewFont)) {
299 opt->fontMetrics = QFontMetrics(*font);
300 opt->font = *font;
301 }
302 }
303 break;
304#endif // QT_CONFIG(itemviews)
305 case ItemBranchIndicator: {
306 if (!m_styleoption)
307 m_styleoption = new QStyleOption;
308
309 m_styleoption->state = QStyle::State_Item; // We don't want to fully support Win 95
310 if (m_properties.value(QStringLiteral("hasChildren")).toBool())
311 m_styleoption->state |= QStyle::State_Children;
312 if (m_properties.value(QStringLiteral("hasSibling")).toBool()) // Even this one could go away
313 m_styleoption->state |= QStyle::State_Sibling;
314 if (m_on)
315 m_styleoption->state |= QStyle::State_Open;
316 }
317 break;
318 case Header: {
319 if (!m_styleoption)
320 m_styleoption = new QStyleOptionHeader();
321
322 QStyleOptionHeader *opt = qstyleoption_cast<QStyleOptionHeader*>(opt: m_styleoption);
323 opt->text = text();
324 opt->textAlignment = static_cast<Qt::AlignmentFlag>(m_properties.value(QStringLiteral("textalignment")).toInt());
325 opt->sortIndicator = activeControl() == QLatin1String("down") ?
326 QStyleOptionHeader::SortDown
327 : activeControl() == QLatin1String("up") ?
328 QStyleOptionHeader::SortUp : QStyleOptionHeader::None;
329 QString headerpos = m_properties.value(QStringLiteral("headerpos")).toString();
330 if (headerpos == QLatin1String("beginning"))
331 opt->position = QStyleOptionHeader::Beginning;
332 else if (headerpos == QLatin1String("end"))
333 opt->position = QStyleOptionHeader::End;
334 else if (headerpos == QLatin1String("only"))
335 opt->position = QStyleOptionHeader::OnlyOneSection;
336 else
337 opt->position = QStyleOptionHeader::Middle;
338 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: QPlatformTheme::HeaderViewFont))
339 opt->fontMetrics = QFontMetrics(*font);
340 }
341 break;
342 case ToolButton: {
343 if (!m_styleoption)
344 m_styleoption = new QStyleOptionToolButton();
345
346 QStyleOptionToolButton *opt =
347 qstyleoption_cast<QStyleOptionToolButton*>(opt: m_styleoption);
348 opt->subControls = QStyle::SC_ToolButton;
349 opt->state |= QStyle::State_AutoRaise;
350 opt->activeSubControls = QStyle::SC_ToolButton;
351 opt->text = text();
352 opt->icon = m_properties[QStringLiteral("icon")].value<QIcon>();
353
354 if (m_properties.value(QStringLiteral("menu")).toBool()) {
355 opt->subControls |= QStyle::SC_ToolButtonMenu;
356 opt->features = QStyleOptionToolButton::HasMenu;
357 }
358
359 // For now icon only is displayed by default.
360 opt->toolButtonStyle = Qt::ToolButtonIconOnly;
361 if (opt->icon.isNull() && !opt->text.isEmpty())
362 opt->toolButtonStyle = Qt::ToolButtonTextOnly;
363
364 int e = qApp->style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize, option: m_styleoption, widget: 0);
365 opt->iconSize = QSize(e, e);
366
367 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: QPlatformTheme::ToolButtonFont)) {
368 opt->fontMetrics = QFontMetrics(*font);
369 opt->font = *font;
370 }
371
372 }
373 break;
374#if QT_CONFIG(toolbar)
375 case ToolBar: {
376 if (!m_styleoption)
377 m_styleoption = new QStyleOptionToolBar();
378 }
379 break;
380#endif
381#if QT_CONFIG(tabbar)
382 case Tab: {
383 if (!m_styleoption)
384 m_styleoption = new QStyleOptionTab();
385
386 QStyleOptionTab *opt = qstyleoption_cast<QStyleOptionTab*>(opt: m_styleoption);
387 opt->text = text();
388
389 if (m_properties.value(QStringLiteral("hasFrame")).toBool())
390 opt->features |= QStyleOptionTab::HasFrame;
391
392 QString orientation = m_properties.value(QStringLiteral("orientation")).toString();
393 QString position = m_properties.value(QStringLiteral("tabpos")).toString();
394 QString selectedPosition = m_properties.value(QStringLiteral("selectedpos")).toString();
395
396 opt->shape = orientation == QLatin1String("Bottom") ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
397 if (position == QLatin1String("beginning"))
398 opt->position = QStyleOptionTab::Beginning;
399 else if (position == QLatin1String("end"))
400 opt->position = QStyleOptionTab::End;
401 else if (position == QLatin1String("only"))
402 opt->position = QStyleOptionTab::OnlyOneTab;
403 else
404 opt->position = QStyleOptionTab::Middle;
405
406 if (selectedPosition == QLatin1String("next"))
407 opt->selectedPosition = QStyleOptionTab::NextIsSelected;
408 else if (selectedPosition == QLatin1String("previous"))
409 opt->selectedPosition = QStyleOptionTab::PreviousIsSelected;
410 else
411 opt->selectedPosition = QStyleOptionTab::NotAdjacent;
412
413
414 } break;
415#endif // QT_CONFIG(tabbar)
416 case Frame: {
417 if (!m_styleoption)
418 m_styleoption = new QStyleOptionFrame();
419
420 QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(opt: m_styleoption);
421 opt->frameShape = QFrame::StyledPanel;
422 opt->lineWidth = 1;
423 opt->midLineWidth = 1;
424 }
425 break;
426 case FocusRect: {
427 if (!m_styleoption)
428 m_styleoption = new QStyleOptionFocusRect();
429 // Needed on windows
430 m_styleoption->state |= QStyle::State_KeyboardFocusChange;
431 }
432 break;
433#if QT_CONFIG(tabwidget)
434 case TabFrame: {
435 if (!m_styleoption)
436 m_styleoption = new QStyleOptionTabWidgetFrame();
437 QStyleOptionTabWidgetFrame *opt = qstyleoption_cast<QStyleOptionTabWidgetFrame*>(opt: m_styleoption);
438
439 opt->selectedTabRect = m_properties[QStringLiteral("selectedTabRect")].toRect();
440 opt->shape = m_properties[QStringLiteral("orientation")] == Qt::BottomEdge ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
441 if (minimum())
442 opt->selectedTabRect = QRect(value(), 0, minimum(), height());
443 opt->tabBarSize = QSize(minimum() , height());
444 // oxygen style needs this hack
445 opt->leftCornerWidgetSize = QSize(value(), 0);
446 }
447 break;
448#endif // QT_CONFIG(tabwidget)
449 case MenuBar:
450 if (!m_styleoption) {
451 QStyleOptionMenuItem *menuOpt = new QStyleOptionMenuItem();
452 menuOpt->menuItemType = QStyleOptionMenuItem::EmptyArea;
453 m_styleoption = menuOpt;
454 }
455
456 break;
457 case MenuBarItem:
458 {
459 if (!m_styleoption)
460 m_styleoption = new QStyleOptionMenuItem();
461
462 QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(opt: m_styleoption);
463 opt->text = text();
464 opt->menuItemType = QStyleOptionMenuItem::Normal;
465 setProperty(name: "_q_showUnderlined", value: m_hints[QStringLiteral("showUnderlined")].toBool());
466
467 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: QPlatformTheme::MenuBarFont)) {
468 opt->font = *font;
469 opt->fontMetrics = QFontMetrics(opt->font);
470 m_font = opt->font;
471 }
472 }
473 break;
474 case Menu: {
475 if (!m_styleoption)
476 m_styleoption = new QStyleOptionMenuItem();
477 }
478 break;
479 case MenuItem:
480 case ComboBoxItem:
481 {
482 if (!m_styleoption)
483 m_styleoption = new QStyleOptionMenuItem();
484
485 QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(opt: m_styleoption);
486 // For GTK style. See below, in setElementType()
487 setProperty(name: "_q_isComboBoxPopupItem", value: m_itemType == ComboBoxItem);
488
489 QQuickMenuItemType1::MenuItemType type =
490 static_cast<QQuickMenuItemType1::MenuItemType>(m_properties[QStringLiteral("type")].toInt());
491 if (type == QQuickMenuItemType1::ScrollIndicator) {
492 int scrollerDirection = m_properties[QStringLiteral("scrollerDirection")].toInt();
493 opt->menuItemType = QStyleOptionMenuItem::Scroller;
494 opt->state |= scrollerDirection == Qt::UpArrow ?
495 QStyle::State_UpArrow : QStyle::State_DownArrow;
496 } else if (type == QQuickMenuItemType1::Separator) {
497 opt->menuItemType = QStyleOptionMenuItem::Separator;
498 } else {
499 opt->text = text();
500
501 if (type == QQuickMenuItemType1::Menu) {
502 opt->menuItemType = QStyleOptionMenuItem::SubMenu;
503 } else {
504 opt->menuItemType = QStyleOptionMenuItem::Normal;
505
506 QString shortcut = m_properties[QStringLiteral("shortcut")].toString();
507 if (!shortcut.isEmpty()) {
508 opt->text += QLatin1Char('\t') + shortcut;
509 opt->tabWidth = qMax(a: opt->tabWidth, b: qRound(d: textWidth(shortcut)));
510 }
511
512 if (m_properties[QStringLiteral("checkable")].toBool()) {
513 opt->checked = on();
514 QVariant exclusive = m_properties[QStringLiteral("exclusive")];
515 opt->checkType = exclusive.toBool() ? QStyleOptionMenuItem::Exclusive :
516 QStyleOptionMenuItem::NonExclusive;
517 }
518 }
519 if (m_properties[QStringLiteral("icon")].canConvert<QIcon>())
520 opt->icon = m_properties[QStringLiteral("icon")].value<QIcon>();
521 setProperty(name: "_q_showUnderlined", value: m_hints["showUnderlined"].toBool());
522
523 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: m_itemType == ComboBoxItem ? QPlatformTheme::ComboMenuItemFont : QPlatformTheme::MenuFont)) {
524 opt->font = *font;
525 opt->fontMetrics = QFontMetrics(opt->font);
526 m_font = opt->font;
527 }
528 }
529 }
530 break;
531 case CheckBox:
532 case RadioButton:
533 {
534 if (!m_styleoption)
535 m_styleoption = new QStyleOptionButton();
536
537 QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(opt: m_styleoption);
538 if (!on())
539 opt->state |= QStyle::State_Off;
540 if (m_properties.value(QStringLiteral("partiallyChecked")).toBool())
541 opt->state |= QStyle::State_NoChange;
542 opt->text = text();
543 }
544 break;
545 case Edit: {
546 if (!m_styleoption)
547 m_styleoption = new QStyleOptionFrame();
548
549 QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(opt: m_styleoption);
550 opt->lineWidth = 1; // this must be non-zero
551 }
552 break;
553 case ComboBox :{
554 if (!m_styleoption)
555 m_styleoption = new QStyleOptionComboBox();
556
557 QStyleOptionComboBox *opt = qstyleoption_cast<QStyleOptionComboBox*>(opt: m_styleoption);
558
559 if (platformFont == QPlatformTheme::SystemFont)
560 platformFont = QPlatformTheme::PushButtonFont;
561 const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: platformFont);
562 if (font)
563 opt->fontMetrics = QFontMetrics(*font);
564 opt->currentText = text();
565 opt->editable = m_properties[QStringLiteral("editable")].toBool();
566#ifdef Q_OS_OSX
567 if (m_properties[QStringLiteral("popup")].canConvert<QObject *>()
568 && style() == QLatin1String("mac")) {
569 QObject *popup = m_properties[QStringLiteral("popup")].value<QObject *>();
570 if (platformFont == QPlatformTheme::MiniFont) {
571 popup->setProperty("__xOffset", -2);
572 popup->setProperty("__yOffset", 5);
573 } else {
574 if (platformFont == QPlatformTheme::SmallFont)
575 popup->setProperty("__xOffset", -1);
576 popup->setProperty("__yOffset", 6);
577 }
578 if (font)
579 popup->setProperty("__font", *font);
580 }
581#endif
582 }
583 break;
584#if QT_CONFIG(spinbox)
585 case SpinBox: {
586 if (!m_styleoption)
587 m_styleoption = new QStyleOptionSpinBox();
588
589 QStyleOptionSpinBox *opt = qstyleoption_cast<QStyleOptionSpinBox*>(opt: m_styleoption);
590 opt->frame = true;
591 opt->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
592 if (value() & 0x1)
593 opt->activeSubControls = QStyle::SC_SpinBoxUp;
594 else if (value() & (1<<1))
595 opt->activeSubControls = QStyle::SC_SpinBoxDown;
596 opt->subControls = QStyle::SC_All;
597 opt->stepEnabled = {};
598 if (value() & (1<<2))
599 opt->stepEnabled |= QAbstractSpinBox::StepUpEnabled;
600 if (value() & (1<<3))
601 opt->stepEnabled |= QAbstractSpinBox::StepDownEnabled;
602 }
603 break;
604#endif // QT_CONFIG(spinbox)
605#if QT_CONFIG(slider)
606 case Slider:
607 case Dial:
608 {
609 if (!m_styleoption)
610 m_styleoption = new QStyleOptionSlider();
611
612 QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(opt: m_styleoption);
613 opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
614 opt->upsideDown = !horizontal();
615 opt->minimum = minimum();
616 opt->maximum = maximum();
617 opt->sliderPosition = value();
618 opt->singleStep = step();
619
620 if (opt->singleStep) {
621 qreal numOfSteps = (opt->maximum - opt->minimum) / opt->singleStep;
622 // at least 5 pixels between tick marks
623 qreal extent = horizontal() ? width() : height();
624 if (numOfSteps && (extent / numOfSteps < 5))
625 opt->tickInterval = qRound(d: (5 * numOfSteps / extent) + 0.5) * step();
626 else
627 opt->tickInterval = opt->singleStep;
628
629 } else // default Qt-components implementation
630 opt->tickInterval = opt->maximum != opt->minimum ? 1200 / (opt->maximum - opt->minimum) : 0;
631
632 opt->sliderValue = value();
633 opt->subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
634 opt->tickPosition = activeControl() == QLatin1String("ticks") ?
635 QSlider::TicksBelow : QSlider::NoTicks;
636 if (opt->tickPosition != QSlider::NoTicks)
637 opt->subControls |= QStyle::SC_SliderTickmarks;
638
639 opt->activeSubControls = QStyle::SC_SliderHandle;
640 }
641 break;
642#endif // QT_CONFIG(slider)
643 case ProgressBar: {
644 if (!m_styleoption)
645 m_styleoption = new QStyleOptionProgressBar();
646
647 QStyleOptionProgressBar *opt = qstyleoption_cast<QStyleOptionProgressBar*>(opt: m_styleoption);
648 opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
649 opt->minimum = minimum();
650 opt->maximum = maximum();
651 opt->progress = value();
652 }
653 break;
654 case GroupBox: {
655 if (!m_styleoption)
656 m_styleoption = new QStyleOptionGroupBox();
657
658 QStyleOptionGroupBox *opt = qstyleoption_cast<QStyleOptionGroupBox*>(opt: m_styleoption);
659 opt->text = text();
660 opt->lineWidth = 1;
661 opt->subControls = QStyle::SC_GroupBoxLabel;
662 opt->features = {};
663 if (m_properties[QStringLiteral("sunken")].toBool()) { // Qt draws an ugly line here so I ignore it
664 opt->subControls |= QStyle::SC_GroupBoxFrame;
665 } else {
666 opt->features |= QStyleOptionFrame::Flat;
667 }
668 if (m_properties[QStringLiteral("checkable")].toBool())
669 opt->subControls |= QStyle::SC_GroupBoxCheckBox;
670
671 }
672 break;
673#if QT_CONFIG(slider)
674 case ScrollBar: {
675 if (!m_styleoption)
676 m_styleoption = new QStyleOptionSlider();
677
678 QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(opt: m_styleoption);
679 opt->minimum = minimum();
680 opt->maximum = maximum();
681 opt->pageStep = qMax(a: 0, b: int(horizontal() ? width() : height()));
682 opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
683 opt->sliderPosition = value();
684 opt->sliderValue = value();
685 opt->activeSubControls = (activeControl() == QLatin1String("up"))
686 ? QStyle::SC_ScrollBarSubLine : (activeControl() == QLatin1String("down")) ?
687 QStyle::SC_ScrollBarAddLine :
688 (activeControl() == QLatin1String("handle")) ?
689 QStyle::SC_ScrollBarSlider : hover() ? QStyle::SC_ScrollBarGroove : QStyle::SC_None;
690 if (raised())
691 opt->state |= QStyle::State_On;
692
693 opt->sliderValue = value();
694 opt->subControls = QStyle::SC_All;
695
696 setTransient(qApp->style()->styleHint(stylehint: QStyle::SH_ScrollBar_Transient, opt: m_styleoption));
697 break;
698 }
699#endif // QT_CONFIG(slider)
700 default:
701 break;
702 }
703
704 if (!m_styleoption)
705 m_styleoption = new QStyleOption();
706
707 if (needsResolvePalette)
708 resolvePalette();
709
710 m_styleoption->styleObject = this;
711 m_styleoption->direction = qApp->layoutDirection();
712
713 int w = m_textureWidth > 0 ? m_textureWidth : width();
714 int h = m_textureHeight > 0 ? m_textureHeight : height();
715
716 m_styleoption->rect = QRect(m_paintMargins, 0, w - 2* m_paintMargins, h);
717
718 if (isEnabled()) {
719 m_styleoption->state |= QStyle::State_Enabled;
720 m_styleoption->palette.setCurrentColorGroup(QPalette::Active);
721 } else {
722 m_styleoption->palette.setCurrentColorGroup(QPalette::Disabled);
723 }
724 if (m_active)
725 m_styleoption->state |= QStyle::State_Active;
726 else
727 m_styleoption->palette.setCurrentColorGroup(QPalette::Inactive);
728 if (m_sunken)
729 m_styleoption->state |= QStyle::State_Sunken;
730 if (m_raised)
731 m_styleoption->state |= QStyle::State_Raised;
732 if (m_selected)
733 m_styleoption->state |= QStyle::State_Selected;
734 if (m_focus)
735 m_styleoption->state |= QStyle::State_HasFocus;
736 if (m_on)
737 m_styleoption->state |= QStyle::State_On;
738 if (m_hover)
739 m_styleoption->state |= QStyle::State_MouseOver;
740 if (m_horizontal)
741 m_styleoption->state |= QStyle::State_Horizontal;
742
743 // some styles don't draw a focus rectangle if
744 // QStyle::State_KeyboardFocusChange is not set
745 if (window()) {
746 Qt::FocusReason lastFocusReason = QQuickWindowPrivate::get(c: window())->lastFocusReason;
747 if (lastFocusReason == Qt::TabFocusReason || lastFocusReason == Qt::BacktabFocusReason) {
748 m_styleoption->state |= QStyle::State_KeyboardFocusChange;
749 }
750 }
751
752 if (sizeHint == QLatin1String("mini")) {
753 m_styleoption->state |= QStyle::State_Mini;
754 } else if (sizeHint == QLatin1String("small")) {
755 m_styleoption->state |= QStyle::State_Small;
756 }
757
758}
759
760void QQuickStyleItem1::resolvePalette()
761{
762 if (QCoreApplication::testAttribute(attribute: Qt::AA_SetPalette))
763 return;
764
765 QPlatformTheme::Palette paletteType = QPlatformTheme::SystemPalette;
766 switch (m_itemType) {
767 case Button:
768 paletteType = QPlatformTheme::ButtonPalette;
769 break;
770 case RadioButton:
771 paletteType = QPlatformTheme::RadioButtonPalette;
772 break;
773 case CheckBox:
774 paletteType = QPlatformTheme::CheckBoxPalette;
775 break;
776 case ComboBox:
777 case ComboBoxItem:
778 paletteType = QPlatformTheme::ComboBoxPalette;
779 break;
780 case ToolBar:
781 case ToolButton:
782 paletteType = QPlatformTheme::ToolButtonPalette;
783 break;
784 case Tab:
785 case TabFrame:
786 paletteType = QPlatformTheme::TabBarPalette;
787 break;
788 case Edit:
789 paletteType = QPlatformTheme::TextEditPalette;
790 break;
791 case GroupBox:
792 paletteType = QPlatformTheme::GroupBoxPalette;
793 break;
794 case Header:
795 paletteType = QPlatformTheme::HeaderPalette;
796 break;
797 case Item:
798 case ItemRow:
799 paletteType = QPlatformTheme::ItemViewPalette;
800 break;
801 case Menu:
802 case MenuItem:
803 paletteType = QPlatformTheme::MenuPalette;
804 break;
805 case MenuBar:
806 case MenuBarItem:
807 paletteType = QPlatformTheme::MenuBarPalette;
808 break;
809 default:
810 break;
811 }
812
813 const QPalette *platformPalette = QGuiApplicationPrivate::platformTheme()->palette(type: paletteType);
814 if (platformPalette)
815 m_styleoption->palette = *platformPalette;
816 // Defaults to SystemPalette otherwise
817}
818
819/*
820 * Property style
821 *
822 * Returns a simplified style name.
823 *
824 * QMacStyle = "mac"
825 * QWindowsXPStyle = "windowsxp"
826 * QFusionStyle = "fusion"
827 */
828
829QString QQuickStyleItem1::style() const
830{
831 QString style = qApp->style()->metaObject()->className();
832 style = style.toLower();
833 if (style.startsWith(c: QLatin1Char('q')))
834 style = style.right(n: style.length() - 1);
835 if (style.endsWith(s: QLatin1String("style")))
836 style = style.left(n: style.length() - 5);
837 return style;
838}
839
840QString QQuickStyleItem1::hitTest(int px, int py)
841{
842 QStyle::SubControl subcontrol = QStyle::SC_All;
843 switch (m_itemType) {
844 case SpinBox :{
845 subcontrol = qApp->style()->hitTestComplexControl(cc: QStyle::CC_SpinBox,
846 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
847 pt: QPoint(px,py), widget: 0);
848 if (subcontrol == QStyle::SC_SpinBoxUp)
849 return QStringLiteral("up");
850 else if (subcontrol == QStyle::SC_SpinBoxDown)
851 return QStringLiteral("down");
852 }
853 break;
854
855 case Slider: {
856 subcontrol = qApp->style()->hitTestComplexControl(cc: QStyle::CC_Slider,
857 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
858 pt: QPoint(px,py), widget: 0);
859 if (subcontrol == QStyle::SC_SliderHandle)
860 return QStringLiteral("handle");
861 }
862 break;
863
864 case ScrollBar: {
865 subcontrol = qApp->style()->hitTestComplexControl(cc: QStyle::CC_ScrollBar,
866 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
867 pt: QPoint(px,py), widget: 0);
868 switch (subcontrol) {
869 case QStyle::SC_ScrollBarSlider:
870 return QStringLiteral("handle");
871
872 case QStyle::SC_ScrollBarSubLine:
873 return QStringLiteral("up");
874
875 case QStyle::SC_ScrollBarSubPage:
876 return QStringLiteral("upPage");
877
878 case QStyle::SC_ScrollBarAddLine:
879 return QStringLiteral("down");
880
881 case QStyle::SC_ScrollBarAddPage:
882 return QStringLiteral("downPage");
883
884 default:
885 break;
886 }
887 }
888 break;
889
890 default:
891 break;
892 }
893 return QStringLiteral("none");
894}
895
896QSize QQuickStyleItem1::sizeFromContents(int width, int height)
897{
898 initStyleOption();
899
900 QSize size;
901 switch (m_itemType) {
902 case RadioButton:
903 size = qApp->style()->sizeFromContents(ct: QStyle::CT_RadioButton, opt: m_styleoption, contentsSize: QSize(width,height));
904 break;
905 case CheckBox:
906 size = qApp->style()->sizeFromContents(ct: QStyle::CT_CheckBox, opt: m_styleoption, contentsSize: QSize(width,height));
907 break;
908 case ToolBar:
909 size = QSize(200, style().contains(s: QLatin1String("windows")) ? 30 : 42);
910 break;
911 case ToolButton: {
912 QStyleOptionToolButton *btn = qstyleoption_cast<QStyleOptionToolButton*>(opt: m_styleoption);
913 int w = 0;
914 int h = 0;
915 if (btn->toolButtonStyle != Qt::ToolButtonTextOnly) {
916 QSize icon = btn->iconSize;
917 w = icon.width();
918 h = icon.height();
919 }
920 if (btn->toolButtonStyle != Qt::ToolButtonIconOnly) {
921 QSize textSize = btn->fontMetrics.size(flags: Qt::TextShowMnemonic, str: btn->text);
922 textSize.setWidth(textSize.width() + btn->fontMetrics.horizontalAdvance(QLatin1Char(' '))*2);
923 if (btn->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
924 h += 4 + textSize.height();
925 if (textSize.width() > w)
926 w = textSize.width();
927 } else if (btn->toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
928 w += 4 + textSize.width();
929 if (textSize.height() > h)
930 h = textSize.height();
931 } else { // TextOnly
932 w = textSize.width();
933 h = textSize.height();
934 }
935 }
936 btn->rect.setSize(QSize(w, h));
937 size = qApp->style()->sizeFromContents(ct: QStyle::CT_ToolButton, opt: m_styleoption, contentsSize: QSize(w, h)); }
938 break;
939 case Button: {
940 QStyleOptionButton *btn = qstyleoption_cast<QStyleOptionButton*>(opt: m_styleoption);
941
942 int contentWidth = btn->fontMetrics.horizontalAdvance(btn->text);
943 int contentHeight = btn->fontMetrics.height();
944 if (!btn->icon.isNull()) {
945 //+4 matches a hardcoded value in QStyle and acts as a margin between the icon and the text.
946 contentWidth += btn->iconSize.width() + 4;
947 contentHeight = qMax(a: btn->fontMetrics.height(), b: btn->iconSize.height());
948 }
949 int newWidth = qMax(a: width, b: contentWidth);
950 int newHeight = qMax(a: height, b: contentHeight);
951 size = qApp->style()->sizeFromContents(ct: QStyle::CT_PushButton, opt: m_styleoption, contentsSize: QSize(newWidth, newHeight)); }
952#ifdef Q_OS_OSX
953 if (style() == QLatin1String("mac")) {
954 // Cancel out QMacStylePrivate::PushButton*Offset, or part of it
955 size -= QSize(7, 6);
956 }
957#endif
958 break;
959 case ComboBox: {
960 QStyleOptionComboBox *btn = qstyleoption_cast<QStyleOptionComboBox*>(opt: m_styleoption);
961 int newWidth = qMax(a: width, b: btn->fontMetrics.horizontalAdvance(btn->currentText));
962 int newHeight = qMax(a: height, b: btn->fontMetrics.height());
963 size = qApp->style()->sizeFromContents(ct: QStyle::CT_ComboBox, opt: m_styleoption, contentsSize: QSize(newWidth, newHeight)); }
964 break;
965 case Tab:
966 size = qApp->style()->sizeFromContents(ct: QStyle::CT_TabBarTab, opt: m_styleoption, contentsSize: QSize(width,height));
967 break;
968 case Slider:
969 size = qApp->style()->sizeFromContents(ct: QStyle::CT_Slider, opt: m_styleoption, contentsSize: QSize(width,height));
970 break;
971 case ProgressBar:
972 size = qApp->style()->sizeFromContents(ct: QStyle::CT_ProgressBar, opt: m_styleoption, contentsSize: QSize(width,height));
973 break;
974 case SpinBox:
975#ifdef Q_OS_OSX
976 if (style() == QLatin1String("mac")) {
977 size = qApp->style()->sizeFromContents(QStyle::CT_SpinBox, m_styleoption, QSize(width, height + 5));
978 break;
979 }
980#endif // fall through if not mac
981 case Edit:
982#ifdef Q_OS_OSX
983 if (style() == QLatin1String("mac")) {
984 QString sizeHint = m_hints.value(QStringLiteral("size")).toString();
985 if (sizeHint == QLatin1String("small") || sizeHint == QLatin1String("mini"))
986 size = QSize(width, 19);
987 else
988 size = QSize(width, 22);
989 if (hints().value(QStringLiteral("rounded")).toBool())
990 size += QSize(4, 4);
991
992 } else
993#endif
994 {
995 // We have to create a new style option since we might be calling with a QStyleOptionSpinBox
996 QStyleOptionFrame frame;
997 frame.state = m_styleoption->state;
998 frame.lineWidth = qApp->style()->pixelMetric(metric: QStyle::PM_DefaultFrameWidth, option: m_styleoption, widget: 0);
999 frame.rect = m_styleoption->rect;
1000 frame.styleObject = this;
1001 size = qApp->style()->sizeFromContents(ct: QStyle::CT_LineEdit, opt: &frame, contentsSize: QSize(width, height));
1002 if (m_itemType == SpinBox)
1003 size.setWidth(qApp->style()->sizeFromContents(ct: QStyle::CT_SpinBox,
1004 opt: m_styleoption, contentsSize: QSize(width + 2, height)).width());
1005 }
1006 break;
1007 case GroupBox: {
1008 QStyleOptionGroupBox *box = qstyleoption_cast<QStyleOptionGroupBox*>(opt: m_styleoption);
1009 QFontMetrics metrics(box->fontMetrics);
1010 int baseWidth = metrics.horizontalAdvance(box->text)
1011 + metrics.horizontalAdvance(QLatin1Char(' '));
1012 int baseHeight = metrics.height() + m_contentHeight;
1013 if (box->subControls & QStyle::SC_GroupBoxCheckBox) {
1014 baseWidth += qApp->style()->pixelMetric(metric: QStyle::PM_IndicatorWidth);
1015 baseWidth += qApp->style()->pixelMetric(metric: QStyle::PM_CheckBoxLabelSpacing);
1016 baseHeight = qMax(a: baseHeight, qApp->style()->pixelMetric(metric: QStyle::PM_IndicatorHeight));
1017 }
1018 size = qApp->style()->sizeFromContents(ct: QStyle::CT_GroupBox, opt: m_styleoption, contentsSize: QSize(qMax(a: baseWidth, b: m_contentWidth), baseHeight));
1019 }
1020 break;
1021 case Header:
1022 size = qApp->style()->sizeFromContents(ct: QStyle::CT_HeaderSection, opt: m_styleoption, contentsSize: QSize(width,height));
1023#ifdef Q_OS_OSX
1024 if (style() == QLatin1String("mac"))
1025 size.setHeight(15);
1026#endif
1027 break;
1028 case ItemRow:
1029 case Item: //fall through
1030 size = qApp->style()->sizeFromContents(ct: QStyle::CT_ItemViewItem, opt: m_styleoption, contentsSize: QSize(width,height));
1031 break;
1032 case MenuBarItem:
1033 size = qApp->style()->sizeFromContents(ct: QStyle::CT_MenuBarItem, opt: m_styleoption, contentsSize: QSize(width,height));
1034 break;
1035 case MenuBar:
1036 size = qApp->style()->sizeFromContents(ct: QStyle::CT_MenuBar, opt: m_styleoption, contentsSize: QSize(width,height));
1037 break;
1038 case Menu:
1039 size = qApp->style()->sizeFromContents(ct: QStyle::CT_Menu, opt: m_styleoption, contentsSize: QSize(width,height));
1040 break;
1041 case MenuItem:
1042 case ComboBoxItem:
1043 if (static_cast<QStyleOptionMenuItem *>(m_styleoption)->menuItemType == QStyleOptionMenuItem::Scroller) {
1044 size.setHeight(qMax(a: QApplication::globalStrut().height(),
1045 qApp->style()->pixelMetric(metric: QStyle::PM_MenuScrollerHeight, option: 0, widget: 0)));
1046 } else {
1047 size = qApp->style()->sizeFromContents(ct: QStyle::CT_MenuItem, opt: m_styleoption, contentsSize: QSize(width,height));
1048 }
1049 break;
1050 default:
1051 break;
1052 } return size;
1053}
1054
1055qreal QQuickStyleItem1::baselineOffset()
1056{
1057 QRect r;
1058 bool ceilResult = true; // By default baseline offset rounding is done upwards
1059 switch (m_itemType) {
1060 case RadioButton:
1061 r = qApp->style()->subElementRect(subElement: QStyle::SE_RadioButtonContents, option: m_styleoption);
1062 break;
1063 case Button:
1064 r = qApp->style()->subElementRect(subElement: QStyle::SE_PushButtonContents, option: m_styleoption);
1065 break;
1066 case CheckBox:
1067 r = qApp->style()->subElementRect(subElement: QStyle::SE_CheckBoxContents, option: m_styleoption);
1068 break;
1069 case Edit:
1070 r = qApp->style()->subElementRect(subElement: QStyle::SE_LineEditContents, option: m_styleoption);
1071 break;
1072 case ComboBox:
1073 if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt: m_styleoption)) {
1074 r = qApp->style()->subControlRect(cc: QStyle::CC_ComboBox, opt: combo, sc: QStyle::SC_ComboBoxEditField);
1075 if (style() != QLatin1String("mac"))
1076 r.adjust(dx1: 0,dy1: 0,dx2: 0,dy2: 1);
1077 }
1078 break;
1079#if QT_CONFIG(spinbox)
1080 case SpinBox:
1081 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt: m_styleoption)) {
1082 r = qApp->style()->subControlRect(cc: QStyle::CC_SpinBox, opt: spinbox, sc: QStyle::SC_SpinBoxEditField);
1083 ceilResult = false;
1084 }
1085 break;
1086#endif
1087 default:
1088 break;
1089 }
1090 if (r.height() > 0) {
1091 const QFontMetrics &fm = m_styleoption->fontMetrics;
1092 int surplus = r.height() - fm.height();
1093 if ((surplus & 1) && ceilResult)
1094 surplus++;
1095 int result = r.top() + surplus/2 + fm.ascent();
1096#ifdef Q_OS_OSX
1097 if (style() == QLatin1String("mac")) {
1098 switch (m_itemType) {
1099 case Button:
1100 case Edit:
1101 result -= 1;
1102 break;
1103 case ComboBox:
1104 // adjust back the adjustments done in drawControl(CE_ComboBoxLabel)
1105 result += 1;
1106 break;
1107 default:
1108 break;
1109 }
1110 }
1111#endif
1112 return result;
1113 }
1114
1115 return 0.;
1116}
1117
1118void QQuickStyleItem1::updateBaselineOffset()
1119{
1120 const qreal baseline = baselineOffset();
1121 if (baseline > 0)
1122 setBaselineOffset(baseline);
1123}
1124
1125void QQuickStyleItem1::setContentWidth(int arg)
1126{
1127 if (m_contentWidth != arg) {
1128 m_contentWidth = arg;
1129 emit contentWidthChanged(arg);
1130 }
1131}
1132
1133void QQuickStyleItem1::setContentHeight(int arg)
1134{
1135 if (m_contentHeight != arg) {
1136 m_contentHeight = arg;
1137 emit contentHeightChanged(arg);
1138 }
1139}
1140
1141void QQuickStyleItem1::updateSizeHint()
1142{
1143 QSize implicitSize = sizeFromContents(width: m_contentWidth, height: m_contentHeight);
1144 setImplicitSize(implicitSize.width(), implicitSize.height());
1145}
1146
1147void QQuickStyleItem1::updateRect()
1148{
1149 initStyleOption();
1150 m_styleoption->rect.setWidth(width());
1151 m_styleoption->rect.setHeight(height());
1152}
1153
1154int QQuickStyleItem1::pixelMetric(const QString &metric)
1155{
1156
1157 if (metric == QLatin1String("scrollbarExtent"))
1158 return qApp->style()->pixelMetric(metric: QStyle::PM_ScrollBarExtent, option: 0 );
1159 else if (metric == QLatin1String("defaultframewidth"))
1160 return qApp->style()->pixelMetric(metric: QStyle::PM_DefaultFrameWidth, option: m_styleoption);
1161 else if (metric == QLatin1String("taboverlap"))
1162 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarTabOverlap, option: 0 );
1163 else if (metric == QLatin1String("tabbaseoverlap"))
1164 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarBaseOverlap, option: m_styleoption );
1165 else if (metric == QLatin1String("tabhspace"))
1166 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarTabHSpace, option: 0 );
1167 else if (metric == QLatin1String("indicatorwidth"))
1168 return qApp->style()->pixelMetric(metric: QStyle::PM_ExclusiveIndicatorWidth, option: 0 );
1169 else if (metric == QLatin1String("tabvspace"))
1170 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarTabVSpace, option: 0 );
1171 else if (metric == QLatin1String("tabbaseheight"))
1172 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarBaseHeight, option: 0 );
1173 else if (metric == QLatin1String("tabvshift"))
1174 return qApp->style()->pixelMetric(metric: QStyle::PM_TabBarTabShiftVertical, option: 0 );
1175 else if (metric == QLatin1String("menubarhmargin"))
1176 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuBarHMargin, option: 0 );
1177 else if (metric == QLatin1String("menubarvmargin"))
1178 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuBarVMargin, option: 0 );
1179 else if (metric == QLatin1String("menubarpanelwidth"))
1180 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuBarPanelWidth, option: 0 );
1181 else if (metric == QLatin1String("menubaritemspacing"))
1182 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuBarItemSpacing, option: 0 );
1183 else if (metric == QLatin1String("spacebelowmenubar"))
1184 return qApp->style()->styleHint(stylehint: QStyle::SH_MainWindow_SpaceBelowMenuBar, opt: m_styleoption);
1185 else if (metric == QLatin1String("menuhmargin"))
1186 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuHMargin, option: 0 );
1187 else if (metric == QLatin1String("menuvmargin"))
1188 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuVMargin, option: 0 );
1189 else if (metric == QLatin1String("menupanelwidth"))
1190 return qApp->style()->pixelMetric(metric: QStyle::PM_MenuPanelWidth, option: 0 );
1191 else if (metric == QLatin1String("submenuoverlap"))
1192 return qApp->style()->pixelMetric(metric: QStyle::PM_SubMenuOverlap, option: 0 );
1193 else if (metric == QLatin1String("splitterwidth"))
1194 return qApp->style()->pixelMetric(metric: QStyle::PM_SplitterWidth, option: 0 );
1195 else if (metric == QLatin1String("scrollbarspacing"))
1196 return abs(qApp->style()->pixelMetric(metric: QStyle::PM_ScrollView_ScrollBarSpacing, option: 0 ));
1197 else if (metric == QLatin1String("treeviewindentation"))
1198 return qApp->style()->pixelMetric(metric: QStyle::PM_TreeViewIndentation, option: 0 );
1199 return 0;
1200}
1201
1202QVariant QQuickStyleItem1::styleHint(const QString &metric)
1203{
1204 initStyleOption();
1205 if (metric == QLatin1String("comboboxpopup")) {
1206 return qApp->style()->styleHint(stylehint: QStyle::SH_ComboBox_Popup, opt: m_styleoption);
1207 } else if (metric == QLatin1String("highlightedTextColor")) {
1208 return m_styleoption->palette.highlightedText().color().name();
1209 } else if (metric == QLatin1String("textColor")) {
1210 QPalette pal = m_styleoption->palette;
1211 pal.setCurrentColorGroup(active()? QPalette::Active : QPalette::Inactive);
1212 return pal.text().color().name();
1213 } else if (metric == QLatin1String("focuswidget")) {
1214 return qApp->style()->styleHint(stylehint: QStyle::SH_FocusFrame_AboveWidget);
1215 } else if (metric == QLatin1String("tabbaralignment")) {
1216 int result = qApp->style()->styleHint(stylehint: QStyle::SH_TabBar_Alignment);
1217 if (result == Qt::AlignCenter)
1218 return QStringLiteral("center");
1219 return QStringLiteral("left");
1220 } else if (metric == QLatin1String("externalScrollBars")) {
1221 return qApp->style()->styleHint(stylehint: QStyle::SH_ScrollView_FrameOnlyAroundContents);
1222 } else if (metric == QLatin1String("scrollToClickPosition"))
1223 return qApp->style()->styleHint(stylehint: QStyle::SH_ScrollBar_LeftClickAbsolutePosition);
1224 else if (metric == QLatin1String("activateItemOnSingleClick"))
1225 return qApp->style()->styleHint(stylehint: QStyle::SH_ItemView_ActivateItemOnSingleClick);
1226 else if (metric == QLatin1String("submenupopupdelay"))
1227 return qApp->style()->styleHint(stylehint: QStyle::SH_Menu_SubMenuPopupDelay, opt: m_styleoption);
1228#if QT_CONFIG(wheelevent)
1229 else if (metric == QLatin1String("wheelScrollLines"))
1230 return qApp->wheelScrollLines();
1231#endif
1232 return 0;
1233
1234 // Add SH_Menu_SpaceActivatesItem
1235}
1236
1237void QQuickStyleItem1::setHints(const QVariantMap &str)
1238{
1239 if (m_hints != str) {
1240 m_hints = str;
1241 initStyleOption();
1242 updateSizeHint();
1243 if (m_styleoption->state & QStyle::State_Mini) {
1244 m_font.setPointSize(9.);
1245 emit fontChanged();
1246 } else if (m_styleoption->state & QStyle::State_Small) {
1247 m_font.setPointSize(11.);
1248 emit fontChanged();
1249 } else {
1250 emit hintChanged();
1251 }
1252 }
1253}
1254
1255void QQuickStyleItem1::resetHints()
1256{
1257 m_hints.clear();
1258}
1259
1260
1261void QQuickStyleItem1::setElementType(const QString &str)
1262{
1263 if (m_type == str)
1264 return;
1265
1266 m_type = str;
1267
1268 emit elementTypeChanged();
1269 if (m_styleoption) {
1270 delete m_styleoption;
1271 m_styleoption = 0;
1272 }
1273
1274 // Only enable visible if the widget can animate
1275 if (str == QLatin1String("menu")) {
1276 m_itemType = Menu;
1277 } else if (str == QLatin1String("menuitem")) {
1278 m_itemType = MenuItem;
1279 } else if (str == QLatin1String("item") || str == QLatin1String("itemrow") || str == QLatin1String("header")) {
1280#ifdef Q_OS_OSX
1281 m_font.setPointSize(11.0);
1282 emit fontChanged();
1283#endif
1284 if (str == QLatin1String("header")) {
1285 m_itemType = Header;
1286 } else {
1287 m_itemType = str == QLatin1String("item") ? Item : ItemRow;
1288 }
1289 } else if (str == QLatin1String("itembranchindicator")) {
1290 m_itemType = ItemBranchIndicator;
1291 } else if (str == QLatin1String("groupbox")) {
1292 m_itemType = GroupBox;
1293 } else if (str == QLatin1String("tab")) {
1294 m_itemType = Tab;
1295 } else if (str == QLatin1String("tabframe")) {
1296 m_itemType = TabFrame;
1297 } else if (str == QLatin1String("comboboxitem")) {
1298 // Gtk uses qobject cast, hence we need to separate this from menuitem
1299 // On mac, we temporarily use the menu item because it has more accurate
1300 // palette.
1301 m_itemType = ComboBoxItem;
1302 } else if (str == QLatin1String("toolbar")) {
1303 m_itemType = ToolBar;
1304 } else if (str == QLatin1String("toolbutton")) {
1305 m_itemType = ToolButton;
1306 } else if (str == QLatin1String("slider")) {
1307 m_itemType = Slider;
1308 } else if (str == QLatin1String("frame")) {
1309 m_itemType = Frame;
1310 } else if (str == QLatin1String("combobox")) {
1311 m_itemType = ComboBox;
1312 } else if (str == QLatin1String("splitter")) {
1313 m_itemType = Splitter;
1314 } else if (str == QLatin1String("progressbar")) {
1315 m_itemType = ProgressBar;
1316 } else if (str == QLatin1String("button")) {
1317 m_itemType = Button;
1318 } else if (str == QLatin1String("checkbox")) {
1319 m_itemType = CheckBox;
1320 } else if (str == QLatin1String("radiobutton")) {
1321 m_itemType = RadioButton;
1322 } else if (str == QLatin1String("edit")) {
1323 m_itemType = Edit;
1324 } else if (str == QLatin1String("spinbox")) {
1325 m_itemType = SpinBox;
1326 } else if (str == QLatin1String("scrollbar")) {
1327 m_itemType = ScrollBar;
1328 } else if (str == QLatin1String("widget")) {
1329 m_itemType = Widget;
1330 } else if (str == QLatin1String("focusframe")) {
1331 m_itemType = FocusFrame;
1332 } else if (str == QLatin1String("focusrect")) {
1333 m_itemType = FocusRect;
1334 } else if (str == QLatin1String("dial")) {
1335 m_itemType = Dial;
1336 } else if (str == QLatin1String("statusbar")) {
1337 m_itemType = StatusBar;
1338 } else if (str == QLatin1String("machelpbutton")) {
1339 m_itemType = MacHelpButton;
1340 } else if (str == QLatin1String("scrollareacorner")) {
1341 m_itemType = ScrollAreaCorner;
1342 } else if (str == QLatin1String("menubar")) {
1343 m_itemType = MenuBar;
1344 } else if (str == QLatin1String("menubaritem")) {
1345 m_itemType = MenuBarItem;
1346 } else {
1347 m_itemType = Undefined;
1348 }
1349 updateSizeHint();
1350}
1351
1352QRectF QQuickStyleItem1::subControlRect(const QString &subcontrolString)
1353{
1354 QStyle::SubControl subcontrol = QStyle::SC_None;
1355 initStyleOption();
1356 switch (m_itemType) {
1357 case SpinBox:
1358 {
1359 QStyle::ComplexControl control = QStyle::CC_SpinBox;
1360 if (subcontrolString == QLatin1String("down"))
1361 subcontrol = QStyle::SC_SpinBoxDown;
1362 else if (subcontrolString == QLatin1String("up"))
1363 subcontrol = QStyle::SC_SpinBoxUp;
1364 else if (subcontrolString == QLatin1String("edit")){
1365 subcontrol = QStyle::SC_SpinBoxEditField;
1366 }
1367 return qApp->style()->subControlRect(cc: control,
1368 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1369 sc: subcontrol);
1370
1371 }
1372 break;
1373 case Slider:
1374 {
1375 QStyle::ComplexControl control = QStyle::CC_Slider;
1376 if (subcontrolString == QLatin1String("handle"))
1377 subcontrol = QStyle::SC_SliderHandle;
1378 else if (subcontrolString == QLatin1String("groove"))
1379 subcontrol = QStyle::SC_SliderGroove;
1380 return qApp->style()->subControlRect(cc: control,
1381 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1382 sc: subcontrol);
1383
1384 }
1385 break;
1386 case ScrollBar:
1387 {
1388 QStyle::ComplexControl control = QStyle::CC_ScrollBar;
1389 if (subcontrolString == QLatin1String("slider"))
1390 subcontrol = QStyle::SC_ScrollBarSlider;
1391 if (subcontrolString == QLatin1String("groove"))
1392 subcontrol = QStyle::SC_ScrollBarGroove;
1393 else if (subcontrolString == QLatin1String("handle"))
1394 subcontrol = QStyle::SC_ScrollBarSlider;
1395 else if (subcontrolString == QLatin1String("add"))
1396 subcontrol = QStyle::SC_ScrollBarAddPage;
1397 else if (subcontrolString == QLatin1String("sub"))
1398 subcontrol = QStyle::SC_ScrollBarSubPage;
1399 return qApp->style()->subControlRect(cc: control,
1400 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1401 sc: subcontrol);
1402 }
1403 break;
1404 case ItemBranchIndicator: {
1405 QStyleOption opt;
1406 opt.rect = QRect(0, 0, implicitWidth(), implicitHeight());
1407 return qApp->style()->subElementRect(subElement: QStyle::SE_TreeViewDisclosureItem, option: &opt, widget: 0);
1408 }
1409 default:
1410 break;
1411 }
1412 return QRectF();
1413}
1414
1415namespace {
1416class QHighDpiPixmapsEnabler1 {
1417public:
1418 QHighDpiPixmapsEnabler1()
1419 :wasEnabled(false)
1420 {
1421 if (!qApp->testAttribute(attribute: Qt::AA_UseHighDpiPixmaps)) {
1422 qApp->setAttribute(attribute: Qt::AA_UseHighDpiPixmaps);
1423 wasEnabled = true;
1424 }
1425 }
1426
1427 ~QHighDpiPixmapsEnabler1()
1428 {
1429 if (wasEnabled)
1430 qApp->setAttribute(attribute: Qt::AA_UseHighDpiPixmaps, on: false);
1431 }
1432private:
1433 bool wasEnabled;
1434};
1435}
1436
1437void QQuickStyleItem1::paint(QPainter *painter)
1438{
1439 initStyleOption();
1440 if (QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(opt: m_styleoption))
1441 painter->setFont(opt->font);
1442 else {
1443 QPlatformTheme::Font platformFont = (m_styleoption->state & QStyle::State_Mini) ? QPlatformTheme::MiniFont :
1444 (m_styleoption->state & QStyle::State_Small) ? QPlatformTheme::SmallFont :
1445 QPlatformTheme::NFonts;
1446 if (platformFont != QPlatformTheme::NFonts)
1447 if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(type: platformFont))
1448 painter->setFont(*font);
1449 }
1450
1451 // Set AA_UseHighDpiPixmaps when calling style code to make QIcon return
1452 // "retina" pixmaps. The flag is controlled by the application so we can't
1453 // set it unconditinally.
1454 QHighDpiPixmapsEnabler1 enabler;
1455
1456 switch (m_itemType) {
1457 case Button:
1458#ifdef Q_OS_OSX
1459 if (style() == QLatin1String("mac")) {
1460 // Add back what was substracted in sizeFromContents()
1461 m_styleoption->rect.adjust(-4, -2, 3, 4);
1462 }
1463#endif
1464 qApp->style()->drawControl(element: QStyle::CE_PushButton, opt: m_styleoption, p: painter);
1465 break;
1466 case ItemRow :{
1467 QPixmap pixmap;
1468 // Only draw through style once
1469 const QString pmKey = QLatin1String("itemrow") % QString::number(m_styleoption->state,base: 16) % activeControl();
1470 if (!QPixmapCache::find(key: pmKey, pixmap: &pixmap) || pixmap.width() < width() || height() != pixmap.height()) {
1471 int newSize = width();
1472 pixmap = QPixmap(newSize, height());
1473 pixmap.fill(fillColor: Qt::transparent);
1474 QPainter pixpainter(&pixmap);
1475 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelItemViewRow, opt: m_styleoption, p: &pixpainter);
1476 if ((style() == QLatin1String("mac") || !qApp->style()->styleHint(stylehint: QStyle::SH_ItemView_ShowDecorationSelected)) && selected()) {
1477 QPalette pal = QApplication::palette(className: "QAbstractItemView");
1478 pal.setCurrentColorGroup(m_styleoption->palette.currentColorGroup());
1479 pixpainter.fillRect(m_styleoption->rect, pal.highlight());
1480 }
1481 QPixmapCache::insert(key: pmKey, pixmap);
1482 }
1483 painter->drawPixmap(x: 0, y: 0, pm: pixmap);
1484 }
1485 break;
1486 case Item:
1487 qApp->style()->drawControl(element: QStyle::CE_ItemViewItem, opt: m_styleoption, p: painter);
1488 break;
1489 case ItemBranchIndicator:
1490 qApp->style()->drawPrimitive(pe: QStyle::PE_IndicatorBranch, opt: m_styleoption, p: painter);
1491 break;
1492 case Header:
1493 qApp->style()->drawControl(element: QStyle::CE_Header, opt: m_styleoption, p: painter);
1494 break;
1495 case ToolButton:
1496
1497#ifdef Q_OS_OSX
1498 if (style() == QLatin1String("mac") && hints().value(QStringLiteral("segmented")).toBool()) {
1499 const QPaintDevice *target = painter->device();
1500 HIThemeSegmentDrawInfo sgi;
1501 sgi.version = 0;
1502 sgi.state = isEnabled() ? kThemeStateActive : kThemeStateDisabled;
1503 if (sunken()) sgi.state |= kThemeStatePressed;
1504 sgi.size = kHIThemeSegmentSizeNormal;
1505 sgi.kind = kHIThemeSegmentKindTextured;
1506 sgi.value = on() && !sunken() ? kThemeButtonOn : kThemeButtonOff;
1507
1508 sgi.adornment |= kHIThemeSegmentAdornmentLeadingSeparator;
1509 if (sunken()) {
1510 sgi.adornment |= kHIThemeSegmentAdornmentTrailingSeparator;
1511 }
1512 SInt32 button_height;
1513 GetThemeMetric(kThemeMetricButtonRoundedHeight, &button_height);
1514 QString buttonPos = m_properties.value(QStringLiteral("position")).toString();
1515 sgi.position = buttonPos == QLatin1String("leftmost") ? kHIThemeSegmentPositionFirst :
1516 buttonPos == QLatin1String("rightmost") ? kHIThemeSegmentPositionLast :
1517 buttonPos == QLatin1String("h_middle") ? kHIThemeSegmentPositionMiddle :
1518 kHIThemeSegmentPositionOnly;
1519 QRect centered = m_styleoption->rect;
1520 centered.setHeight(button_height);
1521 centered.moveCenter(m_styleoption->rect.center());
1522 HIRect hirect = qt_hirectForQRect(centered.translated(0, -1), QRect(0, 0, 0, 0));
1523 HIThemeDrawSegment(&hirect, &sgi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
1524 } else
1525#endif
1526 qApp->style()->drawComplexControl(cc: QStyle::CC_ToolButton, opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption), p: painter);
1527 break;
1528 case Tab:
1529#ifdef Q_OS_OSX
1530 if (style() == QLatin1String("mac")) {
1531 m_styleoption->rect.translate(0, 1); // Unhack QMacStyle's hack
1532 qApp->style()->drawControl(QStyle::CE_TabBarTabShape, m_styleoption, painter);
1533 m_styleoption->rect.translate(0, -1);
1534 qApp->style()->drawControl(QStyle::CE_TabBarTabLabel, m_styleoption, painter);
1535 } else
1536#endif
1537 {
1538 qApp->style()->drawControl(element: QStyle::CE_TabBarTab, opt: m_styleoption, p: painter);
1539 }
1540 break;
1541 case Frame:
1542 qApp->style()->drawControl(element: QStyle::CE_ShapedFrame, opt: m_styleoption, p: painter);
1543 break;
1544 case FocusFrame:
1545 qApp->style()->drawControl(element: QStyle::CE_FocusFrame, opt: m_styleoption, p: painter);
1546 break;
1547 case FocusRect:
1548 qApp->style()->drawPrimitive(pe: QStyle::PE_FrameFocusRect, opt: m_styleoption, p: painter);
1549 break;
1550 case TabFrame:
1551 qApp->style()->drawPrimitive(pe: QStyle::PE_FrameTabWidget, opt: m_styleoption, p: painter);
1552 break;
1553 case MenuBar:
1554 qApp->style()->drawControl(element: QStyle::CE_MenuBarEmptyArea, opt: m_styleoption, p: painter);
1555 break;
1556 case MenuBarItem:
1557 qApp->style()->drawControl(element: QStyle::CE_MenuBarItem, opt: m_styleoption, p: painter);
1558 break;
1559 case MenuItem:
1560 case ComboBoxItem: { // fall through
1561 QStyle::ControlElement menuElement =
1562 static_cast<QStyleOptionMenuItem *>(m_styleoption)->menuItemType == QStyleOptionMenuItem::Scroller ?
1563 QStyle::CE_MenuScroller : QStyle::CE_MenuItem;
1564 qApp->style()->drawControl(element: menuElement, opt: m_styleoption, p: painter);
1565 }
1566 break;
1567 case CheckBox:
1568 qApp->style()->drawControl(element: QStyle::CE_CheckBox, opt: m_styleoption, p: painter);
1569 break;
1570 case RadioButton:
1571 qApp->style()->drawControl(element: QStyle::CE_RadioButton, opt: m_styleoption, p: painter);
1572 break;
1573 case Edit: {
1574#ifdef Q_OS_OSX
1575 if (style() == QLatin1String("mac") && hints().value(QStringLiteral("rounded")).toBool()) {
1576 const QPaintDevice *target = painter->device();
1577 HIThemeFrameDrawInfo fdi;
1578 fdi.version = 0;
1579 fdi.state = kThemeStateActive;
1580 SInt32 frame_size;
1581 GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
1582 fdi.kind = kHIThemeFrameTextFieldRound;
1583 if ((m_styleoption->state & QStyle::State_ReadOnly) || !(m_styleoption->state & QStyle::State_Enabled))
1584 fdi.state = kThemeStateInactive;
1585 fdi.isFocused = hasFocus();
1586 HIRect hirect = qt_hirectForQRect(m_styleoption->rect.adjusted(2, 2, -2, 2), QRect(0, 0, 0, 0));
1587 HIThemeDrawFrame(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
1588 } else
1589#endif
1590 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelLineEdit, opt: m_styleoption, p: painter);
1591 }
1592 break;
1593 case MacHelpButton:
1594#ifdef Q_OS_OSX
1595 {
1596 const QPaintDevice *target = painter->device();
1597 HIThemeButtonDrawInfo fdi;
1598 fdi.kind = kThemeRoundButtonHelp;
1599 fdi.version = 0;
1600 fdi.adornment = 0;
1601 fdi.state = sunken() ? kThemeStatePressed : kThemeStateActive;
1602 HIRect hirect = qt_hirectForQRect(m_styleoption->rect,QRect(0, 0, 0, 0));
1603 HIThemeDrawButton(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal, NULL);
1604 }
1605#endif
1606 break;
1607 case Widget:
1608 qApp->style()->drawPrimitive(pe: QStyle::PE_Widget, opt: m_styleoption, p: painter);
1609 break;
1610 case ScrollAreaCorner:
1611 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelScrollAreaCorner, opt: m_styleoption, p: painter);
1612 break;
1613 case Splitter:
1614 if (m_styleoption->rect.width() == 1)
1615 painter->fillRect(x: 0, y: 0, w: width(), h: height(), b: m_styleoption->palette.dark().color());
1616 else
1617 qApp->style()->drawControl(element: QStyle::CE_Splitter, opt: m_styleoption, p: painter);
1618 break;
1619 case ComboBox:
1620 {
1621 qApp->style()->drawComplexControl(cc: QStyle::CC_ComboBox,
1622 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1623 p: painter);
1624 // This is needed on mac as it will use the painter color and ignore the palette
1625 QPen pen = painter->pen();
1626 painter->setPen(m_styleoption->palette.text().color());
1627 qApp->style()->drawControl(element: QStyle::CE_ComboBoxLabel, opt: m_styleoption, p: painter);
1628 painter->setPen(pen);
1629 } break;
1630 case SpinBox:
1631#ifdef Q_OS_MAC
1632 // macstyle depends on the embedded qlineedit to fill the editfield background
1633 if (style() == QLatin1String("mac")) {
1634 QRect editRect = qApp->style()->subControlRect(QStyle::CC_SpinBox,
1635 qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
1636 QStyle::SC_SpinBoxEditField);
1637 painter->fillRect(editRect.adjusted(-1, -1, 1, 1), m_styleoption->palette.base());
1638 }
1639#endif
1640 qApp->style()->drawComplexControl(cc: QStyle::CC_SpinBox,
1641 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1642 p: painter);
1643 break;
1644 case Slider:
1645 qApp->style()->drawComplexControl(cc: QStyle::CC_Slider,
1646 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1647 p: painter);
1648 break;
1649 case Dial:
1650 qApp->style()->drawComplexControl(cc: QStyle::CC_Dial,
1651 opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption),
1652 p: painter);
1653 break;
1654 case ProgressBar:
1655 qApp->style()->drawControl(element: QStyle::CE_ProgressBar, opt: m_styleoption, p: painter);
1656 break;
1657 case ToolBar:
1658 painter->fillRect(m_styleoption->rect, color: m_styleoption->palette.window().color());
1659 qApp->style()->drawControl(element: QStyle::CE_ToolBar, opt: m_styleoption, p: painter);
1660 painter->save();
1661 painter->setPen(style() != QLatin1String("fusion") ? m_styleoption->palette.dark().color().darker(f: 120) :
1662 m_styleoption->palette.window().color().lighter(f: 107));
1663 painter->drawLine(p1: m_styleoption->rect.bottomLeft(), p2: m_styleoption->rect.bottomRight());
1664 painter->restore();
1665 break;
1666 case StatusBar:
1667#ifdef Q_OS_OSX
1668 if (style() == QLatin1String("mac")) {
1669 qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter);
1670 painter->setPen(m_styleoption->palette.dark().color().darker(120));
1671 painter->drawLine(m_styleoption->rect.topLeft(), m_styleoption->rect.topRight());
1672 } else
1673#endif
1674 {
1675 painter->fillRect(m_styleoption->rect, color: m_styleoption->palette.window().color());
1676 painter->setPen(m_styleoption->palette.dark().color().darker(f: 120));
1677 painter->drawLine(p1: m_styleoption->rect.topLeft(), p2: m_styleoption->rect.topRight());
1678 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelStatusBar, opt: m_styleoption, p: painter);
1679 }
1680 break;
1681 case GroupBox:
1682 qApp->style()->drawComplexControl(cc: QStyle::CC_GroupBox, opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption), p: painter);
1683 break;
1684 case ScrollBar:
1685 qApp->style()->drawComplexControl(cc: QStyle::CC_ScrollBar, opt: qstyleoption_cast<QStyleOptionComplex*>(opt: m_styleoption), p: painter);
1686 break;
1687 case Menu: {
1688 QStyleHintReturnMask val;
1689 qApp->style()->styleHint(stylehint: QStyle::SH_Menu_Mask, opt: m_styleoption, widget: 0, returnData: &val);
1690 painter->save();
1691 painter->setClipRegion(val.region);
1692 painter->fillRect(m_styleoption->rect, m_styleoption->palette.window());
1693 painter->restore();
1694 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelMenu, opt: m_styleoption, p: painter);
1695
1696 if (int fw = qApp->style()->pixelMetric(metric: QStyle::PM_MenuPanelWidth)) {
1697 QStyleOptionFrame frame;
1698 frame.state = QStyle::State_None;
1699 frame.lineWidth = fw;
1700 frame.midLineWidth = 0;
1701 frame.rect = m_styleoption->rect;
1702 frame.styleObject = this;
1703 frame.palette = m_styleoption->palette;
1704 qApp->style()->drawPrimitive(pe: QStyle::PE_FrameMenu, opt: &frame, p: painter);
1705 }
1706 }
1707 break;
1708 default:
1709 break;
1710 }
1711}
1712
1713qreal QQuickStyleItem1::textWidth(const QString &text)
1714{
1715 QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
1716 return fm.boundingRect(string: text).width();
1717}
1718
1719qreal QQuickStyleItem1::textHeight(const QString &text)
1720{
1721 QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
1722 return text.isEmpty() ? fm.height() :
1723 fm.boundingRect(string: text).height();
1724}
1725
1726QString QQuickStyleItem1::elidedText(const QString &text, int elideMode, int width)
1727{
1728 return m_styleoption->fontMetrics.elidedText(text, mode: Qt::TextElideMode(elideMode), width);
1729}
1730
1731bool QQuickStyleItem1::hasThemeIcon(const QString &icon) const
1732{
1733 return QIcon::hasThemeIcon(name: icon);
1734}
1735
1736bool QQuickStyleItem1::event(QEvent *ev)
1737{
1738 if (ev->type() == QEvent::StyleAnimationUpdate) {
1739 if (isVisible()) {
1740 ev->accept();
1741 polish();
1742 }
1743 return true;
1744 } else if (ev->type() == QEvent::StyleChange) {
1745 if (m_itemType == ScrollBar)
1746 initStyleOption();
1747 }
1748 return QQuickItem::event(ev);
1749}
1750
1751void QQuickStyleItem1::setTextureWidth(int w)
1752{
1753 if (m_textureWidth == w)
1754 return;
1755 m_textureWidth = w;
1756 emit textureWidthChanged(w: m_textureWidth);
1757 update();
1758}
1759
1760void QQuickStyleItem1::setTextureHeight(int h)
1761{
1762 if (m_textureHeight == h)
1763 return;
1764 m_textureHeight = h;
1765 emit textureHeightChanged(h: m_textureHeight);
1766 update();
1767}
1768
1769QSGNode *QQuickStyleItem1::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
1770{
1771 if (m_image.isNull()) {
1772 delete node;
1773 return 0;
1774 }
1775
1776 QSGNinePatchNode *styleNode = static_cast<QSGNinePatchNode *>(node);
1777 if (!styleNode)
1778 styleNode = window()->createNinePatchNode();
1779
1780#ifdef QSG_RUNTIME_DESCRIPTION
1781 qsgnode_set_description(node: styleNode,
1782 description: QString::fromLatin1(str: "%1:%2, '%3'")
1783 .arg(a: style())
1784 .arg(a: elementType())
1785 .arg(a: text()));
1786#endif
1787
1788 styleNode->setTexture(window()->createTextureFromImage(image: m_image, options: QQuickWindow::TextureCanUseAtlas));
1789 styleNode->setBounds(boundingRect());
1790 styleNode->setDevicePixelRatio(window()->devicePixelRatio());
1791 styleNode->setPadding(left: m_border.left(), top: m_border.top(), right: m_border.right(), bottom: m_border.bottom());
1792 styleNode->update();
1793
1794 return styleNode;
1795}
1796
1797void QQuickStyleItem1::updatePolish()
1798{
1799 if (width() >= 1 && height() >= 1) { // Note these are reals so 1 pixel is minimum
1800 float devicePixelRatio = window() ? window()->devicePixelRatio() : qApp->devicePixelRatio();
1801 int w = m_textureWidth > 0 ? m_textureWidth : width();
1802 int h = m_textureHeight > 0 ? m_textureHeight : height();
1803 m_image = QImage(w * devicePixelRatio, h * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
1804 m_image.setDevicePixelRatio(devicePixelRatio);
1805 m_image.fill(color: Qt::transparent);
1806 QPainter painter(&m_image);
1807 painter.setLayoutDirection(qApp->layoutDirection());
1808 paint(painter: &painter);
1809 QQuickItem::update();
1810 } else if (!m_image.isNull()) {
1811 m_image = QImage();
1812 QQuickItem::update();
1813 }
1814}
1815
1816QPixmap QQuickTableRowImageProvider1::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
1817{
1818 Q_UNUSED (requestedSize);
1819 int width = 16;
1820 int height = 16;
1821 if (size)
1822 *size = QSize(width, height);
1823
1824 QPixmap pixmap(width, height);
1825#if QT_CONFIG(itemviews)
1826 QStyleOptionViewItem opt;
1827 opt.state |= QStyle::State_Enabled;
1828 opt.rect = QRect(0, 0, width, height);
1829 QString style = qApp->style()->metaObject()->className();
1830 opt.features = {};
1831
1832 if (id.contains(s: QLatin1String("selected")))
1833 opt.state |= QStyle::State_Selected;
1834
1835 if (id.contains(s: QLatin1String("active"))) {
1836 opt.state |= QStyle::State_Active;
1837 opt.palette.setCurrentColorGroup(QPalette::Active);
1838 } else
1839 opt.palette.setCurrentColorGroup(QPalette::Inactive);
1840
1841 if (id.contains(s: QLatin1String("alternate")))
1842 opt.features |= QStyleOptionViewItem::Alternate;
1843
1844 QPalette pal = QApplication::palette(className: "QAbstractItemView");
1845 if (opt.state & QStyle::State_Selected && (style.contains(s: QLatin1String("Mac")) ||
1846 !qApp->style()->styleHint(stylehint: QStyle::SH_ItemView_ShowDecorationSelected))) {
1847 pal.setCurrentColorGroup(opt.palette.currentColorGroup());
1848 pixmap.fill(fillColor: pal.highlight().color());
1849 } else {
1850 pixmap.fill(fillColor: pal.base().color());
1851 QPainter pixpainter(&pixmap);
1852 qApp->style()->drawPrimitive(pe: QStyle::PE_PanelItemViewRow, opt: &opt, p: &pixpainter);
1853 }
1854#else
1855 Q_UNUSED(id);
1856#endif
1857 return pixmap;
1858}
1859
1860QT_END_NAMESPACE
1861

source code of qtquickcontrols/src/controls/Private/qquickstyleitem.cpp