From 6d2680d5a3c990dbe2d679086cc8d9a9a46fb077 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 10 Mar 2023 10:42:50 +0200 Subject: [PATCH] abstracting setting class and more wokr on gamelist class --- shadPS4/gui/game_list_frame.cpp | 48 ++++++++++++++++- shadPS4/gui/game_list_frame.h | 3 +- shadPS4/gui/gui_save.h | 30 +++++++++++ shadPS4/gui/gui_settings.cpp | 16 +++++- shadPS4/gui/gui_settings.h | 40 ++++++++++++-- shadPS4/gui/settings.cpp | 94 +++++++++++++++++++++++++++++++++ shadPS4/gui/settings.h | 48 +++++++++++++++++ shadPS4/gui/shadps4gui.cpp | 2 +- shadPS4/shadPS4.vcxproj | 5 +- shadPS4/shadPS4.vcxproj.filters | 15 ++++-- 10 files changed, 289 insertions(+), 12 deletions(-) create mode 100644 shadPS4/gui/gui_save.h create mode 100644 shadPS4/gui/settings.cpp create mode 100644 shadPS4/gui/settings.h diff --git a/shadPS4/gui/game_list_frame.cpp b/shadPS4/gui/game_list_frame.cpp index 2cb10e98..fd9ca1db 100644 --- a/shadPS4/gui/game_list_frame.cpp +++ b/shadPS4/gui/game_list_frame.cpp @@ -1,8 +1,9 @@ #include "game_list_frame.h" #include "gui_settings.h" -game_list_frame::game_list_frame(QWidget* parent) +game_list_frame::game_list_frame(std::shared_ptr gui_settings,QWidget* parent) : QWidget(parent) + , m_gui_settings(std::move(gui_settings)) { m_game_list = new game_list_table(); m_game_list->setShowGrid(false); @@ -34,6 +35,51 @@ game_list_frame::game_list_frame(QWidget* parent) layout->addWidget(m_game_list); setLayout(layout); //endof temp code + + // Actions regarding showing/hiding columns + auto add_column = [this](gui::game_list_columns col, const QString& header_text, const QString& action_text) + { + m_game_list->setHorizontalHeaderItem(col, new QTableWidgetItem(header_text)); + m_columnActs.append(new QAction(action_text, this)); + }; + + add_column(gui::column_icon, tr("Icon"), tr("Show Icons")); + add_column(gui::column_name, tr("Name"), tr("Show Names")); + add_column(gui::column_serial, tr("Serial"), tr("Show Serials")); + add_column(gui::column_firmware, tr("Firmware"), tr("Show Firmwares")); + add_column(gui::column_version, tr("Version"), tr("Show Versions")); + add_column(gui::column_category, tr("Category"), tr("Show Categories")); + add_column(gui::column_path, tr("Path"), tr("Show Paths")); + + for (int col = 0; col < m_columnActs.count(); ++col) + { + m_columnActs[col]->setCheckable(true); + + connect(m_columnActs[col], &QAction::triggered, this, [this, col](bool checked) + { + if (!checked) // be sure to have at least one column left so you can call the context menu at all time + { + int c = 0; + for (int i = 0; i < m_columnActs.count(); ++i) + { + if (m_gui_settings->GetGamelistColVisibility(i) && ++c > 1) + break; + } + if (c < 2) + { + m_columnActs[col]->setChecked(true); // re-enable the checkbox if we don't change the actual state + return; + } + } + m_game_list->setColumnHidden(col, !checked); // Negate because it's a set col hidden and we have menu say show. + m_gui_settings->SetGamelistColVisibility(col, checked); + + if (checked) // handle hidden columns that have zero width after showing them (stuck between others) + { + FixNarrowColumns(); + } + }); + } } game_list_frame::~game_list_frame(){ diff --git a/shadPS4/gui/game_list_frame.h b/shadPS4/gui/game_list_frame.h index 48dd7c08..4f8e610d 100644 --- a/shadPS4/gui/game_list_frame.h +++ b/shadPS4/gui/game_list_frame.h @@ -11,7 +11,7 @@ class game_list_frame : public QWidget { Q_OBJECT public : - explicit game_list_frame(QWidget* parent = nullptr); + explicit game_list_frame(std::shared_ptr gui_settings,QWidget* parent = nullptr); ~game_list_frame(); /** Fix columns with width smaller than the minimal section size */ void FixNarrowColumns() const; @@ -29,6 +29,7 @@ private: int m_sort_column; // data + std::shared_ptr m_gui_settings; QList m_game_data; // Icons diff --git a/shadPS4/gui/gui_save.h b/shadPS4/gui/gui_save.h new file mode 100644 index 00000000..66970172 --- /dev/null +++ b/shadPS4/gui/gui_save.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +struct gui_save +{ + QString key; + QString name; + QVariant def; + + gui_save() + { + key = ""; + name = ""; + def = QVariant(); + } + + gui_save(const QString& k, const QString& n, const QVariant& d) + { + key = k; + name = n; + def = d; + } + + bool operator==(const gui_save& rhs) const noexcept + { + return key == rhs.key && name == rhs.name && def == rhs.def; + } +}; diff --git a/shadPS4/gui/gui_settings.cpp b/shadPS4/gui/gui_settings.cpp index 4baf9373..3be2dfd1 100644 --- a/shadPS4/gui/gui_settings.cpp +++ b/shadPS4/gui/gui_settings.cpp @@ -3,6 +3,20 @@ gui_settings::gui_settings(QObject* parent) { - m_settings.reset(new QSettings("shadps4.ini", QSettings::Format::IniFormat, parent)); + m_settings.reset(new QSettings("shadps4.ini", QSettings::Format::IniFormat, parent)); //TODO make the path configurable } +void gui_settings::SetGamelistColVisibility(int col, bool val) const +{ + SetValue(GetGuiSaveForColumn(col), val); +} + +bool gui_settings::GetGamelistColVisibility(int col) const +{ + return GetValue(GetGuiSaveForColumn(col)).toBool(); +} + +gui_save gui_settings::GetGuiSaveForColumn(int col) +{ + return gui_save{ gui::game_list, "visibility_" + gui::get_game_list_column_name(static_cast(col)), true }; +} \ No newline at end of file diff --git a/shadPS4/gui/gui_settings.h b/shadPS4/gui/gui_settings.h index 831b6183..57f5e9b9 100644 --- a/shadPS4/gui/gui_settings.h +++ b/shadPS4/gui/gui_settings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "settings.h" namespace gui { @@ -17,15 +17,47 @@ namespace gui column_count }; + inline QString get_game_list_column_name(game_list_columns col) + { + switch (col) + { + case column_icon: + return "column_icon"; + case column_name: + return "column_name"; + case column_serial: + return "column_serial"; + case column_firmware: + return "column_firmware"; + case column_version: + return "column_version"; + case column_category: + return "column_category"; + case column_path: + return "column_path"; + case column_count: + return ""; + } + + throw std::exception("get_game_list_column_name: Invalid column"); + } + + const QString game_list = "GameList"; + } -class gui_settings +class gui_settings : public settings { + Q_OBJECT public: explicit gui_settings(QObject* parent = nullptr); -private: - std::unique_ptr m_settings; + bool GetGamelistColVisibility(int col) const; + + +public Q_SLOTS: + void SetGamelistColVisibility(int col, bool val) const; + static gui_save GetGuiSaveForColumn(int col); }; diff --git a/shadPS4/gui/settings.cpp b/shadPS4/gui/settings.cpp new file mode 100644 index 00000000..9867b2d7 --- /dev/null +++ b/shadPS4/gui/settings.cpp @@ -0,0 +1,94 @@ +#include "settings.h" + +settings::settings(QObject* parent) : QObject(parent), +m_settings_dir(ComputeSettingsDir()) +{ +} + +settings::~settings() +{ + if (m_settings) + { + m_settings->sync(); + } +} + +QString settings::GetSettingsDir() const +{ + return m_settings_dir.absolutePath(); +} + +QString settings::ComputeSettingsDir() +{ + return ""; //TODO currently we configure same dir , make it configurable +} + +void settings::RemoveValue(const QString& key, const QString& name) const +{ + if (m_settings) + { + m_settings->beginGroup(key); + m_settings->remove(name); + m_settings->endGroup(); + } +} + +void settings::RemoveValue(const gui_save& entry) const +{ + RemoveValue(entry.key, entry.name); +} + +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_save& entry) const +{ + return GetValue(entry.key, entry.name, entry.def); +} + +QVariant settings::List2Var(const q_pair_list& list) +{ + QByteArray ba; + QDataStream stream(&ba, QIODevice::WriteOnly); + stream << list; + return QVariant(ba); +} + +q_pair_list settings::Var2List(const QVariant& var) +{ + q_pair_list list; + QByteArray ba = var.toByteArray(); + QDataStream stream(&ba, QIODevice::ReadOnly); + stream >> list; + return list; +} + +void settings::SetValue(const gui_save& entry, const QVariant& value) const +{ + if (m_settings) + { + m_settings->beginGroup(entry.key); + m_settings->setValue(entry.name, value); + m_settings->endGroup(); + } +} + +void settings::SetValue(const QString& key, const QVariant& value) const +{ + if (m_settings) + { + m_settings->setValue(key, value); + } +} + +void settings::SetValue(const QString& key, const QString& name, const QVariant& value) const +{ + if (m_settings) + { + m_settings->beginGroup(key); + m_settings->setValue(name, value); + m_settings->endGroup(); + } +} diff --git a/shadPS4/gui/settings.h b/shadPS4/gui/settings.h new file mode 100644 index 00000000..7116edab --- /dev/null +++ b/shadPS4/gui/settings.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include "gui_save.h" + +typedef QPair q_string_pair; +typedef QPair q_size_pair; +typedef QList q_pair_list; +typedef QList q_size_list; + +// Parent Class for GUI settings +class settings : public QObject +{ + Q_OBJECT + +public: + explicit settings(QObject* parent = nullptr); + ~settings(); + + QString GetSettingsDir() const; + + QVariant GetValue(const QString& key, const QString& name, const QVariant& def) const; + QVariant GetValue(const gui_save& entry) const; + static QVariant List2Var(const q_pair_list& list); + static q_pair_list Var2List(const QVariant& var); + +public Q_SLOTS: + /** Remove entry */ + void RemoveValue(const QString& key, const QString& name) const; + void RemoveValue(const gui_save& entry) const; + + /** Write value to entry */ + void SetValue(const gui_save& entry, const QVariant& value) const; + void SetValue(const QString& key, const QVariant& value) const; + void SetValue(const QString& key, const QString& name, const QVariant& value) const; + +protected: + static QString ComputeSettingsDir(); + + std::unique_ptr m_settings; + QDir m_settings_dir; +}; \ No newline at end of file diff --git a/shadPS4/gui/shadps4gui.cpp b/shadPS4/gui/shadps4gui.cpp index c10d2eb1..9827e6b9 100644 --- a/shadPS4/gui/shadps4gui.cpp +++ b/shadPS4/gui/shadps4gui.cpp @@ -17,7 +17,7 @@ shadps4gui::shadps4gui(std::shared_ptr gui_settings, QWidget* pare //ui.horizontalLayout->addWidget(game_list); //show(); //game_list->PopulateAsync(); - game_list_frame* game_list2 = new game_list_frame(); + game_list_frame* game_list2 = new game_list_frame(m_gui_settings); ui.horizontalLayout->addWidget(game_list2); show(); } diff --git a/shadPS4/shadPS4.vcxproj b/shadPS4/shadPS4.vcxproj index 802acab7..3223ef46 100644 --- a/shadPS4/shadPS4.vcxproj +++ b/shadPS4/shadPS4.vcxproj @@ -22,6 +22,7 @@ + @@ -45,7 +46,9 @@ - + + + diff --git a/shadPS4/shadPS4.vcxproj.filters b/shadPS4/shadPS4.vcxproj.filters index 7e510f3c..e62e16b6 100644 --- a/shadPS4/shadPS4.vcxproj.filters +++ b/shadPS4/shadPS4.vcxproj.filters @@ -74,6 +74,9 @@ gui + + gui + @@ -93,6 +96,12 @@ gui + + gui + + + gui + @@ -110,9 +119,6 @@ emulator\fileFormat - - gui - Header Files @@ -125,6 +131,9 @@ gui + + gui +