add setting, implement it on desktop

This commit is contained in:
David Griswold 2025-10-01 22:15:58 +03:00
parent 0be78e9550
commit 578d632e6f
5 changed files with 80 additions and 19 deletions

View file

@ -2680,25 +2680,14 @@ void GMainWindow::AdjustSpeedLimit(bool increase) {
void GMainWindow::ToggleScreenLayout() { void GMainWindow::ToggleScreenLayout() {
const Settings::LayoutOption new_layout = []() { const Settings::LayoutOption new_layout = []() {
switch (Settings::values.layout_option.GetValue()) { const Settings::LayoutOption current_layout = Settings::values.layout_option.GetValue();
case Settings::LayoutOption::Default: const std::vector<Settings::LayoutOption> layouts_to_cycle = Settings::values.layouts_to_cycle.GetValue();
return Settings::LayoutOption::SingleScreen; const auto current_pos = distance(layouts_to_cycle.begin(),std::find(layouts_to_cycle.begin(),layouts_to_cycle.end(),current_layout));
case Settings::LayoutOption::SingleScreen: if (current_pos >= layouts_to_cycle.size() - 1) {
return Settings::LayoutOption::LargeScreen; // either this layout wasn't found or it was last so move to the beginning
case Settings::LayoutOption::LargeScreen: return layouts_to_cycle[0];
return Settings::LayoutOption::HybridScreen; }else {
case Settings::LayoutOption::HybridScreen: return layouts_to_cycle[current_pos+1];
return Settings::LayoutOption::SideScreen;
case Settings::LayoutOption::SideScreen:
return Settings::LayoutOption::SeparateWindows;
case Settings::LayoutOption::SeparateWindows:
return Settings::LayoutOption::CustomLayout;
case Settings::LayoutOption::CustomLayout:
return Settings::LayoutOption::Default;
default:
LOG_ERROR(Frontend, "Unknown layout option {}",
Settings::values.layout_option.GetValue());
return Settings::LayoutOption::Default;
} }
}(); }();

View file

@ -6,6 +6,8 @@
#include <array> #include <array>
#include <QKeySequence> #include <QKeySequence>
#include <QSettings> #include <QSettings>
#include <QVariant>
#include <QVector>
#include "citra_qt/configuration/config.h" #include "citra_qt/configuration/config.h"
#include "common/file_util.h" #include "common/file_util.h"
#include "common/settings.h" #include "common/settings.h"
@ -132,6 +134,34 @@ void QtConfig::ReadBasicSetting(Settings::Setting<std::string>& setting) {
setting.SetValue(qt_config->value(name, default_value).toString().toStdString()); setting.SetValue(qt_config->value(name, default_value).toString().toStdString());
} }
} }
// definition for vectors of enums
template <typename Type, bool ranged>
void QtConfig::ReadBasicSetting(Settings::Setting<std::vector<Type>, ranged>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const std::vector<Type> default_value = setting.GetDefault();
QStringList stringList = qt_config->value(name).toStringList();
if (qt_config->value(name + QStringLiteral("/default"), false).toBool() || stringList.size() < 1) {
setting.SetValue(default_value);
} else {
if (stringList.size() < 1) {
setting.SetValue(default_value);
} else {
std::vector<Type> newValue;
for (const QString& str : stringList) {
if constexpr (std::is_enum_v<Type>) {
using TypeU = std::underlying_type_t<Type>;
newValue.push_back(static_cast<Type>(str.toInt()));
} else if constexpr (std::is_integral_v<Type>) {
newValue.push_back(str.toInt());
} else {
newValue.push_back(str.toStdString());
}
}
setting.SetValue(newValue);
}
}
}
template <typename Type, bool ranged> template <typename Type, bool ranged>
void QtConfig::ReadBasicSetting(Settings::Setting<Type, ranged>& setting) { void QtConfig::ReadBasicSetting(Settings::Setting<Type, ranged>& setting) {
@ -191,6 +221,29 @@ void QtConfig::WriteBasicSetting(const Settings::Setting<std::string>& setting)
qt_config->setValue(name, QString::fromStdString(value)); qt_config->setValue(name, QString::fromStdString(value));
} }
template <typename Type, bool ranged>
void QtConfig::WriteBasicSetting(const Settings::Setting<std::vector<Type>, ranged>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const std::vector<Type>& value = setting.GetValue();
qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
QStringList stringList;
if constexpr (std::is_enum_v<Type>) {
// For enums, convert to underlying integer type strings
using TypeU = std::underlying_type_t<Type>;
for (const Type& item : value) {
stringList.append(QString::number(static_cast<TypeU>(item)));
}
} else {
// For non-enum types (assuming numeric)
for (const Type& item : value) {
stringList.append(QString::number(item));
}
}
qt_config->setValue(name, stringList);
}
// Explicit u16 definition: Qt would store it as QMetaType otherwise, which is not human-readable // Explicit u16 definition: Qt would store it as QMetaType otherwise, which is not human-readable
template <> template <>
void QtConfig::WriteBasicSetting(const Settings::Setting<u16>& setting) { void QtConfig::WriteBasicSetting(const Settings::Setting<u16>& setting) {
@ -528,6 +581,7 @@ void QtConfig::ReadLayoutValues() {
ReadGlobalSetting(Settings::values.small_screen_position); ReadGlobalSetting(Settings::values.small_screen_position);
if (global) { if (global) {
ReadBasicSetting(Settings::values.layouts_to_cycle);
ReadBasicSetting(Settings::values.mono_render_option); ReadBasicSetting(Settings::values.mono_render_option);
ReadBasicSetting(Settings::values.custom_top_x); ReadBasicSetting(Settings::values.custom_top_x);
ReadBasicSetting(Settings::values.custom_top_y); ReadBasicSetting(Settings::values.custom_top_y);
@ -1092,6 +1146,7 @@ void QtConfig::SaveLayoutValues() {
WriteGlobalSetting(Settings::values.screen_gap); WriteGlobalSetting(Settings::values.screen_gap);
WriteGlobalSetting(Settings::values.small_screen_position); WriteGlobalSetting(Settings::values.small_screen_position);
if (global) { if (global) {
WriteBasicSetting(Settings::values.layouts_to_cycle);
WriteBasicSetting(Settings::values.mono_render_option); WriteBasicSetting(Settings::values.mono_render_option);
WriteBasicSetting(Settings::values.custom_top_x); WriteBasicSetting(Settings::values.custom_top_x);
WriteBasicSetting(Settings::values.custom_top_y); WriteBasicSetting(Settings::values.custom_top_y);

View file

@ -120,6 +120,10 @@ private:
template <typename Type, bool ranged> template <typename Type, bool ranged>
void ReadBasicSetting(Settings::Setting<Type, ranged>& setting); void ReadBasicSetting(Settings::Setting<Type, ranged>& setting);
// Add overload for vectors
template <typename Type, bool ranged>
void ReadBasicSetting(Settings::Setting<std::vector<Type>, ranged>& setting);
/** Sets a value from the setting in the qt_config using the setting's label and default value. /** Sets a value from the setting in the qt_config using the setting's label and default value.
* *
* @param The setting * @param The setting
@ -127,6 +131,10 @@ private:
template <typename Type, bool ranged> template <typename Type, bool ranged>
void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting); void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting);
template <typename Type, bool ranged>
void WriteBasicSetting(const Settings::Setting<std::vector<Type>, ranged>& setting);
ConfigType type; ConfigType type;
std::unique_ptr<QSettings> qt_config; std::unique_ptr<QSettings> qt_config;
std::string qt_config_loc; std::string qt_config_loc;

View file

@ -120,6 +120,7 @@ void LogSettings() {
log_setting("Layout_ScreenGap", values.screen_gap.GetValue()); log_setting("Layout_ScreenGap", values.screen_gap.GetValue());
log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue()); log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue());
log_setting("Layout_SmallScreenPosition", values.small_screen_position.GetValue()); log_setting("Layout_SmallScreenPosition", values.small_screen_position.GetValue());
//log_setting("Layout_LayoutsToCycle",values.layouts_to_cycle.GetValue());
log_setting("Utility_DumpTextures", values.dump_textures.GetValue()); log_setting("Utility_DumpTextures", values.dump_textures.GetValue());
log_setting("Utility_CustomTextures", values.custom_textures.GetValue()); log_setting("Utility_CustomTextures", values.custom_textures.GetValue());
log_setting("Utility_PreloadTextures", values.preload_textures.GetValue()); log_setting("Utility_PreloadTextures", values.preload_textures.GetValue());

View file

@ -522,6 +522,14 @@ struct Values {
SwitchableSetting<bool> upright_screen{false, "upright_screen"}; SwitchableSetting<bool> upright_screen{false, "upright_screen"};
SwitchableSetting<SecondaryDisplayLayout> secondary_display_layout{SecondaryDisplayLayout::None, SwitchableSetting<SecondaryDisplayLayout> secondary_display_layout{SecondaryDisplayLayout::None,
"secondary_display_layout"}; "secondary_display_layout"};
Setting<std::vector<LayoutOption>> layouts_to_cycle{
{LayoutOption::Default, LayoutOption::SingleScreen, LayoutOption::LargeScreen,
LayoutOption::SideScreen,
#ifndef ANDROID
LayoutOption::SeparateWindows,
#endif
LayoutOption::HybridScreen, LayoutOption::CustomLayout},
"layouts_to_cycle"};
SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f, SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f,
"large_screen_proportion"}; "large_screen_proportion"};
SwitchableSetting<int> screen_gap{0, "screen_gap"}; SwitchableSetting<int> screen_gap{0, "screen_gap"};