diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index 5de0f253481..d64005d1f64 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -249,7 +249,8 @@ Window { acceptedButtons: Qt.LeftButton onClicked: { var pickResult = editView.pick(mouse.x, mouse.y); - handleObjectClicked(pickResult.objectHit, mouse.modifiers & Qt.ControlModifier); + handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), + mouse.modifiers & Qt.ControlModifier); if (!pickResult.objectHit) mouse.accepted = false; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp index b104d53a8fe..150b8e9ab19 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp @@ -204,6 +204,20 @@ void GeneralHelper::delayedPropertySet(QObject *obj, int delay, const QString &p }); } +QQuick3DNode *GeneralHelper::resolvePick(QQuick3DNode *pickNode) +{ + if (pickNode) { + // Check if the picked node actually specifies another node as the pick target + QVariant componentVar = pickNode->property("_pickTarget"); + if (componentVar.isValid()) { + auto componentNode = componentVar.value(); + if (componentNode) + return componentNode; + } + } + return pickNode; +} + } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h index 47449351900..890b824aa69 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h @@ -67,6 +67,8 @@ public: float oldZoom, bool updateZoom = true); Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property, const QVariant& value); + Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode); + signals: void overlayUpdateNeeded(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp index f35d1659311..4c725749e2e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp @@ -37,6 +37,7 @@ #ifdef QUICK3D_MODULE #include +#include #include #endif @@ -73,7 +74,7 @@ QQuick3DNode *Quick3DNodeInstance::quick3DNode() const #endif } -void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyToChildren) +void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyToChildInstances) { #ifdef QUICK3D_MODULE auto node = quick3DNode(); @@ -90,22 +91,42 @@ void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyT } if (!parentHidden) { - if (applyToChildren) { - auto getQuick3DInstance = [this](QQuick3DObject *obj) -> Quick3DNodeInstance * { - if (nodeInstanceServer()->hasInstanceForObject(obj)) { - ServerNodeInstance instance = nodeInstanceServer()->instanceForObject(obj); - if (instance.isValid() && qobject_cast(instance.internalObject())) - return static_cast(instance.internalInstance().data()); - } - return nullptr; - }; - const auto childItems = node->childItems(); - for (auto childItem : childItems) { - if (auto quick3dInstance = getQuick3DInstance(childItem)) { + auto getQuick3DInstance = [this](QQuick3DObject *obj) -> Quick3DNodeInstance * { + if (nodeInstanceServer()->hasInstanceForObject(obj)) { + ServerNodeInstance instance = nodeInstanceServer()->instanceForObject(obj); + if (instance.isValid() && qobject_cast(instance.internalObject())) + return static_cast(instance.internalInstance().data()); + } + return nullptr; + }; + const auto childItems = node->childItems(); + for (auto childItem : childItems) { + if (auto quick3dInstance = getQuick3DInstance(childItem)) { + if (applyToChildInstances) { // Don't override explicit block in children if (!QQuick3DNodePrivate::get(quick3dInstance->quick3DNode())->m_isHiddenInEditor) quick3dInstance->setPickable(enable, false, true); } + } else { + // Children of components do not have instances, but will still need to be + // pickable. These need to be set even if applyToChildInstances is false. + std::function checkChildren; + checkChildren = [&](QQuick3DNode *checkNode) { + const auto childItems = checkNode->childItems(); + for (auto child : childItems) { + if (auto childNode = qobject_cast(child)) + checkChildren(childNode); + } + if (auto checkModel = qobject_cast(checkNode)) { + QVariant value; + if (enable) + value = QVariant::fromValue(node); + // Specify the actual pick target with dynamic property + checkModel->setProperty("_pickTarget", value); + checkModel->setPickable(enable); + } + }; + checkChildren(node); } } if (nodeType == QQuick3DObject::Model) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h index 27e2488eb3f..7b48ea9193f 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h @@ -53,7 +53,7 @@ protected: private: Qt5NodeInstanceServer *qt5NodeInstanceServer() const; QQuick3DNode *quick3DNode() const; - void setPickable(bool enable, bool checkParent, bool applyToChildren); + void setPickable(bool enable, bool checkParent, bool applyToChildInstances); }; } // namespace Internal