Add option to require double click to move

This commit is contained in:
Robin Appelman
2018-07-08 18:08:09 +02:00
parent a66cded56d
commit 837a91f920
3 changed files with 83 additions and 24 deletions
+26 -13
View File
@@ -278,22 +278,32 @@ MyStackViewPage {
border.color: "#ffffff" border.color: "#ffffff"
radius: 8 radius: 8
} }
RowLayout { ColumnLayout {
anchors.fill: parent RowLayout {
anchors.fill: parent
MyToggleButton { MyToggleButton {
id: moveShortcutLeft id: moveShortcutLeft
text: "Left Menu Button" text: "Left Menu Button"
onCheckedChanged: { onCheckedChanged: {
MoveCenterTabController.moveShortcutLeft = this.checked MoveCenterTabController.moveShortcutLeft = this.checked
}
} }
}
MyToggleButton { MyToggleButton {
id: moveShortcutRight id: moveShortcutRight
text: "Right Menu Button" text: "Right Menu Button"
onCheckedChanged: { onCheckedChanged: {
MoveCenterTabController.moveShortcutRight = this.checked MoveCenterTabController.moveShortcutRight = this.checked
}
}
MyToggleButton {
id: requireDoubleClick
text: "Require double click"
onCheckedChanged: {
MoveCenterTabController.requireDoubleClick = this.checked
}
} }
} }
} }
@@ -366,6 +376,9 @@ MyStackViewPage {
onMoveShortcutLeftChanged: { onMoveShortcutLeftChanged: {
moveShortcutLeft.checked = MoveCenterTabController.moveShortcutLeft moveShortcutLeft.checked = MoveCenterTabController.moveShortcutLeft
} }
onRequireDoubleClickChanged: {
requireDoubleClick.checked = MoveCenterTabController.requireDoubleClick
}
onTrackingUniverseChanged: { onTrackingUniverseChanged: {
if (MoveCenterTabController.trackingUniverse === 0) { if (MoveCenterTabController.trackingUniverse === 0) {
playspaceModeText.text = "Sitting" playspaceModeText.text = "Sitting"
+48 -9
View File
@@ -17,6 +17,10 @@ void rotateCoordinates(float coordinates[3], float angle) {
// application namespace // application namespace
namespace advsettings { namespace advsettings {
using std::chrono::duration_cast;
using std::chrono::milliseconds;
typedef std::chrono::system_clock clock;
void MoveCenterTabController::initStage1() { void MoveCenterTabController::initStage1() {
setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace()); setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace());
auto settings = OverlayController::appSettings(); auto settings = OverlayController::appSettings();
@@ -33,7 +37,12 @@ void MoveCenterTabController::initStage1() {
if (value.isValid() && !value.isNull()) { if (value.isValid() && !value.isNull()) {
m_moveShortcutLeftEnabled = value.toBool(); m_moveShortcutLeftEnabled = value.toBool();
} }
value = settings->value("requireDoubleClick", m_requireDoubleClick);
if (value.isValid() && !value.isNull()) {
m_requireDoubleClick = value.toBool();
}
settings->endGroup(); settings->endGroup();
lastMoveButtonClick[0] = lastMoveButtonClick[0] = clock::now();
} }
void MoveCenterTabController::initStage2(OverlayController * parent, QQuickWindow * widget) { 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) { void MoveCenterTabController::modOffsetX(float value, bool notify) {
auto angle = m_rotation * 2 * M_PI / 360.0; auto angle = m_rotation * 2 * M_PI / 360.0;
float offset[3] = { value, 0, 0 }; float offset[3] = { value, 0, 0 };
@@ -233,13 +258,23 @@ vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() {
bool rightPressed = m_moveShortcutRightEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_RightHand); bool rightPressed = m_moveShortcutRightEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_RightHand);
bool leftPressed = m_moveShortcutLeftEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_LeftHand); 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 we start pressing the shortcut on a controller we set the active one to it
if (rightPressed && !m_moveShortcutRightPressed) { if (rightPressed && !m_moveShortcutRightPressed) {
activeHand = vr::TrackedControllerRole_RightHand; auto elapsed = duration_cast<milliseconds>(now - lastMoveButtonClick[0]).count();
if (!checkDoubleClick || elapsed < 250) {
activeHand = vr::TrackedControllerRole_RightHand;
}
lastMoveButtonClick[0] = now;
} }
if (leftPressed && !m_moveShortcutLeftPressed) { if (leftPressed && !m_moveShortcutLeftPressed) {
activeHand = vr::TrackedControllerRole_LeftHand; auto elapsed = duration_cast<milliseconds>(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 // 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) { if (!leftPressed && !rightPressed) {
activeHand = vr::TrackedControllerRole_Invalid; activeHand = vr::TrackedControllerRole_Invalid;
if (m_activeMoveController != vr::TrackedControllerRole_Invalid) {
// grace period while switching hands
lastMoveButtonClick[0] = lastMoveButtonClick[1] = now;
}
} }
m_activeMoveController = activeHand; m_activeMoveController = activeHand;
@@ -273,7 +312,7 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe
if (newMoveHand == vr::TrackedControllerRole_Invalid) { if (newMoveHand == vr::TrackedControllerRole_Invalid) {
emit offsetXChanged(m_offsetX); emit offsetXChanged(m_offsetX);
emit offsetYChanged(m_offsetY); emit offsetYChanged(m_offsetY);
emit offsetZChanged(m_offsetZ); emit offsetZChanged(m_offsetZ);
return; return;
} }
auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(newMoveHand); auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(newMoveHand);
@@ -281,7 +320,7 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe
if (oldMoveHand != vr::TrackedControllerRole_Invalid) { if (oldMoveHand != vr::TrackedControllerRole_Invalid) {
emit offsetXChanged(m_offsetX); emit offsetXChanged(m_offsetX);
emit offsetYChanged(m_offsetY); emit offsetYChanged(m_offsetY);
emit offsetZChanged(m_offsetZ); emit offsetZChanged(m_offsetZ);
} }
return; return;
} }
@@ -293,15 +332,15 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe
pose->mDeviceToAbsoluteTracking.m[0][3], pose->mDeviceToAbsoluteTracking.m[0][3],
pose->mDeviceToAbsoluteTracking.m[1][3], pose->mDeviceToAbsoluteTracking.m[1][3],
pose->mDeviceToAbsoluteTracking.m[2][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); rotateCoordinates(relativeControllerPosition, -angle);
float absoluteControllerPosition[] = { float absoluteControllerPosition[] = {
relativeControllerPosition[0] + m_offsetX, relativeControllerPosition[0] + m_offsetX,
relativeControllerPosition[1] + m_offsetY, relativeControllerPosition[1] + m_offsetY,
relativeControllerPosition[2] + m_offsetZ, relativeControllerPosition[2] + m_offsetZ,
}; };
if (oldMoveHand == newMoveHand) { if (oldMoveHand == newMoveHand) {
@@ -318,8 +357,8 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe
rotateCoordinates(diff, angle); 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[0] = absoluteControllerPosition[0];
m_lastControllerPosition[1] = absoluteControllerPosition[1]; m_lastControllerPosition[1] = absoluteControllerPosition[1];
m_lastControllerPosition[2] = absoluteControllerPosition[2]; m_lastControllerPosition[2] = absoluteControllerPosition[2];
+9 -2
View File
@@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <openvr.h> #include <openvr.h>
#include <chrono>
class QQuickWindow; class QQuickWindow;
// application namespace // application namespace
@@ -22,6 +23,7 @@ class MoveCenterTabController : public QObject {
Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged)
Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged)
Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged)
Q_PROPERTY(bool requireDoubleClick READ requireDoubleClick WRITE setRequireDoubleClick NOTIFY requireDoubleClickChanged)
private: private:
OverlayController* parent; OverlayController* parent;
@@ -30,15 +32,17 @@ private:
int m_trackingUniverse = (int)vr::TrackingUniverseStanding; int m_trackingUniverse = (int)vr::TrackingUniverseStanding;
float m_offsetX = 0.0f; float m_offsetX = 0.0f;
float m_offsetY = 0.0f; float m_offsetY = 0.0f;
float m_offsetZ = 0.0f; float m_offsetZ = 0.0f;
int m_rotation = 0; int m_rotation = 0;
bool m_adjustChaperone = true; bool m_adjustChaperone = true;
bool m_moveShortcutRightPressed = false; bool m_moveShortcutRightPressed = false;
bool m_moveShortcutLeftPressed = false; bool m_moveShortcutLeftPressed = false;
vr::ETrackedControllerRole m_activeMoveController; vr::ETrackedControllerRole m_activeMoveController;
float m_lastControllerPosition[3]; float m_lastControllerPosition[3];
bool m_moveShortcutRightEnabled = false; bool m_moveShortcutRightEnabled = false;
bool m_moveShortcutLeftEnabled = false; bool m_moveShortcutLeftEnabled = false;
bool m_requireDoubleClick = false;
std::chrono::system_clock::time_point lastMoveButtonClick[2];
unsigned settingsUpdateCounter = 0; unsigned settingsUpdateCounter = 0;
@@ -57,6 +61,7 @@ public:
bool adjustChaperone() const; bool adjustChaperone() const;
bool moveShortcutRight() const; bool moveShortcutRight() const;
bool moveShortcutLeft() const; bool moveShortcutLeft() const;
bool requireDoubleClick() const;
public slots: public slots:
int trackingUniverse() const; int trackingUniverse() const;
@@ -72,6 +77,7 @@ public slots:
void setMoveShortcutRight(bool value, bool notify = true); void setMoveShortcutRight(bool value, bool notify = true);
void setMoveShortcutLeft(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 modOffsetX(float value, bool notify = true);
void modOffsetY(float value, bool notify = true); void modOffsetY(float value, bool notify = true);
@@ -87,6 +93,7 @@ signals:
void adjustChaperoneChanged(bool value); void adjustChaperoneChanged(bool value);
void moveShortcutRightChanged(bool value); void moveShortcutRightChanged(bool value);
void moveShortcutLeftChanged(bool value); void moveShortcutLeftChanged(bool value);
void requireDoubleClickChanged(bool value);
}; };
} // namespace advsettings } // namespace advsettings