diff --git a/.gitignore b/.gitignore
index 8553f87..96f406a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -370,3 +370,5 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
.visuallint
+GlosSIConfig/steamgrid_api_keys.h
+steamgrid.zip
diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj
index b649a7b..a79c58d 100644
--- a/GlosSIConfig/GlosSIConfig.vcxproj
+++ b/GlosSIConfig/GlosSIConfig.vcxproj
@@ -145,6 +145,7 @@
+
@@ -163,6 +164,7 @@
+
diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters
index 08d81b8..9811199 100644
--- a/GlosSIConfig/GlosSIConfig.vcxproj.filters
+++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters
@@ -83,6 +83,9 @@
qml
+
+ qml
+
@@ -102,6 +105,9 @@
Header Files
+
+ Header Files
+
diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp
index 873304c..c23a67b 100644
--- a/GlosSIConfig/UIModel.cpp
+++ b/GlosSIConfig/UIModel.cpp
@@ -33,6 +33,7 @@ limitations under the License.
#endif
#include "../version.hpp"
+#include "steamgrid_api_keys.h"
UIModel::UIModel() : QObject(nullptr)
{
@@ -479,6 +480,17 @@ QVariantList UIModel::egsGamesList() const
return {{"InstallLocation", "Error"}};
}
+void UIModel::loadSteamGridImages()
+{
+ std::filesystem::path path = QCoreApplication::applicationDirPath().toStdWString();
+ path /= "steamgrid.exe";
+
+ steamgrid_proc_.setProgram(path.string().c_str());
+ steamgrid_proc_.setArguments({"-nonsteamonly", "--onlymissingartwork", "--steamgriddb", steamgridb_key});
+ connect(&steamgrid_proc_, &QProcess::readyReadStandardOutput, this, &UIModel::onSteamGridReadReady);
+ steamgrid_proc_.start();
+ steamgrid_proc_.write("\n");
+}
QString UIModel::getGridImagePath(QVariant shortcut) const
{
@@ -497,9 +509,9 @@ QString UIModel::getGridImagePath(QVariant shortcut) const
}
const std::vector extensions = {".png", ".jpg"};
for (const auto& entry : std::filesystem::directory_iterator(grid_dir)) {
- if (entry.is_regular_file()
- && std::ranges::find(extensions, entry.path().extension().string()) != extensions.end()
- && entry.path().filename().string().find(std::to_string(app_id)) != std::string::npos) {
+ if (entry.is_regular_file() &&
+ std::ranges::find(extensions, entry.path().extension().string()) != extensions.end() &&
+ entry.path().filename().string().find(std::to_string(app_id)) != std::string::npos) {
return QString::fromStdString(entry.path().string());
}
}
@@ -586,6 +598,8 @@ void UIModel::setAcrylicEffect(bool has_acrylic_affect)
emit acrylicChanged();
}
+QStringList UIModel::getSteamgridOutput() const { return steamgrid_output_; }
+
void UIModel::onAvailFilesResponse(QNetworkReply* reply)
{
@@ -658,6 +672,12 @@ void UIModel::onAvailFilesResponse(QNetworkReply* reply)
}
}
+void UIModel::onSteamGridReadReady()
+{
+ steamgrid_output_.push_back(QString::fromLocal8Bit(steamgrid_proc_.readAllStandardOutput()));
+ emit steamgridOutputChanged();
+}
+
void UIModel::writeTarget(const QJsonObject& json, const QString& name) const
{
auto path = config_path_;
diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h
index fa4c944..b3cb982 100644
--- a/GlosSIConfig/UIModel.h
+++ b/GlosSIConfig/UIModel.h
@@ -17,6 +17,7 @@ limitations under the License.
#include
#include
#include
+#include
#include
#include
@@ -37,6 +38,8 @@ class UIModel : public QObject {
Q_PROPERTY(QString versionString READ getVersionString CONSTANT)
Q_PROPERTY(QString newVersionName READ getNewVersionName NOTIFY newVersionAvailable)
+ Q_PROPERTY(QStringList steamgridOutput READ getSteamgridOutput NOTIFY steamgridOutputChanged)
+
public:
UIModel();
@@ -65,6 +68,7 @@ class UIModel : public QObject {
#endif
Q_INVOKABLE QVariantList egsGamesList() const;
+ Q_INVOKABLE void loadSteamGridImages();
Q_INVOKABLE QString getGridImagePath(QVariant shortcut) const;
[[nodiscard]] bool writeShortcutsVDF(const std::wstring& mode, const std::wstring& name,
@@ -75,13 +79,17 @@ class UIModel : public QObject {
[[nodiscard]] bool hasAcrylicEffect() const;
void setAcrylicEffect(bool has_acrylic_affect);
+ QStringList getSteamgridOutput() const;
+
signals:
void acrylicChanged();
void targetListChanged();
void newVersionAvailable();
+ void steamgridOutputChanged();
public slots:
void onAvailFilesResponse(QNetworkReply* reply);
+ void onSteamGridReadReady();
private:
#ifdef _WIN32
@@ -107,6 +115,9 @@ class UIModel : public QObject {
QString new_version_name_;
bool notify_on_snapshots_ = false;
+ QProcess steamgrid_proc_;
+ QStringList steamgrid_output_;
+
std::vector shortcuts_vdf_;
void writeTarget(const QJsonObject& json, const QString& name) const;
diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc
index 64cc986..1d07c92 100644
--- a/GlosSIConfig/qml.qrc
+++ b/GlosSIConfig/qml.qrc
@@ -24,5 +24,6 @@
svg/settings_fill_white_24dp.svg
qml/EGSSelectDialog.qml
svg/add_photo_alternate_white_24dp.svg
+ qml/SteamGridDialog.qml
diff --git a/GlosSIConfig/qml/SteamGridDialog.qml b/GlosSIConfig/qml/SteamGridDialog.qml
new file mode 100644
index 0000000..e7d3b61
--- /dev/null
+++ b/GlosSIConfig/qml/SteamGridDialog.qml
@@ -0,0 +1,156 @@
+/*
+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
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Controls.Material
+
+Dialog {
+ id: gridDialog
+ anchors.centerIn: parent
+
+ signal confirmed(var param)
+
+ visible: false
+ modal: true
+ dim: true
+ parent: Overlay.overlay
+ Overlay.modal: Rectangle {
+ color: Qt.rgba(0,0,0,0.4)
+ opacity: backdropOpacity
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 300
+ }
+ }
+ }
+ property real backdropOpacity: 1.0
+
+ property bool loading: true
+
+
+ onOpened: function() {
+ loading = true;
+ uiModel.loadSteamGridImages();
+ }
+
+ onClosed: function() {
+ }
+
+ enter: Transition {
+ NumberAnimation{target: content; property: "y"; from: parent.height; to: 16; duration: 300; easing.type: Easing.OutQuad }
+ NumberAnimation{target: background; property: "y"; from: parent.height; to: 0; duration: 300; easing.type: Easing.OutQuad }
+ NumberAnimation{target: gridDialog; property: "backdropOpacity"; from: 0; to: 1; duration: 300; easing.type: Easing.OutQuad }
+ }
+
+ exit: Transition {
+ NumberAnimation{target: content; property: "y"; from: 16; to: parent.height; duration: 300; easing.type: Easing.InQuad }
+ NumberAnimation{target: background; property: "y"; from: 0; to: parent.height; duration: 300; easing.type: Easing.InQuad }
+ NumberAnimation{target: gridDialog; property: "backdropOpacity"; from: 1; to: 0; duration: 300; easing.type: Easing.InQuad }
+ }
+
+ background: RPane {
+ id: background
+ radius: 4
+ Material.elevation: 64
+ bgOpacity: 0.97
+ }
+ contentItem: Item {
+ id: content
+ implicitWidth: listview.width
+ implicitHeight: listview.height + titlelabel.height + 16 + 64
+ clip: true
+ Label {
+ id: titlelabel
+ text: qsTr("Loading Grid images...")
+ font.pixelSize: 24
+ font.bold: true
+ }
+
+ BusyIndicator {
+ id: busyIndicator
+ running: visible
+ anchors.top: titlelabel.bottom
+ anchors.topMargin: 8
+ anchors.horizontalCenter: parent.horizontalCenter
+ opacity: loading ? 1 : 0
+ height: loading ? 72 : 0
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 350
+ easing.type: Easing.InOutQuad
+ }
+ }
+ visible: loading
+ }
+
+ ListView {
+ anchors.top: busyIndicator.bottom
+ anchors.topMargin: 16
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 16
+ id: listview
+ width: window.width * 0.45
+ height: window.height * 0.66
+ spacing: 0
+ clip: true
+ model: uiModel.steamgridOutput
+ ScrollBar.vertical: ScrollBar {
+ }
+ onCountChanged: {
+ listview.positionViewAtIndex(listview.count - 1, ListView.Visible)
+ loading = !listview.model[listview.count - 1].includes("Press enter")
+ }
+
+ Behavior on opacity {
+ ParallelAnimation {
+ NumberAnimation {
+ duration: 350
+ easing.type: Easing.InOutQuad
+ }
+ PropertyAnimation {
+ target: listview
+ property: "anchors.topMargin"
+ from: window.height * 0.75
+ to: 16
+ duration: 350
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+
+ delegate: /* Item {
+ width: listview.width
+ height: outputLabel.implicitHeight */
+
+ Label {
+ id: outputLabel
+ text: modelData
+ }
+ // }
+ }
+ Button {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 2
+ anchors.rightMargin: 2
+ text: qsTr("Ok")
+ onClicked: gridDialog.close()
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/GlosSIConfig/qml/UWPSelectDialog.qml b/GlosSIConfig/qml/UWPSelectDialog.qml
index d450b04..3c12235 100644
--- a/GlosSIConfig/qml/UWPSelectDialog.qml
+++ b/GlosSIConfig/qml/UWPSelectDialog.qml
@@ -126,15 +126,6 @@ Dialog {
visible: opacity == 0 ? false : true
}
- Button {
- anchors.right: parent.right
- anchors.top: listview.bottom
- anchors.topMargin: 16
- anchors.rightMargin: 2
- text: qsTr("Cancel")
- onClicked: dlg.close()
- }
-
ListView {
anchors.top: searchBar.bottom
anchors.topMargin: 16
@@ -218,5 +209,14 @@ Dialog {
}
}
}
+
+ Button {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 2
+ anchors.rightMargin: 2
+ text: qsTr("Cancel")
+ onClicked: dlg.close()
+ }
}
}
\ No newline at end of file
diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml
index 0126a17..7e22a54 100644
--- a/GlosSIConfig/qml/main.qml
+++ b/GlosSIConfig/qml/main.qml
@@ -48,6 +48,12 @@ Window {
}
property bool steamShortcutsChanged: false
+
+ onSteamShortcutsChanged: function() {
+ shouldShowLoadGridImagesButton = uiModel.targetList.some((shortcut) => uiModel.isInSteam(shortcut))
+ }
+
+ property bool shouldShowLoadGridImagesButton: false
Component.onCompleted: function() {
if (!uiModel.foundSteam) {
@@ -57,6 +63,7 @@ Window {
if (!uiModel.steamInputXboxSupportEnabled) {
steamXboxDisabledDialog.open();
}
+ shouldShowLoadGridImagesButton = uiModel.targetList.some((shortcut) => uiModel.isInSteam(shortcut))
}
Image {
@@ -370,47 +377,64 @@ Window {
windowContent.editedIndex = index;
}
}
- Column {
+ Row {
spacing: 8
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 24
- RoundButton {
- id: optionsBtn
- width: 64
- height: 64
- text: ""
- contentItem: Item {
- Image {
+ Column {
+ spacing: 8
+ RoundButton {
+ id: optionsBtn
+ anchors.right: parent.right
+ 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
+ anchors.right: parent.right
+ width: 64
+ height: 64
+ text: "+"
+ contentItem: Label {
anchors.centerIn: parent
- source: "qrc:/svg/settings_fill_white_24dp.svg"
- width: 24
- height: 24
+ text: addBtn.text
+ font.pixelSize: 32
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
}
- }
- highlighted: true
- onClicked: function() {
- globalConf.opacity = 1;
- homeContent.opacity = 0;
+ highlighted: true
+ onClicked: selectTypeDialog.open()
}
- }
- 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
+ Button {
+ visible: shouldShowLoadGridImagesButton || steamShortcutsChanged
+ id: loadGridImagesBtn
+ text: qsTr("🖼️ Load steam grid images")
+ highlighted: true
+ onClicked: function() {
+ steamGridDialog.open()
+ }
}
- highlighted: true
- onClicked: selectTypeDialog.open()
}
+
}
+
+
}
Item {
@@ -532,5 +556,10 @@ Window {
}
}
}
+
+ SteamGridDialog {
+ id: steamGridDialog
+ }
+
}
}
diff --git a/GlosSITarget/Resource.rc b/GlosSITarget/Resource.rc
index ccb5d81..009c048 100644
--- a/GlosSITarget/Resource.rc
+++ b/GlosSITarget/Resource.rc
@@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,1,0,203000008020
- PRODUCTVERSION 0,1,0,203000008020
+ FILEVERSION 0,1,0,2033009290000
+ PRODUCTVERSION 0,1,0,2033009290000
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - SteamTarget"
- VALUE "FileVersion", "0.1.0.2-3-gcea802b"
+ VALUE "FileVersion", "0.1.0.2-33-g929abfe"
VALUE "InternalName", "GlosSITarget"
VALUE "LegalCopyright", "Copyright (C) 2021-2022 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSITarget.exe"
VALUE "ProductName", "GlosSI"
- VALUE "ProductVersion", "0.1.0.2-3-gcea802b"
+ VALUE "ProductVersion", "0.1.0.2-33-g929abfe"
END
END
BLOCK "VarFileInfo"
diff --git a/bundle-zip.ps1 b/bundle-zip.ps1
index c6964e7..dffea33 100644
--- a/bundle-zip.ps1
+++ b/bundle-zip.ps1
@@ -18,6 +18,7 @@ Copy-Item "..\..\vc_redist.x64.exe" -Destination "."
Copy-Item "..\..\LICENSE" -Destination "./LICENSE"
Copy-Item "..\..\QT_License" -Destination "./QT_License"
Copy-Item "..\..\THIRD_PARTY_LICENSES.txt" -Destination "./THIRD_PARTY_LICENSES.txt"
+Copy-Item "..\..\steamgrid.exe" -Destination "./steamgrid.exe"
Copy-Item "C:\Qt\Tools\OpenSSL\Win_x64\bin\libcrypto-1_1-x64.dll" -Destination "./libcrypto-1_1-x64.dll"
Copy-Item "C:\Qt\Tools\OpenSSL\Win_x64\bin\libssl-1_1-x64.dll" -Destination "./libssl-1_1-x64.dll"
diff --git a/prebuild.ps1 b/prebuild.ps1
index 23c6fff..b2ee11e 100644
--- a/prebuild.ps1
+++ b/prebuild.ps1
@@ -14,4 +14,20 @@ cd .\GlosSIConfig\
..\version_help.ps1
-cd ../
\ No newline at end of file
+$apiKeyText = "
+/* Autogenerated version info file */
+#pragma once
+
+inline const char* steamgridb_key = ""$env:STEAMGRIDDB_KEY"";
+"
+
+if (!(Test-Path 'steamgrid_api_keys.h')) {
+ New-Item -Path "." -Name "steamgrid_api_keys.h" -ItemType "file" -Value $apiKeyText
+}
+
+cd ../
+
+if (!(Test-Path 'steamgrid.exe')) {
+ Invoke-WebRequest -o steamgrid.zip https://github.com/boppreh/steamgrid/releases/download/v3.4.0/steamgrid_windows.zip
+ 7z e steamgrid.zip steamgrid.exe
+}