diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp index 151c7aca3ed..9221919df45 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp @@ -49,6 +49,18 @@ inline void setVariantPropertyValue(const QmlDesigner::ModelNode &node, property.setValue(value); } +inline void setNodePropertyValue(const QmlDesigner::ModelNode &node, + const QmlDesigner::PropertyName &propertyName, + const QmlDesigner::ModelNode &value) +{ + QmlDesigner::NodeProperty nodeProperty = node.nodeProperty(propertyName); + // Remove the old model node if is available + if (nodeProperty.modelNode()) + nodeProperty.modelNode().destroy(); + + nodeProperty.setModelNode(value); +} + inline void setBindingPropertyExpression(const QmlDesigner::ModelNode &node, const QmlDesigner::PropertyName &propertyName, const QString &expression) @@ -256,7 +268,6 @@ void CollectionView::assignCollectionToNode(const QString &collectionName, const if (!m_widget) return; - using DataType = CollectionDetails::DataType; executeInTransaction("CollectionView::assignCollectionToNode", [&]() { m_dataStore->assignCollectionToNode( this, @@ -273,35 +284,14 @@ void CollectionView::assignCollectionToNode(const QString &collectionName, const // Create and assign a delegate to the list view item if (node.metaInfo().isQtQuickListView()) { - CollectionDetails collection = m_widget->collectionDetailsModel()->upToDateConstCollection( - {dataStoreNode(), collectionName}); - - ModelNode rowItem(createModelNode("QtQuick.Row")); - ::setVariantPropertyValue(rowItem, "spacing", 5); - - const int columnsCount = collection.columns(); - for (int column = 0; column < columnsCount; ++column) { - const DataType dataType = collection.typeAt(column); - const QString columnName = collection.propertyAt(column); - ModelNode cellItem; - if (dataType == DataType::Color) { - cellItem = createModelNode("QtQuick.Rectangle"); - ::setBindingPropertyExpression(cellItem, "color", columnName); - ::setVariantPropertyValue(cellItem, "height", 20); - } else { - cellItem = createModelNode("QtQuick.Text"); - ::setBindingPropertyExpression(cellItem, "text", columnName); - } - ::setVariantPropertyValue(cellItem, "width", 100); - rowItem.defaultNodeAbstractProperty().reparentHere(cellItem); - } - - NodeProperty delegateProperty = node.nodeProperty("delegate"); - // Remove the old model node if is available - if (delegateProperty.modelNode()) - delegateProperty.modelNode().destroy(); - - delegateProperty.setModelNode(rowItem); + ::setNodePropertyValue(node, "delegate", createListViewDelegate(collectionName)); + } else if (node.metaInfo().isQtQuickGridView()) { + QSize delegateSize; + ::setNodePropertyValue(node, + "delegate", + createGridViewDelegate(collectionName, delegateSize)); + ::setVariantPropertyValue(node, "cellWidth", delegateSize.width()); + ::setVariantPropertyValue(node, "cellHeight", delegateSize.height()); } }); } @@ -439,7 +429,7 @@ void CollectionView::onItemLibraryNodeCreated(const ModelNode &node) if (!m_widget) return; - if (node.metaInfo().isQtQuickListView()) { + if (node.metaInfo().isListOrGridView()) { addTask(QSharedPointer( new DropListViewTask(this, m_widget->listModel(), node))); } @@ -454,6 +444,101 @@ void CollectionView::addTask(QSharedPointer task) m_delayedTasks << task; } +ModelNode CollectionView::createListViewDelegate(const QString &collectionName) +{ + using DataType = CollectionDetails::DataType; + using namespace Qt::StringLiterals; + + CollectionDetails collection = m_widget->collectionDetailsModel()->upToDateConstCollection( + {dataStoreNode(), collectionName}); + + ModelNode rowItem(createModelNode("QtQuick.Row")); + ::setVariantPropertyValue(rowItem, "spacing", 5); + + const int columnsCount = collection.columns(); + for (int column = 0; column < columnsCount; ++column) { + const DataType dataType = collection.typeAt(column); + const QString columnName = collection.propertyAt(column); + ModelNode cellItem; + if (dataType == DataType::Color) { + cellItem = createModelNode("QtQuick.Rectangle"); + ::setBindingPropertyExpression(cellItem, "color", columnName); + ::setVariantPropertyValue(cellItem, "height", 20); + } else { + cellItem = createModelNode("QtQuick.Text"); + ::setBindingPropertyExpression(cellItem, "text", columnName); + ::setVariantPropertyValue(cellItem, "clip", true); + ::setBindingPropertyExpression(cellItem, "elide", "Text.ElideRight"_L1); + ::setVariantPropertyValue(cellItem, "leftPadding", 1); + ::setVariantPropertyValue(cellItem, "rightPadding", 1); + } + ::setVariantPropertyValue(cellItem, "width", 100); + rowItem.defaultNodeAbstractProperty().reparentHere(cellItem); + } + return rowItem; +} + +ModelNode CollectionView::createGridViewDelegate(const QString &collectionName, QSize &delegateSize) +{ + using DataType = CollectionDetails::DataType; + using namespace Qt::StringLiterals; + + CollectionDetails collection = m_widget->collectionDetailsModel()->upToDateConstCollection( + {dataStoreNode(), collectionName}); + + constexpr int spacing = 5; + int delegateWidth = 70; + int delegateHeight = 0; + + ModelNode rectItem(createModelNode("QtQuick.Rectangle")); + ::setVariantPropertyValue(rectItem, "clip", true); + ::setVariantPropertyValue(rectItem, "border.color", QColor(Qt::blue)); + ::setVariantPropertyValue(rectItem, "border.width", 1); + + ModelNode colItem(createModelNode("QtQuick.Column")); + ::setVariantPropertyValue(colItem, "spacing", spacing); + ::setVariantPropertyValue(colItem, "topPadding", spacing); + ::setBindingPropertyExpression(colItem, "anchors.fill", "parent"_L1); + + const int columnsCount = collection.columns(); + for (int column = 0; column < columnsCount; ++column) { + const DataType dataType = collection.typeAt(column); + const QString columnName = collection.propertyAt(column); + ModelNode cellItem; + if (dataType == DataType::Color) { + cellItem = createModelNode("QtQuick.Rectangle"); + ::setBindingPropertyExpression(cellItem, "color", columnName); + ::setVariantPropertyValue(cellItem, "width", 40); + ::setVariantPropertyValue(cellItem, "height", 40); + delegateHeight += 40; + } else { + cellItem = createModelNode("QtQuick.Text"); + ::setBindingPropertyExpression(cellItem, "width", "parent.width"_L1); + ::setVariantPropertyValue(cellItem, "height", 20); + ::setBindingPropertyExpression(cellItem, "text", columnName); + ::setVariantPropertyValue(cellItem, "clip", true); + ::setBindingPropertyExpression(cellItem, "elide", "Text.ElideRight"_L1); + ::setVariantPropertyValue(cellItem, "leftPadding", 1); + ::setVariantPropertyValue(cellItem, "rightPadding", 1); + ::setBindingPropertyExpression(cellItem, "horizontalAlignment", "Text.AlignHCenter"_L1); + delegateHeight += 20; + } + delegateHeight += spacing; + ::setBindingPropertyExpression(cellItem, + "anchors.horizontalCenter", + "parent.horizontalCenter"_L1); + colItem.defaultNodeAbstractProperty().reparentHere(cellItem); + } + + rectItem.defaultNodeAbstractProperty().reparentHere(colItem); + ::setVariantPropertyValue(rectItem, "width", delegateWidth); + ::setVariantPropertyValue(rectItem, "height", delegateHeight); + delegateSize.setWidth(delegateWidth); + delegateSize.setHeight(delegateHeight); + + return rectItem; +} + CollectionTask::CollectionTask(CollectionView *view, CollectionListModel *listModel) : m_collectionView(view) , m_listModel(listModel) diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionview.h b/src/plugins/qmldesigner/components/collectioneditor/collectionview.h index 3de3bd7ae6d..20cb045374d 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionview.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionview.h @@ -72,6 +72,8 @@ private: void ensureStudioModelImport(); void onItemLibraryNodeCreated(const ModelNode &node); void addTask(QSharedPointer task); + ModelNode createListViewDelegate(const QString &collectionName); + ModelNode createGridViewDelegate(const QString &collectionName, QSize &delegateSize); std::unique_ptr m_dataStore; Utils::UniqueObjectPtr m_widget; diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index a7060fcdc6c..1a1284f35ee 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -89,7 +89,7 @@ inline bool hasCollectionAsModel(const SelectionContext &selectionState) const ModelNode singleSelectedNode = selectionState.currentSingleSelectedNode(); - return singleSelectedNode.metaInfo().isQtQuickListView() + return singleSelectedNode.metaInfo().isListOrGridView() && singleSelectedNode.property("model").toBindingProperty().expression().startsWith( "DataStore."); } diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index 9c8e32002f6..fd3f2f9be8d 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -185,6 +185,7 @@ public: bool isQtQuick3DLight() const; bool isQtQuickListModel() const; bool isQtQuickListView() const; + bool isQtQuickGridView() const; bool isQtQuick3DMaterial() const; bool isQtQuick3DModel() const; bool isQtQuick3DNode() const; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 04c151444d5..502b2675ccc 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -3358,6 +3358,22 @@ bool NodeMetaInfo::isQtQuickListView() const } } +bool QmlDesigner::NodeMetaInfo::isQtQuickGridView() const +{ + if constexpr (useProjectStorage()) { + if (!isValid()) + return false; + + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"is QtQuick.GridView"_t, category(), keyValue("type id", m_typeId)}; + + using namespace Storage::Info; + return isBasedOnCommonType(m_projectStorage, m_typeId); + } else { + return isValid() && (isSubclassOf("QtQuick.GridView")); + } +} + bool NodeMetaInfo::isQtQuick3DInstanceList() const { if constexpr (useProjectStorage()) {