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)
290 m_lastTextFontOverridesSignature = textOverrideSig;
291 rebuildEffectiveFont();
296 for (QQStyleKitReader *reader : s_allReaders) {
297 reader->m_effectiveVariationsDirty =
true;
298 reader->m_fontDirty =
true;
299 reader->clearLocalStorage();
300 reader->rebuildEffectivePalette();
301 reader->rebuildEffectiveFont();
302 reader->emitChangedForAllStyleProperties(EmitFlag::AllProperties);
308 if (!m_storage.isEmpty())
310 const auto *stylePtr =
style();
311 if (!stylePtr || !stylePtr->loaded())
315
316
317
322
324
325
326
327
328 m_dontEmitChangedSignals =
true;
330 m_dontEmitChangedSignals =
false;
336
337
338
344 QQSK::State effectiveState = m_state;
348 effectiveState &= ~(QQSK::StateFlag::Pressed |
349 QQSK::StateFlag::Hovered |
350 QQSK::StateFlag::Highlighted |
351 QQSK::StateFlag::Focused |
352 QQSK::StateFlag::Hovered);
355 if (effectiveState == QQSK::StateFlag::Unspecified)
356 effectiveState.setFlag(QQSK::StateFlag::Normal);
358 return effectiveState;
363 return m_storage.value(key);
368 m_storage.insert(key, value);
373 return m_dontEmitChangedSignals;
387 populateLocalStorage();
388 emit controlTypeChanged();
393QQStyleKitReader::ControlType QQStyleKitReader::typeAsControlType()
const
396
398 return ControlType(m_type);
404 return m_state.testFlag(QQSK::StateFlag::Hovered);
412 populateLocalStorage();
413 m_state.setFlag(QQSK::StateFlag::Hovered, hovered);
414 emit hoveredChanged();
420 return !m_state.testFlag(QQSK::StateFlag::Disabled);
428 populateLocalStorage();
429 m_state.setFlag(QQSK::StateFlag::Disabled, !enabled);
430 emit enabledChanged();
436 return m_state.testFlag(QQSK::StateFlag::Focused);
444 populateLocalStorage();
445 m_state.setFlag(QQSK::StateFlag::Focused, focused);
446 emit focusedChanged();
452 return m_state.testFlag(QQSK::StateFlag::Checked);
460 populateLocalStorage();
461 m_state.setFlag(QQSK::StateFlag::Checked, checked);
462 emit checkedChanged();
468 return m_state.testFlag(QQSK::StateFlag::Pressed);
476 populateLocalStorage();
477 m_state.setFlag(QQSK::StateFlag::Pressed, pressed);
478 emit pressedChanged();
484 return m_state.testFlag(QQSK::StateFlag::Vertical);
492 populateLocalStorage();
493 m_state.setFlag(QQSK::StateFlag::Vertical, vertical);
494 emit verticalChanged();
500 return m_state.testFlag(QQSK::StateFlag::Highlighted);
508 populateLocalStorage();
509 m_state.setFlag(QQSK::StateFlag::Highlighted, highlighted);
510 emit highlightedChanged();
516 return m_palette.data();
521 if (m_palette == palette)
525 QObject::disconnect(m_palette,
nullptr,
this,
nullptr);
528 emit paletteChanged();
532 QObject::connect(m_palette, &QQuickPalette::changed,
533 this, &QQStyleKitReader::onPaletteChanged);
541 return m_effectivePalette;
550 if (rebuildEffectivePalette()) {
552 emitChangedForAllStyleProperties(EmitFlag::Colors);
558 auto mergedPalette =
style()->paletteForControlType(
this->controlType());
559 const auto stylePaletteResolveMask = mergedPalette.resolveMask();
562 const auto controlPalette = m_palette->toQPalette();
563 mergedPalette = controlPalette.resolve(mergedPalette);
566 mergedPalette.setResolveMask(stylePaletteResolveMask | controlPalette.resolveMask());
568 if (m_effectivePalette == mergedPalette)
571 m_effectivePalette = mergedPalette;
589 QFont font = style->fontForControlType(controlType());
592 if (textProps->isDefined(QQSK::Property::Bold))
594 if (textProps->isDefined(QQSK::Property::Italic))
596 if (textProps->isDefined(QQSK::Property::PointSize))
597 font.setPointSizeF(textProps->pointSize());
615#include "moc_qqstylekitreader_p.cpp"
QQStyleKitTextProperties * text() const
QQStyleKitStyle * style() const
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)
QQStyleKitControlProperties * global() const
void setControlType(QQStyleKitExtendableControlType type)
QPalette effectivePalette() const
static QList< QQStyleKitReader * > s_allReaders
void setVertical(bool vertical)
QQStyleKitExtendableControlType controlType() const
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