qt: save gui settings to separate file (#2984)

* initial save classes for gui save file

* fixup

* some more settings passed to the new saving file

* even more variables parsing

* more settings

* fixup

* more settings

* more settings

* clang fix

* fixed wrong setting

* more setting

* more setting

* added ca_ES

* rename to general_settings

* added set-addon-folder in main

* fixup

* fixup2

* added sr_CS

* Update CMakeLists.txt

---------

Co-authored-by: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com>
This commit is contained in:
georgemoralis
2025-06-12 13:27:52 +03:00
committed by GitHub
parent 34d0d85c15
commit a1d6cd15f4
19 changed files with 383 additions and 370 deletions

View File

@@ -28,8 +28,10 @@
using namespace Common::FS;
CheckUpdate::CheckUpdate(const bool showMessage, QWidget* parent)
: QDialog(parent), networkManager(new QNetworkAccessManager(this)) {
CheckUpdate::CheckUpdate(std::shared_ptr<gui_settings> gui_settings, const bool showMessage,
QWidget* parent)
: QDialog(parent), m_gui_settings(std::move(gui_settings)),
networkManager(new QNetworkAccessManager(this)) {
setWindowTitle(tr("Auto Updater"));
setFixedSize(0, 0);
CheckForUpdates(showMessage);
@@ -43,7 +45,7 @@ void CheckUpdate::CheckForUpdates(const bool showMessage) {
bool checkName = true;
while (checkName) {
updateChannel = QString::fromStdString(Config::getUpdateChannel());
updateChannel = m_gui_settings->GetValue(gui::gen_updateChannel).toString();
if (updateChannel == "Nightly") {
url = QUrl("https://api.github.com/repos/shadps4-emu/shadPS4/releases");
checkName = false;
@@ -52,12 +54,10 @@ void CheckUpdate::CheckForUpdates(const bool showMessage) {
checkName = false;
} else {
if (Common::g_is_release) {
Config::setUpdateChannel("Release");
m_gui_settings->SetValue(gui::gen_updateChannel, "Release");
} else {
Config::setUpdateChannel("Nightly");
m_gui_settings->SetValue(gui::gen_updateChannel, "Nightly");
}
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
Config::save(config_dir / "config.toml");
}
}
@@ -198,7 +198,7 @@ void CheckUpdate::setupUI(const QString& downloadUrl, const QString& latestDate,
titleLayout->addWidget(titleLabel);
layout->addLayout(titleLayout);
QString updateChannel = QString::fromStdString(Config::getUpdateChannel());
QString updateChannel = m_gui_settings->GetValue(gui::gen_updateChannel).toString();
QString updateText = QString("<p><b>" + tr("Update Channel") + ": </b>" + updateChannel +
"<br>"
@@ -273,7 +273,7 @@ void CheckUpdate::setupUI(const QString& downloadUrl, const QString& latestDate,
}
});
if (Config::alwaysShowChangelog()) {
if (m_gui_settings->GetValue(gui::gen_showChangeLog).toBool()) {
requestChangelog(currentRev, latestRev, downloadUrl, latestDate, currentDate);
textField->setVisible(true);
toggleButton->setText(tr("Hide Changelog"));
@@ -290,14 +290,14 @@ void CheckUpdate::setupUI(const QString& downloadUrl, const QString& latestDate,
connect(noButton, &QPushButton::clicked, this, [this]() { close(); });
autoUpdateCheckBox->setChecked(Config::autoUpdate());
autoUpdateCheckBox->setChecked(m_gui_settings->GetValue(gui::gen_checkForUpdates).toBool());
#if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
connect(autoUpdateCheckBox, &QCheckBox::stateChanged, this, [](int state) {
connect(autoUpdateCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
#else
connect(autoUpdateCheckBox, &QCheckBox::checkStateChanged, this, [](Qt::CheckState state) {
connect(autoUpdateCheckBox, &QCheckBox::checkStateChanged, this, [this](Qt::CheckState state) {
#endif
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
Config::setAutoUpdate(state == Qt::Checked);
m_gui_settings->SetValue(gui::gen_checkForUpdates, (state == Qt::Checked));
Config::save(user_dir / "config.toml");
});

View File

@@ -8,12 +8,14 @@
#include <QDialog>
#include <QNetworkAccessManager>
#include <QPushButton>
#include "gui_settings.h"
class CheckUpdate : public QDialog {
Q_OBJECT
public:
explicit CheckUpdate(const bool showMessage, QWidget* parent = nullptr);
explicit CheckUpdate(std::shared_ptr<gui_settings> gui_settings, const bool showMessage,
QWidget* parent = nullptr);
~CheckUpdate();
private slots:
@@ -35,6 +37,7 @@ private:
QString updateDownloadUrl;
QNetworkAccessManager* networkManager;
std::shared_ptr<gui_settings> m_gui_settings;
};
#endif // CHECKUPDATE_H

View File

@@ -5,11 +5,13 @@
#include "game_grid_frame.h"
#include "qt_gui/compatibility_info.h"
GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
GameGridFrame::GameGridFrame(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent)
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
icon_size = Config::getIconSizeGrid();
: QTableWidget(parent), m_gui_settings(std::move(gui_settings)), m_game_info(game_info_get),
m_compat_info(compat_info_get) {
icon_size = m_gui_settings->GetValue(gui::gg_icon_size).toInt();
windowWidth = parent->width();
this->setShowGrid(false);
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
@@ -74,7 +76,7 @@ void GameGridFrame::onCurrentCellChanged(int currentRow, int currentColumn, int
}
void GameGridFrame::PlayBackgroundMusic(QString path) {
if (path.isEmpty() || !Config::getPlayBGM()) {
if (path.isEmpty() || !m_gui_settings->GetValue(gui::gl_playBackgroundMusic).toBool()) {
BackgroundMusicPlayer::getInstance().stopMusic();
return;
}
@@ -91,7 +93,8 @@ void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool from
else
m_games_ = m_game_info->m_games;
m_games_shared = std::make_shared<QVector<GameInfo>>(m_games_);
icon_size = Config::getIconSizeGrid(); // update icon size for resize event.
icon_size =
m_gui_settings->GetValue(gui::gg_icon_size).toInt(); // update icon size for resize event.
int gamesPerRow = windowWidth / (icon_size + 20); // 2 x cell widget border size.
int row = 0;
@@ -118,7 +121,7 @@ void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool from
layout->addWidget(name_label);
// Resizing of font-size.
float fontSize = (Config::getIconSizeGrid() / 5.5f);
float fontSize = (m_gui_settings->GetValue(gui::gg_icon_size).toInt() / 5.5f);
QString styleSheet =
QString("color: white; font-weight: bold; font-size: %1px;").arg(fontSize);
name_label->setStyleSheet(styleSheet);
@@ -168,7 +171,7 @@ void GameGridFrame::SetGridBackgroundImage(int row, int column) {
}
// If background images are hidden, clear the background image
if (!Config::getShowBackgroundImage()) {
if (!m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool()) {
backgroundImage = QImage();
m_last_opacity = -1; // Reset opacity tracking when disabled
m_current_game_path.clear(); // Reset current game path
@@ -177,7 +180,7 @@ void GameGridFrame::SetGridBackgroundImage(int row, int column) {
}
const auto& game = (*m_games_shared)[itemID];
const int opacity = Config::getBackgroundImageOpacity();
const int opacity = m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt();
// Recompute if opacity changed or we switched to a different game
if (opacity != m_last_opacity || game.pic_path != m_current_game_path) {
@@ -195,7 +198,8 @@ void GameGridFrame::SetGridBackgroundImage(int row, int column) {
void GameGridFrame::RefreshGridBackgroundImage() {
QPalette palette;
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
if (!backgroundImage.isNull() &&
m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool()) {
QSize widgetSize = size();
QPixmap scaledPixmap =
QPixmap::fromImage(backgroundImage)

View File

@@ -11,6 +11,7 @@
#include "game_info.h"
#include "game_list_utils.h"
#include "gui_context_menus.h"
#include "gui_settings.h"
#include "qt_gui/compatibility_info.h"
class GameGridFrame : public QTableWidget {
@@ -37,9 +38,11 @@ private:
bool validCellSelected = false;
int m_last_opacity = -1; // Track last opacity to avoid unnecessary recomputation
std::filesystem::path m_current_game_path; // Track current game path to detect changes
std::shared_ptr<gui_settings> m_gui_settings;
public:
explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
explicit GameGridFrame(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent = nullptr);
void PopulateGameGrid(QVector<GameInfo> m_games, bool fromSearch);

View File

@@ -9,11 +9,13 @@
#include "game_list_frame.h"
#include "game_list_utils.h"
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
GameListFrame::GameListFrame(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent)
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
icon_size = Config::getIconSize();
: QTableWidget(parent), m_gui_settings(std::move(gui_settings)), m_game_info(game_info_get),
m_compat_info(compat_info_get) {
icon_size = m_gui_settings->GetValue(gui::gl_icon_size).toInt();
this->setShowGrid(false);
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
@@ -97,7 +99,7 @@ void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int
}
void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
if (!item || !Config::getPlayBGM()) {
if (!item || !m_gui_settings->GetValue(gui::gl_playBackgroundMusic).toBool()) {
BackgroundMusicPlayer::getInstance().stopMusic();
return;
}
@@ -172,7 +174,7 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
}
// If background images are hidden, clear the background image
if (!Config::getShowBackgroundImage()) {
if (!m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool()) {
backgroundImage = QImage();
m_last_opacity = -1; // Reset opacity tracking when disabled
m_current_game_path.clear(); // Reset current game path
@@ -181,7 +183,7 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
}
const auto& game = m_game_info->m_games[item->row()];
const int opacity = Config::getBackgroundImageOpacity();
const int opacity = m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt();
// Recompute if opacity changed or we switched to a different game
if (opacity != m_last_opacity || game.pic_path != m_current_game_path) {
@@ -200,7 +202,8 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
void GameListFrame::RefreshListBackgroundImage() {
QPalette palette;
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
if (!backgroundImage.isNull() &&
m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool()) {
QSize widgetSize = size();
QPixmap scaledPixmap =
QPixmap::fromImage(backgroundImage)

View File

@@ -17,11 +17,13 @@
#include "game_info.h"
#include "game_list_utils.h"
#include "gui_context_menus.h"
#include "gui_settings.h"
class GameListFrame : public QTableWidget {
Q_OBJECT
public:
explicit GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
explicit GameListFrame(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent = nullptr);
Q_SIGNALS:
@@ -48,6 +50,7 @@ private:
QTableWidgetItem* m_current_item = nullptr;
int m_last_opacity = -1; // Track last opacity to avoid unnecessary recomputation
std::filesystem::path m_current_game_path; // Track current game path to detect changes
std::shared_ptr<gui_settings> m_gui_settings;
public:
void PopulateGameList(bool isInitialPopulation = true);

View File

@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "gui_settings.h"
gui_settings::gui_settings(QObject* parent) : settings(parent) {
m_settings = std::make_unique<QSettings>(ComputeSettingsDir() + "qt_ui.ini",
QSettings::Format::IniFormat, parent);
}

46
src/qt_gui/gui_settings.h Normal file
View File

@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QWindow>
#include "settings.h"
namespace gui {
// categories
const QString general_settings = "general_settings";
const QString main_window = "main_window";
const QString game_list = "game_list";
const QString game_grid = "game_grid";
// general
const gui_value gen_checkForUpdates = gui_value(general_settings, "checkForUpdates", false);
const gui_value gen_showChangeLog = gui_value(general_settings, "showChangeLog", false);
const gui_value gen_updateChannel = gui_value(general_settings, "updateChannel", "Release");
// main window settings
const gui_value mw_geometry = gui_value(main_window, "geometry", QByteArray());
const gui_value mw_showLabelsUnderIcons = gui_value(main_window, "showLabelsUnderIcons", true);
// game list settings
const gui_value gl_mode = gui_value(game_list, "tableMode", 0);
const gui_value gl_icon_size = gui_value(game_list, "icon_size", 36);
const gui_value gl_slider_pos = gui_value(game_list, "slider_pos", 0);
const gui_value gl_showBackgroundImage = gui_value(game_list, "showBackgroundImage", true);
const gui_value gl_backgroundImageOpacity = gui_value(game_list, "backgroundImageOpacity", 50);
const gui_value gl_playBackgroundMusic = gui_value(game_list, "playBackgroundMusic", true);
const gui_value gl_backgroundMusicVolume = gui_value(game_list, "backgroundMusicVolume", 50);
// game grid settings
const gui_value gg_icon_size = gui_value(game_grid, "icon_size", 69);
const gui_value gg_slider_pos = gui_value(game_grid, "slider_pos", 0);
} // namespace gui
class gui_settings : public settings {
Q_OBJECT
public:
explicit gui_settings(QObject* parent = nullptr);
~gui_settings() override = default;
};

View File

@@ -32,6 +32,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
ui->setupUi(this);
installEventFilter(this);
setAttribute(Qt::WA_DeleteOnClose);
m_gui_settings = std::make_shared<gui_settings>();
ui->toggleLabelsAct->setChecked(
m_gui_settings->GetValue(gui::mw_showLabelsUnderIcons).toBool());
}
MainWindow::~MainWindow() {
@@ -139,7 +142,7 @@ void MainWindow::PauseGame() {
void MainWindow::toggleLabelsUnderIcons() {
bool showLabels = ui->toggleLabelsAct->isChecked();
Config::setShowLabelsUnderIcons();
m_gui_settings->SetValue(gui::mw_showLabelsUnderIcons, showLabels);
UpdateToolbarLabels();
if (isGameRunning) {
UpdateToolbarButtons();
@@ -290,21 +293,21 @@ void MainWindow::CreateDockWindows() {
setCentralWidget(phCentralWidget);
m_dock_widget.reset(new QDockWidget(tr("Game List"), this));
m_game_list_frame.reset(new GameListFrame(m_game_info, m_compat_info, this));
m_game_list_frame.reset(new GameListFrame(m_gui_settings, m_game_info, m_compat_info, this));
m_game_list_frame->setObjectName("gamelist");
m_game_grid_frame.reset(new GameGridFrame(m_game_info, m_compat_info, this));
m_game_grid_frame.reset(new GameGridFrame(m_gui_settings, m_game_info, m_compat_info, this));
m_game_grid_frame->setObjectName("gamegridlist");
m_elf_viewer.reset(new ElfViewer(this));
m_elf_viewer->setObjectName("elflist");
int table_mode = Config::getTableMode();
int table_mode = m_gui_settings->GetValue(gui::gl_mode).toInt();
int slider_pos = 0;
if (table_mode == 0) { // List
m_game_grid_frame->hide();
m_elf_viewer->hide();
m_game_list_frame->show();
m_dock_widget->setWidget(m_game_list_frame.data());
slider_pos = Config::getSliderPosition();
slider_pos = m_gui_settings->GetValue(gui::gl_slider_pos).toInt();
ui->sizeSlider->setSliderPosition(slider_pos); // set slider pos at start;
isTableList = true;
} else if (table_mode == 1) { // Grid
@@ -312,7 +315,7 @@ void MainWindow::CreateDockWindows() {
m_elf_viewer->hide();
m_game_grid_frame->show();
m_dock_widget->setWidget(m_game_grid_frame.data());
slider_pos = Config::getSliderPositionGrid();
slider_pos = m_gui_settings->GetValue(gui::gg_slider_pos).toInt();
ui->sizeSlider->setSliderPosition(slider_pos); // set slider pos at start;
isTableList = false;
} else {
@@ -356,11 +359,11 @@ void MainWindow::LoadGameLists() {
#ifdef ENABLE_UPDATER
void MainWindow::CheckUpdateMain(bool checkSave) {
if (checkSave) {
if (!Config::autoUpdate()) {
if (!m_gui_settings->GetValue(gui::gen_checkForUpdates).toBool()) {
return;
}
}
auto checkUpdate = new CheckUpdate(false);
auto checkUpdate = new CheckUpdate(m_gui_settings, false);
checkUpdate->exec();
}
#endif
@@ -380,13 +383,13 @@ void MainWindow::CreateConnects() {
m_game_list_frame->icon_size =
48 + value; // 48 is the minimum icon size to use due to text disappearing.
m_game_list_frame->ResizeIcons(48 + value);
Config::setIconSize(48 + value);
Config::setSliderPosition(value);
m_gui_settings->SetValue(gui::gl_icon_size, 48 + value);
m_gui_settings->SetValue(gui::gl_slider_pos, value);
} else {
m_game_grid_frame->icon_size = 69 + value;
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
Config::setIconSizeGrid(69 + value);
Config::setSliderPositionGrid(value);
m_gui_settings->SetValue(gui::gg_icon_size, 69 + value);
m_gui_settings->SetValue(gui::gg_slider_pos, value);
}
});
@@ -404,7 +407,7 @@ void MainWindow::CreateConnects() {
&MainWindow::StartGame);
connect(ui->configureAct, &QAction::triggered, this, [this]() {
auto settingsDialog = new SettingsDialog(m_compat_info, this);
auto settingsDialog = new SettingsDialog(m_gui_settings, m_compat_info, this);
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
&MainWindow::OnLanguageChanged);
@@ -418,7 +421,8 @@ void MainWindow::CreateConnects() {
connect(settingsDialog, &SettingsDialog::BackgroundOpacityChanged, this,
[this](int opacity) {
Config::setBackgroundImageOpacity(opacity);
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity,
std::clamp(opacity, 0, 100));
if (m_game_list_frame) {
QTableWidgetItem* current = m_game_list_frame->GetCurrentItem();
if (current) {
@@ -437,7 +441,7 @@ void MainWindow::CreateConnects() {
});
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
auto settingsDialog = new SettingsDialog(m_compat_info, this);
auto settingsDialog = new SettingsDialog(m_gui_settings, m_compat_info, this);
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
&MainWindow::OnLanguageChanged);
@@ -451,7 +455,8 @@ void MainWindow::CreateConnects() {
connect(settingsDialog, &SettingsDialog::BackgroundOpacityChanged, this,
[this](int opacity) {
Config::setBackgroundImageOpacity(opacity);
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity,
std::clamp(opacity, 0, 100));
if (m_game_list_frame) {
QTableWidgetItem* current = m_game_list_frame->GetCurrentItem();
if (current) {
@@ -481,7 +486,7 @@ void MainWindow::CreateConnects() {
#ifdef ENABLE_UPDATER
connect(ui->updaterAct, &QAction::triggered, this, [this]() {
auto checkUpdate = new CheckUpdate(true);
auto checkUpdate = new CheckUpdate(m_gui_settings, true);
checkUpdate->exec();
});
#endif
@@ -496,13 +501,13 @@ void MainWindow::CreateConnects() {
m_game_list_frame->icon_size =
36; // 36 is the minimum icon size to use due to text disappearing.
ui->sizeSlider->setValue(0); // icone_size - 36
Config::setIconSize(36);
Config::setSliderPosition(0);
m_gui_settings->SetValue(gui::gl_icon_size, 36);
m_gui_settings->SetValue(gui::gl_slider_pos, 0);
} else {
m_game_grid_frame->icon_size = 69;
ui->sizeSlider->setValue(0); // icone_size - 36
Config::setIconSizeGrid(69);
Config::setSliderPositionGrid(0);
m_gui_settings->SetValue(gui::gg_icon_size, 69);
m_gui_settings->SetValue(gui::gg_slider_pos, 9);
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
}
});
@@ -511,13 +516,13 @@ void MainWindow::CreateConnects() {
if (isTableList) {
m_game_list_frame->icon_size = 64;
ui->sizeSlider->setValue(28);
Config::setIconSize(64);
Config::setSliderPosition(28);
m_gui_settings->SetValue(gui::gl_icon_size, 64);
m_gui_settings->SetValue(gui::gl_slider_pos, 28);
} else {
m_game_grid_frame->icon_size = 97;
ui->sizeSlider->setValue(28);
Config::setIconSizeGrid(97);
Config::setSliderPositionGrid(28);
m_gui_settings->SetValue(gui::gg_icon_size, 97);
m_gui_settings->SetValue(gui::gg_slider_pos, 28);
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
}
});
@@ -526,13 +531,13 @@ void MainWindow::CreateConnects() {
if (isTableList) {
m_game_list_frame->icon_size = 128;
ui->sizeSlider->setValue(92);
Config::setIconSize(128);
Config::setSliderPosition(92);
m_gui_settings->SetValue(gui::gl_icon_size, 128);
m_gui_settings->SetValue(gui::gl_slider_pos, 92);
} else {
m_game_grid_frame->icon_size = 161;
ui->sizeSlider->setValue(92);
Config::setIconSizeGrid(161);
Config::setSliderPositionGrid(92);
m_gui_settings->SetValue(gui::gg_icon_size, 161);
m_gui_settings->SetValue(gui::gg_slider_pos, 92);
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
}
});
@@ -541,13 +546,13 @@ void MainWindow::CreateConnects() {
if (isTableList) {
m_game_list_frame->icon_size = 256;
ui->sizeSlider->setValue(220);
Config::setIconSize(256);
Config::setSliderPosition(220);
m_gui_settings->SetValue(gui::gl_icon_size, 256);
m_gui_settings->SetValue(gui::gl_slider_pos, 220);
} else {
m_game_grid_frame->icon_size = 256;
ui->sizeSlider->setValue(220);
Config::setIconSizeGrid(256);
Config::setSliderPositionGrid(220);
m_gui_settings->SetValue(gui::gg_icon_size, 256);
m_gui_settings->SetValue(gui::gg_slider_pos, 220);
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
}
});
@@ -563,8 +568,8 @@ void MainWindow::CreateConnects() {
m_game_list_frame->PopulateGameList();
}
isTableList = true;
Config::setTableMode(0);
int slider_pos = Config::getSliderPosition();
m_gui_settings->SetValue(gui::gl_mode, 0);
int slider_pos = m_gui_settings->GetValue(gui::gl_slider_pos).toInt();
ui->sizeSlider->setEnabled(true);
ui->sizeSlider->setSliderPosition(slider_pos);
ui->mw_searchbar->setText("");
@@ -582,8 +587,8 @@ void MainWindow::CreateConnects() {
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
}
isTableList = false;
Config::setTableMode(1);
int slider_pos_grid = Config::getSliderPositionGrid();
m_gui_settings->SetValue(gui::gl_mode, 1);
int slider_pos_grid = m_gui_settings->GetValue(gui::gg_slider_pos).toInt();
ui->sizeSlider->setEnabled(true);
ui->sizeSlider->setSliderPosition(slider_pos_grid);
ui->mw_searchbar->setText("");
@@ -598,7 +603,7 @@ void MainWindow::CreateConnects() {
m_elf_viewer->show();
isTableList = false;
ui->sizeSlider->setDisabled(true);
Config::setTableMode(2);
m_gui_settings->SetValue(gui::gl_mode, 2);
SetLastIconSizeBullet();
});
@@ -840,7 +845,7 @@ void MainWindow::CreateConnects() {
void MainWindow::StartGame() {
BackgroundMusicPlayer::getInstance().stopMusic();
QString gamePath = "";
int table_mode = Config::getTableMode();
int table_mode = m_gui_settings->GetValue(gui::gl_mode).toInt();
if (table_mode == 0) {
if (m_game_list_frame->currentItem()) {
int itemID = m_game_list_frame->currentItem()->row();
@@ -925,25 +930,25 @@ void MainWindow::RefreshGameTable() {
}
void MainWindow::ConfigureGuiFromSettings() {
setGeometry(Config::getMainWindowGeometryX(), Config::getMainWindowGeometryY(),
Config::getMainWindowGeometryW(), Config::getMainWindowGeometryH());
if (!restoreGeometry(m_gui_settings->GetValue(gui::mw_geometry).toByteArray())) {
// By default, set the window to 70% of the screen
resize(QGuiApplication::primaryScreen()->availableSize() * 0.7);
}
ui->showGameListAct->setChecked(true);
if (Config::getTableMode() == 0) {
int table_mode = m_gui_settings->GetValue(gui::gl_mode).toInt();
if (table_mode == 0) {
ui->setlistModeListAct->setChecked(true);
} else if (Config::getTableMode() == 1) {
} else if (table_mode == 1) {
ui->setlistModeGridAct->setChecked(true);
} else if (Config::getTableMode() == 2) {
} else if (table_mode == 2) {
ui->setlistElfAct->setChecked(true);
}
BackgroundMusicPlayer::getInstance().setVolume(Config::getBGMvolume());
BackgroundMusicPlayer::getInstance().setVolume(
m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt());
}
void MainWindow::SaveWindowState() const {
Config::setMainWindowWidth(this->width());
Config::setMainWindowHeight(this->height());
Config::setMainWindowGeometry(this->geometry().x(), this->geometry().y(),
this->geometry().width(), this->geometry().height());
void MainWindow::SaveWindowState() {
m_gui_settings->SetValue(gui::mw_geometry, saveGeometry(), false);
}
void MainWindow::BootGame() {
@@ -1024,8 +1029,8 @@ void MainWindow::SetLastUsedTheme() {
void MainWindow::SetLastIconSizeBullet() {
// set QAction bullet point if applicable
int lastSize = Config::getIconSize();
int lastSizeGrid = Config::getIconSizeGrid();
int lastSize = m_gui_settings->GetValue(gui::gl_icon_size).toInt();
int lastSizeGrid = m_gui_settings->GetValue(gui::gg_icon_size).toInt();
if (isTableList) {
switch (lastSize) {
case 36:
@@ -1195,7 +1200,7 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) {
auto tblMode = Config::getTableMode();
auto tblMode = m_gui_settings->GetValue(gui::gl_mode).toInt();
if (tblMode != 2 && (tblMode != 1 || m_game_grid_frame->IsValidCellSelected())) {
StartGame();
return true;

View File

@@ -20,6 +20,7 @@
#include "game_info.h"
#include "game_list_frame.h"
#include "game_list_utils.h"
#include "gui_settings.h"
#include "main_window_themes.h"
#include "main_window_ui.h"
@@ -41,7 +42,7 @@ public:
private Q_SLOTS:
void ConfigureGuiFromSettings();
void SaveWindowState() const;
void SaveWindowState();
void SearchGameTable(const QString& text);
void ShowGameList();
void RefreshGameTable();
@@ -102,6 +103,7 @@ private:
std::make_shared<CompatibilityInfoClass>();
QTranslator* translator;
std::shared_ptr<gui_settings> m_gui_settings;
protected:
bool eventFilter(QObject* obj, QEvent* event) override;

View File

@@ -107,7 +107,6 @@ public:
toggleLabelsAct = new QAction(MainWindow);
toggleLabelsAct->setObjectName("toggleLabelsAct");
toggleLabelsAct->setCheckable(true);
toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons());
setIconSizeTinyAct = new QAction(MainWindow);
setIconSizeTinyAct->setObjectName("setIconSizeTinyAct");

77
src/qt_gui/settings.cpp Normal file
View File

@@ -0,0 +1,77 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <common/path_util.h>
#include "settings.h"
settings::settings(QObject* parent) : QObject(parent), m_settings_dir(ComputeSettingsDir()) {}
settings::~settings() {
sync();
}
void settings::sync() {
if (m_settings) {
m_settings->sync();
}
}
QString settings::GetSettingsDir() const {
return m_settings_dir.absolutePath();
}
QString settings::ComputeSettingsDir() {
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
return QString::fromStdString(config_dir.string() + "/");
}
void settings::RemoveValue(const QString& key, const QString& name, bool sync) const {
if (m_settings) {
m_settings->beginGroup(key);
m_settings->remove(name);
m_settings->endGroup();
if (sync) {
m_settings->sync();
}
}
}
void settings::RemoveValue(const gui_value& entry, bool sync) const {
RemoveValue(entry.key, entry.name, sync);
}
QVariant settings::GetValue(const QString& key, const QString& name, const QVariant& def) const {
return m_settings ? m_settings->value(key + "/" + name, def) : def;
}
QVariant settings::GetValue(const gui_value& entry) const {
return GetValue(entry.key, entry.name, entry.def);
}
void settings::SetValue(const gui_value& entry, const QVariant& value, bool sync) const {
SetValue(entry.key, entry.name, value, sync);
}
void settings::SetValue(const QString& key, const QVariant& value, bool sync) const {
if (m_settings) {
m_settings->setValue(key, value);
if (sync) {
m_settings->sync();
}
}
}
void settings::SetValue(const QString& key, const QString& name, const QVariant& value,
bool sync) const {
if (m_settings) {
m_settings->beginGroup(key);
m_settings->setValue(name, value);
m_settings->endGroup();
if (sync) {
m_settings->sync();
}
}
}

55
src/qt_gui/settings.h Normal file
View File

@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QDir>
#include <QSettings>
#include <QString>
#include <QVariant>
struct gui_value {
QString key;
QString name;
QVariant def;
gui_value() {}
gui_value(const QString& k, const QString& n, const QVariant& d) : key(k), name(n), def(d) {}
bool operator==(const gui_value& rhs) const noexcept {
return key == rhs.key && name == rhs.name && def == rhs.def;
}
};
class settings : public QObject {
Q_OBJECT
public:
explicit settings(QObject* parent = nullptr);
~settings();
void sync();
QString GetSettingsDir() const;
QVariant GetValue(const QString& key, const QString& name, const QVariant& def) const;
QVariant GetValue(const gui_value& entry) const;
public Q_SLOTS:
/** Remove entry */
void RemoveValue(const QString& key, const QString& name, bool sync = true) const;
void RemoveValue(const gui_value& entry, bool sync = true) const;
/** Write value to entry */
void SetValue(const gui_value& entry, const QVariant& value, bool sync = true) const;
void SetValue(const QString& key, const QVariant& value, bool sync = true) const;
void SetValue(const QString& key, const QString& name, const QVariant& value,
bool sync = true) const;
protected:
static QString ComputeSettingsDir();
std::unique_ptr<QSettings> m_settings;
QDir m_settings_dir;
};

View File

@@ -71,9 +71,10 @@ int bgm_volume_backup;
static std::vector<QString> m_physical_devices;
SettingsDialog::SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_info,
SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent)
: QDialog(parent), ui(new Ui::SettingsDialog) {
: QDialog(parent), ui(new Ui::SettingsDialog), m_gui_settings(std::move(gui_settings)) {
ui->setupUi(this);
ui->tabWidgetSettings->setUsesScrollButtons(false);
@@ -147,6 +148,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_
Config::save(config_dir / "config.toml");
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
Config::setDefaultValues();
setDefaultValues();
Config::save(config_dir / "config.toml");
LoadValuesFromConfig();
} else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) {
@@ -175,28 +177,34 @@ SettingsDialog::SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_
{
#ifdef ENABLE_UPDATER
#if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
connect(ui->updateCheckBox, &QCheckBox::stateChanged, this,
[](int state) { Config::setAutoUpdate(state == Qt::Checked); });
connect(ui->updateCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
m_gui_settings->SetValue(gui::gen_checkForUpdates, state == Qt::Checked);
});
connect(ui->changelogCheckBox, &QCheckBox::stateChanged, this,
[](int state) { Config::setAlwaysShowChangelog(state == Qt::Checked); });
connect(ui->changelogCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
m_gui_settings->SetValue(gui::gen_showChangeLog, state == Qt::Checked);
});
#else
connect(ui->updateCheckBox, &QCheckBox::checkStateChanged, this,
[](Qt::CheckState state) { Config::setAutoUpdate(state == Qt::Checked); });
[this](Qt::CheckState state) {
m_gui_settings->SetValue(gui::gen_checkForUpdates, state == Qt::Checked);
});
connect(ui->changelogCheckBox, &QCheckBox::checkStateChanged, this,
[](Qt::CheckState state) { Config::setAlwaysShowChangelog(state == Qt::Checked); });
[this](Qt::CheckState state) {
m_gui_settings->SetValue(gui::gen_showChangeLog, state == Qt::Checked);
});
#endif
connect(ui->updateComboBox, &QComboBox::currentTextChanged, this,
[this](const QString& channel) {
if (channelMap.contains(channel)) {
Config::setUpdateChannel(channelMap.value(channel).toStdString());
m_gui_settings->SetValue(gui::gen_updateChannel, channelMap.value(channel));
}
});
connect(ui->checkUpdateButton, &QPushButton::clicked, this, []() {
auto checkUpdate = new CheckUpdate(true);
connect(ui->checkUpdateButton, &QPushButton::clicked, this, [this]() {
auto checkUpdate = new CheckUpdate(m_gui_settings, true);
checkUpdate->exec();
});
#else
@@ -235,12 +243,12 @@ SettingsDialog::SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
#if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this, [](int state) {
connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
#else
connect(ui->showBackgroundImageCheckBox, &QCheckBox::checkStateChanged, this,
[](Qt::CheckState state) {
[this](Qt::CheckState state) {
#endif
Config::setShowBackgroundImage(state == Qt::Checked);
m_gui_settings->SetValue(gui::gl_showBackgroundImage, state == Qt::Checked);
});
}
@@ -505,7 +513,7 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->changelogCheckBox->setChecked(
toml::find_or<bool>(data, "General", "alwaysShowChangelog", false));
QString updateChannel = QString::fromStdString(Config::getUpdateChannel());
QString updateChannel = m_gui_settings->GetValue(gui::gen_updateChannel).toString();
ui->updateComboBox->setCurrentText(
channelMap.key(updateChannel != "Release" && updateChannel != "Nightly"
? (Common::g_is_release ? "Release" : "Nightly")
@@ -536,11 +544,14 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
ResetInstallFolders();
ui->backgroundImageOpacitySlider->setValue(Config::getBackgroundImageOpacity());
ui->showBackgroundImageCheckBox->setChecked(Config::getShowBackgroundImage());
ui->backgroundImageOpacitySlider->setValue(
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt());
ui->showBackgroundImageCheckBox->setChecked(
m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool());
backgroundImageOpacitySlider_backup = Config::getBackgroundImageOpacity();
bgm_volume_backup = Config::getBGMvolume();
backgroundImageOpacitySlider_backup =
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt();
bgm_volume_backup = m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt();
}
void SettingsDialog::InitializeEmulatorLanguages() {
@@ -754,8 +765,7 @@ void SettingsDialog::UpdateSettings() {
} else if (ui->radioButton_Bottom->isChecked()) {
Config::setSideTrophy("bottom");
}
Config::setPlayBGM(ui->playBGMCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, ui->playBGMCheckBox->isChecked());
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked());
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString());
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString());
@@ -764,7 +774,7 @@ void SettingsDialog::UpdateSettings() {
Config::setCursorState(ui->hideCursorComboBox->currentIndex());
Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value());
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1);
Config::setBGMvolume(ui->BGMVolumeSlider->value());
m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, ui->BGMVolumeSlider->value());
Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()]);
Config::setEnableDiscordRPC(ui->discordRPCCheckbox->isChecked());
Config::setScreenWidth(ui->widthSpinBox->value());
@@ -784,16 +794,19 @@ void SettingsDialog::UpdateSettings() {
Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked());
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked());
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked());
Config::setAutoUpdate(ui->updateCheckBox->isChecked());
Config::setAlwaysShowChangelog(ui->changelogCheckBox->isChecked());
Config::setUpdateChannel(channelMap.value(ui->updateComboBox->currentText()).toStdString());
m_gui_settings->SetValue(gui::gen_checkForUpdates, ui->updateCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_showChangeLog, ui->changelogCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_updateChannel,
channelMap.value(ui->updateComboBox->currentText()));
Config::setChooseHomeTab(
chooseHomeTabMap.value(ui->chooseHomeTabComboBox->currentText()).toStdString());
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
Config::setBackgroundImageOpacity(ui->backgroundImageOpacitySlider->value());
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity,
std::clamp(ui->backgroundImageOpacitySlider->value(), 0, 100));
emit BackgroundOpacityChanged(ui->backgroundImageOpacitySlider->value());
Config::setShowBackgroundImage(ui->showBackgroundImageCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_showBackgroundImage,
ui->showBackgroundImageCheckBox->isChecked());
std::vector<Config::GameInstallDir> dirs_with_states;
for (int i = 0; i < ui->gameFoldersListWidget->count(); i++) {
@@ -862,3 +875,16 @@ void SettingsDialog::ResetInstallFolders() {
Config::setAllGameInstallDirs(settings_install_dirs_config);
}
}
void SettingsDialog::setDefaultValues() {
m_gui_settings->SetValue(gui::gl_showBackgroundImage, true);
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50);
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false);
m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, 50);
m_gui_settings->SetValue(gui::gen_checkForUpdates, false);
m_gui_settings->SetValue(gui::gen_showChangeLog, false);
if (Common::g_is_release) {
m_gui_settings->SetValue(gui::gen_updateChannel, "Release");
} else {
m_gui_settings->SetValue(gui::gen_updateChannel, "Nightly");
}
}

View File

@@ -11,6 +11,7 @@
#include "common/config.h"
#include "common/path_util.h"
#include "gui_settings.h"
#include "qt_gui/compatibility_info.h"
namespace Ui {
@@ -20,7 +21,8 @@ class SettingsDialog;
class SettingsDialog : public QDialog {
Q_OBJECT
public:
explicit SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_info,
explicit SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent = nullptr);
~SettingsDialog();
@@ -42,6 +44,7 @@ private:
void OnLanguageChanged(int index);
void OnCursorStateChanged(s16 index);
void closeEvent(QCloseEvent* event) override;
void setDefaultValues();
std::unique_ptr<Ui::SettingsDialog> ui;
@@ -52,4 +55,5 @@ private:
int initialHeight;
bool is_saving = false;
std::shared_ptr<gui_settings> m_gui_settings;
};