QmlDesigner: Fix selection issues in navigator and 3d edit view

Fixed multiple issues with showing correct selection in navigator and
3d edit view:
- Dragging items from item library selects only that item,
  regardless if drag was done to 3d edit view or navigator
- Selection is shown correctly after reparenting items, including
  multiselection reparenting
- Adding a new item to the active scene now shows selection box
  correctly for that item

Change-Id: I5156ca4c22e606c41e1e346ea5c32c3d70d89f5e
Fixes: QDS-1577
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-03-17 17:08:58 +02:00
parent bcfaa8cd37
commit ff6dd4dc2e
6 changed files with 22 additions and 10 deletions

View File

@@ -35,6 +35,7 @@
#include <QtQuick3D/qquick3dobject.h> #include <QtQuick3D/qquick3dobject.h>
#include <QtQuick/qquickwindow.h> #include <QtQuick/qquickwindow.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtCore/qtimer.h>
#include <limits> #include <limits>
@@ -162,6 +163,12 @@ QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphOb
rootRN->localTransform = m; rootRN->localTransform = m;
rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty); rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
rootRN->calculateGlobalVariables(); rootRN->calculateGlobalVariables();
m_asyncUpdatePending = false;
} else if (!m_asyncUpdatePending) {
m_asyncUpdatePending = true;
// A necessary spatial node doesn't yet exist. Defer selection box creation one frame.
QTimer::singleShot(0, this, &SelectionBoxGeometry::update);
return node;
} }
getBounds(m_targetNode, vertexData, indexData, minBounds, maxBounds); getBounds(m_targetNode, vertexData, indexData, minBounds, maxBounds);
appendVertexData(QMatrix4x4(), vertexData, indexData, minBounds, maxBounds); appendVertexData(QMatrix4x4(), vertexData, indexData, minBounds, maxBounds);

View File

@@ -81,6 +81,7 @@ private:
bool m_isEmpty = true; bool m_isEmpty = true;
QVector<QMetaObject::Connection> m_connections; QVector<QMetaObject::Connection> m_connections;
QSSGBounds3 m_bounds; QSSGBounds3 m_bounds;
bool m_asyncUpdatePending = false;
}; };
} }

View File

@@ -925,7 +925,8 @@ void Qt5InformationNodeInstanceServer::reparentInstances(const ReparentInstances
if (m_editView3DRootItem) if (m_editView3DRootItem)
resolveSceneRoots(); resolveSceneRoots();
render3DEditView(); // Make sure selection is in sync after all reparentings are done
m_selectionChangeTimer.start(0);
} }
void Qt5InformationNodeInstanceServer::clearScene(const ClearSceneCommand &command) void Qt5InformationNodeInstanceServer::clearScene(const ClearSceneCommand &command)
@@ -1085,7 +1086,7 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
Q_ARG(QVariant, QVariant::fromValue(selectedObjs))); Q_ARG(QVariant, QVariant::fromValue(selectedObjs)));
} }
render3DEditView(); render3DEditView(2);
} }
void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)

View File

@@ -117,7 +117,10 @@ void Edit3DCanvas::dropEvent(QDropEvent *e)
{ {
Q_UNUSED(e) Q_UNUSED(e)
QmlVisualNode::createQml3DNode(m_parent->view(), m_itemLibraryEntry, m_activeScene); auto modelNode = QmlVisualNode::createQml3DNode(m_parent->view(), m_itemLibraryEntry, m_activeScene).modelNode();
if (modelNode.isValid())
m_parent->view()->setSelectedModelNode(modelNode);
} }
} }

View File

@@ -539,7 +539,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
} }
if (newQmlObjectNode.isValid()) if (newQmlObjectNode.isValid())
m_view->selectModelNode(newQmlObjectNode.modelNode()); m_view->setSelectedModelNode(newQmlObjectNode.modelNode());
} }
} }

View File

@@ -205,6 +205,9 @@ void NavigatorView::nodeReparented(const ModelNode &modelNode,
else else
m_currentModelInterface->notifyModelNodesMoved({modelNode}); m_currentModelInterface->notifyModelNodesMoved({modelNode});
treeWidget()->expand(indexForModelNode(modelNode)); treeWidget()->expand(indexForModelNode(modelNode));
// make sure selection is in sync again
QTimer::singleShot(0, this, &NavigatorView::updateItemSelection);
} }
void NavigatorView::nodeIdChanged(const ModelNode& modelNode, const QString & /*newId*/, const QString & /*oldId*/) void NavigatorView::nodeIdChanged(const ModelNode& modelNode, const QString & /*newId*/, const QString & /*oldId*/)
@@ -256,14 +259,10 @@ void NavigatorView::nodeOrderChanged(const NodeListProperty & listProperty,
const ModelNode & /*node*/, const ModelNode & /*node*/,
int /*oldIndex*/) int /*oldIndex*/)
{ {
bool blocked = blockSelectionChangedSignal(true);
m_currentModelInterface->notifyModelNodesMoved(listProperty.directSubNodes()); m_currentModelInterface->notifyModelNodesMoved(listProperty.directSubNodes());
// make sure selection is in sync again // make sure selection is in sync again
updateItemSelection(); QTimer::singleShot(0, this, &NavigatorView::updateItemSelection);
blockSelectionChangedSignal(blocked);
} }
void NavigatorView::changeToComponent(const QModelIndex &index) void NavigatorView::changeToComponent(const QModelIndex &index)
@@ -405,7 +404,8 @@ void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, con
void NavigatorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/) void NavigatorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/)
{ {
updateItemSelection(); // Update selection asynchronously to ensure NavigatorTreeModel's index cache is up to date
QTimer::singleShot(0, this, &NavigatorView::updateItemSelection);
} }
void NavigatorView::updateItemSelection() void NavigatorView::updateItemSelection()