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,
122
123
124
125 if (!styleReader->m_effectiveVariations.contains(variation))
126 styleReader->m_effectiveVariations.append(variation);
129
130
131
132 if (!variation->m_usageContext.contains(styleOrTheme))
133 variation->m_usageContext.append(styleOrTheme);
137 QQStyleKitReader *styleReader,
139 const AttachedVariationList &attachedVariations)
141 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
142 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
144 static PropertyPathIds ids;
145 if (ids.property.property() == QQSK::Property::NoProperty) {
147
148
149 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
150 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
155 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
156 const auto parentType = attached->controlType();
157 const auto parentBaseTypes = baseTypesForType(parentType);
160
161
162
163 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
164 if (!typeVariationsVariant.isValid())
167 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
169 for (QQStyleKitVariation *variation : typeVariations) {
171
172
175
179 if (variation->getControl(styleReaderType)) {
180 addVariationToReader(styleReader, styleOrTheme, variation);
182 for (
int type : styleReaderBaseType) {
183 if (variation->getControl(type))
184 addVariationToReader(styleReader, styleOrTheme, variation);
192 QQStyleKitReader *styleReader,
194 const AttachedVariationList &attachedVariations)
197
198
199
200
201 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
202 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
204 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
205 for (
const QString &instanceVariationName : attached->variations()) {
206 for (QQStyleKitVariation *variation : styleOrTheme->m_styleVariations) {
207 if (variation->name() != instanceVariationName)
211
212
213
214 if (variation->getControl(styleReaderType)) {
215 addVariationToReader(styleReader, styleOrTheme, variation);
217 for (
int baseType : styleReaderBaseTypes) {
218 if (variation->getControl(baseType))
219 addVariationToReader(styleReader, styleOrTheme, variation);
228 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
231
232
233
234
235
236
237 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
238 styleReader->m_effectiveVariationsDirty =
false;
239 styleReader->m_effectiveVariations.clear();
241 if (!style->m_hasVariations)
245
246
247 AttachedVariationList attachedVariations;
248 for (QObject *current = styleReader; current; current = current->parent()) {
249 if (
const QObject *attachedObject = qmlAttachedPropertiesObject<QQStyleKitVariation>(current,
false)) {
251 attachedVariations.append(attached);
255 if (attachedVariations.isEmpty())
258 for (QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
260 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
261 addTypeVariationsToReader(styleReader, theme, attachedVariations);
263 addInstanceVariationsToReader(styleReader, current, attachedVariations);
264 addTypeVariationsToReader(styleReader, current, attachedVariations);
271 const T *storageProvider, QQSK::State state)
274
275
276
277
278
279
280
281
282
283 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
285 const PropertyStorageId propertyKey = main.storageId(state);
288 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
290 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
291 if (propertyValue.isValid()) {
293 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
294 return propertyValue;
297 const PropertyStorageId altPropertyKey = alternative.storageId(state);
300 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
302 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
303 if (altValue.isValid()) {
305 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
312template <
class INDICES_CONTAINER>
316 int startIndex,
int recursionLevel)
318 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
320
321
322
323
324
325
326
327 stateListIndices[recursionLevel] = i;
328 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
331
332 if (!control->m_writtenStates.testFlag(stateFlag))
336
338 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
339 if (!statesAffectingProperty.testFlag(stateFlag)) {
340 if (alternative.property() == QQSK::Property::NoProperty) {
343 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
344 if (!statesAffectingAlternative.testFlag(stateFlag))
349 if (recursionLevel < s_cachedStateList.length() - 1) {
351 const QVariant value = readPropertyInControlForStates(
352 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
358 QQSK::State storageState = QQSK::StateFlag::Unspecified;
359 for (
int j = 0; j <= recursionLevel; ++j)
360 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
361 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
373
374
375
376
377 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
379 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
380 if (s_cachedState != QQSK::StateFlag::Normal) {
381 QVariant value = readPropertyInControlForStates(
382 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
387 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
388 const QVariant value = readPropertyInStorageForState(
389 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
395 if (s_cachedState != QQSK::StateFlag::Normal) {
396 const QVariant value = readPropertyInControlForStates(
397 ids.property, ids.alternative, control, stateListIndices, 0, 0);
403
404
405
406 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
407 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
414 const QQStyleKitExtendableControlType exactType,
415 const QList<QQStyleKitExtendableControlType> baseTypes)
421
423 const auto writtenProperties = controls->m_writtenPropertyPaths;
424 if (writtenProperties.contains(ids.property.pathId()))
426 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
427 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
429 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
431 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
433 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
439 const QVariant value = readPropertyInControl(ids, control);
444 for (
const int type : baseTypes) {
445 if (
const QQStyleKitControl *control = controls->getControl(type)) {
446 const QVariant value = readPropertyInControl(ids, control);
456 const QList<QPointer<QQStyleKitVariation>> &variations,
458 const PropertyPathIds &ids,
459 const QQStyleKitExtendableControlType exactType,
460 const QList<QQStyleKitExtendableControlType> baseTypes)
462 bool foundAtLeastOneVariation =
false;
463 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
466 if (!variation->m_usageContext.contains(styleOrTheme)) {
467 if (foundAtLeastOneVariation) {
469
470
471
475
478 foundAtLeastOneVariation =
true;
479 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
487 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
490
491
492 style->syncFromQPalette(styleReader->effectivePalette());
495
496
497 cacheReaderState(styleReader->controlState());
499 if (styleReader->m_effectiveVariationsDirty)
500 rebuildVariationsForReader(styleReader, style);
502 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
503 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
508 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
512 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
516 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
520 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
524 if (
auto *fallbackStyle = style->fallbackStyle()) {
526
527 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
536 if (!value.isValid())
545 const QQSK::Property property,
546 const QQSK::Property alternative)
549 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
550 const QQSK::Subclass subclass = controlProperties->subclass();
552 if (subclass != QQSK::Subclass::QQStyleKitReader) {
554
555
556
557
558
559
560
561 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
564 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
565 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
566 return control->readStyleProperty(key);
569 QQStyleKitStyle *style = controlProperties->style();
571 if (!s_styleWarningsIssued) {
572 s_styleWarningsIssued =
true;
573 qmlWarning(group) <<
"style properties cannot be read: No StyleKit style has been set!";
578 if (!style->loaded()) {
584 QQStyleKitReader *styleReader = controlProperties->asQQStyleKitReader();
586 if (s_isReadingProperty) {
587 if (!s_styleWarningsIssued) {
588 s_styleWarningsIssued =
true;
589 qmlWarning(styleReader) <<
"The style property '" << property <<
"' was read "
590 <<
"before finishing the read of another style property. "
591 <<
"This is likely to cause a style glitch.";
594 QScopedValueRollback rollback(s_isReadingProperty,
true);
597 ids.property = group->propertyPathId(property, PropertyPathId::Flag::ExcludeSubtype);
598 ids.alternative = group->propertyPathId(alternative, PropertyPathId::Flag::ExcludeSubtype);
599 const bool insideSubType = pathFlags &
600 (QQSK::PropertyPathFlag::DelegateSubtype1 | QQSK::PropertyPathFlag::DelegateSubtype2);
603 ids.subTypeProperty = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
604 ids.subTypeAlternative = group->propertyPathId(alternative, PropertyPathId::Flag::IncludeSubtype);
610 if (!pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
612
613
614
615
617 const QVariant value = readPropertyInStorageForState(
618 ids.subTypeProperty, ids.subTypeAlternative, styleReader, QQSK::StateFlag::Normal);
622 const QVariant value = readPropertyInStorageForState(
623 ids.property, ids.alternative, styleReader, QQSK::StateFlag::Normal);
628 return readPropertyInStyle(style, ids, styleReader);
633 const QQSK::Property property,
634 const QVariant &value)
640 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
641 const QQSK::Subclass subclass = controlProperties->subclass();
642 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
644 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global)) {
645 qmlWarning(controlProperties) <<
"Properties inside 'global' are read-only!";
649 if (subclass == QQSK::Subclass::QQStyleKitReader) {
651 QQStyleKitReader *reader = controlProperties->asQQStyleKitReader();
652 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
653 const QVariant currentValue = reader->readStyleProperty(key);
654 const bool valueChanged = currentValue != value;
656 reader->writeStyleProperty(key, value);
657 QQStyleKitDebug::notifyPropertyWrite(group, property, reader, QQSK::StateFlag::Normal, key, value);
662 if (subclass == QQSK::Subclass::QQStyleKitState) {
666 const QQSK::State nestedState = controlState->nestedState();
667 const PropertyStorageId key = propertyPathId.storageId(nestedState);
668 const QVariant currentValue = control->readStyleProperty(key);
669 const bool valueChanged = currentValue != value;
672
673
674 control->m_writtenStates |= nestedState;
676
677
678
680 const QQSK::State alreadyWrittenStates = controls->m_writtenPropertyPaths[propertyPathId.pathId()];
681 controls->m_writtenPropertyPaths[propertyPathId.pathId()] = alreadyWrittenStates | nestedState;
683 control->writeStyleProperty(key, value);
684 QQStyleKitDebug::notifyPropertyWrite(group, property, control, nestedState, key, value);
695 const QQSK::Property property)
699 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
700 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
701 const QQSK::Subclass subclass = controlProperties->subclass();
703 if (pathFlags.testFlag(QQSK::PropertyPathFlag::Global))
706 if (subclass == QQSK::Subclass::QQStyleKitReader) {
707 const PropertyStorageId key = propertyPathId.storageId(QQSK::StateFlag::Normal);
708 return controlProperties->asQQStyleKitReader()->readStyleProperty(key).isValid();
711 if (subclass == QQSK::Subclass::QQStyleKitState) {
714 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
715 return control->readStyleProperty(key).isValid();
724#include "moc_qqstylekitpropertyresolver_p.cpp"
QQStyleKitControl * control() const
QQStyleKitControlProperties * controlProperties() const
Combined button and popup list for selecting options.