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 QtGui 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 "qpalette.h"
41#include "qguiapplication.h"
42#include "qguiapplication_p.h"
43#include "qdatastream.h"
44#include "qvariant.h"
45#include "qdebug.h"
46
47QT_BEGIN_NAMESPACE
48
49static int qt_palette_count = 1;
50
51class QPalettePrivate {
52public:
53 QPalettePrivate() : ref(1), ser_no(qt_palette_count++), detach_no(0) { }
54 QAtomicInt ref;
55 QBrush br[QPalette::NColorGroups][QPalette::NColorRoles];
56 int ser_no;
57 int detach_no;
58};
59
60static QColor qt_mix_colors(QColor a, QColor b)
61{
62 return QColor((a.red() + b.red()) / 2, (a.green() + b.green()) / 2,
63 (a.blue() + b.blue()) / 2, (a.alpha() + b.alpha()) / 2);
64}
65
66static void qt_palette_from_color(QPalette &pal, const QColor &button)
67{
68 int h, s, v;
69 button.getHsv(h: &h, s: &s, v: &v);
70 // inactive and active are the same..
71 const QBrush whiteBrush = QBrush(Qt::white);
72 const QBrush blackBrush = QBrush(Qt::black);
73 const QBrush baseBrush = v > 128 ? whiteBrush : blackBrush;
74 const QBrush foregroundBrush = v > 128 ? blackBrush : whiteBrush;
75 const QBrush buttonBrush = QBrush(button);
76 const QBrush buttonBrushDark = QBrush(button.darker());
77 const QBrush buttonBrushDark150 = QBrush(button.darker(f: 150));
78 const QBrush buttonBrushLight150 = QBrush(button.lighter(f: 150));
79 pal.setColorGroup(cr: QPalette::Active, windowText: foregroundBrush, button: buttonBrush, light: buttonBrushLight150,
80 dark: buttonBrushDark, mid: buttonBrushDark150, text: foregroundBrush, bright_text: whiteBrush,
81 base: baseBrush, window: buttonBrush);
82 pal.setColorGroup(cr: QPalette::Inactive, windowText: foregroundBrush, button: buttonBrush, light: buttonBrushLight150,
83 dark: buttonBrushDark, mid: buttonBrushDark150, text: foregroundBrush, bright_text: whiteBrush,
84 base: baseBrush, window: buttonBrush);
85 pal.setColorGroup(cr: QPalette::Disabled, windowText: buttonBrushDark, button: buttonBrush, light: buttonBrushLight150,
86 dark: buttonBrushDark, mid: buttonBrushDark150, text: buttonBrushDark,
87 bright_text: whiteBrush, base: buttonBrush, window: buttonBrush);
88}
89
90/*!
91 \fn QPalette &QPalette::operator=(QPalette &&other)
92
93 Move-assigns \a other to this QPalette instance.
94
95 \since 5.2
96*/
97
98/*!
99 \fn const QColor &QPalette::color(ColorRole role) const
100
101 \overload
102
103 Returns the color that has been set for the given color \a role in
104 the current ColorGroup.
105
106 \sa brush(), ColorRole
107 */
108
109/*!
110 \fn const QBrush &QPalette::brush(ColorRole role) const
111
112 \overload
113
114 Returns the brush that has been set for the given color \a role in
115 the current ColorGroup.
116
117 \sa color(), setBrush(), ColorRole
118*/
119
120/*!
121 \fn void QPalette::setColor(ColorRole role, const QColor &color)
122
123 \overload
124
125 Sets the color used for the given color \a role, in all color
126 groups, to the specified solid \a color.
127
128 \sa brush(), setColor(), ColorRole
129*/
130
131/*!
132 \fn void QPalette::setBrush(ColorRole role, const QBrush &brush)
133
134 Sets the brush for the given color \a role to the specified \a
135 brush for all groups in the palette.
136
137 \sa brush(), setColor(), ColorRole
138*/
139
140/*!
141 \fn const QBrush & QPalette::foreground() const
142 \obsolete
143
144 Use windowText() instead.
145*/
146
147/*!
148 \fn const QBrush & QPalette::windowText() const
149
150 Returns the window text (general foreground) brush of the
151 current color group.
152
153 \sa ColorRole, brush()
154*/
155
156/*!
157 \fn const QBrush & QPalette::button() const
158
159 Returns the button brush of the current color group.
160
161 \sa ColorRole, brush()
162*/
163
164/*!
165 \fn const QBrush & QPalette::light() const
166
167 Returns the light brush of the current color group.
168
169 \sa ColorRole, brush()
170*/
171
172/*!
173 \fn const QBrush& QPalette::midlight() const
174
175 Returns the midlight brush of the current color group.
176
177 \sa ColorRole, brush()
178*/
179
180/*!
181 \fn const QBrush & QPalette::dark() const
182
183 Returns the dark brush of the current color group.
184
185 \sa ColorRole, brush()
186*/
187
188/*!
189 \fn const QBrush & QPalette::mid() const
190
191 Returns the mid brush of the current color group.
192
193 \sa ColorRole, brush()
194*/
195
196/*!
197 \fn const QBrush & QPalette::text() const
198
199 Returns the text foreground brush of the current color group.
200
201 \sa ColorRole, brush()
202*/
203
204/*!
205 \fn const QBrush & QPalette::brightText() const
206
207 Returns the bright text foreground brush of the current color group.
208
209 \sa ColorRole, brush()
210*/
211
212/*!
213 \fn const QBrush & QPalette::buttonText() const
214
215 Returns the button text foreground brush of the current color group.
216
217 \sa ColorRole, brush()
218*/
219
220/*!
221 \fn const QBrush & QPalette::base() const
222
223 Returns the base brush of the current color group.
224
225 \sa ColorRole, brush()
226*/
227
228/*!
229 \fn const QBrush & QPalette::alternateBase() const
230
231 Returns the alternate base brush of the current color group.
232
233 \sa ColorRole, brush()
234*/
235
236/*!
237 \fn const QBrush & QPalette::toolTipBase() const
238 \since 4.4
239
240 Returns the tool tip base brush of the current color group. This brush is
241 used by QToolTip and QWhatsThis.
242
243 \note Tool tips use the Inactive color group of QPalette, because tool
244 tips are not active windows.
245
246 \sa ColorRole, brush()
247*/
248
249/*!
250 \fn const QBrush & QPalette::toolTipText() const
251 \since 4.4
252
253 Returns the tool tip text brush of the current color group. This brush is
254 used by QToolTip and QWhatsThis.
255
256 \note Tool tips use the Inactive color group of QPalette, because tool
257 tips are not active windows.
258
259 \sa ColorRole, brush()
260*/
261
262/*!
263 \fn const QBrush & QPalette::background() const
264 \obsolete
265
266 Use window() instead.
267*/
268
269/*!
270 \fn const QBrush & QPalette::window() const
271
272 Returns the window (general background) brush of the current
273 color group.
274
275 \sa ColorRole, brush()
276*/
277
278/*!
279 \fn const QBrush & QPalette::shadow() const
280
281 Returns the shadow brush of the current color group.
282
283 \sa ColorRole, brush()
284*/
285
286/*!
287 \fn const QBrush & QPalette::highlight() const
288
289 Returns the highlight brush of the current color group.
290
291 \sa ColorRole, brush()
292*/
293
294/*!
295 \fn const QBrush & QPalette::highlightedText() const
296
297 Returns the highlighted text brush of the current color group.
298
299 \sa ColorRole, brush()
300*/
301
302/*!
303 \fn const QBrush & QPalette::link() const
304
305 Returns the unvisited link text brush of the current color group.
306
307 \sa ColorRole, brush()
308*/
309
310/*!
311 \fn const QBrush & QPalette::linkVisited() const
312
313 Returns the visited link text brush of the current color group.
314
315 \sa ColorRole, brush()
316*/
317
318/*!
319 \fn const QBrush & QPalette::placeholderText() const
320 \since 5.12
321
322 Returns the placeholder text brush of the current color group.
323
324 \note Before Qt 5.12, the placeholder text color was hard-coded in the code as
325 QPalette::text().color() where an alpha of 128 was applied.
326 We continue to support this behavior by default, unless you set your own brush.
327 One can get back the original placeholder color setting the special QBrush default
328 constructor as placeholder brush.
329
330 \sa ColorRole, brush()
331*/
332
333/*!
334 \fn ColorGroup QPalette::currentColorGroup() const
335
336 Returns the palette's current color group.
337*/
338
339/*!
340 \fn void QPalette::setCurrentColorGroup(ColorGroup cg)
341
342 Set the palette's current color group to \a cg.
343*/
344
345/*!
346 \class QPalette
347
348 \brief The QPalette class contains color groups for each widget state.
349
350 \inmodule QtGui
351 \ingroup appearance
352 \ingroup shared
353
354 A palette consists of three color groups: \e Active, \e Disabled,
355 and \e Inactive. All widgets in Qt contain a palette and
356 use their palette to draw themselves. This makes the user
357 interface easily configurable and easier to keep consistent.
358
359
360 If you create a new widget we strongly recommend that you use the
361 colors in the palette rather than hard-coding specific colors.
362
363 The color groups:
364 \list
365 \li The Active group is used for the window that has keyboard focus.
366 \li The Inactive group is used for other windows.
367 \li The Disabled group is used for widgets (not windows) that are
368 disabled for some reason.
369 \endlist
370
371 Both active and inactive windows can contain disabled widgets.
372 (Disabled widgets are often called \e inaccessible or \e{grayed
373 out}.)
374
375 In most styles, Active and Inactive look the same.
376
377 Colors and brushes can be set for particular roles in any of a palette's
378 color groups with setColor() and setBrush(). A color group contains a
379 group of colors used by widgets for drawing themselves. We recommend that
380 widgets use color group roles from the palette such as "foreground" and
381 "base" rather than literal colors like "red" or "turquoise". The color
382 roles are enumerated and defined in the \l ColorRole documentation.
383
384 We strongly recommend that you use the default palette of the
385 current style (returned by QGuiApplication::palette()) and
386 modify that as necessary. This is done by Qt's widgets when they
387 are drawn.
388
389 To modify a color group you call the functions
390 setColor() and setBrush(), depending on whether you want a pure
391 color or a pixmap pattern.
392
393 There are also corresponding color() and brush() getters, and a
394 commonly used convenience function to get the ColorRole for the current ColorGroup:
395 window(), windowText(), base(), etc.
396
397
398 You can copy a palette using the copy constructor and test to see
399 if two palettes are \e identical using isCopyOf().
400
401 QPalette is optimized by the use of \l{implicit sharing},
402 so it is very efficient to pass QPalette objects as arguments.
403
404 \warning Some styles do not use the palette for all drawing, for
405 instance, if they make use of native theme engines. This is the
406 case for both the Windows Vista and the \macos
407 styles.
408
409 \sa QApplication::setPalette(), QWidget::setPalette(), QColor
410*/
411
412/*!
413 \enum QPalette::ColorGroup
414
415 \value Disabled
416 \value Active
417 \value Inactive
418 \value Normal synonym for Active
419
420 \omitvalue All
421 \omitvalue NColorGroups
422 \omitvalue Current
423*/
424
425/*!
426 \enum QPalette::ColorRole
427
428 \image palette.png Color Roles
429
430 The ColorRole enum defines the different symbolic color roles used
431 in current GUIs.
432
433 The central roles are:
434
435 \value Window A general background color.
436
437 \value Background This value is obsolete. Use Window instead.
438
439 \value WindowText A general foreground color.
440
441 \value Foreground This value is obsolete. Use WindowText instead.
442
443 \value Base Used mostly as the background color for text entry widgets,
444 but can also be used for other painting - such as the
445 background of combobox drop down lists and toolbar handles.
446 It is usually white or another light color.
447
448 \value AlternateBase Used as the alternate background color in views with
449 alternating row colors (see
450 QAbstractItemView::setAlternatingRowColors()).
451
452 \value ToolTipBase Used as the background color for QToolTip and
453 QWhatsThis. Tool tips use the Inactive color group
454 of QPalette, because tool tips are not active
455 windows.
456
457 \value ToolTipText Used as the foreground color for QToolTip and
458 QWhatsThis. Tool tips use the Inactive color group
459 of QPalette, because tool tips are not active
460 windows.
461
462 \value PlaceholderText Used as the placeholder color for various text input widgets.
463 This enum value has been introduced in Qt 5.12
464
465 \value Text The foreground color used with \c Base. This is usually
466 the same as the \c WindowText, in which case it must provide
467 good contrast with \c Window and \c Base.
468
469 \value Button The general button background color. This background can be different from
470 \c Window as some styles require a different background color for buttons.
471
472 \value ButtonText A foreground color used with the \c Button color.
473
474 \value BrightText A text color that is very different from
475 \c WindowText, and contrasts well with e.g. \c
476 Dark. Typically used for text that needs to be
477 drawn where \c Text or \c WindowText would give
478 poor contrast, such as on pressed push buttons.
479 Note that text colors can be used for things
480 other than just words; text colors are \e
481 usually used for text, but it's quite common to
482 use the text color roles for lines, icons, etc.
483
484
485 There are some color roles used mostly for 3D bevel and shadow effects.
486 All of these are normally derived from \c Window, and used in ways that
487 depend on that relationship. For example, buttons depend on it to make the
488 bevels look attractive, and Motif scroll bars depend on \c Mid to be
489 slightly different from \c Window.
490
491 \value Light Lighter than \c Button color.
492
493 \value Midlight Between \c Button and \c Light.
494
495 \value Dark Darker than \c Button.
496
497 \value Mid Between \c Button and \c Dark.
498
499 \value Shadow A very dark color. By default, the shadow color is
500 Qt::black.
501
502
503 Selected (marked) items have two roles:
504
505 \value Highlight A color to indicate a selected item or the current
506 item. By default, the highlight color is
507 Qt::darkBlue.
508
509 \value HighlightedText A text color that contrasts with \c Highlight.
510 By default, the highlighted text color is Qt::white.
511
512 There are two color roles related to hyperlinks:
513
514 \value Link A text color used for unvisited hyperlinks.
515 By default, the link color is Qt::blue.
516
517 \value LinkVisited A text color used for already visited hyperlinks.
518 By default, the linkvisited color is Qt::magenta.
519
520 Note that we do not use the \c Link and \c LinkVisited roles when
521 rendering rich text in Qt, and that we recommend that you use CSS
522 and the QTextDocument::setDefaultStyleSheet() function to alter
523 the appearance of links. For example:
524
525 \snippet textdocument-css/main.cpp 0
526
527 \value NoRole No role; this special role is often used to indicate that a
528 role has not been assigned.
529
530 \omitvalue NColorRoles
531*/
532
533/*!
534 Constructs an empty palette object with no color roles set.
535
536 When used as the palette of a QWidget the colors are resolved
537 as described by QWidget::setPalette().
538
539 \sa QApplication::setPalette(), QApplication::palette()
540*/
541QPalette::QPalette()
542 : d(nullptr)
543{
544 data.current_group = Active;
545 data.resolve_mask = 0;
546 // Initialize to application palette if present, else default to black.
547 // This makes it possible to instantiate QPalette outside QGuiApplication,
548 // for example in the platform plugins.
549 if (QGuiApplicationPrivate::app_pal) {
550 d = QGuiApplicationPrivate::app_pal->d;
551 d->ref.ref();
552 } else {
553 init();
554 qt_palette_from_color(pal&: *this, button: Qt::black);
555 data.resolve_mask = 0;
556 }
557}
558
559/*!
560 Constructs a palette from the \a button color. The other colors are
561 automatically calculated, based on this color. \c Window will be
562 the button color as well.
563*/
564QPalette::QPalette(const QColor &button)
565{
566 init();
567 qt_palette_from_color(pal&: *this, button);
568}
569
570/*!
571 Constructs a palette from the \a button color. The other colors are
572 automatically calculated, based on this color. \c Window will be
573 the button color as well.
574*/
575QPalette::QPalette(Qt::GlobalColor button)
576{
577 init();
578 qt_palette_from_color(pal&: *this, button);
579}
580
581/*!
582 Constructs a palette. You can pass either brushes, pixmaps or
583 plain colors for \a windowText, \a button, \a light, \a dark, \a
584 mid, \a text, \a bright_text, \a base and \a window.
585
586 \sa QBrush
587*/
588QPalette::QPalette(const QBrush &windowText, const QBrush &button,
589 const QBrush &light, const QBrush &dark,
590 const QBrush &mid, const QBrush &text,
591 const QBrush &bright_text, const QBrush &base,
592 const QBrush &window)
593{
594 init();
595 setColorGroup(cr: All, windowText, button, light, dark, mid, text, bright_text,
596 base, window);
597}
598
599
600/*!\obsolete
601
602 Constructs a palette with the specified \a windowText, \a
603 window, \a light, \a dark, \a mid, \a text, and \a base colors.
604 The button color will be set to the window color.
605*/
606QPalette::QPalette(const QColor &windowText, const QColor &window,
607 const QColor &light, const QColor &dark, const QColor &mid,
608 const QColor &text, const QColor &base)
609{
610 init();
611 const QBrush windowBrush(window);
612 const QBrush lightBrush(light);
613 setColorGroup(cr: All, windowText: QBrush(windowText), button: windowBrush, light: lightBrush,
614 dark: QBrush(dark), mid: QBrush(mid), text: QBrush(text), bright_text: lightBrush,
615 base: QBrush(base), window: windowBrush);
616}
617
618/*!
619 Constructs a palette from a \a button color and a \a window.
620 The other colors are automatically calculated, based on these
621 colors.
622*/
623QPalette::QPalette(const QColor &button, const QColor &window)
624{
625 init();
626 int h, s, v;
627 window.getHsv(h: &h, s: &s, v: &v);
628
629 const QBrush windowBrush = QBrush(window);
630 const QBrush whiteBrush = QBrush(Qt::white);
631 const QBrush blackBrush = QBrush(Qt::black);
632 const QBrush baseBrush = v > 128 ? whiteBrush : blackBrush;
633 const QBrush foregroundBrush = v > 128 ? blackBrush : whiteBrush;
634 const QBrush disabledForeground = QBrush(Qt::darkGray);
635
636 const QBrush buttonBrush = QBrush(button);
637 const QBrush buttonBrushDark = QBrush(button.darker());
638 const QBrush buttonBrushDark150 = QBrush(button.darker(f: 150));
639 const QBrush buttonBrushLight150 = QBrush(button.lighter(f: 150));
640
641 //inactive and active are identical
642 setColorGroup(cr: Inactive, windowText: foregroundBrush, button: buttonBrush, light: buttonBrushLight150, dark: buttonBrushDark,
643 mid: buttonBrushDark150, text: foregroundBrush, bright_text: whiteBrush, base: baseBrush,
644 window: windowBrush);
645 setColorGroup(cr: Active, windowText: foregroundBrush, button: buttonBrush, light: buttonBrushLight150, dark: buttonBrushDark,
646 mid: buttonBrushDark150, text: foregroundBrush, bright_text: whiteBrush, base: baseBrush,
647 window: windowBrush);
648 setColorGroup(cr: Disabled, windowText: disabledForeground, button: buttonBrush, light: buttonBrushLight150,
649 dark: buttonBrushDark, mid: buttonBrushDark150, text: disabledForeground,
650 bright_text: whiteBrush, base: baseBrush, window: windowBrush);
651}
652
653/*!
654 Constructs a copy of \a p.
655
656 This constructor is fast thanks to \l{implicit sharing}.
657*/
658QPalette::QPalette(const QPalette &p)
659 : d(p.d), data(p.data)
660{
661 d->ref.ref();
662}
663
664/*!
665 \fn QPalette::QPalette(QPalette &&other)
666 \since 5.4
667
668 Move-constructs a QPalette instance, making it point at the same
669 object that \a other was pointing to.
670
671 After being moved from, you can only assign to or destroy \a other.
672 Any other operation will result in undefined behavior.
673*/
674
675/*!
676 Destroys the palette.
677*/
678QPalette::~QPalette()
679{
680 if (d && !d->ref.deref())
681 delete d;
682}
683
684/*!\internal*/
685void QPalette::init() {
686 d = new QPalettePrivate;
687 data.resolve_mask = 0;
688 data.current_group = Active; //as a default..
689}
690
691/*!
692 Assigns \a p to this palette and returns a reference to this
693 palette.
694
695 This operation is fast thanks to \l{implicit sharing}.
696*/
697QPalette &QPalette::operator=(const QPalette &p)
698{
699 p.d->ref.ref();
700 data = p.data;
701 if (d && !d->ref.deref())
702 delete d;
703 d = p.d;
704 return *this;
705}
706
707/*!
708 \fn void QPalette::swap(QPalette &other)
709 \since 5.0
710
711 Swaps this palette instance with \a other. This function is very
712 fast and never fails.
713*/
714
715/*!
716 Returns the palette as a QVariant
717*/
718QPalette::operator QVariant() const
719{
720 return QVariant(QMetaType::QPalette, this);
721}
722
723/*!
724 \fn const QColor &QPalette::color(ColorGroup group, ColorRole role) const
725
726 Returns the color in the specified color \a group, used for the
727 given color \a role.
728
729 \sa brush(), setColor(), ColorRole
730*/
731
732/*!
733 \fn const QBrush &QPalette::brush(ColorGroup group, ColorRole role) const
734
735 Returns the brush in the specified color \a group, used for the
736 given color \a role.
737
738 \sa color(), setBrush(), ColorRole
739*/
740const QBrush &QPalette::brush(ColorGroup gr, ColorRole cr) const
741{
742 Q_ASSERT(cr < NColorRoles);
743 if(gr >= (int)NColorGroups) {
744 if(gr == Current) {
745 gr = (ColorGroup)data.current_group;
746 } else {
747 qWarning(msg: "QPalette::brush: Unknown ColorGroup: %d", (int)gr);
748 gr = Active;
749 }
750 }
751 return d->br[gr][cr];
752}
753
754/*!
755 \fn void QPalette::setColor(ColorGroup group, ColorRole role, const QColor &color)
756
757 Sets the color in the specified color \a group, used for the given
758 color \a role, to the specified solid \a color.
759
760 \sa setBrush(), color(), ColorRole
761*/
762
763/*!
764 \fn void QPalette::setBrush(ColorGroup group, ColorRole role, const QBrush &brush)
765 \overload
766
767 Sets the brush in the specified color \a group, used for the given
768 color \a role, to \a brush.
769
770 \sa brush(), setColor(), ColorRole
771*/
772void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b)
773{
774 Q_ASSERT(cr < NColorRoles);
775
776 if (cg == All) {
777 for (uint i = 0; i < NColorGroups; i++)
778 setBrush(cg: ColorGroup(i), cr, b);
779 return;
780 }
781
782 if (cg == Current) {
783 cg = ColorGroup(data.current_group);
784 } else if (cg >= NColorGroups) {
785 qWarning(msg: "QPalette::setBrush: Unknown ColorGroup: %d", cg);
786 cg = Active;
787 }
788
789 // For placeholder we want to continue to respect the original behavior, which is
790 // derivating the text color, but only if user has not yet set his own brush.
791 // We then use Qt::NoBrush as an inernal way to know if the brush is customized or not.
792
793 // ### Qt 6 - remove this special case
794 // Part 1 - Restore initial color to the given color group
795 if (cr == PlaceholderText && b == QBrush()) {
796 QColor col = brush(cr: Text).color();
797 col.setAlpha(128);
798 setBrush(cg, cr: PlaceholderText, b: QBrush(col, Qt::NoBrush));
799 return;
800 }
801
802 if (d->br[cg][cr] != b) {
803 detach();
804 d->br[cg][cr] = b;
805 }
806 data.resolve_mask |= (1<<cr);
807
808 // ### Qt 6 - remove this special case
809 // Part 2 - Update initial color to the given color group
810 if (cr == Text && d->br[cg][PlaceholderText].style() == Qt::NoBrush) {
811 QColor col = brush(cr: Text).color();
812 col.setAlpha(128);
813 setBrush(cg, cr: PlaceholderText, b: QBrush(col, Qt::NoBrush));
814 }
815}
816
817/*!
818 \since 4.2
819
820 Returns \c true if the ColorGroup \a cg and ColorRole \a cr has been
821 set previously on this palette; otherwise returns \c false.
822
823 \sa setBrush()
824*/
825bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const
826{
827 Q_UNUSED(cg);
828 return (data.resolve_mask & (1<<cr));
829}
830
831/*!
832 \internal
833*/
834void QPalette::detach()
835{
836 if (d->ref.loadRelaxed() != 1) {
837 QPalettePrivate *x = new QPalettePrivate;
838 for(int grp = 0; grp < (int)NColorGroups; grp++) {
839 for(int role = 0; role < (int)NColorRoles; role++)
840 x->br[grp][role] = d->br[grp][role];
841 }
842 if(!d->ref.deref())
843 delete d;
844 d = x;
845 }
846 ++d->detach_no;
847}
848
849/*!
850 \fn bool QPalette::operator!=(const QPalette &p) const
851
852 Returns \c true (slowly) if this palette is different from \a p;
853 otherwise returns \c false (usually quickly).
854
855 \note The current ColorGroup is not taken into account when
856 comparing palettes
857
858 \sa operator==()
859*/
860
861/*!
862 Returns \c true (usually quickly) if this palette is equal to \a p;
863 otherwise returns \c false (slowly).
864
865 \note The current ColorGroup is not taken into account when
866 comparing palettes
867
868 \sa operator!=()
869*/
870bool QPalette::operator==(const QPalette &p) const
871{
872 if (isCopyOf(p))
873 return true;
874 for(int grp = 0; grp < (int)NColorGroups; grp++) {
875 for(int role = 0; role < (int)NColorRoles; role++) {
876 if(d->br[grp][role] != p.d->br[grp][role])
877 return false;
878 }
879 }
880 return true;
881}
882
883/*!
884 \fn bool QPalette::isEqual(ColorGroup cg1, ColorGroup cg2) const
885
886 Returns \c true (usually quickly) if color group \a cg1 is equal to
887 \a cg2; otherwise returns \c false.
888*/
889bool QPalette::isEqual(QPalette::ColorGroup group1, QPalette::ColorGroup group2) const
890{
891 if(group1 >= (int)NColorGroups) {
892 if(group1 == Current) {
893 group1 = (ColorGroup)data.current_group;
894 } else {
895 qWarning(msg: "QPalette::brush: Unknown ColorGroup(1): %d", (int)group1);
896 group1 = Active;
897 }
898 }
899 if(group2 >= (int)NColorGroups) {
900 if(group2 == Current) {
901 group2 = (ColorGroup)data.current_group;
902 } else {
903 qWarning(msg: "QPalette::brush: Unknown ColorGroup(2): %d", (int)group2);
904 group2 = Active;
905 }
906 }
907 if(group1 == group2)
908 return true;
909 for(int role = 0; role < (int)NColorRoles; role++) {
910 if(d->br[group1][role] != d->br[group2][role])
911 return false;
912 }
913 return true;
914}
915
916/*! \fn int QPalette::serialNumber() const
917 \obsolete
918
919 Returns a number that identifies the contents of this QPalette
920 object. Distinct QPalette objects can only have the same serial
921 number if they refer to the same contents (but they don't have
922 to). Also, the serial number of a QPalette may change during the
923 lifetime of the object.
924
925 Use cacheKey() instead.
926
927 \warning The serial number doesn't necessarily change when the
928 palette is altered. This means that it may be dangerous to use it
929 as a cache key.
930
931 \sa operator==()
932*/
933
934/*!
935 Returns a number that identifies the contents of this QPalette
936 object. Distinct QPalette objects can have the same key if
937 they refer to the same contents.
938
939 The cacheKey() will change when the palette is altered.
940*/
941qint64 QPalette::cacheKey() const
942{
943 return (((qint64) d->ser_no) << 32) | ((qint64) (d->detach_no));
944}
945
946/*!
947 Returns a new QPalette that is a union of this instance and \a other.
948 Color roles set in this instance take precedence.
949*/
950QPalette QPalette::resolve(const QPalette &other) const
951{
952 if ((*this == other && data.resolve_mask == other.data.resolve_mask)
953 || data.resolve_mask == 0) {
954 QPalette o = other;
955 o.data.resolve_mask = data.resolve_mask;
956 return o;
957 }
958
959 QPalette palette(*this);
960 palette.detach();
961
962 for(int role = 0; role < (int)NColorRoles; role++)
963 if (!(data.resolve_mask & (1<<role)))
964 for(int grp = 0; grp < (int)NColorGroups; grp++)
965 palette.d->br[grp][role] = other.d->br[grp][role];
966 palette.data.resolve_mask |= other.data.resolve_mask;
967
968 return palette;
969}
970
971/*!
972 \fn uint QPalette::resolve() const
973 \internal
974*/
975
976/*!
977 \fn void QPalette::resolve(uint mask)
978 \internal
979*/
980
981
982/*****************************************************************************
983 QPalette stream functions
984 *****************************************************************************/
985
986#ifndef QT_NO_DATASTREAM
987
988static const int NumOldRoles = 7;
989static const int oldRoles[7] = { QPalette::WindowText, QPalette::Window, QPalette::Light,
990 QPalette::Dark, QPalette::Mid, QPalette::Text, QPalette::Base };
991
992/*!
993 \relates QPalette
994
995 Writes the palette, \a p to the stream \a s and returns a
996 reference to the stream.
997
998 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
999*/
1000
1001QDataStream &operator<<(QDataStream &s, const QPalette &p)
1002{
1003 for (int grp = 0; grp < (int)QPalette::NColorGroups; grp++) {
1004 if (s.version() == 1) {
1005 // Qt 1.x
1006 for (int i = 0; i < NumOldRoles; ++i)
1007 s << p.d->br[grp][oldRoles[i]].color();
1008 } else {
1009 int max = (int)QPalette::NColorRoles;
1010 if (s.version() <= QDataStream::Qt_2_1)
1011 max = QPalette::HighlightedText + 1;
1012 else if (s.version() <= QDataStream::Qt_4_3)
1013 max = QPalette::AlternateBase + 1;
1014 else if (s.version() <= QDataStream::Qt_5_11)
1015 max = QPalette::ToolTipText + 1;
1016 for (int r = 0; r < max; r++)
1017 s << p.d->br[grp][r];
1018 }
1019 }
1020 return s;
1021}
1022
1023static void readV1ColorGroup(QDataStream &s, QPalette &pal, QPalette::ColorGroup grp)
1024{
1025 for (int i = 0; i < NumOldRoles; ++i) {
1026 QColor col;
1027 s >> col;
1028 pal.setColor(acg: grp, acr: (QPalette::ColorRole)oldRoles[i], acolor: col);
1029 }
1030}
1031
1032/*!
1033 \relates QPalette
1034
1035 Reads a palette from the stream, \a s into the palette \a p, and
1036 returns a reference to the stream.
1037
1038 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
1039*/
1040
1041QDataStream &operator>>(QDataStream &s, QPalette &p)
1042{
1043 if(s.version() == 1) {
1044 p = QPalette();
1045 readV1ColorGroup(s, pal&: p, grp: QPalette::Active);
1046 readV1ColorGroup(s, pal&: p, grp: QPalette::Disabled);
1047 readV1ColorGroup(s, pal&: p, grp: QPalette::Inactive);
1048 } else {
1049 int max = QPalette::NColorRoles;
1050 if (s.version() <= QDataStream::Qt_2_1) {
1051 p = QPalette();
1052 max = QPalette::HighlightedText + 1;
1053 } else if (s.version() <= QDataStream::Qt_4_3) {
1054 p = QPalette();
1055 max = QPalette::AlternateBase + 1;
1056 } else if (s.version() <= QDataStream::Qt_5_11) {
1057 p = QPalette();
1058 max = QPalette::ToolTipText + 1;
1059 }
1060
1061 QBrush tmp;
1062 for(int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
1063 for(int role = 0; role < max; ++role) {
1064 s >> tmp;
1065 p.setBrush(cg: (QPalette::ColorGroup)grp, cr: (QPalette::ColorRole)role, b: tmp);
1066 }
1067 }
1068 }
1069 return s;
1070}
1071#endif //QT_NO_DATASTREAM
1072
1073/*!
1074 Returns \c true if this palette and \a p are copies of each other,
1075 i.e. one of them was created as a copy of the other and neither
1076 was subsequently modified; otherwise returns \c false. This is much
1077 stricter than equality.
1078
1079 \sa operator=(), operator==()
1080*/
1081
1082bool QPalette::isCopyOf(const QPalette &p) const
1083{
1084 return d == p.d;
1085}
1086
1087/*!
1088
1089 Sets a the group at \a cg. You can pass either brushes, pixmaps or
1090 plain colors for \a windowText, \a button, \a light, \a dark, \a
1091 mid, \a text, \a bright_text, \a base and \a window.
1092
1093 \sa QBrush
1094*/
1095void QPalette::setColorGroup(ColorGroup cg, const QBrush &windowText, const QBrush &button,
1096 const QBrush &light, const QBrush &dark, const QBrush &mid,
1097 const QBrush &text, const QBrush &bright_text, const QBrush &base,
1098 const QBrush &window)
1099{
1100 QBrush alt_base = QBrush(qt_mix_colors(a: base.color(), b: button.color()));
1101 QBrush mid_light = QBrush(qt_mix_colors(a: button.color(), b: light.color()));
1102 QColor toolTipBase(255, 255, 220);
1103 QColor toolTipText(0, 0, 0);
1104
1105 setColorGroup(cr: cg, windowText, button, light, dark, mid, text, bright_text, base,
1106 alternate_base: alt_base, window, midlight: mid_light, button_text: text,
1107 shadow: QBrush(Qt::black), highlight: QBrush(Qt::darkBlue), highlighted_text: QBrush(Qt::white),
1108 link: QBrush(Qt::blue), link_visited: QBrush(Qt::magenta), toolTipBase: QBrush(toolTipBase),
1109 toolTipText: QBrush(toolTipText));
1110
1111 data.resolve_mask &= ~(1 << Highlight);
1112 data.resolve_mask &= ~(1 << HighlightedText);
1113 data.resolve_mask &= ~(1 << LinkVisited);
1114 data.resolve_mask &= ~(1 << Link);
1115}
1116
1117
1118/*!\internal*/
1119void
1120QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBrush &button,
1121 const QBrush &light, const QBrush &dark, const QBrush &mid,
1122 const QBrush &text, const QBrush &bright_text,
1123 const QBrush &base, const QBrush &alternate_base,
1124 const QBrush &background, const QBrush &midlight,
1125 const QBrush &button_text, const QBrush &shadow,
1126 const QBrush &highlight, const QBrush &highlighted_text,
1127 const QBrush &link, const QBrush &link_visited)
1128{
1129 setColorGroup(cr: cg, windowText: foreground, button, light, dark, mid,
1130 text, bright_text, base, alternate_base, window: background,
1131 midlight, button_text, shadow, highlight, highlighted_text,
1132 link, link_visited, toolTipBase: background, toolTipText: foreground);
1133}
1134
1135/*!\internal*/
1136void QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBrush &button,
1137 const QBrush &light, const QBrush &dark, const QBrush &mid,
1138 const QBrush &text, const QBrush &bright_text,
1139 const QBrush &base, const QBrush &alternate_base,
1140 const QBrush &background, const QBrush &midlight,
1141 const QBrush &button_text, const QBrush &shadow,
1142 const QBrush &highlight, const QBrush &highlighted_text,
1143 const QBrush &link, const QBrush &link_visited,
1144 const QBrush &toolTipBase, const QBrush &toolTipText)
1145{
1146 setBrush(cg, cr: WindowText, b: foreground);
1147 setBrush(cg, cr: Button, b: button);
1148 setBrush(cg, cr: Light, b: light);
1149 setBrush(cg, cr: Dark, b: dark);
1150 setBrush(cg, cr: Mid, b: mid);
1151 setBrush(cg, cr: Text, b: text);
1152 setBrush(cg, cr: BrightText, b: bright_text);
1153 setBrush(cg, cr: Base, b: base);
1154 setBrush(cg, cr: AlternateBase, b: alternate_base);
1155 setBrush(cg, cr: Window, b: background);
1156 setBrush(cg, cr: Midlight, b: midlight);
1157 setBrush(cg, cr: ButtonText, b: button_text);
1158 setBrush(cg, cr: Shadow, b: shadow);
1159 setBrush(cg, cr: Highlight, b: highlight);
1160 setBrush(cg, cr: HighlightedText, b: highlighted_text);
1161 setBrush(cg, cr: Link, b: link);
1162 setBrush(cg, cr: LinkVisited, b: link_visited);
1163 setBrush(cg, cr: ToolTipBase, b: toolTipBase);
1164 setBrush(cg, cr: ToolTipText, b: toolTipText);
1165}
1166
1167Q_GUI_EXPORT QPalette qt_fusionPalette()
1168{
1169 QColor backGround(239, 239, 239);
1170 QColor light = backGround.lighter(f: 150);
1171 QColor mid(backGround.darker(f: 130));
1172 QColor midLight = mid.lighter(f: 110);
1173 QColor base = Qt::white;
1174 QColor disabledBase(backGround);
1175 QColor dark = backGround.darker(f: 150);
1176 QColor darkDisabled = QColor(209, 209, 209).darker(f: 110);
1177 QColor text = Qt::black;
1178 QColor hightlightedText = Qt::white;
1179 QColor disabledText = QColor(190, 190, 190);
1180 QColor button = backGround;
1181 QColor shadow = dark.darker(f: 135);
1182 QColor disabledShadow = shadow.lighter(f: 150);
1183
1184 QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base);
1185 fusionPalette.setBrush(acr: QPalette::Midlight, abrush: midLight);
1186 fusionPalette.setBrush(acr: QPalette::Button, abrush: button);
1187 fusionPalette.setBrush(acr: QPalette::Shadow, abrush: shadow);
1188 fusionPalette.setBrush(acr: QPalette::HighlightedText, abrush: hightlightedText);
1189
1190 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::Text, b: disabledText);
1191 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::WindowText, b: disabledText);
1192 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::ButtonText, b: disabledText);
1193 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::Base, b: disabledBase);
1194 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::Dark, b: darkDisabled);
1195 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::Shadow, b: disabledShadow);
1196
1197 fusionPalette.setBrush(cg: QPalette::Active, cr: QPalette::Highlight, b: QColor(48, 140, 198));
1198 fusionPalette.setBrush(cg: QPalette::Inactive, cr: QPalette::Highlight, b: QColor(48, 140, 198));
1199 fusionPalette.setBrush(cg: QPalette::Disabled, cr: QPalette::Highlight, b: QColor(145, 145, 145));
1200 return fusionPalette;
1201}
1202
1203#ifndef QT_NO_DEBUG_STREAM
1204QDebug operator<<(QDebug dbg, const QPalette &p)
1205{
1206 const char *colorGroupNames[] = {"Active", "Disabled", "Inactive"};
1207 const char *colorRoleNames[] =
1208 {"WindowText", "Button", "Light", "Midlight", "Dark", "Mid", "Text",
1209 "BrightText", "ButtonText", "Base", "Window", "Shadow", "Highlight",
1210 "HighlightedText", "Link", "LinkVisited", "AlternateBase", "NoRole",
1211 "ToolTipBase","ToolTipText", "PlaceholderText" };
1212 QDebugStateSaver saver(dbg);
1213 QDebug nospace = dbg.nospace();
1214 const uint mask = p.resolve();
1215 nospace << "QPalette(resolve=" << Qt::hex << Qt::showbase << mask << ',';
1216 for (int role = 0; role < (int)QPalette::NColorRoles; ++role) {
1217 if (mask & (1<<role)) {
1218 if (role)
1219 nospace << ',';
1220 nospace << colorRoleNames[role] << ":[";
1221 for (int group = 0; group < (int)QPalette::NColorGroups; ++group) {
1222 if (group)
1223 nospace << ',';
1224 const QRgb color = p.color(cg: static_cast<QPalette::ColorGroup>(group),
1225 cr: static_cast<QPalette::ColorRole>(role)).rgba();
1226 nospace << colorGroupNames[group] << ':' << color;
1227 }
1228 nospace << ']';
1229 }
1230 }
1231 nospace << ')' << Qt::noshowbase << Qt::dec;
1232 return dbg;
1233}
1234#endif
1235
1236QT_END_NAMESPACE
1237

source code of qtbase/src/gui/kernel/qpalette.cpp