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
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
201
202
203
204
205
206
207
208
209
210
211
212
213
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235using namespace Qt::StringLiterals;
248 if (t->isDefined(QQSK::Property::Bold)) {
249 sig |= (quint64(1) << 0);
250 if (t->styleProperty<
bool>(QQSK::Property::Bold))
251 sig |= (quint64(1) << 1);
254 if (t->isDefined(QQSK::Property::Italic)) {
255 sig |= (quint64(1) << 2);
256 if (t->styleProperty<
bool>(QQSK::Property::Italic))
257 sig |= (quint64(1) << 3);
260 if (t->isDefined(QQSK::Property::PointSize)) {
261 sig |= (quint64(1) << 4);
262 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
264 constexpr int payloadBits = 64 - 5;
265 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
266 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
272QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
273QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
275QQStyleKitReader::QQStyleKitReader(QObject *parent)
276 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
277 , m_dontEmitChangedSignals(
false)
278 , m_effectiveVariationsDirty(
true)
279 , m_transitionsEnabled(
true)
281 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
283 s_allReaders.append(
this);
286QQStyleKitReader::~QQStyleKitReader()
288 s_allReaders.removeOne(
this);
291QQuickStateGroup *QQStyleKitReader::stateGroup()
297
298
299
300 const auto *stylePtr = style();
303 m_stateGroup =
new QQuickStateGroup(
this);
306 auto statesProp = m_stateGroup->statesProperty();
307 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
308 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
309 alternate1->setName(kAlternate1);
310 alternate2->setName(kAlternate2);
311 m_stateGroup->statesProperty().append(&statesProp, alternate1);
312 m_stateGroup->statesProperty().append(&statesProp, alternate2);
314 QQmlComponent *controlComp = createControlChangesComponent();
315 instantiatePropertyChanges(controlComp);
320QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
322 QQmlEngine *engine = qmlEngine(style());
323 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
324 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
327 const QString qmlControlCode = QString::fromUtf8(R"(
328 import QtQuick
329 PropertyChanges {
330 spacing: global.spacing
331 padding: global.padding
332 leftPadding: global.leftPadding
333 rightPadding: global.rightPadding
334 topPadding: global.topPadding
335 bottomPadding: global.bottomPadding
336 text.color: global.text.color
337 text.alignment: global.text.alignment
338 text.bold: global.text.bold
339 text.italic: global.text.italic
340 text.pointSize: global.text.pointSize
341 text.padding: global.text.padding
342 text.leftPadding: global.text.leftPadding
343 text.rightPadding: global.text.rightPadding
344 text.topPadding: global.text.topPadding
345 text.bottomPadding: global.text.bottomPadding
346 }
347 )");
350 QQmlComponent *component =
new QQmlComponent(engine);
351 component->setData(qmlControlCode.toUtf8(), QUrl());
352 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
353 s_propertyChangesComponents.insert(key, component);
354 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
355 s_propertyChangesComponents.remove(key);
360QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
362 QQmlEngine *engine = qmlEngine(style());
363 auto key = PropertyChangesComponents::key_type{engine, delegateName};
364 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
367 static const QString qmlTemplateCode = QString::fromUtf8(R"(
368 import QtQuick
369 PropertyChanges { $ {
370 width: global.$.width
371 height: global.$.height
372 visible: global.$.visible
373 color: global.$.color
374 gradient: global.$.gradient
375 radius: global.$.radius
376 topLeftRadius: global.$.topLeftRadius
377 topRightRadius: global.$.topRightRadius
378 bottomLeftRadius: global.$.bottomLeftRadius
379 bottomRightRadius: global.$.bottomRightRadius
380 margins: global.$.margins
381 alignment: global.$.alignment
382 leftMargin: global.$.leftMargin
383 rightMargin: global.$.rightMargin
384 topMargin: global.$.topMargin
385 bottomMargin: global.$.bottomMargin
386 scale: global.$.scale
387 rotation: global.$.rotation
388 opacity: global.$.opacity
389 border.color: global.$.border.color
390 border.width: global.$.border.width
391 shadow.color: global.$.shadow.color
392 shadow.scale: global.$.shadow.scale
393 shadow.blur: global.$.shadow.blur
394 shadow.visible: global.$.shadow.visible
395 shadow.opacity: global.$.shadow.opacity
396 shadow.verticalOffset: global.$.shadow.verticalOffset
397 shadow.horizontalOffset: global.$.shadow.horizontalOffset
398 shadow.delegate: global.$.shadow.delegate
399 image.source: global.$.image.source
400 image.color: global.$.image.color
401 image.fillMode: global.$.image.fillMode
402 delegate: global.$.delegate
403 data: global.$.data
404 }}
405 )");
407 QString substitutedCode = qmlTemplateCode;
408 substitutedCode.replace(
'$'_L1, delegateName);
409 QQmlComponent *component =
new QQmlComponent(engine);
410 component->setData(substitutedCode.toUtf8(), QUrl());
411 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
412 s_propertyChangesComponents.insert(key, component);
413 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
414 s_propertyChangesComponents.remove(key);
419void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
421 QObject *obj = comp->create(qmlContext(
this));
422 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
423 Q_ASSERT(propertyChanges);
426 propertyChanges->setObject(
this);
428
429
430
431
432
433 propertyChanges->setIsExplicit(
true);
435
436
437 propertyChanges->setRestoreEntryValues(
false);
440 for (QQuickState *state : stateGroup()->states()) {
441 auto changesProp = state->changes();
442 changesProp.append(&changesProp, propertyChanges);
446void QQStyleKitReader::maybeTrackDelegates()
449 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
450 if (m_trackedDelegates.testFlag(type)) {
454 if (!delegate->visible()) {
456
457
461
462
463
464
465 m_trackedDelegates.setFlag(type);
466 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
467 instantiatePropertyChanges(comp);
471void QQStyleKitReader::updateControl()
473 const QQStyleKitStyle *currentStyle = style();
474 if (!m_completed || !currentStyle || !currentStyle->loaded())
478
479
480
481
482
483
484
485
486
487
488
490 maybeTrackDelegates();
492 auto transitionProp = stateGroup()->transitionsProperty();
493 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
494 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
495 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
496 QQuickTransition *transitionInStateGroup =
497 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
498 if (transitionInStyle != transitionInStateGroup) {
499 transitionProp.clear(&transitionProp);
500 if (transitionInStyle)
501 transitionProp.append(&transitionProp, transitionInStyle);
504 switch (m_alternateState) {
505 case AlternateState::Alternate1:
506 m_alternateState = AlternateState::Alternate2;
507 stateGroup()->setState(kAlternate2);
509 case AlternateState::Alternate2:
510 m_alternateState = AlternateState::Alternate1;
511 stateGroup()->setState(kAlternate1);
517 auto textOverrideSig = textFontOverridesSignature(global()->text());
518 if (m_lastTextFontOverridesSignature != textOverrideSig)
520 m_lastTextFontOverridesSignature = textOverrideSig;
521 rebuildEffectiveFont();
524void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
526 for (QQStyleKitReader *reader : s_allReaders) {
527 if (reader->style() == style) {
528 reader->m_effectiveVariationsDirty =
true;
529 reader->m_fontDirty =
true;
530 reader->clearLocalStorage();
531 reader->rebuildEffectivePalette();
532 reader->rebuildEffectiveFont();
533 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
538void QQStyleKitReader::populateLocalStorage()
542
543
549 if (!m_storage.isEmpty())
551 const auto *stylePtr = style();
552 if (!stylePtr || !stylePtr->loaded())
556
557
558
563
565
566
567
568
569 m_dontEmitChangedSignals =
true;
571 m_dontEmitChangedSignals =
false;
574void QQStyleKitReader::clearLocalStorage()
577
578
579
583QQSK::State QQStyleKitReader::controlState()
const
585 QQSK::State effectiveState = m_state;
589 effectiveState &= ~(QQSK::StateFlag::Pressed |
590 QQSK::StateFlag::Hovered |
591 QQSK::StateFlag::Highlighted |
592 QQSK::StateFlag::Focused |
593 QQSK::StateFlag::Hovered);
596 if (effectiveState == QQSK::StateFlag::Unspecified)
597 effectiveState.setFlag(QQSK::StateFlag::Normal);
599 return effectiveState;
602QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
604 return m_storage.value(key);
607void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
609 m_storage.insert(key, value);
612bool QQStyleKitReader::dontEmitChangedSignals()
const
614 return m_dontEmitChangedSignals;
617QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
622void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
628 populateLocalStorage();
629 emit controlTypeChanged();
634QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
637
639 return ControlType(m_type);
643bool QQStyleKitReader::hovered()
const
645 return m_state.testFlag(QQSK::StateFlag::Hovered);
648void QQStyleKitReader::setHovered(
bool hovered)
650 if (hovered == QQStyleKitReader::hovered())
653 populateLocalStorage();
654 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
655 emit hoveredChanged();
659bool QQStyleKitReader::enabled()
const
661 return !m_state.testFlag(QQSK::StateFlag::Disabled);
664void QQStyleKitReader::setEnabled(
bool enabled)
666 if (enabled == QQStyleKitReader::enabled())
669 populateLocalStorage();
670 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
671 emit enabledChanged();
675bool QQStyleKitReader::focused()
const
677 return m_state.testFlag(QQSK::StateFlag::Focused);
680void QQStyleKitReader::setFocused(
bool focused)
682 if (focused == QQStyleKitReader::focused())
685 populateLocalStorage();
686 m_state.setFlag(QQSK::StateFlag::Focused, focused);
687 emit focusedChanged();
691bool QQStyleKitReader::checked()
const
693 return m_state.testFlag(QQSK::StateFlag::Checked);
696void QQStyleKitReader::setChecked(
bool checked)
698 if (checked == QQStyleKitReader::checked())
701 populateLocalStorage();
702 m_state.setFlag(QQSK::StateFlag::Checked, checked);
703 emit checkedChanged();
707bool QQStyleKitReader::pressed()
const
709 return m_state.testFlag(QQSK::StateFlag::Pressed);
712void QQStyleKitReader::setPressed(
bool pressed)
714 if (pressed == QQStyleKitReader::pressed())
717 populateLocalStorage();
718 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
719 emit pressedChanged();
723bool QQStyleKitReader::vertical()
const
725 return m_state.testFlag(QQSK::StateFlag::Vertical);
728void QQStyleKitReader::setVertical(
bool vertical)
730 if (vertical == QQStyleKitReader::vertical())
733 populateLocalStorage();
734 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
735 emit verticalChanged();
739bool QQStyleKitReader::highlighted()
const
741 return m_state.testFlag(QQSK::StateFlag::Highlighted);
744void QQStyleKitReader::setHighlighted(
bool highlighted)
746 if (highlighted == QQStyleKitReader::highlighted())
749 populateLocalStorage();
750 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
751 emit highlightedChanged();
755void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
759 const bool typeChanged = m_type != controlType;
760 const QQSK::State stateChanged = m_state ^ flags;
762 if (!typeChanged && !stateChanged)
765 populateLocalStorage();
767 m_type = controlType;
771 emit controlTypeChanged();
773 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
774 if (stateChanged.testFlag(flag))
777 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
778 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
779 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
780 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
781 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
782 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
783 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
788QObject *QQStyleKitReader::target()
const
790 return m_target.data();
793void QQStyleKitReader::setTarget(QObject *target)
796
797
798
799
803void QQStyleKitReader::setCompleted(
bool completed)
805 m_completed = completed;
808bool QQStyleKitReader::transitionsEnabled()
const
810 return m_transitionsEnabled;
813void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
815 if (m_transitionsEnabled == enabled)
817 m_transitionsEnabled = enabled;
820QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
822 return m_explicitStyle.data();
825void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
827 if (m_explicitStyle == style)
829 m_explicitStyle = style;
831 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
836 m_effectiveVariationsDirty =
true;
839 rebuildEffectivePalette();
840 rebuildEffectiveFont();
841 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
844QQuickPalette *QQStyleKitReader::palette()
const
846 return m_palette.data();
849void QQStyleKitReader::setPalette(QQuickPalette *palette)
851 if (m_palette == palette)
855 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
858 emit paletteChanged();
862 QObject::connect(m_palette, &QQuickPalette::changed,
863 this, &QQStyleKitReader::onPaletteChanged);
869QPalette QQStyleKitReader::effectivePalette()
const
871 return m_effectivePalette;
874void QQStyleKitReader::onPaletteChanged()
876 const QQStyleKitStyle *currentStyle = style();
877 if (!currentStyle || !currentStyle->loaded())
880 if (rebuildEffectivePalette()) {
882 emitChangedForAllStyleProperties(EmitFlag::Colors);
886bool QQStyleKitReader::rebuildEffectivePalette()
888 auto mergedPalette = style()->paletteForControlType(
this->controlType());
889 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
892 const auto controlPalette = m_palette->toQPalette();
893 mergedPalette = controlPalette.resolve(mergedPalette);
896 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
898 if (m_effectivePalette == mergedPalette)
901 m_effectivePalette = mergedPalette;
905QFont QQStyleKitReader::font()
const
910bool QQStyleKitReader::rebuildEffectiveFont()
912 const QQStyleKitStyle *currentStyle = style();
913 if (!currentStyle || !currentStyle->loaded())
919 QFont font = currentStyle->fontForControlType(controlType());
920 const QQStyleKitTextProperties *textProps = global()->text();
922 if (textProps->isDefined(QQSK::Property::Bold))
923 font.setBold(textProps->bold());
924 if (textProps->isDefined(QQSK::Property::Italic))
925 font.setItalic(textProps->italic());
926 if (textProps->isDefined(QQSK::Property::PointSize))
927 font.setPointSizeF(textProps->pointSize());
938QQStyleKitControlProperties *QQStyleKitReader::global()
const
940 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
943void QQStyleKitReader::componentComplete()
950#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