4#include <QtQuick/private/qquickpalette_p.h>
5#include <QtQuick/private/qquickwindow_p.h>
6#include <QtQuick/private/qquickstategroup_p.h>
7#include <QtQuick/private/qquickpropertychanges_p.h>
16using namespace Qt::StringLiterals;
29 if (t->isDefined(QQSK::Property::Bold)) {
30 sig |= (quint64(1) << 0);
31 if (t->styleProperty<
bool>(QQSK::Property::Bold))
32 sig |= (quint64(1) << 1);
35 if (t->isDefined(QQSK::Property::Italic)) {
36 sig |= (quint64(1) << 2);
37 if (t->styleProperty<
bool>(QQSK::Property::Italic))
38 sig |= (quint64(1) << 3);
41 if (t->isDefined(QQSK::Property::PointSize)) {
42 sig |= (quint64(1) << 4);
43 const qreal ps = t->styleProperty<qreal>(QQSK::Property::PointSize);
45 constexpr int payloadBits = 64 - 5;
46 const qint64 maxQ = (quint64(1) << payloadBits) - 1;
47 const quint64 q = quint64(qBound<qint64>(0, qRound64(ps * 64.0), maxQ));
57 : QQStyleKitControlProperties(QQSK::PropertyGroup::Control, parent)
58 , m_dontEmitChangedSignals(
false)
59 , m_effectiveVariationsDirty(
true)
60 , m_global(QQStyleKitControlProperties(QQSK::PropertyGroup::GlobalFlag,
this))
62 s_allReaders.append(
this);
67 s_allReaders.removeOne(
this);
76
77
78
79 const auto *stylePtr =
style();
82 m_stateGroup =
new QQuickStateGroup(
this);
85 auto statesProp = m_stateGroup->statesProperty();
86 QQuickState *alternate1 =
new QQuickState(m_stateGroup);
87 QQuickState *alternate2 =
new QQuickState(m_stateGroup);
88 alternate1->setName(kAlternate1);
89 alternate2->setName(kAlternate2);
90 m_stateGroup->statesProperty().append(&statesProp, alternate1);
91 m_stateGroup->statesProperty().append(&statesProp, alternate2);
93 QQmlComponent *controlComp = createControlChangesComponent();
94 instantiatePropertyChanges(controlComp);
101 static const QLatin1String propertyName(
"control"_L1);
102 if (s_propertyChangesComponents.contains(propertyName))
103 return s_propertyChangesComponents.value(propertyName);
105 const QString qmlControlCode = QString::fromUtf8(R"(
106 import QtQuick
107 PropertyChanges {
108 spacing: global.spacing
109 padding: global.padding
110 leftPadding: global.leftPadding
111 rightPadding: global.rightPadding
112 topPadding: global.topPadding
113 bottomPadding: global.bottomPadding
114 text.color: global.text.color
115 text.alignment: global.text.alignment
116 text.bold: global.text.bold
117 text.italic: global.text.italic
118 text.pointSize: global.text.pointSize
119 text.padding: global.text.padding
120 text.leftPadding: global.text.leftPadding
121 text.rightPadding: global.text.rightPadding
122 text.topPadding: global.text.topPadding
123 text.bottomPadding: global.text.bottomPadding
124 }
125 )");
128 QQmlComponent *component =
new QQmlComponent(qmlEngine(style()));
129 component->setData(qmlControlCode.toUtf8(), QUrl());
130 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
131 s_propertyChangesComponents.insert(propertyName, component);
135QQmlComponent *
QQStyleKitReader::createDelegateChangesComponent(
const QString &delegateName)
const
137 if (s_propertyChangesComponents.contains(delegateName))
138 return s_propertyChangesComponents.value(delegateName);
140 static const QString qmlTemplateCode = QString::fromUtf8(R"(
141 import QtQuick
142 PropertyChanges { $ {
143 implicitWidth: global.$.implicitWidth
144 implicitHeight: global.$.implicitHeight
145 visible: global.$.visible
146 color: global.$.color
147 gradient: global.$.gradient
148 radius: global.$.radius
149 topLeftRadius: global.$.topLeftRadius
150 topRightRadius: global.$.topRightRadius
151 bottomLeftRadius: global.$.bottomLeftRadius
152 bottomRightRadius: global.$.bottomRightRadius
153 margins: global.$.margins
154 alignment: global.$.alignment
155 leftMargin: global.$.leftMargin
156 rightMargin: global.$.rightMargin
157 topMargin: global.$.topMargin
158 bottomMargin: global.$.bottomMargin
159 scale: global.$.scale
160 rotation: global.$.rotation
161 opacity: global.$.opacity
162 border.color: global.$.border.color
163 border.width: global.$.border.width
164 shadow.color: global.$.shadow.color
165 shadow.scale: global.$.shadow.scale
166 shadow.blur: global.$.shadow.blur
167 shadow.visible: global.$.shadow.visible
168 shadow.opacity: global.$.shadow.opacity
169 shadow.verticalOffset: global.$.shadow.verticalOffset
170 shadow.horizontalOffset: global.$.shadow.horizontalOffset
171 shadow.delegate: global.$.shadow.delegate
172 image.source: global.$.image.source
173 image.color: global.$.image.color
174 image.fillMode: global.$.image.fillMode
175 delegate: global.$.delegate
176 data: global.$.data
177 }}
178 )");
180 QString substitutedCode = qmlTemplateCode;
181 substitutedCode.replace(
'$'_L1, delegateName);
182 QQmlComponent *component =
new QQmlComponent(qmlEngine(style()));
183 component->setData(substitutedCode.toUtf8(), QUrl());
184 Q_ASSERT_X(!component->isError(),
__FUNCTION__, component->errorString().toUtf8().constData());
185 s_propertyChangesComponents.insert(delegateName, component);
191 QObject *obj = comp->create(qmlContext(
this));
192 auto *propertyChanges = qobject_cast<QQuickPropertyChanges *>(obj);
193 Q_ASSERT(propertyChanges);
196 propertyChanges->setObject(
this);
198
199
200
201
202
203 propertyChanges->setIsExplicit(
true);
205
206
207 propertyChanges->setRestoreEntryValues(
false);
210 for (QQuickState *state : stateGroup()->states()) {
211 auto changesProp = state->changes();
212 changesProp.append(&changesProp, propertyChanges);
219 [
this](QQStyleKitDelegateProperties *delegate, QQSK::Delegate type,
const QString &delegatePath){
220 if (m_trackedDelegates.testFlag(type)) {
224 if (!delegate->visible()) {
226
227
231
232
233
234
235 m_trackedDelegates.setFlag(type);
236 QQmlComponent *comp = createDelegateChangesComponent(delegatePath);
237 instantiatePropertyChanges(comp);
248
249
250
251
252
253
254
255
256
257
258
260 maybeTrackDelegates();
262 auto transitionProp = stateGroup()->transitionsProperty();
263 const int transitionCountInStateGroup = transitionProp.count(&transitionProp);
264 const bool enabled = QQStyleKit::qmlAttachedProperties()->transitionsEnabled();
265 QQuickTransition *transitionInStyle = enabled ? transition() :
nullptr;
266 QQuickTransition *transitionInStateGroup =
267 transitionCountInStateGroup > 0 ? transitionProp.at(&transitionProp, 0) :
nullptr;
268 if (transitionInStyle != transitionInStateGroup) {
269 transitionProp.clear(&transitionProp);
270 if (transitionInStyle)
271 transitionProp.append(&transitionProp, transitionInStyle);
274 switch (m_alternateState) {
275 case AlternateState::Alternate1:
276 m_alternateState = AlternateState::Alternate2;
277 stateGroup()->setState(kAlternate2);
279 case AlternateState::Alternate2:
280 m_alternateState = AlternateState::Alternate1;
281 stateGroup()->setState(kAlternate1);
287 auto textOverrideSig = textFontOverridesSignature(global()->text());
288 if (m_lastTextFontOverridesSignature != textOverrideSig)
289 m_effectiveFontDirty =
true;
290 m_lastTextFontOverridesSignature = textOverrideSig;
291 rebuildEffectiveFont();
296 for (QQStyleKitReader *reader : s_allReaders) {
297 reader->m_effectiveVariationsDirty =
true;
298 reader->clearLocalStorage();
299 reader->rebuildEffectivePalette();
300 reader->rebuildEffectiveFont();
301 reader->emitChangedForAllStyleProperties();
307 if (!m_storage.isEmpty())
309 const auto *stylePtr =
style();
310 if (!stylePtr || !stylePtr->loaded())
314
315
316
321
323
324
325
326
327 m_dontEmitChangedSignals =
true;
329 m_dontEmitChangedSignals =
false;
335
336
337
343 QQSK::State effectiveState = m_state;
347 effectiveState &= ~(QQSK::StateFlag::Pressed |
348 QQSK::StateFlag::Hovered |
349 QQSK::StateFlag::Highlighted |
350 QQSK::StateFlag::Focused |
351 QQSK::StateFlag::Hovered);
354 if (effectiveState == QQSK::StateFlag::Unspecified)
355 effectiveState.setFlag(QQSK::StateFlag::Normal);
357 return effectiveState;
362 return m_storage.value(key);
367 m_storage.insert(key, value);
372 return m_dontEmitChangedSignals;
386 populateLocalStorage();
392QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
395
397 return ControlType(m_type);
403 return m_state.testFlag(QQSK::StateFlag::Hovered);
411 populateLocalStorage();
412 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
413 emit hoveredChanged();
419 return !m_state.testFlag(QQSK::StateFlag::Disabled);
427 populateLocalStorage();
428 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
429 emit enabledChanged();
435 return m_state.testFlag(QQSK::StateFlag::Focused);
443 populateLocalStorage();
444 m_state.setFlag(QQSK::StateFlag::Focused, focused);
445 emit focusedChanged();
451 return m_state.testFlag(QQSK::StateFlag::Checked);
459 populateLocalStorage();
460 m_state.setFlag(QQSK::StateFlag::Checked, checked);
461 emit checkedChanged();
467 return m_state.testFlag(QQSK::StateFlag::Pressed);
475 populateLocalStorage();
476 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
477 emit pressedChanged();
483 return m_state.testFlag(QQSK::StateFlag::Vertical);
491 populateLocalStorage();
492 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
493 emit verticalChanged();
499 return m_state.testFlag(QQSK::StateFlag::Highlighted);
507 populateLocalStorage();
508 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
509 emit highlightedChanged();
515 return m_palette.data();
520 if (m_palette == palette)
524 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
527 emit paletteChanged();
531 QObject::connect(m_palette, &QQuickPalette::changed,
532 this, &QQStyleKitReader::onPaletteChanged);
540 return m_effectivePalette;
549 if (rebuildEffectivePalette()) {
557 auto mergedPalette =
style()->paletteForControlType(
this->type());
558 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
561 const auto controlPalette = m_palette->toQPalette();
562 mergedPalette = controlPalette.resolve(mergedPalette);
565 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
567 if (m_effectivePalette == mergedPalette)
570 m_effectivePalette = mergedPalette;
585 m_effectiveFontDirty =
true;
588 rebuildEffectiveFont();
593 return m_effectiveFont;
602 if (!m_effectiveFontDirty)
607 QFont mergedFont = style->fontForControlType(
this->type());
608 mergedFont = m_font.resolve(mergedFont);
609 mergedFont.setResolveMask(mergedFont.resolveMask() | m_font.resolveMask());
613 if (textProps->isDefined(QQSK::Property::Bold))
614 mergedFont.setBold(textProps->styleProperty<
bool>(QQSK::Property::Bold));
615 if (textProps->isDefined(QQSK::Property::Italic))
616 mergedFont.setItalic(textProps->styleProperty<
bool>(QQSK::Property::Italic));
617 if (textProps->isDefined(QQSK::Property::PointSize))
618 mergedFont.setPointSizeF(textProps->styleProperty<qreal>(QQSK::Property::PointSize));
621 if (m_effectiveFont == mergedFont)
624 m_effectiveFont = mergedFont;
625 emit effectiveFontChanged();
636#include "moc_qqstylekitreader_p.cpp"
QQStyleKitTextProperties * text() const
void emitChangedForAllStyleProperties()
QQStyleKitStyle * style() const
void setType(QQStyleKitExtendableControlType type)
QVariant readStyleProperty(PropertyStorageId key) const
void setHovered(bool hovered)
void setPressed(bool pressed)
QQSK::State controlState() const
void setFocused(bool focused)
void setPalette(QQuickPalette *palette)
QFont effectiveFont() const
void setFont(const QFont &font)
QQStyleKitExtendableControlType type() const
QQStyleKitControlProperties * global() const
QPalette effectivePalette() const
static QList< QQStyleKitReader * > s_allReaders
void setVertical(bool vertical)
QQuickPalette * palette() const
void setEnabled(bool enabled)
void setHighlighted(bool highlighted)
void setChecked(bool checked)
void writeStyleProperty(PropertyStorageId key, const QVariant &value)
static QQStyleKitStyle * current()
Combined button and popup list for selecting options.
static quint64 textFontOverridesSignature(const QQStyleKitTextProperties *t)
static const QString kAlternate2
static const QString kAlternate1