diff --git a/src/citra_qt/citra_qt.cpp b/src/citra_qt/citra_qt.cpp index 523c3a3be..a28a160b9 100644 --- a/src/citra_qt/citra_qt.cpp +++ b/src/citra_qt/citra_qt.cpp @@ -2680,25 +2680,14 @@ void GMainWindow::AdjustSpeedLimit(bool increase) { void GMainWindow::ToggleScreenLayout() { const Settings::LayoutOption new_layout = []() { - switch (Settings::values.layout_option.GetValue()) { - case Settings::LayoutOption::Default: - return Settings::LayoutOption::SingleScreen; - case Settings::LayoutOption::SingleScreen: - return Settings::LayoutOption::LargeScreen; - case Settings::LayoutOption::LargeScreen: - return Settings::LayoutOption::HybridScreen; - case Settings::LayoutOption::HybridScreen: - 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; + const Settings::LayoutOption current_layout = Settings::values.layout_option.GetValue(); + const std::vector layouts_to_cycle = Settings::values.layouts_to_cycle.GetValue(); + const auto current_pos = distance(layouts_to_cycle.begin(),std::find(layouts_to_cycle.begin(),layouts_to_cycle.end(),current_layout)); + if (current_pos >= layouts_to_cycle.size() - 1) { + // either this layout wasn't found or it was last so move to the beginning + return layouts_to_cycle[0]; + }else { + return layouts_to_cycle[current_pos+1]; } }(); diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 0e7777911..8a88244ce 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include "citra_qt/configuration/config.h" #include "common/file_util.h" #include "common/settings.h" @@ -132,6 +134,34 @@ void QtConfig::ReadBasicSetting(Settings::Setting& setting) { setting.SetValue(qt_config->value(name, default_value).toString().toStdString()); } } +// definition for vectors of enums +template +void QtConfig::ReadBasicSetting(Settings::Setting, ranged>& setting) { + const QString name = QString::fromStdString(setting.GetLabel()); + const std::vector 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 newValue; + for (const QString& str : stringList) { + if constexpr (std::is_enum_v) { + using TypeU = std::underlying_type_t; + newValue.push_back(static_cast(str.toInt())); + } else if constexpr (std::is_integral_v) { + newValue.push_back(str.toInt()); + } else { + newValue.push_back(str.toStdString()); + } + } + setting.SetValue(newValue); + } + } +} template void QtConfig::ReadBasicSetting(Settings::Setting& setting) { @@ -191,6 +221,29 @@ void QtConfig::WriteBasicSetting(const Settings::Setting& setting) qt_config->setValue(name, QString::fromStdString(value)); } +template +void QtConfig::WriteBasicSetting(const Settings::Setting, ranged>& setting) { + const QString name = QString::fromStdString(setting.GetLabel()); + const std::vector& value = setting.GetValue(); + + qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault()); + + QStringList stringList; + if constexpr (std::is_enum_v) { + // For enums, convert to underlying integer type strings + using TypeU = std::underlying_type_t; + for (const Type& item : value) { + stringList.append(QString::number(static_cast(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 template <> void QtConfig::WriteBasicSetting(const Settings::Setting& setting) { @@ -528,6 +581,7 @@ void QtConfig::ReadLayoutValues() { ReadGlobalSetting(Settings::values.small_screen_position); if (global) { + ReadBasicSetting(Settings::values.layouts_to_cycle); ReadBasicSetting(Settings::values.mono_render_option); ReadBasicSetting(Settings::values.custom_top_x); ReadBasicSetting(Settings::values.custom_top_y); @@ -1092,6 +1146,7 @@ void QtConfig::SaveLayoutValues() { WriteGlobalSetting(Settings::values.screen_gap); WriteGlobalSetting(Settings::values.small_screen_position); if (global) { + WriteBasicSetting(Settings::values.layouts_to_cycle); WriteBasicSetting(Settings::values.mono_render_option); WriteBasicSetting(Settings::values.custom_top_x); WriteBasicSetting(Settings::values.custom_top_y); diff --git a/src/citra_qt/configuration/config.h b/src/citra_qt/configuration/config.h index 2c9039dde..f343c17fc 100644 --- a/src/citra_qt/configuration/config.h +++ b/src/citra_qt/configuration/config.h @@ -120,6 +120,10 @@ private: template void ReadBasicSetting(Settings::Setting& setting); + // Add overload for vectors + template + void ReadBasicSetting(Settings::Setting, ranged>& setting); + /** Sets a value from the setting in the qt_config using the setting's label and default value. * * @param The setting @@ -127,6 +131,10 @@ private: template void WriteBasicSetting(const Settings::Setting& setting); + template + void WriteBasicSetting(const Settings::Setting, ranged>& setting); + + ConfigType type; std::unique_ptr qt_config; std::string qt_config_loc; diff --git a/src/common/settings.cpp b/src/common/settings.cpp index f91d1ec58..116dff25c 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -120,6 +120,7 @@ void LogSettings() { log_setting("Layout_ScreenGap", values.screen_gap.GetValue()); log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.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_CustomTextures", values.custom_textures.GetValue()); log_setting("Utility_PreloadTextures", values.preload_textures.GetValue()); diff --git a/src/common/settings.h b/src/common/settings.h index 77061db16..1f4fdfb96 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -522,6 +522,14 @@ struct Values { SwitchableSetting upright_screen{false, "upright_screen"}; SwitchableSetting secondary_display_layout{SecondaryDisplayLayout::None, "secondary_display_layout"}; + Setting> layouts_to_cycle{ + {LayoutOption::Default, LayoutOption::SingleScreen, LayoutOption::LargeScreen, + LayoutOption::SideScreen, +#ifndef ANDROID + LayoutOption::SeparateWindows, +#endif + LayoutOption::HybridScreen, LayoutOption::CustomLayout}, + "layouts_to_cycle"}; SwitchableSetting large_screen_proportion{4.f, 1.f, 16.f, "large_screen_proportion"}; SwitchableSetting screen_gap{0, "screen_gap"};