From 7179023cdb99f3fa5262e41c8a159a2b6642dd1e Mon Sep 17 00:00:00 2001 From: matzman666 Date: Wed, 21 Dec 2016 20:08:31 +0100 Subject: [PATCH] Revive controller settings can be saved into profiles. --- bin/win64/res/qml/RevivePage.qml | 156 ++++++++++++++++++++- src/tabcontrollers/ReviveTabController.cpp | 117 ++++++++++++++++ src/tabcontrollers/ReviveTabController.h | 28 ++++ 3 files changed, 296 insertions(+), 5 deletions(-) diff --git a/bin/win64/res/qml/RevivePage.qml b/bin/win64/res/qml/RevivePage.qml index db86b1b..95a7901 100644 --- a/bin/win64/res/qml/RevivePage.qml +++ b/bin/win64/res/qml/RevivePage.qml @@ -8,7 +8,70 @@ MyStackViewPage { headerText: "Revive Settings" content: ColumnLayout { - spacing: 32 + spacing: 12 + + + MyDialogOkPopup { + id: reviveMessageDialog + function showMessage(title, text) { + dialogTitle = title + dialogText = text + open() + } + } + + MyDialogOkCancelPopup { + id: reviveDeleteProfileDialog + property int profileIndex: -1 + dialogTitle: "Delete Profile" + dialogText: "Do you really want to delete this profile?" + onClosed: { + if (okClicked) { + ReviveTabController.deleteControllerProfile(profileIndex) + } + } + } + + MyDialogOkCancelPopup { + id: reviveNewProfileDialog + dialogTitle: "Create New Profile" + dialogContentItem: ColumnLayout { + RowLayout { + Layout.topMargin: 16 + Layout.leftMargin: 16 + Layout.rightMargin: 16 + MyText { + text: "Name: " + } + MyTextField { + id: reviveNewProfileName + keyBoardUID: 290 + color: "#cccccc" + text: "" + Layout.fillWidth: true + font.pointSize: 20 + function onInputEvent(input) { + reviveNewProfileName.text = input + } + } + } + } + onClosed: { + if (okClicked) { + if (reviveNewProfileName.text == "") { + reviveMessageDialog.showMessage("Create New Profile", "ERROR: Empty profile name.") + } else { + ReviveTabController.addControllerProfile(reviveNewProfileName.text) + } + + } + } + function openPopup() { + reviveNewProfileName.text = "" + open() + } + } + RowLayout { MyToggleButton { @@ -76,6 +139,75 @@ MyStackViewPage { } } + ColumnLayout { + spacing: 8 + Layout.topMargin: 12 + Layout.bottomMargin: 8 + RowLayout { + spacing: 8 + + MyText { + Layout.preferredWidth: 347 + text: "Controller Profile:" + } + + MyComboBox { + id: reviveControllerProfileComboBox + Layout.maximumWidth: 557 + Layout.minimumWidth: 557 + Layout.preferredWidth: 557 + Layout.fillWidth: true + model: [""] + onCurrentIndexChanged: { + if (currentIndex > 0) { + reviveControllerApplyProfileButton.enabled = true + reviveControllerDeleteProfileButton.enabled = true + } else { + reviveControllerApplyProfileButton.enabled = false + reviveControllerDeleteProfileButton.enabled = false + } + } + } + + MyPushButton { + id: reviveControllerApplyProfileButton + enabled: false + Layout.preferredWidth: 200 + text: "Apply" + onClicked: { + if (reviveControllerProfileComboBox.currentIndex > 0) { + ReviveTabController.applyControllerProfile(reviveControllerProfileComboBox.currentIndex - 1) + reviveControllerProfileComboBox.currentIndex = 0 + } + } + } + } + RowLayout { + spacing: 8 + Item { + Layout.fillWidth: true + } + MyPushButton { + id: reviveControllerDeleteProfileButton + enabled: false + Layout.preferredWidth: 200 + text: "Delete Profile" + onClicked: { + if (reviveControllerProfileComboBox.currentIndex > 0) { + reviveDeleteProfileDialog.profileIndex = reviveControllerProfileComboBox.currentIndex - 1 + reviveDeleteProfileDialog.open() + } + } + } + MyPushButton { + Layout.preferredWidth: 200 + text: "New Profile" + onClicked: { + reviveNewProfileDialog.openPopup() + } + } + } + } RowLayout { MyText { @@ -791,6 +923,10 @@ MyStackViewPage { } + Item { + Layout.fillHeight: true + } + RowLayout { MyPushButton { id: revivePersonalInfoButton @@ -815,10 +951,6 @@ MyStackViewPage { } } - Item { - Layout.fillHeight: true - } - Component.onCompleted: { pixelsPerDisplayPixelToggle.checked = ReviveTabController.pixelsPerDisplayPixelOverrideEnabled var v = ReviveTabController.pixelsPerDisplayPixelOverride.toFixed(1) @@ -841,6 +973,7 @@ MyStackViewPage { touchXInputField.text = ReviveTabController.touchX.toFixed(3) touchYInputField.text = ReviveTabController.touchY.toFixed(3) touchZInputField.text = ReviveTabController.touchZ.toFixed(3) + reloadControllerProfiles() } Connections { @@ -884,6 +1017,19 @@ MyStackViewPage { onTouchZChanged : { touchZInputField.text = ReviveTabController.touchZ.toFixed(3) } + onControllerProfilesUpdated: { + reloadControllerProfiles() + } } } + + function reloadControllerProfiles() { + var profiles = [""] + var profileCount = ReviveTabController.getControllerProfileCount() + for (var i = 0; i < profileCount; i++) { + profiles.push(ReviveTabController.getControllerProfileName(i)) + } + reviveControllerProfileComboBox.currentIndex = 0 + reviveControllerProfileComboBox.model = profiles + } } diff --git a/src/tabcontrollers/ReviveTabController.cpp b/src/tabcontrollers/ReviveTabController.cpp index 910a349..d4c0794 100644 --- a/src/tabcontrollers/ReviveTabController.cpp +++ b/src/tabcontrollers/ReviveTabController.cpp @@ -146,6 +146,8 @@ namespace advsettings { m_piGender = 0; } } + + reloadControllerProfiles(); } } @@ -654,4 +656,119 @@ namespace advsettings { return hmdHeight; } + + void ReviveTabController::reloadControllerProfiles() { + controllerProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup("reviveSettings"); + auto profileCount = settings->beginReadArray("controllerProfiles"); + for (int i = 0; i < profileCount; i++) { + settings->setArrayIndex(i); + controllerProfiles.emplace_back(); + auto& entry = controllerProfiles[i]; + entry.profileName = settings->value("profileName").toString().toStdString(); + entry.gripButtonMode = settings->value("gripButtonMode", 0).toInt(); + entry.thumbDeadzone = settings->value("thumbDeadzone", 0.3f).toFloat(); + entry.thumbRange = settings->value("thumbRange", 2.0f).toFloat(); + entry.touchPitch = settings->value("touchPitch", -28.0f).toFloat(); + entry.touchYaw = settings->value("touchYaw", 0.0f).toFloat(); + entry.touchRoll = settings->value("touchRoll", -14.0f).toFloat(); + entry.touchX = settings->value("touchX", 0.016f).toFloat(); + entry.touchY = settings->value("touchY", 0.0f).toFloat(); + entry.touchZ = settings->value("touchZ", 0.016f).toFloat(); + } + settings->endArray(); + settings->endGroup(); + } + + + void ReviveTabController::saveControllerProfiles() { + auto settings = OverlayController::appSettings(); + settings->beginGroup("reviveSettings"); + settings->beginWriteArray("controllerProfiles"); + unsigned i = 0; + for (auto& p : controllerProfiles) { + settings->setArrayIndex(i); + settings->setValue("profileName", QString::fromStdString(p.profileName)); + settings->setValue("gripButtonMode", p.gripButtonMode); + settings->setValue("thumbDeadzone", p.thumbDeadzone); + settings->setValue("thumbRange", p.thumbRange); + settings->setValue("touchPitch", p.touchPitch); + settings->setValue("touchYaw", p.touchYaw); + settings->setValue("touchRoll", p.touchRoll); + settings->setValue("touchX", p.touchX); + settings->setValue("touchY", p.touchY); + settings->setValue("touchZ", p.touchZ); + i++; + } + settings->endArray(); + settings->endGroup(); + } + + Q_INVOKABLE unsigned ReviveTabController::getControllerProfileCount() { + return (unsigned)controllerProfiles.size(); + } + + Q_INVOKABLE QString ReviveTabController::getControllerProfileName(unsigned index) { + if (index >= controllerProfiles.size()) { + return QString(); + } else { + return QString::fromStdString(controllerProfiles[index].profileName); + } + } + + void ReviveTabController::addControllerProfile(QString name) { + vr::EVRSettingsError vrSettingsError; + ReviveControllerProfile* profile = nullptr; + for (auto& p : controllerProfiles) { + if (p.profileName.compare(name.toStdString()) == 0) { + profile = &p; + break; + } + } + if (!profile) { + auto i = controllerProfiles.size(); + controllerProfiles.emplace_back(); + profile = &controllerProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->gripButtonMode = gripButtonMode(); + profile->thumbDeadzone = thumbDeadzone(); + profile->thumbRange = thumbRange(); + profile->touchPitch = touchPitch(); + profile->touchYaw = touchYaw(); + profile->touchRoll = touchRoll(); + profile->touchX = touchX(); + profile->touchY = touchY(); + profile->touchZ = touchZ(); + saveControllerProfiles(); + OverlayController::appSettings()->sync(); + emit controllerProfilesUpdated(); + } + + void ReviveTabController::applyControllerProfile(unsigned index) { + if (index < controllerProfiles.size()) { + auto& profile = controllerProfiles[index]; + setGripButtonMode(profile.gripButtonMode); + setThumbDeadzone(profile.thumbDeadzone); + setThumbRange(profile.thumbRange); + setTouchPitch(profile.touchPitch); + setTouchYaw(profile.touchYaw); + setTouchRoll(profile.touchRoll); + setTouchX(profile.touchX); + setTouchY(profile.touchY); + setTouchZ(profile.touchZ); + } + } + + void ReviveTabController::deleteControllerProfile(unsigned index) { + if (index < controllerProfiles.size()) { + auto pos = controllerProfiles.begin() + index; + controllerProfiles.erase(pos); + saveControllerProfiles(); + OverlayController::appSettings()->sync(); + emit controllerProfilesUpdated(); + } + } + } // namespace advconfig diff --git a/src/tabcontrollers/ReviveTabController.h b/src/tabcontrollers/ReviveTabController.h index d5e2f44..9ffbc29 100644 --- a/src/tabcontrollers/ReviveTabController.h +++ b/src/tabcontrollers/ReviveTabController.h @@ -12,6 +12,20 @@ namespace advsettings { class OverlayController; + struct ReviveControllerProfile { + std::string profileName; + int gripButtonMode; + float thumbDeadzone; + float thumbRange; + float touchPitch; + float touchYaw; + float touchRoll; + float touchX; + float touchY; + float touchZ; + }; + + class ReviveTabController : public QObject { Q_OBJECT Q_PROPERTY(int isOverlayInstalled READ isOverlayInstalled NOTIFY isOverlayInstalledChanged) @@ -56,6 +70,8 @@ namespace advsettings { unsigned settingsUpdateCounter = 0; + std::vector controllerProfiles; + public: void initStage1(); void initStage2(OverlayController* parent, QQuickWindow* widget); @@ -87,6 +103,12 @@ namespace advsettings { Q_INVOKABLE float getCurrentHMDHeight(); + void reloadControllerProfiles(); + void saveControllerProfiles(); + + Q_INVOKABLE unsigned getControllerProfileCount(); + Q_INVOKABLE QString getControllerProfileName(unsigned index); + public slots: void setGripButtonMode(int value, bool notify = true); @@ -109,6 +131,10 @@ namespace advsettings { void setPiName(const QString& value, bool notify = true); void setPiGender(int value, bool notify = true); // 0 .. Unknown, 1 .. Male, 2 .. Female + void addControllerProfile(QString name); + void applyControllerProfile(unsigned index); + void deleteControllerProfile(unsigned index); + void reset(); signals: @@ -134,6 +160,8 @@ namespace advsettings { void piUsernameChanged(const QString& value); void piNameChanged(const QString& value); void piGenderChanged(int value); + + void controllerProfilesUpdated(); }; } // namespace advsettings