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
57
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
96
97
98
99
100
101
102
103
104
105
108
109
110
111
112
113
114
115
116
117
120
121
122
123
124
125
126
127
128
129
132
133
134
135
136
137
138
139
140
141
144
145
146
147
148
149
150
151
152
153
156
157
158
159
160
161
162
163
164
165
168
169
170
171
172
173
174
175
176
177
180
181
182
183
184
185
186
187
188
191
192
193
194
195
196
197
198
199
200
201
202
203
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
225using namespace Qt::StringLiterals;
238 if (t->isDefined(QQSK::Property::Bold)) {
239 sig |= (quint64(1) << 0);
240 if (t->styleProperty<
bool>(QQSK::Property::Bold))
241 sig |= (quint64(1) << 1);
244 if (t->isDefined(QQSK::Property::Italic)) {
245 sig |= (quint64(1) << 2);
246 if (t->styleProperty<
bool>(QQSK::Property::Italic))
247 sig |= (quint64(1) << 3);
250 if (t->isDefined(QQSK::Property::PointSize)) {
251 sig |= (quint64(1) << 4);
252 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
254 constexpr int payloadBits = 64 - 5;
255 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
256 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
262QList<QQStyleKitReader *> QQStyleKitReader::s_allReaders;
263QQStyleKitReader::PropertyChangesComponents QQStyleKitReader::s_propertyChangesComponents;
265QQStyleKitReader::QQStyleKitReader(QObject *parent)
266 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
267 , m_dontEmitChangedSignals(
false)
268 , m_effectiveVariationsDirty(
true)
269 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
271 s_allReaders.append(
this);
274QQStyleKitReader::~QQStyleKitReader()
276 s_allReaders.removeOne(
this);
279QQuickStateGroup *QQStyleKitReader::stateGroup()
285
286
287
288 const auto *stylePtr = style();
291 m_stateGroup =
new QQuickStateGroup(
this);
294 auto statesProp = m_stateGroup->statesProperty();
295 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
296 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
297 alternate1->setName(kAlternate1);
298 alternate2->setName(kAlternate2);
299 m_stateGroup->statesProperty().append(&statesProp, alternate1);
300 m_stateGroup->statesProperty().append(&statesProp, alternate2);
302 QQmlComponent *controlComp = createControlChangesComponent();
303 instantiatePropertyChanges(controlComp);
308QQmlComponent *QQStyleKitReader::createControlChangesComponent()
const
310 QQmlEngine *engine = qmlEngine(style());
311 auto key = PropertyChangesComponents::key_type{engine, u"control"_s};
312 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
315 const QString qmlControlCode = QString::fromUtf8(R"(
316 import QtQuick
317 PropertyChanges {
318 spacing: global.spacing
319 padding: global.padding
320 leftPadding: global.leftPadding
321 rightPadding: global.rightPadding
322 topPadding: global.topPadding
323 bottomPadding: global.bottomPadding
324 text.color: global.text.color
325 text.alignment: global.text.alignment
326 text.bold: global.text.bold
327 text.italic: global.text.italic
328 text.pointSize: global.text.pointSize
329 text.padding: global.text.padding
330 text.leftPadding: global.text.leftPadding
331 text.rightPadding: global.text.rightPadding
332 text.topPadding: global.text.topPadding
333 text.bottomPadding: global.text.bottomPadding
334 }
335 )");
338 QQmlComponent *component =
new QQmlComponent(engine);
339 component->setData(qmlControlCode.toUtf8(), QUrl());
340 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
341 s_propertyChangesComponents.insert(key, component);
342 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
343 s_propertyChangesComponents.remove(key);
348QQmlComponent *QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
350 QQmlEngine *engine = qmlEngine(style());
351 auto key = PropertyChangesComponents::key_type{engine, delegateName};
352 if (
auto r = s_propertyChangesComponents.value(key,
nullptr))
355 static const QString qmlTemplateCode = QString::fromUtf8(R"(
356 import QtQuick
357 PropertyChanges { $ {
358 implicitWidth: global.$.implicitWidth
359 implicitHeight: global.$.implicitHeight
360 visible: global.$.visible
361 color: global.$.color
362 gradient: global.$.gradient
363 radius: global.$.radius
364 topLeftRadius: global.$.topLeftRadius
365 topRightRadius: global.$.topRightRadius
366 bottomLeftRadius: global.$.bottomLeftRadius
367 bottomRightRadius: global.$.bottomRightRadius
368 margins: global.$.margins
369 alignment: global.$.alignment
370 leftMargin: global.$.leftMargin
371 rightMargin: global.$.rightMargin
372 topMargin: global.$.topMargin
373 bottomMargin: global.$.bottomMargin
374 scale: global.$.scale
375 rotation: global.$.rotation
376 opacity: global.$.opacity
377 border.color: global.$.border.color
378 border.width: global.$.border.width
379 shadow.color: global.$.shadow.color
380 shadow.scale: global.$.shadow.scale
381 shadow.blur: global.$.shadow.blur
382 shadow.visible: global.$.shadow.visible
383 shadow.opacity: global.$.shadow.opacity
384 shadow.verticalOffset: global.$.shadow.verticalOffset
385 shadow.horizontalOffset: global.$.shadow.horizontalOffset
386 shadow.delegate: global.$.shadow.delegate
387 image.source: global.$.image.source
388 image.color: global.$.image.color
389 image.fillMode: global.$.image.fillMode
390 delegate: global.$.delegate
391 data: global.$.data
392 }}
393 )");
395 QString substitutedCode = qmlTemplateCode;
396 substitutedCode.replace(
'$'_L1, delegateName);
397 QQmlComponent *component =
new QQmlComponent(engine);
398 component->setData(substitutedCode.toUtf8(), QUrl());
399 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
400 s_propertyChangesComponents.insert(key, component);
401 QObject::connect(engine, &QObject::destroyed, engine, [key = std::move(key)] {
402 s_propertyChangesComponents.remove(key);
407void QQStyleKitReader::instantiatePropertyChanges(QQmlComponent *comp)
409 QObject *obj = comp->create(qmlContext(
this));
410 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
411 Q_ASSERT(propertyChanges);
414 propertyChanges->setObject(
this);
416
417
418
419
420
421 propertyChanges->setIsExplicit(
true);
423
424
425 propertyChanges->setRestoreEntryValues(
false);
428 for (QQuickState *state : stateGroup()->states()) {
429 auto changesProp = state->changes();
430 changesProp.append(&changesProp, propertyChanges);
434void QQStyleKitReader::maybeTrackDelegates()
437 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
438 if (m_trackedDelegates.testFlag(type)) {
442 if (!delegate->visible()) {
444
445
449
450
451
452
453 m_trackedDelegates.setFlag(type);
454 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
455 instantiatePropertyChanges(comp);
459void QQStyleKitReader::updateControl()
461 const QQStyleKitStyle *currentStyle = style();
462 if (!currentStyle || !currentStyle->loaded())
466
467
468
469
470
471
472
473
474
475
476
478 maybeTrackDelegates();
480 auto transitionProp = stateGroup()->transitionsProperty();
481 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
482 const bool enabled = QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
483 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
484 QQuickTransition *transitionInStateGroup =
485 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
486 if (transitionInStyle != transitionInStateGroup) {
487 transitionProp.clear(&transitionProp);
488 if (transitionInStyle)
489 transitionProp.append(&transitionProp, transitionInStyle);
492 switch (m_alternateState) {
493 case AlternateState::Alternate1:
494 m_alternateState = AlternateState::Alternate2;
495 stateGroup()->setState(kAlternate2);
497 case AlternateState::Alternate2:
498 m_alternateState = AlternateState::Alternate1;
499 stateGroup()->setState(kAlternate1);
505 auto textOverrideSig = textFontOverridesSignature(global()->text());
506 if (m_lastTextFontOverridesSignature != textOverrideSig)
508 m_lastTextFontOverridesSignature = textOverrideSig;
509 rebuildEffectiveFont();
512void QQStyleKitReader::resetReadersForStyle(
const QQStyleKitStyle *style)
514 for (QQStyleKitReader *reader : s_allReaders) {
515 if (reader->style() == style) {
516 reader->m_effectiveVariationsDirty =
true;
517 reader->m_fontDirty =
true;
518 reader->clearLocalStorage();
519 reader->rebuildEffectivePalette();
520 reader->rebuildEffectiveFont();
521 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
526void QQStyleKitReader::populateLocalStorage()
528 if (!m_storage.isEmpty())
530 const auto *stylePtr = style();
531 if (!stylePtr || !stylePtr->loaded())
535
536
537
542
544
545
546
547
548 m_dontEmitChangedSignals =
true;
550 m_dontEmitChangedSignals =
false;
553void QQStyleKitReader::clearLocalStorage()
556
557
558
562QQSK::State QQStyleKitReader::controlState()
const
564 QQSK::State effectiveState = m_state;
568 effectiveState &= ~(QQSK::StateFlag::Pressed |
569 QQSK::StateFlag::Hovered |
570 QQSK::StateFlag::Highlighted |
571 QQSK::StateFlag::Focused |
572 QQSK::StateFlag::Hovered);
575 if (effectiveState == QQSK::StateFlag::Unspecified)
576 effectiveState.setFlag(QQSK::StateFlag::Normal);
578 return effectiveState;
581QVariant QQStyleKitReader::readStyleProperty(PropertyStorageId key)
const
583 return m_storage.value(key);
586void QQStyleKitReader::writeStyleProperty(PropertyStorageId key,
const QVariant &value)
588 m_storage.insert(key, value);
591bool QQStyleKitReader::dontEmitChangedSignals()
const
593 return m_dontEmitChangedSignals;
596QQStyleKitExtendableControlType QQStyleKitReader::controlType()
const
601void QQStyleKitReader::setControlType(QQStyleKitExtendableControlType type)
607 populateLocalStorage();
608 emit controlTypeChanged();
613QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
616
618 return ControlType(m_type);
622bool QQStyleKitReader::hovered()
const
624 return m_state.testFlag(QQSK::StateFlag::Hovered);
627void QQStyleKitReader::setHovered(
bool hovered)
629 if (hovered == QQStyleKitReader::hovered())
632 populateLocalStorage();
633 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
634 emit hoveredChanged();
638bool QQStyleKitReader::enabled()
const
640 return !m_state.testFlag(QQSK::StateFlag::Disabled);
643void QQStyleKitReader::setEnabled(
bool enabled)
645 if (enabled == QQStyleKitReader::enabled())
648 populateLocalStorage();
649 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
650 emit enabledChanged();
654bool QQStyleKitReader::focused()
const
656 return m_state.testFlag(QQSK::StateFlag::Focused);
659void QQStyleKitReader::setFocused(
bool focused)
661 if (focused == QQStyleKitReader::focused())
664 populateLocalStorage();
665 m_state.setFlag(QQSK::StateFlag::Focused, focused);
666 emit focusedChanged();
670bool QQStyleKitReader::checked()
const
672 return m_state.testFlag(QQSK::StateFlag::Checked);
675void QQStyleKitReader::setChecked(
bool checked)
677 if (checked == QQStyleKitReader::checked())
680 populateLocalStorage();
681 m_state.setFlag(QQSK::StateFlag::Checked, checked);
682 emit checkedChanged();
686bool QQStyleKitReader::pressed()
const
688 return m_state.testFlag(QQSK::StateFlag::Pressed);
691void QQStyleKitReader::setPressed(
bool pressed)
693 if (pressed == QQStyleKitReader::pressed())
696 populateLocalStorage();
697 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
698 emit pressedChanged();
702bool QQStyleKitReader::vertical()
const
704 return m_state.testFlag(QQSK::StateFlag::Vertical);
707void QQStyleKitReader::setVertical(
bool vertical)
709 if (vertical == QQStyleKitReader::vertical())
712 populateLocalStorage();
713 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
714 emit verticalChanged();
718bool QQStyleKitReader::highlighted()
const
720 return m_state.testFlag(QQSK::StateFlag::Highlighted);
723void QQStyleKitReader::setHighlighted(
bool highlighted)
725 if (highlighted == QQStyleKitReader::highlighted())
728 populateLocalStorage();
729 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
730 emit highlightedChanged();
734QQStyleKitStyle *QQStyleKitReader::explicitStyle()
const
736 return m_explicitStyle.data();
739void QQStyleKitReader::setExplicitStyle(QQStyleKitStyle *style)
741 if (m_explicitStyle == style)
743 m_explicitStyle = style;
745 if (!m_explicitStyle || !m_explicitStyle->loaded()) {
750 m_effectiveVariationsDirty =
true;
753 rebuildEffectivePalette();
754 rebuildEffectiveFont();
755 emitChangedForAllStyleProperties(EmitFlag::AllProperties);
758QQuickPalette *QQStyleKitReader::palette()
const
760 return m_palette.data();
763void QQStyleKitReader::setPalette(QQuickPalette *palette)
765 if (m_palette == palette)
769 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
772 emit paletteChanged();
776 QObject::connect(m_palette, &QQuickPalette::changed,
777 this, &QQStyleKitReader::onPaletteChanged);
783QPalette QQStyleKitReader::effectivePalette()
const
785 return m_effectivePalette;
788void QQStyleKitReader::onPaletteChanged()
790 const QQStyleKitStyle *currentStyle = style();
791 if (!currentStyle || !currentStyle->loaded())
794 if (rebuildEffectivePalette()) {
796 emitChangedForAllStyleProperties(EmitFlag::Colors);
800bool QQStyleKitReader::rebuildEffectivePalette()
802 auto mergedPalette = style()->paletteForControlType(
this->controlType());
803 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
806 const auto controlPalette = m_palette->toQPalette();
807 mergedPalette = controlPalette.resolve(mergedPalette);
810 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
812 if (m_effectivePalette == mergedPalette)
815 m_effectivePalette = mergedPalette;
819QFont QQStyleKitReader::font()
const
824bool QQStyleKitReader::rebuildEffectiveFont()
826 const QQStyleKitStyle *currentStyle = style();
827 if (!currentStyle || !currentStyle->loaded())
833 QFont font = currentStyle->fontForControlType(controlType());
834 const QQStyleKitTextProperties *textProps = global()->text();
836 if (textProps->isDefined(QQSK::Property::Bold))
837 font.setBold(textProps->bold());
838 if (textProps->isDefined(QQSK::Property::Italic))
839 font.setItalic(textProps->italic());
840 if (textProps->isDefined(QQSK::Property::PointSize))
841 font.setPointSizeF(textProps->pointSize());
852QQStyleKitControlProperties *QQStyleKitReader::global()
const
854 return &
const_cast<QQStyleKitReader *>(
this)->m_global;
859#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