From 837a91f920c9e3ec074ea980bd5501082169a2ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 8 Jul 2018 18:08:09 +0200 Subject: [PATCH] Add option to require double click to move --- src/res/qml/PlayspacePage.qml | 39 ++++++++----- .../MoveCenterTabController.cpp | 57 ++++++++++++++++--- src/tabcontrollers/MoveCenterTabController.h | 11 +++- 3 files changed, 83 insertions(+), 24 deletions(-) diff --git a/src/res/qml/PlayspacePage.qml b/src/res/qml/PlayspacePage.qml index 741121f..3c7ec21 100644 --- a/src/res/qml/PlayspacePage.qml +++ b/src/res/qml/PlayspacePage.qml @@ -278,22 +278,32 @@ MyStackViewPage { border.color: "#ffffff" radius: 8 } - RowLayout { - anchors.fill: parent + ColumnLayout { + RowLayout { + anchors.fill: parent - MyToggleButton { - id: moveShortcutLeft - text: "Left Menu Button" - onCheckedChanged: { - MoveCenterTabController.moveShortcutLeft = this.checked + MyToggleButton { + id: moveShortcutLeft + text: "Left Menu Button" + onCheckedChanged: { + MoveCenterTabController.moveShortcutLeft = this.checked + } } - } - MyToggleButton { - id: moveShortcutRight - text: "Right Menu Button" - onCheckedChanged: { - MoveCenterTabController.moveShortcutRight = this.checked + MyToggleButton { + id: moveShortcutRight + text: "Right Menu Button" + onCheckedChanged: { + MoveCenterTabController.moveShortcutRight = this.checked + } + } + + MyToggleButton { + id: requireDoubleClick + text: "Require double click" + onCheckedChanged: { + MoveCenterTabController.requireDoubleClick = this.checked + } } } } @@ -366,6 +376,9 @@ MyStackViewPage { onMoveShortcutLeftChanged: { moveShortcutLeft.checked = MoveCenterTabController.moveShortcutLeft } + onRequireDoubleClickChanged: { + requireDoubleClick.checked = MoveCenterTabController.requireDoubleClick + } onTrackingUniverseChanged: { if (MoveCenterTabController.trackingUniverse === 0) { playspaceModeText.text = "Sitting" diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index aeea663..a2729a6 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -17,6 +17,10 @@ void rotateCoordinates(float coordinates[3], float angle) { // application namespace namespace advsettings { +using std::chrono::duration_cast; +using std::chrono::milliseconds; +typedef std::chrono::system_clock clock; + void MoveCenterTabController::initStage1() { setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace()); auto settings = OverlayController::appSettings(); @@ -33,7 +37,12 @@ void MoveCenterTabController::initStage1() { if (value.isValid() && !value.isNull()) { m_moveShortcutLeftEnabled = value.toBool(); } + value = settings->value("requireDoubleClick", m_requireDoubleClick); + if (value.isValid() && !value.isNull()) { + m_requireDoubleClick = value.toBool(); + } settings->endGroup(); + lastMoveButtonClick[0] = lastMoveButtonClick[0] = clock::now(); } void MoveCenterTabController::initStage2(OverlayController * parent, QQuickWindow * widget) { @@ -164,6 +173,22 @@ void MoveCenterTabController::setMoveShortcutLeft(bool value, bool notify) { } } +bool MoveCenterTabController::requireDoubleClick() const { + return m_requireDoubleClick; +} + +void MoveCenterTabController::setRequireDoubleClick(bool value, bool notify) { + m_requireDoubleClick = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup("playspaceSettings"); + settings->setValue("requireDoubleClick", m_requireDoubleClick); + settings->endGroup(); + settings->sync(); + if (notify) { + emit requireDoubleClickChanged(m_requireDoubleClick); + } +} + void MoveCenterTabController::modOffsetX(float value, bool notify) { auto angle = m_rotation * 2 * M_PI / 360.0; float offset[3] = { value, 0, 0 }; @@ -233,13 +258,23 @@ vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() { bool rightPressed = m_moveShortcutRightEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_RightHand); bool leftPressed = m_moveShortcutLeftEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_LeftHand); + bool checkDoubleClick = m_requireDoubleClick && activeHand == vr::TrackedControllerRole_Invalid; + auto now = clock::now(); // if we start pressing the shortcut on a controller we set the active one to it if (rightPressed && !m_moveShortcutRightPressed) { - activeHand = vr::TrackedControllerRole_RightHand; + auto elapsed = duration_cast(now - lastMoveButtonClick[0]).count(); + if (!checkDoubleClick || elapsed < 250) { + activeHand = vr::TrackedControllerRole_RightHand; + } + lastMoveButtonClick[0] = now; } if (leftPressed && !m_moveShortcutLeftPressed) { - activeHand = vr::TrackedControllerRole_LeftHand; + auto elapsed = duration_cast(now - lastMoveButtonClick[1]).count(); + if (!checkDoubleClick || elapsed < 250) { + activeHand = vr::TrackedControllerRole_LeftHand; + } + lastMoveButtonClick[1] = now; } // if we let down of a shortcut we set the active hand to any remaining pressed down hand @@ -252,6 +287,10 @@ vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() { if (!leftPressed && !rightPressed) { activeHand = vr::TrackedControllerRole_Invalid; + if (m_activeMoveController != vr::TrackedControllerRole_Invalid) { + // grace period while switching hands + lastMoveButtonClick[0] = lastMoveButtonClick[1] = now; + } } m_activeMoveController = activeHand; @@ -273,7 +312,7 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe if (newMoveHand == vr::TrackedControllerRole_Invalid) { emit offsetXChanged(m_offsetX); emit offsetYChanged(m_offsetY); - emit offsetZChanged(m_offsetZ); + emit offsetZChanged(m_offsetZ); return; } auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(newMoveHand); @@ -281,7 +320,7 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe if (oldMoveHand != vr::TrackedControllerRole_Invalid) { emit offsetXChanged(m_offsetX); emit offsetYChanged(m_offsetY); - emit offsetZChanged(m_offsetZ); + emit offsetZChanged(m_offsetZ); } return; } @@ -293,15 +332,15 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe pose->mDeviceToAbsoluteTracking.m[0][3], pose->mDeviceToAbsoluteTracking.m[1][3], pose->mDeviceToAbsoluteTracking.m[2][3] - }; + }; - auto angle = m_rotation * 2 * M_PI / 360.0; + auto angle = m_rotation * 2 * M_PI / 360.0; rotateCoordinates(relativeControllerPosition, -angle); float absoluteControllerPosition[] = { relativeControllerPosition[0] + m_offsetX, relativeControllerPosition[1] + m_offsetY, relativeControllerPosition[2] + m_offsetZ, - }; + }; if (oldMoveHand == newMoveHand) { @@ -318,8 +357,8 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe rotateCoordinates(diff, angle); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, diff, m_adjustChaperone); - } + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, diff, m_adjustChaperone); + } m_lastControllerPosition[0] = absoluteControllerPosition[0]; m_lastControllerPosition[1] = absoluteControllerPosition[1]; m_lastControllerPosition[2] = absoluteControllerPosition[2]; diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 4c35640..d3fd079 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -3,6 +3,7 @@ #include #include +#include class QQuickWindow; // application namespace @@ -22,6 +23,7 @@ class MoveCenterTabController : public QObject { Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) + Q_PROPERTY(bool requireDoubleClick READ requireDoubleClick WRITE setRequireDoubleClick NOTIFY requireDoubleClickChanged) private: OverlayController* parent; @@ -30,15 +32,17 @@ private: int m_trackingUniverse = (int)vr::TrackingUniverseStanding; float m_offsetX = 0.0f; float m_offsetY = 0.0f; - float m_offsetZ = 0.0f; + float m_offsetZ = 0.0f; int m_rotation = 0; bool m_adjustChaperone = true; bool m_moveShortcutRightPressed = false; bool m_moveShortcutLeftPressed = false; vr::ETrackedControllerRole m_activeMoveController; - float m_lastControllerPosition[3]; + float m_lastControllerPosition[3]; bool m_moveShortcutRightEnabled = false; bool m_moveShortcutLeftEnabled = false; + bool m_requireDoubleClick = false; + std::chrono::system_clock::time_point lastMoveButtonClick[2]; unsigned settingsUpdateCounter = 0; @@ -57,6 +61,7 @@ public: bool adjustChaperone() const; bool moveShortcutRight() const; bool moveShortcutLeft() const; + bool requireDoubleClick() const; public slots: int trackingUniverse() const; @@ -72,6 +77,7 @@ public slots: void setMoveShortcutRight(bool value, bool notify = true); void setMoveShortcutLeft(bool value, bool notify = true); + void setRequireDoubleClick(bool value, bool notify = true); void modOffsetX(float value, bool notify = true); void modOffsetY(float value, bool notify = true); @@ -87,6 +93,7 @@ signals: void adjustChaperoneChanged(bool value); void moveShortcutRightChanged(bool value); void moveShortcutLeftChanged(bool value); + void requireDoubleClickChanged(bool value); }; } // namespace advsettings