diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-09-24 15:49:49 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-10-05 09:10:16 +0000 |
commit | e0611c0cfafe850f206f67fd919938531a7af97c (patch) | |
tree | 30337755189f88a36b577531184e77c74ebd565a | |
parent | 9e5744b1f37156f791b229d1b9d9b0882b90cd90 (diff) | |
download | qt-creator-e0611c0cfafe850f206f67fd919938531a7af97c.tar.gz |
QmlDesigner: Add support for Component type
Component type is added to Component Library and can be dragged to
the scene. Items under the component are not shown in the scene.
Fixes: QDS-5093
Change-Id: I0c80647e73124866a8b772022a761ca6cbb545a1
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
9 files changed, 71 insertions, 41 deletions
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index d63ae11611..3ce402589c 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -617,7 +617,6 @@ class UnsupportedTypesByQmlUi : public QStringList { public: UnsupportedTypesByQmlUi() : QStringList({"ShaderEffect", - "Component", "Drawer"}) { append(UnsupportedTypesByVisualDesigner()); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index 8200558d18..4f000e1295 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -99,8 +99,7 @@ FormEditorItem::FormEditorItem(const QmlItemNode &qmlItemNode, FormEditorScene* m_borderWidth(1.0), m_highlightBoundingRect(false), m_blurContent(false), - m_isContentVisible(true), - m_isFormEditorVisible(true) + m_isContentVisible(true) { setCacheMode(QGraphicsItem::NoCache); setup(); @@ -208,17 +207,6 @@ bool FormEditorItem::isContentVisible() const return m_isContentVisible; } - -bool FormEditorItem::isFormEditorVisible() const -{ - return m_isFormEditorVisible; -} -void FormEditorItem::setFormEditorVisible(bool isVisible) -{ - m_isFormEditorVisible = isVisible; - setVisible(isVisible); -} - QPointF FormEditorItem::center() const { return mapToScene(qmlItemNode().instanceBoundingRect().center()); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h index 769488aa4a..2213f42a66 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h @@ -104,9 +104,6 @@ public: void setContentVisible(bool visible); bool isContentVisible() const; - bool isFormEditorVisible() const; - void setFormEditorVisible(bool isVisible); - QPointF center() const; qreal selectionWeigth(const QPointF &point, int iteration); @@ -152,7 +149,6 @@ private: // variables bool m_highlightBoundingRect; bool m_blurContent; bool m_isContentVisible; - bool m_isFormEditorVisible; }; class FormEditorFlowItem : public FormEditorItem diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 0ee760b9a1..9a01bbd940 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -199,16 +199,6 @@ void FormEditorView::removeNodeFromScene(const QmlItemNode &qmlItemNode) m_currentTool->itemsAboutToRemoved(removedItemList); } -void FormEditorView::hideNodeFromScene(const QmlItemNode &qmlItemNode) -{ - if (FormEditorItem *item = m_scene->itemForQmlItemNode(qmlItemNode)) { - QList<FormEditorItem*> removedItems = scene()->itemsForQmlItemNodes(qmlItemNode.allSubModelNodes()); - removedItems.append(item); - m_currentTool->itemsAboutToRemoved(removedItems); - item->setFormEditorVisible(false); - } -} - void FormEditorView::createFormEditorWidget() { m_formEditorWidget = QPointer<FormEditorWidget>(new FormEditorWidget(this)); @@ -248,10 +238,7 @@ void FormEditorView::temporaryBlockView(int duration) void FormEditorView::nodeCreated(const ModelNode &node) { - //If the node has source for components/custom parsers we ignore it. - if (QmlItemNode::isValidQmlItemNode(node) && node.nodeSourceType() == ModelNode::NodeWithoutSource) //only setup QmlItems - setupFormEditorItemTree(QmlItemNode(node)); - else if (QmlVisualNode::isFlowTransition(node)) + if (QmlVisualNode::isFlowTransition(node)) setupFormEditorItemTree(QmlItemNode(node)); } @@ -349,8 +336,26 @@ static inline bool hasNodeSourceParent(const ModelNode &node) void FormEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) { - if (hasNodeSourceParent(node)) - hideNodeFromScene(node); + // If node is not connected to scene root, don't do anything yet to avoid duplicated effort, + // as any removal or addition will remove or add descendants as well. + if (!node.isInHierarchy()) + return; + + QmlItemNode itemNode(node); + if (hasNodeSourceParent(node)) { + if (FormEditorItem *item = m_scene->itemForQmlItemNode(itemNode)) { + QList<FormEditorItem *> removed = scene()->itemsForQmlItemNodes(itemNode.allSubModelNodes()); + removed.append(item); + m_currentTool->itemsAboutToRemoved(removed); + removeNodeFromScene(itemNode); + } + } else if (itemNode.isValid() && node.nodeSourceType() == ModelNode::NodeWithoutSource) { + if (!m_scene->itemForQmlItemNode(itemNode)) { + setupFormEditorItemTree(itemNode); + // Simulate selection change to refresh tools + selectedNodesChanged(selectedModelNodes(), {}); + } + } } WidgetInfo FormEditorView::widgetInfo() @@ -603,8 +608,7 @@ void FormEditorView::auxiliaryDataChanged(const ModelNode &node, const PropertyN if (name == "invisible") { if (FormEditorItem *item = scene()->itemForQmlItemNode(QmlItemNode(node))) { bool isInvisible = data.toBool(); - if (item->isFormEditorVisible()) - item->setVisible(!isInvisible); + item->setVisible(!isInvisible); ModelNode newNode(node); if (isInvisible) newNode.deselectNode(); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index ba2b79df99..04b7d1e83e 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -144,7 +144,6 @@ protected: private: void setupFormEditorItemTree(const QmlItemNode &qmlItemNode); void removeNodeFromScene(const QmlItemNode &qmlItemNode); - void hideNodeFromScene(const QmlItemNode &qmlItemNode); void createFormEditorWidget(); void temporaryBlockView(int duration = 1000); void resetNodeInstanceView(); diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp index 7230e97a1c..b6bf74e3d4 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp @@ -34,6 +34,8 @@ #include <nodemetainfo.h> +#include <utils/algorithm.h> + #include <QGraphicsSceneMouseEvent> #include <QDebug> @@ -242,9 +244,23 @@ void SelectionTool::dragMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGr { } -void SelectionTool::itemsAboutToRemoved(const QList<FormEditorItem*> &/*itemList*/) +void SelectionTool::itemsAboutToRemoved(const QList<FormEditorItem*> &itemList) { - + const QList<FormEditorItem *> current = items(); + + QList<FormEditorItem *> remaining = Utils::filtered(current, [&itemList](const FormEditorItem *item) { + return !itemList.contains(item); + }); + + if (!remaining.isEmpty()) { + m_selectionIndicator.setItems(remaining); + m_resizeIndicator.setItems(remaining); + m_rotationIndicator.setItems(remaining); + m_anchorIndicator.setItems(remaining); + m_bindingIndicator.setItems(remaining); + } else { + clear(); + } } void SelectionTool::clear() diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 5abc38eba6..7f8a75f1c4 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -1085,10 +1085,18 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper if (modelNode.isValid() && modelNode != parentProperty.parentModelNode() && !modelNode.isAncestorOf(parentProperty.parentModelNode()) - && (modelNode.metaInfo().isSubclassOf(propertyQmlType) || propertyQmlType == "alias")) { + && (modelNode.metaInfo().isSubclassOf(propertyQmlType) + || propertyQmlType == "alias" + || parentProperty.name() == "data")) { //### todo: allowing alias is just a heuristic //once the MetaInfo is part of instances we can do this right + // We assume above that "data" property in parent accepts all types. + // This is a workaround for Component parents to accept children, even though they + // do not have an actual "data" property or apparently any other default property. + // When the actual reparenting happens, model will create the "data" property if + // it is missing. + bool nodeCanBeMovedToParentProperty = removeModelNodeFromNodeProperty(parentProperty, modelNode); if (nodeCanBeMovedToParentProperty) { reparentModelNodeToNodeProperty(parentProperty, modelNode); diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp index 802740fc1d..544471b03c 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp @@ -309,7 +309,11 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view, } } - newQmlObjectNode = QmlObjectNode(view->createModelNode(itemLibraryEntry.typeName(), majorVersion, minorVersion, propertyPairList)); + ModelNode::NodeSourceType nodeSourceType = ModelNode::NodeWithoutSource; + if (itemLibraryEntry.typeName() == "QtQml.Component") + nodeSourceType = ModelNode::NodeWithComponentSource; + + newQmlObjectNode = QmlObjectNode(view->createModelNode(itemLibraryEntry.typeName(), majorVersion, minorVersion, propertyPairList, {}, {}, nodeSourceType)); } else { newQmlObjectNode = createQmlObjectNodeFromSource(view, itemLibraryEntry.qmlSource(), position); } diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index bbd91d40a8..877f120339 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -432,4 +432,20 @@ MetaInfo { } } + Type { + name: "QtQml.Component" + icon: ":/qtquickplugin/images/item-icon16.png" + + Hints { + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Component" + category: "e.Qt Quick - Component" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "2.0" + } + } } |