#include "postprocessingshaderconfigwidget.h" #include #include #include #include #include using FrontendCommon::PostProcessingShader; PostProcessingShaderConfigWidget::PostProcessingShaderConfigWidget(QWidget* parent, FrontendCommon::PostProcessingShader* shader) : QWidget(parent), m_shader(shader) { createUi(); } PostProcessingShaderConfigWidget::~PostProcessingShaderConfigWidget() = default; void PostProcessingShaderConfigWidget::createUi() { m_layout = new QGridLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); u32 row = 0; for (PostProcessingShader::Option& option : m_shader->GetOptions()) { if (option.type == PostProcessingShader::Option::Type::Bool) { QCheckBox* checkbox = new QCheckBox(QString::fromStdString(option.ui_name), this); checkbox->setChecked(option.value[0].int_value != 0); connect(checkbox, &QCheckBox::stateChanged, [this, &option](int state) { option.value[0].int_value = (state == Qt::Checked) ? 1 : 0; configChanged(); }); connect(this, &PostProcessingShaderConfigWidget::resettingtoDefaults, [&option, checkbox]() { QSignalBlocker sb(checkbox); checkbox->setChecked(option.default_value[0].int_value != 0); option.value = option.default_value; }); m_layout->addWidget(checkbox, row, 0, 1, 3, Qt::AlignLeft); row++; } else { for (u32 i = 0; i < option.vector_size; i++) { QString label; if (option.vector_size <= 1) { label = QStringLiteral("%1").arg(QString::fromStdString(option.ui_name)); } else { static constexpr std::array suffixes = { {QT_TR_NOOP("Red"), QT_TR_NOOP("Green"), QT_TR_NOOP("Blue"), QT_TR_NOOP("Alpha")}}; label = tr("%1 (%2)").arg(QString::fromStdString(option.ui_name)).arg(tr(suffixes[i])); } m_layout->addWidget(new QLabel(label, this), row, 0, 1, 1, Qt::AlignLeft); QSlider* slider = new QSlider(Qt::Horizontal, this); m_layout->addWidget(slider, row, 1, 1, 1, Qt::AlignLeft); QLabel* slider_label = new QLabel(this); m_layout->addWidget(slider_label, row, 2, 1, 1, Qt::AlignLeft); if (option.type == PostProcessingShader::Option::Type::Int) { slider_label->setText(QStringLiteral("%1").arg(option.value[i].int_value)); const int range = std::max(option.max_value[i].int_value - option.min_value[i].int_value, 1); const int step_value = (option.step_value[i].int_value != 0) ? option.step_value[i].int_value : ((range + 99) / 100); const int num_steps = range / step_value; slider->setMinimum(0); slider->setMaximum(num_steps); slider->setSingleStep(1); slider->setTickInterval(step_value); slider->setValue((option.value[i].int_value - option.min_value[i].int_value) / step_value); connect(slider, &QSlider::valueChanged, [this, &option, i, slider_label, step_value](int value) { const int new_value = std::clamp(option.min_value[i].int_value + (value * option.step_value[i].int_value), option.min_value[i].int_value, option.max_value[i].int_value); option.value[i].int_value = new_value; slider_label->setText(QStringLiteral("%1").arg(new_value)); configChanged(); }); connect(this, &PostProcessingShaderConfigWidget::resettingtoDefaults, [&option, i, slider, slider_label, step_value]() { QSignalBlocker sb(slider); slider->setValue((option.default_value[i].int_value - option.min_value[i].int_value) / step_value); slider_label->setText(QStringLiteral("%1").arg(option.default_value[i].int_value)); option.value = option.default_value; }); } else { slider_label->setText(QStringLiteral("%1").arg(option.value[i].float_value)); const float range = std::max(option.max_value[i].float_value - option.min_value[i].float_value, 1.0f); const float step_value = (option.step_value[i].float_value != 0) ? option.step_value[i].float_value : ((range + 99.0f) / 100.0f); const float num_steps = range / step_value; slider->setMinimum(0); slider->setMaximum(num_steps); slider->setSingleStep(1); slider->setTickInterval(step_value); slider->setValue( static_cast((option.value[i].float_value - option.min_value[i].float_value) / step_value)); connect(slider, &QSlider::valueChanged, [this, &option, i, slider_label, step_value](int value) { const float new_value = std::clamp(option.min_value[i].float_value + (static_cast(value) * option.step_value[i].float_value), option.min_value[i].float_value, option.max_value[i].float_value); option.value[i].float_value = new_value; slider_label->setText(QStringLiteral("%1").arg(new_value)); configChanged(); }); connect(this, &PostProcessingShaderConfigWidget::resettingtoDefaults, [&option, i, slider, slider_label, step_value]() { QSignalBlocker sb(slider); slider->setValue(static_cast( (option.default_value[i].float_value - option.min_value[i].float_value) / step_value)); slider_label->setText(QStringLiteral("%1").arg(option.default_value[i].float_value)); option.value = option.default_value; }); } row++; } } } QPushButton* reset_button = new QPushButton(tr("Reset to Defaults"), this); connect(reset_button, &QPushButton::clicked, this, &PostProcessingShaderConfigWidget::onResetToDefaultsClicked); m_layout->addWidget(reset_button, row, 0, 1, 1); } void PostProcessingShaderConfigWidget::onResetToDefaultsClicked() { resettingtoDefaults(); configChanged(); } PostProcessingShaderConfigDialog::PostProcessingShaderConfigDialog(QWidget* parent, FrontendCommon::PostProcessingShader* shader) : QDialog(parent) { setWindowTitle(tr("%1 Shader Options").arg(QString::fromStdString(shader->GetName()))); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QGridLayout* layout = new QGridLayout(this); m_widget = new PostProcessingShaderConfigWidget(this, shader); layout->addWidget(m_widget); connect(m_widget, &PostProcessingShaderConfigWidget::configChanged, this, &PostProcessingShaderConfigDialog::onConfigChanged); QPushButton* close_button = new QPushButton(tr("Close"), this); connect(close_button, &QPushButton::clicked, this, &PostProcessingShaderConfigDialog::onCloseClicked); m_widget->getLayout()->addWidget(close_button, m_widget->getLayout()->rowCount() - 1, 2, 1, 2); } PostProcessingShaderConfigDialog::~PostProcessingShaderConfigDialog() = default; void PostProcessingShaderConfigDialog::onConfigChanged() { configChanged(); } void PostProcessingShaderConfigDialog::onCloseClicked() { done(0); }