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
97
98
99
100
101
102
103
104
105
106
109
110
111
112
113
114
115
116
117
118
121
122
123
124
125
126
127
128
129
130
133
134
135
136
137
138
139
140
141
142
145
146
147
148
149
150
151
152
153
154
157
158
159
160
161
162
163
164
165
166
169
170
171
172
173
174
175
176
177
178
181
182
183
184
185
186
187
188
189
192
193
194
195
196
197
198
199
200
201
202
203
204
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
226using namespace Qt::StringLiterals;
239 if (t->isDefined(QQSK::Property::Bold)) {
240 sig |= (quint64(1) << 0);
241 if (t->styleProperty<
bool>(QQSK::Property::Bold))
242 sig |= (quint64(1) << 1);
245 if (t->isDefined(QQSK::Property::Italic)) {
246 sig |= (quint64(1) << 2);
247 if (t->styleProperty<
bool>(QQSK::Property::Italic))
248 sig |= (quint64(1) << 3);
251 if (t->isDefined(QQSK::Property::PointSize)) {
252 sig |= (quint64(1) << 4);
253 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
255 constexpr int payloadBits = 64 - 5;
256 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
257 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
263QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
264QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
266QQStyleKitReader::QQStyleKitReader(QObject *parent)
267 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
268 , m_dontEmitChangedSignals(
false)
269 , m_effectiveVariationsDirty(
true)
270 , m_transitionsEnabled(
true)
271 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
273 s_allReaders.append(
this);
276QQStyleKitReader::~QQStyleKitReader()
278 s_allReaders.removeOne(
this);
281QQuickStateGroup *QQStyleKitReader::stateGroup()
287
288
289
290 const auto *stylePtr = style();
293 m_stateGroup =
new QQuickStateGroup(
this);
296 auto statesProp = m_stateGroup->statesProperty();
297 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
298 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
299 alternate1->setName(kAlternate1);
300 alternate2->setName(kAlternate2);
301 m_stateGroup->statesProperty().append(&statesProp, alternate1);
302 m_stateGroup->statesProperty().append(&statesProp, alternate2);
304 QQmlComponent *controlComp = createControlChangesComponent();
305 instantiatePropertyChanges(controlComp);
310QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
312 QQmlEngine *engine = qmlEngine(style());
313 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
314 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
317 const QString qmlControlCode = QString::fromUtf8(R"(
318 import QtQuick
319 PropertyChanges {
320 spacing: global.spacing
321 padding: global.padding
322 leftPadding: global.leftPadding
323 rightPadding: global.rightPadding
324 topPadding: global.topPadding
325 bottomPadding: global.bottomPadding
326 text.color: global.text.color
327 text.alignment: global.text.alignment
328 text.bold: global.text.bold
329 text.italic: global.text.italic
330 text.pointSize: global.text.pointSize
331 text.padding: global.text.padding
332 text.leftPadding: global.text.leftPadding
333 text.rightPadding: global.text.rightPadding
334 text.topPadding: global.text.topPadding
335 text.bottomPadding: global.text.bottomPadding
336 }
337 )");
340 QQmlComponent *component =
new QQmlComponent(engine);
341 component->setData(qmlControlCode.toUtf8(), QUrl());
342 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
343 s_propertyChangesComponents.insert(key, component);
344 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
345 s_propertyChangesComponents.remove(key);
350QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
352 QQmlEngine *engine = qmlEngine(style());
353 auto key = PropertyChangesComponents::key_type{engine, delegateName};
354 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
357 static const QString qmlTemplateCode = QString::fromUtf8(R"(
358 import QtQuick
359 PropertyChanges { $ {
360 implicitWidth: global.$.implicitWidth
361 implicitHeight: global.$.implicitHeight
362 visible: global.$.visible
363 color: global.$.color
364 gradient: global.$.gradient
365 radius: global.$.radius
366 topLeftRadius: global.$.topLeftRadius
367 topRightRadius: global.$.topRightRadius
368 bottomLeftRadius: global.$.bottomLeftRadius
369 bottomRightRadius: global.$.bottomRightRadius
370 margins: global.$.margins
371 alignment: global.$.alignment
372 leftMargin: global.$.leftMargin
373 rightMargin: global.$.rightMargin
374 topMargin: global.$.topMargin
375 bottomMargin: global.$.bottomMargin
376 scale: global.$.scale
377 rotation: global.$.rotation
378 opacity: global.$.opacity
379 border.color: global.$.border.color
380 border.width: global.$.border.width
381 shadow.color: global.$.shadow.color
382 shadow.scale: global.$.shadow.scale
383 shadow.blur: global.$.shadow.blur
384 shadow.visible: global.$.shadow.visible
385 shadow.opacity: global.$.shadow.opacity
386 shadow.verticalOffset: global.$.shadow.verticalOffset
387 shadow.horizontalOffset: global.$.shadow.horizontalOffset
388 shadow.delegate: global.$.shadow.delegate
389 image.source: global.$.image.source
390 image.color: global.$.image.color
391 image.fillMode: global.$.image.fillMode
392 delegate: global.$.delegate
393 data: global.$.data
394 }}
395 )");
397 QString substitutedCode = qmlTemplateCode;
398 substitutedCode.replace(
'$'_L1, delegateName);
399 QQmlComponent *component =
new QQmlComponent(engine);
400 component->setData(substitutedCode.toUtf8(), QUrl());
401 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
402 s_propertyChangesComponents.insert(key, component);
403 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
404 s_propertyChangesComponents.remove(key);
409void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
411 QObject *obj = comp->create(qmlContext(
this));
412 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
413 Q_ASSERT(propertyChanges);
416 propertyChanges->setObject(
this);
418
419
420
421
422
423 propertyChanges->setIsExplicit(
true);
425
426
427 propertyChanges->setRestoreEntryValues(
false);
430 for (QQuickState *state : stateGroup()->states()) {
431 auto changesProp = state->changes();
432 changesProp.append(&changesProp, propertyChanges);
436void QQStyleKitReader::maybeTrackDelegates()
439 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
440 if (m_trackedDelegates.testFlag(type)) {
444 if (!delegate->visible()) {
446
447
451
452
453
454
455 m_trackedDelegates.setFlag(type);
456 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
457 instantiatePropertyChanges(comp);
461void QQStyleKitReader::updateControl()
463 const QQStyleKitStyle *currentStyle = style();
464 if (!currentStyle || !currentStyle->loaded())
468
469
470
471
472
473
474
475
476
477
478
480 maybeTrackDelegates();
482 auto transitionProp = stateGroup()->transitionsProperty();
483 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
484 const bool enabled = m_transitionsEnabled && QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
485 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
486 QQuickTransition *transitionInStateGroup =
487 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
488 if (transitionInStyle != transitionInStateGroup) {
489 transitionProp.clear(&transitionProp);
490 if (transitionInStyle)
491 transitionProp.append(&transitionProp, transitionInStyle);
494 switch (m_alternateState) {
495 case AlternateState::Alternate1:
496 m_alternateState = AlternateState::Alternate2;
497 stateGroup()->setState(kAlternate2);
499 case AlternateState::Alternate2:
500 m_alternateState = AlternateState::Alternate1;
501 stateGroup()->setState(kAlternate1);
507 auto textOverrideSig = textFontOverridesSignature(global()->text());
508 if (m_lastTextFontOverridesSignature != textOverrideSig)
510 m_lastTextFontOverridesSignature = textOverrideSig;
511 rebuildEffectiveFont();
514void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
516 for (QQStyleKitReader *reader : s_allReaders) {
517 if (reader->style() == style) {
518 reader->m_effectiveVariationsDirty =
true;
519 reader->m_fontDirty =
true;
520 reader->clearLocalStorage();
521 reader->rebuildEffectivePalette();
522 reader->rebuildEffectiveFont();
523 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
528void QQStyleKitReader::populateLocalStorage()
530 if (!m_storage.isEmpty())
532 const auto *stylePtr = style();
533 if (!stylePtr || !stylePtr->loaded())
537
538
539
544
546
547
548
549
550 m_dontEmitChangedSignals =
true;
552 m_dontEmitChangedSignals =
false;
555void QQStyleKitReader::clearLocalStorage()
558
559
560
564QQSK::State QQStyleKitReader::controlState()
const
566 QQSK::State effectiveState = m_state;
570 effectiveState &= ~(QQSK::StateFlag::Pressed |
571 QQSK::StateFlag::Hovered |
572 QQSK::StateFlag::Highlighted |
573 QQSK::StateFlag::Focused |
574 QQSK::StateFlag::Hovered);
577 if (effectiveState == QQSK::StateFlag::Unspecified)
578 effectiveState.setFlag(QQSK::StateFlag::Normal);
580 return effectiveState;
583QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
585 return m_storage.value(key);
588void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
590 m_storage.insert(key, value);
593bool QQStyleKitReader::dontEmitChangedSignals()
const
595 return m_dontEmitChangedSignals;
598QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
603void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
609 populateLocalStorage();
610 emit controlTypeChanged();
615QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
618
620 return ControlType(m_type);
624bool QQStyleKitReader::hovered()
const
626 return m_state.testFlag(QQSK::StateFlag::Hovered);
629void QQStyleKitReader::setHovered(
bool hovered)
631 if (hovered == QQStyleKitReader::hovered())
634 populateLocalStorage();
635 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
636 emit hoveredChanged();
640bool QQStyleKitReader::enabled()
const
642 return !m_state.testFlag(QQSK::StateFlag::Disabled);
645void QQStyleKitReader::setEnabled(
bool enabled)
647 if (enabled == QQStyleKitReader::enabled())
650 populateLocalStorage();
651 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
652 emit enabledChanged();
656bool QQStyleKitReader::focused()
const
658 return m_state.testFlag(QQSK::StateFlag::Focused);
661void QQStyleKitReader::setFocused(
bool focused)
663 if (focused == QQStyleKitReader::focused())
666 populateLocalStorage();
667 m_state.setFlag(QQSK::StateFlag::Focused, focused);
668 emit focusedChanged();
672bool QQStyleKitReader::checked()
const
674 return m_state.testFlag(QQSK::StateFlag::Checked);
677void QQStyleKitReader::setChecked(
bool checked)
679 if (checked == QQStyleKitReader::checked())
682 populateLocalStorage();
683 m_state.setFlag(QQSK::StateFlag::Checked, checked);
684 emit checkedChanged();
688bool QQStyleKitReader::pressed()
const
690 return m_state.testFlag(QQSK::StateFlag::Pressed);
693void QQStyleKitReader::setPressed(
bool pressed)
695 if (pressed == QQStyleKitReader::pressed())
698 populateLocalStorage();
699 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
700 emit pressedChanged();
704bool QQStyleKitReader::vertical()
const
706 return m_state.testFlag(QQSK::StateFlag::Vertical);
709void QQStyleKitReader::setVertical(
bool vertical)
711 if (vertical == QQStyleKitReader::vertical())
714 populateLocalStorage();
715 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
716 emit verticalChanged();
720bool QQStyleKitReader::highlighted()
const
722 return m_state.testFlag(QQSK::StateFlag::Highlighted);
725void QQStyleKitReader::setHighlighted(
bool highlighted)
727 if (highlighted == QQStyleKitReader::highlighted())
730 populateLocalStorage();
731 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
732 emit highlightedChanged();
736void QQStyleKitReader::setControlTypeAndState(QQStyleKitExtendableControlType controlType, QQSK::State flags)
740 const bool typeChanged = m_type != controlType;
741 const QQSK::State stateChanged = m_state ^ flags;
743 if (!typeChanged && !stateChanged)
746 populateLocalStorage();
748 m_type = controlType;
752 emit controlTypeChanged();
754 auto emitChanged = [
this, &stateChanged](QQSK::StateFlag flag,
void (QQStyleKitReader::*signal)()) {
755 if (stateChanged.testFlag(flag))
758 emitChanged(QQSK::StateFlag::Hovered, &QQStyleKitReader::hoveredChanged);
759 emitChanged(QQSK::StateFlag::Disabled, &QQStyleKitReader::enabledChanged);
760 emitChanged(QQSK::StateFlag::Focused, &QQStyleKitReader::focusedChanged);
761 emitChanged(QQSK::StateFlag::Checked, &QQStyleKitReader::checkedChanged);
762 emitChanged(QQSK::StateFlag::Pressed, &QQStyleKitReader::pressedChanged);
763 emitChanged(QQSK::StateFlag::Vertical, &QQStyleKitReader::verticalChanged);
764 emitChanged(QQSK::StateFlag::Highlighted, &QQStyleKitReader::highlightedChanged);
769QObject *QQStyleKitReader::target()
const
771 return m_target.data();
774void QQStyleKitReader::setTarget(QObject *target)
777
778
779
780
784bool QQStyleKitReader::transitionsEnabled()
const
786 return m_transitionsEnabled;
789void QQStyleKitReader::setTransitionsEnabled(
bool enabled)
791 if (m_transitionsEnabled == enabled)
793 m_transitionsEnabled = enabled;
796QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
798 return m_explicitStyle.data();
801void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
803 if (m_explicitStyle == style)
805 m_explicitStyle = style;
807 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
812 m_effectiveVariationsDirty =
true;
815 rebuildEffectivePalette();
816 rebuildEffectiveFont();
817 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
820QQuickPalette *QQStyleKitReader::palette()
const
822 return m_palette.data();
825void QQStyleKitReader::setPalette(QQuickPalette *palette)
827 if (m_palette == palette)
831 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
834 emit paletteChanged();
838 QObject::connect(m_palette, &QQuickPalette::changed,
839 this, &QQStyleKitReader::onPaletteChanged);
845QPalette QQStyleKitReader::effectivePalette()
const
847 return m_effectivePalette;
850void QQStyleKitReader::onPaletteChanged()
852 const QQStyleKitStyle *currentStyle = style();
853 if (!currentStyle || !currentStyle->loaded())
856 if (rebuildEffectivePalette()) {
858 emitChangedForAllStyleProperties(EmitFlag::Colors);
862bool QQStyleKitReader::rebuildEffectivePalette()
864 auto mergedPalette = style()->paletteForControlType(
this->controlType());
865 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
868 const auto controlPalette = m_palette->toQPalette();
869 mergedPalette = controlPalette.resolve(mergedPalette);
872 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
874 if (m_effectivePalette == mergedPalette)
877 m_effectivePalette = mergedPalette;
881QFont QQStyleKitReader::font()
const
886bool QQStyleKitReader::rebuildEffectiveFont()
888 const QQStyleKitStyle *currentStyle = style();
889 if (!currentStyle || !currentStyle->loaded())
895 QFont font = currentStyle->fontForControlType(controlType());
896 const QQStyleKitTextProperties *textProps = global()->text();
898 if (textProps->isDefined(QQSK::Property::Bold))
899 font.setBold(textProps->bold());
900 if (textProps->isDefined(QQSK::Property::Italic))
901 font.setItalic(textProps->italic());
902 if (textProps->isDefined(QQSK::Property::PointSize))
903 font.setPointSizeF(textProps->pointSize());
914QQStyleKitControlProperties *QQStyleKitReader::global()
const
916 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
921#include "moc_qqstylekitreader_p.cpp"
Combined button and popup list for selecting options.
static quint64 textFontOverridesSignature(const QQStyleKitTextProperties *t)
static const QString kAlternate2
static const QString kAlternate1