Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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>;
125 using Self = QQuickPaletteProviderPrivateBase<I, Impl>;
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>
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, itemWithPalette(), [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_base_of_v<T, QQuickWindow>) {
234 return getPrivateImpl<QQuickWindowPrivate>(item);
235 } else if constexpr (std::is_base_of_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 // Popups should always inherit from their window, even child popups: QTBUG-115707.
261 if (!std::is_base_of_v<QQuickPopup, I>) {
262 for (auto parentItem = itemWithPalette()->parentItem(); parentItem;
263 parentItem = parentItem->parentItem()) {
264
265 // Don't allocate a new palette here. Use only if it's already pre allocated
266 if (parentItem && getPrivate(*parentItem)->providesPalette()) {
267 return getPrivate(*parentItem)->palette()->toQPalette();
268 }
269 }
270 }
271
272 if (auto wp = windowPalette()) {
273 return wp->toQPalette();
274 }
275 }
276
277 return fallbackPalette;
278}
279
280template<class I>
281const QQuickItem* rootItem(const I &item)
282{
283 if constexpr (isRootWindow<I>()) {
284 return item.contentItem();
285 } else if constexpr (std::is_base_of_v<QQuickPopup, I>) {
286 return nullptr;
287 } else {
288 return &item;
289 }
290}
291
292template<class I, class Impl>
294{
295 if (providesPalette()) {
296 // If palette is changed, then this function will be invoked
297 // for all children because of connection with signal changed()
298 palette()->inheritPalette(parentPalette);
299 } else {
300 // Otherwise, just propagate parent palette to all children
301 updateChildrenPalettes(parentPalette);
302 }
303}
304
305template<class I, class Impl>
307{
308 if constexpr (!isRootWindow<I>()) {
309 if (providesPalette()) {
310 const bool enabled = itemWithPalette()->isEnabled();
311 const auto window = itemWithPalette()->window();
312 const bool active = window ? window->isActive() : true;
313 palette()->setCurrentGroup(enabled ? (active ? QPalette::Active : QPalette::Inactive)
315 }
316 }
317}
318
319template<class I, class Impl>
321{
322 if constexpr (std::is_same_v<QQuickWindow, I> && std::is_same_v<QQuickWindowPrivate, Impl>) {
323 /* QQuickWindowPrivate instantiates this template, but does not include QQuickItemPrivate
324 * This causes an error with the QQuickItemPrivate::inheritPalette call below on MSVC in
325 * static builds, as QQuickItemPrivate is incomplete. To work around this situation, we do
326 * nothing in this instantiation of updateChildrenPalettes and instead add an override in
327 * QQuickWindowPrivate, which does the correct thing.
328 */
329 Q_UNREACHABLE_RETURN(); // You are not supposed to call this function
330 } else {
331 if (auto root = rootItem(*itemWithPalette())) {
332 for (auto &&child : root->childItems()) {
333 if (Q_LIKELY(child)) {
334 getPrivate(*child)->inheritPalette(parentPalette);
335 }
336 }
337 }
338 }
339}
340
341template<class I, class Impl>
343{
344 Q_ASSERT(itemWithPalette());
345
346 if constexpr (!isRootWindow<I>()) {
347 // Item with palette has the same lifetime as its implementation that inherits this class
348 I::connect(itemWithPalette(), &I::parentChanged,
349 itemWithPalette(), [this]() { inheritPalette(parentPalette(defaultPalette())); });
350 I::connect(itemWithPalette(), &I::windowChanged,
351 itemWithPalette(), [this]() { inheritPalette(parentPalette(defaultPalette())); });
352 I::connect(itemWithPalette(), &I::enabledChanged,
353 itemWithPalette(), [this]() { setCurrentColorGroup(); });
354 }
355}
356
357template<class I, class Impl>
359{
360 static_assert(std::is_base_of<QObjectData, Impl>{},
361 "The Impl class must inherit QObjectData");
362
363 return static_cast<const I*>(static_cast<const Impl*>(this)->q_ptr);
364}
365
366template<class I, class Impl>
368{
369 return const_cast<I*>(const_cast<const Self*>(this)->itemWithPalette());
370}
371
372template<class I, class Impl>
374{
375 Q_ASSERT(m_palette); return m_palette.get();
376}
377
378template<class I, class Impl>
380{
381 return palette()->toQPalette();
382}
383
385
386#endif // QQUICKPALETTEPROVIDERPRIVATEBASE_H
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
@ Inactive
Definition qpalette.h:49
@ Disabled
Definition qpalette.h:49
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
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:166
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]