From 5a8b389ddd3f18605469bad10cd429d89758a1c2 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Thu, 18 Apr 2024 11:49:03 +0300 Subject: [PATCH] QmlDesigner: Create and assign a model to the dropped GridView The delegate for GridView is different from ListView. Also cellWidth and cellHeight should be specified for the GridView Also the delegate for the listView is modified to clip and elide the text. Task-number: QDS-12306 Fixes: QDS-12386 Change-Id: I7e75b9e7f234c5e021637e703088539886a8f25f Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../collectioneditor/collectionview.cpp | 147 ++++++++++++++---- .../collectioneditor/collectionview.h | 2 + .../modelnodecontextmenu_helper.h | 2 +- .../designercore/include/nodemetainfo.h | 1 + .../designercore/metainfo/nodemetainfo.cpp | 16 ++ 5 files changed, 136 insertions(+), 32 deletions(-) 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()) {