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
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
195
198
199
200
201
202
203
204
205
206
209
210
211
212
213
214
215
216
217
218
219
220
221
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
243using namespace Qt::StringLiterals;
256 if (t->isDefined(QQSK::Property::Bold)) {
257 sig |= (quint64(1) << 0);
258 if (t->styleProperty<
bool>(QQSK::Property::Bold))
259 sig |= (quint64(1) << 1);
262 if (t->isDefined(QQSK::Property::Italic)) {
263 sig |= (quint64(1) << 2);
264 if (t->styleProperty<
bool>(QQSK::Property::Italic))
265 sig |= (quint64(1) << 3);
268 if (t->isDefined(QQSK::Property::PointSize)) {
269 sig |= (quint64(1) << 4);
270 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
272 constexpr int payloadBits = 64 - 5;
273 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
274 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
280QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
281QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
283QQStyleKitReader::QQStyleKitReader(QObject *parent)
284 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
285 , m_dontEmitChangedSignals(
false)
286 , m_effectiveVariationsDirty(
true)
287 , m_transitionsEnabled(
true)
289 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
291 s_allReaders.append(
this);
294QQStyleKitReader::~QQStyleKitReader()
296 s_allReaders.removeOne(
this);
299QQuickStateGroup *QQStyleKitReader::stateGroup()
305
306
307
308 const auto *stylePtr = style();
311 m_stateGroup =
new QQuickStateGroup(
this);
314 auto statesProp = m_stateGroup->statesProperty();
315 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
316 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
317 alternate1->setName(kAlternate1);
318 alternate2->setName(kAlternate2);
319 m_stateGroup->statesProperty().append(&statesProp, alternate1);
320 m_stateGroup->statesProperty().append(&statesProp, alternate2);
322 QQmlComponent *controlComp = createControlChangesComponent();
323 instantiatePropertyChanges(controlComp);
328QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
330 QQmlEngine *engine = qmlEngine(style());
331 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
332 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
335 const QString qmlControlCode = QString::fromUtf8(R"(
336 import QtQuick
337 PropertyChanges {
338 spacing: global.spacing
339 padding: global.padding
340 leftPadding: global.leftPadding
341 rightPadding: global.rightPadding
342 topPadding: global.topPadding
343 bottomPadding: global.bottomPadding
344 text.color: global.text.color
345 text.alignment: global.text.alignment
346 text.bold: global.text.bold
347 text.italic: global.text.italic
348 text.pointSize: global.text.pointSize
349 text.padding: global.text.padding
350 text.leftPadding: global.text.leftPadding
351 text.rightPadding: global.text.rightPadding
352 text.topPadding: global.text.topPadding
353 text.bottomPadding: global.text.bottomPadding
354 }
355 )");
358 QQmlComponent *component =
new QQmlComponent(engine);
359 component->setData(qmlControlCode.toUtf8(), QUrl());
360 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
361 s_propertyChangesComponents.insert(key, component);
362 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
363 s_propertyChangesComponents.remove(key);
368QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
370 QQmlEngine *engine = qmlEngine(style());
371 auto key = PropertyChangesComponents::key_type{engine, delegateName};
372 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
375 static const QString qmlTemplateCode = QString::fromUtf8(R"(
376 import QtQuick
377 PropertyChanges { $ {
378 width: global.$.width
379 height: global.$.height
380 visible: global.$.visible
381 color: global.$.color
382 gradient: global.$.gradient
383 radius: global.$.radius
384 topLeftRadius: global.$.topLeftRadius
385 topRightRadius: global.$.topRightRadius
386 bottomLeftRadius: global.$.bottomLeftRadius
387 bottomRightRadius: global.$.bottomRightRadius
388 margins: global.$.margins
389 alignment: global.$.alignment
390 leftMargin: global.$.leftMargin
391 rightMargin: global.$.rightMargin
392 topMargin: global.$.topMargin
393 bottomMargin: global.$.bottomMargin
394 scale: global.$.scale
395 rotation: global.$.rotation
396 opacity: global.$.opacity
397 border.color: global.$.border.color
398 border.width: global.$.border.width
399 shadow.color: global.$.shadow.color
400 shadow.scale: global.$.shadow.scale
401 shadow.blur: global.$.shadow.blur
402 shadow.visible: global.$.shadow.visible
403 shadow.opacity: global.$.shadow.opacity
404 shadow.verticalOffset: global.$.shadow.verticalOffset
405 shadow.horizontalOffset: global.$.shadow.horizontalOffset
406 shadow.delegate: global.$.shadow.delegate
407 image.source: global.$.image.source
408 image.color: global.$.image.color
409 image.fillMode: global.$.image.fillMode
410 delegate: global.$.delegate
411 data: global.$.data
412 }}
413 )");
415 QString substitutedCode = qmlTemplateCode;
416 substitutedCode.replace(
'$'_L1, delegateName);
417 QQmlComponent *component =
new QQmlComponent(engine);
418 component->setData(substitutedCode.toUtf8(), QUrl());
419 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
420 s_propertyChangesComponents.insert(key, component);
421 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
422 s_propertyChangesComponents.remove(key);
427void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
429 QObject *obj = comp->create(qmlContext(
this));
430 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
431 Q_ASSERT(propertyChanges);
434 propertyChanges->setObject(
this);
436
437
438
439
440
441 propertyChanges->setIsExplicit(
true);
443
444
445 propertyChanges->setRestoreEntryValues(
false);
448 for (QQuickState *state : stateGroup()->states()) {
449 auto changesProp = state->changes();
450 changesProp.append(&changesProp, propertyChanges);
454void QQStyleKitReader::maybeTrackDelegates()
457 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
458 if (m_trackedDelegates.testFlag(type)) {
462 if (!delegate->visible()) {
464
465
469
470
471
472
473 m_trackedDelegates.setFlag(type);
474 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
475 instantiatePropertyChanges(comp);
479void QQStyleKitReader::updateControl(
bool applyStateChange)
481 const QQStyleKitStyle *currentStyle = style();
482 if (!m_completed || !currentStyle || !currentStyle->loaded())
485 if (applyStateChange) {
487
488
489
490
491
492
493
494
495
496
497
499 maybeTrackDelegates();
501 auto transitionProp = stateGroup()->transitionsProperty();
502 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
503 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
504 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
505 QQuickTransition *transitionInStateGroup =
506 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
507 if (transitionInStyle != transitionInStateGroup) {
508 transitionProp.clear(&transitionProp);
509 if (transitionInStyle)
510 transitionProp.append(&transitionProp, transitionInStyle);
513 switch (m_alternateState) {
514 case AlternateState::Alternate1:
515 m_alternateState = AlternateState::Alternate2;
516 stateGroup()->setState(kAlternate2);
518 case AlternateState::Alternate2:
519 m_alternateState = AlternateState::Alternate1;
520 stateGroup()->setState(kAlternate1);
533 auto textOverrideSig = textFontOverridesSignature(global()->text());
534 if (m_lastTextFontOverridesSignature != textOverrideSig)
536 m_lastTextFontOverridesSignature = textOverrideSig;
537 rebuildEffectiveFont();
540void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
542 for (QQStyleKitReader *reader : s_allReaders) {
543 if (reader->style() == style) {
544 reader->m_effectiveVariationsDirty =
true;
545 reader->m_fontDirty =
true;
546 reader->clearLocalStorage();
547 reader->rebuildEffectivePalette();
548 reader->rebuildEffectiveFont();
549 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
554void QQStyleKitReader::populateLocalStorage()
558
559
565 if (!m_storage.isEmpty())
567 const auto *stylePtr = style();
568 if (!stylePtr || !stylePtr->loaded())
572
573
574
579
581
582
583
584
585 m_dontEmitChangedSignals =
true;
587 m_dontEmitChangedSignals =
false;
590void QQStyleKitReader::clearLocalStorage()
593
594
595
599QQSK::State QQStyleKitReader::controlState()
const
601 QQSK::State effectiveState = m_state;
605 effectiveState &= ~(QQSK::StateFlag::Pressed |
606 QQSK::StateFlag::Hovered |
607 QQSK::StateFlag::Highlighted |
608 QQSK::StateFlag::Focused |
609 QQSK::StateFlag::Hovered);
612 if (effectiveState == QQSK::StateFlag::Unspecified)
613 effectiveState.setFlag(QQSK::StateFlag::Normal);
615 return effectiveState;
618QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
620 return m_storage.value(key);
623void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
625 m_storage.insert(key, value);
628bool QQStyleKitReader::dontEmitChangedSignals()
const
630 return m_dontEmitChangedSignals;
633QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
638void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
644 populateLocalStorage();
645 emit controlTypeChanged();
650QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
653
655 return ControlType(m_type);
659bool QQStyleKitReader::hovered()
const
661 return m_state.testFlag(QQSK::StateFlag::Hovered);
664void QQStyleKitReader::setHovered(
bool hovered)
666 if (hovered == QQStyleKitReader::hovered())
669 populateLocalStorage();
670 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
671 emit hoveredChanged();
675bool QQStyleKitReader::enabled()
const
677 return !m_state.testFlag(QQSK::StateFlag::Disabled);
680void QQStyleKitReader::setEnabled(
bool enabled)
682 if (enabled == QQStyleKitReader::enabled())
685 populateLocalStorage();
686 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
687 emit enabledChanged();
691bool QQStyleKitReader::focused()
const
693 return m_state.testFlag(QQSK::StateFlag::Focused);
696void QQStyleKitReader::setFocused(
bool focused)
698 if (focused == QQStyleKitReader::focused())
701 populateLocalStorage();
702 m_state.setFlag(QQSK::StateFlag::Focused, focused);
703 emit focusedChanged();
707bool QQStyleKitReader::checked()
const
709 return m_state.testFlag(QQSK::StateFlag::Checked);
712void QQStyleKitReader::setChecked(
bool checked)
714 if (checked == QQStyleKitReader::checked())
717 populateLocalStorage();
718 m_state.setFlag(QQSK::StateFlag::Checked, checked);
719 emit checkedChanged();
723bool QQStyleKitReader::pressed()
const
725 return m_state.testFlag(QQSK::StateFlag::Pressed);
728void QQStyleKitReader::setPressed(
bool pressed)
730 if (pressed == QQStyleKitReader::pressed())
733 populateLocalStorage();
734 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
735 emit pressedChanged();
739bool QQStyleKitReader::vertical()
const
741 return m_state.testFlag(QQSK::StateFlag::Vertical);
744void QQStyleKitReader::setVertical(
bool vertical)
746 if (vertical == QQStyleKitReader::vertical())
749 populateLocalStorage();
750 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
751 emit verticalChanged();
755bool QQStyleKitReader::highlighted()
const
757 return m_state.testFlag(QQSK::StateFlag::Highlighted);
760void QQStyleKitReader::setHighlighted(
bool highlighted)
762 if (highlighted == QQStyleKitReader::highlighted())
765 populateLocalStorage();
766 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
767 emit highlightedChanged();
771void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags,
772 bool applyStateChange)
776 const bool typeChanged = m_type != controlType;
777 const QQSK::State stateChanged = m_state ^ flags;
779 if (!typeChanged && !stateChanged)
782 if (applyStateChange)
783 populateLocalStorage();
785 m_type = controlType;
788 updateControl(applyStateChange);
791QObject *QQStyleKitReader::target()
const
793 return m_target.data();
796void QQStyleKitReader::setTarget(QObject *target)
799
800
801
802
806void QQStyleKitReader::setCompleted(
bool completed)
808 m_completed = completed;
811bool QQStyleKitReader::transitionsEnabled()
const
813 return m_transitionsEnabled;
816void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
818 if (m_transitionsEnabled == enabled)
820 m_transitionsEnabled = enabled;
823QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
825 return m_explicitStyle.data();
828void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
830 if (m_explicitStyle == style)
832 m_explicitStyle = style;
834 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
839 m_effectiveVariationsDirty =
true;
842 rebuildEffectivePalette();
843 rebuildEffectiveFont();
844 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
847QQuickPalette *QQStyleKitReader::palette()
const
849 return m_palette.data();
852void QQStyleKitReader::setPalette(QQuickPalette *palette)
854 if (m_palette == palette)
858 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
861 emit paletteChanged();
865 QObject::connect(m_palette, &QQuickPalette::changed,
866 this, &QQStyleKitReader::onPaletteChanged);
872QPalette QQStyleKitReader::effectivePalette()
const
874 return m_effectivePalette;
877void QQStyleKitReader::onPaletteChanged()
879 const QQStyleKitStyle *currentStyle = style();
880 if (!currentStyle || !currentStyle->loaded())
883 if (rebuildEffectivePalette()) {
885 emitChangedForAllStyleProperties(EmitFlag::Colors);
889bool QQStyleKitReader::rebuildEffectivePalette()
891 auto mergedPalette = style()->paletteForControlType(
this->controlType());
892 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
895 const auto controlPalette = m_palette->toQPalette();
896 mergedPalette = controlPalette.resolve(mergedPalette);
899 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
901 if (m_effectivePalette == mergedPalette)
904 m_effectivePalette = mergedPalette;
908QFont QQStyleKitReader::font()
const
913bool QQStyleKitReader::rebuildEffectiveFont()
915 const QQStyleKitStyle *currentStyle = style();
916 if (!currentStyle || !currentStyle->loaded())
922 QFont font = currentStyle->fontForControlType(controlType());
923 const QQStyleKitTextProperties *textProps = global()->text();
925 if (textProps->isDefined(QQSK::Property::Bold))
926 font.setBold(textProps->bold());
927 if (textProps->isDefined(QQSK::Property::Italic))
928 font.setItalic(textProps->italic());
929 if (textProps->isDefined(QQSK::Property::PointSize))
930 font.setPointSizeF(textProps->pointSize());
941QQStyleKitControlProperties *QQStyleKitReader::global()
const
943 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
946void QQStyleKitReader::componentComplete()
953#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