Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquickpaletteproviderprivatebase_p.h
Go to the documentation of this file.
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#ifndef QQUICKPALETTEPROVIDERPRIVATEBASE_H
4#define QQUICKPALETTEPROVIDERPRIVATEBASE_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <QtQuick/private/qquickpalette_p.h>
18#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
19#include <QtGui/qwindow.h>
20#include <QtQml/private/qlazilyallocated_p.h>
21
23
24class QWindow;
25class QQuickWindow;
27class QQuickItem;
29class QQuickPopup;
31
42template <class I, class Impl>
44{
45 static_assert(std::is_base_of<QObject, I>{}, "The interface class must inherit QObject");
46
47public:
49
62 virtual QQuickPalette *palette() const;
63
69 virtual void setPalette(QQuickPalette *p);
70
76 virtual void resetPalette();
77
85 virtual bool providesPalette() const;
86
92 QPalette defaultPalette() const override;
93
99 QPalette parentPalette(const QPalette &fallbackPalette) const override;
100
108
119
120protected:
122
123private:
124 using PalettePtr = std::unique_ptr<QQuickPalette>;
126
127 void registerPalette(PalettePtr palette);
128
129 bool isValidPalette(const QQuickPalette *palette) const;
130
131 QQuickPalette *windowPalette() const;
132
133
134 void connectItem();
135
136 const I *itemWithPalette() const;
137 I *itemWithPalette();
138
139 QQuickPalette *paletteData() const;
140
141 QPalette toQPalette() const;
142
143private:
144 PalettePtr m_palette;
145};
146
147template<class I, class Impl>
149{
150 if (!providesPalette()) {
151 // It's required to create a new palette without parent,
152 // because this method can be called from the rendering thread
153 const_cast<Self*>(this)->registerPalette(std::make_unique<QQuickPalette>());
154 Q_EMIT const_cast<Self*>(this)->itemWithPalette()->paletteCreated();
155 }
156
157 return paletteData();
158}
159
160template<class I, class Impl>
162{
163 if (!palette) {
164 qWarning("Palette cannot be null.");
165 return false;
166 }
167
168 if (providesPalette() && paletteData() == palette) {
169 qWarning("Self assignment makes no sense.");
170 return false;
171 }
172
173 return true;
174}
175
176template<class I, class Impl>
178{
179 if (isValidPalette(p)) {
180 palette()->fromQPalette(p->toQPalette());
181 }
182}
183
184template<class I, class Impl>
186{
187 paletteData()->reset();
188}
189
190template<class I, class Impl>
192{
193 return !!m_palette;
194}
195
196template<class I, class Impl>
198{
199 return QPalette();
200}
201
202template <class Window>
203inline constexpr bool isRootWindow() { return std::is_base_of_v<QWindow, Window>; }
204
205template<class I, class Impl>
207{
208 if constexpr (!isRootWindow<I>()) {
209 // Connect item only once, before initial data allocation
210 if (!providesPalette()) {
211 connectItem();
212 }
213 }
214
215 m_palette = std::move(palette);
216 m_palette->setPaletteProvider(this);
217 m_palette->inheritPalette(parentPalette(defaultPalette()));
218
219 setCurrentColorGroup();
220
221 // In order to avoid extra noise, we should connect
222 // the following signals only after everything is already setup
223 I::connect(paletteData(), &QQuickPalette::changed, itemWithPalette(), &I::paletteChanged);
224 I::connect(paletteData(), &QQuickPalette::changed, [this]{ updateChildrenPalettes(toQPalette()); });
225}
226
227template<class T> struct dependent_false : std::false_type {};
228template<class Impl, class I> decltype(auto) getPrivateImpl(I &t) { return Impl::get(&t); }
229
230template <class T>
231decltype(auto) getPrivate(T &item)
232{
233 if constexpr (std::is_same_v<T, QQuickWindow>) {
234 return getPrivateImpl<QQuickWindowPrivate>(item);
235 } else if constexpr (std::is_same_v<T, QQuickItem>) {
236 return getPrivateImpl<QQuickItemPrivate>(item);
237 } else {
238 static_assert (dependent_false<T>::value, "Extend please.");
239 }
240}
241
242template<class I, class Impl>
244{
245 if constexpr (!isRootWindow<I>()) {
246 if (auto window = itemWithPalette()->window()) {
247 if (getPrivate(*window)->providesPalette()) {
248 return getPrivate(*window)->palette();
249 }
250 }
251 }
252
253 return nullptr;
254}
255
256template<class I, class Impl>
258{
259 if constexpr (!isRootWindow<I>()) {
260 for (auto parentItem = itemWithPalette()->parentItem(); parentItem;
261 parentItem = parentItem->parentItem()) {
262
263 // Don't allocate a new palette here. Use only if it's already pre allocated
264 if (parentItem && getPrivate(*parentItem)->providesPalette()) {
265 return getPrivate(*parentItem)->palette()->toQPalette();
266 }
267 }
268
269 if (auto wp = windowPalette()) {
270 return wp->toQPalette();
271 }
272 }
273
274 return fallbackPalette;
275}
276
277template<class I>
278const QQuickItem* rootItem(const I &item)
279{
280 if constexpr (isRootWindow<I>()) {
281 return item.contentItem();
282 } else if constexpr (std::is_same_v<QQuickPopup, I>) {
283 return nullptr;
284 } else {
285 return &item;
286 }
287}
288
289template<class I, class Impl>
291{
292 if (providesPalette()) {
293 // If palette is changed, then this function will be invoked
294 // for all children because of connection with signal changed()
295 palette()->inheritPalette(parentPalette);
296 } else {
297 // Otherwise, just propagate parent palette to all children
298 updateChildrenPalettes(parentPalette);
299 }
300}
301
302template<class I, class Impl>
304{
305 if constexpr (!isRootWindow<I>()) {
306 if (providesPalette()) {
307 const bool enabled = itemWithPalette()->isEnabled();
308 const auto window = itemWithPalette()->window();
309 const bool active = window ? window->isActive() : true;
310 palette()->setCurrentGroup(enabled ? (active ? QPalette::Active : QPalette::Inactive)
312 }
313 }
314}
315
316template<class I, class Impl>
318{
319 if constexpr (std::is_same_v<QQuickWindow, I> && std::is_same_v<QQuickWindowPrivate, Impl>) {
320 /* QQuickWindowPrivate instantiates this template, but does not include QQuickItemPrivate
321 * This causes an error with the QQuickItemPrivate::inheritPalette call below on MSVC in
322 * static builds, as QQuickItemPrivate is incomplete. To work around this situation, we do
323 * nothing in this instantiation of updateChildrenPalettes and instead add an override in
324 * QQuickWindowPrivate, which does the correct thing.
325 */
326 Q_UNREACHABLE_RETURN(); // You are not supposed to call this function
327 } else {
328 if (auto root = rootItem(*itemWithPalette())) {
329 for (auto &&child : root->childItems()) {
330 if (Q_LIKELY(child)) {
331 getPrivate(*child)->inheritPalette(parentPalette);
332 }
333 }
334 }
335 }
336}
337
338template<class I, class Impl>
340{
341 Q_ASSERT(itemWithPalette());
342
343 if constexpr (!isRootWindow<I>()) {
344 // Item with palette has the same lifetime as its implementation that inherits this class
345 I::connect(itemWithPalette(), &I::parentChanged , [this]() { inheritPalette(parentPalette(defaultPalette())); });
346 I::connect(itemWithPalette(), &I::windowChanged , [this]() { inheritPalette(parentPalette(defaultPalette())); });
347 I::connect(itemWithPalette(), &I::enabledChanged, [this]() { setCurrentColorGroup(); });
348 }
349}
350
351template<class I, class Impl>
353{
354 static_assert(std::is_base_of<QObjectData, Impl>{},
355 "The Impl class must inherit QObjectData");
356
357 return static_cast<const I*>(static_cast<const Impl*>(this)->q_ptr);
358}
359
360template<class I, class Impl>
362{
363 return const_cast<I*>(const_cast<const Self*>(this)->itemWithPalette());
364}
365
366template<class I, class Impl>
368{
369 Q_ASSERT(m_palette); return m_palette.get();
370}
371
372template<class I, class Impl>
374{
375 return palette()->toQPalette();
376}
377
379
380#endif // QQUICKPALETTEPROVIDERPRIVATEBASE_H
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
@ Inactive
Definition qpalette.h:48
@ Disabled
Definition qpalette.h:48
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
void inheritPalette(const QPalette &parentPalette)
virtual void updateChildrenPalettes(const QPalette &parentPalette)
virtual ~QQuickPaletteProviderPrivateBase()=default
QPalette parentPalette(const QPalette &fallbackPalette) const override
Contains color groups for each QML item state. \inmodule QtQuick.
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtGui
Definition qwindow.h:63
Combined button and popup list for selecting options.
#define Q_LIKELY(x)
#define qWarning
Definition qlogging.h:162
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
const QQuickItem * rootItem(const I &item)
decltype(auto) getPrivate(T &item)
constexpr bool isRootWindow()
decltype(auto) getPrivateImpl(I &t)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_EMIT
QGraphicsItem * item
QLayoutItem * child
[0]
aWidget window() -> setWindowTitle("New Window Title")
[2]