From 1d71e6ac17af40a20b1ef3f616b2ae9858ed0eab Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 10 Feb 2020 15:32:57 +0200 Subject: [PATCH] QmlDesigner: Store tool state on per-scene basis Tool state of the scene is linked to qml id of the scene root, so that tool states are preserved through delete and undo, which causes generation of new internal ids for instances. Tool state storage doesn't currently survive changing of scene root qml id, as tracking that isn't trivial. It's not enough to simply track id change commands because model repurposes existing nodes when major graph changes occur, causing unexpected id changes e.g. when delete/undo is done. Change-Id: I74d11ce47e86ce5d29796399c4a91b65980b1597 Fixes: QDS-1536 Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../qmlpuppet/commands/createscenecommand.cpp | 4 +- .../qmlpuppet/commands/createscenecommand.h | 6 +- .../nodeinstanceserverinterface.cpp | 3 - .../mockfiles/EditCameraController.qml | 31 ++++-- .../qml/qmlpuppet/mockfiles/EditView3D.qml | 51 +++++++-- .../qml/qmlpuppet/mockfiles/ToolBarButton.qml | 3 +- .../qml2puppet/editor3d/generalhelper.cpp | 102 +++++++++++------- .../qml2puppet/editor3d/generalhelper.h | 14 +-- .../qt5informationnodeinstanceserver.cpp | 57 ++++++---- .../qt5informationnodeinstanceserver.h | 7 +- .../designercore/include/nodeinstanceview.h | 2 +- .../instances/nodeinstanceview.cpp | 7 +- 12 files changed, 188 insertions(+), 99 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.cpp index d35b98ca5d1..0c69dc0aa4b 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.cpp @@ -40,7 +40,7 @@ CreateSceneCommand::CreateSceneCommand(const QVector &instanc const QVector &importVector, const QVector &mockupTypeVector, const QUrl &fileUrl, - const QVariantMap &edit3dToolStates) + const QHash &edit3dToolStates) : m_instanceVector(instanceContainer), m_reparentInstanceVector(reparentContainer), m_idVector(idVector), @@ -99,7 +99,7 @@ QUrl CreateSceneCommand::fileUrl() const return m_fileUrl; } -QVariantMap CreateSceneCommand::edit3dToolStates() const +QHash CreateSceneCommand::edit3dToolStates() const { return m_edit3dToolStates; } diff --git a/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.h b/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.h index 0e8ec629b57..fbfd2d2d5f9 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/createscenecommand.h @@ -54,7 +54,7 @@ public: const QVector &importVector, const QVector &mockupTypeVector, const QUrl &fileUrl, - const QVariantMap &edit3dToolStates); + const QHash &edit3dToolStates); QVector instances() const; QVector reparentInstances() const; @@ -65,7 +65,7 @@ public: QVector imports() const; QVector mockupTypes() const; QUrl fileUrl() const; - QVariantMap edit3dToolStates() const; + QHash edit3dToolStates() const; private: QVector m_instanceVector; @@ -77,7 +77,7 @@ private: QVector m_importVector; QVector m_mockupTypeVector; QUrl m_fileUrl; - QVariantMap m_edit3dToolStates; + QHash m_edit3dToolStates; }; QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command); diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp index 914c996ebc2..5c7c9d2953a 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp @@ -216,9 +216,6 @@ void NodeInstanceServerInterface::registerCommands() qRegisterMetaType>("QPairIntInt"); qRegisterMetaTypeStreamOperators>("QPairIntInt"); - - qRegisterMetaType>("QPairStringVariant"); - qRegisterMetaTypeStreamOperators>("QPairStringVariant"); } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml index 2edeeab21fb..f6bd540fe57 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml @@ -31,7 +31,7 @@ Item { property Camera camera: null property View3D view3d: null - + property string sceneId property vector3d _lookAtPoint property vector3d _pressPoint property vector3d _prevPoint @@ -42,10 +42,13 @@ Item { property bool _dragging property int _button property real _zoomFactor: 1 - property real _defaultCameraLookAtDistance: 0 property Camera _prevCamera: null + readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, -600) + readonly property vector3d _defaultCameraRotation: Qt.vector3d(45, 0, 0) + readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() - function restoreCameraState(cameraState) { + function restoreCameraState(cameraState) + { if (!camera) return; @@ -57,7 +60,21 @@ Item { _zoomFactor, false); } - function storeCameraState(delay) { + function restoreDefaultState() + { + if (!camera) + return; + + _lookAtPoint = Qt.vector3d(0, 0, 0); + _zoomFactor = 1; + camera.position = _defaultCameraPosition; + camera.rotation = _defaultCameraRotation; + _generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, + _zoomFactor, false); + } + + function storeCameraState(delay) + { if (!camera) return; @@ -66,7 +83,7 @@ Item { cameraState[1] = _zoomFactor; cameraState[2] = camera.position; cameraState[3] = camera.rotation; - _generalHelper.storeToolState("editCamState", cameraState, delay); + _generalHelper.storeToolState(sceneId, "editCamState", cameraState, delay); } @@ -92,10 +109,6 @@ Item { _lookAtPoint, _zoomFactor, true); } - Component.onCompleted: { - cameraCtrl._defaultCameraLookAtDistance = Qt.vector3d(0, 600, -600).length(); - } - onCameraChanged: { if (camera && _prevCamera) { // Reset zoom on previous camera to ensure it's properties are good to copy to new cam diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index f57123d0dcd..4b90659e6e6 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -61,9 +61,9 @@ Window { signal commitObjectProperty(var object, var propName) signal changeObjectProperty(var object, var propName) - onUsePerspectiveChanged: _generalHelper.storeToolState("usePerspective", usePerspective) - onShowEditLightChanged: _generalHelper.storeToolState("showEditLight", showEditLight) - onGlobalOrientationChanged: _generalHelper.storeToolState("globalOrientation", globalOrientation) + onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective) + onShowEditLightChanged: _generalHelper.storeToolState(sceneId,"showEditLight", showEditLight) + onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) onActiveSceneChanged: { if (editView) { @@ -86,39 +86,57 @@ Window { editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;}); selectionBoxes.length = 0; + updateToolStates(); } } } // Disables edit view update if scene doesn't match current activeScene. // If it matches, updates are enabled. - function enableEditViewUpdate(scene) { + function enableEditViewUpdate(scene) + { if (editView) _generalHelper.enableItemUpdate(editView, (scene && scene === activeScene)); } - function updateToolStates(toolStates) { - // Init the stored state so we don't unnecessarily reflect changes back to creator - _generalHelper.initToolStates(toolStates); - _generalHelper.restoreWindowState(viewWindow, toolStates); + function restoreWindowState() + { + // It is expected that tool states have been initialized before calling this + _generalHelper.restoreWindowState(viewWindow); + } + function updateToolStates() + { + var toolStates = _generalHelper.getToolStates(sceneId); if ("showEditLight" in toolStates) showEditLight = toolStates.showEditLight; + else + showEditLight = false; if ("usePerspective" in toolStates) usePerspective = toolStates.usePerspective; + else + usePerspective = false; if ("globalOrientation" in toolStates) globalOrientation = toolStates.globalOrientation; + else + globalOrientation = false; var groupIndex; var group; var i; + btnSelectItem.selected = false; + btnSelectGroup.selected = true; if ("groupSelect" in toolStates) { groupIndex = toolStates.groupSelect; group = toolbarButtons.buttonGroups["groupSelect"]; for (i = 0; i < group.length; ++i) group[i].selected = (i === groupIndex); } + + btnRotate.selected = false; + btnScale.selected = false; + btnMove.selected = true; if ("groupTransform" in toolStates) { groupIndex = toolStates.groupTransform; group = toolbarButtons.buttonGroups["groupTransform"]; @@ -128,9 +146,12 @@ Window { if ("editCamState" in toolStates) cameraControl.restoreCameraState(toolStates.editCamState); + else + cameraControl.restoreDefaultState(); } - function ensureSelectionBoxes(count) { + function ensureSelectionBoxes(count) + { var needMore = count - selectionBoxes.length if (needMore > 0) { var component = Qt.createComponent("SelectionBox.qml"); @@ -149,7 +170,8 @@ Window { } } - function selectObjects(objects) { + function selectObjects(objects) + { // Create selection boxes as necessary. One more box than is actually needed is created, so // that we always have a previously created box to use for new selection. // This fixes an occasional visual glitch when creating a new box. @@ -168,7 +190,8 @@ Window { selectedNode = objects[0]; } - function handleObjectClicked(object, multi) { + function handleObjectClicked(object, multi) + { var theObject = object; if (btnSelectGroup.selected) { while (theObject && theObject !== activeScene && theObject.parent !== activeScene) @@ -511,6 +534,7 @@ Window { camera: viewWindow.editView ? viewWindow.editView.camera : null anchors.fill: parent view3d: viewWindow.editView + sceneId: viewWindow.sceneId } } @@ -540,6 +564,7 @@ Window { currentShortcut: selected ? "" : shortcut tool: "item_selection" buttonGroup: "groupSelect" + sceneId: viewWindow.sceneId } ToolBarButton { @@ -549,6 +574,7 @@ Window { currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut tool: "group_selection" buttonGroup: "groupSelect" + sceneId: viewWindow.sceneId } Rectangle { // separator @@ -566,6 +592,7 @@ Window { currentShortcut: shortcut tool: "move" buttonGroup: "groupTransform" + sceneId: viewWindow.sceneId } ToolBarButton { @@ -575,6 +602,7 @@ Window { currentShortcut: shortcut tool: "rotate" buttonGroup: "groupTransform" + sceneId: viewWindow.sceneId } ToolBarButton { @@ -584,6 +612,7 @@ Window { currentShortcut: shortcut tool: "scale" buttonGroup: "groupTransform" + sceneId: viewWindow.sceneId } Rectangle { // separator diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml index 924a7d25bda..f3f69cdb0e8 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml @@ -35,6 +35,7 @@ Rectangle { property string tool property string buttonGroup property bool togglable: true + property string sceneId property int _buttonGroupIndex: -1 property var _buttonGroupArray: [] @@ -89,7 +90,7 @@ Rectangle { root.selected = true; if (_buttonGroupIndex >= 0) - _generalHelper.storeToolState(root.buttonGroup, root._buttonGroupIndex) + _generalHelper.storeToolState(sceneId, root.buttonGroup, root._buttonGroupIndex) if (!root.togglable) { // Deselect button after a short while (selection acts as simple click indicator) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp index 4d175d8569f..7c33ab2b8e4 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp @@ -48,6 +48,8 @@ namespace QmlDesigner { namespace Internal { +const QString globalStateId = QStringLiteral("@GTS"); // global tool state + GeneralHelper::GeneralHelper() : QObject() { @@ -228,10 +230,13 @@ QQuick3DNode *GeneralHelper::resolvePick(QQuick3DNode *pickNode) return pickNode; } -void GeneralHelper::storeToolState(const QString &tool, const QVariant &state, int delay) +void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool, const QVariant &state, + int delay) { if (delay > 0) { - m_toolStatesPending.insert(tool, state); + QVariantMap sceneToolState; + sceneToolState.insert(tool, state); + m_toolStatesPending.insert(sceneId, sceneToolState); m_toolStateUpdateTimer.start(delay); } else { if (m_toolStateUpdateTimer.isActive()) @@ -242,16 +247,17 @@ void GeneralHelper::storeToolState(const QString &tool, const QVariant &state, i theState = state.value(); else theState = state; - if (m_toolStates[tool] != theState) { - m_toolStates.insert(tool, theState); - emit toolStateChanged(tool, theState); + QVariantMap &sceneToolState = m_toolStates[sceneId]; + if (sceneToolState[tool] != theState) { + sceneToolState.insert(tool, theState); + emit toolStateChanged(sceneId, tool, theState); } } } -void GeneralHelper::initToolStates(const QVariantMap &toolStates) +void GeneralHelper::initToolStates(const QString &sceneId, const QVariantMap &toolStates) { - m_toolStates = toolStates; + m_toolStates[sceneId] = toolStates; } void GeneralHelper::storeWindowState(QQuickWindow *w) @@ -262,42 +268,45 @@ void GeneralHelper::storeWindowState(QQuickWindow *w) windowState.insert("maximized", maximized); windowState.insert("geometry", geometry); - storeToolState("windowState", windowState, 500); + storeToolState(globalStateId, "windowState", windowState, 500); } -void GeneralHelper::restoreWindowState(QQuickWindow *w, const QVariantMap &toolStates) +void GeneralHelper::restoreWindowState(QQuickWindow *w) { - const QString stateKey = QStringLiteral("windowState"); - if (toolStates.contains(stateKey)) { - QVariantMap windowState = toolStates[stateKey].value(); + if (m_toolStates.contains(globalStateId)) { + const QVariantMap &globalStateMap = m_toolStates[globalStateId]; + const QString stateKey = QStringLiteral("windowState"); + if (globalStateMap.contains(stateKey)) { + QVariantMap windowState = globalStateMap[stateKey].value(); - doRestoreWindowState(w, windowState); - - // If the mouse cursor at puppet launch time is in a different screen than the one where the - // view geometry was saved on, the initial position and size can be incorrect, but if - // we reset the geometry again asynchronously, it should end up with correct geometry. - QTimer::singleShot(0, [this, w, windowState]() { doRestoreWindowState(w, windowState); - QTimer::singleShot(0, [w]() { - // Make sure that the window is at least partially visible on the screen - QRect geo = w->geometry(); - QRect sRect = w->screen()->geometry(); - if (geo.left() > sRect.right() - 150) - geo.moveRight(sRect.right()); - if (geo.right() < sRect.left() + 150) - geo.moveLeft(sRect.left()); - if (geo.top() > sRect.bottom() - 150) - geo.moveBottom(sRect.bottom()); - if (geo.bottom() < sRect.top() + 150) - geo.moveTop(sRect.top()); - if (geo.width() > sRect.width()) - geo.setWidth(sRect.width()); - if (geo.height() > sRect.height()) - geo.setHeight(sRect.height()); - w->setGeometry(geo); + // If the mouse cursor at puppet launch time is in a different screen than the one where the + // view geometry was saved on, the initial position and size can be incorrect, but if + // we reset the geometry again asynchronously, it should end up with correct geometry. + QTimer::singleShot(0, [this, w, windowState]() { + doRestoreWindowState(w, windowState); + + QTimer::singleShot(0, [w]() { + // Make sure that the window is at least partially visible on the screen + QRect geo = w->geometry(); + QRect sRect = w->screen()->geometry(); + if (geo.left() > sRect.right() - 150) + geo.moveRight(sRect.right()); + if (geo.right() < sRect.left() + 150) + geo.moveLeft(sRect.left()); + if (geo.top() > sRect.bottom() - 150) + geo.moveBottom(sRect.bottom()); + if (geo.bottom() < sRect.top() + 150) + geo.moveTop(sRect.top()); + if (geo.width() > sRect.width()) + geo.setWidth(sRect.width()); + if (geo.height() > sRect.height()) + geo.setHeight(sRect.height()); + w->setGeometry(geo); + }); }); - }); + } } } @@ -307,6 +316,14 @@ void GeneralHelper::enableItemUpdate(QQuickItem *item, bool enable) item->setFlag(QQuickItem::ItemHasContents, enable); } +QVariantMap GeneralHelper::getToolStates(const QString &sceneId) +{ + handlePendingToolStateUpdate(); + if (m_toolStates.contains(sceneId)) + return m_toolStates[sceneId]; + return {}; +} + void GeneralHelper::doRestoreWindowState(QQuickWindow *w, const QVariantMap &windowState) { const QString geoKey = QStringLiteral("geometry"); @@ -336,10 +353,15 @@ bool GeneralHelper::isMacOS() const void GeneralHelper::handlePendingToolStateUpdate() { m_toolStateUpdateTimer.stop(); - auto it = m_toolStatesPending.constBegin(); - while (it != m_toolStatesPending.constEnd()) { - storeToolState(it.key(), it.value()); - ++it; + auto sceneIt = m_toolStatesPending.constBegin(); + while (sceneIt != m_toolStatesPending.constEnd()) { + const QVariantMap &sceneToolState = sceneIt.value(); + auto toolIt = sceneToolState.constBegin(); + while (toolIt != sceneToolState.constEnd()) { + storeToolState(sceneIt.key(), toolIt.key(), toolIt.value()); + ++toolIt; + } + ++sceneIt; } m_toolStatesPending.clear(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h index 03a9eb3d371..a6b66907488 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h @@ -71,17 +71,19 @@ public: Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property, const QVariant& value); Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode); - Q_INVOKABLE void storeToolState(const QString &tool, const QVariant &state, int delayEmit = 0); - Q_INVOKABLE void initToolStates(const QVariantMap &toolStates); + Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool, + const QVariant &state, int delayEmit = 0); + void initToolStates(const QString &sceneId, const QVariantMap &toolStates); Q_INVOKABLE void storeWindowState(QQuickWindow *w); - Q_INVOKABLE void restoreWindowState(QQuickWindow *w, const QVariantMap &toolStates); + void restoreWindowState(QQuickWindow *w); Q_INVOKABLE void enableItemUpdate(QQuickItem *item, bool enable); + Q_INVOKABLE QVariantMap getToolStates(const QString &sceneId); bool isMacOS() const; signals: void overlayUpdateNeeded(); - void toolStateChanged(const QString &tool, const QVariant &toolState); + void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); private slots: void doRestoreWindowState(QQuickWindow *w, const QVariantMap &windowState); @@ -91,8 +93,8 @@ private: QTimer m_overlayUpdateTimer; QTimer m_toolStateUpdateTimer; - QVariantMap m_toolStates; - QVariantMap m_toolStatesPending; + QHash m_toolStates; + QHash m_toolStatesPending; }; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 08cd930a575..4af404869ad 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -110,14 +110,8 @@ bool Qt5InformationNodeInstanceServer::eventFilter(QObject *, QEvent *event) QDropEvent *dropEvent = static_cast(event); QByteArray data = dropEvent->mimeData()->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo")); if (!data.isEmpty()) { - ServerNodeInstance sceneInstance; - if (hasInstanceForObject(m_active3DScene)) - sceneInstance = instanceForObject(m_active3DScene); - else if (hasInstanceForObject(m_active3DView)) - sceneInstance = instanceForObject(m_active3DView); - nodeInstanceClient()->library3DItemDropped(createDrop3DLibraryItemCommand( - data, sceneInstance.instanceId())); + data, active3DSceneInstance().instanceId())); } } break; @@ -178,6 +172,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine) QObject::connect(helper, &QmlDesigner::Internal::GeneralHelper::toolStateChanged, this, &Qt5InformationNodeInstanceServer::handleToolStateChanged); engine->rootContext()->setContextProperty("_generalHelper", helper); + m_3dHelper = helper; qmlRegisterType("MouseArea3D", 1, 0, "MouseArea3D"); qmlRegisterType("CameraGeometry", 1, 0, "CameraGeometry"); qmlRegisterType("GridGeometry", 1, 0, "GridGeometry"); @@ -326,10 +321,14 @@ void Qt5InformationNodeInstanceServer::handleObjectPropertyChange(const QVariant m_changedProperty = propertyName; } -void Qt5InformationNodeInstanceServer::handleToolStateChanged(const QString &tool, +void Qt5InformationNodeInstanceServer::handleToolStateChanged(const QString &sceneId, + const QString &tool, const QVariant &toolState) { - QPair data = {tool, toolState}; + QVariantList data; + data << sceneId; + data << tool; + data << toolState; nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::Edit3DToolState, QVariant::fromValue(data)}); } @@ -385,17 +384,17 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D() QMetaObject::invokeMethod(m_editView3D, "enableEditViewUpdate", Q_ARG(QVariant, activeSceneVar)); + ServerNodeInstance sceneInstance = active3DSceneInstance(); + QVariant sceneInstanceVar; + QQmlProperty sceneIdProperty(m_editView3D, "sceneId", context()); + if (sceneInstance.isValid()) + sceneInstanceVar = QVariant::fromValue(sceneInstance.id()); + sceneIdProperty.write(sceneInstanceVar); + QQmlProperty sceneProperty(m_editView3D, "activeScene", context()); sceneProperty.write(activeSceneVar); - QString sceneId; - if (hasInstanceForObject(m_active3DScene)) - sceneId = instanceForObject(m_active3DScene).id(); - if (m_active3DView && sceneId.isEmpty() && hasInstanceForObject(m_active3DView)) - sceneId = instanceForObject(m_active3DView).id(); updateView3DRect(m_active3DView); - QQmlProperty viewIdProperty(m_editView3D, "sceneId", context()); - viewIdProperty.write(QVariant::fromValue(sceneId)); } void Qt5InformationNodeInstanceServer::removeNode3D(QObject *node) @@ -454,6 +453,16 @@ void Qt5InformationNodeInstanceServer::resolveSceneRoots() #endif } +ServerNodeInstance Qt5InformationNodeInstanceServer::active3DSceneInstance() const +{ + ServerNodeInstance sceneInstance; + if (hasInstanceForObject(m_active3DScene)) + sceneInstance = instanceForObject(m_active3DScene); + else if (hasInstanceForObject(m_active3DView)) + sceneInstance = instanceForObject(m_active3DView); + return sceneInstance; +} + Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5NodeInstanceServer(nodeInstanceClient) { @@ -756,8 +765,9 @@ QObject *Qt5InformationNodeInstanceServer::find3DSceneRoot(QObject *obj) const } void Qt5InformationNodeInstanceServer::setup3DEditView(const QList &instanceList, - const QVariantMap &toolStates) + const QHash &toolStates) { +#ifdef QUICK3D_MODULE ServerNodeInstance root = rootNodeInstance(); add3DViewPorts(instanceList); @@ -776,12 +786,21 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList(m_3dHelper); + if (helper) { + auto it = toolStates.constBegin(); + while (it != toolStates.constEnd()) { + helper->initToolStates(it.key(), it.value()); + ++it; + } + helper->restoreWindowState(qobject_cast(m_editView3D)); + } + updateActiveSceneToEditView3D(); createCameraAndLightGizmos(instanceList); - - QMetaObject::invokeMethod(m_editView3D, "updateToolStates", Q_ARG(QVariant, toolStates)); } +#endif } void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index f37485c4b47..12b2f12821a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -62,7 +62,8 @@ private slots: void handleSelectionChanged(const QVariant &objs); void handleObjectPropertyCommit(const QVariant &object, const QVariant &propName); void handleObjectPropertyChange(const QVariant &object, const QVariant &propName); - void handleToolStateChanged(const QString &tool, const QVariant &toolState); + void handleToolStateChanged(const QString &sceneId, const QString &tool, + const QVariant &toolState); void handleView3DSizeChange(); void handleView3DDestroyed(QObject *obj); void handleNode3DDestroyed(QObject *obj); @@ -83,7 +84,7 @@ private: void handleSelectionChangeTimeout(); QObject *createEditView3D(QQmlEngine *engine); void setup3DEditView(const QList &instanceList, - const QVariantMap &toolStates); + const QHash &toolStates); void createCameraAndLightGizmos(const QList &instanceList) const; void add3DViewPorts(const QList &instanceList); void add3DScenes(const QList &instanceList); @@ -102,6 +103,7 @@ private: void updateActiveSceneToEditView3D(); void removeNode3D(QObject *node); void resolveSceneRoots(); + ServerNodeInstance active3DSceneInstance() const; QObject *m_editView3D = nullptr; QSet m_view3Ds; @@ -116,6 +118,7 @@ private: QVariant m_changedNode; PropertyName m_changedProperty; ChangeSelectionCommand m_pendingSelectionChangeCommand; + QObject *m_3dHelper = nullptr; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index cb2962b3457..33c436aa100 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -211,7 +211,7 @@ private: // functions ProjectExplorer::Target *m_currentTarget = nullptr; int m_restartProcessTimerId; RewriterTransaction m_puppetTransaction; - QVariantMap m_edit3DToolStates; + QHash m_edit3DToolStates; // Key: instance qml id, value: related tool states }; } // namespace ProxyNodeInstanceView diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 49832c1622e..a7cf6a64e14 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -1464,8 +1464,11 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand handlePuppetKeyPress(key, modifiers); } else if (command.type() == PuppetToCreatorCommand::Edit3DToolState) { if (!m_nodeInstanceServer.isNull()) { - auto data = qvariant_cast>(command.data()); - m_edit3DToolStates[data.first] = data.second; + auto data = qvariant_cast(command.data()); + if (data.size() == 3) { + QString qmlId = data[0].toString(); + m_edit3DToolStates[qmlId].insert(data[1].toString(), data[2]); + } } } }