You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
6.8 KiB
254 lines
6.8 KiB
/*
|
|
Copyright 2020-2021 Brad Parker
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#include <QCloseEvent>
|
|
#include <QResizeEvent>
|
|
#include <QPainter>
|
|
#include <QScrollArea>
|
|
#include <QVBoxLayout>
|
|
#include <QFormLayout>
|
|
#include <QComboBox>
|
|
#include <QToolButton>
|
|
#include <QAction>
|
|
#include <QTimer>
|
|
#include <QLabel>
|
|
|
|
#include "coreoptionsdialog.h"
|
|
#include "core.h"
|
|
|
|
// adapted from RetroArch's core options dialog that I originally wrote here: https://github.com/libretro/RetroArch/blob/v1.8.6/ui/drivers/qt/coreoptionsdialog.cpp
|
|
|
|
CoreOptionsDialog::CoreOptionsDialog(QWidget *parent, Core *core) :
|
|
QDialog(parent)
|
|
,m_layout()
|
|
,m_scrollArea()
|
|
,m_core(core)
|
|
{
|
|
setWindowTitle(tr("Core Options"));
|
|
setWindowFlags(Qt::Widget); // no close button exists otherwise
|
|
setObjectName("coreOptionsDialog");
|
|
|
|
resize(720, 480);
|
|
|
|
QTimer::singleShot(0, this, SLOT(clearLayout()));
|
|
}
|
|
|
|
CoreOptionsDialog::~CoreOptionsDialog() {
|
|
}
|
|
|
|
void CoreOptionsDialog::resizeEvent(QResizeEvent *event) {
|
|
QDialog::resizeEvent(event);
|
|
|
|
if(!m_scrollArea)
|
|
return;
|
|
|
|
m_scrollArea->resize(event->size());
|
|
|
|
emit resized(event->size());
|
|
}
|
|
|
|
void CoreOptionsDialog::closeEvent(QCloseEvent *event) {
|
|
QDialog::closeEvent(event);
|
|
|
|
emit closed();
|
|
}
|
|
|
|
void CoreOptionsDialog::paintEvent(QPaintEvent *event) {
|
|
QStyleOption o;
|
|
QPainter p;
|
|
o.initFrom(this);
|
|
p.begin(this);
|
|
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
|
|
p.end();
|
|
|
|
QDialog::paintEvent(event);
|
|
}
|
|
|
|
void CoreOptionsDialog::clearLayout() {
|
|
QWidget *widget = nullptr;
|
|
|
|
if(m_scrollArea) {
|
|
for(QObject *obj : children()) {
|
|
obj->deleteLater();
|
|
}
|
|
}
|
|
|
|
m_layout = new QVBoxLayout();
|
|
|
|
widget = new QWidget();
|
|
widget->setLayout(m_layout);
|
|
widget->setObjectName("coreOptionsWidget");
|
|
|
|
m_scrollArea = new QScrollArea();
|
|
|
|
m_scrollArea->setParent(this);
|
|
m_scrollArea->setWidgetResizable(true);
|
|
m_scrollArea->setWidget(widget);
|
|
m_scrollArea->setObjectName("coreOptionsScrollArea");
|
|
m_scrollArea->show();
|
|
}
|
|
|
|
void CoreOptionsDialog::reload() {
|
|
buildLayout();
|
|
}
|
|
|
|
void CoreOptionsDialog::onCoreOptionComboBoxCurrentIndexChanged(int index) {
|
|
QMap<QString, Core::CoreOption> &coreOptions = m_core->getCoreOptions();
|
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
|
QString key, val;
|
|
|
|
if(!comboBox)
|
|
return;
|
|
|
|
key = comboBox->itemData(index, Qt::UserRole).toString();
|
|
val = comboBox->itemText(index);
|
|
|
|
if(coreOptions.size() > 0) {
|
|
Core::CoreOption &option = coreOptions[key];
|
|
|
|
for(int k = 0; k < option.values.size(); k++) {
|
|
QString str = option.values.at(k);
|
|
|
|
if(!str.isEmpty() && str == val) {
|
|
option.val = str;
|
|
option.valArray = option.val.toUtf8();
|
|
option.valData = option.valArray.constData();
|
|
|
|
m_core->setVariablesChanged(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CoreOptionsDialog::buildLayout() {
|
|
QFormLayout *form = nullptr;
|
|
const QMap<QString, Core::CoreOption> &coreOptions = m_core->getCoreOptions();
|
|
|
|
clearLayout();
|
|
|
|
if(coreOptions.size() > 0) {
|
|
form = new QFormLayout();
|
|
|
|
QToolButton *resetAllButton = new QToolButton(this);
|
|
|
|
resetAllButton->setDefaultAction(new QAction(tr("Reset All"), this));
|
|
connect(resetAllButton, &QToolButton::clicked, this, &CoreOptionsDialog::onCoreOptionResetAllClicked);
|
|
|
|
const QList<Core::CoreOption> &options = coreOptions.values();
|
|
|
|
for(int j = 0; j < coreOptions.size(); j++) {
|
|
const Core::CoreOption &option = options.at(j);
|
|
const QString &desc = option.name;
|
|
const QString &val = option.val;
|
|
QComboBox *comboBox = nullptr;
|
|
QLabel *descLabel = nullptr;
|
|
QHBoxLayout *comboLayout = nullptr;
|
|
QToolButton *resetButton = nullptr;
|
|
|
|
if(desc.isEmpty())
|
|
continue;
|
|
|
|
if(option.values.size() == 0)
|
|
continue;
|
|
|
|
comboLayout = new QHBoxLayout();
|
|
descLabel = new QLabel(desc, this);
|
|
comboBox = new QComboBox(this);
|
|
comboBox->setObjectName("coreOptionComboBox");
|
|
resetButton = new QToolButton(this);
|
|
resetButton->setObjectName("resetButton");
|
|
resetButton->setDefaultAction(new QAction(tr("Reset"), this));
|
|
resetButton->setProperty("comboBox", QVariant::fromValue(comboBox));
|
|
|
|
connect(resetButton, &QToolButton::clicked, this, &CoreOptionsDialog::onCoreOptionResetClicked);
|
|
|
|
for(int k = 0; k < option.values.size(); k++) {
|
|
comboBox->addItem(option.values.at(k), option.key);
|
|
}
|
|
|
|
comboBox->setCurrentText(val);
|
|
// NOTE: if new core options interface is added, default may be one other than the first
|
|
comboBox->setProperty("default_index", 0);
|
|
|
|
// Only connect the signal after setting the default item
|
|
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CoreOptionsDialog::onCoreOptionComboBoxCurrentIndexChanged);
|
|
|
|
comboLayout->addWidget(comboBox);
|
|
comboLayout->addWidget(resetButton);
|
|
|
|
form->addRow(descLabel, comboLayout);
|
|
}
|
|
|
|
form->addRow(resetAllButton, new QWidget(this));
|
|
|
|
m_layout->addLayout(form);
|
|
}else{
|
|
QLabel *noParamsLabel = new QLabel(tr("No core options available."), this);
|
|
noParamsLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
m_layout->addWidget(noParamsLabel);
|
|
}
|
|
|
|
m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
|
|
|
resize(width() + 1, height());
|
|
show();
|
|
resize(width() - 1, height());
|
|
}
|
|
|
|
void CoreOptionsDialog::onCoreOptionResetClicked() {
|
|
QToolButton *button = qobject_cast<QToolButton*>(sender());
|
|
QComboBox *comboBox = nullptr;
|
|
int default_index = 0;
|
|
bool ok = false;
|
|
|
|
if(!button)
|
|
return;
|
|
|
|
comboBox = qobject_cast<QComboBox*>(button->property("comboBox").value<QComboBox*>());
|
|
|
|
if(!comboBox)
|
|
return;
|
|
|
|
default_index = comboBox->property("default_index").toInt(&ok);
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
if(default_index >= 0 && default_index < comboBox->count())
|
|
comboBox->setCurrentIndex(default_index);
|
|
}
|
|
|
|
void CoreOptionsDialog::onCoreOptionResetAllClicked() {
|
|
QList<QComboBox*> comboBoxes = findChildren<QComboBox*>("coreOptionComboBox");
|
|
|
|
for(int i = 0; i < comboBoxes.count(); i++) {
|
|
QComboBox *comboBox = comboBoxes.at(i);
|
|
int default_index = 0;
|
|
bool ok = false;
|
|
|
|
if(!comboBox)
|
|
continue;
|
|
|
|
default_index = comboBox->property("default_index").toInt(&ok);
|
|
|
|
if(!ok)
|
|
continue;
|
|
|
|
if(default_index >= 0 && default_index < comboBox->count())
|
|
comboBox->setCurrentIndex(default_index);
|
|
}
|
|
}
|
|
|