GlosSIConfig: Integrate SteamGrid

pull/192/head
Peter Repukat 2 years ago
parent 93026dfb75
commit 6e69b6ec1c

2
.gitignore vendored

@ -370,3 +370,5 @@ MigrationBackup/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
.visuallint .visuallint
GlosSIConfig/steamgrid_api_keys.h
steamgrid.zip

@ -145,6 +145,7 @@
<None Include="qml\CollapsiblePane.qml" /> <None Include="qml\CollapsiblePane.qml" />
<None Include="qml\EGSSelectDialog.qml" /> <None Include="qml\EGSSelectDialog.qml" />
<None Include="qml\GlobalConf.qml" /> <None Include="qml\GlobalConf.qml" />
<None Include="qml\SteamGridDialog.qml" />
<None Include="qml\SteamInputXboxDisabledDialog.qml" /> <None Include="qml\SteamInputXboxDisabledDialog.qml" />
<None Include="qml\AddSelectTypeDialog.qml" /> <None Include="qml\AddSelectTypeDialog.qml" />
<None Include="qml\FluentTextInput.qml" /> <None Include="qml\FluentTextInput.qml" />
@ -163,6 +164,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="ExeImageProvider.h" /> <ClInclude Include="ExeImageProvider.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="steamgrid_api_keys.h" />
<ClInclude Include="UWPFetch.h" /> <ClInclude Include="UWPFetch.h" />
<ClInclude Include="WinEventFilter.h" /> <ClInclude Include="WinEventFilter.h" />
</ItemGroup> </ItemGroup>

@ -83,6 +83,9 @@
<None Include="qml\EGSSelectDialog.qml"> <None Include="qml\EGSSelectDialog.qml">
<Filter>qml</Filter> <Filter>qml</Filter>
</None> </None>
<None Include="qml\SteamGridDialog.qml">
<Filter>qml</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="UIModel.h"> <QtMoc Include="UIModel.h">
@ -102,6 +105,9 @@
<ClInclude Include="ExeImageProvider.h"> <ClInclude Include="ExeImageProvider.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="steamgrid_api_keys.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Xml Include="manifest.xml"> <Xml Include="manifest.xml">

@ -33,6 +33,7 @@ limitations under the License.
#endif #endif
#include "../version.hpp" #include "../version.hpp"
#include "steamgrid_api_keys.h"
UIModel::UIModel() : QObject(nullptr) UIModel::UIModel() : QObject(nullptr)
{ {
@ -479,6 +480,17 @@ QVariantList UIModel::egsGamesList() const
return {{"InstallLocation", "Error"}}; 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 QString UIModel::getGridImagePath(QVariant shortcut) const
{ {
@ -497,9 +509,9 @@ QString UIModel::getGridImagePath(QVariant shortcut) const
} }
const std::vector<std::string> extensions = {".png", ".jpg"}; const std::vector<std::string> extensions = {".png", ".jpg"};
for (const auto& entry : std::filesystem::directory_iterator(grid_dir)) { for (const auto& entry : std::filesystem::directory_iterator(grid_dir)) {
if (entry.is_regular_file() if (entry.is_regular_file() &&
&& std::ranges::find(extensions, entry.path().extension().string()) != extensions.end() std::ranges::find(extensions, entry.path().extension().string()) != extensions.end() &&
&& entry.path().filename().string().find(std::to_string(app_id)) != std::string::npos) { entry.path().filename().string().find(std::to_string(app_id)) != std::string::npos) {
return QString::fromStdString(entry.path().string()); return QString::fromStdString(entry.path().string());
} }
} }
@ -586,6 +598,8 @@ void UIModel::setAcrylicEffect(bool has_acrylic_affect)
emit acrylicChanged(); emit acrylicChanged();
} }
QStringList UIModel::getSteamgridOutput() const { return steamgrid_output_; }
void UIModel::onAvailFilesResponse(QNetworkReply* reply) 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 void UIModel::writeTarget(const QJsonObject& json, const QString& name) const
{ {
auto path = config_path_; auto path = config_path_;

@ -17,6 +17,7 @@ limitations under the License.
#include <QJsonObject> #include <QJsonObject>
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include <QProcess>
#include <filesystem> #include <filesystem>
#include <shortcuts_vdf.hpp> #include <shortcuts_vdf.hpp>
@ -37,6 +38,8 @@ class UIModel : public QObject {
Q_PROPERTY(QString versionString READ getVersionString CONSTANT) Q_PROPERTY(QString versionString READ getVersionString CONSTANT)
Q_PROPERTY(QString newVersionName READ getNewVersionName NOTIFY newVersionAvailable) Q_PROPERTY(QString newVersionName READ getNewVersionName NOTIFY newVersionAvailable)
Q_PROPERTY(QStringList steamgridOutput READ getSteamgridOutput NOTIFY steamgridOutputChanged)
public: public:
UIModel(); UIModel();
@ -65,6 +68,7 @@ class UIModel : public QObject {
#endif #endif
Q_INVOKABLE QVariantList egsGamesList() const; Q_INVOKABLE QVariantList egsGamesList() const;
Q_INVOKABLE void loadSteamGridImages();
Q_INVOKABLE QString getGridImagePath(QVariant shortcut) const; Q_INVOKABLE QString getGridImagePath(QVariant shortcut) const;
[[nodiscard]] bool writeShortcutsVDF(const std::wstring& mode, const std::wstring& name, [[nodiscard]] bool writeShortcutsVDF(const std::wstring& mode, const std::wstring& name,
@ -75,13 +79,17 @@ class UIModel : public QObject {
[[nodiscard]] bool hasAcrylicEffect() const; [[nodiscard]] bool hasAcrylicEffect() const;
void setAcrylicEffect(bool has_acrylic_affect); void setAcrylicEffect(bool has_acrylic_affect);
QStringList getSteamgridOutput() const;
signals: signals:
void acrylicChanged(); void acrylicChanged();
void targetListChanged(); void targetListChanged();
void newVersionAvailable(); void newVersionAvailable();
void steamgridOutputChanged();
public slots: public slots:
void onAvailFilesResponse(QNetworkReply* reply); void onAvailFilesResponse(QNetworkReply* reply);
void onSteamGridReadReady();
private: private:
#ifdef _WIN32 #ifdef _WIN32
@ -107,6 +115,9 @@ class UIModel : public QObject {
QString new_version_name_; QString new_version_name_;
bool notify_on_snapshots_ = false; bool notify_on_snapshots_ = false;
QProcess steamgrid_proc_;
QStringList steamgrid_output_;
std::vector<VDFParser::Shortcut> shortcuts_vdf_; std::vector<VDFParser::Shortcut> shortcuts_vdf_;
void writeTarget(const QJsonObject& json, const QString& name) const; void writeTarget(const QJsonObject& json, const QString& name) const;

@ -24,5 +24,6 @@
<file>svg/settings_fill_white_24dp.svg</file> <file>svg/settings_fill_white_24dp.svg</file>
<file>qml/EGSSelectDialog.qml</file> <file>qml/EGSSelectDialog.qml</file>
<file>svg/add_photo_alternate_white_24dp.svg</file> <file>svg/add_photo_alternate_white_24dp.svg</file>
<file>qml/SteamGridDialog.qml</file>
</qresource> </qresource>
</RCC> </RCC>

@ -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()
}
}
}

@ -126,15 +126,6 @@ Dialog {
visible: opacity == 0 ? false : true 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 { ListView {
anchors.top: searchBar.bottom anchors.top: searchBar.bottom
anchors.topMargin: 16 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()
}
} }
} }

@ -48,6 +48,12 @@ Window {
} }
property bool steamShortcutsChanged: false property bool steamShortcutsChanged: false
onSteamShortcutsChanged: function() {
shouldShowLoadGridImagesButton = uiModel.targetList.some((shortcut) => uiModel.isInSteam(shortcut))
}
property bool shouldShowLoadGridImagesButton: false
Component.onCompleted: function() { Component.onCompleted: function() {
if (!uiModel.foundSteam) { if (!uiModel.foundSteam) {
@ -57,6 +63,7 @@ Window {
if (!uiModel.steamInputXboxSupportEnabled) { if (!uiModel.steamInputXboxSupportEnabled) {
steamXboxDisabledDialog.open(); steamXboxDisabledDialog.open();
} }
shouldShowLoadGridImagesButton = uiModel.targetList.some((shortcut) => uiModel.isInSteam(shortcut))
} }
Image { Image {
@ -370,47 +377,64 @@ Window {
windowContent.editedIndex = index; windowContent.editedIndex = index;
} }
} }
Column { Row {
spacing: 8 spacing: 8
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.margins: 24 anchors.margins: 24
RoundButton { Column {
id: optionsBtn spacing: 8
width: 64 RoundButton {
height: 64 id: optionsBtn
text: "" anchors.right: parent.right
contentItem: Item { width: 64
Image { 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 anchors.centerIn: parent
source: "qrc:/svg/settings_fill_white_24dp.svg" text: addBtn.text
width: 24 font.pixelSize: 32
height: 24 horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
} }
} highlighted: true
highlighted: true onClicked: selectTypeDialog.open()
onClicked: function() {
globalConf.opacity = 1;
homeContent.opacity = 0;
} }
} Button {
RoundButton { visible: shouldShowLoadGridImagesButton || steamShortcutsChanged
id: addBtn id: loadGridImagesBtn
width: 64 text: qsTr("🖼️ Load steam grid images")
height: 64 highlighted: true
text: "+" onClicked: function() {
contentItem: Label { steamGridDialog.open()
anchors.centerIn: parent }
text: addBtn.text
font.pixelSize: 32
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
} }
highlighted: true
onClicked: selectTypeDialog.open()
} }
} }
} }
Item { Item {
@ -532,5 +556,10 @@ Window {
} }
} }
} }
SteamGridDialog {
id: steamGridDialog
}
} }
} }

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,1,0,203000008020 FILEVERSION 0,1,0,2033009290000
PRODUCTVERSION 0,1,0,203000008020 PRODUCTVERSION 0,1,0,2033009290000
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - SteamTarget" VALUE "FileDescription", "GlosSI - SteamTarget"
VALUE "FileVersion", "0.1.0.2-3-gcea802b" VALUE "FileVersion", "0.1.0.2-33-g929abfe"
VALUE "InternalName", "GlosSITarget" VALUE "InternalName", "GlosSITarget"
VALUE "LegalCopyright", "Copyright (C) 2021-2022 Peter Repukat - FlatspotSoftware" VALUE "LegalCopyright", "Copyright (C) 2021-2022 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSITarget.exe" VALUE "OriginalFilename", "GlosSITarget.exe"
VALUE "ProductName", "GlosSI" VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.1.0.2-3-gcea802b" VALUE "ProductVersion", "0.1.0.2-33-g929abfe"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

@ -18,6 +18,7 @@ Copy-Item "..\..\vc_redist.x64.exe" -Destination "."
Copy-Item "..\..\LICENSE" -Destination "./LICENSE" Copy-Item "..\..\LICENSE" -Destination "./LICENSE"
Copy-Item "..\..\QT_License" -Destination "./QT_License" Copy-Item "..\..\QT_License" -Destination "./QT_License"
Copy-Item "..\..\THIRD_PARTY_LICENSES.txt" -Destination "./THIRD_PARTY_LICENSES.txt" 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\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" Copy-Item "C:\Qt\Tools\OpenSSL\Win_x64\bin\libssl-1_1-x64.dll" -Destination "./libssl-1_1-x64.dll"

@ -14,4 +14,20 @@ cd .\GlosSIConfig\
..\version_help.ps1 ..\version_help.ps1
cd ../ $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
}

Loading…
Cancel
Save