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
115
118
119
120
121
122
123
124
125
126
127
130
131
132
133
134
135
136
137
138
139
142
143
144
145
146
147
148
149
150
151
154
155
156
157
158
159
160
161
162
163
166
167
168
169
170
171
172
173
174
175
178
179
180
181
182
183
184
185
186
187
190
191
192
193
194
195
196
197
198
199
202
203
204
205
206
207
208
209
210
213
214
215
216
217
218
219
220
221
222
223
224
225
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
247using namespace Qt::StringLiterals;
260 if (t->isDefined(QQSK::Property::Bold)) {
261 sig |= (quint64(1) << 0);
262 if (t->styleProperty<
bool>(QQSK::Property::Bold))
263 sig |= (quint64(1) << 1);
266 if (t->isDefined(QQSK::Property::Italic)) {
267 sig |= (quint64(1) << 2);
268 if (t->styleProperty<
bool>(QQSK::Property::Italic))
269 sig |= (quint64(1) << 3);
272 if (t->isDefined(QQSK::Property::PointSize)) {
273 sig |= (quint64(1) << 4);
274 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
276 constexpr int payloadBits = 64 - 5;
277 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
278 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
284QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
285QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
287QQStyleKitReader::QQStyleKitReader(QObject *parent)
288 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
289 , m_dontEmitChangedSignals(
false)
290 , m_effectiveVariationsDirty(
true)
291 , m_transitionsEnabled(
true)
293 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
297QQStyleKitReader::~QQStyleKitReader()
299 s_allReaders.removeOne(
this);
302QQuickStateGroup *QQStyleKitReader::stateGroup()
308
309
310
311 const auto *stylePtr = style();
314 m_stateGroup =
new QQuickStateGroup(
this);
317 auto statesProp = m_stateGroup->statesProperty();
318 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
319 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
320 alternate1->setName(kAlternate1);
321 alternate2->setName(kAlternate2);
322 m_stateGroup->statesProperty().append(&statesProp, alternate1);
323 m_stateGroup->statesProperty().append(&statesProp, alternate2);
325 QQmlComponent *controlComp = createControlChangesComponent();
326 instantiatePropertyChanges(controlComp);
331QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
333 QQmlEngine *engine = qmlEngine(style());
334 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
335 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
338 const QString qmlControlCode = QString::fromUtf8(R"(
339 import QtQuick
340 PropertyChanges {
341 spacing: global.spacing
342 padding: global.padding
343 leftPadding: global.leftPadding
344 rightPadding: global.rightPadding
345 topPadding: global.topPadding
346 bottomPadding: global.bottomPadding
347 text.color: global.text.color
348 text.alignment: global.text.alignment
349 text.bold: global.text.bold
350 text.italic: global.text.italic
351 text.pointSize: global.text.pointSize
352 text.padding: global.text.padding
353 text.leftPadding: global.text.leftPadding
354 text.rightPadding: global.text.rightPadding
355 text.topPadding: global.text.topPadding
356 text.bottomPadding: global.text.bottomPadding
357 }
358 )");
361 QQmlComponent *component =
new QQmlComponent(engine, engine);
362 component->setData(qmlControlCode.toUtf8(), QUrl());
363 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
364 s_propertyChangesComponents.insert(key, component);
365 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
366 s_propertyChangesComponents.remove(key);
371QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
373 QQmlEngine *engine = qmlEngine(style());
374 auto key = PropertyChangesComponents::key_type{engine, delegateName};
375 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
378 static const QString qmlTemplateCode = QString::fromUtf8(R"(
379 import QtQuick
380 PropertyChanges { $ {
381 width: global.$.width
382 height: global.$.height
383 visible: global.$.visible
384 color: global.$.color
385 gradient: global.$.gradient
386 radius: global.$.radius
387 topLeftRadius: global.$.topLeftRadius
388 topRightRadius: global.$.topRightRadius
389 bottomLeftRadius: global.$.bottomLeftRadius
390 bottomRightRadius: global.$.bottomRightRadius
391 margins: global.$.margins
392 alignment: global.$.alignment
393 leftMargin: global.$.leftMargin
394 rightMargin: global.$.rightMargin
395 topMargin: global.$.topMargin
396 bottomMargin: global.$.bottomMargin
397 scale: global.$.scale
398 rotation: global.$.rotation
399 opacity: global.$.opacity
400 border.color: global.$.border.color
401 border.width: global.$.border.width
402 shadow.color: global.$.shadow.color
403 shadow.scale: global.$.shadow.scale
404 shadow.blur: global.$.shadow.blur
405 shadow.visible: global.$.shadow.visible
406 shadow.opacity: global.$.shadow.opacity
407 shadow.verticalOffset: global.$.shadow.verticalOffset
408 shadow.horizontalOffset: global.$.shadow.horizontalOffset
409 shadow.delegate: global.$.shadow.delegate
410 image.source: global.$.image.source
411 image.color: global.$.image.color
412 image.fillMode: global.$.image.fillMode
413 delegate: global.$.delegate
414 data: global.$.data
415 }}
416 )");
418 QString substitutedCode = qmlTemplateCode;
419 substitutedCode.replace(
'$'_L1, delegateName);
420 QQmlComponent *component =
new QQmlComponent(engine, engine);
421 component->setData(substitutedCode.toUtf8(), QUrl());
422 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
423 s_propertyChangesComponents.insert(key, component);
424 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
425 s_propertyChangesComponents.remove(key);
430void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
432 QObject *obj = comp->create(qmlContext(
this));
433 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
434 Q_ASSERT(propertyChanges);
437 propertyChanges->setObject(
this);
439
440
441
442
443
444 propertyChanges->setIsExplicit(
true);
446
447
448 propertyChanges->setRestoreEntryValues(
false);
451 for (QQuickState *state : stateGroup()->states()) {
452 auto changesProp = state->changes();
453 changesProp.append(&changesProp, propertyChanges);
457void QQStyleKitReader::maybeTrackDelegates()
460 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
461 if (m_trackedDelegates.testFlag(type)) {
465 if (!delegate->visible()) {
467
468
472
473
474
475
476 m_trackedDelegates.setFlag(type);
477 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
478 instantiatePropertyChanges(comp);
482void QQStyleKitReader::updateControl(
bool applyStateChange)
484 const QQStyleKitStyle *currentStyle = style();
485 if (!m_completed || !currentStyle || !currentStyle->loaded())
488 if (applyStateChange) {
490
491
492
493
494
495
496
497
498
499
500
502 maybeTrackDelegates();
504 auto transitionProp = stateGroup()->transitionsProperty();
505 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
506 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
507 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
508 QQuickTransition *transitionInStateGroup =
509 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
510 if (transitionInStyle != transitionInStateGroup) {
511 transitionProp.clear(&transitionProp);
512 if (transitionInStyle)
513 transitionProp.append(&transitionProp, transitionInStyle);
516 switch (m_alternateState) {
517 case AlternateState::Alternate1:
518 m_alternateState = AlternateState::Alternate2;
519 stateGroup()->setState(kAlternate2);
521 case AlternateState::Alternate2:
522 m_alternateState = AlternateState::Alternate1;
523 stateGroup()->setState(kAlternate1);
536 auto textOverrideSig = textFontOverridesSignature(global()->text());
537 if (m_lastTextFontOverridesSignature != textOverrideSig)
539 m_lastTextFontOverridesSignature = textOverrideSig;
540 rebuildEffectiveFont();
543void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
545 for (QQStyleKitReader *reader : s_allReaders) {
546 if (reader->style() == style) {
547 reader->m_effectiveVariationsDirty =
true;
548 reader->m_fontDirty =
true;
549 reader->clearLocalStorage();
550 reader->rebuildEffectivePalette();
551 reader->rebuildEffectiveFont();
552 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
557void QQStyleKitReader::populateLocalStorage()
561
562
568 if (!m_storage.isEmpty())
570 const auto *stylePtr = style();
571 if (!stylePtr || !stylePtr->loaded())
575
576
577
582
584
585
586
587
588 m_dontEmitChangedSignals =
true;
590 m_dontEmitChangedSignals =
false;
593void QQStyleKitReader::clearLocalStorage()
596
597
598
602QQSK::State QQStyleKitReader::controlState()
const
604 QQSK::State effectiveState = m_state;
608 effectiveState &= ~(QQSK::StateFlag::Pressed |
609 QQSK::StateFlag::Hovered |
610 QQSK::StateFlag::Highlighted |
611 QQSK::StateFlag::Focused |
612 QQSK::StateFlag::Hovered);
615 if (effectiveState == QQSK::StateFlag::Unspecified)
616 effectiveState.setFlag(QQSK::StateFlag::Normal);
618 return effectiveState;
621QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
623 return m_storage.value(key);
626void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
628 m_storage.insert(key, value);
631bool QQStyleKitReader::dontEmitChangedSignals()
const
633 return m_dontEmitChangedSignals;
636QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
641void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
647 populateLocalStorage();
648 emit controlTypeChanged();
653QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
656
658 return ControlType(m_type);
662bool QQStyleKitReader::hovered()
const
664 return m_state.testFlag(QQSK::StateFlag::Hovered);
667void QQStyleKitReader::setHovered(
bool hovered)
669 if (hovered == QQStyleKitReader::hovered())
672 populateLocalStorage();
673 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
674 emit hoveredChanged();
678bool QQStyleKitReader::enabled()
const
680 return !m_state.testFlag(QQSK::StateFlag::Disabled);
683void QQStyleKitReader::setEnabled(
bool enabled)
685 if (enabled == QQStyleKitReader::enabled())
688 populateLocalStorage();
689 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
690 emit enabledChanged();
694bool QQStyleKitReader::focused()
const
696 return m_state.testFlag(QQSK::StateFlag::Focused);
699void QQStyleKitReader::setFocused(
bool focused)
701 if (focused == QQStyleKitReader::focused())
704 populateLocalStorage();
705 m_state.setFlag(QQSK::StateFlag::Focused, focused);
706 emit focusedChanged();
710bool QQStyleKitReader::checked()
const
712 return m_state.testFlag(QQSK::StateFlag::Checked);
715void QQStyleKitReader::setChecked(
bool checked)
717 if (checked == QQStyleKitReader::checked())
720 populateLocalStorage();
721 m_state.setFlag(QQSK::StateFlag::Checked, checked);
722 emit checkedChanged();
726bool QQStyleKitReader::pressed()
const
728 return m_state.testFlag(QQSK::StateFlag::Pressed);
731void QQStyleKitReader::setPressed(
bool pressed)
733 if (pressed == QQStyleKitReader::pressed())
736 populateLocalStorage();
737 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
738 emit pressedChanged();
742bool QQStyleKitReader::vertical()
const
744 return m_state.testFlag(QQSK::StateFlag::Vertical);
747void QQStyleKitReader::setVertical(
bool vertical)
749 if (vertical == QQStyleKitReader::vertical())
752 populateLocalStorage();
753 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
754 emit verticalChanged();
758bool QQStyleKitReader::highlighted()
const
760 return m_state.testFlag(QQSK::StateFlag::Highlighted);
763void QQStyleKitReader::setHighlighted(
bool highlighted)
765 if (highlighted == QQStyleKitReader::highlighted())
768 populateLocalStorage();
769 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
770 emit highlightedChanged();
774void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags,
775 bool applyStateChange)
779 const bool typeChanged = m_type != controlType;
780 const QQSK::State stateChanged = m_state ^ flags;
782 if (!typeChanged && !stateChanged)
785 if (applyStateChange)
786 populateLocalStorage();
788 m_type = controlType;
791 updateControl(applyStateChange);
794QObject *QQStyleKitReader::target()
const
796 return m_target.data();
799void QQStyleKitReader::setTarget(QObject *target)
802
803
804
805
809void QQStyleKitReader::setCompleted(
bool completed)
811 const QQStyleKitStyle *currentStyle = style();
812 if (currentStyle && currentStyle->loaded()) {
814 rebuildEffectiveFont();
815 rebuildEffectivePalette();
818
819
820
821
822
823 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
827 s_allReaders.append(
this);
829 m_completed = completed;
832bool QQStyleKitReader::transitionsEnabled()
const
834 return m_transitionsEnabled;
837void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
839 if (m_transitionsEnabled == enabled)
841 m_transitionsEnabled = enabled;
844QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
846 return m_explicitStyle.data();
849void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
851 if (m_explicitStyle == style)
853 m_explicitStyle = style;
855 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
860 m_effectiveVariationsDirty =
true;
863 rebuildEffectivePalette();
864 rebuildEffectiveFont();
865 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
868QQuickPalette *QQStyleKitReader::palette()
const
870 return m_palette.data();
873void QQStyleKitReader::setPalette(QQuickPalette *palette)
875 if (m_palette == palette)
879 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
882 emit paletteChanged();
886 QObject::connect(m_palette, &QQuickPalette::changed,
887 this, &QQStyleKitReader::onPaletteChanged);
893QPalette QQStyleKitReader::effectivePalette()
const
895 return m_effectivePalette;
898void QQStyleKitReader::onPaletteChanged()
900 const QQStyleKitStyle *currentStyle = style();
901 if (!m_completed || !currentStyle || !currentStyle->loaded())
904 if (rebuildEffectivePalette()) {
906 emitChangedForAllStyleProperties(EmitFlag::Colors);
910bool QQStyleKitReader::rebuildEffectivePalette()
912 auto mergedPalette = style()->paletteForControlType(
this->controlType());
913 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
916 const auto controlPalette = m_palette->toQPalette();
917 mergedPalette = controlPalette.resolve(mergedPalette);
920 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
922 if (m_effectivePalette == mergedPalette)
925 m_effectivePalette = mergedPalette;
929QFont QQStyleKitReader::font()
const
934bool QQStyleKitReader::rebuildEffectiveFont()
936 const QQStyleKitStyle *currentStyle = style();
937 if (!currentStyle || !currentStyle->loaded())
943 QFont font = currentStyle->fontForControlType(controlType());
944 const QQStyleKitTextProperties *textProps = global()->text();
946 if (textProps->isDefined(QQSK::Property::Bold))
947 font.setBold(textProps->bold());
948 if (textProps->isDefined(QQSK::Property::Italic))
949 font.setItalic(textProps->italic());
950 if (textProps->isDefined(QQSK::Property::PointSize))
951 font.setPointSizeF(textProps->pointSize());
962QQStyleKitControlProperties *QQStyleKitReader::global()
const
964 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
967void QQStyleKitReader::componentComplete()
974#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