summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp
diff options
context:
space:
mode:
authorspycrab <spycrab@users.noreply.github.com>2018-07-07 00:40:15 +0200
committerspycrab <spycrab@users.noreply.github.com>2018-07-07 00:48:38 +0200
commit13ba24c5a6795532c8893eccf2a21ae95682e1b7 (patch)
tree747e394036c189c46add1b3e1451e50f48230e11 /Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp
parent059880bb1640d5a3b0e1fbbf66e1a356df4b9f41 (diff)
Move DolphinQt2 to DolphinQt
Diffstat (limited to 'Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp')
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp362
1 files changed, 362 insertions, 0 deletions
diff --git a/Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp b/Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp
new file mode 100644
index 0000000000..bcc2c83425
--- /dev/null
+++ b/Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp
@@ -0,0 +1,362 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt/Config/Graphics/PostProcessingConfigWindow.h"
+
+#include <cmath>
+#include <vector>
+
+#include <QCheckBox>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QSlider>
+#include <QString>
+#include <QTabWidget>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include "DolphinQt/Config/Graphics/EnhancementsWidget.h"
+
+#include "VideoCommon/PostProcessing.h"
+#include "VideoCommon/RenderBase.h"
+#include "VideoCommon/VideoConfig.h"
+
+using ConfigurationOption = PostProcessingShaderConfiguration::ConfigurationOption;
+using OptionType = ConfigurationOption::OptionType;
+
+PostProcessingConfigWindow::PostProcessingConfigWindow(EnhancementsWidget* parent,
+ const std::string& shader)
+ : QDialog(parent), m_shader(shader)
+{
+ if (g_renderer && g_renderer->GetPostProcessor())
+ {
+ m_post_processor = g_renderer->GetPostProcessor()->GetConfig();
+ }
+ else
+ {
+ m_post_processor = new PostProcessingShaderConfiguration();
+ m_post_processor->LoadShader(m_shader);
+ }
+
+ setWindowTitle(tr("Post Processing Shader Configuration"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ PopulateGroups();
+ Create();
+ ConnectWidgets();
+}
+
+PostProcessingConfigWindow::~PostProcessingConfigWindow()
+{
+ m_post_processor->SaveOptionsConfiguration();
+ if (!(g_renderer && g_renderer->GetPostProcessor()))
+ {
+ delete m_post_processor;
+ }
+}
+
+void PostProcessingConfigWindow::PopulateGroups()
+{
+ const PostProcessingShaderConfiguration::ConfigMap& config_map = m_post_processor->GetOptions();
+
+ auto config_groups = std::vector<std::unique_ptr<ConfigGroup>>();
+ for (const auto& it : config_map)
+ {
+ auto config_group = std::make_unique<ConfigGroup>(&it.second);
+ m_config_map[it.first] = config_group.get();
+ config_groups.push_back(std::move(config_group));
+ }
+
+ for (auto& config_group : config_groups)
+ {
+ const std::string& parent_name = config_group->GetParent();
+ if (parent_name.empty())
+ {
+ m_config_groups.emplace_back(std::move(config_group));
+ }
+ else
+ {
+ m_config_map[parent_name]->AddSubGroup(std::move(config_group));
+ }
+ }
+}
+
+void PostProcessingConfigWindow::Create()
+{
+ m_tabs = new QTabWidget();
+ auto* const general = new QWidget(m_tabs);
+ auto* const general_layout = new QGridLayout(general);
+
+ u32 row = 0;
+ bool add_general_page = false;
+ for (const auto& it : m_config_groups)
+ {
+ if (it->HasSubGroups())
+ {
+ auto* const tab = CreateDependentTab(it);
+ m_tabs->addTab(tab, QString::fromStdString(it->GetGUIName()));
+ }
+ else
+ {
+ if (!add_general_page)
+ {
+ add_general_page = true;
+ }
+ row = it->AddWidgets(this, general_layout, row);
+ }
+ }
+
+ if (add_general_page)
+ {
+ m_tabs->insertTab(0, general, tr("General"));
+ }
+
+ m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok);
+
+ auto* layout = new QVBoxLayout(this);
+ layout->addWidget(m_tabs);
+ layout->addWidget(m_buttons);
+}
+
+void PostProcessingConfigWindow::ConnectWidgets()
+{
+ connect(m_buttons, &QDialogButtonBox::accepted, this, &PostProcessingConfigWindow::accept);
+}
+
+QWidget*
+PostProcessingConfigWindow::CreateDependentTab(const std::unique_ptr<ConfigGroup>& config_group)
+{
+ auto* const tab = new QWidget(m_tabs);
+ auto* const layout = new QGridLayout(tab);
+
+ u32 row = config_group->AddWidgets(this, layout, 0);
+ for (const auto& child : config_group->GetSubGroups())
+ {
+ row = child->AddWidgets(this, layout, row);
+ }
+
+ return tab;
+}
+
+void PostProcessingConfigWindow::UpdateBool(ConfigGroup* const config_group, const bool state)
+{
+ m_post_processor->SetOptionb(config_group->GetOptionName(), state);
+
+ config_group->EnableSuboptions(state);
+}
+
+void PostProcessingConfigWindow::UpdateInteger(ConfigGroup* const config_group, const int value)
+{
+ const ConfigurationOption& config_option =
+ m_post_processor->GetOption(config_group->GetOptionName());
+
+ const size_t vector_size = config_option.m_integer_values.size();
+
+ for (size_t i = 0; i < vector_size; ++i)
+ {
+ const int current_step = config_group->GetSliderValue(i);
+ const s32 current_value = config_option.m_integer_step_values[i] * current_step +
+ config_option.m_integer_min_values[i];
+ m_post_processor->SetOptioni(config_option.m_option_name, static_cast<int>(i), current_value);
+ config_group->SetSliderText(i, QString::number(current_value));
+ }
+}
+
+void PostProcessingConfigWindow::UpdateFloat(ConfigGroup* const config_group, const int value)
+{
+ const ConfigurationOption& config_option =
+ m_post_processor->GetOption(config_group->GetOptionName());
+
+ const size_t vector_size = config_option.m_float_values.size();
+
+ for (size_t i = 0; i < vector_size; ++i)
+ {
+ const int current_step = config_group->GetSliderValue(static_cast<unsigned int>(i));
+ const float current_value =
+ config_option.m_float_step_values[i] * current_step + config_option.m_float_min_values[i];
+ m_post_processor->SetOptionf(config_option.m_option_name, static_cast<int>(i), current_value);
+ config_group->SetSliderText(i, QString::asprintf("%f", current_value));
+ }
+}
+
+PostProcessingConfigWindow::ConfigGroup::ConfigGroup(const ConfigurationOption* config_option)
+ : m_config_option(config_option)
+{
+}
+
+const std::string& PostProcessingConfigWindow::ConfigGroup::GetGUIName() const noexcept
+{
+ return m_config_option->m_gui_name;
+}
+
+const std::string& PostProcessingConfigWindow::ConfigGroup::GetParent() const noexcept
+{
+ return m_config_option->m_dependent_option;
+}
+
+const std::string& PostProcessingConfigWindow::ConfigGroup::GetOptionName() const noexcept
+{
+ return m_config_option->m_option_name;
+}
+
+void PostProcessingConfigWindow::ConfigGroup::AddSubGroup(std::unique_ptr<ConfigGroup>&& subgroup)
+{
+ m_subgroups.emplace_back(std::move(subgroup));
+}
+
+bool PostProcessingConfigWindow::ConfigGroup::HasSubGroups() const noexcept
+{
+ return !m_subgroups.empty();
+}
+
+const std::vector<std::unique_ptr<PostProcessingConfigWindow::ConfigGroup>>&
+PostProcessingConfigWindow::ConfigGroup::GetSubGroups() const noexcept
+{
+ return m_subgroups;
+}
+
+u32 PostProcessingConfigWindow::ConfigGroup::AddWidgets(PostProcessingConfigWindow* const parent,
+ QGridLayout* const grid, const u32 row)
+{
+ auto* const name = new QLabel(QString::fromStdString(m_config_option->m_gui_name));
+ grid->addWidget(name, row, 0);
+
+ switch (m_config_option->m_type)
+ {
+ case OptionType::OPTION_BOOL:
+ return AddBool(parent, grid, row);
+ case OptionType::OPTION_FLOAT:
+ return AddFloat(parent, grid, row);
+ case OptionType::OPTION_INTEGER:
+ return AddInteger(parent, grid, row);
+ default:
+ // obviously shouldn't get here
+ std::abort();
+ }
+}
+
+u32 PostProcessingConfigWindow::ConfigGroup::AddBool(PostProcessingConfigWindow* const parent,
+ QGridLayout* const grid, const u32 row)
+{
+ m_checkbox = new QCheckBox();
+ m_checkbox->setChecked(m_config_option->m_bool_value);
+ QObject::connect(m_checkbox, &QCheckBox::toggled,
+ [this, parent](bool checked) { parent->UpdateBool(this, checked); });
+ grid->addWidget(m_checkbox, row, 2);
+
+ return row + 1;
+}
+
+u32 PostProcessingConfigWindow::ConfigGroup::AddInteger(PostProcessingConfigWindow* const parent,
+ QGridLayout* const grid, u32 row)
+{
+ const size_t vector_size = m_config_option->m_integer_values.size();
+
+ for (size_t i = 0; i < vector_size; ++i)
+ {
+ const int current_value = m_config_option->m_integer_values[i];
+ const double range =
+ m_config_option->m_integer_max_values[i] - m_config_option->m_integer_min_values[i];
+ // "How many steps we have is the range divided by the step interval configured.
+ // This may not be 100% spot on accurate since developers can have odd stepping intervals
+ // set.
+ // Round up so if it is outside our range, then set it to the minimum or maximum"
+ const int steps =
+ std::ceil(range / static_cast<double>(m_config_option->m_integer_step_values[i]));
+
+ auto* const slider = new QSlider(Qt::Orientation::Horizontal);
+ slider->setMinimum(0);
+ slider->setMaximum(steps);
+ slider->setValue(current_value);
+ slider->setTickInterval(range / steps);
+ QObject::connect(slider, &QSlider::valueChanged,
+ [this, parent](int value) { parent->UpdateInteger(this, value); });
+
+ auto* const value_box = new QLineEdit(QString::number(current_value));
+ value_box->setEnabled(false);
+
+ grid->addWidget(slider, row, 1);
+ grid->addWidget(value_box, row, 2);
+
+ m_sliders.push_back(slider);
+ m_value_boxes.push_back(value_box);
+ if (vector_size > 1)
+ {
+ row++;
+ }
+ }
+
+ return row + 1;
+}
+
+u32 PostProcessingConfigWindow::ConfigGroup::AddFloat(PostProcessingConfigWindow* const parent,
+ QGridLayout* const grid, u32 row)
+{
+ const size_t vector_size = m_config_option->m_float_values.size();
+
+ for (size_t i = 0; i < vector_size; ++i)
+ {
+ const int current_value =
+ m_config_option->m_float_values[i] / m_config_option->m_float_step_values[i];
+ const float range =
+ m_config_option->m_float_max_values[i] - m_config_option->m_float_min_values[i];
+ const int steps = std::ceil(range / m_config_option->m_float_step_values[i]);
+
+ auto* const slider = new QSlider(Qt::Orientation::Horizontal);
+ slider->setMinimum(0);
+ slider->setMaximum(steps);
+ slider->setValue(current_value);
+ slider->setTickInterval(range / steps);
+ QObject::connect(slider, &QSlider::valueChanged,
+ [this, parent](int value) { parent->UpdateFloat(this, value); });
+
+ auto* const value_box =
+ new QLineEdit(QString::asprintf("%f", m_config_option->m_float_values[i]));
+ value_box->setEnabled(false);
+
+ grid->addWidget(slider, row, 1);
+ grid->addWidget(value_box, row, 2);
+
+ m_sliders.push_back(slider);
+ m_value_boxes.push_back(value_box);
+ if (vector_size > 1)
+ {
+ row++;
+ }
+ }
+
+ return row + 1;
+}
+
+void PostProcessingConfigWindow::ConfigGroup::EnableSuboptions(const bool state)
+{
+ for (auto& it : m_subgroups)
+ {
+ if (it->m_config_option->m_type == OptionType::OPTION_BOOL)
+ {
+ it->m_checkbox->setEnabled(state);
+ }
+ else
+ {
+ for (auto& slider : it->m_sliders)
+ {
+ slider->setEnabled(state);
+ }
+ }
+ it->EnableSuboptions(state);
+ }
+}
+
+int PostProcessingConfigWindow::ConfigGroup::GetSliderValue(size_t index) const
+{
+ return m_sliders[index]->value();
+}
+
+void PostProcessingConfigWindow::ConfigGroup::SetSliderText(size_t index, const QString& text)
+{
+ m_value_boxes[index]->setText(text);
+}