1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#include "qquickpalettecolorprovider_p.h"
4
5#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
6
7QT_BEGIN_NAMESPACE
8
9static bool notEq(const QPalette &p1, const QPalette &p2)
10{
11 return p1.resolveMask() != p2.resolveMask() || p1 != p2;
12}
13
14static QPalette::ColorGroup adjustCg(QPalette::ColorGroup group)
15{
16 return group == QPalette::All ? QPalette::Active : group;
17}
18
19class DefaultPalettesProvider : public QQuickAbstractPaletteProvider
20{
21public:
22 QPalette defaultPalette() const override { static QPalette p; return p; }
23};
24
25static std::default_delete<const QQuickAbstractPaletteProvider> defaultDeleter() { return {}; }
26
27QQuickPaletteColorProvider::QQuickPaletteColorProvider()
28 : m_paletteProvider(ProviderPtr(new DefaultPalettesProvider, defaultDeleter()))
29{
30}
31
32const QColor &QQuickPaletteColorProvider::color(QPalette::ColorGroup group, QPalette::ColorRole role) const
33{
34 return m_resolvedPalette.color(cg: adjustCg(group), cr: role);
35}
36
37bool QQuickPaletteColorProvider::setColor(QPalette::ColorGroup g, QPalette::ColorRole r, QColor c)
38{
39 ensureRequestedPalette();
40 m_requestedPalette->setColor(acg: g, acr: r, acolor: c);
41
42 return updateInheritedPalette();
43}
44
45bool QQuickPaletteColorProvider::resetColor(QPalette::ColorGroup group, QPalette::ColorRole role)
46{
47 const auto &defaultPalette = paletteProvider()->defaultPalette() ;
48 const auto &defaultColor = defaultPalette.color(cg: adjustCg(group), cr: role);
49
50 return setColor(g: group, r: role, c: defaultColor);
51}
52
53bool QQuickPaletteColorProvider::fromQPalette(QPalette p)
54{
55 m_requestedPalette.value() = std::move(p);
56 return updateInheritedPalette();
57}
58
59QPalette QQuickPaletteColorProvider::palette() const
60{
61 return m_resolvedPalette;
62}
63
64const QQuickAbstractPaletteProvider *QQuickPaletteColorProvider::paletteProvider() const
65{
66 Q_ASSERT(m_paletteProvider);
67 return m_paletteProvider.get();
68}
69
70void QQuickPaletteColorProvider::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider)
71{
72 static const auto emptyDeleter = [](auto &&){};
73 m_paletteProvider = ProviderPtr(paletteProvider, emptyDeleter);
74}
75
76bool QQuickPaletteColorProvider::copyColorGroup(QPalette::ColorGroup cg,
77 const QQuickPaletteColorProvider &p)
78{
79 ensureRequestedPalette();
80
81 auto srcPalette = p.palette();
82 for (int roleIndex = QPalette::WindowText; roleIndex < QPalette::NColorRoles; ++roleIndex) {
83 const auto cr = QPalette::ColorRole(roleIndex);
84 if (srcPalette.isBrushSet(cg, cr)) {
85 m_requestedPalette->setBrush(cg, cr, brush: srcPalette.brush(cg, cr));
86 }
87 }
88
89 return updateInheritedPalette();
90}
91
92bool QQuickPaletteColorProvider::reset()
93{
94 return fromQPalette(p: QPalette());
95}
96
97/*! \internal
98 Merge the given \a palette with the existing requested palette, remember
99 that it is the inherited palette (in case updateInheritedPalette() is
100 called later), and update the stored palette (to be returned from
101 \l palette()) if the result is different. Returns whether the stored
102 palette got changed.
103*/
104bool QQuickPaletteColorProvider::inheritPalette(const QPalette &palette)
105{
106 m_lastInheritedPalette.value() = palette;
107 return doInheritPalette(palette);
108}
109
110/*! \internal
111 Merge the given \a palette with the existing requested palette, and update
112 the stored palette (to be returned from \l palette()) if the result is
113 different. Returns whether the stored palette got changed.
114*/
115bool QQuickPaletteColorProvider::doInheritPalette(const QPalette &palette)
116{
117 auto inheritedMask = m_requestedPalette.isAllocated() ? m_requestedPalette->resolveMask() | palette.resolveMask()
118 : palette.resolveMask();
119 QPalette parentPalette = m_requestedPalette.isAllocated() ? m_requestedPalette->resolve(other: palette) : palette;
120 parentPalette.setResolveMask(inheritedMask);
121
122 auto tmpResolvedPalette = parentPalette.resolve(other: paletteProvider()->defaultPalette());
123 tmpResolvedPalette.setResolveMask(tmpResolvedPalette.resolveMask() | inheritedMask);
124
125 bool changed = notEq(p1: tmpResolvedPalette, p2: m_resolvedPalette);
126 if (changed)
127 std::swap(a&: tmpResolvedPalette, b&: m_resolvedPalette);
128
129 return changed;
130}
131
132/*! \internal
133 Update the stored palette (to be returned from \l palette()) from the
134 parent palette. Returns whether the stored palette got changed.
135*/
136bool QQuickPaletteColorProvider::updateInheritedPalette()
137{
138 // Use last inherited palette as parentPalette's fallbackPalette: it's useful when parentPalette doesn't exist.
139 const QPalette &p = m_lastInheritedPalette.isAllocated() ? m_lastInheritedPalette.value()
140 : paletteProvider()->defaultPalette();
141 return doInheritPalette(palette: paletteProvider()->parentPalette(fallbackPalette: p));
142}
143
144void QQuickPaletteColorProvider::ensureRequestedPalette()
145{
146 if (m_requestedPalette.isAllocated())
147 return;
148
149 m_requestedPalette.value() = QPalette();
150}
151
152QT_END_NAMESPACE
153

source code of qtdeclarative/src/quick/items/qquickpalettecolorprovider.cpp