diff options
| author | iwubcode <iwubcode@users.noreply.github.com> | 2022-03-02 00:38:00 -0600 |
|---|---|---|
| committer | iwubcode <iwubcode@users.noreply.github.com> | 2022-06-27 18:22:06 -0500 |
| commit | f3054aa99f69a71479c9a2e382b9016fbb00df33 (patch) | |
| tree | 6f39ee37a7083719f8a1c5d4075bc10cefe37237 /Source/Core/DolphinQt/Config/GraphicsModListWidget.cpp | |
| parent | 1480b78f6478e4da9cc43e146d3b7377b7fe99df (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.cpp | 268 |
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; +} |
