1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses |
5 | |
6 | #include "declarativetheme_p.h" |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | DeclarativeTheme3D::DeclarativeTheme3D(QObject *parent) |
11 | : Q3DTheme(parent), |
12 | m_colors(QList<DeclarativeColor *>()), |
13 | m_gradients(QList<ColorGradient *>()), |
14 | m_singleHLGradient(0), |
15 | m_multiHLGradient(0), |
16 | m_dummyGradients(false), |
17 | m_dummyColors(false) |
18 | { |
19 | connect(sender: this, signal: &Q3DTheme::typeChanged, context: this, slot: &DeclarativeTheme3D::handleTypeChange); |
20 | } |
21 | |
22 | DeclarativeTheme3D::~DeclarativeTheme3D() |
23 | { |
24 | } |
25 | |
26 | QQmlListProperty<QObject> DeclarativeTheme3D::themeChildren() |
27 | { |
28 | return QQmlListProperty<QObject>(this, this, &DeclarativeTheme3D::appendThemeChildren, |
29 | 0, 0, 0); |
30 | } |
31 | |
32 | void DeclarativeTheme3D::appendThemeChildren(QQmlListProperty<QObject> *list, QObject *element) |
33 | { |
34 | Q_UNUSED(list); |
35 | Q_UNUSED(element); |
36 | // Nothing to do, themeChildren is there only to enable scoping gradient items in Theme3D item. |
37 | } |
38 | |
39 | void DeclarativeTheme3D::handleTypeChange(Theme themeType) |
40 | { |
41 | Q_UNUSED(themeType); |
42 | |
43 | // Theme changed, disconnect base color/gradient connections |
44 | if (!m_colors.isEmpty()) { |
45 | foreach (DeclarativeColor *item, m_colors) |
46 | disconnect(sender: item, signal: 0, receiver: this, member: 0); |
47 | m_colors.clear(); |
48 | } |
49 | if (!m_gradients.isEmpty()) { |
50 | foreach (ColorGradient *item, m_gradients) |
51 | disconnect(sender: item, signal: 0, receiver: this, member: 0); |
52 | m_gradients.clear(); |
53 | } |
54 | } |
55 | |
56 | void DeclarativeTheme3D::handleBaseColorUpdate() |
57 | { |
58 | int colorCount = m_colors.size(); |
59 | int changed = 0; |
60 | // Check which one changed |
61 | DeclarativeColor *color = qobject_cast<DeclarativeColor *>(object: QObject::sender()); |
62 | for (int i = 0; i < colorCount; i++) { |
63 | if (color == m_colors.at(i)) { |
64 | changed = i; |
65 | break; |
66 | } |
67 | } |
68 | // Update the changed one from the list |
69 | QList<QColor> list = Q3DTheme::baseColors(); |
70 | list[changed] = m_colors.at(i: changed)->color(); |
71 | // Set the changed list |
72 | Q3DTheme::setBaseColors(list); |
73 | } |
74 | |
75 | void DeclarativeTheme3D::handleBaseGradientUpdate() |
76 | { |
77 | int gradientCount = m_gradients.size(); |
78 | int changed = 0; |
79 | // Check which one changed |
80 | ColorGradient *gradient = qobject_cast<ColorGradient *>(object: QObject::sender()); |
81 | for (int i = 0; i < gradientCount; i++) { |
82 | if (gradient == m_gradients.at(i)) { |
83 | changed = i; |
84 | break; |
85 | } |
86 | } |
87 | // Update the changed one from the list |
88 | QList<QLinearGradient> list = Q3DTheme::baseGradients(); |
89 | list[changed] = convertGradient(gradient); |
90 | // Set the changed list |
91 | Q3DTheme::setBaseGradients(list); |
92 | } |
93 | |
94 | void DeclarativeTheme3D::handleSingleHLGradientUpdate() |
95 | { |
96 | if (m_singleHLGradient) |
97 | setThemeGradient(gradient: m_singleHLGradient, type: GradientTypeSingleHL); |
98 | } |
99 | |
100 | void DeclarativeTheme3D::handleMultiHLGradientUpdate() |
101 | { |
102 | if (m_multiHLGradient) |
103 | setThemeGradient(gradient: m_multiHLGradient, type: GradientTypeMultiHL); |
104 | } |
105 | |
106 | void DeclarativeTheme3D::setSingleHighlightGradient(ColorGradient *gradient) |
107 | { |
108 | // connect new / disconnect old |
109 | if (gradient != m_singleHLGradient) { |
110 | if (m_singleHLGradient) |
111 | QObject::disconnect(sender: m_singleHLGradient, signal: 0, receiver: this, member: 0); |
112 | |
113 | m_singleHLGradient = gradient; |
114 | |
115 | if (m_singleHLGradient) { |
116 | QObject::connect(sender: m_singleHLGradient, signal: &ColorGradient::updated, context: this, |
117 | slot: &DeclarativeTheme3D::handleSingleHLGradientUpdate); |
118 | } |
119 | |
120 | emit singleHighlightGradientChanged(gradient: m_singleHLGradient); |
121 | } |
122 | |
123 | if (m_singleHLGradient) |
124 | setThemeGradient(gradient: m_singleHLGradient, type: GradientTypeSingleHL); |
125 | } |
126 | |
127 | ColorGradient *DeclarativeTheme3D::singleHighlightGradient() const |
128 | { |
129 | return m_singleHLGradient; |
130 | } |
131 | |
132 | void DeclarativeTheme3D::setMultiHighlightGradient(ColorGradient *gradient) |
133 | { |
134 | // connect new / disconnect old |
135 | if (gradient != m_multiHLGradient) { |
136 | if (m_multiHLGradient) |
137 | QObject::disconnect(sender: m_multiHLGradient, signal: 0, receiver: this, member: 0); |
138 | |
139 | m_multiHLGradient = gradient; |
140 | |
141 | if (m_multiHLGradient) { |
142 | QObject::connect(sender: m_multiHLGradient, signal: &ColorGradient::updated, context: this, |
143 | slot: &DeclarativeTheme3D::handleMultiHLGradientUpdate); |
144 | } |
145 | |
146 | emit multiHighlightGradientChanged(gradient: m_multiHLGradient); |
147 | } |
148 | |
149 | if (m_multiHLGradient) |
150 | setThemeGradient(gradient: m_multiHLGradient, type: GradientTypeMultiHL); |
151 | } |
152 | |
153 | ColorGradient *DeclarativeTheme3D::multiHighlightGradient() const |
154 | { |
155 | return m_multiHLGradient; |
156 | } |
157 | |
158 | void DeclarativeTheme3D::classBegin() |
159 | { |
160 | // Turn off predefined type forcing for the duration of initial class construction |
161 | // so that predefined type customization can be done. |
162 | d_ptr->setForcePredefinedType(false); |
163 | } |
164 | |
165 | void DeclarativeTheme3D::componentComplete() |
166 | { |
167 | d_ptr->setForcePredefinedType(true); |
168 | } |
169 | |
170 | |
171 | void DeclarativeTheme3D::setThemeGradient(ColorGradient *gradient, GradientType type) |
172 | { |
173 | QLinearGradient newGradient = convertGradient(gradient); |
174 | |
175 | switch (type) { |
176 | case GradientTypeSingleHL: |
177 | Q3DTheme::setSingleHighlightGradient(newGradient); |
178 | break; |
179 | case GradientTypeMultiHL: |
180 | Q3DTheme::setMultiHighlightGradient(newGradient); |
181 | break; |
182 | default: |
183 | qWarning(msg: "Incorrect usage. Type may be GradientTypeSingleHL or GradientTypeMultiHL."); |
184 | break; |
185 | } |
186 | } |
187 | |
188 | QLinearGradient DeclarativeTheme3D::convertGradient(ColorGradient *gradient) |
189 | { |
190 | QLinearGradient newGradient; |
191 | QGradientStops stops; |
192 | QList<ColorGradientStop *> qmlstops = gradient->m_stops; |
193 | |
194 | // Get sorted gradient stops |
195 | for (int i = 0; i < qmlstops.size(); i++) { |
196 | int j = 0; |
197 | while (j < stops.size() && stops.at(i: j).first < qmlstops[i]->position()) |
198 | j++; |
199 | stops.insert(i: j, t: QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color())); |
200 | } |
201 | |
202 | newGradient.setStops(stops); |
203 | |
204 | return newGradient; |
205 | } |
206 | |
207 | ColorGradient *DeclarativeTheme3D::convertGradient(const QLinearGradient &gradient) |
208 | { |
209 | ColorGradient *newGradient = new ColorGradient(this); |
210 | QGradientStops stops = gradient.stops(); |
211 | ColorGradientStop *qmlstop; |
212 | |
213 | // Convert stops |
214 | for (int i = 0; i < stops.size(); i++) { |
215 | qmlstop = new ColorGradientStop(newGradient); |
216 | qmlstop->setColor(stops.at(i).second); |
217 | qmlstop->setPosition(stops.at(i).first); |
218 | newGradient->m_stops.append(t: qmlstop); |
219 | } |
220 | |
221 | return newGradient; |
222 | } |
223 | |
224 | void DeclarativeTheme3D::addColor(DeclarativeColor *color) |
225 | { |
226 | if (!color) { |
227 | qWarning(msg: "Color is invalid, use ThemeColor"); |
228 | return; |
229 | } |
230 | clearDummyColors(); |
231 | m_colors.append(t: color); |
232 | connect(sender: color, signal: &DeclarativeColor::colorChanged, |
233 | context: this, slot: &DeclarativeTheme3D::handleBaseColorUpdate); |
234 | QList<QColor> list = Q3DTheme::baseColors(); |
235 | list.append(t: color->color()); |
236 | Q3DTheme::setBaseColors(list); |
237 | } |
238 | |
239 | QList<DeclarativeColor *> DeclarativeTheme3D::colorList() |
240 | { |
241 | if (m_colors.isEmpty()) { |
242 | // Create dummy ThemeColors from theme's colors |
243 | m_dummyColors = true; |
244 | QList<QColor> list = Q3DTheme::baseColors(); |
245 | foreach (QColor item, list) { |
246 | DeclarativeColor *color = new DeclarativeColor(this); |
247 | color->setColor(item); |
248 | m_colors.append(t: color); |
249 | connect(sender: color, signal: &DeclarativeColor::colorChanged, |
250 | context: this, slot: &DeclarativeTheme3D::handleBaseColorUpdate); |
251 | } |
252 | } |
253 | return m_colors; |
254 | } |
255 | |
256 | void DeclarativeTheme3D::clearColors() |
257 | { |
258 | clearDummyColors(); |
259 | foreach (DeclarativeColor *item, m_colors) |
260 | disconnect(sender: item, signal: 0, receiver: this, member: 0); |
261 | m_colors.clear(); |
262 | Q3DTheme::setBaseColors(QList<QColor>()); |
263 | } |
264 | |
265 | void DeclarativeTheme3D::clearDummyColors() |
266 | { |
267 | if (m_dummyColors) { |
268 | foreach (DeclarativeColor *item, m_colors) |
269 | delete item; |
270 | m_colors.clear(); |
271 | m_dummyColors = false; |
272 | } |
273 | } |
274 | |
275 | void DeclarativeTheme3D::addGradient(ColorGradient *gradient) |
276 | { |
277 | if (!gradient) { |
278 | qWarning(msg: "Gradient is invalid, use ColorGradient"); |
279 | return; |
280 | } |
281 | clearDummyGradients(); |
282 | m_gradients.append(t: gradient); |
283 | connect(sender: gradient, signal: &ColorGradient::updated, |
284 | context: this, slot: &DeclarativeTheme3D::handleBaseGradientUpdate); |
285 | QList<QLinearGradient> list = Q3DTheme::baseGradients(); |
286 | list.append(t: convertGradient(gradient)); |
287 | Q3DTheme::setBaseGradients(list); |
288 | } |
289 | |
290 | QList<ColorGradient *> DeclarativeTheme3D::gradientList() |
291 | { |
292 | if (m_gradients.isEmpty()) { |
293 | // Create dummy ColorGradients from theme's gradients |
294 | m_dummyGradients = true; |
295 | QList<QLinearGradient> list = Q3DTheme::baseGradients(); |
296 | foreach (QLinearGradient item, list) { |
297 | ColorGradient *gradient = convertGradient(gradient: item); |
298 | m_gradients.append(t: gradient); |
299 | connect(sender: gradient, signal: &ColorGradient::updated, |
300 | context: this, slot: &DeclarativeTheme3D::handleBaseGradientUpdate); |
301 | } |
302 | } |
303 | |
304 | return m_gradients; |
305 | } |
306 | |
307 | void DeclarativeTheme3D::clearGradients() |
308 | { |
309 | clearDummyGradients(); |
310 | foreach (ColorGradient *item, m_gradients) |
311 | disconnect(sender: item, signal: 0, receiver: this, member: 0); |
312 | m_gradients.clear(); |
313 | Q3DTheme::setBaseGradients(QList<QLinearGradient>()); |
314 | } |
315 | |
316 | void DeclarativeTheme3D::clearDummyGradients() |
317 | { |
318 | if (m_dummyGradients) { |
319 | foreach (ColorGradient *item, m_gradients) |
320 | delete item; |
321 | m_gradients.clear(); |
322 | m_dummyGradients = false; |
323 | } |
324 | } |
325 | |
326 | QQmlListProperty<DeclarativeColor> DeclarativeTheme3D::baseColors() |
327 | { |
328 | return QQmlListProperty<DeclarativeColor>(this, this, |
329 | &DeclarativeTheme3D::appendBaseColorsFunc, |
330 | &DeclarativeTheme3D::countBaseColorsFunc, |
331 | &DeclarativeTheme3D::atBaseColorsFunc, |
332 | &DeclarativeTheme3D::clearBaseColorsFunc); |
333 | } |
334 | |
335 | void DeclarativeTheme3D::appendBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list, |
336 | DeclarativeColor *color) |
337 | { |
338 | reinterpret_cast<DeclarativeTheme3D *>(list->data)->addColor(color); |
339 | } |
340 | |
341 | qsizetype DeclarativeTheme3D::countBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list) |
342 | { |
343 | return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().size(); |
344 | } |
345 | |
346 | DeclarativeColor *DeclarativeTheme3D::atBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list, |
347 | qsizetype index) |
348 | { |
349 | return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().at(i: index); |
350 | } |
351 | |
352 | void DeclarativeTheme3D::clearBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list) |
353 | { |
354 | reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearColors(); |
355 | } |
356 | |
357 | QQmlListProperty<ColorGradient> DeclarativeTheme3D::baseGradients() |
358 | { |
359 | return QQmlListProperty<ColorGradient>(this, this, |
360 | &DeclarativeTheme3D::appendBaseGradientsFunc, |
361 | &DeclarativeTheme3D::countBaseGradientsFunc, |
362 | &DeclarativeTheme3D::atBaseGradientsFunc, |
363 | &DeclarativeTheme3D::clearBaseGradientsFunc); |
364 | } |
365 | |
366 | void DeclarativeTheme3D::appendBaseGradientsFunc(QQmlListProperty<ColorGradient> *list, |
367 | ColorGradient *gradient) |
368 | { |
369 | reinterpret_cast<DeclarativeTheme3D *>(list->data)->addGradient(gradient); |
370 | } |
371 | |
372 | qsizetype DeclarativeTheme3D::countBaseGradientsFunc(QQmlListProperty<ColorGradient> *list) |
373 | { |
374 | return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().size(); |
375 | } |
376 | |
377 | ColorGradient *DeclarativeTheme3D::atBaseGradientsFunc(QQmlListProperty<ColorGradient> *list, |
378 | qsizetype index) |
379 | { |
380 | return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().at(i: index); |
381 | } |
382 | |
383 | void DeclarativeTheme3D::clearBaseGradientsFunc(QQmlListProperty<ColorGradient> *list) |
384 | { |
385 | reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearGradients(); |
386 | } |
387 | |
388 | QT_END_NAMESPACE |
389 |
Definitions
- DeclarativeTheme3D
- ~DeclarativeTheme3D
- themeChildren
- appendThemeChildren
- handleTypeChange
- handleBaseColorUpdate
- handleBaseGradientUpdate
- handleSingleHLGradientUpdate
- handleMultiHLGradientUpdate
- setSingleHighlightGradient
- singleHighlightGradient
- setMultiHighlightGradient
- multiHighlightGradient
- classBegin
- componentComplete
- setThemeGradient
- convertGradient
- convertGradient
- addColor
- colorList
- clearColors
- clearDummyColors
- addGradient
- gradientList
- clearGradients
- clearDummyGradients
- baseColors
- appendBaseColorsFunc
- countBaseColorsFunc
- atBaseColorsFunc
- clearBaseColorsFunc
- baseGradients
- appendBaseGradientsFunc
- countBaseGradientsFunc
- atBaseGradientsFunc
Learn to use CMake with our Intro Training
Find out more