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
102
103
104
105
106
107
108
109
110
111
114
115
116
117
118
119
120
121
122
123
126
127
128
129
130
131
132
133
134
135
138
139
140
141
142
143
144
145
146
147
150
151
152
153
154
155
156
157
158
159
162
163
164
165
166
167
168
169
170
171
174
175
176
177
178
179
180
181
182
183
186
187
188
189
190
191
192
193
194
197
198
199
200
201
202
203
204
205
206
207
208
209
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
231using namespace Qt::StringLiterals;
244 if (t->isDefined(QQSK::Property::Bold)) {
245 sig |= (quint64(1) << 0);
246 if (t->styleProperty<
bool>(QQSK::Property::Bold))
247 sig |= (quint64(1) << 1);
250 if (t->isDefined(QQSK::Property::Italic)) {
251 sig |= (quint64(1) << 2);
252 if (t->styleProperty<
bool>(QQSK::Property::Italic))
253 sig |= (quint64(1) << 3);
256 if (t->isDefined(QQSK::Property::PointSize)) {
257 sig |= (quint64(1) << 4);
258 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
260 constexpr int payloadBits = 64 - 5;
261 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
262 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
268QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
269QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
271QQStyleKitReader::QQStyleKitReader(QObject *parent)
272 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
273 , m_dontEmitChangedSignals(
false)
274 , m_effectiveVariationsDirty(
true)
275 , m_transitionsEnabled(
true)
277 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
279 s_allReaders.append(
this);
282QQStyleKitReader::~QQStyleKitReader()
284 s_allReaders.removeOne(
this);
287QQuickStateGroup *QQStyleKitReader::stateGroup()
293
294
295
296 const auto *stylePtr = style();
299 m_stateGroup =
new QQuickStateGroup(
this);
302 auto statesProp = m_stateGroup->statesProperty();
303 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
304 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
305 alternate1->setName(kAlternate1);
306 alternate2->setName(kAlternate2);
307 m_stateGroup->statesProperty().append(&statesProp, alternate1);
308 m_stateGroup->statesProperty().append(&statesProp, alternate2);
310 QQmlComponent *controlComp = createControlChangesComponent();
311 instantiatePropertyChanges(controlComp);
316QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
318 QQmlEngine *engine = qmlEngine(style());
319 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
320 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
323 const QString qmlControlCode = QString::fromUtf8(R"(
324 import QtQuick
325 PropertyChanges {
326 spacing: global.spacing
327 padding: global.padding
328 leftPadding: global.leftPadding
329 rightPadding: global.rightPadding
330 topPadding: global.topPadding
331 bottomPadding: global.bottomPadding
332 text.color: global.text.color
333 text.alignment: global.text.alignment
334 text.bold: global.text.bold
335 text.italic: global.text.italic
336 text.pointSize: global.text.pointSize
337 text.padding: global.text.padding
338 text.leftPadding: global.text.leftPadding
339 text.rightPadding: global.text.rightPadding
340 text.topPadding: global.text.topPadding
341 text.bottomPadding: global.text.bottomPadding
342 }
343 )");
346 QQmlComponent *component =
new QQmlComponent(engine);
347 component->setData(qmlControlCode.toUtf8(), QUrl());
348 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
349 s_propertyChangesComponents.insert(key, component);
350 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
351 s_propertyChangesComponents.remove(key);
356QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
358 QQmlEngine *engine = qmlEngine(style());
359 auto key = PropertyChangesComponents::key_type{engine, delegateName};
360 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
363 static const QString qmlTemplateCode = QString::fromUtf8(R"(
364 import QtQuick
365 PropertyChanges { $ {
366 implicitWidth: global.$.implicitWidth
367 implicitHeight: global.$.implicitHeight
368 visible: global.$.visible
369 color: global.$.color
370 gradient: global.$.gradient
371 radius: global.$.radius
372 topLeftRadius: global.$.topLeftRadius
373 topRightRadius: global.$.topRightRadius
374 bottomLeftRadius: global.$.bottomLeftRadius
375 bottomRightRadius: global.$.bottomRightRadius
376 margins: global.$.margins
377 alignment: global.$.alignment
378 leftMargin: global.$.leftMargin
379 rightMargin: global.$.rightMargin
380 topMargin: global.$.topMargin
381 bottomMargin: global.$.bottomMargin
382 scale: global.$.scale
383 rotation: global.$.rotation
384 opacity: global.$.opacity
385 border.color: global.$.border.color
386 border.width: global.$.border.width
387 shadow.color: global.$.shadow.color
388 shadow.scale: global.$.shadow.scale
389 shadow.blur: global.$.shadow.blur
390 shadow.visible: global.$.shadow.visible
391 shadow.opacity: global.$.shadow.opacity
392 shadow.verticalOffset: global.$.shadow.verticalOffset
393 shadow.horizontalOffset: global.$.shadow.horizontalOffset
394 shadow.delegate: global.$.shadow.delegate
395 image.source: global.$.image.source
396 image.color: global.$.image.color
397 image.fillMode: global.$.image.fillMode
398 delegate: global.$.delegate
399 data: global.$.data
400 }}
401 )");
403 QString substitutedCode = qmlTemplateCode;
404 substitutedCode.replace(
'$'_L1, delegateName);
405 QQmlComponent *component =
new QQmlComponent(engine);
406 component->setData(substitutedCode.toUtf8(), QUrl());
407 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
408 s_propertyChangesComponents.insert(key, component);
409 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
410 s_propertyChangesComponents.remove(key);
415void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
417 QObject *obj = comp->create(qmlContext(
this));
418 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
419 Q_ASSERT(propertyChanges);
422 propertyChanges->setObject(
this);
424
425
426
427
428
429 propertyChanges->setIsExplicit(
true);
431
432
433 propertyChanges->setRestoreEntryValues(
false);
436 for (QQuickState *state : stateGroup()->states()) {
437 auto changesProp = state->changes();
438 changesProp.append(&changesProp, propertyChanges);
442void QQStyleKitReader::maybeTrackDelegates()
445 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
446 if (m_trackedDelegates.testFlag(type)) {
450 if (!delegate->visible()) {
452
453
457
458
459
460
461 m_trackedDelegates.setFlag(type);
462 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
463 instantiatePropertyChanges(comp);
467void QQStyleKitReader::updateControl()
469 const QQStyleKitStyle *currentStyle = style();
470 if (!m_completed || !currentStyle || !currentStyle->loaded())
474
475
476
477
478
479
480
481
482
483
484
486 maybeTrackDelegates();
488 auto transitionProp = stateGroup()->transitionsProperty();
489 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
490 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
491 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
492 QQuickTransition *transitionInStateGroup =
493 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
494 if (transitionInStyle != transitionInStateGroup) {
495 transitionProp.clear(&transitionProp);
496 if (transitionInStyle)
497 transitionProp.append(&transitionProp, transitionInStyle);
500 switch (m_alternateState) {
501 case AlternateState::Alternate1:
502 m_alternateState = AlternateState::Alternate2;
503 stateGroup()->setState(kAlternate2);
505 case AlternateState::Alternate2:
506 m_alternateState = AlternateState::Alternate1;
507 stateGroup()->setState(kAlternate1);
513 auto textOverrideSig = textFontOverridesSignature(global()->text());
514 if (m_lastTextFontOverridesSignature != textOverrideSig)
516 m_lastTextFontOverridesSignature = textOverrideSig;
517 rebuildEffectiveFont();
520void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
522 for (QQStyleKitReader *reader : s_allReaders) {
523 if (reader->style() == style) {
524 reader->m_effectiveVariationsDirty =
true;
525 reader->m_fontDirty =
true;
526 reader->clearLocalStorage();
527 reader->rebuildEffectivePalette();
528 reader->rebuildEffectiveFont();
529 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
534void QQStyleKitReader::populateLocalStorage()
538
539
545 if (!m_storage.isEmpty())
547 const auto *stylePtr = style();
548 if (!stylePtr || !stylePtr->loaded())
552
553
554
559
561
562
563
564
565 m_dontEmitChangedSignals =
true;
567 m_dontEmitChangedSignals =
false;
570void QQStyleKitReader::clearLocalStorage()
573
574
575
579QQSK::State QQStyleKitReader::controlState()
const
581 QQSK::State effectiveState = m_state;
585 effectiveState &= ~(QQSK::StateFlag::Pressed |
586 QQSK::StateFlag::Hovered |
587 QQSK::StateFlag::Highlighted |
588 QQSK::StateFlag::Focused |
589 QQSK::StateFlag::Hovered);
592 if (effectiveState == QQSK::StateFlag::Unspecified)
593 effectiveState.setFlag(QQSK::StateFlag::Normal);
595 return effectiveState;
598QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
600 return m_storage.value(key);
603void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
605 m_storage.insert(key, value);
608bool QQStyleKitReader::dontEmitChangedSignals()
const
610 return m_dontEmitChangedSignals;
613QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
618void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
624 populateLocalStorage();
625 emit controlTypeChanged();
630QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
633
635 return ControlType(m_type);
639bool QQStyleKitReader::hovered()
const
641 return m_state.testFlag(QQSK::StateFlag::Hovered);
644void QQStyleKitReader::setHovered(
bool hovered)
646 if (hovered == QQStyleKitReader::hovered())
649 populateLocalStorage();
650 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
651 emit hoveredChanged();
655bool QQStyleKitReader::enabled()
const
657 return !m_state.testFlag(QQSK::StateFlag::Disabled);
660void QQStyleKitReader::setEnabled(
bool enabled)
662 if (enabled == QQStyleKitReader::enabled())
665 populateLocalStorage();
666 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
667 emit enabledChanged();
671bool QQStyleKitReader::focused()
const
673 return m_state.testFlag(QQSK::StateFlag::Focused);
676void QQStyleKitReader::setFocused(
bool focused)
678 if (focused == QQStyleKitReader::focused())
681 populateLocalStorage();
682 m_state.setFlag(QQSK::StateFlag::Focused, focused);
683 emit focusedChanged();
687bool QQStyleKitReader::checked()
const
689 return m_state.testFlag(QQSK::StateFlag::Checked);
692void QQStyleKitReader::setChecked(
bool checked)
694 if (checked == QQStyleKitReader::checked())
697 populateLocalStorage();
698 m_state.setFlag(QQSK::StateFlag::Checked, checked);
699 emit checkedChanged();
703bool QQStyleKitReader::pressed()
const
705 return m_state.testFlag(QQSK::StateFlag::Pressed);
708void QQStyleKitReader::setPressed(
bool pressed)
710 if (pressed == QQStyleKitReader::pressed())
713 populateLocalStorage();
714 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
715 emit pressedChanged();
719bool QQStyleKitReader::vertical()
const
721 return m_state.testFlag(QQSK::StateFlag::Vertical);
724void QQStyleKitReader::setVertical(
bool vertical)
726 if (vertical == QQStyleKitReader::vertical())
729 populateLocalStorage();
730 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
731 emit verticalChanged();
735bool QQStyleKitReader::highlighted()
const
737 return m_state.testFlag(QQSK::StateFlag::Highlighted);
740void QQStyleKitReader::setHighlighted(
bool highlighted)
742 if (highlighted == QQStyleKitReader::highlighted())
745 populateLocalStorage();
746 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
747 emit highlightedChanged();
751void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
755 const bool typeChanged = m_type != controlType;
756 const QQSK::State stateChanged = m_state ^ flags;
758 if (!typeChanged && !stateChanged)
761 populateLocalStorage();
763 m_type = controlType;
767 emit controlTypeChanged();
769 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
770 if (stateChanged.testFlag(flag))
773 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
774 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
775 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
776 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
777 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
778 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
779 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
784QObject *QQStyleKitReader::target()
const
786 return m_target.data();
789void QQStyleKitReader::setTarget(QObject *target)
792
793
794
795
799void QQStyleKitReader::setCompleted(
bool completed)
801 m_completed = completed;
804bool QQStyleKitReader::transitionsEnabled()
const
806 return m_transitionsEnabled;
809void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
811 if (m_transitionsEnabled == enabled)
813 m_transitionsEnabled = enabled;
816QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
818 return m_explicitStyle.data();
821void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
823 if (m_explicitStyle == style)
825 m_explicitStyle = style;
827 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
832 m_effectiveVariationsDirty =
true;
835 rebuildEffectivePalette();
836 rebuildEffectiveFont();
837 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
840QQuickPalette *QQStyleKitReader::palette()
const
842 return m_palette.data();
845void QQStyleKitReader::setPalette(QQuickPalette *palette)
847 if (m_palette == palette)
851 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
854 emit paletteChanged();
858 QObject::connect(m_palette, &QQuickPalette::changed,
859 this, &QQStyleKitReader::onPaletteChanged);
865QPalette QQStyleKitReader::effectivePalette()
const
867 return m_effectivePalette;
870void QQStyleKitReader::onPaletteChanged()
872 const QQStyleKitStyle *currentStyle = style();
873 if (!currentStyle || !currentStyle->loaded())
876 if (rebuildEffectivePalette()) {
878 emitChangedForAllStyleProperties(EmitFlag::Colors);
882bool QQStyleKitReader::rebuildEffectivePalette()
884 auto mergedPalette = style()->paletteForControlType(
this->controlType());
885 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
888 const auto controlPalette = m_palette->toQPalette();
889 mergedPalette = controlPalette.resolve(mergedPalette);
892 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
894 if (m_effectivePalette == mergedPalette)
897 m_effectivePalette = mergedPalette;
901QFont QQStyleKitReader::font()
const
906bool QQStyleKitReader::rebuildEffectiveFont()
908 const QQStyleKitStyle *currentStyle = style();
909 if (!currentStyle || !currentStyle->loaded())
915 QFont font = currentStyle->fontForControlType(controlType());
916 const QQStyleKitTextProperties *textProps = global()->text();
918 if (textProps->isDefined(QQSK::Property::Bold))
919 font.setBold(textProps->bold());
920 if (textProps->isDefined(QQSK::Property::Italic))
921 font.setItalic(textProps->italic());
922 if (textProps->isDefined(QQSK::Property::PointSize))
923 font.setPointSizeF(textProps->pointSize());
934QQStyleKitControlProperties *QQStyleKitReader::global()
const
936 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
939void QQStyleKitReader::componentComplete()
946#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