4#include <QtQuick/private/qquickpalette_p.h>
5#include <QtQuick/private/qquickwindow_p.h>
6#include <QtQuick/private/qquickstategroup_p.h>
7#include <QtQuick/private/qquickpropertychanges_p.h>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
100
101
102
103
104
105
106
107
108
109
112
113
114
115
116
117
118
119
120
121
124
125
126
127
128
129
130
131
132
133
136
137
138
139
140
141
142
143
144
145
148
149
150
151
152
153
154
155
156
157
160
161
162
163
164
165
166
167
168
169
172
173
174
175
176
177
178
179
180
181
184
185
186
187
188
189
190
191
192
195
196
197
198
199
200
201
202
203
204
205
206
207
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
229using namespace Qt::StringLiterals;
242 if (t->isDefined(QQSK::Property::Bold)) {
243 sig |= (quint64(1) << 0);
244 if (t->styleProperty<
bool>(QQSK::Property::Bold))
245 sig |= (quint64(1) << 1);
248 if (t->isDefined(QQSK::Property::Italic)) {
249 sig |= (quint64(1) << 2);
250 if (t->styleProperty<
bool>(QQSK::Property::Italic))
251 sig |= (quint64(1) << 3);
254 if (t->isDefined(QQSK::Property::PointSize)) {
255 sig |= (quint64(1) << 4);
256 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
258 constexpr int payloadBits = 64 - 5;
259 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
260 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
266QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
267QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
269QQStyleKitReader::QQStyleKitReader(QObject *parent)
270 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
271 , m_dontEmitChangedSignals(
false)
272 , m_effectiveVariationsDirty(
true)
273 , m_transitionsEnabled(
true)
275 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
277 s_allReaders.append(
this);
280QQStyleKitReader::~QQStyleKitReader()
282 s_allReaders.removeOne(
this);
285QQuickStateGroup *QQStyleKitReader::stateGroup()
291
292
293
294 const auto *stylePtr = style();
297 m_stateGroup =
new QQuickStateGroup(
this);
300 auto statesProp = m_stateGroup->statesProperty();
301 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
302 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
303 alternate1->setName(kAlternate1);
304 alternate2->setName(kAlternate2);
305 m_stateGroup->statesProperty().append(&statesProp, alternate1);
306 m_stateGroup->statesProperty().append(&statesProp, alternate2);
308 QQmlComponent *controlComp = createControlChangesComponent();
309 instantiatePropertyChanges(controlComp);
314QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
316 QQmlEngine *engine = qmlEngine(style());
317 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
318 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
321 const QString qmlControlCode = QString::fromUtf8(R"(
322 import QtQuick
323 PropertyChanges {
324 spacing: global.spacing
325 padding: global.padding
326 leftPadding: global.leftPadding
327 rightPadding: global.rightPadding
328 topPadding: global.topPadding
329 bottomPadding: global.bottomPadding
330 text.color: global.text.color
331 text.alignment: global.text.alignment
332 text.bold: global.text.bold
333 text.italic: global.text.italic
334 text.pointSize: global.text.pointSize
335 text.padding: global.text.padding
336 text.leftPadding: global.text.leftPadding
337 text.rightPadding: global.text.rightPadding
338 text.topPadding: global.text.topPadding
339 text.bottomPadding: global.text.bottomPadding
340 }
341 )");
344 QQmlComponent *component =
new QQmlComponent(engine);
345 component->setData(qmlControlCode.toUtf8(), QUrl());
346 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
347 s_propertyChangesComponents.insert(key, component);
348 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
349 s_propertyChangesComponents.remove(key);
354QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
356 QQmlEngine *engine = qmlEngine(style());
357 auto key = PropertyChangesComponents::key_type{engine, delegateName};
358 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
361 static const QString qmlTemplateCode = QString::fromUtf8(R"(
362 import QtQuick
363 PropertyChanges { $ {
364 implicitWidth: global.$.implicitWidth
365 implicitHeight: global.$.implicitHeight
366 visible: global.$.visible
367 color: global.$.color
368 gradient: global.$.gradient
369 radius: global.$.radius
370 topLeftRadius: global.$.topLeftRadius
371 topRightRadius: global.$.topRightRadius
372 bottomLeftRadius: global.$.bottomLeftRadius
373 bottomRightRadius: global.$.bottomRightRadius
374 margins: global.$.margins
375 alignment: global.$.alignment
376 leftMargin: global.$.leftMargin
377 rightMargin: global.$.rightMargin
378 topMargin: global.$.topMargin
379 bottomMargin: global.$.bottomMargin
380 scale: global.$.scale
381 rotation: global.$.rotation
382 opacity: global.$.opacity
383 border.color: global.$.border.color
384 border.width: global.$.border.width
385 shadow.color: global.$.shadow.color
386 shadow.scale: global.$.shadow.scale
387 shadow.blur: global.$.shadow.blur
388 shadow.visible: global.$.shadow.visible
389 shadow.opacity: global.$.shadow.opacity
390 shadow.verticalOffset: global.$.shadow.verticalOffset
391 shadow.horizontalOffset: global.$.shadow.horizontalOffset
392 shadow.delegate: global.$.shadow.delegate
393 image.source: global.$.image.source
394 image.color: global.$.image.color
395 image.fillMode: global.$.image.fillMode
396 delegate: global.$.delegate
397 data: global.$.data
398 }}
399 )");
401 QString substitutedCode = qmlTemplateCode;
402 substitutedCode.replace(
'$'_L1, delegateName);
403 QQmlComponent *component =
new QQmlComponent(engine);
404 component->setData(substitutedCode.toUtf8(), QUrl());
405 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
406 s_propertyChangesComponents.insert(key, component);
407 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
408 s_propertyChangesComponents.remove(key);
413void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
415 QObject *obj = comp->create(qmlContext(
this));
416 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
417 Q_ASSERT(propertyChanges);
420 propertyChanges->setObject(
this);
422
423
424
425
426
427 propertyChanges->setIsExplicit(
true);
429
430
431 propertyChanges->setRestoreEntryValues(
false);
434 for (QQuickState *state : stateGroup()->states()) {
435 auto changesProp = state->changes();
436 changesProp.append(&changesProp, propertyChanges);
440void QQStyleKitReader::maybeTrackDelegates()
443 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
444 if (m_trackedDelegates.testFlag(type)) {
448 if (!delegate->visible()) {
450
451
455
456
457
458
459 m_trackedDelegates.setFlag(type);
460 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
461 instantiatePropertyChanges(comp);
465void QQStyleKitReader::updateControl()
467 const QQStyleKitStyle *currentStyle = style();
468 if (!m_completed || !currentStyle || !currentStyle->loaded())
472
473
474
475
476
477
478
479
480
481
482
484 maybeTrackDelegates();
486 auto transitionProp = stateGroup()->transitionsProperty();
487 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
488 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
489 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
490 QQuickTransition *transitionInStateGroup =
491 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
492 if (transitionInStyle != transitionInStateGroup) {
493 transitionProp.clear(&transitionProp);
494 if (transitionInStyle)
495 transitionProp.append(&transitionProp, transitionInStyle);
498 switch (m_alternateState) {
499 case AlternateState::Alternate1:
500 m_alternateState = AlternateState::Alternate2;
501 stateGroup()->setState(kAlternate2);
503 case AlternateState::Alternate2:
504 m_alternateState = AlternateState::Alternate1;
505 stateGroup()->setState(kAlternate1);
511 auto textOverrideSig = textFontOverridesSignature(global()->text());
512 if (m_lastTextFontOverridesSignature != textOverrideSig)
514 m_lastTextFontOverridesSignature = textOverrideSig;
515 rebuildEffectiveFont();
518void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
520 for (QQStyleKitReader *reader : s_allReaders) {
521 if (reader->style() == style) {
522 reader->m_effectiveVariationsDirty =
true;
523 reader->m_fontDirty =
true;
524 reader->clearLocalStorage();
525 reader->rebuildEffectivePalette();
526 reader->rebuildEffectiveFont();
527 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
532void QQStyleKitReader::populateLocalStorage()
536
537
543 if (!m_storage.isEmpty())
545 const auto *stylePtr = style();
546 if (!stylePtr || !stylePtr->loaded())
550
551
552
557
559
560
561
562
563 m_dontEmitChangedSignals =
true;
565 m_dontEmitChangedSignals =
false;
568void QQStyleKitReader::clearLocalStorage()
571
572
573
577QQSK::State QQStyleKitReader::controlState()
const
579 QQSK::State effectiveState = m_state;
583 effectiveState &= ~(QQSK::StateFlag::Pressed |
584 QQSK::StateFlag::Hovered |
585 QQSK::StateFlag::Highlighted |
586 QQSK::StateFlag::Focused |
587 QQSK::StateFlag::Hovered);
590 if (effectiveState == QQSK::StateFlag::Unspecified)
591 effectiveState.setFlag(QQSK::StateFlag::Normal);
593 return effectiveState;
596QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
598 return m_storage.value(key);
601void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
603 m_storage.insert(key, value);
606bool QQStyleKitReader::dontEmitChangedSignals()
const
608 return m_dontEmitChangedSignals;
611QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
616void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
622 populateLocalStorage();
623 emit controlTypeChanged();
628QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
631
633 return ControlType(m_type);
637bool QQStyleKitReader::hovered()
const
639 return m_state.testFlag(QQSK::StateFlag::Hovered);
642void QQStyleKitReader::setHovered(
bool hovered)
644 if (hovered == QQStyleKitReader::hovered())
647 populateLocalStorage();
648 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
649 emit hoveredChanged();
653bool QQStyleKitReader::enabled()
const
655 return !m_state.testFlag(QQSK::StateFlag::Disabled);
658void QQStyleKitReader::setEnabled(
bool enabled)
660 if (enabled == QQStyleKitReader::enabled())
663 populateLocalStorage();
664 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
665 emit enabledChanged();
669bool QQStyleKitReader::focused()
const
671 return m_state.testFlag(QQSK::StateFlag::Focused);
674void QQStyleKitReader::setFocused(
bool focused)
676 if (focused == QQStyleKitReader::focused())
679 populateLocalStorage();
680 m_state.setFlag(QQSK::StateFlag::Focused, focused);
681 emit focusedChanged();
685bool QQStyleKitReader::checked()
const
687 return m_state.testFlag(QQSK::StateFlag::Checked);
690void QQStyleKitReader::setChecked(
bool checked)
692 if (checked == QQStyleKitReader::checked())
695 populateLocalStorage();
696 m_state.setFlag(QQSK::StateFlag::Checked, checked);
697 emit checkedChanged();
701bool QQStyleKitReader::pressed()
const
703 return m_state.testFlag(QQSK::StateFlag::Pressed);
706void QQStyleKitReader::setPressed(
bool pressed)
708 if (pressed == QQStyleKitReader::pressed())
711 populateLocalStorage();
712 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
713 emit pressedChanged();
717bool QQStyleKitReader::vertical()
const
719 return m_state.testFlag(QQSK::StateFlag::Vertical);
722void QQStyleKitReader::setVertical(
bool vertical)
724 if (vertical == QQStyleKitReader::vertical())
727 populateLocalStorage();
728 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
729 emit verticalChanged();
733bool QQStyleKitReader::highlighted()
const
735 return m_state.testFlag(QQSK::StateFlag::Highlighted);
738void QQStyleKitReader::setHighlighted(
bool highlighted)
740 if (highlighted == QQStyleKitReader::highlighted())
743 populateLocalStorage();
744 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
745 emit highlightedChanged();
749void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
753 const bool typeChanged = m_type != controlType;
754 const QQSK::State stateChanged = m_state ^ flags;
756 if (!typeChanged && !stateChanged)
759 populateLocalStorage();
761 m_type = controlType;
765 emit controlTypeChanged();
767 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
768 if (stateChanged.testFlag(flag))
771 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
772 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
773 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
774 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
775 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
776 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
777 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
782QObject *QQStyleKitReader::target()
const
784 return m_target.data();
787void QQStyleKitReader::setTarget(QObject *target)
790
791
792
793
797bool QQStyleKitReader::transitionsEnabled()
const
799 return m_transitionsEnabled;
802void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
804 if (m_transitionsEnabled == enabled)
806 m_transitionsEnabled = enabled;
809QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
811 return m_explicitStyle.data();
814void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
816 if (m_explicitStyle == style)
818 m_explicitStyle = style;
820 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
825 m_effectiveVariationsDirty =
true;
828 rebuildEffectivePalette();
829 rebuildEffectiveFont();
830 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
833QQuickPalette *QQStyleKitReader::palette()
const
835 return m_palette.data();
838void QQStyleKitReader::setPalette(QQuickPalette *palette)
840 if (m_palette == palette)
844 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
847 emit paletteChanged();
851 QObject::connect(m_palette, &QQuickPalette::changed,
852 this, &QQStyleKitReader::onPaletteChanged);
858QPalette QQStyleKitReader::effectivePalette()
const
860 return m_effectivePalette;
863void QQStyleKitReader::onPaletteChanged()
865 const QQStyleKitStyle *currentStyle = style();
866 if (!currentStyle || !currentStyle->loaded())
869 if (rebuildEffectivePalette()) {
871 emitChangedForAllStyleProperties(EmitFlag::Colors);
875bool QQStyleKitReader::rebuildEffectivePalette()
877 auto mergedPalette = style()->paletteForControlType(
this->controlType());
878 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
881 const auto controlPalette = m_palette->toQPalette();
882 mergedPalette = controlPalette.resolve(mergedPalette);
885 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
887 if (m_effectivePalette == mergedPalette)
890 m_effectivePalette = mergedPalette;
894QFont QQStyleKitReader::font()
const
899bool QQStyleKitReader::rebuildEffectiveFont()
901 const QQStyleKitStyle *currentStyle = style();
902 if (!currentStyle || !currentStyle->loaded())
908 QFont font = currentStyle->fontForControlType(controlType());
909 const QQStyleKitTextProperties *textProps = global()->text();
911 if (textProps->isDefined(QQSK::Property::Bold))
912 font.setBold(textProps->bold());
913 if (textProps->isDefined(QQSK::Property::Italic))
914 font.setItalic(textProps->italic());
915 if (textProps->isDefined(QQSK::Property::PointSize))
916 font.setPointSizeF(textProps->pointSize());
927QQStyleKitControlProperties *QQStyleKitReader::global()
const
929 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
934#include "moc_qqstylekitreader_p.cpp"
Combined button and popup list for selecting options.
static quint64 textFontOverridesSignature(const QQStyleKitTextProperties *t)
static const QString kAlternate2
static const QString kAlternate1