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 {
|
component Cell: Rectangle {
|
||||||
required property string display
|
required property var display
|
||||||
required property int row
|
required property int row
|
||||||
required property int column
|
required property int column
|
||||||
|
|
||||||
required property bool editing
|
required property bool editing
|
||||||
|
|
||||||
required property bool isBinding
|
required property bool isBinding
|
||||||
|
required property var propertyValue
|
||||||
|
|
||||||
color: root.backgroundColor
|
color: root.backgroundColor
|
||||||
implicitWidth: root.cellWidth
|
implicitWidth: root.cellWidth
|
||||||
@@ -227,7 +228,7 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
leftPadding: root.leftPadding
|
leftPadding: root.leftPadding
|
||||||
|
|
||||||
value: parseInt(numberDelegate.display)
|
value: numberDelegate.display
|
||||||
from: -1000 // TODO define min/max
|
from: -1000 // TODO define min/max
|
||||||
to: 1000
|
to: 1000
|
||||||
editable: true
|
editable: true
|
||||||
@@ -261,7 +262,7 @@ Rectangle {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: root.leftPadding
|
anchors.leftMargin: root.leftPadding
|
||||||
|
|
||||||
checked: flagDelegate.display === "true"
|
checked: flagDelegate.display
|
||||||
text: flagDelegate.display
|
text: flagDelegate.display
|
||||||
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
@@ -328,7 +329,7 @@ Rectangle {
|
|||||||
height: parent.height
|
height: parent.height
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
color: StudioTheme.Values.themeTextColor
|
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
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "collectionmodel.h"
|
#include "collectionmodel.h"
|
||||||
|
#include <designsystem/dsstore.h>
|
||||||
#include <designsystem/dsthemegroup.h>
|
#include <designsystem/dsthemegroup.h>
|
||||||
#include <designsystem/dsthememanager.h>
|
#include <designsystem/dsthememanager.h>
|
||||||
|
|
||||||
@@ -9,8 +10,9 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
CollectionModel::CollectionModel(DSThemeManager *collection)
|
CollectionModel::CollectionModel(DSThemeManager *collection, const DSStore *store)
|
||||||
: m_collection(collection)
|
: m_collection(collection)
|
||||||
|
, m_store(store)
|
||||||
{
|
{
|
||||||
updateCache();
|
updateCache();
|
||||||
}
|
}
|
||||||
@@ -47,14 +49,22 @@ QVariant CollectionModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!property)
|
if (!property)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
const QVariant propertyValue = property->value.toString();
|
||||||
|
const QVariant displayValue = property->isBinding
|
||||||
|
? m_store->resolvedDSBinding(propertyValue.toString()).value
|
||||||
|
: property->value;
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return property->value.toString();
|
case Roles::ResolvedValueRole:
|
||||||
case static_cast<int>(Roles::GroupRole):
|
return displayValue;
|
||||||
|
case Roles::PropertyValueRole:
|
||||||
|
return propertyValue;
|
||||||
|
case Roles::GroupRole:
|
||||||
return QVariant::fromValue<GroupType>(groupType);
|
return QVariant::fromValue<GroupType>(groupType);
|
||||||
case static_cast<int>(Roles::BindingRole):
|
case Roles::BindingRole:
|
||||||
return property->isBinding;
|
return property->isBinding;
|
||||||
case static_cast<int>(Roles::ActiveThemeRole):
|
case Roles::ActiveThemeRole:
|
||||||
return m_collection->activeTheme() == themeId;
|
return m_collection->activeTheme() == themeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +96,7 @@ QVariant CollectionModel::headerData(int section, Qt::Orientation orientation, i
|
|||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return QString::fromLatin1(m_collection->themeName(themeId));
|
return QString::fromLatin1(m_collection->themeName(themeId));
|
||||||
case static_cast<int>(Roles::ActiveThemeRole):
|
case Roles::ActiveThemeRole:
|
||||||
return m_collection->activeTheme() == themeId;
|
return m_collection->activeTheme() == themeId;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -97,7 +107,7 @@ QVariant CollectionModel::headerData(int section, Qt::Orientation orientation, i
|
|||||||
if (auto propInfo = findPropertyName(section)) {
|
if (auto propInfo = findPropertyName(section)) {
|
||||||
if (role == Qt::DisplayRole)
|
if (role == Qt::DisplayRole)
|
||||||
return QString::fromLatin1(propInfo->second);
|
return QString::fromLatin1(propInfo->second);
|
||||||
if (role == static_cast<int>(Roles::GroupRole))
|
if (role == Roles::GroupRole)
|
||||||
return QVariant::fromValue<GroupType>(propInfo->first);
|
return QVariant::fromValue<GroupType>(propInfo->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,9 +122,11 @@ Qt::ItemFlags CollectionModel::flags(const QModelIndex &index) const
|
|||||||
QHash<int, QByteArray> CollectionModel::roleNames() const
|
QHash<int, QByteArray> CollectionModel::roleNames() const
|
||||||
{
|
{
|
||||||
auto roles = QAbstractItemModel::roleNames();
|
auto roles = QAbstractItemModel::roleNames();
|
||||||
roles.insert(static_cast<int>(Roles::GroupRole), "group");
|
roles.insert(Roles::ResolvedValueRole, "resolvedValue");
|
||||||
roles.insert(static_cast<int>(Roles::BindingRole), "isBinding");
|
roles.insert(Roles::GroupRole, "group");
|
||||||
roles.insert(static_cast<int>(Roles::ActiveThemeRole), "isActive");
|
roles.insert(Roles::BindingRole, "isBinding");
|
||||||
|
roles.insert(Roles::ActiveThemeRole, "isActive");
|
||||||
|
roles.insert(Roles::PropertyValueRole, "propertyValue");
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
class DSThemeManager;
|
class DSThemeManager;
|
||||||
|
class DSStore;
|
||||||
using PropInfo = std::pair<GroupType, PropertyName>;
|
using PropInfo = std::pair<GroupType, PropertyName>;
|
||||||
|
|
||||||
class CollectionModel : public QAbstractItemModel
|
class CollectionModel : public QAbstractItemModel
|
||||||
@@ -17,11 +18,17 @@ class CollectionModel : public QAbstractItemModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
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)
|
Q_PROPERTY(QStringList themeNames READ themeNameList NOTIFY themeNameChanged FINAL)
|
||||||
|
|
||||||
CollectionModel(DSThemeManager *collection);
|
CollectionModel(DSThemeManager *collection, const DSStore *store);
|
||||||
|
|
||||||
QStringList themeNameList() const;
|
QStringList themeNameList() const;
|
||||||
Q_INVOKABLE void setActiveTheme(const QString &themeName);
|
Q_INVOKABLE void setActiveTheme(const QString &themeName);
|
||||||
@@ -66,6 +73,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DSThemeManager *m_collection = nullptr;
|
DSThemeManager *m_collection = nullptr;
|
||||||
|
const DSStore *m_store;
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
std::vector<ThemeId> m_themeIdList;
|
std::vector<ThemeId> m_themeIdList;
|
||||||
|
@@ -74,7 +74,8 @@ QStringList DesignSystemInterface::collections() const
|
|||||||
CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection)
|
CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection)
|
||||||
{
|
{
|
||||||
auto [newItr, success] = m_models.try_emplace(typeName,
|
auto [newItr, success] = m_models.try_emplace(typeName,
|
||||||
std::make_unique<CollectionModel>(collection));
|
std::make_unique<CollectionModel>(collection,
|
||||||
|
m_store));
|
||||||
if (success) {
|
if (success) {
|
||||||
// Otherwise the model will be deleted by the QML engine.
|
// Otherwise the model will be deleted by the QML engine.
|
||||||
QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership);
|
QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership);
|
||||||
|
@@ -248,6 +248,28 @@ QStringList DSStore::collectionNames() const
|
|||||||
return names;
|
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
|
QString DSStore::uniqueCollectionName(const QString &hint) const
|
||||||
{
|
{
|
||||||
return UniqueName::generateTypeName(hint, "Collection", [this](const QString &t) {
|
return UniqueName::generateTypeName(hint, "Collection", [this](const QString &t) {
|
||||||
|
@@ -38,6 +38,8 @@ public:
|
|||||||
std::optional<Utils::FilePath> moduleDirPath() const;
|
std::optional<Utils::FilePath> moduleDirPath() const;
|
||||||
QStringList collectionNames() const;
|
QStringList collectionNames() const;
|
||||||
|
|
||||||
|
ThemeProperty resolvedDSBinding(QStringView binding) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString uniqueCollectionName(const QString &hint) const;
|
QString uniqueCollectionName(const QString &hint) const;
|
||||||
std::optional<QString> loadCollection(const QString &typeName, const Utils::FilePath &qmlFilePath);
|
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);
|
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,
|
std::optional<ThemeProperty> DSThemeManager::property(ThemeId themeId,
|
||||||
GroupType gType,
|
GroupType gType,
|
||||||
const PropertyName &name) const
|
const PropertyName &name) const
|
||||||
|
@@ -50,6 +50,8 @@ public:
|
|||||||
|
|
||||||
void duplicateTheme(ThemeId from, ThemeId to);
|
void duplicateTheme(ThemeId from, ThemeId to);
|
||||||
|
|
||||||
|
std::optional<GroupType> groupType(const PropertyName &name) const;
|
||||||
|
|
||||||
bool addProperty(GroupType gType, const ThemeProperty &p);
|
bool addProperty(GroupType gType, const ThemeProperty &p);
|
||||||
std::optional<ThemeProperty> property(ThemeId themeId,
|
std::optional<ThemeProperty> property(ThemeId themeId,
|
||||||
GroupType gType,
|
GroupType gType,
|
||||||
|
Reference in New Issue
Block a user