12#include <QtQuickTemplates2/private/qquickcontrol_p.h>
13#include <QtCore/QScopedValueRollback>
23 QQStyleKitExtendableControlType exactType)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
49 case QQStyleKitReader::ApplicationWindow: {
50 static QList<QQStyleKitExtendableControlType> t =
51 { QQStyleKitReader::ApplicationWindow };
53 case QQStyleKitReader::Button:
54 case QQStyleKitReader::DelayButton:
55 case QQStyleKitReader::FlatButton:
56 case QQStyleKitReader::ToolButton:
57 case QQStyleKitReader::TabButton:
58 case QQStyleKitReader::RadioButton:
59 case QQStyleKitReader::RoundButton:
60 case QQStyleKitReader::CheckBox:
61 case QQStyleKitReader::SwitchControl: {
62 static QList<QQStyleKitExtendableControlType> t =
63 { QQStyleKitReader::AbstractButton, QQStyleKitReader::Control };
65 case QQStyleKitReader::CheckDelegate:
66 case QQStyleKitReader::RadioDelegate:
67 case QQStyleKitReader::SwipeDelegate:
68 case QQStyleKitReader::SwitchDelegate: {
69 static QList<QQStyleKitExtendableControlType> t =
70 { QQStyleKitReader::ItemDelegate, QQStyleKitReader::Control };
72 case QQStyleKitReader::Menu:
73 case QQStyleKitReader::Dialog: {
74 static QList<QQStyleKitExtendableControlType> t =
75 { QQStyleKitReader::Popup, QQStyleKitReader::Control };
77 case QQStyleKitReader::Page:
78 case QQStyleKitReader::DialogButtonBox:
79 case QQStyleKitReader::Frame:
80 case QQStyleKitReader::TabBar:
81 case QQStyleKitReader::ToolBar: {
82 static QList<QQStyleKitExtendableControlType> t =
83 { QQStyleKitReader::Pane, QQStyleKitReader::Control };
85 case QQStyleKitReader::GroupBox: {
86 static QList<QQStyleKitExtendableControlType> t =
87 { QQStyleKitReader::Frame, QQStyleKitReader::Pane, QQStyleKitReader::Control };
90 case QQStyleKitReader::TextField:
91 case QQStyleKitReader::TextArea: {
92 static QList<QQStyleKitExtendableControlType> t =
93 { QQStyleKitReader::TextInput, QQStyleKitReader::Control };
96 static QList<QQStyleKitExtendableControlType> t =
97 { QQStyleKitReader::Control };
107 Q_ASSERT(state != QQSK::StateFlag::Unspecified);
108 if (state == s_cachedState)
111 s_cachedState = state;
114
115
116
117
118 s_cachedStateList.clear();
119 if (state.testFlag(QQSK::StateFlag::Pressed))
120 s_cachedStateList.append(QQSK::StateFlag::Pressed);
121 if (state.testFlag(QQSK::StateFlag::Hovered))
122 s_cachedStateList.append(QQSK::StateFlag::Hovered);
123 if (state.testFlag(QQSK::StateFlag::Highlighted))
124 s_cachedStateList.append(QQSK::StateFlag::Highlighted);
125 if (state.testFlag(QQSK::StateFlag::Focused))
126 s_cachedStateList.append(QQSK::StateFlag::Focused);
127 if (state.testFlag(QQSK::StateFlag::Checked))
128 s_cachedStateList.append(QQSK::StateFlag::Checked);
129 if (state.testFlag(QQSK::StateFlag::Vertical))
130 s_cachedStateList.append(QQSK::StateFlag::Vertical);
131 if (state.testFlag(QQSK::StateFlag::Disabled))
132 s_cachedStateList.append(QQSK::StateFlag::Disabled);
136 QQStyleKitReader *styleReader,
141
142
143
144 if (!styleReader->m_effectiveVariations.contains(variation))
145 styleReader->m_effectiveVariations.append(variation);
148
149
150
151 if (!variation->m_usageContext.contains(styleOrTheme))
152 variation->m_usageContext.append(styleOrTheme);
156 QQStyleKitReader *styleReader,
158 const AttachedVariationList &attachedVariations)
160 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
161 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
163 static PropertyPathIds ids;
164 if (ids.property.property() == QQSK::Property::NoProperty) {
166
167
168 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
169 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
174 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
175 const auto parentType = attached->controlType();
176 const auto parentBaseTypes = baseTypesForType(parentType);
179
180
181
182 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
183 if (!typeVariationsVariant.isValid())
186 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
188 for (QQStyleKitVariation *variation : typeVariations) {
190
191
194
198 if (variation->getControlStyle(styleReaderType)) {
199 addVariationToReader(styleReader, styleOrTheme, variation);
201 for (
int type : styleReaderBaseType) {
202 if (variation->getControlStyle(type))
203 addVariationToReader(styleReader, styleOrTheme, variation);
211 QQStyleKitReader *styleReader,
213 const AttachedVariationList &attachedVariations)
216
217
218
219
220 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
221 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
223 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
224 for (
const QString &instanceVariationName : attached->variations()) {
225 for (QQStyleKitVariation *variation : styleOrTheme->m_styleVariations) {
226 if (variation->name() != instanceVariationName)
230
231
232
233 if (variation->getControlStyle(styleReaderType)) {
234 addVariationToReader(styleReader, styleOrTheme, variation);
236 for (
int baseType : styleReaderBaseTypes) {
237 if (variation->getControlStyle(baseType))
238 addVariationToReader(styleReader, styleOrTheme, variation);
247 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
250
251
252
253
254
255
256 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
257 styleReader->m_effectiveVariationsDirty =
false;
258 styleReader->m_effectiveVariations.clear();
260 if (!style->m_hasVariations)
264
265
266 AttachedVariationList attachedVariations;
267 for (QObject *current = styleReader; current; current = current->parent()) {
268 if (
const QObject *attachedObject = qmlAttachedPropertiesObject<QQStyleKitVariation>(current,
false)) {
270 attachedVariations.append(attached);
274 if (attachedVariations.isEmpty())
277 for (QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
279 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
280 addTypeVariationsToReader(styleReader, theme, attachedVariations);
282 addInstanceVariationsToReader(styleReader, current, attachedVariations);
283 addTypeVariationsToReader(styleReader, current, attachedVariations);
290 const T *storageProvider, QQSK::State state)
293
294
295
296
297
298
299
300
301
302 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
304 const PropertyStorageId propertyKey = main.storageId(state);
307 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
309 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
310 if (propertyValue.isValid()) {
312 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
313 return propertyValue;
316 const PropertyStorageId altPropertyKey = alternative.storageId(state);
319 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
321 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
322 if (altValue.isValid()) {
324 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
331template <
class INDICES_CONTAINER>
335 int startIndex,
int recursionLevel)
337 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
339
340
341
342
343
344
345
346 stateListIndices[recursionLevel] = i;
347 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
350
351 if (!control->m_writtenStates.testFlag(stateFlag))
355
357 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
358 if (!statesAffectingProperty.testFlag(stateFlag)) {
359 if (alternative.property() == QQSK::Property::NoProperty) {
362 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
363 if (!statesAffectingAlternative.testFlag(stateFlag))
368 if (recursionLevel < s_cachedStateList.length() - 1) {
370 const QVariant value = readPropertyInControlForStates(
371 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
377 QQSK::State storageState = QQSK::StateFlag::Unspecified;
378 for (
int j = 0; j <= recursionLevel; ++j)
379 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
380 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
392
393
394
395
396 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
398 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
399 if (s_cachedState != QQSK::StateFlag::Normal) {
400 QVariant value = readPropertyInControlForStates(
401 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
406 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
407 const QVariant value = readPropertyInStorageForState(
408 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
414 if (s_cachedState != QQSK::StateFlag::Normal) {
415 const QVariant value = readPropertyInControlForStates(
416 ids.property, ids.alternative, control, stateListIndices, 0, 0);
422
423
424
425 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
426 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
433 const QQStyleKitExtendableControlType exactType,
434 const QList<QQStyleKitExtendableControlType> baseTypes)
440
442 const auto writtenProperties = controls->m_writtenPropertyPaths;
443 if (writtenProperties.contains(ids.property.pathId()))
445 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
446 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
448 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
450 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
452 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
458 const QVariant value = readPropertyInControl(ids, control);
463 for (
const int type : baseTypes) {
464 if (
const QQStyleKitControl *control = controls->getControlStyle(type)) {
465 const QVariant value = readPropertyInControl(ids, control);
475 const QList<QPointer<QQStyleKitVariation>> &variations,
477 const PropertyPathIds &ids,
478 const QQStyleKitExtendableControlType exactType,
479 const QList<QQStyleKitExtendableControlType> baseTypes)
481 bool foundAtLeastOneVariation =
false;
482 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
485 if (!variation->m_usageContext.contains(styleOrTheme)) {
486 if (foundAtLeastOneVariation) {
488
489
490
494
497 foundAtLeastOneVariation =
true;
498 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
506 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
509
510
511 style->syncFromQPalette(styleReader->effectivePalette());
514
515
516 cacheReaderState(styleReader->controlState());
518 if (styleReader->m_effectiveVariationsDirty)
519 rebuildVariationsForReader(styleReader, style);
521 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
522 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
527 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
531 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
535 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
539 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
543 if (
auto *fallbackStyle = style->fallbackStyle()) {
545
546 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
555 if (!value.isValid())
564 const QQSK::Property property,
565 const QQSK::Property alternative)
568 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
569 const QQSK::Subclass subclass = controlProperties->subclass();
571 if (subclass != QQSK::Subclass::QQStyleKitReader) {
573
574
575
576
577
578
579
580 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
583 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
584 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
585 return control->readStyleProperty(key);
588 QQStyleKitStyle *style = controlProperties->style();
589 if (!style || !style->loaded()) {
591
592
593
598 QQStyleKitReader *styleReader = controlProperties->asQQStyleKitReader();
600 if (s_isReadingProperty) {
601 if (!s_styleWarningsIssued) {
602 s_styleWarningsIssued =
true;
603 qmlWarning(styleReader) <<
"The style property '" << property <<
"' was read "
604 <<
"before finishing the read of another style property. "
605 <<
"This is likely to cause a style glitch.";
608 QScopedValueRollback rollback(s_isReadingProperty,
true);
611 ids.property = group->propertyPathId(property, PropertyPathId::Flag::ExcludeSubtype);
612 ids.alternative = group->propertyPathId(alternative, PropertyPathId::Flag::ExcludeSubtype);
613 const bool insideSubType = pathFlags &
614 (QQSK::PropertyPathFlag::DelegateSubtype1 | QQSK::PropertyPathFlag::DelegateSubtype2);
617 ids.subTypeProperty = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
618 ids.subTypeAlternative = group->propertyPathId(alternative, PropertyPathId::Flag::IncludeSubtype);
624 if (!pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
626
627
628
629
631 const QVariant value = readPropertyInStorageForState(
632 ids.subTypeProperty, ids.subTypeAlternative, styleReader, QQSK::StateFlag::Normal);
636 const QVariant value = readPropertyInStorageForState(
637 ids.property, ids.alternative, styleReader, QQSK::StateFlag::Normal);
642 return readPropertyInStyle(style, ids, styleReader);
647 const QQSK::Property property,
648 const QVariant &value)
654 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
655 const QQSK::Subclass subclass = controlProperties->subclass();
656 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
658 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
659 qmlWarning(controlProperties) <<
"Properties inside 'global' are read-only!";
663 if (subclass == QQSK::Subclass::QQStyleKitReader) {
665 QQStyleKitReader *reader = controlProperties->asQQStyleKitReader();
666 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
667 const QVariant currentValue = reader->readStyleProperty(key);
668 const bool valueChanged = currentValue != value;
670 reader->writeStyleProperty(key, value);
671 QQStyleKitDebug::notifyPropertyWrite(group, property, reader, QQSK::StateFlag::Normal, key, value);
676 if (subclass == QQSK::Subclass::QQStyleKitState) {
680 const QQSK::State nestedState = controlState->nestedState();
681 const PropertyStorageId key = propertyPathId.storageId(nestedState);
682 const QVariant currentValue = control->readStyleProperty(key);
683 const bool valueChanged = currentValue != value;
686
687
688 control->m_writtenStates |= nestedState;
690
691
692
694 const QQSK::State alreadyWrittenStates = controls->m_writtenPropertyPaths[propertyPathId.pathId()];
695 controls->m_writtenPropertyPaths[propertyPathId.pathId()] = alreadyWrittenStates | nestedState;
697 control->writeStyleProperty(key, value);
698 QQStyleKitDebug::notifyPropertyWrite(group, property, control, nestedState, key, value);
709 const QQSK::Property property)
713 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
714 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
715 const QQSK::Subclass subclass = controlProperties->subclass();
717 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global))
720 if (subclass == QQSK::Subclass::QQStyleKitReader) {
721 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
722 return controlProperties->asQQStyleKitReader()->readStyleProperty(key).isValid();
725 if (subclass == QQSK::Subclass::QQStyleKitState) {
728 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
729 return control->readStyleProperty(key).isValid();
738#include "moc_qqstylekitpropertyresolver_p.cpp"
QQStyleKitControl * control() const
QQStyleKitControlProperties * controlProperties() const
Combined button and popup list for selecting options.