From 97a6d37ef39aba8ec42c3ca4a51942f53f14a970 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 10 Jan 2022 16:40:35 +0200 Subject: [PATCH] QmlDesigner: Support moving 3D edit camera with arrow keys 3D edit camera can now be moved up/down/left/right with arrow keys. Task-number: QDS-5790 Change-Id: I3b4a095b96bdaa9d00bf6b29b750af1f783b485e Reviewed-by: Mahmoud Badri --- .../qmlpuppet/commands/inputeventcommand.cpp | 16 +++++++++- .../qmlpuppet/commands/inputeventcommand.h | 14 ++++++++- .../mockfiles/qt5/EditCameraController.qml | 31 +++++++++++++++++++ .../qmlpuppet/mockfiles/qt5/EditView3D.qml | 1 + .../mockfiles/qt6/EditCameraController.qml | 31 +++++++++++++++++++ .../qmlpuppet/mockfiles/qt6/EditView3D.qml | 1 + .../qt5informationnodeinstanceserver.cpp | 4 +++ .../components/edit3d/edit3dcanvas.cpp | 12 +++++++ .../components/edit3d/edit3dcanvas.h | 2 ++ 9 files changed, 110 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.cpp index 4eb4f3380ab..9636048e3a5 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.cpp @@ -45,6 +45,11 @@ InputEventCommand::InputEventCommand(QInputEvent *e) #endif m_buttons = we->buttons(); m_angleDelta = we->angleDelta().y(); + } else if (m_type == QEvent::KeyPress || m_type == QEvent::KeyRelease) { + auto ke = static_cast(e); + m_key = ke->key(); + m_count = ke->count(); + m_autoRepeat = ke->isAutoRepeat(); } else { auto me = static_cast(e); m_pos = me->pos(); @@ -61,6 +66,9 @@ QDataStream &operator<<(QDataStream &out, const InputEventCommand &command) out << command.buttons(); out << command.modifiers(); out << command.angleDelta(); + out << command.key(); + out << command.count(); + out << command.autoRepeat(); return out; } @@ -77,6 +85,9 @@ QDataStream &operator>>(QDataStream &in, InputEventCommand &command) in >> command.m_buttons; in >> command.m_modifiers; in >> command.m_angleDelta; + in >> command.m_key; + in >> command.m_count; + in >> command.m_autoRepeat; return in; } @@ -89,7 +100,10 @@ QDebug operator <<(QDebug debug, const InputEventCommand &command) << "button: " << command.button() << ", " << "buttons: " << command.buttons() << ", " << "modifiers: " << command.modifiers() << ", " - << "angleDelta: " << command.angleDelta() << ")"; + << "angleDelta: " << command.angleDelta() << ", " + << "key: " << command.key() << ", " + << "count: " << command.count() << ", " + << "autoRepeat: " << command.autoRepeat() << ")"; } diff --git a/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.h b/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.h index fc484380a1e..c6b8a138107 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/inputeventcommand.h @@ -48,14 +48,26 @@ public: Qt::MouseButtons buttons() const { return m_buttons; } Qt::KeyboardModifiers modifiers() const { return m_modifiers; } int angleDelta() const { return m_angleDelta; } + int key() const { return m_key; } + int count() const { return m_count; } + bool autoRepeat() const { return m_autoRepeat; } private: QEvent::Type m_type = QEvent::None; + Qt::KeyboardModifiers m_modifiers = Qt::NoModifier; + + // Mouse events QPoint m_pos; Qt::MouseButton m_button = Qt::NoButton; Qt::MouseButtons m_buttons = Qt::NoButton; - Qt::KeyboardModifiers m_modifiers = Qt::NoModifier; + + // Wheel events int m_angleDelta = 0; + + // Key events + int m_key = 0; + int m_count = 1; + bool m_autoRepeat = false; }; QDataStream &operator<<(QDataStream &out, const InputEventCommand &command); diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditCameraController.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditCameraController.qml index f5a21dacb96..ca4a7c77c1c 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditCameraController.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditCameraController.qml @@ -46,6 +46,7 @@ Item { readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600) readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0) readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() + readonly property real _keyPanAmount: 5 property bool ignoreToolState: false function restoreCameraState(cameraState) @@ -188,4 +189,34 @@ Item { } } } + + Keys.onPressed: { + var pressPoint = Qt.vector3d(view3d.width / 2, view3d.height / 2, 0); + var currentPoint; + + switch (event.key) { + case Qt.Key_Left: + currentPoint = pressPoint.plus(Qt.vector3d(_keyPanAmount, 0, 0)); + break; + case Qt.Key_Right: + currentPoint = pressPoint.plus(Qt.vector3d(-_keyPanAmount, 0, 0)); + break; + case Qt.Key_Up: + currentPoint = pressPoint.plus(Qt.vector3d(0, _keyPanAmount, 0)); + break; + case Qt.Key_Down: + currentPoint = pressPoint.plus(Qt.vector3d(0, -_keyPanAmount, 0)); + break; + default: + break; + } + + if (currentPoint) { + _lookAtPoint = _generalHelper.panCamera( + camera, cameraCtrl.camera.sceneTransform, + cameraCtrl.camera.position, _lookAtPoint, + pressPoint, currentPoint, _zoomFactor); + event.accepted = true; + } + } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml index cda0808b734..2aabb4d1bbf 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml @@ -97,6 +97,7 @@ Item { editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;}); selectionBoxes.length = 0; + cameraControl.forceActiveFocus(); return true; } return false; diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditCameraController.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditCameraController.qml index bba05742315..145284f6e3c 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditCameraController.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditCameraController.qml @@ -46,6 +46,7 @@ Item { readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600) readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0) readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() + readonly property real _keyPanAmount: 5 property bool ignoreToolState: false function restoreCameraState(cameraState) @@ -188,4 +189,34 @@ Item { } } } + + Keys.onPressed: { + var pressPoint = Qt.vector3d(view3d.width / 2, view3d.height / 2, 0); + var currentPoint; + + switch (event.key) { + case Qt.Key_Left: + currentPoint = pressPoint.plus(Qt.vector3d(_keyPanAmount, 0, 0)); + break; + case Qt.Key_Right: + currentPoint = pressPoint.plus(Qt.vector3d(-_keyPanAmount, 0, 0)); + break; + case Qt.Key_Up: + currentPoint = pressPoint.plus(Qt.vector3d(0, _keyPanAmount, 0)); + break; + case Qt.Key_Down: + currentPoint = pressPoint.plus(Qt.vector3d(0, -_keyPanAmount, 0)); + break; + default: + break; + } + + if (currentPoint) { + _lookAtPoint = _generalHelper.panCamera( + camera, cameraCtrl.camera.sceneTransform, + cameraCtrl.camera.position, _lookAtPoint, + pressPoint, currentPoint, _zoomFactor); + event.accepted = true; + } + } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml index cd3ec158a4c..c9abab7ab72 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml @@ -98,6 +98,7 @@ Item { editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;}); selectionBoxes.length = 0; + cameraControl.forceActiveFocus(); return true; } return false; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 76b3475872f..a806db9bd36 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -262,6 +262,10 @@ void Qt5InformationNodeInstanceServer::handleInputEvents() #endif angleDelta = 0; QGuiApplication::sendEvent(m_editView3DData.window, we); + } else if (command.type() == QEvent::KeyPress || command.type() == QEvent::KeyRelease) { + QKeyEvent *ke = new QKeyEvent(command.type(), command.key(), command.modifiers(), + QString(), command.autoRepeat(), command.count()); + QGuiApplication::sendEvent(m_editView3DData.window, ke); } else { if (command.type() == QEvent::MouseMove && i < m_pendingInputEventCommands.size() - 1) { // Peek at next command. If that is also a move with only difference being diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp index bb04dea333f..7ea74f6cbee 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp @@ -88,6 +88,18 @@ void Edit3DCanvas::wheelEvent(QWheelEvent *e) QWidget::wheelEvent(e); } +void Edit3DCanvas::keyPressEvent(QKeyEvent *e) +{ + m_parent->view()->sendInputEvent(e); + QWidget::keyPressEvent(e); +} + +void Edit3DCanvas::keyReleaseEvent(QKeyEvent *e) +{ + m_parent->view()->sendInputEvent(e); + QWidget::keyReleaseEvent(e); +} + void Edit3DCanvas::paintEvent(QPaintEvent *e) { Q_UNUSED(e) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h index 140c23e89e2..b6f07683d7e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h @@ -54,6 +54,8 @@ protected: void mouseDoubleClickEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void wheelEvent(QWheelEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void keyReleaseEvent(QKeyEvent *e) override; void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; void dragEnterEvent(QDragEnterEvent *e) override;