From 39f81f39ab03bbea8a530b53a26f9ee17b70d470 Mon Sep 17 00:00:00 2001 From: Mel Klimushyn Date: Sat, 21 Jan 2017 18:56:03 -0800 Subject: [PATCH 1/3] Add optional toggle of the Y offset to MoveCenterTabController. Allows short players and wheelchair users to fully interact with height-limited applications by both boosting their height and being able to touch the in-game floor when necessary. --- bin/win64/res/qml/PlayspacePage.qml | 262 +++++++++++++++++- .../MoveCenterTabController.cpp | 236 ++++++++++++++++ src/tabcontrollers/MoveCenterTabController.h | 43 +++ 3 files changed, 528 insertions(+), 13 deletions(-) diff --git a/bin/win64/res/qml/PlayspacePage.qml b/bin/win64/res/qml/PlayspacePage.qml index 62ad039..20283db 100644 --- a/bin/win64/res/qml/PlayspacePage.qml +++ b/bin/win64/res/qml/PlayspacePage.qml @@ -8,6 +8,149 @@ import matzman666.advsettings 1.0 MyStackViewPage { headerText: "Play Space Settings" + MyDialogOkCancelPopup { + id: pttControllerConfigDialog + property int controllerIndex: -1 + dialogTitle: "Controller Configuration" + dialogWidth: 600 + dialogHeight: 620 + dialogContentItem: ColumnLayout { + MyText { + text: "Buttons" + } + Rectangle { + color: "#cccccc" + height: 1 + Layout.fillWidth: true + } + MyToggleButton { + id: pttControllerConfigGripButtonToggle + text: "Grip" + } + MyToggleButton { + id: pttControllerConfigMenuButtonToggle + text: "Menu" + } + MyToggleButton { + id: pttControllerConfigTriggerButtonToggle + text: "Trigger" + } + + MyText { + Layout.topMargin: 32 + text: "Touchpad" + } + Rectangle { + color: "#cccccc" + height: 1 + Layout.fillWidth: true + } + RowLayout { + spacing: 64 + MyToggleButton { + id: pttControllerConfigPadLeftToggle + text: "Left" + } + MyToggleButton { + id: pttControllerConfigPadRightToggle + text: "Right" + } + } + RowLayout { + spacing: 64 + MyToggleButton { + id: pttControllerConfigPadTopToggle + text: "Top" + } + MyToggleButton { + id: pttControllerConfigPadBottomToggle + text: "Bottom" + } + } + RowLayout { + MyText { + text: "Mode:" + } + MyComboBox { + id: pttControllerConfigPadModeCombo + Layout.preferredWidth: 250 + model: ["Disabled", "Touched", "Pressed"] + } + } + } + onClosed: { + if (okClicked) { + var buttons = [] + if (pttControllerConfigGripButtonToggle.checked) { + buttons.push(2) + } + if (pttControllerConfigMenuButtonToggle.checked) { + buttons.push(1) + } + var triggerMode = 0 + if (pttControllerConfigTriggerButtonToggle.checked) { + triggerMode = 1 + } + var padAreas = 0 + if (pttControllerConfigPadLeftToggle.checked) { + padAreas |= (1 << 0) + } + if (pttControllerConfigPadTopToggle.checked) { + padAreas |= (1 << 1) + } + if (pttControllerConfigPadRightToggle.checked) { + padAreas |= (1 << 2) + } + if (pttControllerConfigPadBottomToggle.checked) { + padAreas |= (1 << 3) + } + MoveCenterTabController.setPttControllerConfig(controllerIndex, buttons, triggerMode, pttControllerConfigPadModeCombo.currentIndex, padAreas); + } + } + function openPopup(controller) { + if (controller === 0) { + dialogTitle = "Left Controller Configuration" + controllerIndex = 0 + } else { + dialogTitle = "Right Controller Configuration" + controllerIndex = 1 + } + pttControllerConfigGripButtonToggle.checked = false + pttControllerConfigMenuButtonToggle.checked = false + pttControllerConfigTriggerButtonToggle.checked = false + pttControllerConfigPadLeftToggle.checked = false + pttControllerConfigPadTopToggle.checked = false + pttControllerConfigPadRightToggle.checked = false + pttControllerConfigPadBottomToggle.checked = false + pttControllerConfigPadModeCombo.currentIndex = MoveCenterTabController.pttTouchpadMode(controllerIndex) + var buttons = MoveCenterTabController.pttDigitalButtons(controllerIndex) + for (var i = 0; i < buttons.length; i++) { + if (buttons[i] == 1) { + pttControllerConfigMenuButtonToggle.checked = true + } else if (buttons[i] == 2) { + pttControllerConfigGripButtonToggle.checked = true + } + } + if (MoveCenterTabController.pttTriggerMode(controllerIndex) > 0) { + pttControllerConfigTriggerButtonToggle.checked = true + } + var padAreas = MoveCenterTabController.pttTouchpadArea(controllerIndex) + if (padAreas & (1 << 0)) { + pttControllerConfigPadLeftToggle.checked = true + } + if (padAreas & (1 << 1)) { + pttControllerConfigPadTopToggle.checked = true + } + if (padAreas & (1 << 2)) { + pttControllerConfigPadRightToggle.checked = true + } + if (padAreas & (1 << 3)) { + pttControllerConfigPadBottomToggle.checked = true + } + open() + } + } + content: ColumnLayout { spacing: 18 @@ -63,10 +206,10 @@ MyStackViewPage { } } - MyTextField { + MyTextField { id: playSpaceMoveXText text: "0.00" - keyBoardUID: 101 + keyBoardUID: 101 Layout.preferredWidth: 140 Layout.leftMargin: 10 Layout.rightMargin: 10 @@ -265,22 +408,100 @@ MyStackViewPage { } } - MyToggleButton { - id: playspaceAdjustChaperoneToggle - text: "Adjust Chaperone" - onCheckedChanged: { - MoveCenterTabController.adjustChaperone = this.checked + GroupBox { + Layout.fillWidth: true + + label: MyText { + leftPadding: 10 + text: "Push-to-Toggle Y-Axis Offset" + bottomPadding: -10 + } + + background: Rectangle { + color: "transparent" + border.color: "#ffffff" + radius: 8 + } + + ColumnLayout { + anchors.fill: parent + + Rectangle { + color: "#ffffff" + height: 1 + Layout.fillWidth: true + Layout.bottomMargin: 5 + } + + ColumnLayout { + RowLayout { + MyToggleButton { + id: offsetYPttEnabledToggle + Layout.preferredWidth: 260 + text: "Enabled" + onClicked: { + MoveCenterTabController.pttEnabled = checked + } + } + MyToggleButton { + id: offsetYPttLeftControllerToggle + text: "Left Controller" + onClicked: { + MoveCenterTabController.setPttLeftControllerEnabled(checked, false) + } + } + MyPushButton { + text: "Configure" + onClicked: { + pttControllerConfigDialog.openPopup(0) + } + } + Item { + Layout.fillWidth: true + } + MyToggleButton { + id: offsetYPttRightControllerToggle + text: "Right Controller" + onClicked: { + MoveCenterTabController.setPttRightControllerEnabled(checked, false) + } + } + MyPushButton { + text: "Configure" + onClicked: { + pttControllerConfigDialog.openPopup(1) + } + } + } + } } } Item { Layout.fillHeight: true; Layout.fillWidth: true} - MyPushButton { - id: playspaceResetButton - Layout.preferredWidth: 250 - text: "Reset" - onClicked: { - MoveCenterTabController.reset() + ColumnLayout { + Layout.fillWidth: true + + RowLayout { + MyToggleButton { + id: playspaceAdjustChaperoneToggle + text: "Adjust Chaperone" + Layout.preferredWidth: 250 + onCheckedChanged: { + MoveCenterTabController.adjustChaperone = this.checked + } + } + + Item { Layout.fillWidth: true} + + MyPushButton { + id: playspaceResetButton + Layout.preferredWidth: 250 + text: "Reset" + onClicked: { + MoveCenterTabController.reset() + } + } } } @@ -305,6 +526,9 @@ MyStackViewPage { } else { playspaceModeText.text = "Unknown(" + MoveCenterTabController.trackingUniverse + ")" } + offsetYPttEnabledToggle.checked = MoveCenterTabController.pttEnabled + offsetYPttLeftControllerToggle.checked = MoveCenterTabController.pttLeftControllerEnabled + offsetYPttRightControllerToggle.checked = MoveCenterTabController.pttRightControllerEnabled } Connections { @@ -341,6 +565,18 @@ MyStackViewPage { playspaceModeText.text = "Unknown(" + MoveCenterTabController.trackingUniverse + ")" } } + onPttEnabledChanged: { + offsetYPttEnabledToggle.checked = MoveCenterTabController.pttEnabled + } + onPttActiveChanged: { + + } + onPttLeftControllerEnabledChanged: { + offsetYPttLeftControllerToggle.checked = MoveCenterTabController.pttLeftControllerEnabled + } + onPttRightControllerEnabledChanged: { + offsetYPttRightControllerToggle.checked = MoveCenterTabController.pttRightControllerEnabled + } } } diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index 26977d2..5a5234a 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -14,6 +14,8 @@ void MoveCenterTabController::initStage1() { if (value.isValid() && !value.isNull()) { m_adjustChaperone = value.toBool(); } + + reloadPttConfig(); } void MoveCenterTabController::initStage2(OverlayController * parent, QQuickWindow * widget) { @@ -135,6 +137,72 @@ void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) { } } +bool MoveCenterTabController::pttEnabled() const { + return m_pttEnabled; +} + +void MoveCenterTabController::setPttEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttEnabled) { + m_pttEnabled = value; + if (notify) { + emit pttEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } +} + +void MoveCenterTabController::offsetYToggle(bool enabled) { + float delta; + if (enabled) { + m_toggleOffsetY = m_offsetY; + delta = -m_toggleOffsetY; + } else { + delta = m_toggleOffsetY; + } + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, delta, m_adjustChaperone); +} + +bool MoveCenterTabController::pttActive() const { + return m_pttActive; +} + +bool MoveCenterTabController::pttLeftControllerEnabled() const { + return m_pttLeftControllerEnabled; +} + +void MoveCenterTabController::setPttLeftControllerEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttLeftControllerEnabled) { + m_pttLeftControllerEnabled = value; + if (notify) { + emit pttLeftControllerEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } +} + +bool MoveCenterTabController::pttRightControllerEnabled() const { + return m_pttRightControllerEnabled; +} + +void MoveCenterTabController::setPttRightControllerEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttRightControllerEnabled) { + m_pttRightControllerEnabled = value; + if (notify) { + emit pttRightControllerEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } +} + void MoveCenterTabController::modOffsetX(float value, bool notify) { if (m_rotation == 0) { parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, value, m_adjustChaperone); @@ -184,6 +252,7 @@ void MoveCenterTabController::reset() { vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); m_offsetX = 0.0f; m_offsetY = 0.0f; + m_toggleOffsetY = 0.0f; m_offsetZ = 0.0f; m_rotation = 0; emit offsetXChanged(m_offsetX); @@ -193,12 +262,179 @@ void MoveCenterTabController::reset() { } void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe) { + if (!eventLoopMutex.try_lock()) { + return; + } if (settingsUpdateCounter >= 50) { setTrackingUniverse((int)universe); settingsUpdateCounter = 0; } else { settingsUpdateCounter++; } + static auto handleControllerState = [](const vr::VRControllerState_t& state, PttControllerConfig* config) -> bool { + if (state.ulButtonPressed & config->digitalButtonMask) { + return true; + } + if (config->triggerMode) { + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger) + || state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) { + return true; + } + } + if (config->touchpadMode) { + if (((config->touchpadMode & 1) && (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad))) + || ((config->touchpadMode & 2) && (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)))) { + if (config->touchpadAreas == (PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + PAD_AREA_BOTTOM)) { + return true; + } else { + float x = state.rAxis[0].x; + float y = state.rAxis[0].y; + if (std::abs(x) >= 0.2 || std::abs(y) >= 0.2) { // deadzone in the middle + if (x < 0 && std::abs(y) < -x && (config->touchpadAreas & PAD_AREA_LEFT)) { + return true; + } else if (y > 0 && std::abs(x) < y && (config->touchpadAreas & PAD_AREA_TOP)) { + return true; + } else if (x > 0 && std::abs(y) < x && (config->touchpadAreas & PAD_AREA_RIGHT)) { + return true; + } else if (y < 0 && std::abs(x) < -y && (config->touchpadAreas & PAD_AREA_BOTTOM)) { + return true; + } + } + } + } + } + return false; + }; + if (m_pttEnabled) { + bool newState = false; + if (m_pttLeftControllerEnabled) { + auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); + if (leftId != vr::k_unTrackedDeviceIndexInvalid) { + vr::VRControllerState_t state; + if (vr::VRSystem()->GetControllerState(leftId, &state, sizeof(vr::VRControllerState_t))) { + newState |= handleControllerState(state, m_pttControllerConfigs); + } + } + } + if (m_pttRightControllerEnabled) { + auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); + if (rightId != vr::k_unTrackedDeviceIndexInvalid) { + vr::VRControllerState_t state; + if (vr::VRSystem()->GetControllerState(rightId, &state, sizeof(vr::VRControllerState_t))) { + newState |= handleControllerState(state, m_pttControllerConfigs + 1); + } + } + } + if (newState && !m_pttActive) { + m_pttActive = true; + offsetYToggle(true); + emit pttActiveChanged(m_pttActive); + } else if (!newState && m_pttActive) { + m_pttActive = false; + offsetYToggle(false); + emit pttActiveChanged(m_pttActive); + } + } + eventLoopMutex.unlock(); } +void MoveCenterTabController::setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas) { + std::lock_guard lock(eventLoopMutex); + if (controller < 2) { + uint64_t buttonMask = 0; + for (auto b : buttons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[controller].digitalButtons = buttons; + m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; + m_pttControllerConfigs[controller].triggerMode = triggerMode; + m_pttControllerConfigs[controller].touchpadMode = padMode; + m_pttControllerConfigs[controller].touchpadAreas = padAreas; + savePttConfig(); + } +} + +void MoveCenterTabController::reloadPttConfig() { + std::lock_guard lock(eventLoopMutex); + auto settings = OverlayController::appSettings(); + settings->beginGroup("playspaceSettings"); + setPttEnabled(settings->value("pttEnabled", false).toBool(), true, false); + setPttLeftControllerEnabled(settings->value("pttLeftControllerEnabled", false).toBool(), true, false); + setPttRightControllerEnabled(settings->value("pttRightControllerEnabled", false).toBool(), true, false); + m_pttControllerConfigs[0].digitalButtons = settings->value("pttDigitalButtons_0").toList(); + uint64_t buttonMask = 0; + for (auto b : m_pttControllerConfigs[0].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[0].digitalButtonMask = buttonMask; + m_pttControllerConfigs[0].triggerMode = settings->value("pttTriggerMode_0", 0).toUInt(); + m_pttControllerConfigs[0].touchpadMode = settings->value("pttTouchpadMode_0", 0).toUInt(); + m_pttControllerConfigs[0].touchpadAreas = settings->value("pttTouchPadAreas_0", 0).toUInt(); + m_pttControllerConfigs[1].digitalButtons = settings->value("pttDigitalButtons_1").toList(); + buttonMask = 0; + for (auto b : m_pttControllerConfigs[0].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[1].digitalButtonMask = buttonMask; + m_pttControllerConfigs[1].triggerMode = settings->value("pttTriggerMode_1", 0).toUInt(); + m_pttControllerConfigs[1].touchpadMode = settings->value("pttTouchpadMode_1", 0).toUInt(); + m_pttControllerConfigs[1].touchpadAreas = settings->value("pttTouchPadAreas_1", 0).toUInt(); + settings->endGroup(); +} + +void MoveCenterTabController::savePttConfig() { + auto settings = OverlayController::appSettings(); + settings->beginGroup("playspaceSettings"); + settings->setValue("pttEnabled", pttEnabled()); + settings->setValue("pttLeftControllerEnabled", pttLeftControllerEnabled()); + settings->setValue("pttRightControllerEnabled", pttRightControllerEnabled()); + settings->setValue("pttDigitalButtons_0", m_pttControllerConfigs[0].digitalButtons); + settings->setValue("pttTriggerMode_0", m_pttControllerConfigs[0].triggerMode); + settings->setValue("pttTouchpadMode_0", m_pttControllerConfigs[0].touchpadMode); + settings->setValue("pttTouchPadAreas_0", m_pttControllerConfigs[0].touchpadAreas); + settings->setValue("pttDigitalButtons_1", m_pttControllerConfigs[1].digitalButtons); + settings->setValue("pttTriggerMode_1", m_pttControllerConfigs[1].triggerMode); + settings->setValue("pttTouchpadMode_1", m_pttControllerConfigs[1].touchpadMode); + settings->setValue("pttTouchPadAreas_1", m_pttControllerConfigs[1].touchpadAreas); + settings->endGroup(); +} + + +QVariantList MoveCenterTabController::pttDigitalButtons(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].digitalButtons; + } + return QVariantList(); +} + +unsigned long MoveCenterTabController::pttDigitalButtonMask(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].digitalButtonMask; + } + return 0; +} + +unsigned MoveCenterTabController::pttTouchpadMode(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].touchpadMode; + } + return 0; +} + +unsigned MoveCenterTabController::pttTriggerMode(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].triggerMode; + } + return 0; +} + +unsigned MoveCenterTabController::pttTouchpadArea(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].touchpadAreas; + } + return 0; +} + + + } // namespace advconfig diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 270582e..ad9efe5 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -1,8 +1,11 @@ #pragma once +#include "AudioTabController.h" #include +#include #include +#include class QQuickWindow; // application namespace @@ -20,20 +23,36 @@ class MoveCenterTabController : public QObject { Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged) Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) + Q_PROPERTY(bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY pttEnabledChanged) + Q_PROPERTY(bool pttActive READ pttActive NOTIFY pttActiveChanged) + Q_PROPERTY(bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged) + Q_PROPERTY(bool pttRightControllerEnabled READ pttRightControllerEnabled WRITE setPttRightControllerEnabled NOTIFY pttRightControllerEnabledChanged) private: + void offsetYToggle(bool enabled); + OverlayController* parent; QQuickWindow* widget; int m_trackingUniverse = (int)vr::TrackingUniverseStanding; float m_offsetX = 0.0f; float m_offsetY = 0.0f; + float m_toggleOffsetY = 0.0f; float m_offsetZ = 0.0f; int m_rotation = 0; bool m_adjustChaperone = true; + bool m_pttEnabled = false; + bool m_pttActive = false; + bool m_pttShowNotification = false; + bool m_pttLeftControllerEnabled = false; + bool m_pttRightControllerEnabled = false; + PttControllerConfig m_pttControllerConfigs[2]; + unsigned settingsUpdateCounter = 0; + std::recursive_mutex eventLoopMutex; + public: void initStage1(); void initStage2(OverlayController* parent, QQuickWindow* widget); @@ -46,6 +65,19 @@ public: int rotation() const; bool adjustChaperone() const; + bool pttEnabled() const; + bool pttActive() const; + bool pttLeftControllerEnabled() const; + bool pttRightControllerEnabled() const; + void reloadPttConfig(); + void savePttConfig(); + + Q_INVOKABLE QVariantList pttDigitalButtons(unsigned controller); + Q_INVOKABLE unsigned long pttDigitalButtonMask(unsigned controller); + Q_INVOKABLE unsigned pttTouchpadMode(unsigned controller); + Q_INVOKABLE unsigned pttTriggerMode(unsigned controller); + Q_INVOKABLE unsigned pttTouchpadArea(unsigned controller); + public slots: int trackingUniverse() const; void setTrackingUniverse(int value, bool notify = true); @@ -63,6 +95,12 @@ public slots: void modOffsetZ(float value, bool notify = true); void reset(); + void setPttEnabled(bool value, bool notify = true, bool save = true); + void setPttLeftControllerEnabled(bool value, bool notify = true, bool save = true); + void setPttRightControllerEnabled(bool value, bool notify = true, bool save = true); + + void setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas); + signals: void trackingUniverseChanged(int value); void offsetXChanged(float value); @@ -70,6 +108,11 @@ signals: void offsetZChanged(float value); void rotationChanged(int value); void adjustChaperoneChanged(bool value); + + void pttEnabledChanged(bool value); + void pttActiveChanged(bool value); + void pttLeftControllerEnabledChanged(bool value); + void pttRightControllerEnabledChanged(bool value); }; } // namespace advsettings From 6271f230dfe098f952a5cfecb25a79ec4dc61885 Mon Sep 17 00:00:00 2001 From: Mel Klimushyn Date: Sat, 28 Jan 2017 11:06:28 -0800 Subject: [PATCH 2/3] Refactor out duplicate PTT logic into a shared controller. --- advancedSettings.pro | 6 +- bin/win64/res/qml/AudioPage.qml | 142 +---- bin/win64/res/qml/PlayspacePage.qml | 142 +---- .../res/qml/PttControllerConfigDialog.qml | 148 ++++++ src/tabcontrollers/AudioTabController.cpp | 478 +---------------- src/tabcontrollers/AudioTabController.h | 88 +--- .../MoveCenterTabController.cpp | 233 +-------- src/tabcontrollers/MoveCenterTabController.h | 46 +- src/tabcontrollers/PttController.cpp | 491 ++++++++++++++++++ src/tabcontrollers/PttController.h | 120 +++++ 10 files changed, 805 insertions(+), 1089 deletions(-) create mode 100644 bin/win64/res/qml/PttControllerConfigDialog.qml create mode 100644 src/tabcontrollers/PttController.cpp create mode 100644 src/tabcontrollers/PttController.h diff --git a/advancedSettings.pro b/advancedSettings.pro index 67fd97b..8fa06eb 100644 --- a/advancedSettings.pro +++ b/advancedSettings.pro @@ -23,7 +23,8 @@ SOURCES += src/main.cpp\ src/tabcontrollers/SteamVRTabController.cpp \ src/tabcontrollers/ReviveTabController.cpp \ src/tabcontrollers/UtilitiesTabController.cpp \ - src/tabcontrollers/audiomanager/AudioManagerWindows.cpp + src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \ + src/tabcontrollers/PttController.cpp HEADERS += src/overlaycontroller.h \ src/logging.h \ @@ -37,7 +38,8 @@ HEADERS += src/overlaycontroller.h \ src/tabcontrollers/ReviveTabController.h \ src/tabcontrollers/UtilitiesTabController.h \ src/tabcontrollers/AudioManager.h \ - src/tabcontrollers/audiomanager/AudioManagerWindows.h + src/tabcontrollers/audiomanager/AudioManagerWindows.h \ + src/tabcontrollers/PttController.h INCLUDEPATH += third-party/openvr/include \ third-party/easylogging++ diff --git a/bin/win64/res/qml/AudioPage.qml b/bin/win64/res/qml/AudioPage.qml index 18def4a..80b3bd4 100644 --- a/bin/win64/res/qml/AudioPage.qml +++ b/bin/win64/res/qml/AudioPage.qml @@ -30,147 +30,9 @@ MyStackViewPage { } } - MyDialogOkCancelPopup { + PttControllerConfigDialog { id: pttControllerConfigDialog - property int controllerIndex: -1 - dialogTitle: "Controller Configuration" - dialogWidth: 600 - dialogHeight: 620 - dialogContentItem: ColumnLayout { - MyText { - text: "Buttons" - } - Rectangle { - color: "#cccccc" - height: 1 - Layout.fillWidth: true - } - MyToggleButton { - id: pttControllerConfigGripButtonToggle - text: "Grip" - } - MyToggleButton { - id: pttControllerConfigMenuButtonToggle - text: "Menu" - } - MyToggleButton { - id: pttControllerConfigTriggerButtonToggle - text: "Trigger" - } - - MyText { - Layout.topMargin: 32 - text: "Touchpad" - } - Rectangle { - color: "#cccccc" - height: 1 - Layout.fillWidth: true - } - RowLayout { - spacing: 64 - MyToggleButton { - id: pttControllerConfigPadLeftToggle - text: "Left" - } - MyToggleButton { - id: pttControllerConfigPadRightToggle - text: "Right" - } - } - RowLayout { - spacing: 64 - MyToggleButton { - id: pttControllerConfigPadTopToggle - text: "Top" - } - MyToggleButton { - id: pttControllerConfigPadBottomToggle - text: "Bottom" - } - } - RowLayout { - MyText { - text: "Mode:" - } - MyComboBox { - id: pttControllerConfigPadModeCombo - Layout.preferredWidth: 250 - model: ["Disabled", "Touched", "Pressed"] - } - } - } - onClosed: { - if (okClicked) { - var buttons = [] - if (pttControllerConfigGripButtonToggle.checked) { - buttons.push(2) - } - if (pttControllerConfigMenuButtonToggle.checked) { - buttons.push(1) - } - var triggerMode = 0 - if (pttControllerConfigTriggerButtonToggle.checked) { - triggerMode = 1 - } - var padAreas = 0 - if (pttControllerConfigPadLeftToggle.checked) { - padAreas |= (1 << 0) - } - if (pttControllerConfigPadTopToggle.checked) { - padAreas |= (1 << 1) - } - if (pttControllerConfigPadRightToggle.checked) { - padAreas |= (1 << 2) - } - if (pttControllerConfigPadBottomToggle.checked) { - padAreas |= (1 << 3) - } - AudioTabController.setPttControllerConfig(controllerIndex, buttons, triggerMode, pttControllerConfigPadModeCombo.currentIndex, padAreas); - } - } - function openPopup(controller) { - if (controller === 0) { - dialogTitle = "Left Controller Configuration" - controllerIndex = 0 - } else { - dialogTitle = "Right Controller Configuration" - controllerIndex = 1 - } - pttControllerConfigGripButtonToggle.checked = false - pttControllerConfigMenuButtonToggle.checked = false - pttControllerConfigTriggerButtonToggle.checked = false - pttControllerConfigPadLeftToggle.checked = false - pttControllerConfigPadTopToggle.checked = false - pttControllerConfigPadRightToggle.checked = false - pttControllerConfigPadBottomToggle.checked = false - pttControllerConfigPadModeCombo.currentIndex = AudioTabController.pttTouchpadMode(controllerIndex) - var buttons = AudioTabController.pttDigitalButtons(controllerIndex) - for (var i = 0; i < buttons.length; i++) { - if (buttons[i] == 1) { - pttControllerConfigMenuButtonToggle.checked = true - } else if (buttons[i] == 2) { - pttControllerConfigGripButtonToggle.checked = true - } - } - if (AudioTabController.pttTriggerMode(controllerIndex) > 0) { - pttControllerConfigTriggerButtonToggle.checked = true - } - var padAreas = AudioTabController.pttTouchpadArea(controllerIndex) - if (padAreas & (1 << 0)) { - pttControllerConfigPadLeftToggle.checked = true - } - if (padAreas & (1 << 1)) { - pttControllerConfigPadTopToggle.checked = true - } - if (padAreas & (1 << 2)) { - pttControllerConfigPadRightToggle.checked = true - } - if (padAreas & (1 << 3)) { - pttControllerConfigPadBottomToggle.checked = true - } - open() - } + pttControllerConfigClass: AudioTabController } MyDialogOkCancelPopup { diff --git a/bin/win64/res/qml/PlayspacePage.qml b/bin/win64/res/qml/PlayspacePage.qml index 20283db..706b116 100644 --- a/bin/win64/res/qml/PlayspacePage.qml +++ b/bin/win64/res/qml/PlayspacePage.qml @@ -8,147 +8,9 @@ import matzman666.advsettings 1.0 MyStackViewPage { headerText: "Play Space Settings" - MyDialogOkCancelPopup { + PttControllerConfigDialog { id: pttControllerConfigDialog - property int controllerIndex: -1 - dialogTitle: "Controller Configuration" - dialogWidth: 600 - dialogHeight: 620 - dialogContentItem: ColumnLayout { - MyText { - text: "Buttons" - } - Rectangle { - color: "#cccccc" - height: 1 - Layout.fillWidth: true - } - MyToggleButton { - id: pttControllerConfigGripButtonToggle - text: "Grip" - } - MyToggleButton { - id: pttControllerConfigMenuButtonToggle - text: "Menu" - } - MyToggleButton { - id: pttControllerConfigTriggerButtonToggle - text: "Trigger" - } - - MyText { - Layout.topMargin: 32 - text: "Touchpad" - } - Rectangle { - color: "#cccccc" - height: 1 - Layout.fillWidth: true - } - RowLayout { - spacing: 64 - MyToggleButton { - id: pttControllerConfigPadLeftToggle - text: "Left" - } - MyToggleButton { - id: pttControllerConfigPadRightToggle - text: "Right" - } - } - RowLayout { - spacing: 64 - MyToggleButton { - id: pttControllerConfigPadTopToggle - text: "Top" - } - MyToggleButton { - id: pttControllerConfigPadBottomToggle - text: "Bottom" - } - } - RowLayout { - MyText { - text: "Mode:" - } - MyComboBox { - id: pttControllerConfigPadModeCombo - Layout.preferredWidth: 250 - model: ["Disabled", "Touched", "Pressed"] - } - } - } - onClosed: { - if (okClicked) { - var buttons = [] - if (pttControllerConfigGripButtonToggle.checked) { - buttons.push(2) - } - if (pttControllerConfigMenuButtonToggle.checked) { - buttons.push(1) - } - var triggerMode = 0 - if (pttControllerConfigTriggerButtonToggle.checked) { - triggerMode = 1 - } - var padAreas = 0 - if (pttControllerConfigPadLeftToggle.checked) { - padAreas |= (1 << 0) - } - if (pttControllerConfigPadTopToggle.checked) { - padAreas |= (1 << 1) - } - if (pttControllerConfigPadRightToggle.checked) { - padAreas |= (1 << 2) - } - if (pttControllerConfigPadBottomToggle.checked) { - padAreas |= (1 << 3) - } - MoveCenterTabController.setPttControllerConfig(controllerIndex, buttons, triggerMode, pttControllerConfigPadModeCombo.currentIndex, padAreas); - } - } - function openPopup(controller) { - if (controller === 0) { - dialogTitle = "Left Controller Configuration" - controllerIndex = 0 - } else { - dialogTitle = "Right Controller Configuration" - controllerIndex = 1 - } - pttControllerConfigGripButtonToggle.checked = false - pttControllerConfigMenuButtonToggle.checked = false - pttControllerConfigTriggerButtonToggle.checked = false - pttControllerConfigPadLeftToggle.checked = false - pttControllerConfigPadTopToggle.checked = false - pttControllerConfigPadRightToggle.checked = false - pttControllerConfigPadBottomToggle.checked = false - pttControllerConfigPadModeCombo.currentIndex = MoveCenterTabController.pttTouchpadMode(controllerIndex) - var buttons = MoveCenterTabController.pttDigitalButtons(controllerIndex) - for (var i = 0; i < buttons.length; i++) { - if (buttons[i] == 1) { - pttControllerConfigMenuButtonToggle.checked = true - } else if (buttons[i] == 2) { - pttControllerConfigGripButtonToggle.checked = true - } - } - if (MoveCenterTabController.pttTriggerMode(controllerIndex) > 0) { - pttControllerConfigTriggerButtonToggle.checked = true - } - var padAreas = MoveCenterTabController.pttTouchpadArea(controllerIndex) - if (padAreas & (1 << 0)) { - pttControllerConfigPadLeftToggle.checked = true - } - if (padAreas & (1 << 1)) { - pttControllerConfigPadTopToggle.checked = true - } - if (padAreas & (1 << 2)) { - pttControllerConfigPadRightToggle.checked = true - } - if (padAreas & (1 << 3)) { - pttControllerConfigPadBottomToggle.checked = true - } - open() - } + pttControllerConfigClass: MoveCenterTabController } content: ColumnLayout { diff --git a/bin/win64/res/qml/PttControllerConfigDialog.qml b/bin/win64/res/qml/PttControllerConfigDialog.qml new file mode 100644 index 0000000..c1d5ddd --- /dev/null +++ b/bin/win64/res/qml/PttControllerConfigDialog.qml @@ -0,0 +1,148 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 +import matzman666.advsettings 1.0 + +MyDialogOkCancelPopup { + id: pttControllerConfigDialog + property var pttControllerConfigClass + property int controllerIndex: -1 + dialogTitle: "Controller Configuration" + dialogWidth: 600 + dialogHeight: 620 + dialogContentItem: ColumnLayout { + MyText { + text: "Buttons" + } + Rectangle { + color: "#cccccc" + height: 1 + Layout.fillWidth: true + } + MyToggleButton { + id: pttControllerConfigGripButtonToggle + text: "Grip" + } + MyToggleButton { + id: pttControllerConfigMenuButtonToggle + text: "Menu" + } + MyToggleButton { + id: pttControllerConfigTriggerButtonToggle + text: "Trigger" + } + + MyText { + Layout.topMargin: 32 + text: "Touchpad" + } + Rectangle { + color: "#cccccc" + height: 1 + Layout.fillWidth: true + } + RowLayout { + spacing: 64 + MyToggleButton { + id: pttControllerConfigPadLeftToggle + text: "Left" + } + MyToggleButton { + id: pttControllerConfigPadRightToggle + text: "Right" + } + } + RowLayout { + spacing: 64 + MyToggleButton { + id: pttControllerConfigPadTopToggle + text: "Top" + } + MyToggleButton { + id: pttControllerConfigPadBottomToggle + text: "Bottom" + } + } + RowLayout { + MyText { + text: "Mode:" + } + MyComboBox { + id: pttControllerConfigPadModeCombo + Layout.preferredWidth: 250 + model: ["Disabled", "Touched", "Pressed"] + } + } + } + onClosed: { + if (okClicked) { + var buttons = [] + if (pttControllerConfigGripButtonToggle.checked) { + buttons.push(2) + } + if (pttControllerConfigMenuButtonToggle.checked) { + buttons.push(1) + } + var triggerMode = 0 + if (pttControllerConfigTriggerButtonToggle.checked) { + triggerMode = 1 + } + var padAreas = 0 + if (pttControllerConfigPadLeftToggle.checked) { + padAreas |= (1 << 0) + } + if (pttControllerConfigPadTopToggle.checked) { + padAreas |= (1 << 1) + } + if (pttControllerConfigPadRightToggle.checked) { + padAreas |= (1 << 2) + } + if (pttControllerConfigPadBottomToggle.checked) { + padAreas |= (1 << 3) + } + pttControllerConfigClass.setPttControllerConfig(controllerIndex, buttons, triggerMode, pttControllerConfigPadModeCombo.currentIndex, padAreas); + } + } + function openPopup(controller) { + if (controller === 0) { + dialogTitle = "Left Controller Configuration" + controllerIndex = 0 + } else { + dialogTitle = "Right Controller Configuration" + controllerIndex = 1 + } + pttControllerConfigGripButtonToggle.checked = false + pttControllerConfigMenuButtonToggle.checked = false + pttControllerConfigTriggerButtonToggle.checked = false + pttControllerConfigPadLeftToggle.checked = false + pttControllerConfigPadTopToggle.checked = false + pttControllerConfigPadRightToggle.checked = false + pttControllerConfigPadBottomToggle.checked = false + pttControllerConfigPadModeCombo.currentIndex = pttControllerConfigClass.pttTouchpadMode(controllerIndex) + var buttons = pttControllerConfigClass.pttDigitalButtons(controllerIndex) + for (var i = 0; i < buttons.length; i++) { + if (buttons[i] == 1) { + pttControllerConfigMenuButtonToggle.checked = true + } else if (buttons[i] == 2) { + pttControllerConfigGripButtonToggle.checked = true + } + } + if (pttControllerConfigClass.pttTriggerMode(controllerIndex) > 0) { + pttControllerConfigTriggerButtonToggle.checked = true + } + var padAreas = pttControllerConfigClass.pttTouchpadArea(controllerIndex) + if (padAreas & (1 << 0)) { + pttControllerConfigPadLeftToggle.checked = true + } + if (padAreas & (1 << 1)) { + pttControllerConfigPadTopToggle.checked = true + } + if (padAreas & (1 << 2)) { + pttControllerConfigPadRightToggle.checked = true + } + if (padAreas & (1 << 3)) { + pttControllerConfigPadBottomToggle.checked = true + } + open() + } +} diff --git a/src/tabcontrollers/AudioTabController.cpp b/src/tabcontrollers/AudioTabController.cpp index 5b414e4..c437c6c 100644 --- a/src/tabcontrollers/AudioTabController.cpp +++ b/src/tabcontrollers/AudioTabController.cpp @@ -97,241 +97,6 @@ namespace advsettings { return m_micMuted; } - - bool AudioTabController::pttEnabled() const { - return m_pttEnabled; - } - - - bool AudioTabController::pttActive() const { - return m_pttActive; - } - - - bool AudioTabController::pttShowNotification() const { - return m_pttShowNotification; - } - - - bool AudioTabController::pttLeftControllerEnabled() const { - return m_pttLeftControllerEnabled; - } - - - bool AudioTabController::pttRightControllerEnabled() const { - return m_pttRightControllerEnabled; - } - - void AudioTabController::setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas) { - std::lock_guard lock(eventLoopMutex); - if (controller < 2) { - uint64_t buttonMask = 0; - for (auto b : buttons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[controller].digitalButtons = buttons; - m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; - m_pttControllerConfigs[controller].triggerMode = triggerMode; - m_pttControllerConfigs[controller].touchpadMode = padMode; - m_pttControllerConfigs[controller].touchpadAreas = padAreas; - savePttConfig(); - } - } - - void AudioTabController::reloadPttProfiles() { - pttProfiles.clear(); - auto settings = OverlayController::appSettings(); - settings->beginGroup("audioSettings"); - auto profileCount = settings->beginReadArray("pttProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - pttProfiles.emplace_back(); - auto& entry = pttProfiles[i]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.showNotification = settings->value("showNotification", true).toBool(); - entry.leftControllerEnabled = settings->value("leftControllerEnabled", false).toBool(); - entry.rightControllerEnabled = settings->value("rightControllerEnabled", false).toBool(); - entry.controllerConfigs[0].digitalButtons = settings->value("digitalButtons_0").toList(); - uint64_t buttonMask = 0; - for (auto b : entry.controllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - entry.controllerConfigs[0].digitalButtonMask = buttonMask; - entry.controllerConfigs[0].triggerMode = settings->value("triggerMode_0", 0).toUInt(); - entry.controllerConfigs[0].touchpadMode = settings->value("touchpadMode_0", 0).toUInt(); - entry.controllerConfigs[0].touchpadAreas = settings->value("touchPadAreas_0", 0).toUInt(); - entry.controllerConfigs[1].digitalButtons = settings->value("digitalButtons_1").toList(); - buttonMask = 0; - for (auto b : entry.controllerConfigs[1].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - entry.controllerConfigs[1].digitalButtonMask = buttonMask; - entry.controllerConfigs[1].triggerMode = settings->value("triggerMode_1", 0).toUInt(); - entry.controllerConfigs[1].touchpadMode = settings->value("touchpadMode_1", 0).toUInt(); - entry.controllerConfigs[1].touchpadAreas = settings->value("touchPadAreas_1", 0).toUInt(); - } - settings->endArray(); - settings->endGroup(); - } - - void AudioTabController::savePttProfiles() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("audioSettings"); - settings->beginWriteArray("pttProfiles"); - unsigned i = 0; - for (auto& p : pttProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("showNotification", p.showNotification); - settings->setValue("leftControllerEnabled", p.leftControllerEnabled); - settings->setValue("rightControllerEnabled", p.rightControllerEnabled); - settings->setValue("digitalButtons_0", p.controllerConfigs[0].digitalButtons); - settings->setValue("triggerMode_0", p.controllerConfigs[0].triggerMode); - settings->setValue("touchpadMode_0", p.controllerConfigs[0].touchpadMode); - settings->setValue("touchPadAreas_0", p.controllerConfigs[0].touchpadAreas); - settings->setValue("digitalButtons_1", p.controllerConfigs[1].digitalButtons); - settings->setValue("triggerMode_1", p.controllerConfigs[1].triggerMode); - settings->setValue("touchpadMode_1", p.controllerConfigs[1].touchpadMode); - settings->setValue("touchPadAreas_1", p.controllerConfigs[1].touchpadAreas); - i++; - } - settings->endArray(); - settings->endGroup(); - } - - - void AudioTabController::reloadPttConfig() { - std::lock_guard lock(eventLoopMutex); - auto settings = OverlayController::appSettings(); - settings->beginGroup("audioSettings"); - setPttEnabled(settings->value("pttEnabled", false).toBool(), true, false); - setPttLeftControllerEnabled(settings->value("pttLeftControllerEnabled", false).toBool(), true, false); - setPttRightControllerEnabled(settings->value("pttRightControllerEnabled", false).toBool(), true, false); - setPttShowNotification(settings->value("pttShowNotification", true).toBool(), true, false); - m_pttControllerConfigs[0].digitalButtons = settings->value("pttDigitalButtons_0").toList(); - uint64_t buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[0].digitalButtonMask = buttonMask; - m_pttControllerConfigs[0].triggerMode = settings->value("pttTriggerMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadMode = settings->value("pttTouchpadMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadAreas = settings->value("pttTouchPadAreas_0", 0).toUInt(); - m_pttControllerConfigs[1].digitalButtons = settings->value("pttDigitalButtons_1").toList(); - buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[1].digitalButtonMask = buttonMask; - m_pttControllerConfigs[1].triggerMode = settings->value("pttTriggerMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadMode = settings->value("pttTouchpadMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadAreas = settings->value("pttTouchPadAreas_1", 0).toUInt(); - settings->endGroup(); - } - - void AudioTabController::savePttConfig() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("audioSettings"); - settings->setValue("pttEnabled", pttEnabled()); - settings->setValue("pttLeftControllerEnabled", pttLeftControllerEnabled()); - settings->setValue("pttRightControllerEnabled", pttRightControllerEnabled()); - settings->setValue("pttShowNotification", pttShowNotification()); - settings->setValue("pttDigitalButtons_0", m_pttControllerConfigs[0].digitalButtons); - settings->setValue("pttTriggerMode_0", m_pttControllerConfigs[0].triggerMode); - settings->setValue("pttTouchpadMode_0", m_pttControllerConfigs[0].touchpadMode); - settings->setValue("pttTouchPadAreas_0", m_pttControllerConfigs[0].touchpadAreas); - settings->setValue("pttDigitalButtons_1", m_pttControllerConfigs[1].digitalButtons); - settings->setValue("pttTriggerMode_1", m_pttControllerConfigs[1].triggerMode); - settings->setValue("pttTouchpadMode_1", m_pttControllerConfigs[1].touchpadMode); - settings->setValue("pttTouchPadAreas_1", m_pttControllerConfigs[1].touchpadAreas); - settings->endGroup(); - } - - void logControllerState(const vr::VRControllerState_t& state, const std::string& prefix) { - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_A)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " pressed"; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_A)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " touched"; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; - } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; - } - } - void AudioTabController::eventLoopTick() { if (!eventLoopMutex.try_lock()) { return; @@ -370,191 +135,28 @@ namespace advsettings { } else { settingsUpdateCounter++; } - static auto handleControllerState = [](const vr::VRControllerState_t& state, PttControllerConfig* config) -> bool { - if (state.ulButtonPressed & config->digitalButtonMask) { - return true; - } - if (config->triggerMode) { - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger) - || state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) { - return true; - } - } - if (config->touchpadMode) { - if (((config->touchpadMode & 1) && (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad))) - || ((config->touchpadMode & 2) && (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)))) { - if (config->touchpadAreas == (PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + PAD_AREA_BOTTOM)) { - return true; - } else { - float x = state.rAxis[0].x; - float y = state.rAxis[0].y; - if (std::abs(x) >= 0.2 || std::abs(y) >= 0.2) { // deadzone in the middle - if (x < 0 && std::abs(y) < -x && (config->touchpadAreas & PAD_AREA_LEFT)) { - return true; - } else if (y > 0 && std::abs(x) < y && (config->touchpadAreas & PAD_AREA_TOP)) { - return true; - } else if (x > 0 && std::abs(y) < x && (config->touchpadAreas & PAD_AREA_RIGHT)) { - return true; - } else if (y < 0 && std::abs(x) < -y && (config->touchpadAreas & PAD_AREA_BOTTOM)) { - return true; - } - } - } - } - } - return false; - }; - if (m_pttEnabled) { - bool newState = false; - if (m_pttLeftControllerEnabled) { - auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - if (leftId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(leftId, &state, sizeof(vr::VRControllerState_t))) { - //logControllerState(state, "Left "); - newState |= handleControllerState(state, m_pttControllerConfigs); - } - } - } - if (m_pttRightControllerEnabled) { - auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (rightId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(rightId, &state, sizeof(vr::VRControllerState_t))) { - //logControllerState(state, "Right "); - newState |= handleControllerState(state, m_pttControllerConfigs + 1); - } - } - } - if (newState && !m_pttActive) { - if (audioManager && audioManager->isMicValid()) { - m_pttActive = true; - setMicMuted(false); - if (m_pttShowNotification && m_ulNotificationOverlayHandle != vr::k_ulOverlayHandleInvalid) { - vr::VROverlay()->ShowOverlay(m_ulNotificationOverlayHandle); - } - emit pttActiveChanged(m_pttActive); - } - } else if (!newState && m_pttActive) { - if (audioManager && audioManager->isMicValid()) { - m_pttActive = false; - setMicMuted(true); - if (m_pttShowNotification && m_ulNotificationOverlayHandle != vr::k_ulOverlayHandleInvalid) { - vr::VROverlay()->HideOverlay(m_ulNotificationOverlayHandle); - } - emit pttActiveChanged(m_pttActive); - } - } - } + checkPttStatus(); eventLoopMutex.unlock(); } - void AudioTabController::addPttProfile(QString name) { - PttProfile* profile = nullptr; - for (auto& p : pttProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } - } - if (!profile) { - auto i = pttProfiles.size(); - pttProfiles.emplace_back(); - profile = &pttProfiles[i]; - } - profile->profileName = name.toStdString(); - profile->showNotification = m_pttShowNotification; - profile->leftControllerEnabled = m_pttLeftControllerEnabled; - profile->rightControllerEnabled = m_pttRightControllerEnabled; - profile->controllerConfigs[0].digitalButtons = m_pttControllerConfigs[0].digitalButtons; - profile->controllerConfigs[0].digitalButtonMask = m_pttControllerConfigs[0].digitalButtonMask; - profile->controllerConfigs[0].triggerMode = m_pttControllerConfigs[0].triggerMode; - profile->controllerConfigs[0].touchpadMode = m_pttControllerConfigs[0].touchpadMode; - profile->controllerConfigs[0].touchpadAreas = m_pttControllerConfigs[0].touchpadAreas; - profile->controllerConfigs[1].digitalButtons = m_pttControllerConfigs[1].digitalButtons; - profile->controllerConfigs[1].digitalButtonMask = m_pttControllerConfigs[1].digitalButtonMask; - profile->controllerConfigs[1].triggerMode = m_pttControllerConfigs[1].triggerMode; - profile->controllerConfigs[1].touchpadMode = m_pttControllerConfigs[1].touchpadMode; - profile->controllerConfigs[1].touchpadAreas = m_pttControllerConfigs[1].touchpadAreas; - savePttProfiles(); - OverlayController::appSettings()->sync(); - emit pttProfilesUpdated(); + bool AudioTabController::pttChangeValid() { + return audioManager && audioManager->isMicValid(); } - void AudioTabController::applyPttProfile(unsigned index) { - std::lock_guard lock(eventLoopMutex); - if (index < pttProfiles.size()) { - auto& profile = pttProfiles[index]; - setPttShowNotification(profile.showNotification); - setPttLeftControllerEnabled(profile.leftControllerEnabled); - setPttRightControllerEnabled(profile.rightControllerEnabled); - m_pttControllerConfigs[0].digitalButtons = profile.controllerConfigs[0].digitalButtons; - m_pttControllerConfigs[0].digitalButtonMask = profile.controllerConfigs[0].digitalButtonMask; - m_pttControllerConfigs[0].triggerMode = profile.controllerConfigs[0].triggerMode; - m_pttControllerConfigs[0].touchpadMode = profile.controllerConfigs[0].touchpadMode; - m_pttControllerConfigs[0].touchpadAreas = profile.controllerConfigs[0].touchpadAreas; - m_pttControllerConfigs[1].digitalButtons = profile.controllerConfigs[1].digitalButtons; - m_pttControllerConfigs[1].digitalButtonMask = profile.controllerConfigs[1].digitalButtonMask; - m_pttControllerConfigs[1].triggerMode = profile.controllerConfigs[1].triggerMode; - m_pttControllerConfigs[1].touchpadMode = profile.controllerConfigs[1].touchpadMode; - m_pttControllerConfigs[1].touchpadAreas = profile.controllerConfigs[1].touchpadAreas; - } + void AudioTabController::onPttStart() { + setMicMuted(false); } - void AudioTabController::deletePttProfile(unsigned index) { - if (index < pttProfiles.size()) { - auto pos = pttProfiles.begin() + index; - pttProfiles.erase(pos); - savePttProfiles(); - OverlayController::appSettings()->sync(); - emit pttProfilesUpdated(); - } + void AudioTabController::onPttEnabled() { + setMicMuted(true); } - QVariantList AudioTabController::pttDigitalButtons(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtons; - } - return QVariantList(); + void AudioTabController::onPttStop() { + setMicMuted(true); } - unsigned long AudioTabController::pttDigitalButtonMask(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtonMask; - } - return 0; - } - - unsigned AudioTabController::pttTouchpadMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadMode; - } - return 0; - } - - unsigned AudioTabController::pttTriggerMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].triggerMode; - } - return 0; - } - - unsigned AudioTabController::pttTouchpadArea(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadAreas; - } - return 0; - } - - unsigned AudioTabController::getPttProfileCount() { - return (unsigned)pttProfiles.size(); - } - - QString AudioTabController::getPttProfileName(unsigned index) { - if (index < pttProfiles.size()) { - return QString::fromStdString(pttProfiles[index].profileName); - } - return ""; + void AudioTabController::onPttDisabled() { + setMicMuted(false); } void AudioTabController::setMirrorVolume(float value, bool notify) { @@ -609,64 +211,6 @@ namespace advsettings { } } - void AudioTabController::setPttEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttEnabled) { - m_pttEnabled = value; - if (value) { - setMicMuted(true); - } else { - setMicMuted(false); - } - if (notify) { - emit pttEnabledChanged(value); - } - if (save) { - savePttConfig(); - } - } - } - - void AudioTabController::setPttShowNotification(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttShowNotification) { - m_pttShowNotification = value; - if (notify) { - emit pttShowNotificationChanged(value); - } - if (save) { - savePttConfig(); - } - } - } - - void AudioTabController::setPttLeftControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttLeftControllerEnabled) { - m_pttLeftControllerEnabled = value; - if (notify) { - emit pttLeftControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } - } - } - - void AudioTabController::setPttRightControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttRightControllerEnabled) { - m_pttRightControllerEnabled = value; - if (notify) { - emit pttRightControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } - } - } - - void AudioTabController::onNewRecordingDevice() { if (audioManager->isMicValid()) { if (!m_micPresent) { diff --git a/src/tabcontrollers/AudioTabController.h b/src/tabcontrollers/AudioTabController.h index e7f98cd..4469682 100644 --- a/src/tabcontrollers/AudioTabController.h +++ b/src/tabcontrollers/AudioTabController.h @@ -2,6 +2,7 @@ #pragma once #include "AudioManager.h" +#include "PttController.h" #include #include #include @@ -17,32 +18,8 @@ namespace advsettings { // forward declaration class OverlayController; - enum TouchPadArea { - PAD_AREA_LEFT = (1 << 0), - PAD_AREA_TOP = (1 << 1), - PAD_AREA_RIGHT = (1 << 2), - PAD_AREA_BOTTOM = (1 << 3), - }; - struct PttControllerConfig { - QVariantList digitalButtons; - uint64_t digitalButtonMask = 0; - unsigned triggerMode = 0; // 0 .. disabled, 1 .. enabled - unsigned touchpadMode = 0; // 0 .. disabled, 1 .. only touch, 2 .. only press, 3 .. both - unsigned touchpadAreas = 0; - }; - - struct PttProfile { - std::string profileName; - - bool showNotification = false; - bool leftControllerEnabled = false; - bool rightControllerEnabled = false; - PttControllerConfig controllerConfigs[2]; - }; - - - class AudioTabController : public QObject { + class AudioTabController : public PttController { Q_OBJECT Q_PROPERTY(bool mirrorPresent READ mirrorPresent NOTIFY mirrorPresentChanged) Q_PROPERTY(QString mirrorDevName READ mirrorDevName NOTIFY mirrorDevNameChanged) @@ -52,11 +29,6 @@ namespace advsettings { Q_PROPERTY(QString micDevName READ micDevName NOTIFY micDevNameChanged) Q_PROPERTY(float micVolume READ micVolume WRITE setMicVolume NOTIFY micVolumeChanged) Q_PROPERTY(bool micMuted READ micMuted WRITE setMicMuted NOTIFY micMutedChanged) - Q_PROPERTY(bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY pttEnabledChanged) - Q_PROPERTY(bool pttActive READ pttActive NOTIFY pttActiveChanged) - Q_PROPERTY(bool pttShowNotification READ pttShowNotification WRITE setPttShowNotification NOTIFY pttShowNotificationChanged) - Q_PROPERTY(bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged) - Q_PROPERTY(bool pttRightControllerEnabled READ pttRightControllerEnabled WRITE setPttRightControllerEnabled NOTIFY pttRightControllerEnabledChanged) private: OverlayController* parent; @@ -73,22 +45,19 @@ namespace advsettings { QString m_micDevName = ""; float m_micVolume = 1.0; bool m_micMuted = false; - - bool m_pttEnabled = false; - bool m_pttActive = false; - bool m_pttShowNotification = false; - bool m_pttLeftControllerEnabled = false; - bool m_pttRightControllerEnabled = false; - PttControllerConfig m_pttControllerConfigs[2]; unsigned settingsUpdateCounter = 0; - std::vector pttProfiles; - std::unique_ptr audioManager; std::string lastMirrorDevId; - std::recursive_mutex eventLoopMutex; + QString getSettingsName() override { return "audioSettings"; } + void onPttStart() override; + void onPttStop() override; + void onPttEnabled() override; + void onPttDisabled() override; + bool pttChangeValid() override; + virtual vr::VROverlayHandle_t getNotificationOverlayHandle() override { return m_ulNotificationOverlayHandle; } public: void initStage1(); @@ -106,28 +75,8 @@ namespace advsettings { float micVolume() const; bool micMuted() const; - bool pttEnabled() const; - bool pttActive() const; - bool pttShowNotification() const; - bool pttLeftControllerEnabled() const; - bool pttRightControllerEnabled() const; - - void reloadPttProfiles(); - void reloadPttConfig(); - void savePttProfiles(); - void savePttConfig(); - void onNewRecordingDevice(); - Q_INVOKABLE QVariantList pttDigitalButtons(unsigned controller); - Q_INVOKABLE unsigned long pttDigitalButtonMask(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadMode(unsigned controller); - Q_INVOKABLE unsigned pttTriggerMode(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadArea(unsigned controller); - - Q_INVOKABLE unsigned getPttProfileCount(); - Q_INVOKABLE QString getPttProfileName(unsigned index); - public slots: void setMirrorVolume(float value, bool notify = true); void setMirrorMuted(bool value, bool notify = true); @@ -135,17 +84,6 @@ namespace advsettings { void setMicVolume(float value, bool notify = true); void setMicMuted(bool value, bool notify = true); - void setPttEnabled(bool value, bool notify = true, bool save = true); - void setPttShowNotification(bool value, bool notify = true, bool save = true); - void setPttLeftControllerEnabled(bool value, bool notify = true, bool save = true); - void setPttRightControllerEnabled(bool value, bool notify = true, bool save = true); - - void setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas); - - void addPttProfile(QString name); - void applyPttProfile(unsigned index); - void deletePttProfile(unsigned index); - signals: void mirrorPresentChanged(bool value); void mirrorDevNameChanged(QString value); @@ -156,14 +94,6 @@ namespace advsettings { void micDevNameChanged(QString value); void micVolumeChanged(float value); void micMutedChanged(bool value); - - void pttEnabledChanged(bool value); - void pttActiveChanged(bool value); - void pttShowNotificationChanged(bool value); - void pttLeftControllerEnabledChanged(bool value); - void pttRightControllerEnabledChanged(bool value); - - void pttProfilesUpdated(); }; } // namespace advsettings diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index 5a5234a..945991a 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -137,70 +137,20 @@ void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) { } } -bool MoveCenterTabController::pttEnabled() const { - return m_pttEnabled; +void MoveCenterTabController::onPttStart() { + m_toggleOffsetY = m_offsetY; + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, -m_toggleOffsetY, m_adjustChaperone); } -void MoveCenterTabController::setPttEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttEnabled) { - m_pttEnabled = value; - if (notify) { - emit pttEnabledChanged(value); - } - if (save) { - savePttConfig(); - } - } +void MoveCenterTabController::onPttStop() { + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, m_toggleOffsetY, m_adjustChaperone); } -void MoveCenterTabController::offsetYToggle(bool enabled) { - float delta; - if (enabled) { - m_toggleOffsetY = m_offsetY; - delta = -m_toggleOffsetY; - } else { - delta = m_toggleOffsetY; - } - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, delta, m_adjustChaperone); -} - -bool MoveCenterTabController::pttActive() const { - return m_pttActive; -} - -bool MoveCenterTabController::pttLeftControllerEnabled() const { - return m_pttLeftControllerEnabled; -} - -void MoveCenterTabController::setPttLeftControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttLeftControllerEnabled) { - m_pttLeftControllerEnabled = value; - if (notify) { - emit pttLeftControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } - } -} - -bool MoveCenterTabController::pttRightControllerEnabled() const { - return m_pttRightControllerEnabled; -} - -void MoveCenterTabController::setPttRightControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttRightControllerEnabled) { - m_pttRightControllerEnabled = value; - if (notify) { - emit pttRightControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } +void MoveCenterTabController::onPttDisabled() { + if (pttActive()) { + stopPtt(); } + m_toggleOffsetY = 0; } void MoveCenterTabController::modOffsetX(float value, bool notify) { @@ -244,6 +194,7 @@ void MoveCenterTabController::modOffsetZ(float value, bool notify) { } void MoveCenterTabController::reset() { + std::lock_guard lock(eventLoopMutex); vr::VRChaperoneSetup()->RevertWorkingCopy(); parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, -m_rotation * 2 * M_PI / 360.0, m_adjustChaperone, false); parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, -m_offsetX, m_adjustChaperone, false); @@ -271,170 +222,8 @@ void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe } else { settingsUpdateCounter++; } - static auto handleControllerState = [](const vr::VRControllerState_t& state, PttControllerConfig* config) -> bool { - if (state.ulButtonPressed & config->digitalButtonMask) { - return true; - } - if (config->triggerMode) { - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger) - || state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) { - return true; - } - } - if (config->touchpadMode) { - if (((config->touchpadMode & 1) && (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad))) - || ((config->touchpadMode & 2) && (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)))) { - if (config->touchpadAreas == (PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + PAD_AREA_BOTTOM)) { - return true; - } else { - float x = state.rAxis[0].x; - float y = state.rAxis[0].y; - if (std::abs(x) >= 0.2 || std::abs(y) >= 0.2) { // deadzone in the middle - if (x < 0 && std::abs(y) < -x && (config->touchpadAreas & PAD_AREA_LEFT)) { - return true; - } else if (y > 0 && std::abs(x) < y && (config->touchpadAreas & PAD_AREA_TOP)) { - return true; - } else if (x > 0 && std::abs(y) < x && (config->touchpadAreas & PAD_AREA_RIGHT)) { - return true; - } else if (y < 0 && std::abs(x) < -y && (config->touchpadAreas & PAD_AREA_BOTTOM)) { - return true; - } - } - } - } - } - return false; - }; - if (m_pttEnabled) { - bool newState = false; - if (m_pttLeftControllerEnabled) { - auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - if (leftId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(leftId, &state, sizeof(vr::VRControllerState_t))) { - newState |= handleControllerState(state, m_pttControllerConfigs); - } - } - } - if (m_pttRightControllerEnabled) { - auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (rightId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(rightId, &state, sizeof(vr::VRControllerState_t))) { - newState |= handleControllerState(state, m_pttControllerConfigs + 1); - } - } - } - if (newState && !m_pttActive) { - m_pttActive = true; - offsetYToggle(true); - emit pttActiveChanged(m_pttActive); - } else if (!newState && m_pttActive) { - m_pttActive = false; - offsetYToggle(false); - emit pttActiveChanged(m_pttActive); - } - } + checkPttStatus(); eventLoopMutex.unlock(); } -void MoveCenterTabController::setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas) { - std::lock_guard lock(eventLoopMutex); - if (controller < 2) { - uint64_t buttonMask = 0; - for (auto b : buttons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[controller].digitalButtons = buttons; - m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; - m_pttControllerConfigs[controller].triggerMode = triggerMode; - m_pttControllerConfigs[controller].touchpadMode = padMode; - m_pttControllerConfigs[controller].touchpadAreas = padAreas; - savePttConfig(); - } -} - -void MoveCenterTabController::reloadPttConfig() { - std::lock_guard lock(eventLoopMutex); - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - setPttEnabled(settings->value("pttEnabled", false).toBool(), true, false); - setPttLeftControllerEnabled(settings->value("pttLeftControllerEnabled", false).toBool(), true, false); - setPttRightControllerEnabled(settings->value("pttRightControllerEnabled", false).toBool(), true, false); - m_pttControllerConfigs[0].digitalButtons = settings->value("pttDigitalButtons_0").toList(); - uint64_t buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[0].digitalButtonMask = buttonMask; - m_pttControllerConfigs[0].triggerMode = settings->value("pttTriggerMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadMode = settings->value("pttTouchpadMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadAreas = settings->value("pttTouchPadAreas_0", 0).toUInt(); - m_pttControllerConfigs[1].digitalButtons = settings->value("pttDigitalButtons_1").toList(); - buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[1].digitalButtonMask = buttonMask; - m_pttControllerConfigs[1].triggerMode = settings->value("pttTriggerMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadMode = settings->value("pttTouchpadMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadAreas = settings->value("pttTouchPadAreas_1", 0).toUInt(); - settings->endGroup(); -} - -void MoveCenterTabController::savePttConfig() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("pttEnabled", pttEnabled()); - settings->setValue("pttLeftControllerEnabled", pttLeftControllerEnabled()); - settings->setValue("pttRightControllerEnabled", pttRightControllerEnabled()); - settings->setValue("pttDigitalButtons_0", m_pttControllerConfigs[0].digitalButtons); - settings->setValue("pttTriggerMode_0", m_pttControllerConfigs[0].triggerMode); - settings->setValue("pttTouchpadMode_0", m_pttControllerConfigs[0].touchpadMode); - settings->setValue("pttTouchPadAreas_0", m_pttControllerConfigs[0].touchpadAreas); - settings->setValue("pttDigitalButtons_1", m_pttControllerConfigs[1].digitalButtons); - settings->setValue("pttTriggerMode_1", m_pttControllerConfigs[1].triggerMode); - settings->setValue("pttTouchpadMode_1", m_pttControllerConfigs[1].touchpadMode); - settings->setValue("pttTouchPadAreas_1", m_pttControllerConfigs[1].touchpadAreas); - settings->endGroup(); -} - - -QVariantList MoveCenterTabController::pttDigitalButtons(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtons; - } - return QVariantList(); -} - -unsigned long MoveCenterTabController::pttDigitalButtonMask(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtonMask; - } - return 0; -} - -unsigned MoveCenterTabController::pttTouchpadMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadMode; - } - return 0; -} - -unsigned MoveCenterTabController::pttTriggerMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].triggerMode; - } - return 0; -} - -unsigned MoveCenterTabController::pttTouchpadArea(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadAreas; - } - return 0; -} - - - } // namespace advconfig diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index ad9efe5..3d62f23 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -2,7 +2,9 @@ #pragma once #include "AudioTabController.h" +#include "PttController.h" #include +#include #include #include #include @@ -15,7 +17,7 @@ namespace advsettings { class OverlayController; -class MoveCenterTabController : public QObject { +class MoveCenterTabController : public PttController { Q_OBJECT Q_PROPERTY(int trackingUniverse READ trackingUniverse WRITE setTrackingUniverse NOTIFY trackingUniverseChanged) Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged) @@ -23,14 +25,8 @@ class MoveCenterTabController : public QObject { Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged) Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) - Q_PROPERTY(bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY pttEnabledChanged) - Q_PROPERTY(bool pttActive READ pttActive NOTIFY pttActiveChanged) - Q_PROPERTY(bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged) - Q_PROPERTY(bool pttRightControllerEnabled READ pttRightControllerEnabled WRITE setPttRightControllerEnabled NOTIFY pttRightControllerEnabledChanged) private: - void offsetYToggle(bool enabled); - OverlayController* parent; QQuickWindow* widget; @@ -42,16 +38,12 @@ private: int m_rotation = 0; bool m_adjustChaperone = true; - bool m_pttEnabled = false; - bool m_pttActive = false; - bool m_pttShowNotification = false; - bool m_pttLeftControllerEnabled = false; - bool m_pttRightControllerEnabled = false; - PttControllerConfig m_pttControllerConfigs[2]; - unsigned settingsUpdateCounter = 0; - std::recursive_mutex eventLoopMutex; + QString getSettingsName() override { return "playspaceSettings"; } + void onPttStart() override; + void onPttStop() override; + void onPttDisabled() override; public: void initStage1(); @@ -65,19 +57,6 @@ public: int rotation() const; bool adjustChaperone() const; - bool pttEnabled() const; - bool pttActive() const; - bool pttLeftControllerEnabled() const; - bool pttRightControllerEnabled() const; - void reloadPttConfig(); - void savePttConfig(); - - Q_INVOKABLE QVariantList pttDigitalButtons(unsigned controller); - Q_INVOKABLE unsigned long pttDigitalButtonMask(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadMode(unsigned controller); - Q_INVOKABLE unsigned pttTriggerMode(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadArea(unsigned controller); - public slots: int trackingUniverse() const; void setTrackingUniverse(int value, bool notify = true); @@ -95,12 +74,6 @@ public slots: void modOffsetZ(float value, bool notify = true); void reset(); - void setPttEnabled(bool value, bool notify = true, bool save = true); - void setPttLeftControllerEnabled(bool value, bool notify = true, bool save = true); - void setPttRightControllerEnabled(bool value, bool notify = true, bool save = true); - - void setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas); - signals: void trackingUniverseChanged(int value); void offsetXChanged(float value); @@ -108,11 +81,6 @@ signals: void offsetZChanged(float value); void rotationChanged(int value); void adjustChaperoneChanged(bool value); - - void pttEnabledChanged(bool value); - void pttActiveChanged(bool value); - void pttLeftControllerEnabledChanged(bool value); - void pttRightControllerEnabledChanged(bool value); }; } // namespace advsettings diff --git a/src/tabcontrollers/PttController.cpp b/src/tabcontrollers/PttController.cpp new file mode 100644 index 0000000..2fa0a30 --- /dev/null +++ b/src/tabcontrollers/PttController.cpp @@ -0,0 +1,491 @@ +#include "PttController.h" +#include +#include +#include "../overlaycontroller.h" + +// application namespace +namespace advsettings { + + bool PttController::pttEnabled() const { + return m_pttEnabled; + } + + + bool PttController::pttActive() const { + return m_pttActive; + } + + + bool PttController::pttShowNotification() const { + return m_pttShowNotification; + } + + + bool PttController::pttLeftControllerEnabled() const { + return m_pttLeftControllerEnabled; + } + + + bool PttController::pttRightControllerEnabled() const { + return m_pttRightControllerEnabled; + } + + void PttController::setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas) { + std::lock_guard lock(eventLoopMutex); + if (controller < 2) { + uint64_t buttonMask = 0; + for (auto b : buttons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[controller].digitalButtons = buttons; + m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; + m_pttControllerConfigs[controller].triggerMode = triggerMode; + m_pttControllerConfigs[controller].touchpadMode = padMode; + m_pttControllerConfigs[controller].touchpadAreas = padAreas; + savePttConfig(); + } + } + + void PttController::reloadPttProfiles() { + pttProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup(getSettingsName()); + auto profileCount = settings->beginReadArray("pttProfiles"); + for (int i = 0; i < profileCount; i++) { + settings->setArrayIndex(i); + pttProfiles.emplace_back(); + auto& entry = pttProfiles[i]; + entry.profileName = settings->value("profileName").toString().toStdString(); + entry.showNotification = settings->value("showNotification", true).toBool(); + entry.leftControllerEnabled = settings->value("leftControllerEnabled", false).toBool(); + entry.rightControllerEnabled = settings->value("rightControllerEnabled", false).toBool(); + entry.controllerConfigs[0].digitalButtons = settings->value("digitalButtons_0").toList(); + uint64_t buttonMask = 0; + for (auto b : entry.controllerConfigs[0].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + entry.controllerConfigs[0].digitalButtonMask = buttonMask; + entry.controllerConfigs[0].triggerMode = settings->value("triggerMode_0", 0).toUInt(); + entry.controllerConfigs[0].touchpadMode = settings->value("touchpadMode_0", 0).toUInt(); + entry.controllerConfigs[0].touchpadAreas = settings->value("touchPadAreas_0", 0).toUInt(); + entry.controllerConfigs[1].digitalButtons = settings->value("digitalButtons_1").toList(); + buttonMask = 0; + for (auto b : entry.controllerConfigs[1].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + entry.controllerConfigs[1].digitalButtonMask = buttonMask; + entry.controllerConfigs[1].triggerMode = settings->value("triggerMode_1", 0).toUInt(); + entry.controllerConfigs[1].touchpadMode = settings->value("touchpadMode_1", 0).toUInt(); + entry.controllerConfigs[1].touchpadAreas = settings->value("touchPadAreas_1", 0).toUInt(); + } + settings->endArray(); + settings->endGroup(); + } + + void PttController::savePttProfiles() { + auto settings = OverlayController::appSettings(); + settings->beginGroup(getSettingsName()); + settings->beginWriteArray("pttProfiles"); + unsigned i = 0; + for (auto& p : pttProfiles) { + settings->setArrayIndex(i); + settings->setValue("profileName", QString::fromStdString(p.profileName)); + settings->setValue("showNotification", p.showNotification); + settings->setValue("leftControllerEnabled", p.leftControllerEnabled); + settings->setValue("rightControllerEnabled", p.rightControllerEnabled); + settings->setValue("digitalButtons_0", p.controllerConfigs[0].digitalButtons); + settings->setValue("triggerMode_0", p.controllerConfigs[0].triggerMode); + settings->setValue("touchpadMode_0", p.controllerConfigs[0].touchpadMode); + settings->setValue("touchPadAreas_0", p.controllerConfigs[0].touchpadAreas); + settings->setValue("digitalButtons_1", p.controllerConfigs[1].digitalButtons); + settings->setValue("triggerMode_1", p.controllerConfigs[1].triggerMode); + settings->setValue("touchpadMode_1", p.controllerConfigs[1].touchpadMode); + settings->setValue("touchPadAreas_1", p.controllerConfigs[1].touchpadAreas); + i++; + } + settings->endArray(); + settings->endGroup(); + } + + + void PttController::reloadPttConfig() { + std::lock_guard lock(eventLoopMutex); + auto settings = OverlayController::appSettings(); + settings->beginGroup(getSettingsName()); + setPttEnabled(settings->value("pttEnabled", false).toBool(), true, false); + setPttLeftControllerEnabled(settings->value("pttLeftControllerEnabled", false).toBool(), true, false); + setPttRightControllerEnabled(settings->value("pttRightControllerEnabled", false).toBool(), true, false); + setPttShowNotification(settings->value("pttShowNotification", true).toBool(), true, false); + m_pttControllerConfigs[0].digitalButtons = settings->value("pttDigitalButtons_0").toList(); + uint64_t buttonMask = 0; + for (auto b : m_pttControllerConfigs[0].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[0].digitalButtonMask = buttonMask; + m_pttControllerConfigs[0].triggerMode = settings->value("pttTriggerMode_0", 0).toUInt(); + m_pttControllerConfigs[0].touchpadMode = settings->value("pttTouchpadMode_0", 0).toUInt(); + m_pttControllerConfigs[0].touchpadAreas = settings->value("pttTouchPadAreas_0", 0).toUInt(); + m_pttControllerConfigs[1].digitalButtons = settings->value("pttDigitalButtons_1").toList(); + buttonMask = 0; + for (auto b : m_pttControllerConfigs[0].digitalButtons) { + buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + } + m_pttControllerConfigs[1].digitalButtonMask = buttonMask; + m_pttControllerConfigs[1].triggerMode = settings->value("pttTriggerMode_1", 0).toUInt(); + m_pttControllerConfigs[1].touchpadMode = settings->value("pttTouchpadMode_1", 0).toUInt(); + m_pttControllerConfigs[1].touchpadAreas = settings->value("pttTouchPadAreas_1", 0).toUInt(); + settings->endGroup(); + } + + void PttController::savePttConfig() { + auto settings = OverlayController::appSettings(); + settings->beginGroup(getSettingsName()); + settings->setValue("pttEnabled", pttEnabled()); + settings->setValue("pttLeftControllerEnabled", pttLeftControllerEnabled()); + settings->setValue("pttRightControllerEnabled", pttRightControllerEnabled()); + settings->setValue("pttShowNotification", pttShowNotification()); + settings->setValue("pttDigitalButtons_0", m_pttControllerConfigs[0].digitalButtons); + settings->setValue("pttTriggerMode_0", m_pttControllerConfigs[0].triggerMode); + settings->setValue("pttTouchpadMode_0", m_pttControllerConfigs[0].touchpadMode); + settings->setValue("pttTouchPadAreas_0", m_pttControllerConfigs[0].touchpadAreas); + settings->setValue("pttDigitalButtons_1", m_pttControllerConfigs[1].digitalButtons); + settings->setValue("pttTriggerMode_1", m_pttControllerConfigs[1].triggerMode); + settings->setValue("pttTouchpadMode_1", m_pttControllerConfigs[1].touchpadMode); + settings->setValue("pttTouchPadAreas_1", m_pttControllerConfigs[1].touchpadAreas); + settings->endGroup(); + } + + void PttController::checkPttStatus() { + static auto handleControllerState = [](const vr::VRControllerState_t& state, PttControllerConfig* config) -> bool { + if (state.ulButtonPressed & config->digitalButtonMask) { + return true; + } + if (config->triggerMode) { + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger) + || state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) { + return true; + } + } + if (config->touchpadMode) { + if (((config->touchpadMode & 1) && (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad))) + || ((config->touchpadMode & 2) && (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)))) { + if (config->touchpadAreas == (PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + PAD_AREA_BOTTOM)) { + return true; + } else { + float x = state.rAxis[0].x; + float y = state.rAxis[0].y; + if (std::abs(x) >= 0.2 || std::abs(y) >= 0.2) { // deadzone in the middle + if (x < 0 && std::abs(y) < -x && (config->touchpadAreas & PAD_AREA_LEFT)) { + return true; + } else if (y > 0 && std::abs(x) < y && (config->touchpadAreas & PAD_AREA_TOP)) { + return true; + } else if (x > 0 && std::abs(y) < x && (config->touchpadAreas & PAD_AREA_RIGHT)) { + return true; + } else if (y < 0 && std::abs(x) < -y && (config->touchpadAreas & PAD_AREA_BOTTOM)) { + return true; + } + } + } + } + } + return false; + }; + if (m_pttEnabled) { + bool newState = false; + if (m_pttLeftControllerEnabled) { + auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); + if (leftId != vr::k_unTrackedDeviceIndexInvalid) { + vr::VRControllerState_t state; + if (vr::VRSystem()->GetControllerState(leftId, &state, sizeof(vr::VRControllerState_t))) { + //logControllerState(state, "Left "); + newState |= handleControllerState(state, m_pttControllerConfigs); + } + } + } + if (m_pttRightControllerEnabled) { + auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); + if (rightId != vr::k_unTrackedDeviceIndexInvalid) { + vr::VRControllerState_t state; + if (vr::VRSystem()->GetControllerState(rightId, &state, sizeof(vr::VRControllerState_t))) { + //logControllerState(state, "Right "); + newState |= handleControllerState(state, m_pttControllerConfigs + 1); + } + } + } + if (newState && !m_pttActive && pttChangeValid()) { + startPtt(); + } else if (!newState && m_pttActive && pttChangeValid()) { + stopPtt(); + } + } + } + + void PttController::startPtt() { + m_pttActive = true; + onPttStart(); + if (m_pttShowNotification && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid) { + vr::VROverlay()->ShowOverlay(getNotificationOverlayHandle()); + } + emit pttActiveChanged(m_pttActive); + } + + void PttController::stopPtt() { + m_pttActive = false; + onPttStop(); + if (m_pttShowNotification && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid) { + vr::VROverlay()->HideOverlay(getNotificationOverlayHandle()); + } + emit pttActiveChanged(m_pttActive); + } + + void PttController::addPttProfile(QString name) { + PttProfile* profile = nullptr; + for (auto& p : pttProfiles) { + if (p.profileName.compare(name.toStdString()) == 0) { + profile = &p; + break; + } + } + if (!profile) { + auto i = pttProfiles.size(); + pttProfiles.emplace_back(); + profile = &pttProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->showNotification = m_pttShowNotification; + profile->leftControllerEnabled = m_pttLeftControllerEnabled; + profile->rightControllerEnabled = m_pttRightControllerEnabled; + profile->controllerConfigs[0].digitalButtons = m_pttControllerConfigs[0].digitalButtons; + profile->controllerConfigs[0].digitalButtonMask = m_pttControllerConfigs[0].digitalButtonMask; + profile->controllerConfigs[0].triggerMode = m_pttControllerConfigs[0].triggerMode; + profile->controllerConfigs[0].touchpadMode = m_pttControllerConfigs[0].touchpadMode; + profile->controllerConfigs[0].touchpadAreas = m_pttControllerConfigs[0].touchpadAreas; + profile->controllerConfigs[1].digitalButtons = m_pttControllerConfigs[1].digitalButtons; + profile->controllerConfigs[1].digitalButtonMask = m_pttControllerConfigs[1].digitalButtonMask; + profile->controllerConfigs[1].triggerMode = m_pttControllerConfigs[1].triggerMode; + profile->controllerConfigs[1].touchpadMode = m_pttControllerConfigs[1].touchpadMode; + profile->controllerConfigs[1].touchpadAreas = m_pttControllerConfigs[1].touchpadAreas; + savePttProfiles(); + OverlayController::appSettings()->sync(); + emit pttProfilesUpdated(); + } + + void PttController::applyPttProfile(unsigned index) { + std::lock_guard lock(eventLoopMutex); + if (index < pttProfiles.size()) { + auto& profile = pttProfiles[index]; + setPttShowNotification(profile.showNotification); + setPttLeftControllerEnabled(profile.leftControllerEnabled); + setPttRightControllerEnabled(profile.rightControllerEnabled); + m_pttControllerConfigs[0].digitalButtons = profile.controllerConfigs[0].digitalButtons; + m_pttControllerConfigs[0].digitalButtonMask = profile.controllerConfigs[0].digitalButtonMask; + m_pttControllerConfigs[0].triggerMode = profile.controllerConfigs[0].triggerMode; + m_pttControllerConfigs[0].touchpadMode = profile.controllerConfigs[0].touchpadMode; + m_pttControllerConfigs[0].touchpadAreas = profile.controllerConfigs[0].touchpadAreas; + m_pttControllerConfigs[1].digitalButtons = profile.controllerConfigs[1].digitalButtons; + m_pttControllerConfigs[1].digitalButtonMask = profile.controllerConfigs[1].digitalButtonMask; + m_pttControllerConfigs[1].triggerMode = profile.controllerConfigs[1].triggerMode; + m_pttControllerConfigs[1].touchpadMode = profile.controllerConfigs[1].touchpadMode; + m_pttControllerConfigs[1].touchpadAreas = profile.controllerConfigs[1].touchpadAreas; + } + } + + void PttController::deletePttProfile(unsigned index) { + if (index < pttProfiles.size()) { + auto pos = pttProfiles.begin() + index; + pttProfiles.erase(pos); + savePttProfiles(); + OverlayController::appSettings()->sync(); + emit pttProfilesUpdated(); + } + } + + QVariantList PttController::pttDigitalButtons(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].digitalButtons; + } + return QVariantList(); + } + + unsigned long PttController::pttDigitalButtonMask(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].digitalButtonMask; + } + return 0; + } + + unsigned PttController::pttTouchpadMode(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].touchpadMode; + } + return 0; + } + + unsigned PttController::pttTriggerMode(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].triggerMode; + } + return 0; + } + + unsigned PttController::pttTouchpadArea(unsigned controller) { + if (controller < 2) { + return m_pttControllerConfigs[controller].touchpadAreas; + } + return 0; + } + + unsigned PttController::getPttProfileCount() { + return (unsigned)pttProfiles.size(); + } + + QString PttController::getPttProfileName(unsigned index) { + if (index < pttProfiles.size()) { + return QString::fromStdString(pttProfiles[index].profileName); + } + return ""; + } + + void PttController::setPttEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttEnabled) { + m_pttEnabled = value; + if (value) { + onPttEnabled(); + } else { + onPttDisabled(); + } + if (notify) { + emit pttEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } + } + + void PttController::setPttShowNotification(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttShowNotification) { + m_pttShowNotification = value; + if (notify) { + emit pttShowNotificationChanged(value); + } + if (save) { + savePttConfig(); + } + } + } + + void PttController::setPttLeftControllerEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttLeftControllerEnabled) { + m_pttLeftControllerEnabled = value; + if (notify) { + emit pttLeftControllerEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } + } + + void PttController::setPttRightControllerEnabled(bool value, bool notify, bool save) { + std::lock_guard lock(eventLoopMutex); + if (value != m_pttRightControllerEnabled) { + m_pttRightControllerEnabled = value; + if (notify) { + emit pttRightControllerEnabledChanged(value); + } + if (save) { + savePttConfig(); + } + } + } + + void logControllerState(const vr::VRControllerState_t& state, const std::string& prefix) { + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_A)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " pressed"; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_A)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " touched"; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " pressed"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " touched"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " pressed"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " touched"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " pressed"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " touched"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " pressed"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " touched"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " pressed"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; + } + if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " touched"; + LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; + } + } + +} // namespace advconfig diff --git a/src/tabcontrollers/PttController.h b/src/tabcontrollers/PttController.h new file mode 100644 index 0000000..8fe0051 --- /dev/null +++ b/src/tabcontrollers/PttController.h @@ -0,0 +1,120 @@ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +class QQuickWindow; +// application namespace +namespace advsettings { + + // forward declaration + class OverlayController; + + enum TouchPadArea { + PAD_AREA_LEFT = (1 << 0), + PAD_AREA_TOP = (1 << 1), + PAD_AREA_RIGHT = (1 << 2), + PAD_AREA_BOTTOM = (1 << 3), + }; + + struct PttControllerConfig { + QVariantList digitalButtons; + uint64_t digitalButtonMask = 0; + unsigned triggerMode = 0; // 0 .. disabled, 1 .. enabled + unsigned touchpadMode = 0; // 0 .. disabled, 1 .. only touch, 2 .. only press, 3 .. both + unsigned touchpadAreas = 0; + }; + + struct PttProfile { + std::string profileName; + + bool showNotification = false; + bool leftControllerEnabled = false; + bool rightControllerEnabled = false; + PttControllerConfig controllerConfigs[2]; + }; + + + class PttController : public QObject { + Q_OBJECT + Q_PROPERTY(bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY pttEnabledChanged) + Q_PROPERTY(bool pttActive READ pttActive NOTIFY pttActiveChanged) + Q_PROPERTY(bool pttShowNotification READ pttShowNotification WRITE setPttShowNotification NOTIFY pttShowNotificationChanged) + Q_PROPERTY(bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged) + Q_PROPERTY(bool pttRightControllerEnabled READ pttRightControllerEnabled WRITE setPttRightControllerEnabled NOTIFY pttRightControllerEnabledChanged) + + private: + bool m_pttEnabled = false; + bool m_pttActive = false; + bool m_pttShowNotification = false; + bool m_pttLeftControllerEnabled = false; + bool m_pttRightControllerEnabled = false; + PttControllerConfig m_pttControllerConfigs[2]; + + std::vector pttProfiles; + + protected: + void checkPttStatus(); + virtual QString getSettingsName() { return "pttSettings"; } + virtual void onPttStart() {}; + virtual void onPttStop() {}; + virtual void onPttEnabled() {}; + virtual void onPttDisabled() {}; + virtual bool pttChangeValid() { return true; } + virtual vr::VROverlayHandle_t getNotificationOverlayHandle() { return vr::k_ulOverlayHandleInvalid; } + std::recursive_mutex eventLoopMutex; + + public: + bool pttEnabled() const; + bool pttActive() const; + bool pttShowNotification() const; + bool pttLeftControllerEnabled() const; + bool pttRightControllerEnabled() const; + + void startPtt(); + void stopPtt(); + + void reloadPttProfiles(); + void reloadPttConfig(); + void savePttProfiles(); + void savePttConfig(); + + + Q_INVOKABLE QVariantList pttDigitalButtons(unsigned controller); + Q_INVOKABLE unsigned long pttDigitalButtonMask(unsigned controller); + Q_INVOKABLE unsigned pttTouchpadMode(unsigned controller); + Q_INVOKABLE unsigned pttTriggerMode(unsigned controller); + Q_INVOKABLE unsigned pttTouchpadArea(unsigned controller); + + Q_INVOKABLE unsigned getPttProfileCount(); + Q_INVOKABLE QString getPttProfileName(unsigned index); + + public slots: + void setPttEnabled(bool value, bool notify = true, bool save = true); + void setPttShowNotification(bool value, bool notify = true, bool save = true); + void setPttLeftControllerEnabled(bool value, bool notify = true, bool save = true); + void setPttRightControllerEnabled(bool value, bool notify = true, bool save = true); + + void setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas); + + void addPttProfile(QString name); + void applyPttProfile(unsigned index); + void deletePttProfile(unsigned index); + + signals: + void pttEnabledChanged(bool value); + void pttActiveChanged(bool value); + void pttShowNotificationChanged(bool value); + void pttLeftControllerEnabledChanged(bool value); + void pttRightControllerEnabledChanged(bool value); + + void pttProfilesUpdated(); + }; + +} // namespace advsettings From 2cd04f906e2eabf8748e8e78998b924e854224ac Mon Sep 17 00:00:00 2001 From: matzman666 Date: Mon, 30 Jan 2017 20:50:55 +0100 Subject: [PATCH 3/3] Some GUI layout corrections, some tidying up, and it's better to make PttController::getSettingsName() pure virtual. --- bin/win64/res/qml/PlayspacePage.qml | 38 ++++++++------------ installer/uninstallFiles.list | 1 + src/tabcontrollers/AudioTabController.h | 6 ---- src/tabcontrollers/MoveCenterTabController.h | 6 ---- src/tabcontrollers/PttController.h | 3 +- 5 files changed, 17 insertions(+), 37 deletions(-) diff --git a/bin/win64/res/qml/PlayspacePage.qml b/bin/win64/res/qml/PlayspacePage.qml index 706b116..6111a3d 100644 --- a/bin/win64/res/qml/PlayspacePage.qml +++ b/bin/win64/res/qml/PlayspacePage.qml @@ -339,31 +339,23 @@ MyStackViewPage { } } + MyToggleButton { + id: playspaceAdjustChaperoneToggle + text: "Adjust Chaperone" + Layout.preferredWidth: 270 + onCheckedChanged: { + MoveCenterTabController.adjustChaperone = this.checked + } + } + Item { Layout.fillHeight: true; Layout.fillWidth: true} - ColumnLayout { - Layout.fillWidth: true - - RowLayout { - MyToggleButton { - id: playspaceAdjustChaperoneToggle - text: "Adjust Chaperone" - Layout.preferredWidth: 250 - onCheckedChanged: { - MoveCenterTabController.adjustChaperone = this.checked - } - } - - Item { Layout.fillWidth: true} - - MyPushButton { - id: playspaceResetButton - Layout.preferredWidth: 250 - text: "Reset" - onClicked: { - MoveCenterTabController.reset() - } - } + MyPushButton { + id: playspaceResetButton + Layout.preferredWidth: 250 + text: "Reset" + onClicked: { + MoveCenterTabController.reset() } } diff --git a/installer/uninstallFiles.list b/installer/uninstallFiles.list index 6ea3392..4bd3f10 100644 --- a/installer/uninstallFiles.list +++ b/installer/uninstallFiles.list @@ -405,6 +405,7 @@ Delete $INSTDIR\res\qml\MyText.qml Delete $INSTDIR\res\qml\MyTextField.qml Delete $INSTDIR\res\qml\MyToggleButton.qml Delete $INSTDIR\res\qml\PlayspacePage.qml +Delete $INSTDIR\res\qml\PttControllerConfigDialog.qml Delete $INSTDIR\res\qml\ptt_notification.png Delete $INSTDIR\res\qml\ptt_notification.svg Delete $INSTDIR\res\qml\qmldir diff --git a/src/tabcontrollers/AudioTabController.h b/src/tabcontrollers/AudioTabController.h index 4469682..6eab364 100644 --- a/src/tabcontrollers/AudioTabController.h +++ b/src/tabcontrollers/AudioTabController.h @@ -3,13 +3,7 @@ #include "AudioManager.h" #include "PttController.h" -#include -#include -#include -#include #include -#include -#include class QQuickWindow; // application namespace diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 3d62f23..6a1c67e 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -1,13 +1,7 @@ #pragma once -#include "AudioTabController.h" #include "PttController.h" -#include -#include -#include -#include -#include class QQuickWindow; // application namespace diff --git a/src/tabcontrollers/PttController.h b/src/tabcontrollers/PttController.h index 8fe0051..0079a74 100644 --- a/src/tabcontrollers/PttController.h +++ b/src/tabcontrollers/PttController.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -61,7 +60,7 @@ namespace advsettings { protected: void checkPttStatus(); - virtual QString getSettingsName() { return "pttSettings"; } + virtual QString getSettingsName() = 0; virtual void onPttStart() {}; virtual void onPttStop() {}; virtual void onPttEnabled() {};