DesignSystem: Resolve design system bindings

Task-number: QDS-14261
Change-Id: I24215950c556f201bbfb53d043b63fd596ccc6aa
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Vikas Pachdha
2024-12-30 00:04:03 +01:00
parent 4789783d12
commit 2a721d5937
8 changed files with 74 additions and 17 deletions

View File

@@ -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
}
}

View File

@@ -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 <designsystem/dsstore.h>
#include <designsystem/dsthemegroup.h>
#include <designsystem/dsthememanager.h>
@@ -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<int>(Roles::GroupRole):
case Roles::ResolvedValueRole:
return displayValue;
case Roles::PropertyValueRole:
return propertyValue;
case Roles::GroupRole:
return QVariant::fromValue<GroupType>(groupType);
case static_cast<int>(Roles::BindingRole):
case Roles::BindingRole:
return property->isBinding;
case static_cast<int>(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<int>(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<int>(Roles::GroupRole))
if (role == Roles::GroupRole)
return QVariant::fromValue<GroupType>(propInfo->first);
}
}
@@ -112,9 +122,11 @@ Qt::ItemFlags CollectionModel::flags(const QModelIndex &index) const
QHash<int, QByteArray> CollectionModel::roleNames() const
{
auto roles = QAbstractItemModel::roleNames();
roles.insert(static_cast<int>(Roles::GroupRole), "group");
roles.insert(static_cast<int>(Roles::BindingRole), "isBinding");
roles.insert(static_cast<int>(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;
}

View File

@@ -10,6 +10,7 @@
namespace QmlDesigner {
class DSThemeManager;
class DSStore;
using PropInfo = std::pair<GroupType, PropertyName>;
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<ThemeId> m_themeIdList;

View File

@@ -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<CollectionModel>(collection));
std::make_unique<CollectionModel>(collection,
m_store));
if (success) {
// Otherwise the model will be deleted by the QML engine.
QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership);

View File

@@ -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) {

View File

@@ -38,6 +38,8 @@ public:
std::optional<Utils::FilePath> moduleDirPath() const;
QStringList collectionNames() const;
ThemeProperty resolvedDSBinding(QStringView binding) const;
private:
QString uniqueCollectionName(const QString &hint) const;
std::optional<QString> loadCollection(const QString &typeName, const Utils::FilePath &qmlFilePath);

View File

@@ -150,6 +150,15 @@ void DSThemeManager::duplicateTheme(ThemeId from, ThemeId to)
group->duplicateValues(from, to);
}
std::optional<GroupType> DSThemeManager::groupType(const PropertyName &name) const
{
for (const auto &[gt, group] : m_groups) {
if (group->hasProperty(name))
return gt;
}
return {};
}
std::optional<ThemeProperty> DSThemeManager::property(ThemeId themeId,
GroupType gType,
const PropertyName &name) const

View File

@@ -50,6 +50,8 @@ public:
void duplicateTheme(ThemeId from, ThemeId to);
std::optional<GroupType> groupType(const PropertyName &name) const;
bool addProperty(GroupType gType, const ThemeProperty &p);
std::optional<ThemeProperty> property(ThemeId themeId,
GroupType gType,