shared_widget: Forward-port Citra changes

Seemed like a good time to move these over.
Also remove usage of std::sto{l,ll,ul,f,d}
This commit is contained in:
lat9nq 2023-09-13 13:50:25 -04:00
parent 2d2c176f03
commit 3ae3706c84
2 changed files with 134 additions and 31 deletions

View File

@ -151,7 +151,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
return -1; return -1;
}; };
const u32 setting_value = std::stoi(setting.ToString()); const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0);
combobox->setCurrentIndex(find_index(setting_value)); combobox->setCurrentIndex(find_index(setting_value));
serializer = [this, enumeration]() { serializer = [this, enumeration]() {
@ -160,7 +160,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
}; };
restore_func = [this, find_index]() { restore_func = [this, find_index]() {
const u32 global_value = std::stoi(RelevantDefault(setting)); const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0);
combobox->setCurrentIndex(find_index(global_value)); combobox->setCurrentIndex(find_index(global_value));
}; };
@ -209,7 +209,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
} }
}; };
const u32 setting_value = std::stoi(setting.ToString()); const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0);
set_index(setting_value); set_index(setting_value);
serializer = [get_selected]() { serializer = [get_selected]() {
@ -218,7 +218,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
}; };
restore_func = [this, set_index]() { restore_func = [this, set_index]() {
const u32 global_value = std::stoi(RelevantDefault(setting)); const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0);
set_index(global_value); set_index(global_value);
}; };
@ -255,6 +255,58 @@ QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer,
return line_edit; return line_edit;
} }
static void CreateIntSlider(Settings::BasicSetting& setting, bool reversed, float multiplier,
QLabel* feedback, const QString& use_format, QSlider* slider,
std::function<std::string()>& serializer,
std::function<void()>& restore_func) {
int max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0);
const auto update_feedback = [=](int value) {
int present = (reversed ? max_val - value : value) * multiplier + 0.5f;
feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>()));
};
QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback);
update_feedback(std::strtol(setting.ToString().c_str(), nullptr, 0));
slider->setMinimum(std::strtol(setting.MinVal().c_str(), nullptr, 0));
slider->setMaximum(max_val);
slider->setValue(std::strtol(setting.ToString().c_str(), nullptr, 0));
serializer = [slider]() { return std::to_string(slider->value()); };
restore_func = [slider, &setting]() {
slider->setValue(std::strtol(RelevantDefault(setting).c_str(), nullptr, 0));
};
}
static void CreateFloatSlider(Settings::BasicSetting& setting, bool reversed, float multiplier,
QLabel* feedback, const QString& use_format, QSlider* slider,
std::function<std::string()>& serializer,
std::function<void()>& restore_func) {
float max_val = std::strtof(setting.MaxVal().c_str(), nullptr);
float min_val = std::strtof(setting.MinVal().c_str(), nullptr);
float use_multiplier = multiplier == default_multiplier ? default_float_multiplier : multiplier;
const auto update_feedback = [=](float value) {
int present = (reversed ? max_val - value : value) + 0.5f;
feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>()));
};
QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback);
update_feedback(std::strtof(setting.ToString().c_str(), nullptr));
slider->setMinimum(min_val * use_multiplier);
slider->setMaximum(max_val * use_multiplier);
slider->setValue(std::strtof(setting.ToString().c_str(), nullptr) * use_multiplier);
serializer = [slider, use_multiplier]() {
return std::to_string(slider->value() / use_multiplier);
};
restore_func = [slider, &setting, use_multiplier]() {
slider->setValue(std::strtof(RelevantDefault(setting).c_str(), nullptr) * use_multiplier);
};
}
QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix,
std::function<std::string()>& serializer, std::function<std::string()>& serializer,
std::function<void()>& restore_func, std::function<void()>& restore_func,
@ -278,27 +330,20 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
int max_val = std::stoi(setting.MaxVal());
QString suffix = QString suffix =
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
const QString use_format = QStringLiteral("%1").append(suffix); const QString use_format = QStringLiteral("%1").append(suffix);
QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { if (setting.IsIntegral()) {
int present = (reversed ? max_val - value : value) * multiplier + 0.5f; CreateIntSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer,
feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); restore_func);
}); } else {
CreateFloatSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer,
slider->setMinimum(std::stoi(setting.MinVal())); restore_func);
slider->setMaximum(max_val); }
slider->setValue(std::stoi(setting.ToString()));
slider->setInvertedAppearance(reversed); slider->setInvertedAppearance(reversed);
slider->setInvertedControls(reversed);
serializer = [this]() { return std::to_string(slider->value()); };
restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); };
if (!Settings::IsConfiguringGlobal()) { if (!Settings::IsConfiguringGlobal()) {
QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); });
@ -311,11 +356,9 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix,
std::function<std::string()>& serializer, std::function<std::string()>& serializer,
std::function<void()>& restore_func, std::function<void()>& restore_func,
const std::function<void()>& touch) { const std::function<void()>& touch) {
const int min_val = const auto min_val = std::strtol(setting.MinVal().c_str(), nullptr, 0);
setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min(); const auto max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0);
const int max_val = const auto default_val = std::strtol(setting.ToString().c_str(), nullptr, 0);
setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max();
const int default_val = std::stoi(setting.ToString());
QString suffix = QString suffix =
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
@ -329,13 +372,13 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix,
serializer = [this]() { return std::to_string(spinbox->value()); }; serializer = [this]() { return std::to_string(spinbox->value()); };
restore_func = [this]() { restore_func = [this]() {
auto value{std::stol(RelevantDefault(setting))}; auto value{std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)};
spinbox->setValue(value); spinbox->setValue(value);
}; };
if (!Settings::IsConfiguringGlobal()) { if (!Settings::IsConfiguringGlobal()) {
QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() {
if (spinbox->value() != std::stoi(setting.ToStringGlobal())) { if (spinbox->value() != std::strtol(setting.ToStringGlobal().c_str(), nullptr, 0)) {
touch(); touch();
} }
}); });
@ -344,6 +387,43 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix,
return spinbox; return spinbox;
} }
QWidget* Widget::CreateDoubleSpinBox(const QString& given_suffix,
std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch) {
const auto min_val = std::strtod(setting.MinVal().c_str(), nullptr);
const auto max_val = std::strtod(setting.MaxVal().c_str(), nullptr);
const auto default_val = std::strtod(setting.ToString().c_str(), nullptr);
QString suffix =
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
double_spinbox = new QDoubleSpinBox(this);
double_spinbox->setRange(min_val, max_val);
double_spinbox->setValue(default_val);
double_spinbox->setSuffix(suffix);
double_spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
serializer = [this]() { return fmt::format("{:f}", double_spinbox->value()); };
restore_func = [this]() {
auto value{std::strtod(RelevantDefault(setting).c_str(), nullptr)};
double_spinbox->setValue(value);
};
if (!Settings::IsConfiguringGlobal()) {
QObject::connect(double_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
[this, touch]() {
if (double_spinbox->value() !=
std::strtod(setting.ToStringGlobal().c_str(), nullptr)) {
touch();
}
});
}
return double_spinbox;
}
QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
std::function<void()>& restore_func, std::function<void()>& restore_func,
const std::function<void()>& touch) { const std::function<void()>& touch) {
@ -353,7 +433,8 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
} }
auto to_hex = [=](const std::string& input) { auto to_hex = [=](const std::string& input) {
return QString::fromStdString(fmt::format("{:08x}", std::stoul(input))); return QString::fromStdString(
fmt::format("{:08x}", std::strtoul(input.c_str(), nullptr, 0)));
}; };
QRegularExpressionValidator* regex = new QRegularExpressionValidator( QRegularExpressionValidator* regex = new QRegularExpressionValidator(
@ -366,7 +447,7 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
line_edit->setValidator(regex); line_edit->setValidator(regex);
auto hex_to_dec = [this]() -> std::string { auto hex_to_dec = [this]() -> std::string {
return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16)); return std::to_string(std::strtoul(line_edit->text().toStdString().c_str(), nullptr, 16));
}; };
serializer = [hex_to_dec]() { return hex_to_dec(); }; serializer = [hex_to_dec]() { return hex_to_dec(); };
@ -386,7 +467,8 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict,
std::function<void()>& restore_func, std::function<void()>& restore_func,
const std::function<void()>& touch) { const std::function<void()>& touch) {
const long long current_time = QDateTime::currentSecsSinceEpoch(); const long long current_time = QDateTime::currentSecsSinceEpoch();
const s64 the_time = disabled ? current_time : std::stoll(setting.ToString()); const s64 the_time =
disabled ? current_time : std::strtoll(setting.ToString().c_str(), nullptr, 0);
const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); const auto default_val = QDateTime::fromSecsSinceEpoch(the_time);
date_time_edit = new QDateTimeEdit(this); date_time_edit = new QDateTimeEdit(this);
@ -399,7 +481,7 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict,
auto get_clear_val = [this, restrict, current_time]() { auto get_clear_val = [this, restrict, current_time]() {
return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() {
if (restrict && checkbox->checkState() == Qt::Checked) { if (restrict && checkbox->checkState() == Qt::Checked) {
return std::stoll(RelevantDefault(setting)); return std::strtoll(RelevantDefault(setting).c_str(), nullptr, 0);
} }
return current_time; return current_time;
}()); }());
@ -506,8 +588,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
} else { } else {
data_component = CreateCombobox(serializer, restore_func, touch); data_component = CreateCombobox(serializer, restore_func, touch);
} }
} else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || } else if (setting.IsIntegral()) {
type == typeid(s64) || type == typeid(u8)) {
switch (request) { switch (request) {
case RequestType::Slider: case RequestType::Slider:
case RequestType::ReverseSlider: case RequestType::ReverseSlider:
@ -534,6 +615,20 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
} else if (setting.IsFloatingPoint()) {
switch (request) {
case RequestType::Default:
case RequestType::SpinBox:
data_component = CreateDoubleSpinBox(suffix, serializer, restore_func, touch);
break;
case RequestType::Slider:
case RequestType::ReverseSlider:
data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix,
serializer, restore_func, touch);
break;
default:
UNIMPLEMENTED();
}
} else if (type == typeid(std::string)) { } else if (type == typeid(std::string)) {
switch (request) { switch (request) {
case RequestType::Default: case RequestType::Default:

View File

@ -22,6 +22,7 @@ class QObject;
class QPushButton; class QPushButton;
class QSlider; class QSlider;
class QSpinBox; class QSpinBox;
class QDoubleSpinBox;
class QRadioButton; class QRadioButton;
namespace Settings { namespace Settings {
@ -43,6 +44,9 @@ enum class RequestType {
MaxEnum, MaxEnum,
}; };
constexpr const float default_multiplier{1.f};
constexpr const float default_float_multiplier{100.f};
class Widget : public QWidget { class Widget : public QWidget {
Q_OBJECT Q_OBJECT
@ -89,6 +93,7 @@ public:
QPushButton* restore_button{}; ///< Restore button for custom configurations QPushButton* restore_button{}; ///< Restore button for custom configurations
QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit
QSpinBox* spinbox{}; QSpinBox* spinbox{};
QDoubleSpinBox* double_spinbox{};
QCheckBox* checkbox{}; QCheckBox* checkbox{};
QSlider* slider{}; QSlider* slider{};
QComboBox* combobox{}; QComboBox* combobox{};
@ -126,6 +131,9 @@ private:
const std::function<void()>& touch); const std::function<void()>& touch);
QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer,
std::function<void()>& restore_func, const std::function<void()>& touch); std::function<void()>& restore_func, const std::function<void()>& touch);
QWidget* CreateDoubleSpinBox(const QString& suffix, std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch);
QWidget* parent; QWidget* parent;
const TranslationMap& translations; const TranslationMap& translations;