forked from qt-creator/qt-creator
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:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user