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 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | static bool notEq(const QPalette &p1, const QPalette &p2) |
10 | { |
11 | return p1.resolveMask() != p2.resolveMask() || p1 != p2; |
12 | } |
13 | |
14 | static QPalette::ColorGroup adjustCg(QPalette::ColorGroup group) |
15 | { |
16 | return group == QPalette::All ? QPalette::Active : group; |
17 | } |
18 | |
19 | class DefaultPalettesProvider : public QQuickAbstractPaletteProvider |
20 | { |
21 | public: |
22 | QPalette defaultPalette() const override { static QPalette p; return p; } |
23 | }; |
24 | |
25 | static std::default_delete<const QQuickAbstractPaletteProvider> defaultDeleter() { return {}; } |
26 | |
27 | QQuickPaletteColorProvider::QQuickPaletteColorProvider() |
28 | : m_paletteProvider(ProviderPtr(new DefaultPalettesProvider, defaultDeleter())) |
29 | { |
30 | } |
31 | |
32 | const QColor &QQuickPaletteColorProvider::color(QPalette::ColorGroup group, QPalette::ColorRole role) const |
33 | { |
34 | return m_resolvedPalette.color(cg: adjustCg(group), cr: role); |
35 | } |
36 | |
37 | bool 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 | |
45 | bool 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 | |
53 | bool QQuickPaletteColorProvider::fromQPalette(QPalette p) |
54 | { |
55 | m_requestedPalette.value() = std::move(p); |
56 | return updateInheritedPalette(); |
57 | } |
58 | |
59 | QPalette QQuickPaletteColorProvider::palette() const |
60 | { |
61 | return m_resolvedPalette; |
62 | } |
63 | |
64 | const QQuickAbstractPaletteProvider *QQuickPaletteColorProvider::paletteProvider() const |
65 | { |
66 | Q_ASSERT(m_paletteProvider); |
67 | return m_paletteProvider.get(); |
68 | } |
69 | |
70 | void QQuickPaletteColorProvider::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider) |
71 | { |
72 | static const auto emptyDeleter = [](auto &&){}; |
73 | m_paletteProvider = ProviderPtr(paletteProvider, emptyDeleter); |
74 | } |
75 | |
76 | bool 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 | |
92 | bool 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 | */ |
104 | bool 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 | */ |
115 | bool 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 | */ |
136 | bool 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 | |
144 | void QQuickPaletteColorProvider::ensureRequestedPalette() |
145 | { |
146 | if (m_requestedPalette.isAllocated()) |
147 | return; |
148 | |
149 | m_requestedPalette.value() = QPalette(); |
150 | } |
151 | |
152 | QT_END_NAMESPACE |
153 | |