QmlDesigner: Fix picking issues

We now check also the parent chain for pickability, because
a node is not pickable if one of the ancestors is not pickable,
as all properties picking depends on (visibility, locked state)
are implicitly inherited by descendants.

Rotate gizmo rings default to regular View3D picking when the angle
is so steep that the plane intersection is not reliable. With new
global picking enabled handling we need to check all hits instead
of just the first one.

Change-Id: Ib1aa604b06f7db1041f5d4c3019cc2badf29a20f
Fixes: QDS-5679
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2021-12-03 16:30:35 +02:00
parent 9b4e68dd84
commit eba2a0520b
3 changed files with 27 additions and 9 deletions
@@ -337,7 +337,7 @@ void GeneralHelper::unregisterGizmoTarget(QQuick3DNode *node)
}
}
bool GeneralHelper::isLocked(QQuick3DNode *node)
bool GeneralHelper::isLocked(QQuick3DNode *node) const
{
if (node) {
QVariant lockValue = node->property("_edit3dLocked");
@@ -346,7 +346,7 @@ bool GeneralHelper::isLocked(QQuick3DNode *node)
return false;
}
bool GeneralHelper::isHidden(QQuick3DNode *node)
bool GeneralHelper::isHidden(QQuick3DNode *node) const
{
if (node) {
QVariant hideValue = node->property("_edit3dHidden");
@@ -355,8 +355,18 @@ bool GeneralHelper::isHidden(QQuick3DNode *node)
return false;
}
bool GeneralHelper::isPickable(QQuick3DNode *node) {
return (node && !isLocked(node) && !isHidden(node) && node->visible());
bool GeneralHelper::isPickable(QQuick3DNode *node) const
{
if (!node)
return false;
QQuick3DNode *n = node;
while (n) {
if (!n->visible() || isLocked(n) || isHidden(n))
return false;
n = n->parentNode();
}
return true;
}
void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool, const QVariant &state,
@@ -80,9 +80,9 @@ public:
Q_INVOKABLE void registerGizmoTarget(QQuick3DNode *node);
Q_INVOKABLE void unregisterGizmoTarget(QQuick3DNode *node);
Q_INVOKABLE bool isLocked(QQuick3DNode *node);
Q_INVOKABLE bool isHidden(QQuick3DNode *node);
Q_INVOKABLE bool isPickable(QQuick3DNode *node);
Q_INVOKABLE bool isLocked(QQuick3DNode *node) const;
Q_INVOKABLE bool isHidden(QQuick3DNode *node) const;
Q_INVOKABLE bool isPickable(QQuick3DNode *node) const;
Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool,
const QVariant &state, int delayEmit = 0);
@@ -898,8 +898,16 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
// a problem
onCircle = false;
if (m_pickNode) {
QQuick3DPickResult pr = m_view3D->pick(float(mousePos.x()), float(mousePos.y()));
pickSuccess = pr.objectHit() == m_pickNode;
// We need to pick all as various other geometries can often be the first
// pick result, such as camera frustum or light geometry
const QList<QQuick3DPickResult> results = m_view3D->pickAll(float(mousePos.x()),
float(mousePos.y()));
for (const auto &pr : results) {
if (pr.objectHit() == m_pickNode) {
pickSuccess = true;
break;
}
}
}
}
}