2026-03-20 22:09:14 +01:00
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
2025-08-06 07:48:11 +02:00
// SPDX-License-Identifier: GPL-3.0-or-later
2022-05-15 02:06:02 +02:00
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
2016-01-24 18:34:05 +01:00
2023-11-12 02:03:01 -05:00
# include <QSettings>
# include "common/fs/fs.h"
# include "common/fs/path_util.h"
2025-10-15 05:05:03 +02:00
# include "qt_common/config/uisettings.h"
2016-01-24 18:34:05 +01:00
2023-06-20 19:26:12 -04:00
# ifndef CANNOT_EXPLICITLY_INSTANTIATE
2023-06-10 23:40:39 -04:00
namespace Settings {
template class Setting < bool > ;
template class Setting < std : : string > ;
template class Setting < u16 , true > ;
template class Setting < u32 > ;
template class Setting < u8 , true > ;
template class Setting < u8 > ;
template class Setting < unsigned long long > ;
} // namespace Settings
2023-06-18 19:57:14 -04:00
# endif
2023-06-10 23:40:39 -04:00
2023-11-12 02:03:01 -05:00
namespace FS = Common : : FS ;
2016-01-24 18:34:05 +01:00
namespace UISettings {
2026-03-20 22:09:14 +01:00
// This shouldn't have anything except static initializers (no functions). So
// QKeySequence(...).toString() is NOT ALLOWED HERE.
// This must be in alphabetical order according to action name as it must have the same order as
// UISetting::values.shortcuts, which is alphabetically ordered.
// clang-format off
const std : : array < Shortcut , 33 > default_hotkeys { {
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Audio Mute/Unmute " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+M " ) , std : : string ( " Home+Dpad_Right " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Audio Volume Down " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " - " ) , std : : string ( " Home+Dpad_Down " ) , Qt : : ApplicationShortcut , true } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Audio Volume Up " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " = " ) , std : : string ( " Home+Dpad_Up " ) , Qt : : ApplicationShortcut , true } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Capture Screenshot " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+P " ) , std : : string ( " Screenshot " ) , Qt : : WidgetWithChildrenShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Change Adapting Filter " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F8 " ) , std : : string ( " Home+L " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Change Docked Mode " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F10 " ) , std : : string ( " Home+X " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Change GPU Mode " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F9 " ) , std : : string ( " Home+R " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Configure " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+, " ) , std : : string ( " " ) , Qt : : WidgetWithChildrenShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Configure Current Game " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+. " ) , std : : string ( " " ) , Qt : : WidgetWithChildrenShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Continue/Pause Emulation " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F4 " ) , std : : string ( " Home+Plus " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Exit Fullscreen " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Esc " ) , std : : string ( " " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Exit Eden " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+Q " ) , std : : string ( " Home+Minus " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Fullscreen " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F11 " ) , std : : string ( " Home+B " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Load File " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+O " ) , std : : string ( " " ) , Qt : : WidgetWithChildrenShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Load/Remove Amiibo " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F2 " ) , std : : string ( " Home+A " ) , Qt : : WidgetWithChildrenShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Browse Public Game Lobby " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+B " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Create Room " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+N " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Direct Connect to Room " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+C " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Leave Room " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+L " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Show Current Room " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+R " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Restart Emulation " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F6 " ) , std : : string ( " R+Plus+Minus " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Stop Emulation " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " F5 " ) , std : : string ( " L+Plus+Minus " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " TAS Record " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+F7 " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " TAS Reset " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+F6 " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " TAS Start/Stop " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+F5 " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Filter Bar " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+F " ) , std : : string ( " " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Framerate Limit " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+U " ) , std : : string ( " Home+Y " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Turbo Speed " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+Z " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Slow Speed " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+X " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Mouse Panning " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+F9 " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Renderdoc Capture " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " " ) , std : : string ( " " ) , Qt : : ApplicationShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Status Bar " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+S " ) , std : : string ( " " ) , Qt : : WindowShortcut , false } } ,
{ QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Toggle Performance Overlay " ) ) . toStdString ( ) , QStringLiteral ( QT_TRANSLATE_NOOP ( " Hotkeys " , " Main Window " ) ) . toStdString ( ) , { std : : string ( " Ctrl+V " ) , std : : string ( " " ) , Qt : : WindowShortcut , false } } ,
} } ;
// clang-format on
2018-10-04 06:33:17 -04:00
const Themes themes { {
2021-11-13 22:14:30 -05:00
{ " Default " , " default " } ,
{ " Default Colorful " , " colorful " } ,
2018-10-04 06:33:17 -04:00
{ " Dark " , " qdarkstyle " } ,
2020-01-22 21:12:45 +01:00
{ " Dark Colorful " , " colorful_dark " } ,
2020-07-18 09:23:20 -04:00
{ " Midnight Blue " , " qdarkstyle_midnight_blue " } ,
{ " Midnight Blue Colorful " , " colorful_midnight_blue " } ,
2018-10-04 06:33:17 -04:00
} } ;
2022-04-10 14:04:50 -07:00
bool IsDarkTheme ( ) {
const auto & theme = UISettings : : values . theme ;
2023-11-12 02:03:01 -05:00
return theme = = std : : string ( " qdarkstyle " ) | | theme = = std : : string ( " qdarkstyle_midnight_blue " ) | |
theme = = std : : string ( " colorful_dark " ) | | theme = = std : : string ( " colorful_midnight_blue " ) ;
2022-04-10 14:04:50 -07:00
}
2016-01-24 18:34:05 +01:00
Values values = { } ;
2020-07-22 10:39:53 -04:00
2023-08-15 22:42:28 -04:00
u32 CalculateWidth ( u32 height , Settings : : AspectRatio ratio ) {
switch ( ratio ) {
case Settings : : AspectRatio : : R4_3 :
return height * 4 / 3 ;
case Settings : : AspectRatio : : R21_9 :
return height * 21 / 9 ;
case Settings : : AspectRatio : : R16_10 :
return height * 16 / 10 ;
case Settings : : AspectRatio : : R16_9 :
case Settings : : AspectRatio : : Stretch :
2023-08-16 22:57:19 -04:00
// TODO: Move this function wherever appropriate to implement Stretched aspect
2023-08-15 22:42:28 -04:00
break ;
}
return height * 16 / 9 ;
}
2023-11-12 02:03:01 -05:00
void SaveWindowState ( ) {
const auto window_state_config_loc =
2025-05-08 22:16:07 +00:00
FS : : PathToUTF8String ( FS : : GetEdenPath ( FS : : EdenPath : : ConfigDir ) / " window_state.ini " ) ;
2023-11-12 02:03:01 -05:00
void ( FS : : CreateParentDir ( window_state_config_loc ) ) ;
QSettings config ( QString : : fromStdString ( window_state_config_loc ) , QSettings : : IniFormat ) ;
config . setValue ( QStringLiteral ( " geometry " ) , values . geometry ) ;
config . setValue ( QStringLiteral ( " state " ) , values . state ) ;
config . setValue ( QStringLiteral ( " geometryRenderWindow " ) , values . renderwindow_geometry ) ;
config . setValue ( QStringLiteral ( " gameListHeaderState " ) , values . gamelist_header_state ) ;
config . sync ( ) ;
}
void RestoreWindowState ( std : : unique_ptr < QtConfig > & qtConfig ) {
const auto window_state_config_loc =
2025-05-08 22:16:07 +00:00
FS : : PathToUTF8String ( FS : : GetEdenPath ( FS : : EdenPath : : ConfigDir ) / " window_state.ini " ) ;
2023-11-12 02:03:01 -05:00
// Migrate window state from old location
if ( ! FS : : Exists ( window_state_config_loc ) & & qtConfig - > Exists ( " UI " , " UILayout \\ geometry " ) ) {
const auto config_loc =
2025-05-08 22:16:07 +00:00
FS : : PathToUTF8String ( FS : : GetEdenPath ( FS : : EdenPath : : ConfigDir ) / " qt-config.ini " ) ;
2023-11-12 02:03:01 -05:00
QSettings config ( QString : : fromStdString ( config_loc ) , QSettings : : IniFormat ) ;
config . beginGroup ( QStringLiteral ( " UI " ) ) ;
config . beginGroup ( QStringLiteral ( " UILayout " ) ) ;
values . geometry = config . value ( QStringLiteral ( " geometry " ) ) . toByteArray ( ) ;
values . state = config . value ( QStringLiteral ( " state " ) ) . toByteArray ( ) ;
values . renderwindow_geometry =
config . value ( QStringLiteral ( " geometryRenderWindow " ) ) . toByteArray ( ) ;
values . gamelist_header_state =
config . value ( QStringLiteral ( " gameListHeaderState " ) ) . toByteArray ( ) ;
config . endGroup ( ) ;
config . endGroup ( ) ;
return ;
}
void ( FS : : CreateParentDir ( window_state_config_loc ) ) ;
const QSettings config ( QString : : fromStdString ( window_state_config_loc ) , QSettings : : IniFormat ) ;
values . geometry = config . value ( QStringLiteral ( " geometry " ) ) . toByteArray ( ) ;
values . state = config . value ( QStringLiteral ( " state " ) ) . toByteArray ( ) ;
values . renderwindow_geometry =
config . value ( QStringLiteral ( " geometryRenderWindow " ) ) . toByteArray ( ) ;
values . gamelist_header_state =
config . value ( QStringLiteral ( " gameListHeaderState " ) ) . toByteArray ( ) ;
}
2018-10-04 06:33:17 -04:00
} // namespace UISettings