1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquickmaterialstyle_p.h"
38
39#include <QtCore/qdebug.h>
40#include <QtCore/qsettings.h>
41#include <QtQml/qqmlinfo.h>
42#include <QtQuickControls2/private/qquickstyle_p.h>
43
44QT_BEGIN_NAMESPACE
45
46static const QRgb colors[][14] = {
47 // Red
48 {
49 0xFFFFEBEE, // Shade50
50 0xFFFFCDD2, // Shade100
51 0xFFEF9A9A, // Shade200
52 0xFFE57373, // Shade300
53 0xFFEF5350, // Shade400
54 0xFFF44336, // Shade500
55 0xFFE53935, // Shade600
56 0xFFD32F2F, // Shade700
57 0xFFC62828, // Shade800
58 0xFFB71C1C, // Shade900
59 0xFFFF8A80, // ShadeA100
60 0xFFFF5252, // ShadeA200
61 0xFFFF1744, // ShadeA400
62 0xFFD50000 // ShadeA700
63 },
64 // Pink
65 {
66 0xFFFCE4EC, // Shade50
67 0xFFF8BBD0, // Shade100
68 0xFFF48FB1, // Shade200
69 0xFFF06292, // Shade300
70 0xFFEC407A, // Shade400
71 0xFFE91E63, // Shade500
72 0xFFD81B60, // Shade600
73 0xFFC2185B, // Shade700
74 0xFFAD1457, // Shade800
75 0xFF880E4F, // Shade900
76 0xFFFF80AB, // ShadeA100
77 0xFFFF4081, // ShadeA200
78 0xFFF50057, // ShadeA400
79 0xFFC51162 // ShadeA700
80 },
81 // Purple
82 {
83 0xFFF3E5F5, // Shade50
84 0xFFE1BEE7, // Shade100
85 0xFFCE93D8, // Shade200
86 0xFFBA68C8, // Shade300
87 0xFFAB47BC, // Shade400
88 0xFF9C27B0, // Shade500
89 0xFF8E24AA, // Shade600
90 0xFF7B1FA2, // Shade700
91 0xFF6A1B9A, // Shade800
92 0xFF4A148C, // Shade900
93 0xFFEA80FC, // ShadeA100
94 0xFFE040FB, // ShadeA200
95 0xFFD500F9, // ShadeA400
96 0xFFAA00FF // ShadeA700
97 },
98 // DeepPurple
99 {
100 0xFFEDE7F6, // Shade50
101 0xFFD1C4E9, // Shade100
102 0xFFB39DDB, // Shade200
103 0xFF9575CD, // Shade300
104 0xFF7E57C2, // Shade400
105 0xFF673AB7, // Shade500
106 0xFF5E35B1, // Shade600
107 0xFF512DA8, // Shade700
108 0xFF4527A0, // Shade800
109 0xFF311B92, // Shade900
110 0xFFB388FF, // ShadeA100
111 0xFF7C4DFF, // ShadeA200
112 0xFF651FFF, // ShadeA400
113 0xFF6200EA // ShadeA700
114 },
115 // Indigo
116 {
117 0xFFE8EAF6, // Shade50
118 0xFFC5CAE9, // Shade100
119 0xFF9FA8DA, // Shade200
120 0xFF7986CB, // Shade300
121 0xFF5C6BC0, // Shade400
122 0xFF3F51B5, // Shade500
123 0xFF3949AB, // Shade600
124 0xFF303F9F, // Shade700
125 0xFF283593, // Shade800
126 0xFF1A237E, // Shade900
127 0xFF8C9EFF, // ShadeA100
128 0xFF536DFE, // ShadeA200
129 0xFF3D5AFE, // ShadeA400
130 0xFF304FFE // ShadeA700
131 },
132 // Blue
133 {
134 0xFFE3F2FD, // Shade50
135 0xFFBBDEFB, // Shade100
136 0xFF90CAF9, // Shade200
137 0xFF64B5F6, // Shade300
138 0xFF42A5F5, // Shade400
139 0xFF2196F3, // Shade500
140 0xFF1E88E5, // Shade600
141 0xFF1976D2, // Shade700
142 0xFF1565C0, // Shade800
143 0xFF0D47A1, // Shade900
144 0xFF82B1FF, // ShadeA100
145 0xFF448AFF, // ShadeA200
146 0xFF2979FF, // ShadeA400
147 0xFF2962FF // ShadeA700
148 },
149 // LightBlue
150 {
151 0xFFE1F5FE, // Shade50
152 0xFFB3E5FC, // Shade100
153 0xFF81D4FA, // Shade200
154 0xFF4FC3F7, // Shade300
155 0xFF29B6F6, // Shade400
156 0xFF03A9F4, // Shade500
157 0xFF039BE5, // Shade600
158 0xFF0288D1, // Shade700
159 0xFF0277BD, // Shade800
160 0xFF01579B, // Shade900
161 0xFF80D8FF, // ShadeA100
162 0xFF40C4FF, // ShadeA200
163 0xFF00B0FF, // ShadeA400
164 0xFF0091EA // ShadeA700
165 },
166 // Cyan
167 {
168 0xFFE0F7FA, // Shade50
169 0xFFB2EBF2, // Shade100
170 0xFF80DEEA, // Shade200
171 0xFF4DD0E1, // Shade300
172 0xFF26C6DA, // Shade400
173 0xFF00BCD4, // Shade500
174 0xFF00ACC1, // Shade600
175 0xFF0097A7, // Shade700
176 0xFF00838F, // Shade800
177 0xFF006064, // Shade900
178 0xFF84FFFF, // ShadeA100
179 0xFF18FFFF, // ShadeA200
180 0xFF00E5FF, // ShadeA400
181 0xFF00B8D4 // ShadeA700
182 },
183 // Teal
184 {
185 0xFFE0F2F1, // Shade50
186 0xFFB2DFDB, // Shade100
187 0xFF80CBC4, // Shade200
188 0xFF4DB6AC, // Shade300
189 0xFF26A69A, // Shade400
190 0xFF009688, // Shade500
191 0xFF00897B, // Shade600
192 0xFF00796B, // Shade700
193 0xFF00695C, // Shade800
194 0xFF004D40, // Shade900
195 0xFFA7FFEB, // ShadeA100
196 0xFF64FFDA, // ShadeA200
197 0xFF1DE9B6, // ShadeA400
198 0xFF00BFA5 // ShadeA700
199 },
200 // Green
201 {
202 0xFFE8F5E9, // Shade50
203 0xFFC8E6C9, // Shade100
204 0xFFA5D6A7, // Shade200
205 0xFF81C784, // Shade300
206 0xFF66BB6A, // Shade400
207 0xFF4CAF50, // Shade500
208 0xFF43A047, // Shade600
209 0xFF388E3C, // Shade700
210 0xFF2E7D32, // Shade800
211 0xFF1B5E20, // Shade900
212 0xFFB9F6CA, // ShadeA100
213 0xFF69F0AE, // ShadeA200
214 0xFF00E676, // ShadeA400
215 0xFF00C853 // ShadeA700
216 },
217 // LightGreen
218 {
219 0xFFF1F8E9, // Shade50
220 0xFFDCEDC8, // Shade100
221 0xFFC5E1A5, // Shade200
222 0xFFAED581, // Shade300
223 0xFF9CCC65, // Shade400
224 0xFF8BC34A, // Shade500
225 0xFF7CB342, // Shade600
226 0xFF689F38, // Shade700
227 0xFF558B2F, // Shade800
228 0xFF33691E, // Shade900
229 0xFFCCFF90, // ShadeA100
230 0xFFB2FF59, // ShadeA200
231 0xFF76FF03, // ShadeA400
232 0xFF64DD17 // ShadeA700
233 },
234 // Lime
235 {
236 0xFFF9FBE7, // Shade50
237 0xFFF0F4C3, // Shade100
238 0xFFE6EE9C, // Shade200
239 0xFFDCE775, // Shade300
240 0xFFD4E157, // Shade400
241 0xFFCDDC39, // Shade500
242 0xFFC0CA33, // Shade600
243 0xFFAFB42B, // Shade700
244 0xFF9E9D24, // Shade800
245 0xFF827717, // Shade900
246 0xFFF4FF81, // ShadeA100
247 0xFFEEFF41, // ShadeA200
248 0xFFC6FF00, // ShadeA400
249 0xFFAEEA00 // ShadeA700
250 },
251 // Yellow
252 {
253 0xFFFFFDE7, // Shade50
254 0xFFFFF9C4, // Shade100
255 0xFFFFF59D, // Shade200
256 0xFFFFF176, // Shade300
257 0xFFFFEE58, // Shade400
258 0xFFFFEB3B, // Shade500
259 0xFFFDD835, // Shade600
260 0xFFFBC02D, // Shade700
261 0xFFF9A825, // Shade800
262 0xFFF57F17, // Shade900
263 0xFFFFFF8D, // ShadeA100
264 0xFFFFFF00, // ShadeA200
265 0xFFFFEA00, // ShadeA400
266 0xFFFFD600 // ShadeA700
267 },
268 // Amber
269 {
270 0xFFFFF8E1, // Shade50
271 0xFFFFECB3, // Shade100
272 0xFFFFE082, // Shade200
273 0xFFFFD54F, // Shade300
274 0xFFFFCA28, // Shade400
275 0xFFFFC107, // Shade500
276 0xFFFFB300, // Shade600
277 0xFFFFA000, // Shade700
278 0xFFFF8F00, // Shade800
279 0xFFFF6F00, // Shade900
280 0xFFFFE57F, // ShadeA100
281 0xFFFFD740, // ShadeA200
282 0xFFFFC400, // ShadeA400
283 0xFFFFAB00 // ShadeA700
284 },
285 // Orange
286 {
287 0xFFFFF3E0, // Shade50
288 0xFFFFE0B2, // Shade100
289 0xFFFFCC80, // Shade200
290 0xFFFFB74D, // Shade300
291 0xFFFFA726, // Shade400
292 0xFFFF9800, // Shade500
293 0xFFFB8C00, // Shade600
294 0xFFF57C00, // Shade700
295 0xFFEF6C00, // Shade800
296 0xFFE65100, // Shade900
297 0xFFFFD180, // ShadeA100
298 0xFFFFAB40, // ShadeA200
299 0xFFFF9100, // ShadeA400
300 0xFFFF6D00 // ShadeA700
301 },
302 // DeepOrange
303 {
304 0xFFFBE9E7, // Shade50
305 0xFFFFCCBC, // Shade100
306 0xFFFFAB91, // Shade200
307 0xFFFF8A65, // Shade300
308 0xFFFF7043, // Shade400
309 0xFFFF5722, // Shade500
310 0xFFF4511E, // Shade600
311 0xFFE64A19, // Shade700
312 0xFFD84315, // Shade800
313 0xFFBF360C, // Shade900
314 0xFFFF9E80, // ShadeA100
315 0xFFFF6E40, // ShadeA200
316 0xFFFF3D00, // ShadeA400
317 0xFFDD2C00 // ShadeA700
318 },
319 // Brown
320 {
321 0xFFEFEBE9, // Shade50
322 0xFFD7CCC8, // Shade100
323 0xFFBCAAA4, // Shade200
324 0xFFA1887F, // Shade300
325 0xFF8D6E63, // Shade400
326 0xFF795548, // Shade500
327 0xFF6D4C41, // Shade600
328 0xFF5D4037, // Shade700
329 0xFF4E342E, // Shade800
330 0xFF3E2723, // Shade900
331 0xFF000000, // ShadeA100
332 0xFF000000, // ShadeA200
333 0xFF000000, // ShadeA400
334 0xFF000000 // ShadeA700
335 },
336 // Grey
337 {
338 0xFFFAFAFA, // Shade50
339 0xFFF5F5F5, // Shade100
340 0xFFEEEEEE, // Shade200
341 0xFFE0E0E0, // Shade300
342 0xFFBDBDBD, // Shade400
343 0xFF9E9E9E, // Shade500
344 0xFF757575, // Shade600
345 0xFF616161, // Shade700
346 0xFF424242, // Shade800
347 0xFF212121, // Shade900
348 0xFF000000, // ShadeA100
349 0xFF000000, // ShadeA200
350 0xFF000000, // ShadeA400
351 0xFF000000 // ShadeA700
352 },
353 // BlueGrey
354 {
355 0xFFECEFF1, // Shade50
356 0xFFCFD8DC, // Shade100
357 0xFFB0BEC5, // Shade200
358 0xFF90A4AE, // Shade300
359 0xFF78909C, // Shade400
360 0xFF607D8B, // Shade500
361 0xFF546E7A, // Shade600
362 0xFF455A64, // Shade700
363 0xFF37474F, // Shade800
364 0xFF263238, // Shade900
365 0xFF000000, // ShadeA100
366 0xFF000000, // ShadeA200
367 0xFF000000, // ShadeA400
368 0xFF000000 // ShadeA700
369 }
370};
371
372// If no value was inherited from a parent or explicitly set, the "global" values are used.
373// The initial, default values of the globals are hard-coded here, but the environment
374// variables and .conf file override them if specified.
375static QQuickMaterialStyle::Theme globalTheme = QQuickMaterialStyle::Light;
376static uint globalPrimary = QQuickMaterialStyle::Indigo;
377static uint globalAccent = QQuickMaterialStyle::Pink;
378static uint globalForeground = 0xDD000000; // primaryTextColorLight
379static uint globalBackground = 0xFFFAFAFA; // backgroundColorLight
380// These represent whether a global foreground/background was set.
381// Each style's m_hasForeground/m_hasBackground are initialized to these values.
382static bool hasGlobalForeground = false;
383static bool hasGlobalBackground = false;
384// These represent whether or not the global color value was specified as one of the
385// values that QColor accepts, as opposed to one of the pre-defined colors like Red.
386static bool globalPrimaryCustom = false;
387static bool globalAccentCustom = false;
388static bool globalForegroundCustom = true;
389static bool globalBackgroundCustom = true;
390// This is global because:
391// 1) The theme needs access to it to determine font sizes.
392// 2) There can only be one variant used for the whole application.
393static QQuickMaterialStyle::Variant globalVariant = QQuickMaterialStyle::Normal;
394
395static const QRgb backgroundColorLight = 0xFFFAFAFA;
396static const QRgb backgroundColorDark = 0xFF303030;
397static const QRgb dialogColorLight = 0xFFFFFFFF;
398static const QRgb dialogColorDark = 0xFF424242;
399static const QRgb primaryTextColorLight = 0xDD000000;
400static const QRgb primaryTextColorDark = 0xFFFFFFFF;
401static const QRgb secondaryTextColorLight = 0x89000000;
402static const QRgb secondaryTextColorDark = 0xB2FFFFFF;
403static const QRgb hintTextColorLight = 0x60000000;
404static const QRgb hintTextColorDark = 0x4CFFFFFF;
405static const QRgb dividerColorLight = 0x1E000000;
406static const QRgb dividerColorDark = 0x1EFFFFFF;
407static const QRgb iconColorLight = 0x89000000;
408static const QRgb iconColorDark = 0xFFFFFFFF;
409static const QRgb iconDisabledColorLight = 0x42000000;
410static const QRgb iconDisabledColorDark = 0x4CFFFFFF;
411static const QRgb raisedButtonColorLight = 0xFFD6D7D7;
412static const QRgb raisedButtonColorDark = 0x3FCCCCCC;
413static const QRgb raisedButtonDisabledColorLight = dividerColorLight;
414static const QRgb raisedButtonDisabledColorDark = dividerColorDark;
415static const QRgb frameColorLight = hintTextColorLight;
416static const QRgb frameColorDark = hintTextColorDark;
417static const QRgb switchUncheckedTrackColorLight = 0x42000000;
418static const QRgb switchUncheckedTrackColorDark = 0x4CFFFFFF;
419static const QRgb switchDisabledTrackColorLight = 0x1E000000;
420static const QRgb switchDisabledTrackColorDark = 0x19FFFFFF;
421static const QRgb rippleColorLight = 0x10000000;
422static const QRgb rippleColorDark = 0x20FFFFFF;
423static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC;
424static const QRgb spinBoxDisabledIconColorDark = 0xFF666666;
425static const QRgb sliderDisabledColorLight = 0xFF9E9E9E;
426static const QRgb sliderDisabledColorDark = 0xFF616161;
427
428static QQuickMaterialStyle::Theme effectiveTheme(QQuickMaterialStyle::Theme theme)
429{
430 if (theme == QQuickMaterialStyle::System)
431 theme = QQuickStylePrivate::isDarkSystemTheme() ? QQuickMaterialStyle::Dark : QQuickMaterialStyle::Light;
432 return theme;
433}
434
435QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickAttachedObject(parent),
436 m_customPrimary(globalPrimaryCustom),
437 m_customAccent(globalAccentCustom),
438 m_customForeground(globalForegroundCustom),
439 m_customBackground(globalBackgroundCustom),
440 m_hasForeground(hasGlobalForeground),
441 m_hasBackground(hasGlobalBackground),
442 m_theme(globalTheme),
443 m_primary(globalPrimary),
444 m_accent(globalAccent),
445 m_foreground(globalForeground),
446 m_background(globalBackground)
447{
448 QQuickAttachedObject::init();
449}
450
451QQuickMaterialStyle *QQuickMaterialStyle::qmlAttachedProperties(QObject *object)
452{
453 return new QQuickMaterialStyle(object);
454}
455
456QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const
457{
458 return m_theme;
459}
460
461void QQuickMaterialStyle::setTheme(Theme theme)
462{
463 if (theme == System)
464 theme = QQuickStylePrivate::isDarkSystemTheme() ? Dark : Light;
465
466 m_explicitTheme = true;
467 if (m_theme == theme)
468 return;
469
470 m_theme = theme;
471 propagateTheme();
472 themeChange();
473 if (!m_customAccent)
474 accentChange();
475 if (!m_hasBackground)
476 backgroundChange();
477 if (!m_hasForeground)
478 foregroundChange();
479}
480
481void QQuickMaterialStyle::inheritTheme(Theme theme)
482{
483 if (m_explicitTheme || m_theme == theme)
484 return;
485
486 m_theme = theme;
487 propagateTheme();
488 themeChange();
489 if (!m_customAccent)
490 accentChange();
491 if (!m_hasBackground)
492 backgroundChange();
493 if (!m_hasForeground)
494 foregroundChange();
495}
496
497void QQuickMaterialStyle::propagateTheme()
498{
499 const auto styles = attachedChildren();
500 for (QQuickAttachedObject *child : styles) {
501 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: child);
502 if (material)
503 material->inheritTheme(theme: m_theme);
504 }
505}
506
507void QQuickMaterialStyle::resetTheme()
508{
509 if (!m_explicitTheme)
510 return;
511
512 m_explicitTheme = false;
513 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: attachedParent());
514 inheritTheme(theme: material ? material->theme() : globalTheme);
515}
516
517void QQuickMaterialStyle::themeChange()
518{
519 emit themeChanged();
520 emit themeOrAccentChanged();
521 emit primaryHighlightedTextColor();
522 emit buttonColorChanged();
523 emit buttonDisabledColorChanged();
524 emit dialogColorChanged();
525 emit tooltipColorChanged();
526 emit toolBarColorChanged();
527 emit toolTextColorChanged();
528}
529
530QVariant QQuickMaterialStyle::primary() const
531{
532 return primaryColor();
533}
534
535void QQuickMaterialStyle::setPrimary(const QVariant &var)
536{
537 QRgb primary = 0;
538 bool custom = false;
539 if (!variantToRgba(var, name: "primary", rgba: &primary, custom: &custom))
540 return;
541
542 m_explicitPrimary = true;
543 if (m_primary == primary)
544 return;
545
546 m_customPrimary = custom;
547 m_primary = primary;
548 propagatePrimary();
549 primaryChange();
550}
551
552void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom)
553{
554 if (m_explicitPrimary || m_primary == primary)
555 return;
556
557 m_customPrimary = custom;
558 m_primary = primary;
559 propagatePrimary();
560 primaryChange();
561}
562
563void QQuickMaterialStyle::propagatePrimary()
564{
565 const auto styles = attachedChildren();
566 for (QQuickAttachedObject *child : styles) {
567 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: child);
568 if (material)
569 material->inheritPrimary(primary: m_primary, custom: m_customPrimary);
570 }
571}
572
573void QQuickMaterialStyle::resetPrimary()
574{
575 if (!m_explicitPrimary)
576 return;
577
578 m_customPrimary = false;
579 m_explicitPrimary = false;
580 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: attachedParent());
581 if (material)
582 inheritPrimary(primary: material->m_primary, custom: material->m_customPrimary);
583 else
584 inheritPrimary(primary: globalPrimary, custom: false);
585}
586
587void QQuickMaterialStyle::primaryChange()
588{
589 emit primaryChanged();
590 emit toolBarColorChanged();
591 emit toolTextColorChanged();
592}
593
594QVariant QQuickMaterialStyle::accent() const
595{
596 return accentColor();
597}
598
599void QQuickMaterialStyle::setAccent(const QVariant &var)
600{
601 QRgb accent = 0;
602 bool custom = false;
603 if (!variantToRgba(var, name: "accent", rgba: &accent, custom: &custom))
604 return;
605
606 m_explicitAccent = true;
607 if (m_accent == accent)
608 return;
609
610 m_customAccent = custom;
611 m_accent = accent;
612 propagateAccent();
613 accentChange();
614}
615
616void QQuickMaterialStyle::inheritAccent(uint accent, bool custom)
617{
618 if (m_explicitAccent || m_accent == accent)
619 return;
620
621 m_customAccent = custom;
622 m_accent = accent;
623 propagateAccent();
624 accentChange();
625}
626
627void QQuickMaterialStyle::propagateAccent()
628{
629 const auto styles = attachedChildren();
630 for (QQuickAttachedObject *child : styles) {
631 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: child);
632 if (material)
633 material->inheritAccent(accent: m_accent, custom: m_customAccent);
634 }
635}
636
637void QQuickMaterialStyle::resetAccent()
638{
639 if (!m_explicitAccent)
640 return;
641
642 m_customAccent = false;
643 m_explicitAccent = false;
644 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: attachedParent());
645 if (material)
646 inheritAccent(accent: material->m_accent, custom: material->m_customAccent);
647 else
648 inheritAccent(accent: globalAccent, custom: false);
649}
650
651void QQuickMaterialStyle::accentChange()
652{
653 emit accentChanged();
654 emit themeOrAccentChanged();
655 emit buttonColorChanged();
656}
657
658QVariant QQuickMaterialStyle::foreground() const
659{
660 if (!m_hasForeground)
661 return QColor::fromRgba(rgba: m_theme == Light ? primaryTextColorLight : primaryTextColorDark);
662 if (m_customForeground)
663 return QColor::fromRgba(rgba: m_foreground);
664 if (m_foreground > BlueGrey)
665 return QColor();
666 return QColor::fromRgba(rgba: colors[m_foreground][Shade500]);
667}
668
669void QQuickMaterialStyle::setForeground(const QVariant &var)
670{
671 QRgb foreground = 0;
672 bool custom = false;
673 if (!variantToRgba(var, name: "foreground", rgba: &foreground, custom: &custom))
674 return;
675
676 m_hasForeground = true;
677 m_explicitForeground = true;
678 if (m_foreground == foreground)
679 return;
680
681 m_customForeground = custom;
682 m_foreground = foreground;
683 propagateForeground();
684 foregroundChange();
685}
686
687void QQuickMaterialStyle::inheritForeground(uint foreground, bool custom, bool has)
688{
689 if (m_explicitForeground || m_foreground == foreground)
690 return;
691
692 m_hasForeground = has;
693 m_customForeground = custom;
694 m_foreground = foreground;
695 propagateForeground();
696 foregroundChange();
697}
698
699void QQuickMaterialStyle::propagateForeground()
700{
701 const auto styles = attachedChildren();
702 for (QQuickAttachedObject *child : styles) {
703 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: child);
704 if (material)
705 material->inheritForeground(foreground: m_foreground, custom: m_customForeground, has: m_hasForeground);
706 }
707}
708
709void QQuickMaterialStyle::resetForeground()
710{
711 if (!m_explicitForeground)
712 return;
713
714 m_hasForeground = false;
715 m_customForeground = false;
716 m_explicitForeground = false;
717 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: attachedParent());
718 inheritForeground(foreground: material ? material->m_foreground : globalForeground, custom: true, has: material ? material->m_hasForeground : false);
719}
720
721void QQuickMaterialStyle::foregroundChange()
722{
723 emit foregroundChanged();
724 emit primaryHighlightedTextColorChanged();
725 // TODO: This causes a binding loop: see QTBUG-85699 and the comments on its fix
726// emit toolTextColorChanged();
727}
728
729QVariant QQuickMaterialStyle::background() const
730{
731 return backgroundColor();
732}
733
734void QQuickMaterialStyle::setBackground(const QVariant &var)
735{
736 QRgb background = 0;
737 bool custom = false;
738 if (!variantToRgba(var, name: "background", rgba: &background, custom: &custom))
739 return;
740
741 m_hasBackground = true;
742 m_explicitBackground = true;
743 if (m_background == background)
744 return;
745
746 m_customBackground = custom;
747 m_background = background;
748 propagateBackground();
749 backgroundChange();
750}
751
752void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool has)
753{
754 if (m_explicitBackground || m_background == background)
755 return;
756
757 m_hasBackground = has;
758 m_customBackground = custom;
759 m_background = background;
760 propagateBackground();
761 backgroundChange();
762}
763
764void QQuickMaterialStyle::propagateBackground()
765{
766 const auto styles = attachedChildren();
767 for (QQuickAttachedObject *child : styles) {
768 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: child);
769 if (material)
770 material->inheritBackground(background: m_background, custom: m_customBackground, has: m_hasBackground);
771 }
772}
773
774void QQuickMaterialStyle::resetBackground()
775{
776 if (!m_explicitBackground)
777 return;
778
779 m_hasBackground = false;
780 m_customBackground = false;
781 m_explicitBackground = false;
782 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: attachedParent());
783 inheritBackground(background: material ? material->m_background : globalBackground, custom: true, has: material ? material->m_hasBackground : false);
784}
785
786void QQuickMaterialStyle::backgroundChange()
787{
788 emit backgroundChanged();
789 emit buttonColorChanged();
790 emit dialogColorChanged();
791 emit tooltipColorChanged();
792 emit toolBarColorChanged();
793}
794
795int QQuickMaterialStyle::elevation() const
796{
797 return m_elevation;
798}
799
800void QQuickMaterialStyle::setElevation(int elevation)
801{
802 if (m_elevation == elevation)
803 return;
804
805 m_elevation = elevation;
806 elevationChange();
807}
808
809void QQuickMaterialStyle::resetElevation()
810{
811 setElevation(0);
812}
813
814void QQuickMaterialStyle::elevationChange()
815{
816 emit elevationChanged();
817 emit buttonDisabledColorChanged();
818}
819
820QColor QQuickMaterialStyle::primaryColor() const
821{
822 if (m_customPrimary)
823 return QColor::fromRgba(rgba: m_primary);
824 if (m_primary > BlueGrey)
825 return QColor();
826 return colors[m_primary][Shade500];
827}
828
829QColor QQuickMaterialStyle::accentColor(Shade shade) const
830{
831 if (m_customAccent)
832 return shade == themeShade() ? QColor::fromRgba(rgba: m_accent)
833 : this->shade(color: QColor::fromRgba(rgba: m_accent), shade);
834 if (m_accent > BlueGrey)
835 return QColor();
836 return colors[m_accent][shade];
837}
838
839QColor QQuickMaterialStyle::accentColor() const
840{
841 return accentColor(shade: themeShade());
842}
843
844QColor QQuickMaterialStyle::backgroundColor(Shade shade) const
845{
846 if (!m_hasBackground)
847 return QColor::fromRgba(rgba: m_theme == Light ? backgroundColorLight : backgroundColorDark);
848 if (m_customBackground)
849 return shade == themeShade() ? QColor::fromRgba(rgba: m_background)
850 : this->shade(color: QColor::fromRgba(rgba: m_background), shade);
851 if (m_background > BlueGrey)
852 return QColor();
853 return colors[m_background][shade];
854}
855
856QColor QQuickMaterialStyle::backgroundColor() const
857{
858 return backgroundColor(shade: themeShade());
859}
860
861QColor QQuickMaterialStyle::primaryTextColor() const
862{
863 return QColor::fromRgba(rgba: m_theme == Light ? primaryTextColorLight : primaryTextColorDark);
864}
865
866QColor QQuickMaterialStyle::primaryHighlightedTextColor() const
867{
868 if (m_explicitForeground)
869 return primaryTextColor();
870 return QColor::fromRgba(rgba: primaryTextColorDark);
871}
872
873QColor QQuickMaterialStyle::secondaryTextColor() const
874{
875 return QColor::fromRgba(rgba: m_theme == Light ? secondaryTextColorLight : secondaryTextColorDark);
876}
877
878QColor QQuickMaterialStyle::hintTextColor() const
879{
880 return QColor::fromRgba(rgba: m_theme == Light ? hintTextColorLight : hintTextColorDark);
881}
882
883QColor QQuickMaterialStyle::textSelectionColor() const
884{
885 QColor color = accentColor();
886 color.setAlphaF(0.4);
887 return color;
888}
889
890QColor QQuickMaterialStyle::dropShadowColor() const
891{
892 return QColor::fromRgba(rgba: 0x40000000);
893}
894
895QColor QQuickMaterialStyle::dividerColor() const
896{
897 return QColor::fromRgba(rgba: m_theme == Light ? dividerColorLight : dividerColorDark);
898}
899
900QColor QQuickMaterialStyle::iconColor() const
901{
902 return QColor::fromRgba(rgba: m_theme == Light ? iconColorLight : iconColorDark);
903}
904
905QColor QQuickMaterialStyle::iconDisabledColor() const
906{
907 return QColor::fromRgba(rgba: m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark);
908}
909
910QColor QQuickMaterialStyle::buttonColor(bool highlighted) const
911{
912 Shade shade = themeShade();
913
914 QColor color = Qt::transparent;
915
916 if (m_explicitBackground) {
917 color = backgroundColor(shade);
918 } else if (highlighted) {
919 color = accentColor(shade);
920 } else if (elevation() > 0) {
921 color = QColor::fromRgba(rgba: m_theme == Light ? raisedButtonColorLight
922 : raisedButtonColorDark);
923 }
924
925 return color;
926}
927
928QColor QQuickMaterialStyle::buttonColor() const
929{
930 return buttonColor(highlighted: false);
931}
932
933QColor QQuickMaterialStyle::buttonDisabledColor() const
934{
935 if (elevation() > 0) {
936 return QColor::fromRgba(rgba: m_theme == Light ? raisedButtonDisabledColorLight
937 : raisedButtonDisabledColorDark);
938 } else {
939 return Qt::transparent;
940 }
941}
942
943QColor QQuickMaterialStyle::highlightedButtonColor() const
944{
945 return buttonColor(highlighted: true);
946}
947
948QColor QQuickMaterialStyle::frameColor() const
949{
950 return QColor::fromRgba(rgba: m_theme == Light ? frameColorLight : frameColorDark);
951}
952
953QColor QQuickMaterialStyle::rippleColor() const
954{
955 return QColor::fromRgba(rgba: m_theme == Light ? rippleColorLight : rippleColorDark);
956}
957
958QColor QQuickMaterialStyle::highlightedRippleColor() const
959{
960 QColor pressColor = accentColor();
961 pressColor.setAlpha(m_theme == Light ? 30 : 50);
962 return pressColor;
963}
964
965QColor QQuickMaterialStyle::switchUncheckedTrackColor() const
966{
967 return QColor::fromRgba(rgba: m_theme == Light ? switchUncheckedTrackColorLight : switchUncheckedTrackColorDark);
968}
969
970QColor QQuickMaterialStyle::switchCheckedTrackColor() const
971{
972 QColor trackColor(accentColor());
973 trackColor.setAlphaF(0.5);
974 return trackColor;
975}
976
977QColor QQuickMaterialStyle::switchUncheckedHandleColor() const
978{
979 return m_theme == Light ? color(color: Grey, shade: Shade50) : color(color: Grey, shade: Shade400);
980}
981
982QColor QQuickMaterialStyle::switchCheckedHandleColor() const
983{
984 return m_theme == Light ? accentColor() : shade(color: accentColor(), shade: Shade200);
985}
986
987QColor QQuickMaterialStyle::switchDisabledTrackColor() const
988{
989 return QColor::fromRgba(rgba: m_theme == Light ? switchDisabledTrackColorLight : switchDisabledTrackColorDark);
990}
991
992QColor QQuickMaterialStyle::switchDisabledHandleColor() const
993{
994 return m_theme == Light ? color(color: Grey, shade: Shade400) : color(color: Grey, shade: Shade800);
995}
996
997QColor QQuickMaterialStyle::scrollBarColor() const
998{
999 return QColor::fromRgba(rgba: m_theme == Light ? 0x40000000 : 0x40FFFFFF);
1000}
1001
1002QColor QQuickMaterialStyle::scrollBarHoveredColor() const
1003{
1004 return QColor::fromRgba(rgba: m_theme == Light ? 0x60000000 : 0x60FFFFFF);
1005}
1006
1007QColor QQuickMaterialStyle::scrollBarPressedColor() const
1008{
1009 return QColor::fromRgba(rgba: m_theme == Light ? 0x80000000 : 0x80FFFFFF);
1010}
1011
1012QColor QQuickMaterialStyle::dialogColor() const
1013{
1014 if (m_hasBackground)
1015 return backgroundColor();
1016 return QColor::fromRgba(rgba: m_theme == Light ? dialogColorLight : dialogColorDark);
1017}
1018
1019QColor QQuickMaterialStyle::backgroundDimColor() const
1020{
1021 return QColor::fromRgba(rgba: m_theme == Light ? 0x99303030 : 0x99fafafa);
1022}
1023
1024QColor QQuickMaterialStyle::listHighlightColor() const
1025{
1026 return QColor::fromRgba(rgba: m_theme == Light ? 0x1e000000 : 0x1effffff);
1027}
1028
1029QColor QQuickMaterialStyle::tooltipColor() const
1030{
1031 if (m_explicitBackground)
1032 return backgroundColor();
1033 return color(color: Grey, shade: Shade700);
1034}
1035
1036QColor QQuickMaterialStyle::toolBarColor() const
1037{
1038 if (m_explicitBackground)
1039 return backgroundColor();
1040 return primaryColor();
1041}
1042
1043QColor QQuickMaterialStyle::toolTextColor() const
1044{
1045 if (m_hasForeground || m_customPrimary)
1046 return primaryTextColor();
1047
1048 switch (m_primary) {
1049 case Red:
1050 case Pink:
1051 case Purple:
1052 case DeepPurple:
1053 case Indigo:
1054 case Blue:
1055 case Teal:
1056 case DeepOrange:
1057 case Brown:
1058 case BlueGrey:
1059 return QColor::fromRgba(rgba: primaryTextColorDark);
1060
1061 case LightBlue:
1062 case Cyan:
1063 case Green:
1064 case LightGreen:
1065 case Lime:
1066 case Yellow:
1067 case Amber:
1068 case Orange:
1069 case Grey:
1070 return QColor::fromRgba(rgba: primaryTextColorLight);
1071
1072 default:
1073 break;
1074 }
1075
1076 return primaryTextColor();
1077}
1078
1079QColor QQuickMaterialStyle::spinBoxDisabledIconColor() const
1080{
1081 return QColor::fromRgba(rgba: m_theme == Light ? spinBoxDisabledIconColorLight : spinBoxDisabledIconColorDark);
1082}
1083
1084QColor QQuickMaterialStyle::sliderDisabledColor() const
1085{
1086 return QColor::fromRgba(rgba: m_theme == Light ? sliderDisabledColorLight : sliderDisabledColorDark);
1087}
1088
1089QColor QQuickMaterialStyle::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const
1090{
1091 int count = sizeof(colors) / sizeof(colors[0]);
1092 if (color < 0 || color >= count)
1093 return QColor();
1094
1095 count = sizeof(colors[0]) / sizeof(colors[0][0]);
1096 if (shade < 0 || shade >= count)
1097 return QColor();
1098
1099 return colors[color][shade];
1100}
1101
1102static QColor lighterShade(const QColor &color, qreal amount)
1103{
1104 QColor hsl = color.toHsl();
1105 hsl.setHslF(h: hsl.hueF(), s: hsl.saturationF(), l: qBound<qreal>(min: 0.0, val: hsl.lightnessF() + amount, max: 1.0), a: color.alphaF());
1106 return hsl.convertTo(colorSpec: color.spec());
1107}
1108
1109static QColor darkerShade(const QColor &color, qreal amount)
1110{
1111 QColor hsl = color.toHsl();
1112 hsl.setHslF(h: hsl.hueF(), s: hsl.saturationF(), l: qBound<qreal>(min: 0.0, val: hsl.lightnessF() - amount, max: 1.0), a: color.alphaF());
1113 return hsl.convertTo(colorSpec: color.spec());
1114}
1115
1116QQuickMaterialStyle::Shade QQuickMaterialStyle::themeShade() const
1117{
1118 return m_theme == Light ? Shade500 : Shade200;
1119}
1120
1121/*
1122 * The following lightness values originate from the Material Design Color Generator project.
1123 *
1124 * The MIT License (MIT)
1125 *
1126 * Copyright (c) 2015 mbitson
1127 *
1128 * Permission is hereby granted, free of charge, to any person obtaining a copy
1129 * of this software and associated documentation files (the "Software"), to deal
1130 * in the Software without restriction, including without limitation the rights
1131 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1132 * copies of the Software, and to permit persons to whom the Software is
1133 * furnished to do so, subject to the following conditions:
1134 *
1135 * The above copyright notice and this permission notice shall be included in all
1136 * copies or substantial portions of the Software.
1137 *
1138 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1139 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1140 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1141 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1142 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1143 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1144 * SOFTWARE.
1145 */
1146
1147// Returns the same color, if shade == themeShade()
1148QColor QQuickMaterialStyle::shade(const QColor &color, Shade shade) const
1149{
1150 switch (shade) {
1151 case Shade50:
1152 return lighterShade(color, amount: m_theme == Light ? 0.52 : 0.26);
1153 case Shade100:
1154 return lighterShade(color, amount: m_theme == Light ? 0.37 : 0.11);
1155 case Shade200:
1156 return m_theme == Light ? lighterShade(color, amount: 0.26) : color;
1157 case Shade300:
1158 return m_theme == Light ? lighterShade(color, amount: 0.12) : darkerShade(color, amount: 0.14);
1159 case Shade400:
1160 return m_theme == Light ? lighterShade(color, amount: 0.06) : darkerShade(color, amount: 0.20);
1161 case Shade500:
1162 return m_theme == Light ? color : darkerShade(color, amount: 0.26);
1163 case Shade600:
1164 return darkerShade(color, amount: m_theme == Light ? 0.06 : 0.32);
1165 case Shade700:
1166 return darkerShade(color, amount: m_theme == Light ? 0.12 : 0.38);
1167 case Shade800:
1168 return darkerShade(color, amount: m_theme == Light ? 0.18 : 0.44);
1169 case Shade900:
1170 return darkerShade(color, amount: m_theme == Light ? 0.24 : 0.50);
1171 case ShadeA100:
1172 return lighterShade(color, amount: m_theme == Light ? 0.54 : 0.28);
1173 case ShadeA200:
1174 return lighterShade(color, amount: m_theme == Light ? 0.37 : 0.11);
1175 case ShadeA400:
1176 return m_theme == Light ? lighterShade(color, amount: 0.06) : darkerShade(color, amount: 0.20);
1177 case ShadeA700:
1178 return darkerShade(color, amount: m_theme == Light ? 0.12 : 0.38);
1179 default:
1180 Q_UNREACHABLE();
1181 return QColor();
1182 }
1183}
1184
1185int QQuickMaterialStyle::touchTarget() const
1186{
1187 // https://material.io/guidelines/components/buttons.html#buttons-style
1188 return globalVariant == Dense ? 44 : 48;
1189}
1190
1191int QQuickMaterialStyle::buttonHeight() const
1192{
1193 // https://material.io/guidelines/components/buttons.html#buttons-style
1194 return globalVariant == Dense ? 32 : 36;
1195}
1196
1197int QQuickMaterialStyle::delegateHeight() const
1198{
1199 // https://material.io/guidelines/components/lists.html#lists-specs
1200 return globalVariant == Dense ? 40 : 48;
1201}
1202
1203int QQuickMaterialStyle::dialogButtonBoxHeight() const
1204{
1205 return globalVariant == Dense ? 48 : 52;
1206}
1207
1208int QQuickMaterialStyle::frameVerticalPadding() const
1209{
1210 return globalVariant == Dense ? 8 : 12;
1211}
1212
1213int QQuickMaterialStyle::menuItemHeight() const
1214{
1215 // https://material.io/guidelines/components/menus.html#menus-simple-menus
1216 return globalVariant == Dense ? 32 : 48;
1217}
1218
1219int QQuickMaterialStyle::menuItemVerticalPadding() const
1220{
1221 return globalVariant == Dense ? 8 : 12;
1222}
1223
1224int QQuickMaterialStyle::switchDelegateVerticalPadding() const
1225{
1226 // SwitchDelegate's indicator is much larger than the others due to the shadow,
1227 // so we must reduce its padding to ensure its implicitHeight is 40 when dense.
1228 return globalVariant == Dense ? 4 : 8;
1229}
1230
1231int QQuickMaterialStyle::tooltipHeight() const
1232{
1233 // https://material.io/guidelines/components/tooltips.html
1234 return globalVariant == Dense ? 22 : 32;
1235}
1236
1237QQuickMaterialStyle::Variant QQuickMaterialStyle::variant()
1238{
1239 return globalVariant;
1240}
1241
1242template <typename Enum>
1243static Enum toEnumValue(const QByteArray &value, bool *ok)
1244{
1245 QMetaEnum enumeration = QMetaEnum::fromType<Enum>();
1246 return static_cast<Enum>(enumeration.keyToValue(key: value, ok));
1247}
1248
1249static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name)
1250{
1251 QByteArray value = qgetenv(varName: env);
1252#if QT_CONFIG(settings)
1253 if (value.isNull() && !settings.isNull())
1254 value = settings->value(key: name).toByteArray();
1255#endif
1256 return value;
1257}
1258
1259void QQuickMaterialStyle::initGlobals()
1260{
1261 QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Material"));
1262
1263 bool ok = false;
1264 QByteArray themeValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_THEME", settings, QStringLiteral("Theme"));
1265 Theme themeEnum = toEnumValue<Theme>(value: themeValue, ok: &ok);
1266 if (ok)
1267 globalTheme = effectiveTheme(theme: themeEnum);
1268 else if (!themeValue.isEmpty())
1269 qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue;
1270
1271 QByteArray variantValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_VARIANT", settings, QStringLiteral("Variant"));
1272 Variant variantEnum = toEnumValue<Variant>(value: variantValue, ok: &ok);
1273 if (ok)
1274 globalVariant = variantEnum;
1275 else if (!variantValue.isEmpty())
1276 qWarning().nospace().noquote() << "Material: unknown variant value: " << variantValue;
1277
1278 QByteArray primaryValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_PRIMARY", settings, QStringLiteral("Primary"));
1279 Color primaryEnum = toEnumValue<Color>(value: primaryValue, ok: &ok);
1280 if (ok) {
1281 globalPrimaryCustom = false;
1282 globalPrimary = primaryEnum;
1283 } else {
1284 QColor color(primaryValue.constData());
1285 if (color.isValid()) {
1286 globalPrimaryCustom = true;
1287 globalPrimary = color.rgba();
1288 } else if (!primaryValue.isEmpty()) {
1289 qWarning().nospace().noquote() << "Material: unknown primary value: " << primaryValue;
1290 }
1291 }
1292
1293 QByteArray accentValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_ACCENT", settings, QStringLiteral("Accent"));
1294 Color accentEnum = toEnumValue<Color>(value: accentValue, ok: &ok);
1295 if (ok) {
1296 globalAccentCustom = false;
1297 globalAccent = accentEnum;
1298 } else if (!accentValue.isEmpty()) {
1299 QColor color(accentValue.constData());
1300 if (color.isValid()) {
1301 globalAccentCustom = true;
1302 globalAccent = color.rgba();
1303 } else {
1304 qWarning().nospace().noquote() << "Material: unknown accent value: " << accentValue;
1305 }
1306 }
1307
1308 QByteArray foregroundValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_FOREGROUND", settings, QStringLiteral("Foreground"));
1309 Color foregroundEnum = toEnumValue<Color>(value: foregroundValue, ok: &ok);
1310 if (ok) {
1311 globalForegroundCustom = false;
1312 globalForeground = foregroundEnum;
1313 hasGlobalForeground = true;
1314 } else if (!foregroundValue.isEmpty()) {
1315 QColor color(foregroundValue.constData());
1316 if (color.isValid()) {
1317 globalForegroundCustom = true;
1318 globalForeground = color.rgba();
1319 hasGlobalForeground = true;
1320 } else {
1321 qWarning().nospace().noquote() << "Material: unknown foreground value: " << foregroundValue;
1322 }
1323 }
1324
1325 QByteArray backgroundValue = resolveSetting(env: "QT_QUICK_CONTROLS_MATERIAL_BACKGROUND", settings, QStringLiteral("Background"));
1326 Color backgroundEnum = toEnumValue<Color>(value: backgroundValue, ok: &ok);
1327 if (ok) {
1328 globalBackgroundCustom = false;
1329 globalBackground = backgroundEnum;
1330 hasGlobalBackground = true;
1331 } else if (!backgroundValue.isEmpty()) {
1332 QColor color(backgroundValue.constData());
1333 if (color.isValid()) {
1334 globalBackgroundCustom = true;
1335 globalBackground = color.rgba();
1336 hasGlobalBackground = true;
1337 } else {
1338 qWarning().nospace().noquote() << "Material: unknown background value: " << backgroundValue;
1339 }
1340 }
1341}
1342
1343void QQuickMaterialStyle::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent)
1344{
1345 Q_UNUSED(oldParent);
1346 QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(object: newParent);
1347 if (material) {
1348 inheritPrimary(primary: material->m_primary, custom: material->m_customPrimary);
1349 inheritAccent(accent: material->m_accent, custom: material->m_customAccent);
1350 inheritForeground(foreground: material->m_foreground, custom: material->m_customForeground, has: material->m_hasForeground);
1351 inheritBackground(background: material->m_background, custom: material->m_customBackground, has: material->m_hasBackground);
1352 inheritTheme(theme: material->theme());
1353 }
1354}
1355
1356bool QQuickMaterialStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const
1357{
1358 *custom = false;
1359 if (var.type() == QVariant::Int) {
1360 int val = var.toInt();
1361 if (val > BlueGrey) {
1362 qmlWarning(me: parent()) << "unknown Material." << name << " value: " << val;
1363 return false;
1364 }
1365 *rgba = val;
1366 } else {
1367 int val = QMetaEnum::fromType<Color>().keyToValue(key: var.toByteArray());
1368 if (val != -1) {
1369 *rgba = val;
1370 } else {
1371 QColor color(var.toString());
1372 if (!color.isValid()) {
1373 qmlWarning(me: parent()) << "unknown Material." << name << " value: " << var.toString();
1374 return false;
1375 }
1376 *custom = true;
1377 *rgba = color.rgba();
1378 }
1379 }
1380 return true;
1381}
1382
1383QT_END_NAMESPACE
1384

source code of qtquickcontrols2/src/imports/controls/material/qquickmaterialstyle.cpp