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
40 case QQStyleKitReader::ApplicationWindow: {
41 static QList<QQStyleKitExtendableControlType> t =
42 { QQStyleKitReader::ApplicationWindow };
44 case QQStyleKitReader::Button:
45 case QQStyleKitReader::FlatButton:
46 case QQStyleKitReader::ToolButton:
47 case QQStyleKitReader::TabButton:
48 case QQStyleKitReader::RadioButton:
49 case QQStyleKitReader::CheckBox:
50 case QQStyleKitReader::SwitchControl: {
51 static QList<QQStyleKitExtendableControlType> t =
52 { QQStyleKitReader::AbstractButton, QQStyleKitReader::Control };
54 case QQStyleKitReader::Menu:
55 case QQStyleKitReader::Dialog: {
56 static QList<QQStyleKitExtendableControlType> t =
57 { QQStyleKitReader::Popup, QQStyleKitReader::Control };
59 case QQStyleKitReader::Page:
60 case QQStyleKitReader::Frame:
61 case QQStyleKitReader::TabBar:
62 case QQStyleKitReader::ToolBar: {
63 static QList<QQStyleKitExtendableControlType> t =
64 { QQStyleKitReader::Pane, QQStyleKitReader::Control };
66 case QQStyleKitReader::GroupBox: {
67 static QList<QQStyleKitExtendableControlType> t =
68 { QQStyleKitReader::Frame, QQStyleKitReader::Pane, QQStyleKitReader::Control };
71 case QQStyleKitReader::TextField:
72 case QQStyleKitReader::TextArea: {
73 static QList<QQStyleKitExtendableControlType> t =
74 { QQStyleKitReader::TextInput, QQStyleKitReader::Control };
77 static QList<QQStyleKitExtendableControlType> t =
78 { QQStyleKitReader::Control };
88 Q_ASSERT(state != QQSK::StateFlag::Unspecified);
89 if (state == s_cachedState)
92 s_cachedState = state;
95
96
97
98
99 s_cachedStateList.clear();
100 if (state.testFlag(QQSK::StateFlag::Pressed))
101 s_cachedStateList.append(QQSK::StateFlag::Pressed);
102 if (state.testFlag(QQSK::StateFlag::Hovered))
103 s_cachedStateList.append(QQSK::StateFlag::Hovered);
104 if (state.testFlag(QQSK::StateFlag::Highlighted))
105 s_cachedStateList.append(QQSK::StateFlag::Highlighted);
106 if (state.testFlag(QQSK::StateFlag::Focused))
107 s_cachedStateList.append(QQSK::StateFlag::Focused);
108 if (state.testFlag(QQSK::StateFlag::Checked))
109 s_cachedStateList.append(QQSK::StateFlag::Checked);
110 if (state.testFlag(QQSK::StateFlag::Vertical))
111 s_cachedStateList.append(QQSK::StateFlag::Vertical);
112 if (state.testFlag(QQSK::StateFlag::Disabled))
113 s_cachedStateList.append(QQSK::StateFlag::Disabled);
117 QQStyleKitReader *styleReader,
121 styleReader->m_effectiveVariations.append(variation);
122 variation->m_owner = styleOrTheme;
123 styleOrTheme->m_hasVariationsThatAffectExistingStyleReaders =
true;
127 QQStyleKitReader *styleReader,
129 const AttachedVariationList &attachedVariations)
131 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
132 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
134 static PropertyPathIds ids;
135 if (ids.property.property() == QQSK::Property::NoProperty) {
137
138
139 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
140 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
145 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
146 const auto parentType = attached->controlType();
147 const auto parentBaseTypes = baseTypesForType(parentType);
150
151
152
153 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
154 if (!typeVariationsVariant.isValid())
157 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
159 for (QQStyleKitVariation *variation : typeVariations) {
161
162
165
169 if (variation->getControl(styleReaderType)) {
170 addVariationToReader(styleReader, styleOrTheme, variation);
172 for (
int type : styleReaderBaseType) {
173 if (variation->getControl(type))
174 addVariationToReader(styleReader, styleOrTheme, variation);
182 QQStyleKitReader *styleReader,
184 const AttachedVariationList &attachedVariations)
187
188
189
190
191 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
192 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
194 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
195 for (
const QString &instanceVariationName : attached->variations()) {
196 for (QQStyleKitVariation *variation : styleOrTheme->variations()) {
197 if (variation->name() != instanceVariationName)
201
202
203
204 if (variation->getControl(styleReaderType)) {
205 addVariationToReader(styleReader, styleOrTheme, variation);
207 for (
int baseType : styleReaderBaseTypes) {
208 if (variation->getControl(baseType))
209 addVariationToReader(styleReader, styleOrTheme, variation);
218 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
221
222
223
224
225
226
227 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
228 styleReader->m_effectiveVariationsDirty =
false;
229 styleReader->m_effectiveVariations.clear();
233 if (!hasTypeVariations && !hasInstanceVariations) {
235
236
241
242
243 AttachedVariationList attachedVariations;
244 QObject *parentObj = styleReader;
246 const QObject *attachedObject = qmlAttachedPropertiesObject<
QQStyleKitVariation>(parentObj,
false);
247 if (attachedObject) {
249 attachedVariations.append(attached);
251 parentObj = parentObj->parent();
254 QQStyleKitStyle *currentStyle = style;
255 while (currentStyle) {
257 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
258 addTypeVariationsToReader(styleReader, theme, attachedVariations);
260 addInstanceVariationsToReader(styleReader, currentStyle, attachedVariations);
261 addTypeVariationsToReader(styleReader, currentStyle, attachedVariations);
262 currentStyle = currentStyle->fallbackStyle();
269 const T *storageProvider, QQSK::State state)
272
273
274
275
276
277
278
279
280
281 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
283 const PropertyStorageId propertyKey = main.storageId(state);
286 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
288 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
289 if (propertyValue.isValid()) {
291 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
292 return propertyValue;
295 const PropertyStorageId altPropertyKey = alternative.storageId(state);
298 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
300 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
301 if (altValue.isValid()) {
303 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
310template <
class INDICES_CONTAINER>
314 int startIndex,
int recursionLevel)
316 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
318
319
320
321
322
323
324
325 stateListIndices[recursionLevel] = i;
326 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
329
330 if (!control->m_writtenStates.testFlag(stateFlag))
334
336 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
337 if (!statesAffectingProperty.testFlag(stateFlag)) {
338 if (alternative.property() == QQSK::Property::NoProperty) {
341 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
342 if (!statesAffectingAlternative.testFlag(stateFlag))
347 if (recursionLevel < s_cachedStateList.length() - 1) {
349 const QVariant value = readPropertyInControlForStates(
350 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
356 QQSK::State storageState = QQSK::StateFlag::Unspecified;
357 for (
int j = 0; j <= recursionLevel; ++j)
358 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
359 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
371
372
373
374
375 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
377 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
378 if (s_cachedState != QQSK::StateFlag::Normal) {
379 QVariant value = readPropertyInControlForStates(
380 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
385 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
386 const QVariant value = readPropertyInStorageForState(
387 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
393 if (s_cachedState != QQSK::StateFlag::Normal) {
394 const QVariant value = readPropertyInControlForStates(
395 ids.property, ids.alternative, control, stateListIndices, 0, 0);
401
402
403
404 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
405 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
412 const QQStyleKitExtendableControlType exactType,
413 const QList<QQStyleKitExtendableControlType> baseTypes)
419
421 const auto writtenProperties = controls->m_writtenPropertyPaths;
422 if (writtenProperties.contains(ids.property.pathId()))
424 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
425 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
427 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
429 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
431 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
437 const QVariant value = readPropertyInControl(ids, control);
442 for (
const int type : baseTypes) {
443 if (
const QQStyleKitControl *control = controls->getControl(type)) {
444 const QVariant value = readPropertyInControl(ids, control);
454 const QList<QPointer<QQStyleKitVariation>> &variations,
456 const PropertyPathIds &ids,
457 const QQStyleKitExtendableControlType exactType,
458 const QList<QQStyleKitExtendableControlType> baseTypes)
460 if (!styleOrTheme->m_hasVariationsThatAffectExistingStyleReaders)
463 bool foundAtLeastOneVariation =
false;
464 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
467 if (variation->m_owner != styleOrTheme) {
468 if (foundAtLeastOneVariation) {
470
471
472
477 foundAtLeastOneVariation =
true;
478 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
486 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
489
490
491 style->syncFromQPalette(styleReader->effectivePalette());
494
495
496 cacheReaderState(styleReader->controlState());
498 if (styleReader->m_effectiveVariationsDirty)
499 rebuildVariationsForReader(styleReader, style);
501 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
502 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
507 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
511 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
515 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
519 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
523 if (
auto *fallbackStyle = style->fallbackStyle()) {
525
526 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
535 if (!value.isValid())
544 const QQSK::Property property,
545 const QQSK::Property alternative)
548 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
549 const QQSK::Subclass subclass = controlProperties->subclass();
551 if (subclass != QQSK::Subclass::QQStyleKitReader) {
553
554
555
556
557
558
559
560 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
563 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
564 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
565 return control->readStyleProperty(key);
568 QQStyleKitStyle *style = controlProperties->style();
570 if (!s_styleWarningsIssued) {
571 s_styleWarningsIssued =
true;
572 qmlWarning(group) <<
"style properties cannot be read: No StyleKit style has been set!";
577 if (!style->loaded()) {
583 QQStyleKitReader *styleReader = controlProperties->asQQStyleKitReader();
585 if (s_isReadingProperty) {
586 if (!s_styleWarningsIssued) {
587 s_styleWarningsIssued =
true;
588 qmlWarning(styleReader) <<
"The style property '" << property <<
"' was read "
589 <<
"before finishing the read of another style property. "
590 <<
"This is likely to cause a style glitch.";
593 QScopedValueRollback rollback(s_isReadingProperty,
true);
596 ids.property = group->propertyPathId(property, PropertyPathId::Flag::ExcludeSubtype);
597 ids.alternative = group->propertyPathId(alternative, PropertyPathId::Flag::ExcludeSubtype);
598 const bool insideSubType = pathFlags &
599 (QQSK::PropertyPathFlag::DelegateSubtype1 | QQSK::PropertyPathFlag::DelegateSubtype2);
602 ids.subTypeProperty = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
603 ids.subTypeAlternative = group->propertyPathId(alternative, PropertyPathId::Flag::IncludeSubtype);
609 if (!pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
611
612
613
614
616 const QVariant value = readPropertyInStorageForState(
617 ids.subTypeProperty, ids.subTypeAlternative, styleReader, QQSK::StateFlag::Normal);
621 const QVariant value = readPropertyInStorageForState(
622 ids.property, ids.alternative, styleReader, QQSK::StateFlag::Normal);
627 return readPropertyInStyle(style, ids, styleReader);
632 const QQSK::Property property,
633 const QVariant &value)
639 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
640 const QQSK::Subclass subclass = controlProperties->subclass();
641 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
643 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
644 qmlWarning(controlProperties) <<
"Properties inside 'global' are read-only!";
648 if (subclass == QQSK::Subclass::QQStyleKitReader) {
650 QQStyleKitReader *reader = controlProperties->asQQStyleKitReader();
651 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
652 const QVariant currentValue = reader->readStyleProperty(key);
653 const bool valueChanged = currentValue != value;
655 reader->writeStyleProperty(key, value);
656 QQStyleKitDebug::notifyPropertyWrite(group, property, reader, QQSK::StateFlag::Normal, key, value);
661 if (subclass == QQSK::Subclass::QQStyleKitState) {
665 const QQSK::State nestedState = controlState->nestedState();
666 const PropertyStorageId key = propertyPathId.storageId(nestedState);
667 const QVariant currentValue = control->readStyleProperty(key);
668 const bool valueChanged = currentValue != value;
671
672
673 control->m_writtenStates |= nestedState;
675
676
677
679 const QQSK::State alreadyWrittenStates = controls->m_writtenPropertyPaths[propertyPathId.pathId()];
680 controls->m_writtenPropertyPaths[propertyPathId.pathId()] = alreadyWrittenStates | nestedState;
682 control->writeStyleProperty(key, value);
683 QQStyleKitDebug::notifyPropertyWrite(group, property, control, nestedState, key, value);
694 const QQSK::Property property)
698 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
699 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
700 const QQSK::Subclass subclass = controlProperties->subclass();
702 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global))
705 if (subclass == QQSK::Subclass::QQStyleKitReader) {
706 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
707 return controlProperties->asQQStyleKitReader()->readStyleProperty(key).isValid();
710 if (subclass == QQSK::Subclass::QQStyleKitState) {
713 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
714 return control->readStyleProperty(key).isValid();
723#include "moc_qqstylekitpropertyresolver_p.cpp"
QQStyleKitControl * control() const
QQStyleKitControlProperties * controlProperties() const
Combined button and popup list for selecting options.