diff --git a/share/qtcreator/qmldesigner/designsystem/Main.qml b/share/qtcreator/qmldesigner/designsystem/Main.qml index 7033eda1f6d..7c444c44e4f 100644 --- a/share/qtcreator/qmldesigner/designsystem/Main.qml +++ b/share/qtcreator/qmldesigner/designsystem/Main.qml @@ -121,13 +121,14 @@ Rectangle { } component Cell: Rectangle { - required property string display + required property var display required property int row required property int column required property bool editing required property bool isBinding + required property var propertyValue color: root.backgroundColor implicitWidth: root.cellWidth @@ -227,7 +228,7 @@ Rectangle { anchors.fill: parent leftPadding: root.leftPadding - value: parseInt(numberDelegate.display) + value: numberDelegate.display from: -1000 // TODO define min/max to: 1000 editable: true @@ -261,7 +262,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: root.leftPadding - checked: flagDelegate.display === "true" + checked: flagDelegate.display text: flagDelegate.display onToggled: { @@ -328,7 +329,7 @@ Rectangle { height: parent.height verticalAlignment: Qt.AlignVCenter color: StudioTheme.Values.themeTextColor - text: colorDelegate.display + text: colorDelegate.propertyValue } } diff --git a/src/plugins/qmldesigner/components/designsystemview/collectionmodel.cpp b/src/plugins/qmldesigner/components/designsystemview/collectionmodel.cpp index 8f0da771143..a9c4922caf4 100644 --- a/src/plugins/qmldesigner/components/designsystemview/collectionmodel.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/collectionmodel.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "collectionmodel.h" +#include #include #include @@ -9,8 +10,9 @@ namespace QmlDesigner { -CollectionModel::CollectionModel(DSThemeManager *collection) +CollectionModel::CollectionModel(DSThemeManager *collection, const DSStore *store) : m_collection(collection) + , m_store(store) { updateCache(); } @@ -47,14 +49,22 @@ QVariant CollectionModel::data(const QModelIndex &index, int role) const if (!property) return {}; + const QVariant propertyValue = property->value.toString(); + const QVariant displayValue = property->isBinding + ? m_store->resolvedDSBinding(propertyValue.toString()).value + : property->value; + switch (role) { case Qt::DisplayRole: - return property->value.toString(); - case static_cast(Roles::GroupRole): + case Roles::ResolvedValueRole: + return displayValue; + case Roles::PropertyValueRole: + return propertyValue; + case Roles::GroupRole: return QVariant::fromValue(groupType); - case static_cast(Roles::BindingRole): + case Roles::BindingRole: return property->isBinding; - case static_cast(Roles::ActiveThemeRole): + case Roles::ActiveThemeRole: return m_collection->activeTheme() == themeId; } @@ -86,7 +96,7 @@ QVariant CollectionModel::headerData(int section, Qt::Orientation orientation, i switch (role) { case Qt::DisplayRole: return QString::fromLatin1(m_collection->themeName(themeId)); - case static_cast(Roles::ActiveThemeRole): + case Roles::ActiveThemeRole: return m_collection->activeTheme() == themeId; default: break; @@ -97,7 +107,7 @@ QVariant CollectionModel::headerData(int section, Qt::Orientation orientation, i if (auto propInfo = findPropertyName(section)) { if (role == Qt::DisplayRole) return QString::fromLatin1(propInfo->second); - if (role == static_cast(Roles::GroupRole)) + if (role == Roles::GroupRole) return QVariant::fromValue(propInfo->first); } } @@ -112,9 +122,11 @@ Qt::ItemFlags CollectionModel::flags(const QModelIndex &index) const QHash CollectionModel::roleNames() const { auto roles = QAbstractItemModel::roleNames(); - roles.insert(static_cast(Roles::GroupRole), "group"); - roles.insert(static_cast(Roles::BindingRole), "isBinding"); - roles.insert(static_cast(Roles::ActiveThemeRole), "isActive"); + roles.insert(Roles::ResolvedValueRole, "resolvedValue"); + roles.insert(Roles::GroupRole, "group"); + roles.insert(Roles::BindingRole, "isBinding"); + roles.insert(Roles::ActiveThemeRole, "isActive"); + roles.insert(Roles::PropertyValueRole, "propertyValue"); return roles; } diff --git a/src/plugins/qmldesigner/components/designsystemview/collectionmodel.h b/src/plugins/qmldesigner/components/designsystemview/collectionmodel.h index 3ab0250822b..c0b43500012 100644 --- a/src/plugins/qmldesigner/components/designsystemview/collectionmodel.h +++ b/src/plugins/qmldesigner/components/designsystemview/collectionmodel.h @@ -10,6 +10,7 @@ namespace QmlDesigner { class DSThemeManager; +class DSStore; using PropInfo = std::pair; class CollectionModel : public QAbstractItemModel @@ -17,11 +18,17 @@ class CollectionModel : public QAbstractItemModel Q_OBJECT public: - enum class Roles { GroupRole = Qt::UserRole + 1, BindingRole, ActiveThemeRole }; + enum Roles { + GroupRole = Qt::UserRole + 1, + BindingRole, + ActiveThemeRole, + ResolvedValueRole, + PropertyValueRole + }; Q_PROPERTY(QStringList themeNames READ themeNameList NOTIFY themeNameChanged FINAL) - CollectionModel(DSThemeManager *collection); + CollectionModel(DSThemeManager *collection, const DSStore *store); QStringList themeNameList() const; Q_INVOKABLE void setActiveTheme(const QString &themeName); @@ -66,6 +73,7 @@ private: private: DSThemeManager *m_collection = nullptr; + const DSStore *m_store; // cache std::vector m_themeIdList; diff --git a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp index 987d30e7263..e7f07cbf9a1 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp @@ -74,7 +74,8 @@ QStringList DesignSystemInterface::collections() const CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection) { auto [newItr, success] = m_models.try_emplace(typeName, - std::make_unique(collection)); + std::make_unique(collection, + m_store)); if (success) { // Otherwise the model will be deleted by the QML engine. QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership); diff --git a/src/plugins/qmldesigner/libs/designsystem/dsstore.cpp b/src/plugins/qmldesigner/libs/designsystem/dsstore.cpp index ffa4050c9d5..143ba6f262b 100644 --- a/src/plugins/qmldesigner/libs/designsystem/dsstore.cpp +++ b/src/plugins/qmldesigner/libs/designsystem/dsstore.cpp @@ -248,6 +248,28 @@ QStringList DSStore::collectionNames() const return names; } +ThemeProperty DSStore::resolvedDSBinding(QStringView binding) const +{ + const auto parts = binding.split('.', Qt::SkipEmptyParts); + if (parts.size() != 3) + return {}; + + const auto &collectionName = parts[0]; + auto itr = m_collections.find(collectionName.toString()); + if (itr == m_collections.end()) + return {}; + + const DSThemeManager &boundCollection = itr->second; + const auto &propertyName = parts[2].toLatin1(); + if (const auto group = boundCollection.groupType(propertyName)) { + auto property = boundCollection.property(boundCollection.activeTheme(), *group, propertyName); + if (property) + return property->isBinding ? resolvedDSBinding(property->value.toString()) : *property; + } + + return {}; +} + QString DSStore::uniqueCollectionName(const QString &hint) const { return UniqueName::generateTypeName(hint, "Collection", [this](const QString &t) { diff --git a/src/plugins/qmldesigner/libs/designsystem/dsstore.h b/src/plugins/qmldesigner/libs/designsystem/dsstore.h index 9708587821a..f51794edcf8 100644 --- a/src/plugins/qmldesigner/libs/designsystem/dsstore.h +++ b/src/plugins/qmldesigner/libs/designsystem/dsstore.h @@ -38,6 +38,8 @@ public: std::optional moduleDirPath() const; QStringList collectionNames() const; + ThemeProperty resolvedDSBinding(QStringView binding) const; + private: QString uniqueCollectionName(const QString &hint) const; std::optional loadCollection(const QString &typeName, const Utils::FilePath &qmlFilePath); diff --git a/src/plugins/qmldesigner/libs/designsystem/dsthememanager.cpp b/src/plugins/qmldesigner/libs/designsystem/dsthememanager.cpp index 08e430c77a3..d891ba7b153 100644 --- a/src/plugins/qmldesigner/libs/designsystem/dsthememanager.cpp +++ b/src/plugins/qmldesigner/libs/designsystem/dsthememanager.cpp @@ -150,6 +150,15 @@ void DSThemeManager::duplicateTheme(ThemeId from, ThemeId to) group->duplicateValues(from, to); } +std::optional DSThemeManager::groupType(const PropertyName &name) const +{ + for (const auto &[gt, group] : m_groups) { + if (group->hasProperty(name)) + return gt; + } + return {}; +} + std::optional DSThemeManager::property(ThemeId themeId, GroupType gType, const PropertyName &name) const diff --git a/src/plugins/qmldesigner/libs/designsystem/dsthememanager.h b/src/plugins/qmldesigner/libs/designsystem/dsthememanager.h index c36bcfed831..27556292a6d 100644 --- a/src/plugins/qmldesigner/libs/designsystem/dsthememanager.h +++ b/src/plugins/qmldesigner/libs/designsystem/dsthememanager.h @@ -50,6 +50,8 @@ public: void duplicateTheme(ThemeId from, ThemeId to); + std::optional groupType(const PropertyName &name) const; + bool addProperty(GroupType gType, const ThemeProperty &p); std::optional property(ThemeId themeId, GroupType gType,