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#include <QtGui/private/qpalette_p.h>
7
8QT_BEGIN_NAMESPACE
9
10static bool notEq(const QPalette &p1, const QPalette &p2)
11{
12 return p1.resolveMask() != p2.resolveMask() || p1 != p2;
13}
14
15static QPalette::ColorGroup adjustCg(QPalette::ColorGroup group)
16{
17 return group == QPalette::All ? QPalette::Active : group;
18}
19
20class DefaultPalettesProvider : public QQuickAbstractPaletteProvider
21{
22public:
23 QPalette defaultPalette() const override { static QPalette p; return p; }
24};
25
26static std::default_delete<const QQuickAbstractPaletteProvider> defaultDeleter() { return {}; }
27
28QQuickPaletteColorProvider::QQuickPaletteColorProvider()
29 : m_paletteProvider(ProviderPtr(new DefaultPalettesProvider, defaultDeleter()))
30{
31}
32
33const QColor &QQuickPaletteColorProvider::color(QPalette::ColorGroup group, QPalette::ColorRole role) const
34{
35 return m_resolvedPalette.color(cg: adjustCg(group), cr: role);
36}
37
38bool QQuickPaletteColorProvider::setColor(QPalette::ColorGroup g, QPalette::ColorRole r, QColor c)
39{
40 ensureRequestedPalette();
41 m_requestedPalette->setColor(acg: g, acr: r, acolor: c);
42
43 return updateInheritedPalette();
44}
45
46bool QQuickPaletteColorProvider::resetColor(QPalette::ColorGroup group, QPalette::ColorRole role)
47{
48 if (!m_requestedPalette.isAllocated())
49 return false;
50
51 QPalette::ResolveMask unsetResolveMask = 0;
52
53 if (group == QPalette::Current)
54 group = m_requestedPalette->currentColorGroup();
55
56 if (group == QPalette::All) {
57 for (int g = QPalette::Active; g < QPalette::NColorGroups; ++g)
58 unsetResolveMask |= (QPalette::ResolveMask(1) << QPalettePrivate::bitPosition(colorGroup: QPalette::ColorGroup(g), colorRole: role));
59 } else {
60 unsetResolveMask = (QPalette::ResolveMask(1) << QPalettePrivate::bitPosition(colorGroup: group, colorRole: role));
61 }
62
63 m_requestedPalette->setResolveMask(m_requestedPalette->resolveMask() & ~unsetResolveMask);
64
65 return updateInheritedPalette();
66}
67
68bool QQuickPaletteColorProvider::resetColor(QPalette::ColorGroup group)
69{
70 if (!m_requestedPalette.isAllocated())
71 return false;
72
73 QPalette::ResolveMask unsetResolveMask = 0;
74
75 auto getResolveMask = [] (QPalette::ColorGroup group) {
76 QPalette::ResolveMask mask = 0;
77 for (int roleIndex = QPalette::WindowText; roleIndex < QPalette::NColorRoles; ++roleIndex) {
78 const auto cr = QPalette::ColorRole(roleIndex);
79 mask |= (QPalette::ResolveMask(1) << QPalettePrivate::bitPosition(colorGroup: group, colorRole: cr));
80 }
81 return mask;
82 };
83
84 if (group == QPalette::Current)
85 group = m_requestedPalette->currentColorGroup();
86
87 if (group == QPalette::All) {
88 for (int g = QPalette::Active; g < QPalette::NColorGroups; ++g)
89 unsetResolveMask |= getResolveMask(QPalette::ColorGroup(g));
90 } else {
91 unsetResolveMask = getResolveMask(group);
92 }
93
94 m_requestedPalette->setResolveMask(m_requestedPalette->resolveMask() & ~unsetResolveMask);
95
96 return updateInheritedPalette();
97}
98
99bool QQuickPaletteColorProvider::fromQPalette(QPalette p)
100{
101 m_requestedPalette.value() = std::move(p);
102 return updateInheritedPalette();
103}
104
105QPalette QQuickPaletteColorProvider::palette() const
106{
107 return m_resolvedPalette;
108}
109
110const QQuickAbstractPaletteProvider *QQuickPaletteColorProvider::paletteProvider() const
111{
112 Q_ASSERT(m_paletteProvider);
113 return m_paletteProvider.get();
114}
115
116void QQuickPaletteColorProvider::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider)
117{
118 static const auto emptyDeleter = [](auto &&){};
119 m_paletteProvider = ProviderPtr(paletteProvider, emptyDeleter);
120}
121
122bool QQuickPaletteColorProvider::copyColorGroup(QPalette::ColorGroup cg,
123 const QQuickPaletteColorProvider &p)
124{
125 ensureRequestedPalette();
126
127 auto srcPalette = p.palette();
128 for (int roleIndex = QPalette::WindowText; roleIndex < QPalette::NColorRoles; ++roleIndex) {
129 const auto cr = QPalette::ColorRole(roleIndex);
130 if (srcPalette.isBrushSet(cg, cr)) {
131 m_requestedPalette->setBrush(cg, cr, brush: srcPalette.brush(cg, cr));
132 }
133 }
134
135 return updateInheritedPalette();
136}
137
138bool QQuickPaletteColorProvider::reset()
139{
140 return fromQPalette(p: QPalette());
141}
142
143/*! \internal
144 Merge the given \a palette with the existing requested palette, remember
145 that it is the inherited palette (in case updateInheritedPalette() is
146 called later), and update the stored palette (to be returned from
147 \l palette()) if the result is different. Returns whether the stored
148 palette got changed.
149*/
150bool QQuickPaletteColorProvider::inheritPalette(const QPalette &palette)
151{
152 m_lastInheritedPalette.value() = palette;
153 return doInheritPalette(palette);
154}
155
156/*! \internal
157 Merge the given \a palette with the existing requested palette, and update
158 the stored palette (to be returned from \l palette()) if the result is
159 different. Returns whether the stored palette got changed.
160*/
161bool QQuickPaletteColorProvider::doInheritPalette(const QPalette &palette)
162{
163 auto inheritedMask = m_requestedPalette.isAllocated() ? m_requestedPalette->resolveMask() | palette.resolveMask()
164 : palette.resolveMask();
165 // If a palette was set on this item, it should always win over the palette to be inherited from.
166 QPalette parentPalette = m_requestedPalette.isAllocated() ? m_requestedPalette->resolve(other: palette) : palette;
167 parentPalette.setResolveMask(inheritedMask);
168
169 auto tmpResolvedPalette = parentPalette.resolve(other: paletteProvider()->defaultPalette());
170 tmpResolvedPalette.setResolveMask(tmpResolvedPalette.resolveMask() | inheritedMask);
171
172 bool changed = notEq(p1: tmpResolvedPalette, p2: m_resolvedPalette);
173 if (changed)
174 std::swap(a&: tmpResolvedPalette, b&: m_resolvedPalette);
175
176 return changed;
177}
178
179/*! \internal
180 Update the stored palette (to be returned from \l palette()) from the
181 parent palette. Returns whether the stored palette got changed.
182*/
183bool QQuickPaletteColorProvider::updateInheritedPalette()
184{
185 // Use last inherited palette as parentPalette's fallbackPalette: it's useful when parentPalette doesn't exist.
186 const QPalette &p = m_lastInheritedPalette.isAllocated() ? m_lastInheritedPalette.value()
187 : paletteProvider()->defaultPalette();
188 return doInheritPalette(palette: paletteProvider()->parentPalette(fallbackPalette: p));
189}
190
191void QQuickPaletteColorProvider::ensureRequestedPalette()
192{
193 if (m_requestedPalette.isAllocated())
194 return;
195
196 m_requestedPalette.value() = QPalette();
197}
198
199QT_END_NAMESPACE
200

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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