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::FlatButton:
55 case QQStyleKitReader::ToolButton:
56 case QQStyleKitReader::TabButton:
57 case QQStyleKitReader::RadioButton:
58 case QQStyleKitReader::RoundButton:
59 case QQStyleKitReader::CheckBox:
60 case QQStyleKitReader::SwitchControl: {
61 static QList<QQStyleKitExtendableControlType> t =
62 { QQStyleKitReader::AbstractButton, QQStyleKitReader::Control };
64 case QQStyleKitReader::Menu:
65 case QQStyleKitReader::Dialog: {
66 static QList<QQStyleKitExtendableControlType> t =
67 { QQStyleKitReader::Popup, QQStyleKitReader::Control };
69 case QQStyleKitReader::Page:
70 case QQStyleKitReader::Frame:
71 case QQStyleKitReader::TabBar:
72 case QQStyleKitReader::ToolBar: {
73 static QList<QQStyleKitExtendableControlType> t =
74 { QQStyleKitReader::Pane, QQStyleKitReader::Control };
76 case QQStyleKitReader::GroupBox: {
77 static QList<QQStyleKitExtendableControlType> t =
78 { QQStyleKitReader::Frame, QQStyleKitReader::Pane, QQStyleKitReader::Control };
81 case QQStyleKitReader::TextField:
82 case QQStyleKitReader::TextArea: {
83 static QList<QQStyleKitExtendableControlType> t =
84 { QQStyleKitReader::TextInput, QQStyleKitReader::Control };
87 static QList<QQStyleKitExtendableControlType> t =
88 { QQStyleKitReader::Control };
98 Q_ASSERT(state != QQSK::StateFlag::Unspecified);
99 if (state == s_cachedState)
102 s_cachedState = state;
105
106
107
108
109 s_cachedStateList.clear();
110 if (state.testFlag(QQSK::StateFlag::Pressed))
111 s_cachedStateList.append(QQSK::StateFlag::Pressed);
112 if (state.testFlag(QQSK::StateFlag::Hovered))
113 s_cachedStateList.append(QQSK::StateFlag::Hovered);
114 if (state.testFlag(QQSK::StateFlag::Highlighted))
115 s_cachedStateList.append(QQSK::StateFlag::Highlighted);
116 if (state.testFlag(QQSK::StateFlag::Focused))
117 s_cachedStateList.append(QQSK::StateFlag::Focused);
118 if (state.testFlag(QQSK::StateFlag::Checked))
119 s_cachedStateList.append(QQSK::StateFlag::Checked);
120 if (state.testFlag(QQSK::StateFlag::Vertical))
121 s_cachedStateList.append(QQSK::StateFlag::Vertical);
122 if (state.testFlag(QQSK::StateFlag::Disabled))
123 s_cachedStateList.append(QQSK::StateFlag::Disabled);
127 QQStyleKitReader *styleReader,
132
133
134
135 if (!styleReader->m_effectiveVariations.contains(variation))
136 styleReader->m_effectiveVariations.append(variation);
139
140
141
142 if (!variation->m_usageContext.contains(styleOrTheme))
143 variation->m_usageContext.append(styleOrTheme);
147 QQStyleKitReader *styleReader,
149 const AttachedVariationList &attachedVariations)
151 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
152 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
154 static PropertyPathIds ids;
155 if (ids.property.property() == QQSK::Property::NoProperty) {
157
158
159 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
160 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
165 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
166 const auto parentType = attached->controlType();
167 const auto parentBaseTypes = baseTypesForType(parentType);
170
171
172
173 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
174 if (!typeVariationsVariant.isValid())
177 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
179 for (QQStyleKitVariation *variation : typeVariations) {
181
182
185
189 if (variation->getControl(styleReaderType)) {
190 addVariationToReader(styleReader, styleOrTheme, variation);
192 for (
int type : styleReaderBaseType) {
193 if (variation->getControl(type))
194 addVariationToReader(styleReader, styleOrTheme, variation);
202 QQStyleKitReader *styleReader,
204 const AttachedVariationList &attachedVariations)
207
208
209
210
211 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
212 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
214 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
215 for (
const QString &instanceVariationName : attached->variations()) {
216 for (QQStyleKitVariation *variation : styleOrTheme->m_styleVariations) {
217 if (variation->name() != instanceVariationName)
221
222
223
224 if (variation->getControl(styleReaderType)) {
225 addVariationToReader(styleReader, styleOrTheme, variation);
227 for (
int baseType : styleReaderBaseTypes) {
228 if (variation->getControl(baseType))
229 addVariationToReader(styleReader, styleOrTheme, variation);
238 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
241
242
243
244
245
246
247 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
248 styleReader->m_effectiveVariationsDirty =
false;
249 styleReader->m_effectiveVariations.clear();
251 if (!style->m_hasVariations)
255
256
257 AttachedVariationList attachedVariations;
258 for (QObject *current = styleReader; current; current = current->parent()) {
259 if (
const QObject *attachedObject = qmlAttachedPropertiesObject<QQStyleKitVariation>(current,
false)) {
261 attachedVariations.append(attached);
265 if (attachedVariations.isEmpty())
268 for (QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
270 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
271 addTypeVariationsToReader(styleReader, theme, attachedVariations);
273 addInstanceVariationsToReader(styleReader, current, attachedVariations);
274 addTypeVariationsToReader(styleReader, current, attachedVariations);
281 const T *storageProvider, QQSK::State state)
284
285
286
287
288
289
290
291
292
293 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
295 const PropertyStorageId propertyKey = main.storageId(state);
298 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
300 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
301 if (propertyValue.isValid()) {
303 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
304 return propertyValue;
307 const PropertyStorageId altPropertyKey = alternative.storageId(state);
310 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
312 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
313 if (altValue.isValid()) {
315 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
322template <
class INDICES_CONTAINER>
326 int startIndex,
int recursionLevel)
328 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
330
331
332
333
334
335
336
337 stateListIndices[recursionLevel] = i;
338 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
341
342 if (!control->m_writtenStates.testFlag(stateFlag))
346
348 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
349 if (!statesAffectingProperty.testFlag(stateFlag)) {
350 if (alternative.property() == QQSK::Property::NoProperty) {
353 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
354 if (!statesAffectingAlternative.testFlag(stateFlag))
359 if (recursionLevel < s_cachedStateList.length() - 1) {
361 const QVariant value = readPropertyInControlForStates(
362 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
368 QQSK::State storageState = QQSK::StateFlag::Unspecified;
369 for (
int j = 0; j <= recursionLevel; ++j)
370 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
371 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
383
384
385
386
387 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
389 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
390 if (s_cachedState != QQSK::StateFlag::Normal) {
391 QVariant value = readPropertyInControlForStates(
392 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
397 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
398 const QVariant value = readPropertyInStorageForState(
399 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
405 if (s_cachedState != QQSK::StateFlag::Normal) {
406 const QVariant value = readPropertyInControlForStates(
407 ids.property, ids.alternative, control, stateListIndices, 0, 0);
413
414
415
416 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
417 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
424 const QQStyleKitExtendableControlType exactType,
425 const QList<QQStyleKitExtendableControlType> baseTypes)
431
433 const auto writtenProperties = controls->m_writtenPropertyPaths;
434 if (writtenProperties.contains(ids.property.pathId()))
436 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
437 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
439 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
441 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
443 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
449 const QVariant value = readPropertyInControl(ids, control);
454 for (
const int type : baseTypes) {
455 if (
const QQStyleKitControl *control = controls->getControl(type)) {
456 const QVariant value = readPropertyInControl(ids, control);
466 const QList<QPointer<QQStyleKitVariation>> &variations,
468 const PropertyPathIds &ids,
469 const QQStyleKitExtendableControlType exactType,
470 const QList<QQStyleKitExtendableControlType> baseTypes)
472 bool foundAtLeastOneVariation =
false;
473 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
476 if (!variation->m_usageContext.contains(styleOrTheme)) {
477 if (foundAtLeastOneVariation) {
479
480
481
485
488 foundAtLeastOneVariation =
true;
489 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
497 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
500
501
502 style->syncFromQPalette(styleReader->effectivePalette());
505
506
507 cacheReaderState(styleReader->controlState());
509 if (styleReader->m_effectiveVariationsDirty)
510 rebuildVariationsForReader(styleReader, style);
512 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
513 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
518 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
522 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
526 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
530 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
534 if (
auto *fallbackStyle = style->fallbackStyle()) {
536
537 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
546 if (!value.isValid())
555 const QQSK::Property property,
556 const QQSK::Property alternative)
559 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
560 const QQSK::Subclass subclass = controlProperties->subclass();
562 if (subclass != QQSK::Subclass::QQStyleKitReader) {
564
565
566
567
568
569
570
571 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
574 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
575 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
576 return control->readStyleProperty(key);
579 QQStyleKitStyle *style = controlProperties->style();
580 if (!style || !style->loaded()) {
582
583
584
589 QQStyleKitReader *styleReader = controlProperties->asQQStyleKitReader();
591 if (s_isReadingProperty) {
592 if (!s_styleWarningsIssued) {
593 s_styleWarningsIssued =
true;
594 qmlWarning(styleReader) <<
"The style property '" << property <<
"' was read "
595 <<
"before finishing the read of another style property. "
596 <<
"This is likely to cause a style glitch.";
599 QScopedValueRollback rollback(s_isReadingProperty,
true);
602 ids.property = group->propertyPathId(property, PropertyPathId::Flag::ExcludeSubtype);
603 ids.alternative = group->propertyPathId(alternative, PropertyPathId::Flag::ExcludeSubtype);
604 const bool insideSubType = pathFlags &
605 (QQSK::PropertyPathFlag::DelegateSubtype1 | QQSK::PropertyPathFlag::DelegateSubtype2);
608 ids.subTypeProperty = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
609 ids.subTypeAlternative = group->propertyPathId(alternative, PropertyPathId::Flag::IncludeSubtype);
615 if (!pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
617
618
619
620
622 const QVariant value = readPropertyInStorageForState(
623 ids.subTypeProperty, ids.subTypeAlternative, styleReader, QQSK::StateFlag::Normal);
627 const QVariant value = readPropertyInStorageForState(
628 ids.property, ids.alternative, styleReader, QQSK::StateFlag::Normal);
633 return readPropertyInStyle(style, ids, styleReader);
638 const QQSK::Property property,
639 const QVariant &value)
645 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
646 const QQSK::Subclass subclass = controlProperties->subclass();
647 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
649 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
650 qmlWarning(controlProperties) <<
"Properties inside 'global' are read-only!";
654 if (subclass == QQSK::Subclass::QQStyleKitReader) {
656 QQStyleKitReader *reader = controlProperties->asQQStyleKitReader();
657 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
658 const QVariant currentValue = reader->readStyleProperty(key);
659 const bool valueChanged = currentValue != value;
661 reader->writeStyleProperty(key, value);
662 QQStyleKitDebug::notifyPropertyWrite(group, property, reader, QQSK::StateFlag::Normal, key, value);
667 if (subclass == QQSK::Subclass::QQStyleKitState) {
671 const QQSK::State nestedState = controlState->nestedState();
672 const PropertyStorageId key = propertyPathId.storageId(nestedState);
673 const QVariant currentValue = control->readStyleProperty(key);
674 const bool valueChanged = currentValue != value;
677
678
679 control->m_writtenStates |= nestedState;
681
682
683
685 const QQSK::State alreadyWrittenStates = controls->m_writtenPropertyPaths[propertyPathId.pathId()];
686 controls->m_writtenPropertyPaths[propertyPathId.pathId()] = alreadyWrittenStates | nestedState;
688 control->writeStyleProperty(key, value);
689 QQStyleKitDebug::notifyPropertyWrite(group, property, control, nestedState, key, value);
700 const QQSK::Property property)
704 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
705 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
706 const QQSK::Subclass subclass = controlProperties->subclass();
708 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global))
711 if (subclass == QQSK::Subclass::QQStyleKitReader) {
712 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
713 return controlProperties->asQQStyleKitReader()->readStyleProperty(key).isValid();
716 if (subclass == QQSK::Subclass::QQStyleKitState) {
719 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
720 return control->readStyleProperty(key).isValid();
729#include "moc_qqstylekitpropertyresolver_p.cpp"
QQStyleKitControl * control() const
QQStyleKitControlProperties * controlProperties() const
Combined button and popup list for selecting options.