diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj index 8c2b354..0ba8142 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj +++ b/GlosSIConfig/GlosSIConfig.vcxproj @@ -143,6 +143,7 @@ + diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters index fca686f..f7483fd 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj.filters +++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters @@ -77,6 +77,9 @@ qml + + qml + diff --git a/GlosSIConfig/Resource.rc b/GlosSIConfig/Resource.rc index f8b7337..9f6cc17 100644 --- a/GlosSIConfig/Resource.rc +++ b/GlosSIConfig/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,9,1029000008904 - PRODUCTVERSION 0,0,9,1029000008904 + FILEVERSION 0,0,9,1037005000102 + PRODUCTVERSION 0,0,9,1037005000102 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - Config" - VALUE "FileVersion", "0.0.9.1-29-gefe89c4" + VALUE "FileVersion", "0.0.9.1-37-g5ebe102" VALUE "InternalName", "GlosSIConfig" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.9.1-29-gefe89c4" + VALUE "ProductVersion", "0.0.9.1-37-g5ebe102" END END BLOCK "VarFileInfo" diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index 0f0ca26..63589a5 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -305,6 +305,88 @@ void UIModel::updateCheck() connect(manager, &QNetworkAccessManager::finished, this, &UIModel::onAvailFilesResponse); } +QVariantMap UIModel::getDefaultConf() const +{ + auto path = std::filesystem::temp_directory_path().parent_path().parent_path().parent_path(); + + path /= "Roaming"; + path /= "GlosSI"; + path /= "default.json"; + + if (std::filesystem::exists(path)) { + QFile file(QString::fromStdWString(path)); + if (file.open(QIODevice::ReadOnly)) { + const auto data = file.readAll(); + file.close(); + return QJsonDocument::fromJson(data).object().toVariantMap(); + } + } + + QJsonObject obj = { + {"icon", QJsonValue::Null}, + {"name", QJsonValue::Null}, + {"version", 1}, + {"extendedLogging", false}, + {"snapshotNotify", false}, + { + "controller", + QJsonObject{ + {"maxControllers", 1}, + {"emulateDS4", false}, + {"allowDesktopConfig", false} + } + }, + { + "devices", + QJsonObject{ + {"hideDevices", true}, + {"realDeviceIds", false}, + } + }, + { + "launch", + QJsonObject{ + {"closeOnExit", true}, + {"launch", false}, + {"launchAppArgs", QJsonValue::Null}, + {"launchPath", QJsonValue::Null}, + {"waitForChildProcs", true}, + } + }, + { + "window", + QJsonObject{ + {"disableOverlay", false}, + {"maxFps", QJsonValue::Null}, + {"scale", QJsonValue::Null}, + {"windowMode", false}, + } + }, + }; + + saveDefaultConf(obj.toVariantMap()); + return getDefaultConf(); + +} + +void UIModel::saveDefaultConf(QVariantMap conf) const +{ + auto path = std::filesystem::temp_directory_path().parent_path().parent_path().parent_path(); + + path /= "Roaming"; + path /= "GlosSI"; + path /= "default.json"; + + QFile file(path); + if (!file.open(QIODevice::Text | QIODevice::ReadWrite)) { + qDebug() << "Couldn't open file for writing: " << path; + return; + } + + file.write(QString(QJsonDocument::fromVariant(conf).toJson(QJsonDocument::Indented)).toStdString().data()); + file.close(); +} + #ifdef _WIN32 QVariantList UIModel::uwpApps() { return UWPFetch::UWPAppList(); } #endif @@ -391,6 +473,12 @@ void UIModel::onAvailFilesResponse(QNetworkReply* reply) QJsonObject json = QJsonDocument::fromJson(respStr).object(); + const auto defaultConf = getDefaultConf(); + bool snapshotNotify = + defaultConf.contains("snapshotNotify") + ? defaultConf["snapshotNotify"].toJsonValue().toBool() + : false; + struct VersionInfo { int major; int minor; @@ -401,8 +489,9 @@ void UIModel::onAvailFilesResponse(QNetworkReply* reply) std::vector> new_versions; for (const auto& info : - json.keys() | std::ranges::views::filter([this, &json](const auto& key) { - return notify_on_snapshots_ ? true : json[key].toObject().value("type") == "release"; + json.keys() | std::ranges::views::filter([this, &json, snapshotNotify](const auto& key) { + return notify_on_snapshots_ ? true + : json[key].toObject().value("type") == (snapshotNotify ? "snapshot" : "release"); }) | std::ranges::views::transform([&json](const auto& key) -> std::pair { const auto versionString = json[key].toObject().value("version").toString(); const auto cleanVersion = versionString.split("-")[0]; diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h index 3ac7782..8943d27 100644 --- a/GlosSIConfig/UIModel.h +++ b/GlosSIConfig/UIModel.h @@ -53,6 +53,10 @@ class UIModel : public QObject { Q_INVOKABLE bool restartSteam(); Q_INVOKABLE void updateCheck(); + + Q_INVOKABLE QVariantMap getDefaultConf() const; + Q_INVOKABLE void saveDefaultConf(QVariantMap conf) const; + #ifdef _WIN32 Q_INVOKABLE QVariantList uwpApps(); #endif diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc index 4c331a8..d3945e1 100644 --- a/GlosSIConfig/qml.qrc +++ b/GlosSIConfig/qml.qrc @@ -20,5 +20,7 @@ svg/expand_more_white_24dp.svg GlosSI_Logo_512.png qml/AdvancedTargetSettings.qml + qml/GlobalConf.qml + svg/settings_fill_white_24dp.svg diff --git a/GlosSIConfig/qml/AdvancedTargetSettings.qml b/GlosSIConfig/qml/AdvancedTargetSettings.qml index d2c9e91..5d02b96 100644 --- a/GlosSIConfig/qml/AdvancedTargetSettings.qml +++ b/GlosSIConfig/qml/AdvancedTargetSettings.qml @@ -25,12 +25,22 @@ CollapsiblePane { bgOpacity: 0.97 title: qsTr("Advanced ⚙️") + property string subTitle: "" + property var shortcutInfo: ({}) content: Column { spacing: 16 + Label { + id: subTitleLabel + width: parent.width + font.pixelSize: 16 + text: subTitle + height: text == "" ? 0 : 24 + } + RPane { width: parent.width radius: 4 @@ -41,6 +51,7 @@ CollapsiblePane { id: advancedLaunchCol spacing: 4 height: advancedLaunchedRow.height + Row { id: advancedLaunchedRow spacing: 32 diff --git a/GlosSIConfig/qml/GlobalConf.qml b/GlosSIConfig/qml/GlobalConf.qml new file mode 100644 index 0000000..7d3a24e --- /dev/null +++ b/GlosSIConfig/qml/GlobalConf.qml @@ -0,0 +1,130 @@ +/* +Copyright 2021-2022 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import QtQuick 6.2 +import QtQuick.Controls 6.2 +import QtQuick.Layouts 6.2 +import QtQuick.Controls.Material 6.2 +import QtQuick.Dialogs 6.2 + + +Item { + id: globalConfContent + anchors.fill: parent + + signal cancel() + signal done() + + property var config: ({}) + + Component.onCompleted: function() { + config = uiModel.getDefaultConf() + } + + Flickable { + id: flickable + anchors.margins: 0 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + clip: true + ScrollBar.vertical: ScrollBar { + + } + contentWidth: parent.width + contentHeight: confColumn.height + flickableDirection: Flickable.VerticalFlick + + Column { + id: confColumn + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 32 + anchors.rightMargin: 32 + spacing: 4 + + Item { + width: 1 + height: 32 + } + + RPane { + width: parent.width + radius: 4 + Material.elevation: 32 + bgOpacity: 0.97 + Column { + width: parent.width + height: parent.height + spacing: 4 + Row { + spacing: 32 + width: parent.width + CheckBox { + id: launchApp + text: qsTr("Notify me about Snapshots") + checked: config ? config.snapshotNotify : false + onCheckedChanged: function() { + config.snapshotNotify = checked + } + } + } + } + } + + Item { + width: 1 + height: 4 + } + + AdvancedTargetSettings { + id: advancedTargetSettings + shortcutInfo: config + title: qsTr("Advanced default target settings ⚙️") + subTitle: qsTr( + "Default settings when creating new shortcuts\n" + + "as well as settings applied when launching GlosSITarget without config") + } + + Item { + width: 1 + height: 32 + } + } + } + + Row { + spacing: 8 + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.margins: 24 + anchors.bottomMargin: 16 + Button { + text: qsTr("Cancel") + onClicked: function() { + cancel() + } + } + Button { + text: qsTr("💾 Save") + highlighted: true + onClicked: function() { + uiModel.saveDefaultConf(config) + done() + } + } + } +} \ No newline at end of file diff --git a/GlosSIConfig/qml/ShortcutProps.qml b/GlosSIConfig/qml/ShortcutProps.qml index 7774558..985d2c5 100644 --- a/GlosSIConfig/qml/ShortcutProps.qml +++ b/GlosSIConfig/qml/ShortcutProps.qml @@ -32,34 +32,7 @@ Item { property var shortcutInfo: ({}) function resetInfo() { - shortcutInfo = ({ - "controller": { - "maxControllers": 1, - "emulateDS4": false, - "allowDesktopConfig": false - }, - "devices": { - "hideDevices": true, - "realDeviceIds": false - }, - "icon": null, - "launch": { - "closeOnExit": true, - "launch": false, - "launchAppArgs": null, - "launchPath": null, - "waitForChildProcs": true - }, - "name": null, - "version": 1, - "window": { - "disableOverlay": false, - "maxFps": null, - "scale": null, - "windowMode": false - }, - "extendedLogging": false - }) + shortcutInfo = uiModel.getDefaultConf() } Component.onCompleted: function() { @@ -267,6 +240,7 @@ Item { AdvancedTargetSettings { id: advancedTargetSettings + shortcutInfo: shortcutInfo } Item { diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml index 7c32f59..9daccc0 100644 --- a/GlosSIConfig/qml/main.qml +++ b/GlosSIConfig/qml/main.qml @@ -234,24 +234,46 @@ Window { windowContent.editedIndex = index; } } - RoundButton { - id: addBtn + Column { + spacing: 8 anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 24 - width: 64 - height: 64 - text: "+" - contentItem: Label { - anchors.centerIn: parent - text: addBtn.text - font.pixelSize: 32 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight + RoundButton { + id: optionsBtn + width: 64 + height: 64 + text: "" + contentItem: Item { + Image { + anchors.centerIn: parent + source: "qrc:/svg/settings_fill_white_24dp.svg" + width: 24 + height: 24 + } + } + highlighted: true + onClicked: function() { + globalConf.opacity = 1; + homeContent.opacity = 0; + } + } + RoundButton { + id: addBtn + width: 64 + height: 64 + text: "+" + contentItem: Label { + anchors.centerIn: parent + text: addBtn.text + font.pixelSize: 32 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + highlighted: true + onClicked: selectTypeDialog.open() } - highlighted: true - onClicked: selectTypeDialog.open() } } @@ -299,6 +321,46 @@ Window { } } + Item { + id: globalConf + height: parent.height + width: parent.width + opacity: 0 + property real animMarg: opacity == 0 ? parent.height : 0 + y: animMarg + visible: opacity === 0 ? false : true + Behavior on opacity { + ParallelAnimation { + NumberAnimation { + duration: 300 + property: "opacity" + easing.type: opacity === 0 ? Easing.OutQuad : Easing.InOutQuad + } + PropertyAnimation { + duration: 300 + target: globalConf + property: "animMarg"; + from: globalConf.animMarg + to: globalConf.animMarg > 0 ? 0 : globalConf.parent.height; + easing.type: opacity === 0 ? Easing.OutQuad : Easing.InOutQuad + } + } + } + GlobalConf { + id: glConf + anchors.fill: parent + onCancel: function() { + globalConf.opacity = 0; + homeContent.opacity = 1; + } + onDone: function() { + globalConf.opacity = 0; + homeContent.opacity = 1; + } + } + } + + Label { id: versionInfo anchors.bottom: parent.bottom diff --git a/GlosSIConfig/svg/settings_fill_white_24dp.svg b/GlosSIConfig/svg/settings_fill_white_24dp.svg new file mode 100644 index 0000000..2995c75 --- /dev/null +++ b/GlosSIConfig/svg/settings_fill_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file