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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
117
118
119
120
121
122
123
124
125
126
129
130
131
132
133
134
135
136
137
138
141
142
143
144
145
146
147
148
149
150
153
154
155
156
157
158
159
160
161
162
165
166
167
168
169
170
171
172
173
174
177
178
179
180
181
182
183
184
185
186
189
190
191
192
193
194
195
196
197
198
201
202
203
204
205
206
207
208
209
212
213
214
215
216
217
218
219
220
221
222
223
224
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
246using namespace Qt::StringLiterals;
259 if (t->isDefined(QQSK::Property::Bold)) {
260 sig |= (quint64(1) << 0);
261 if (t->styleProperty<
bool>(QQSK::Property::Bold))
262 sig |= (quint64(1) << 1);
265 if (t->isDefined(QQSK::Property::Italic)) {
266 sig |= (quint64(1) << 2);
267 if (t->styleProperty<
bool>(QQSK::Property::Italic))
268 sig |= (quint64(1) << 3);
271 if (t->isDefined(QQSK::Property::PointSize)) {
272 sig |= (quint64(1) << 4);
273 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
275 constexpr int payloadBits = 64 - 5;
276 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
277 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
283QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
284QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
286QQStyleKitReader::QQStyleKitReader(QObject *parent)
287 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
288 , m_dontEmitChangedSignals(
false)
289 , m_effectiveVariationsDirty(
true)
290 , m_transitionsEnabled(
true)
292 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
296QQStyleKitReader::~QQStyleKitReader()
298 s_allReaders.removeOne(
this);
301QQuickStateGroup *QQStyleKitReader::stateGroup()
307
308
309
310 const auto *stylePtr = style();
313 m_stateGroup =
new QQuickStateGroup(
this);
316 auto statesProp = m_stateGroup->statesProperty();
317 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
318 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
319 alternate1->setName(kAlternate1);
320 alternate2->setName(kAlternate2);
321 m_stateGroup->statesProperty().append(&statesProp, alternate1);
322 m_stateGroup->statesProperty().append(&statesProp, alternate2);
324 QQmlComponent *controlComp = createControlChangesComponent();
325 instantiatePropertyChanges(controlComp);
330QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
332 QQmlEngine *engine = qmlEngine(style());
333 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
334 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
337 const QString qmlControlCode = QString::fromUtf8(R"(
338 import QtQuick
339 PropertyChanges {
340 spacing: global.spacing
341 padding: global.padding
342 leftPadding: global.leftPadding
343 rightPadding: global.rightPadding
344 topPadding: global.topPadding
345 bottomPadding: global.bottomPadding
346 text.color: global.text.color
347 text.alignment: global.text.alignment
348 text.bold: global.text.bold
349 text.italic: global.text.italic
350 text.pointSize: global.text.pointSize
351 text.padding: global.text.padding
352 text.leftPadding: global.text.leftPadding
353 text.rightPadding: global.text.rightPadding
354 text.topPadding: global.text.topPadding
355 text.bottomPadding: global.text.bottomPadding
356 }
357 )");
360 QQmlComponent *component =
new QQmlComponent(engine, engine);
361 component->setData(qmlControlCode.toUtf8(), QUrl());
362 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
363 s_propertyChangesComponents.insert(key, component);
364 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
365 s_propertyChangesComponents.remove(key);
370QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
372 QQmlEngine *engine = qmlEngine(style());
373 auto key = PropertyChangesComponents::key_type{engine, delegateName};
374 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
377 static const QString qmlTemplateCode = QString::fromUtf8(R"(
378 import QtQuick
379 PropertyChanges { $ {
380 width: global.$.width
381 height: global.$.height
382 visible: global.$.visible
383 color: global.$.color
384 gradient: global.$.gradient
385 radius: global.$.radius
386 topLeftRadius: global.$.topLeftRadius
387 topRightRadius: global.$.topRightRadius
388 bottomLeftRadius: global.$.bottomLeftRadius
389 bottomRightRadius: global.$.bottomRightRadius
390 margins: global.$.margins
391 alignment: global.$.alignment
392 leftMargin: global.$.leftMargin
393 rightMargin: global.$.rightMargin
394 topMargin: global.$.topMargin
395 bottomMargin: global.$.bottomMargin
396 scale: global.$.scale
397 rotation: global.$.rotation
398 opacity: global.$.opacity
399 border.color: global.$.border.color
400 border.width: global.$.border.width
401 shadow.color: global.$.shadow.color
402 shadow.scale: global.$.shadow.scale
403 shadow.blur: global.$.shadow.blur
404 shadow.visible: global.$.shadow.visible
405 shadow.opacity: global.$.shadow.opacity
406 shadow.verticalOffset: global.$.shadow.verticalOffset
407 shadow.horizontalOffset: global.$.shadow.horizontalOffset
408 shadow.delegate: global.$.shadow.delegate
409 image.source: global.$.image.source
410 image.color: global.$.image.color
411 image.fillMode: global.$.image.fillMode
412 delegate: global.$.delegate
413 data: global.$.data
414 }}
415 )");
417 QString substitutedCode = qmlTemplateCode;
418 substitutedCode.replace(
'$'_L1, delegateName);
419 QQmlComponent *component =
new QQmlComponent(engine, engine);
420 component->setData(substitutedCode.toUtf8(), QUrl());
421 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
422 s_propertyChangesComponents.insert(key, component);
423 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
424 s_propertyChangesComponents.remove(key);
429void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
431 QObject *obj = comp->create(qmlContext(
this));
432 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
433 Q_ASSERT(propertyChanges);
436 propertyChanges->setObject(
this);
438
439
440
441
442
443 propertyChanges->setIsExplicit(
true);
445
446
447 propertyChanges->setRestoreEntryValues(
false);
450 for (QQuickState *state : stateGroup()->states()) {
451 auto changesProp = state->changes();
452 changesProp.append(&changesProp, propertyChanges);
456void QQStyleKitReader::maybeTrackDelegates()
459 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
460 if (m_trackedDelegates.testFlag(type)) {
464 if (!delegate->visible()) {
466
467
471
472
473
474
475 m_trackedDelegates.setFlag(type);
476 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
477 instantiatePropertyChanges(comp);
481void QQStyleKitReader::updateControl(
bool applyStateChange)
483 const QQStyleKitStyle *currentStyle = style();
484 if (!m_completed || !currentStyle || !currentStyle->loaded())
487 if (applyStateChange) {
489
490
491
492
493
494
495
496
497
498
499
501 maybeTrackDelegates();
503 auto transitionProp = stateGroup()->transitionsProperty();
504 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
505 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
506 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
507 QQuickTransition *transitionInStateGroup =
508 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
509 if (transitionInStyle != transitionInStateGroup) {
510 transitionProp.clear(&transitionProp);
511 if (transitionInStyle)
512 transitionProp.append(&transitionProp, transitionInStyle);
515 switch (m_alternateState) {
516 case AlternateState::Alternate1:
517 m_alternateState = AlternateState::Alternate2;
518 stateGroup()->setState(kAlternate2);
520 case AlternateState::Alternate2:
521 m_alternateState = AlternateState::Alternate1;
522 stateGroup()->setState(kAlternate1);
535 auto textOverrideSig = textFontOverridesSignature(global()->text());
536 if (m_lastTextFontOverridesSignature != textOverrideSig)
538 m_lastTextFontOverridesSignature = textOverrideSig;
539 rebuildEffectiveFont();
542void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
544 for (QQStyleKitReader *reader : s_allReaders) {
545 if (reader->style() == style) {
546 reader->m_effectiveVariationsDirty =
true;
547 reader->m_fontDirty =
true;
548 reader->clearLocalStorage();
549 reader->rebuildEffectivePalette();
550 reader->rebuildEffectiveFont();
551 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
556void QQStyleKitReader::populateLocalStorage()
560
561
567 if (!m_storage.isEmpty())
569 const auto *stylePtr = style();
570 if (!stylePtr || !stylePtr->loaded())
574
575
576
581
583
584
585
586
587 m_dontEmitChangedSignals =
true;
589 m_dontEmitChangedSignals =
false;
592void QQStyleKitReader::clearLocalStorage()
595
596
597
601QQSK::State QQStyleKitReader::controlState()
const
603 QQSK::State effectiveState = m_state;
607 effectiveState &= ~(QQSK::StateFlag::Pressed |
608 QQSK::StateFlag::Hovered |
609 QQSK::StateFlag::Highlighted |
610 QQSK::StateFlag::Focused |
611 QQSK::StateFlag::Hovered);
614 if (effectiveState == QQSK::StateFlag::Unspecified)
615 effectiveState.setFlag(QQSK::StateFlag::Normal);
617 return effectiveState;
620QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
622 return m_storage.value(key);
625void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
627 m_storage.insert(key, value);
630bool QQStyleKitReader::dontEmitChangedSignals()
const
632 return m_dontEmitChangedSignals;
635QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
640void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
646 populateLocalStorage();
647 emit controlTypeChanged();
652QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
655
657 return ControlType(m_type);
661bool QQStyleKitReader::hovered()
const
663 return m_state.testFlag(QQSK::StateFlag::Hovered);
666void QQStyleKitReader::setHovered(
bool hovered)
668 if (hovered == QQStyleKitReader::hovered())
671 populateLocalStorage();
672 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
673 emit hoveredChanged();
677bool QQStyleKitReader::enabled()
const
679 return !m_state.testFlag(QQSK::StateFlag::Disabled);
682void QQStyleKitReader::setEnabled(
bool enabled)
684 if (enabled == QQStyleKitReader::enabled())
687 populateLocalStorage();
688 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
689 emit enabledChanged();
693bool QQStyleKitReader::focused()
const
695 return m_state.testFlag(QQSK::StateFlag::Focused);
698void QQStyleKitReader::setFocused(
bool focused)
700 if (focused == QQStyleKitReader::focused())
703 populateLocalStorage();
704 m_state.setFlag(QQSK::StateFlag::Focused, focused);
705 emit focusedChanged();
709bool QQStyleKitReader::checked()
const
711 return m_state.testFlag(QQSK::StateFlag::Checked);
714void QQStyleKitReader::setChecked(
bool checked)
716 if (checked == QQStyleKitReader::checked())
719 populateLocalStorage();
720 m_state.setFlag(QQSK::StateFlag::Checked, checked);
721 emit checkedChanged();
725bool QQStyleKitReader::pressed()
const
727 return m_state.testFlag(QQSK::StateFlag::Pressed);
730void QQStyleKitReader::setPressed(
bool pressed)
732 if (pressed == QQStyleKitReader::pressed())
735 populateLocalStorage();
736 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
737 emit pressedChanged();
741bool QQStyleKitReader::vertical()
const
743 return m_state.testFlag(QQSK::StateFlag::Vertical);
746void QQStyleKitReader::setVertical(
bool vertical)
748 if (vertical == QQStyleKitReader::vertical())
751 populateLocalStorage();
752 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
753 emit verticalChanged();
757bool QQStyleKitReader::highlighted()
const
759 return m_state.testFlag(QQSK::StateFlag::Highlighted);
762void QQStyleKitReader::setHighlighted(
bool highlighted)
764 if (highlighted == QQStyleKitReader::highlighted())
767 populateLocalStorage();
768 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
769 emit highlightedChanged();
773void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags,
774 bool applyStateChange)
778 const bool typeChanged = m_type != controlType;
779 const QQSK::State stateChanged = m_state ^ flags;
781 if (!typeChanged && !stateChanged)
784 if (applyStateChange)
785 populateLocalStorage();
787 m_type = controlType;
790 updateControl(applyStateChange);
793QObject *QQStyleKitReader::target()
const
795 return m_target.data();
798void QQStyleKitReader::setTarget(QObject *target)
801
802
803
804
808void QQStyleKitReader::setCompleted(
bool completed)
810 const QQStyleKitStyle *currentStyle = style();
811 if (currentStyle && currentStyle->loaded()) {
813 rebuildEffectiveFont();
814 rebuildEffectivePalette();
817
818
819
820
821
822 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
826 s_allReaders.append(
this);
828 m_completed = completed;
831bool QQStyleKitReader::transitionsEnabled()
const
833 return m_transitionsEnabled;
836void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
838 if (m_transitionsEnabled == enabled)
840 m_transitionsEnabled = enabled;
843QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
845 return m_explicitStyle.data();
848void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
850 if (m_explicitStyle == style)
852 m_explicitStyle = style;
854 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
859 m_effectiveVariationsDirty =
true;
862 rebuildEffectivePalette();
863 rebuildEffectiveFont();
864 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
867QQuickPalette *QQStyleKitReader::palette()
const
869 return m_palette.data();
872void QQStyleKitReader::setPalette(QQuickPalette *palette)
874 if (m_palette == palette)
878 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
881 emit paletteChanged();
885 QObject::connect(m_palette, &QQuickPalette::changed,
886 this, &QQStyleKitReader::onPaletteChanged);
892QPalette QQStyleKitReader::effectivePalette()
const
894 return m_effectivePalette;
897void QQStyleKitReader::onPaletteChanged()
899 const QQStyleKitStyle *currentStyle = style();
900 if (!m_completed || !currentStyle || !currentStyle->loaded())
903 if (rebuildEffectivePalette()) {
905 emitChangedForAllStyleProperties(EmitFlag::Colors);
909bool QQStyleKitReader::rebuildEffectivePalette()
911 auto mergedPalette = style()->paletteForControlType(
this->controlType());
912 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
915 const auto controlPalette = m_palette->toQPalette();
916 mergedPalette = controlPalette.resolve(mergedPalette);
919 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
921 if (m_effectivePalette == mergedPalette)
924 m_effectivePalette = mergedPalette;
928QFont QQStyleKitReader::font()
const
933bool QQStyleKitReader::rebuildEffectiveFont()
935 const QQStyleKitStyle *currentStyle = style();
936 if (!currentStyle || !currentStyle->loaded())
942 QFont font = currentStyle->fontForControlType(controlType());
943 const QQStyleKitTextProperties *textProps = global()->text();
945 if (textProps->isDefined(QQSK::Property::Bold))
946 font.setBold(textProps->bold());
947 if (textProps->isDefined(QQSK::Property::Italic))
948 font.setItalic(textProps->italic());
949 if (textProps->isDefined(QQSK::Property::PointSize))
950 font.setPointSizeF(textProps->pointSize());
961QQStyleKitControlProperties *QQStyleKitReader::global()
const
963 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
966void QQStyleKitReader::componentComplete()
973#include "moc_qqstylekitreader_p.cpp"
Combined button and popup list for selecting options.
static quint64 textFontOverridesSignature(const QQStyleKitTextProperties *t)
static constexpr QLatin1StringView kAlternate1
static constexpr QLatin1StringView kAlternate2