summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2022-03-02 00:38:00 -0600
committeriwubcode <iwubcode@users.noreply.github.com>2022-06-27 18:22:06 -0500
commitf3054aa99f69a71479c9a2e382b9016fbb00df33 (patch)
tree6f39ee37a7083719f8a1c5d4075bc10cefe37237 /Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp
parent1480b78f6478e4da9cc43e146d3b7377b7fe99df (diff)
DolphinQt: add widget in game properties to list the various graphics mods available
Diffstat (limited to 'Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp')
-rw-r--r--Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp b/Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp
new file mode 100644
index 0000000000..8782bbc97d
--- /dev/null
+++ b/Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp
@@ -0,0 +1,268 @@
+// Copyright 2022 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "DolphinQt/Config/GraphicsModListWidget.h"
+
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QListWidget>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <set>
+
+#include "Core/ConfigManager.h"
+#include "Core/Core.h"
+#include "DolphinQt/Settings.h"
+#include "UICommon/GameFile.h"
+#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
+#include "VideoCommon/VideoConfig.h"
+
+GraphicsModListWidget::GraphicsModListWidget(const UICommon::GameFile& game)
+ : m_game_id(game.GetGameID()), m_mod_group(m_game_id)
+{
+ CalculateGameRunning(Core::GetState());
+ if (m_loaded_game_is_running && g_Config.graphics_mod_config)
+ {
+ m_mod_group.SetChangeCount(g_Config.graphics_mod_config->GetChangeCount());
+ }
+ CreateWidgets();
+ ConnectWidgets();
+
+ RefreshModList();
+ OnModChanged(std::nullopt);
+}
+
+GraphicsModListWidget::~GraphicsModListWidget()
+{
+ if (m_needs_save)
+ {
+ m_mod_group.Save();
+ }
+}
+
+void GraphicsModListWidget::CreateWidgets()
+{
+ auto* main_layout = new QHBoxLayout(this);
+
+ auto* left_v_layout = new QVBoxLayout;
+
+ m_mod_list = new QListWidget;
+ m_mod_list->setSortingEnabled(false);
+ m_mod_list->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectItems);
+ m_mod_list->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+ m_mod_list->setSelectionRectVisible(true);
+ m_mod_list->setDragDropMode(QAbstractItemView::InternalMove);
+
+ m_refresh = new QPushButton(tr("&Refresh List"));
+ QHBoxLayout* hlayout = new QHBoxLayout;
+ hlayout->addStretch();
+ hlayout->addWidget(m_refresh);
+
+ left_v_layout->addWidget(m_mod_list);
+ left_v_layout->addLayout(hlayout);
+
+ auto* right_v_layout = new QVBoxLayout;
+
+ m_selected_mod_name = new QLabel();
+ right_v_layout->addWidget(m_selected_mod_name);
+
+ m_mod_meta_layout = new QVBoxLayout;
+ right_v_layout->addLayout(m_mod_meta_layout);
+
+ main_layout->addLayout(left_v_layout);
+ main_layout->addLayout(right_v_layout, 1);
+
+ setLayout(main_layout);
+}
+
+void GraphicsModListWidget::ConnectWidgets()
+{
+ connect(m_mod_list, &QListWidget::itemSelectionChanged, this,
+ &GraphicsModListWidget::ModSelectionChanged);
+
+ connect(m_mod_list, &QListWidget::itemChanged, this, &GraphicsModListWidget::ModItemChanged);
+
+ connect(m_mod_list->model(), &QAbstractItemModel::rowsMoved, this,
+ &GraphicsModListWidget::SaveModList);
+
+ connect(m_refresh, &QPushButton::clicked, this, &GraphicsModListWidget::RefreshModList);
+
+ connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
+ &GraphicsModListWidget::CalculateGameRunning);
+}
+
+void GraphicsModListWidget::RefreshModList()
+{
+ m_mod_list->setCurrentItem(nullptr);
+ m_mod_list->clear();
+
+ m_mod_group = GraphicsModGroupConfig(m_game_id);
+ m_mod_group.Load();
+
+ std::set<std::string> groups;
+
+ for (const auto& mod : m_mod_group.GetMods())
+ {
+ if (mod.m_groups.empty())
+ continue;
+
+ for (const auto& group : mod.m_groups)
+ {
+ groups.insert(group.m_name);
+ }
+ }
+
+ for (const auto& mod : m_mod_group.GetMods())
+ {
+ // Group only mods shouldn't be shown
+ if (mod.m_features.empty())
+ continue;
+
+ // If the group doesn't exist in the available mod's features, skip
+ if (std::none_of(mod.m_features.begin(), mod.m_features.end(),
+ [&groups](const GraphicsModFeatureConfig& feature) {
+ return groups.count(feature.m_group) == 1;
+ }))
+ {
+ continue;
+ }
+
+ QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(mod.m_title));
+ item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
+ item->setData(Qt::UserRole, QString::fromStdString(mod.GetAbsolutePath()));
+ item->setCheckState(mod.m_enabled ? Qt::Checked : Qt::Unchecked);
+
+ m_mod_list->addItem(item);
+ }
+}
+
+void GraphicsModListWidget::ModSelectionChanged()
+{
+ if (m_mod_list->currentItem() == nullptr)
+ return;
+ if (m_mod_list->count() == 0)
+ return;
+ const auto absolute_path = m_mod_list->currentItem()->data(Qt::UserRole).toString().toStdString();
+ OnModChanged(absolute_path);
+}
+
+void GraphicsModListWidget::ModItemChanged(QListWidgetItem* item)
+{
+ const auto absolute_path = item->data(Qt::UserRole).toString();
+ GraphicsModConfig* mod = m_mod_group.GetMod(absolute_path.toStdString());
+ if (!mod)
+ return;
+
+ const bool was_enabled = mod->m_enabled;
+ const bool should_enable = item->checkState() == Qt::Checked;
+ mod->m_enabled = should_enable;
+ if (was_enabled == should_enable)
+ return;
+
+ m_mod_group.SetChangeCount(m_mod_group.GetChangeCount() + 1);
+ if (m_loaded_game_is_running)
+ {
+ g_Config.graphics_mod_config = m_mod_group;
+ }
+ m_needs_save = true;
+}
+
+void GraphicsModListWidget::OnModChanged(std::optional<std::string> absolute_path)
+{
+ ClearLayoutRecursively(m_mod_meta_layout);
+
+ adjustSize();
+
+ if (!absolute_path)
+ {
+ m_selected_mod_name->setText(QStringLiteral("No graphics mod selected"));
+ m_selected_mod_name->setAlignment(Qt::AlignCenter);
+ return;
+ }
+
+ GraphicsModConfig* mod = m_mod_group.GetMod(*absolute_path);
+ if (!mod)
+ return;
+
+ m_selected_mod_name->setText(QString::fromStdString(mod->m_title));
+ m_selected_mod_name->setAlignment(Qt::AlignLeft);
+ QFont font = m_selected_mod_name->font();
+ font.setWeight(QFont::Bold);
+ m_selected_mod_name->setFont(font);
+
+ if (!mod->m_author.empty())
+ {
+ auto* author_label = new QLabel(tr("By: ") + QString::fromStdString(mod->m_author));
+ m_mod_meta_layout->addWidget(author_label);
+ }
+
+ if (!mod->m_description.empty())
+ {
+ auto* description_label =
+ new QLabel(tr("Description: ") + QString::fromStdString(mod->m_description));
+ m_mod_meta_layout->addWidget(description_label);
+ }
+}
+
+void GraphicsModListWidget::SaveModList()
+{
+ for (int i = 0; i < m_mod_list->count(); i++)
+ {
+ const auto absolute_path = m_mod_list->model()
+ ->data(m_mod_list->model()->index(i, 0), Qt::UserRole)
+ .toString()
+ .toStdString();
+ m_mod_group.GetMod(absolute_path)->m_weight = i;
+ }
+
+ if (m_loaded_game_is_running)
+ {
+ g_Config.graphics_mod_config = m_mod_group;
+ }
+ m_needs_save = true;
+}
+
+void GraphicsModListWidget::ClearLayoutRecursively(QLayout* layout)
+{
+ while (QLayoutItem* child = layout->takeAt(0))
+ {
+ if (child == nullptr)
+ continue;
+
+ if (child->widget())
+ {
+ layout->removeWidget(child->widget());
+ delete child->widget();
+ }
+ else if (child->layout())
+ {
+ ClearLayoutRecursively(child->layout());
+ layout->removeItem(child);
+ }
+ else
+ {
+ layout->removeItem(child);
+ }
+ delete child;
+ }
+}
+
+void GraphicsModListWidget::SaveToDisk()
+{
+ m_needs_save = false;
+ m_mod_group.Save();
+}
+
+const GraphicsModGroupConfig& GraphicsModListWidget::GetGraphicsModConfig() const
+{
+ return m_mod_group;
+}
+
+void GraphicsModListWidget::CalculateGameRunning(Core::State state)
+{
+ m_loaded_game_is_running =
+ state == Core::State::Running ? m_game_id == SConfig::GetInstance().GetGameID() : false;
+}