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
111
112
113
114
115
116
117
118
119
120
123
124
125
126
127
128
129
130
131
132
135
136
137
138
139
140
141
142
143
144
147
148
149
150
151
152
153
154
155
156
159
160
161
162
163
164
165
166
167
168
171
172
173
174
175
176
177
178
179
180
183
184
185
186
187
188
189
190
191
192
195
196
197
198
199
200
201
202
203
206
207
208
209
210
211
212
213
214
215
216
217
218
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
240using namespace Qt::StringLiterals;
253 if (t->isDefined(QQSK::Property::Bold)) {
254 sig |= (quint64(1) << 0);
255 if (t->styleProperty<
bool>(QQSK::Property::Bold))
256 sig |= (quint64(1) << 1);
259 if (t->isDefined(QQSK::Property::Italic)) {
260 sig |= (quint64(1) << 2);
261 if (t->styleProperty<
bool>(QQSK::Property::Italic))
262 sig |= (quint64(1) << 3);
265 if (t->isDefined(QQSK::Property::PointSize)) {
266 sig |= (quint64(1) << 4);
267 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
269 constexpr int payloadBits = 64 - 5;
270 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
271 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
277QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
278QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
280QQStyleKitReader::QQStyleKitReader(QObject *parent)
281 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
282 , m_dontEmitChangedSignals(
false)
283 , m_effectiveVariationsDirty(
true)
284 , m_transitionsEnabled(
true)
286 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
288 s_allReaders.append(
this);
291QQStyleKitReader::~QQStyleKitReader()
293 s_allReaders.removeOne(
this);
296QQuickStateGroup *QQStyleKitReader::stateGroup()
302
303
304
305 const auto *stylePtr = style();
308 m_stateGroup =
new QQuickStateGroup(
this);
311 auto statesProp = m_stateGroup->statesProperty();
312 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
313 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
314 alternate1->setName(kAlternate1);
315 alternate2->setName(kAlternate2);
316 m_stateGroup->statesProperty().append(&statesProp, alternate1);
317 m_stateGroup->statesProperty().append(&statesProp, alternate2);
319 QQmlComponent *controlComp = createControlChangesComponent();
320 instantiatePropertyChanges(controlComp);
325QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
327 QQmlEngine *engine = qmlEngine(style());
328 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
329 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
332 const QString qmlControlCode = QString::fromUtf8(R"(
333 import QtQuick
334 PropertyChanges {
335 spacing: global.spacing
336 padding: global.padding
337 leftPadding: global.leftPadding
338 rightPadding: global.rightPadding
339 topPadding: global.topPadding
340 bottomPadding: global.bottomPadding
341 text.color: global.text.color
342 text.alignment: global.text.alignment
343 text.bold: global.text.bold
344 text.italic: global.text.italic
345 text.pointSize: global.text.pointSize
346 text.padding: global.text.padding
347 text.leftPadding: global.text.leftPadding
348 text.rightPadding: global.text.rightPadding
349 text.topPadding: global.text.topPadding
350 text.bottomPadding: global.text.bottomPadding
351 }
352 )");
355 QQmlComponent *component =
new QQmlComponent(engine);
356 component->setData(qmlControlCode.toUtf8(), QUrl());
357 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
358 s_propertyChangesComponents.insert(key, component);
359 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
360 s_propertyChangesComponents.remove(key);
365QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
367 QQmlEngine *engine = qmlEngine(style());
368 auto key = PropertyChangesComponents::key_type{engine, delegateName};
369 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
372 static const QString qmlTemplateCode = QString::fromUtf8(R"(
373 import QtQuick
374 PropertyChanges { $ {
375 width: global.$.width
376 height: global.$.height
377 visible: global.$.visible
378 color: global.$.color
379 gradient: global.$.gradient
380 radius: global.$.radius
381 topLeftRadius: global.$.topLeftRadius
382 topRightRadius: global.$.topRightRadius
383 bottomLeftRadius: global.$.bottomLeftRadius
384 bottomRightRadius: global.$.bottomRightRadius
385 margins: global.$.margins
386 alignment: global.$.alignment
387 leftMargin: global.$.leftMargin
388 rightMargin: global.$.rightMargin
389 topMargin: global.$.topMargin
390 bottomMargin: global.$.bottomMargin
391 scale: global.$.scale
392 rotation: global.$.rotation
393 opacity: global.$.opacity
394 border.color: global.$.border.color
395 border.width: global.$.border.width
396 shadow.color: global.$.shadow.color
397 shadow.scale: global.$.shadow.scale
398 shadow.blur: global.$.shadow.blur
399 shadow.visible: global.$.shadow.visible
400 shadow.opacity: global.$.shadow.opacity
401 shadow.verticalOffset: global.$.shadow.verticalOffset
402 shadow.horizontalOffset: global.$.shadow.horizontalOffset
403 shadow.delegate: global.$.shadow.delegate
404 image.source: global.$.image.source
405 image.color: global.$.image.color
406 image.fillMode: global.$.image.fillMode
407 delegate: global.$.delegate
408 data: global.$.data
409 }}
410 )");
412 QString substitutedCode = qmlTemplateCode;
413 substitutedCode.replace(
'$'_L1, delegateName);
414 QQmlComponent *component =
new QQmlComponent(engine);
415 component->setData(substitutedCode.toUtf8(), QUrl());
416 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
417 s_propertyChangesComponents.insert(key, component);
418 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
419 s_propertyChangesComponents.remove(key);
424void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
426 QObject *obj = comp->create(qmlContext(
this));
427 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
428 Q_ASSERT(propertyChanges);
431 propertyChanges->setObject(
this);
433
434
435
436
437
438 propertyChanges->setIsExplicit(
true);
440
441
442 propertyChanges->setRestoreEntryValues(
false);
445 for (QQuickState *state : stateGroup()->states()) {
446 auto changesProp = state->changes();
447 changesProp.append(&changesProp, propertyChanges);
451void QQStyleKitReader::maybeTrackDelegates()
454 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
455 if (m_trackedDelegates.testFlag(type)) {
459 if (!delegate->visible()) {
461
462
466
467
468
469
470 m_trackedDelegates.setFlag(type);
471 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
472 instantiatePropertyChanges(comp);
476void QQStyleKitReader::updateControl()
478 const QQStyleKitStyle *currentStyle = style();
479 if (!m_completed || !currentStyle || !currentStyle->loaded())
483
484
485
486
487
488
489
490
491
492
493
495 maybeTrackDelegates();
497 auto transitionProp = stateGroup()->transitionsProperty();
498 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
499 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
500 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
501 QQuickTransition *transitionInStateGroup =
502 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
503 if (transitionInStyle != transitionInStateGroup) {
504 transitionProp.clear(&transitionProp);
505 if (transitionInStyle)
506 transitionProp.append(&transitionProp, transitionInStyle);
509 switch (m_alternateState) {
510 case AlternateState::Alternate1:
511 m_alternateState = AlternateState::Alternate2;
512 stateGroup()->setState(kAlternate2);
514 case AlternateState::Alternate2:
515 m_alternateState = AlternateState::Alternate1;
516 stateGroup()->setState(kAlternate1);
522 auto textOverrideSig = textFontOverridesSignature(global()->text());
523 if (m_lastTextFontOverridesSignature != textOverrideSig)
525 m_lastTextFontOverridesSignature = textOverrideSig;
526 rebuildEffectiveFont();
529void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
531 for (QQStyleKitReader *reader : s_allReaders) {
532 if (reader->style() == style) {
533 reader->m_effectiveVariationsDirty =
true;
534 reader->m_fontDirty =
true;
535 reader->clearLocalStorage();
536 reader->rebuildEffectivePalette();
537 reader->rebuildEffectiveFont();
538 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
543void QQStyleKitReader::populateLocalStorage()
547
548
554 if (!m_storage.isEmpty())
556 const auto *stylePtr = style();
557 if (!stylePtr || !stylePtr->loaded())
561
562
563
568
570
571
572
573
574 m_dontEmitChangedSignals =
true;
576 m_dontEmitChangedSignals =
false;
579void QQStyleKitReader::clearLocalStorage()
582
583
584
588QQSK::State QQStyleKitReader::controlState()
const
590 QQSK::State effectiveState = m_state;
594 effectiveState &= ~(QQSK::StateFlag::Pressed |
595 QQSK::StateFlag::Hovered |
596 QQSK::StateFlag::Highlighted |
597 QQSK::StateFlag::Focused |
598 QQSK::StateFlag::Hovered);
601 if (effectiveState == QQSK::StateFlag::Unspecified)
602 effectiveState.setFlag(QQSK::StateFlag::Normal);
604 return effectiveState;
607QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
609 return m_storage.value(key);
612void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
614 m_storage.insert(key, value);
617bool QQStyleKitReader::dontEmitChangedSignals()
const
619 return m_dontEmitChangedSignals;
622QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
627void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
633 populateLocalStorage();
634 emit controlTypeChanged();
639QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
642
644 return ControlType(m_type);
648bool QQStyleKitReader::hovered()
const
650 return m_state.testFlag(QQSK::StateFlag::Hovered);
653void QQStyleKitReader::setHovered(
bool hovered)
655 if (hovered == QQStyleKitReader::hovered())
658 populateLocalStorage();
659 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
660 emit hoveredChanged();
664bool QQStyleKitReader::enabled()
const
666 return !m_state.testFlag(QQSK::StateFlag::Disabled);
669void QQStyleKitReader::setEnabled(
bool enabled)
671 if (enabled == QQStyleKitReader::enabled())
674 populateLocalStorage();
675 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
676 emit enabledChanged();
680bool QQStyleKitReader::focused()
const
682 return m_state.testFlag(QQSK::StateFlag::Focused);
685void QQStyleKitReader::setFocused(
bool focused)
687 if (focused == QQStyleKitReader::focused())
690 populateLocalStorage();
691 m_state.setFlag(QQSK::StateFlag::Focused, focused);
692 emit focusedChanged();
696bool QQStyleKitReader::checked()
const
698 return m_state.testFlag(QQSK::StateFlag::Checked);
701void QQStyleKitReader::setChecked(
bool checked)
703 if (checked == QQStyleKitReader::checked())
706 populateLocalStorage();
707 m_state.setFlag(QQSK::StateFlag::Checked, checked);
708 emit checkedChanged();
712bool QQStyleKitReader::pressed()
const
714 return m_state.testFlag(QQSK::StateFlag::Pressed);
717void QQStyleKitReader::setPressed(
bool pressed)
719 if (pressed == QQStyleKitReader::pressed())
722 populateLocalStorage();
723 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
724 emit pressedChanged();
728bool QQStyleKitReader::vertical()
const
730 return m_state.testFlag(QQSK::StateFlag::Vertical);
733void QQStyleKitReader::setVertical(
bool vertical)
735 if (vertical == QQStyleKitReader::vertical())
738 populateLocalStorage();
739 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
740 emit verticalChanged();
744bool QQStyleKitReader::highlighted()
const
746 return m_state.testFlag(QQSK::StateFlag::Highlighted);
749void QQStyleKitReader::setHighlighted(
bool highlighted)
751 if (highlighted == QQStyleKitReader::highlighted())
754 populateLocalStorage();
755 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
756 emit highlightedChanged();
760void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
764 const bool typeChanged = m_type != controlType;
765 const QQSK::State stateChanged = m_state ^ flags;
767 if (!typeChanged && !stateChanged)
770 populateLocalStorage();
772 m_type = controlType;
776 emit controlTypeChanged();
778 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
779 if (stateChanged.testFlag(flag))
782 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
783 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
784 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
785 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
786 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
787 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
788 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
793QObject *QQStyleKitReader::target()
const
795 return m_target.data();
798void QQStyleKitReader::setTarget(QObject *target)
801
802
803
804
808void QQStyleKitReader::setCompleted(
bool completed)
810 m_completed = completed;
813bool QQStyleKitReader::transitionsEnabled()
const
815 return m_transitionsEnabled;
818void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
820 if (m_transitionsEnabled == enabled)
822 m_transitionsEnabled = enabled;
825QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
827 return m_explicitStyle.data();
830void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
832 if (m_explicitStyle == style)
834 m_explicitStyle = style;
836 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
841 m_effectiveVariationsDirty =
true;
844 rebuildEffectivePalette();
845 rebuildEffectiveFont();
846 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
849QQuickPalette *QQStyleKitReader::palette()
const
851 return m_palette.data();
854void QQStyleKitReader::setPalette(QQuickPalette *palette)
856 if (m_palette == palette)
860 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
863 emit paletteChanged();
867 QObject::connect(m_palette, &QQuickPalette::changed,
868 this, &QQStyleKitReader::onPaletteChanged);
874QPalette QQStyleKitReader::effectivePalette()
const
876 return m_effectivePalette;
879void QQStyleKitReader::onPaletteChanged()
881 const QQStyleKitStyle *currentStyle = style();
882 if (!currentStyle || !currentStyle->loaded())
885 if (rebuildEffectivePalette()) {
887 emitChangedForAllStyleProperties(EmitFlag::Colors);
891bool QQStyleKitReader::rebuildEffectivePalette()
893 auto mergedPalette = style()->paletteForControlType(
this->controlType());
894 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
897 const auto controlPalette = m_palette->toQPalette();
898 mergedPalette = controlPalette.resolve(mergedPalette);
901 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
903 if (m_effectivePalette == mergedPalette)
906 m_effectivePalette = mergedPalette;
910QFont QQStyleKitReader::font()
const
915bool QQStyleKitReader::rebuildEffectiveFont()
917 const QQStyleKitStyle *currentStyle = style();
918 if (!currentStyle || !currentStyle->loaded())
924 QFont font = currentStyle->fontForControlType(controlType());
925 const QQStyleKitTextProperties *textProps = global()->text();
927 if (textProps->isDefined(QQSK::Property::Bold))
928 font.setBold(textProps->bold());
929 if (textProps->isDefined(QQSK::Property::Italic))
930 font.setItalic(textProps->italic());
931 if (textProps->isDefined(QQSK::Property::PointSize))
932 font.setPointSizeF(textProps->pointSize());
943QQStyleKitControlProperties *QQStyleKitReader::global()
const
945 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
948void QQStyleKitReader::componentComplete()
955#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