// Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qqstylekitcontrol_p.h" #include "qqstylekitpropertyresolver_p.h" QT_BEGIN_NAMESPACE int QQStyleKitControlAttached::s_variationCount = 0; QQStyleKitControl::QQStyleKitControl(QObject *parent) : QQStyleKitControlState(parent) { } QQmlListProperty QQStyleKitControl::variations() { const bool isWrite = subclass() == QQSK::Subclass::QQStyleKitState; if (isWrite) { if (!QQStyleKitPropertyResolver::hasLocalStyleProperty(this, QQSK::Property::Variations)) { /* We need to handle both the setter and the getter in the getter, since QML doesn't * use a separate setter for QQmlListProperty. This means that we need to initialize * the storage with an empty QList, since we need to be prepared for the QML engine * inserting elements into it behind our back. A negative side-effect of this logic * is that a simple read of the property for a QQStyleKitState will also accidentally * populate the local storage of that QQStylKitState, and thereby affect propagation. * Note: since Variations is not a part of QQStyleKitProperties, it's not possible, * and there is also no point, in emitting a changed signal globally, since a * QQuickStyleKitReader inherits QQStyleKitProperties and not QQStyleKitControl, * and as such, doesn't have a 'variations' property. */ auto *newList = new QList(); setStyleProperty(QQSK::Property::Variations, newList); } } /* Read the property, taking propagation into account. Note that since QQmlListProperty takes * a pointer to a QList as argument, we need to store the list as a pointer as well */ const QVariant variant = QQStyleKitPropertyResolver::readStyleProperty(this, QQSK::Property::Variations); if (!variant.isValid()) { // Return a read-only list. Trying to change this list from the app has no effect. static auto *emptyList = new QList(); return QQmlListProperty(this, emptyList); } const auto value = qvariant_cast *>(variant); return QQmlListProperty(this, value); } QQStyleKitControlAttached *QQStyleKitControl::qmlAttachedProperties(QObject *object) { return new QQStyleKitControlAttached(object); } QVariant QQStyleKitControl::readStyleProperty(PropertyStorageId key) const { return m_storage.value(key); } void QQStyleKitControl::writeStyleProperty(PropertyStorageId key, const QVariant &value) { m_storage.insert(key, value); } QQStyleKitControlAttached::QQStyleKitControlAttached(QObject *parent) : QObject(parent) { } QStringList QQStyleKitControlAttached::variations() const { return m_variations; } void QQStyleKitControlAttached::setVariations(const QStringList &variations) { if (m_variations == variations) return; /* As an optimization, we count the number of variations set from the application. * That way, if s_variationCount == 1, for example, and we found a variation while * resolving the effective variations for a specific QQStyleReader, we can stop the search. */ s_variationCount++; m_variations = variations; emit variationsChanged(); } QQStyleKitExtendedControlType QQStyleKitControlAttached::controlType() { return m_controlType; } void QQStyleKitControlAttached::setControlType(QQStyleKitExtendedControlType type) { if (m_controlType == type) return; m_controlType = type; emit controlTypeChanged(); } QT_END_NAMESPACE #include "moc_qqstylekitcontrol_p.cpp"