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
44 case QQStyleKitReader::ApplicationWindow: {
45 static QList<QQStyleKitExtendableControlType> t =
46 { QQStyleKitReader::ApplicationWindow };
48 case QQStyleKitReader::Button:
49 case QQStyleKitReader::FlatButton:
50 case QQStyleKitReader::ToolButton:
51 case QQStyleKitReader::TabButton:
52 case QQStyleKitReader::RadioButton:
53 case QQStyleKitReader::RoundButton:
54 case QQStyleKitReader::CheckBox:
55 case QQStyleKitReader::SwitchControl: {
56 static QList<QQStyleKitExtendableControlType> t =
57 { QQStyleKitReader::AbstractButton, QQStyleKitReader::Control };
59 case QQStyleKitReader::Menu:
60 case QQStyleKitReader::Dialog: {
61 static QList<QQStyleKitExtendableControlType> t =
62 { QQStyleKitReader::Popup, QQStyleKitReader::Control };
64 case QQStyleKitReader::Page:
65 case QQStyleKitReader::Frame:
66 case QQStyleKitReader::TabBar:
67 case QQStyleKitReader::ToolBar: {
68 static QList<QQStyleKitExtendableControlType> t =
69 { QQStyleKitReader::Pane, QQStyleKitReader::Control };
71 case QQStyleKitReader::GroupBox: {
72 static QList<QQStyleKitExtendableControlType> t =
73 { QQStyleKitReader::Frame, QQStyleKitReader::Pane, QQStyleKitReader::Control };
76 case QQStyleKitReader::TextField:
77 case QQStyleKitReader::TextArea: {
78 static QList<QQStyleKitExtendableControlType> t =
79 { QQStyleKitReader::TextInput, QQStyleKitReader::Control };
82 static QList<QQStyleKitExtendableControlType> t =
83 { QQStyleKitReader::Control };
93 Q_ASSERT(state != QQSK::StateFlag::Unspecified);
94 if (state == s_cachedState)
97 s_cachedState = state;
100
101
102
103
104 s_cachedStateList.clear();
105 if (state.testFlag(QQSK::StateFlag::Pressed))
106 s_cachedStateList.append(QQSK::StateFlag::Pressed);
107 if (state.testFlag(QQSK::StateFlag::Hovered))
108 s_cachedStateList.append(QQSK::StateFlag::Hovered);
109 if (state.testFlag(QQSK::StateFlag::Highlighted))
110 s_cachedStateList.append(QQSK::StateFlag::Highlighted);
111 if (state.testFlag(QQSK::StateFlag::Focused))
112 s_cachedStateList.append(QQSK::StateFlag::Focused);
113 if (state.testFlag(QQSK::StateFlag::Checked))
114 s_cachedStateList.append(QQSK::StateFlag::Checked);
115 if (state.testFlag(QQSK::StateFlag::Vertical))
116 s_cachedStateList.append(QQSK::StateFlag::Vertical);
117 if (state.testFlag(QQSK::StateFlag::Disabled))
118 s_cachedStateList.append(QQSK::StateFlag::Disabled);
122 QQStyleKitReader *styleReader,
127
128
129
130 if (!styleReader->m_effectiveVariations.contains(variation))
131 styleReader->m_effectiveVariations.append(variation);
134
135
136
137 if (!variation->m_usageContext.contains(styleOrTheme))
138 variation->m_usageContext.append(styleOrTheme);
142 QQStyleKitReader *styleReader,
144 const AttachedVariationList &attachedVariations)
146 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
147 const auto styleReaderBaseType = baseTypesForType(styleReaderType);
149 static PropertyPathIds ids;
150 if (ids.property.property() == QQSK::Property::NoProperty) {
152
153
154 ids.property = styleReader->propertyPathId(QQSK::Property::Variations, PropertyPathId::Flag::ExcludeSubtype);
155 ids.alternative = styleReader->propertyPathId(QQSK::Property::NoProperty, PropertyPathId::Flag::ExcludeSubtype);
160 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
161 const auto parentType = attached->controlType();
162 const auto parentBaseTypes = baseTypesForType(parentType);
165
166
167
168 const QVariant typeVariationsVariant = readPropertyInRelevantControls(styleOrTheme, ids, parentType, parentBaseTypes);
169 if (!typeVariationsVariant.isValid())
172 const auto typeVariations = *qvariant_cast<QList<QQStyleKitVariation *> *>(typeVariationsVariant);
174 for (QQStyleKitVariation *variation : typeVariations) {
176
177
180
184 if (variation->getControl(styleReaderType)) {
185 addVariationToReader(styleReader, styleOrTheme, variation);
187 for (
int type : styleReaderBaseType) {
188 if (variation->getControl(type))
189 addVariationToReader(styleReader, styleOrTheme, variation);
197 QQStyleKitReader *styleReader,
199 const AttachedVariationList &attachedVariations)
202
203
204
205
206 const QQStyleKitExtendableControlType styleReaderType = styleReader->controlType();
207 const auto styleReaderBaseTypes = baseTypesForType(styleReaderType);
209 for (
const QQStyleKitVariationAttached *attached : attachedVariations) {
210 for (
const QString &instanceVariationName : attached->variations()) {
211 for (QQStyleKitVariation *variation : styleOrTheme->m_styleVariations) {
212 if (variation->name() != instanceVariationName)
216
217
218
219 if (variation->getControl(styleReaderType)) {
220 addVariationToReader(styleReader, styleOrTheme, variation);
222 for (
int baseType : styleReaderBaseTypes) {
223 if (variation->getControl(baseType))
224 addVariationToReader(styleReader, styleOrTheme, variation);
233 QQStyleKitReader *styleReader, QQStyleKitStyle *style)
236
237
238
239
240
241
242 Q_ASSERT(styleReader->m_effectiveVariationsDirty);
243 styleReader->m_effectiveVariationsDirty =
false;
244 styleReader->m_effectiveVariations.clear();
246 if (!style->m_hasVariations)
250
251
252 AttachedVariationList attachedVariations;
253 for (QObject *current = styleReader; current; current = current->parent()) {
254 if (
const QObject *attachedObject = qmlAttachedPropertiesObject<QQStyleKitVariation>(current,
false)) {
256 attachedVariations.append(attached);
260 if (attachedVariations.isEmpty())
263 for (QQStyleKitStyle *current = style; current; current = current->fallbackStyle()) {
265 addInstanceVariationsToReader(styleReader, theme, attachedVariations);
266 addTypeVariationsToReader(styleReader, theme, attachedVariations);
268 addInstanceVariationsToReader(styleReader, current, attachedVariations);
269 addTypeVariationsToReader(styleReader, current, attachedVariations);
276 const T *storageProvider, QQSK::State state)
279
280
281
282
283
284
285
286
287
288 Q_ASSERT(qlonglong(state) <= qlonglong(QQSK::StateFlag::MAX_STATE));
290 const PropertyStorageId propertyKey = main.storageId(state);
293 QQStyleKitDebug::trace(main, storageProvider, state, propertyKey);
295 const QVariant propertyValue = storageProvider->readStyleProperty(propertyKey);
296 if (propertyValue.isValid()) {
298 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, propertyValue);
299 return propertyValue;
302 const PropertyStorageId altPropertyKey = alternative.storageId(state);
305 QQStyleKitDebug::trace(alternative, storageProvider, state, altPropertyKey);
307 const QVariant altValue = storageProvider->readStyleProperty(altPropertyKey);
308 if (altValue.isValid()) {
310 QQStyleKitDebug::notifyPropertyRead(main, storageProvider, state, altValue);
317template <
class INDICES_CONTAINER>
321 int startIndex,
int recursionLevel)
323 for (
int i = startIndex; i < s_cachedStateList.length(); ++i) {
325
326
327
328
329
330
331
332 stateListIndices[recursionLevel] = i;
333 const QQSK::StateFlag stateFlag = s_cachedStateList[i];
336
337 if (!control->m_writtenStates.testFlag(stateFlag))
341
343 const QQSK::State statesAffectingProperty = controls->m_writtenPropertyPaths[main.pathId()];
344 if (!statesAffectingProperty.testFlag(stateFlag)) {
345 if (alternative.property() == QQSK::Property::NoProperty) {
348 const QQSK::State statesAffectingAlternative = controls->m_writtenPropertyPaths[alternative.pathId()];
349 if (!statesAffectingAlternative.testFlag(stateFlag))
354 if (recursionLevel < s_cachedStateList.length() - 1) {
356 const QVariant value = readPropertyInControlForStates(
357 main, alternative, control, stateListIndices, i + 1, recursionLevel + 1);
363 QQSK::State storageState = QQSK::StateFlag::Unspecified;
364 for (
int j = 0; j <= recursionLevel; ++j)
365 storageState.setFlag(s_cachedStateList[stateListIndices[j]]);
366 const QVariant value = readPropertyInStorageForState(main, alternative, control, storageState);
378
379
380
381
382 QVarLengthArray<
int, 10> stateListIndices(s_cachedStateList.length());
384 if (ids.subTypeProperty.property() != QQSK::Property::NoProperty) {
385 if (s_cachedState != QQSK::StateFlag::Normal) {
386 QVariant value = readPropertyInControlForStates(
387 ids.subTypeProperty, ids.subTypeAlternative, control, stateListIndices, 0, 0);
392 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal)) {
393 const QVariant value = readPropertyInStorageForState(
394 ids.subTypeProperty, ids.subTypeAlternative, control, QQSK::StateFlag::Normal);
400 if (s_cachedState != QQSK::StateFlag::Normal) {
401 const QVariant value = readPropertyInControlForStates(
402 ids.property, ids.alternative, control, stateListIndices, 0, 0);
408
409
410
411 if (control->m_writtenStates.testFlag(QQSK::StateFlag::Normal))
412 return readPropertyInStorageForState(ids.property, ids.alternative, control, QQSK::StateFlag::Normal);
419 const QQStyleKitExtendableControlType exactType,
420 const QList<QQStyleKitExtendableControlType> baseTypes)
426
428 const auto writtenProperties = controls->m_writtenPropertyPaths;
429 if (writtenProperties.contains(ids.property.pathId()))
431 const bool hasAlternative = ids.alternative.property() != QQSK::Property::NoProperty;
432 if (hasAlternative && writtenProperties.contains(ids.alternative.pathId()))
434 if (ids.subTypeProperty.property() == QQSK::Property::NoProperty)
436 if (writtenProperties.contains(ids.subTypeProperty.pathId()))
438 if (hasAlternative && writtenProperties.contains(ids.subTypeAlternative.pathId()))
444 const QVariant value = readPropertyInControl(ids, control);
449 for (
const int type : baseTypes) {
450 if (
const QQStyleKitControl *control = controls->getControl(type)) {
451 const QVariant value = readPropertyInControl(ids, control);
461 const QList<QPointer<QQStyleKitVariation>> &variations,
463 const PropertyPathIds &ids,
464 const QQStyleKitExtendableControlType exactType,
465 const QList<QQStyleKitExtendableControlType> baseTypes)
467 bool foundAtLeastOneVariation =
false;
468 for (
const QPointer<QQStyleKitVariation> &variation : variations) {
471 if (!variation->m_usageContext.contains(styleOrTheme)) {
472 if (foundAtLeastOneVariation) {
474
475
476
480
483 foundAtLeastOneVariation =
true;
484 const QVariant value = readPropertyInRelevantControls(variation, ids, exactType, baseTypes);
492 QQStyleKitStyle *style,
const PropertyPathIds &ids, QQStyleKitReader *styleReader)
495
496
497 style->syncFromQPalette(styleReader->effectivePalette());
500
501
502 cacheReaderState(styleReader->controlState());
504 if (styleReader->m_effectiveVariationsDirty)
505 rebuildVariationsForReader(styleReader, style);
507 const QQStyleKitExtendableControlType exactType = styleReader->controlType();
508 const QList<QQStyleKitExtendableControlType> baseTypes = baseTypesForType(exactType);
513 value = readPropertyInVariations(styleReader->m_effectiveVariations, style->theme(), ids, exactType, baseTypes);
517 value = readPropertyInRelevantControls(style->theme(), ids, exactType, baseTypes);
521 value = readPropertyInVariations(styleReader->m_effectiveVariations, style, ids, exactType, baseTypes);
525 value = readPropertyInRelevantControls(style, ids, exactType, baseTypes);
529 if (
auto *fallbackStyle = style->fallbackStyle()) {
531
532 value = readPropertyInStyle(fallbackStyle, ids, styleReader);
541 if (!value.isValid())
550 const QQSK::Property property,
551 const QQSK::Property alternative)
554 const QQSK::PropertyPathFlags pathFlags = group->pathFlags();
555 const QQSK::Subclass subclass = controlProperties->subclass();
557 if (subclass != QQSK::Subclass::QQStyleKitReader) {
559
560
561
562
563
564
565
566 Q_ASSERT(subclass == QQSK::Subclass::QQStyleKitState);
569 const PropertyPathId propertyPathId = group->propertyPathId(property, PropertyPathId::Flag::IncludeSubtype);
570 const PropertyStorageId key = propertyPathId.storageId(controlState->nestedState());
571 return control->readStyleProperty(key);
574 QQStyleKitStyle *style = controlProperties->style();
576 if (!s_styleWarningsIssued) {
577 s_styleWarningsIssued =
true;
578 qmlWarning(group) <<
"style properties cannot be read: No StyleKit style has been set!";
583 if (!style->loaded()) {
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.