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::Dialog:
73 case QQStyleKitReader::Drawer:
74 case QQStyleKitReader::Menu:
75 case QQStyleKitReader::ToolTip: {
76 static QList<QQStyleKitExtendableControlType> t =
77 { QQStyleKitReader::Popup, QQStyleKitReader::Control };
79 case QQStyleKitReader::Page:
80 case QQStyleKitReader::DialogButtonBox:
81 case QQStyleKitReader::Frame:
82 case QQStyleKitReader::TabBar:
83 case QQStyleKitReader::ToolBar: {
84 static QList<QQStyleKitExtendableControlType> t =
85 { QQStyleKitReader::Pane, QQStyleKitReader::Control };
87 case QQStyleKitReader::GroupBox: {
88 static QList<QQStyleKitExtendableControlType> t =
89 { QQStyleKitReader::Frame, QQStyleKitReader::Pane, QQStyleKitReader::Control };
92 case QQStyleKitReader::TextField:
93 case QQStyleKitReader::TextArea: {
94 static QList<QQStyleKitExtendableControlType> t =
95 { QQStyleKitReader::TextInput, QQStyleKitReader::Control };
98 static QList<QQStyleKitExtendableControlType> t =
99 { QQStyleKitReader::Control };
109 Q_ASSERT(state != QQSK::StateFlag::Unspecified);
110 if (state == s_cachedState)
113 s_cachedState = state;
116
117
118
119
120 s_cachedStateList.clear();
121 if (state.testFlag(QQSK::StateFlag::Pressed))
122 s_cachedStateList.append(QQSK::StateFlag::Pressed);
123 if (state.testFlag(QQSK::StateFlag::Hovered))
124 s_cachedStateList.append(QQSK::StateFlag::Hovered);
125 if (state.testFlag(QQSK::StateFlag::Highlighted))
126 s_cachedStateList.append(QQSK::StateFlag::Highlighted);
127 if (state.testFlag(QQSK::StateFlag::Focused))
128 s_cachedStateList.append(QQSK::StateFlag::Focused);
129 if (state.testFlag(QQSK::StateFlag::Checked))
130 s_cachedStateList.append(QQSK::StateFlag::Checked);
131 if (state.testFlag(QQSK::StateFlag::Vertical))
132 s_cachedStateList.append(QQSK::StateFlag::Vertical);
133 if (state.testFlag(QQSK::StateFlag::Disabled))
134 s_cachedStateList.append(QQSK::StateFlag::Disabled);
138 QQStyleKitReader *styleReader,
143
144
145
146 if (!styleReader->m_effectiveVariations.contains(variation))
147 styleReader->m_effectiveVariations.append(variation);
150
151
152
153 if (!variation->m_usageContext.contains(styleOrTheme))
154 variation->m_usageContext.append(styleOrTheme);
158 QQStyleKitReader *styleReader,
160 const AttachedVariationList &attachedVariations)
162 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
163 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
165 static PropertyPathIds ids;
166 if (ids.property.property() == QQSK::Property::NoProperty) {
168
169
170 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
171 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
176 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
177 const auto parentType = attached->controlType();
178 const auto parentBaseTypes = baseTypesForType(parentType);
181
182
183
184 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
185 if (!typeVariationsVariant.isValid())
188 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
190 for (QQStyleKitVariation *variation : typeVariations) {
192
193
196
200 if (variation->getControlStyle(styleReaderType)) {
201 addVariationToReader(styleReader, styleOrTheme, variation);
203 for (
int type : styleReaderBaseType) {
204 if (variation->getControlStyle(type))
205 addVariationToReader(styleReader, styleOrTheme, variation);
213 QQStyleKitReader *styleReader,
215 const AttachedVariationList &attachedVariations)
218
219
220
221
222 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
223 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
225 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
226 for (
const QString &instanceVariationName : attached->variations()) {
227 for (QQStyleKitVariation *variation : styleOrTheme->m_styleVariations) {
228 if (variation->name() != instanceVariationName)
232
233
234
235 if (variation->getControlStyle(styleReaderType)) {
236 addVariationToReader(styleReader, styleOrTheme, variation);
238 for (
int baseType : styleReaderBaseTypes) {
239 if (variation->getControlStyle(baseType))
240 addVariationToReader(styleReader, styleOrTheme, variation);
249 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
252
253
254
255
256
257
258 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
259 styleReader->m_effectiveVariationsDirty =
false;
260 styleReader->m_effectiveVariations.clear();
262 if (!style->m_hasVariations)
266
267
268 AttachedVariationList attachedVariations;
269 for (QObject *current = styleReader; current; current = current->parent()) {
270 if (
const QObject *attachedObject = qmlAttachedPropertiesObject<QQStyleKitVariation>(current,
false)) {
272 attachedVariations.append(attached);
276 if (attachedVariations.isEmpty())
279 for (QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
281 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
282 addTypeVariationsToReader(styleReader, theme, attachedVariations);
284 addInstanceVariationsToReader(styleReader, current, attachedVariations);
285 addTypeVariationsToReader(styleReader, current, attachedVariations);
292 const T *storageProvider, QQSK::State state)
295
296
297
298
299
300
301
302
303
304 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
306 const PropertyStorageId propertyKey = main.storageId(state);
309 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
311 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
312 if (propertyValue.isValid()) {
314 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
315 return propertyValue;
318 const PropertyStorageId altPropertyKey = alternative.storageId(state);
321 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
323 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
324 if (altValue.isValid()) {
326 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
333template <
class INDICES_CONTAINER>
337 int startIndex,
int recursionLevel)
339 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
341
342
343
344
345
346
347
348 stateListIndices[recursionLevel] = i;
349 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
352
353 if (!control->m_writtenStates.testFlag(stateFlag))
357
359 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
360 if (!statesAffectingProperty.testFlag(stateFlag)) {
361 if (alternative.property() == QQSK::Property::NoProperty) {
364 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
365 if (!statesAffectingAlternative.testFlag(stateFlag))
370 if (recursionLevel < s_cachedStateList.length() - 1) {
372 const QVariant value = readPropertyInControlForStates(
373 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
379 QQSK::State storageState = QQSK::StateFlag::Unspecified;
380 for (
int j = 0; j <= recursionLevel; ++j)
381 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
382 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
394
395
396
397
398 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
400 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
401 if (s_cachedState != QQSK::StateFlag::Normal) {
402 QVariant value = readPropertyInControlForStates(
403 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
408 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
409 const QVariant value = readPropertyInStorageForState(
410 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
416 if (s_cachedState != QQSK::StateFlag::Normal) {
417 const QVariant value = readPropertyInControlForStates(
418 ids.property, ids.alternative, control, stateListIndices, 0, 0);
424
425
426
427 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
428 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
435 const QQStyleKitExtendableControlType exactType,
436 const QList<QQStyleKitExtendableControlType> baseTypes)
442
444 const auto writtenProperties = controls->m_writtenPropertyPaths;
445 if (writtenProperties.contains(ids.property.pathId()))
447 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
448 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
450 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
452 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
454 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
460 const QVariant value = readPropertyInControl(ids, control);
465 for (
const int type : baseTypes) {
466 if (
const QQStyleKitControl *control = controls->getControlStyle(type)) {
467 const QVariant value = readPropertyInControl(ids, control);
477 const QList<QPointer<QQStyleKitVariation>> &variations,
479 const PropertyPathIds &ids,
480 const QQStyleKitExtendableControlType exactType,
481 const QList<QQStyleKitExtendableControlType> baseTypes)
483 bool foundAtLeastOneVariation =
false;
484 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
487 if (!variation->m_usageContext.contains(styleOrTheme)) {
488 if (foundAtLeastOneVariation) {
490
491
492
496
499 foundAtLeastOneVariation =
true;
500 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
508 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
511
512
513 style->syncFromQPalette(styleReader->effectivePalette());
516
517
518 cacheReaderState(styleReader->controlState());
520 if (styleReader->m_effectiveVariationsDirty)
521 rebuildVariationsForReader(styleReader, style);
523 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
524 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
529 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
533 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
537 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
541 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
545 if (
auto *fallbackStyle = style->fallbackStyle()) {
547
548 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
557 if (!value.isValid())
566 const QQSK::Property property,
567 const QQSK::Property alternative)
570 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
571 const QQSK::Subclass subclass = controlProperties->subclass();
573 if (subclass != QQSK::Subclass::QQStyleKitReader) {
575
576
577
578
579
580
581
582 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
585 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
586 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
587 return control->readStyleProperty(key);
590 QQStyleKitStyle *style = controlProperties->style();
591 if (!style || !style->loaded()) {
593
594
595
600 QQStyleKitReader *styleReader = controlProperties->asQQStyleKitReader();
602 if (s_isReadingProperty) {
603 if (!s_styleWarningsIssued) {
604 s_styleWarningsIssued =
true;
605 qmlWarning(styleReader) <<
"The style property '" << property <<
"' was read "
606 <<
"before finishing the read of another style property. "
607 <<
"This is likely to cause a style glitch.";
610 QScopedValueRollback rollback(s_isReadingProperty,
true);
613 ids.property = group->propertyPathId(property, PropertyPathId::Flag::ExcludeSubtype);
614 ids.alternative = group->propertyPathId(alternative, PropertyPathId::Flag::ExcludeSubtype);
615 const bool insideSubType = pathFlags &
616 (QQSK::PropertyPathFlag::DelegateSubtype1 | QQSK::PropertyPathFlag::DelegateSubtype2);
619 ids.subTypeProperty = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
620 ids.subTypeAlternative = group->propertyPathId(alternative, PropertyPathId::Flag::IncludeSubtype);
626 if (!pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
628
629
630
631
633 const QVariant value = readPropertyInStorageForState(
634 ids.subTypeProperty, ids.subTypeAlternative, styleReader, QQSK::StateFlag::Normal);
638 const QVariant value = readPropertyInStorageForState(
639 ids.property, ids.alternative, styleReader, QQSK::StateFlag::Normal);
644 return readPropertyInStyle(style, ids, styleReader);
649 const QQSK::Property property,
650 const QVariant &value)
656 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
657 const QQSK::Subclass subclass = controlProperties->subclass();
658 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
660 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
661 qmlWarning(controlProperties) <<
"Properties inside 'global' are read-only!";
665 if (subclass == QQSK::Subclass::QQStyleKitReader) {
667 QQStyleKitReader *reader = controlProperties->asQQStyleKitReader();
668 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
669 const QVariant currentValue = reader->readStyleProperty(key);
670 const bool valueChanged = currentValue != value;
672 reader->writeStyleProperty(key, value);
673 QQStyleKitDebug::notifyPropertyWrite(group, property, reader, QQSK::StateFlag::Normal, key, value);
678 if (subclass == QQSK::Subclass::QQStyleKitState) {
682 const QQSK::State nestedState = controlState->nestedState();
683 const PropertyStorageId key = propertyPathId.storageId(nestedState);
684 const QVariant currentValue = control->readStyleProperty(key);
685 const bool valueChanged = currentValue != value;
688
689
690 control->m_writtenStates |= nestedState;
692
693
694
696 const QQSK::State alreadyWrittenStates = controls->m_writtenPropertyPaths[propertyPathId.pathId()];
697 controls->m_writtenPropertyPaths[propertyPathId.pathId()] = alreadyWrittenStates | nestedState;
699 control->writeStyleProperty(key, value);
700 QQStyleKitDebug::notifyPropertyWrite(group, property, control, nestedState, key, value);
711 const QQSK::Property property)
715 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
716 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
717 const QQSK::Subclass subclass = controlProperties->subclass();
719 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global))
722 if (subclass == QQSK::Subclass::QQStyleKitReader) {
723 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
724 return controlProperties->asQQStyleKitReader()->readStyleProperty(key).isValid();
727 if (subclass == QQSK::Subclass::QQStyleKitState) {
730 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
731 return control->readStyleProperty(key).isValid();
740#include "moc_qqstylekitpropertyresolver_p.cpp"
QQStyleKitControl * control() const
QQStyleKitControlProperties * controlProperties() const
Combined button and popup list for selecting options.