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
110
111
112
113
114
115
116
117
118
119
122
123
124
125
126
127
128
129
130
131
134
135
136
137
138
139
140
141
142
143
146
147
148
149
150
151
152
153
154
155
158
159
160
161
162
163
164
165
166
167
170
171
172
173
174
175
176
177
178
179
182
183
184
185
186
187
188
189
190
191
194
195
196
197
198
199
200
201
202
205
206
207
208
209
210
211
212
213
214
215
216
217
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
239using namespace Qt::StringLiterals;
252 if (t->isDefined(QQSK::Property::Bold)) {
253 sig |= (quint64(1) << 0);
254 if (t->styleProperty<
bool>(QQSK::Property::Bold))
255 sig |= (quint64(1) << 1);
258 if (t->isDefined(QQSK::Property::Italic)) {
259 sig |= (quint64(1) << 2);
260 if (t->styleProperty<
bool>(QQSK::Property::Italic))
261 sig |= (quint64(1) << 3);
264 if (t->isDefined(QQSK::Property::PointSize)) {
265 sig |= (quint64(1) << 4);
266 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
268 constexpr int payloadBits = 64 - 5;
269 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
270 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
276QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
277QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
279QQStyleKitReader::QQStyleKitReader(QObject *parent)
280 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
281 , m_dontEmitChangedSignals(
false)
282 , m_effectiveVariationsDirty(
true)
283 , m_transitionsEnabled(
true)
285 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
287 s_allReaders.append(
this);
290QQStyleKitReader::~QQStyleKitReader()
292 s_allReaders.removeOne(
this);
295QQuickStateGroup *QQStyleKitReader::stateGroup()
301
302
303
304 const auto *stylePtr = style();
307 m_stateGroup =
new QQuickStateGroup(
this);
310 auto statesProp = m_stateGroup->statesProperty();
311 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
312 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
313 alternate1->setName(kAlternate1);
314 alternate2->setName(kAlternate2);
315 m_stateGroup->statesProperty().append(&statesProp, alternate1);
316 m_stateGroup->statesProperty().append(&statesProp, alternate2);
318 QQmlComponent *controlComp = createControlChangesComponent();
319 instantiatePropertyChanges(controlComp);
324QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
326 QQmlEngine *engine = qmlEngine(style());
327 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
328 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
331 const QString qmlControlCode = QString::fromUtf8(R"(
332 import QtQuick
333 PropertyChanges {
334 spacing: global.spacing
335 padding: global.padding
336 leftPadding: global.leftPadding
337 rightPadding: global.rightPadding
338 topPadding: global.topPadding
339 bottomPadding: global.bottomPadding
340 text.color: global.text.color
341 text.alignment: global.text.alignment
342 text.bold: global.text.bold
343 text.italic: global.text.italic
344 text.pointSize: global.text.pointSize
345 text.padding: global.text.padding
346 text.leftPadding: global.text.leftPadding
347 text.rightPadding: global.text.rightPadding
348 text.topPadding: global.text.topPadding
349 text.bottomPadding: global.text.bottomPadding
350 }
351 )");
354 QQmlComponent *component =
new QQmlComponent(engine);
355 component->setData(qmlControlCode.toUtf8(), QUrl());
356 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
357 s_propertyChangesComponents.insert(key, component);
358 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
359 s_propertyChangesComponents.remove(key);
364QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
366 QQmlEngine *engine = qmlEngine(style());
367 auto key = PropertyChangesComponents::key_type{engine, delegateName};
368 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
371 static const QString qmlTemplateCode = QString::fromUtf8(R"(
372 import QtQuick
373 PropertyChanges { $ {
374 width: global.$.width
375 height: global.$.height
376 visible: global.$.visible
377 color: global.$.color
378 gradient: global.$.gradient
379 radius: global.$.radius
380 topLeftRadius: global.$.topLeftRadius
381 topRightRadius: global.$.topRightRadius
382 bottomLeftRadius: global.$.bottomLeftRadius
383 bottomRightRadius: global.$.bottomRightRadius
384 margins: global.$.margins
385 alignment: global.$.alignment
386 leftMargin: global.$.leftMargin
387 rightMargin: global.$.rightMargin
388 topMargin: global.$.topMargin
389 bottomMargin: global.$.bottomMargin
390 scale: global.$.scale
391 rotation: global.$.rotation
392 opacity: global.$.opacity
393 border.color: global.$.border.color
394 border.width: global.$.border.width
395 shadow.color: global.$.shadow.color
396 shadow.scale: global.$.shadow.scale
397 shadow.blur: global.$.shadow.blur
398 shadow.visible: global.$.shadow.visible
399 shadow.opacity: global.$.shadow.opacity
400 shadow.verticalOffset: global.$.shadow.verticalOffset
401 shadow.horizontalOffset: global.$.shadow.horizontalOffset
402 shadow.delegate: global.$.shadow.delegate
403 image.source: global.$.image.source
404 image.color: global.$.image.color
405 image.fillMode: global.$.image.fillMode
406 delegate: global.$.delegate
407 data: global.$.data
408 }}
409 )");
411 QString substitutedCode = qmlTemplateCode;
412 substitutedCode.replace(
'$'_L1, delegateName);
413 QQmlComponent *component =
new QQmlComponent(engine);
414 component->setData(substitutedCode.toUtf8(), QUrl());
415 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
416 s_propertyChangesComponents.insert(key, component);
417 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
418 s_propertyChangesComponents.remove(key);
423void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
425 QObject *obj = comp->create(qmlContext(
this));
426 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
427 Q_ASSERT(propertyChanges);
430 propertyChanges->setObject(
this);
432
433
434
435
436
437 propertyChanges->setIsExplicit(
true);
439
440
441 propertyChanges->setRestoreEntryValues(
false);
444 for (QQuickState *state : stateGroup()->states()) {
445 auto changesProp = state->changes();
446 changesProp.append(&changesProp, propertyChanges);
450void QQStyleKitReader::maybeTrackDelegates()
453 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
454 if (m_trackedDelegates.testFlag(type)) {
458 if (!delegate->visible()) {
460
461
465
466
467
468
469 m_trackedDelegates.setFlag(type);
470 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
471 instantiatePropertyChanges(comp);
475void QQStyleKitReader::updateControl()
477 const QQStyleKitStyle *currentStyle = style();
478 if (!m_completed || !currentStyle || !currentStyle->loaded())
482
483
484
485
486
487
488
489
490
491
492
494 maybeTrackDelegates();
496 auto transitionProp = stateGroup()->transitionsProperty();
497 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
498 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
499 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
500 QQuickTransition *transitionInStateGroup =
501 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
502 if (transitionInStyle != transitionInStateGroup) {
503 transitionProp.clear(&transitionProp);
504 if (transitionInStyle)
505 transitionProp.append(&transitionProp, transitionInStyle);
508 switch (m_alternateState) {
509 case AlternateState::Alternate1:
510 m_alternateState = AlternateState::Alternate2;
511 stateGroup()->setState(kAlternate2);
513 case AlternateState::Alternate2:
514 m_alternateState = AlternateState::Alternate1;
515 stateGroup()->setState(kAlternate1);
521 auto textOverrideSig = textFontOverridesSignature(global()->text());
522 if (m_lastTextFontOverridesSignature != textOverrideSig)
524 m_lastTextFontOverridesSignature = textOverrideSig;
525 rebuildEffectiveFont();
528void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
530 for (QQStyleKitReader *reader : s_allReaders) {
531 if (reader->style() == style) {
532 reader->m_effectiveVariationsDirty =
true;
533 reader->m_fontDirty =
true;
534 reader->clearLocalStorage();
535 reader->rebuildEffectivePalette();
536 reader->rebuildEffectiveFont();
537 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
542void QQStyleKitReader::populateLocalStorage()
546
547
553 if (!m_storage.isEmpty())
555 const auto *stylePtr = style();
556 if (!stylePtr || !stylePtr->loaded())
560
561
562
567
569
570
571
572
573 m_dontEmitChangedSignals =
true;
575 m_dontEmitChangedSignals =
false;
578void QQStyleKitReader::clearLocalStorage()
581
582
583
587QQSK::State QQStyleKitReader::controlState()
const
589 QQSK::State effectiveState = m_state;
593 effectiveState &= ~(QQSK::StateFlag::Pressed |
594 QQSK::StateFlag::Hovered |
595 QQSK::StateFlag::Highlighted |
596 QQSK::StateFlag::Focused |
597 QQSK::StateFlag::Hovered);
600 if (effectiveState == QQSK::StateFlag::Unspecified)
601 effectiveState.setFlag(QQSK::StateFlag::Normal);
603 return effectiveState;
606QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
608 return m_storage.value(key);
611void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
613 m_storage.insert(key, value);
616bool QQStyleKitReader::dontEmitChangedSignals()
const
618 return m_dontEmitChangedSignals;
621QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
626void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
632 populateLocalStorage();
633 emit controlTypeChanged();
638QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
641
643 return ControlType(m_type);
647bool QQStyleKitReader::hovered()
const
649 return m_state.testFlag(QQSK::StateFlag::Hovered);
652void QQStyleKitReader::setHovered(
bool hovered)
654 if (hovered == QQStyleKitReader::hovered())
657 populateLocalStorage();
658 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
659 emit hoveredChanged();
663bool QQStyleKitReader::enabled()
const
665 return !m_state.testFlag(QQSK::StateFlag::Disabled);
668void QQStyleKitReader::setEnabled(
bool enabled)
670 if (enabled == QQStyleKitReader::enabled())
673 populateLocalStorage();
674 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
675 emit enabledChanged();
679bool QQStyleKitReader::focused()
const
681 return m_state.testFlag(QQSK::StateFlag::Focused);
684void QQStyleKitReader::setFocused(
bool focused)
686 if (focused == QQStyleKitReader::focused())
689 populateLocalStorage();
690 m_state.setFlag(QQSK::StateFlag::Focused, focused);
691 emit focusedChanged();
695bool QQStyleKitReader::checked()
const
697 return m_state.testFlag(QQSK::StateFlag::Checked);
700void QQStyleKitReader::setChecked(
bool checked)
702 if (checked == QQStyleKitReader::checked())
705 populateLocalStorage();
706 m_state.setFlag(QQSK::StateFlag::Checked, checked);
707 emit checkedChanged();
711bool QQStyleKitReader::pressed()
const
713 return m_state.testFlag(QQSK::StateFlag::Pressed);
716void QQStyleKitReader::setPressed(
bool pressed)
718 if (pressed == QQStyleKitReader::pressed())
721 populateLocalStorage();
722 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
723 emit pressedChanged();
727bool QQStyleKitReader::vertical()
const
729 return m_state.testFlag(QQSK::StateFlag::Vertical);
732void QQStyleKitReader::setVertical(
bool vertical)
734 if (vertical == QQStyleKitReader::vertical())
737 populateLocalStorage();
738 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
739 emit verticalChanged();
743bool QQStyleKitReader::highlighted()
const
745 return m_state.testFlag(QQSK::StateFlag::Highlighted);
748void QQStyleKitReader::setHighlighted(
bool highlighted)
750 if (highlighted == QQStyleKitReader::highlighted())
753 populateLocalStorage();
754 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
755 emit highlightedChanged();
759void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
763 const bool typeChanged = m_type != controlType;
764 const QQSK::State stateChanged = m_state ^ flags;
766 if (!typeChanged && !stateChanged)
769 populateLocalStorage();
771 m_type = controlType;
775 emit controlTypeChanged();
777 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
778 if (stateChanged.testFlag(flag))
781 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
782 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
783 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
784 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
785 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
786 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
787 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
792QObject *QQStyleKitReader::target()
const
794 return m_target.data();
797void QQStyleKitReader::setTarget(QObject *target)
800
801
802
803
807void QQStyleKitReader::setCompleted(
bool completed)
809 m_completed = completed;
812bool QQStyleKitReader::transitionsEnabled()
const
814 return m_transitionsEnabled;
817void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
819 if (m_transitionsEnabled == enabled)
821 m_transitionsEnabled = enabled;
824QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
826 return m_explicitStyle.data();
829void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
831 if (m_explicitStyle == style)
833 m_explicitStyle = style;
835 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
840 m_effectiveVariationsDirty =
true;
843 rebuildEffectivePalette();
844 rebuildEffectiveFont();
845 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
848QQuickPalette *QQStyleKitReader::palette()
const
850 return m_palette.data();
853void QQStyleKitReader::setPalette(QQuickPalette *palette)
855 if (m_palette == palette)
859 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
862 emit paletteChanged();
866 QObject::connect(m_palette, &QQuickPalette::changed,
867 this, &QQStyleKitReader::onPaletteChanged);
873QPalette QQStyleKitReader::effectivePalette()
const
875 return m_effectivePalette;
878void QQStyleKitReader::onPaletteChanged()
880 const QQStyleKitStyle *currentStyle = style();
881 if (!currentStyle || !currentStyle->loaded())
884 if (rebuildEffectivePalette()) {
886 emitChangedForAllStyleProperties(EmitFlag::Colors);
890bool QQStyleKitReader::rebuildEffectivePalette()
892 auto mergedPalette = style()->paletteForControlType(
this->controlType());
893 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
896 const auto controlPalette = m_palette->toQPalette();
897 mergedPalette = controlPalette.resolve(mergedPalette);
900 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
902 if (m_effectivePalette == mergedPalette)
905 m_effectivePalette = mergedPalette;
909QFont QQStyleKitReader::font()
const
914bool QQStyleKitReader::rebuildEffectiveFont()
916 const QQStyleKitStyle *currentStyle = style();
917 if (!currentStyle || !currentStyle->loaded())
923 QFont font = currentStyle->fontForControlType(controlType());
924 const QQStyleKitTextProperties *textProps = global()->text();
926 if (textProps->isDefined(QQSK::Property::Bold))
927 font.setBold(textProps->bold());
928 if (textProps->isDefined(QQSK::Property::Italic))
929 font.setItalic(textProps->italic());
930 if (textProps->isDefined(QQSK::Property::PointSize))
931 font.setPointSizeF(textProps->pointSize());
942QQStyleKitControlProperties *QQStyleKitReader::global()
const
944 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
947void QQStyleKitReader::componentComplete()
954#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