From bd6fedc0f29d616e5fae44bd69370eb50910a04e Mon Sep 17 00:00:00 2001 From: CozmoP <25121396+CozmoP@users.noreply.github.com> Date: Wed, 27 Mar 2019 02:37:34 +0100 Subject: [PATCH 1/4] Qt: WIP settings dialog --- Makefile.common | 69 +- config.def.h | 6 +- configuration.c | 2 + griffin/griffin.c | 3 +- griffin/griffin_cpp.cpp | 23 + pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj | 102 +- retroarch.c | 6 +- ui/drivers/qt/options/achievements.cpp | 48 + ui/drivers/qt/options/audio.cpp | 94 ++ ui/drivers/qt/options/configuration.cpp | 38 + ui/drivers/qt/options/core.cpp | 38 + ui/drivers/qt/options/directory.cpp | 58 + ui/drivers/qt/options/drivers.cpp | 45 + ui/drivers/qt/options/input.cpp | 162 +++ ui/drivers/qt/options/latency.cpp | 57 + ui/drivers/qt/options/logging.cpp | 37 + ui/drivers/qt/options/network.cpp | 171 +++ ui/drivers/qt/options/options.h | 537 ++++++++ ui/drivers/qt/options/osd.cpp | 95 ++ ui/drivers/qt/options/playlists.cpp | 43 + ui/drivers/qt/options/recording.cpp | 57 + ui/drivers/qt/options/saving.cpp | 65 + ui/drivers/qt/options/throttle.cpp | 62 + ui/drivers/qt/options/ui.cpp | 288 ++++ ui/drivers/qt/options/user.cpp | 76 ++ ui/drivers/qt/options/video.cpp | 337 +++++ ui/drivers/qt/settingswidgets.cpp | 1187 +++++++++++++++++ ui/drivers/qt/settingswidgets.h | 421 ++++++ ui/drivers/qt/ui_qt_themes.h | 9 +- ui/drivers/qt/ui_qt_window.cpp | 3 + ui/drivers/qt/viewoptionsdialog.cpp | 243 +++- ui/drivers/qt/viewoptionsdialog.h | 44 +- 32 files changed, 4349 insertions(+), 77 deletions(-) create mode 100644 ui/drivers/qt/options/achievements.cpp create mode 100644 ui/drivers/qt/options/audio.cpp create mode 100644 ui/drivers/qt/options/configuration.cpp create mode 100644 ui/drivers/qt/options/core.cpp create mode 100644 ui/drivers/qt/options/directory.cpp create mode 100644 ui/drivers/qt/options/drivers.cpp create mode 100644 ui/drivers/qt/options/input.cpp create mode 100644 ui/drivers/qt/options/latency.cpp create mode 100644 ui/drivers/qt/options/logging.cpp create mode 100644 ui/drivers/qt/options/network.cpp create mode 100644 ui/drivers/qt/options/options.h create mode 100644 ui/drivers/qt/options/osd.cpp create mode 100644 ui/drivers/qt/options/playlists.cpp create mode 100644 ui/drivers/qt/options/recording.cpp create mode 100644 ui/drivers/qt/options/saving.cpp create mode 100644 ui/drivers/qt/options/throttle.cpp create mode 100644 ui/drivers/qt/options/ui.cpp create mode 100644 ui/drivers/qt/options/user.cpp create mode 100644 ui/drivers/qt/options/video.cpp create mode 100644 ui/drivers/qt/settingswidgets.cpp create mode 100644 ui/drivers/qt/settingswidgets.h diff --git a/Makefile.common b/Makefile.common index 1923f238a9..3d51f1591e 100644 --- a/Makefile.common +++ b/Makefile.common @@ -102,9 +102,9 @@ ifeq ($(HAVE_NETPLAYDISCOVERY), 1) endif ifeq ($(HAVE_NETLOGGER), 1) - DEF_FLAGS += -DHAVE_LOGGER - DEFINES += -DHAVE_LOGGER - OBJ += network/net_logger.o + DEF_FLAGS += -DHAVE_LOGGER + DEFINES += -DHAVE_LOGGER + OBJ += network/net_logger.o endif # System @@ -357,6 +357,27 @@ ifeq ($(HAVE_QT), 1) ui/drivers/qt/thumbnaildownload.o \ ui/drivers/qt/thumbnailpackdownload.o \ ui/drivers/qt/playlistthumbnaildownload.o + ifeq ($(HAVE_MENU), 1) + OBJ += ui/drivers/qt/settingswidgets.o \ + ui/drivers/qt/options/achievements.o \ + ui/drivers/qt/options/audio.o \ + ui/drivers/qt/options/configuration.o \ + ui/drivers/qt/options/core.o \ + ui/drivers/qt/options/directory.o \ + ui/drivers/qt/options/drivers.o \ + ui/drivers/qt/options/input.o \ + ui/drivers/qt/options/latency.o \ + ui/drivers/qt/options/logging.o \ + ui/drivers/qt/options/network.o \ + ui/drivers/qt/options/osd.o \ + ui/drivers/qt/options/playlists.o \ + ui/drivers/qt/options/recording.o \ + ui/drivers/qt/options/saving.o \ + ui/drivers/qt/options/throttle.o \ + ui/drivers/qt/options/ui.o \ + ui/drivers/qt/options/user.o \ + ui/drivers/qt/options/video.o + endif MOC_HEADERS += ui/drivers/ui_qt.h \ ui/drivers/qt/ui_qt_load_core_window.h \ @@ -367,6 +388,10 @@ ifeq ($(HAVE_QT), 1) ui/drivers/qt/coreinfodialog.h \ ui/drivers/qt/playlistentrydialog.h \ ui/drivers/qt/viewoptionsdialog.h + ifeq ($(HAVE_MENU), 1) + MOC_HEADERS += ui/drivers/qt/settingswidgets.h \ + ui/drivers/qt/options/options.h + endif DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) $(QT5NETWORK_CFLAGS) -DHAVE_MAIN #DEFINES += $(QT5WEBENGINE_CFLAGS) @@ -519,16 +544,16 @@ endif ifeq ($(HAVE_COREAUDIO), 1) OBJ += audio/drivers/coreaudio.o - HAVE_COREAUDIO_LIBS = 1 + HAVE_COREAUDIO_LIBS = 1 endif ifeq ($(HAVE_COREAUDIO3), 1) OBJ += audio/drivers/coreaudio3.o - HAVE_COREAUDIO_LIBS = 1 + HAVE_COREAUDIO_LIBS = 1 endif ifeq ($(HAVE_COREAUDIO_LIBS), 1) - LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit + LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit endif ifeq ($(HAVE_CORETEXT), 1) @@ -796,8 +821,8 @@ ifeq ($(HAVE_MENU_COMMON), 1) menu/menu_thumbnail_path.o ifeq ($(HAVE_MENU_COMMON),1) - OBJ += menu/drivers_display/menu_display_null.o - endif + OBJ += menu/drivers_display/menu_display_null.o + endif ifeq ($(HAVE_MENU_WIDGETS), 1) OBJ += menu/widgets/menu_widgets.o @@ -807,8 +832,8 @@ endif ifeq ($(HAVE_OVERLAY), 1) DEFINES += -DHAVE_OVERLAY OBJ += tasks/task_overlay.o \ - input/input_overlay.o \ - led/drivers/led_overlay.o + input/input_overlay.o \ + led/drivers/led_overlay.o endif ifeq ($(HAVE_STB_FONT), 1) @@ -895,11 +920,11 @@ endif ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o \ - input/drivers/wayland_input.o \ - gfx/common/wayland/xdg-shell.o \ - gfx/common/wayland/xdg-shell-unstable-v6.o \ - gfx/common/wayland/idle-inhibit-unstable-v1.o \ - gfx/common/wayland/xdg-decoration-unstable-v1.o + input/drivers/wayland_input.o \ + gfx/common/wayland/xdg-shell.o \ + gfx/common/wayland/xdg-shell-unstable-v6.o \ + gfx/common/wayland/idle-inhibit-unstable-v1.o \ + gfx/common/wayland/xdg-decoration-unstable-v1.o ifeq ($(HAVE_EGL), 1) LIBS += $(EGL_LIBS) endif @@ -1174,7 +1199,7 @@ ifeq ($(HAVE_GL_CONTEXT), 1) OBJ += gfx/drivers_context/cgl_ctx.o else ifneq ($(findstring Win32,$(OS)),) GL_LIBS := -lopengl32 -lgdi32 -lcomdlg32 - WANT_WGL=1 + WANT_WGL=1 endif LIBS += $(GL_LIBS) endif @@ -1347,8 +1372,8 @@ ifeq ($(HAVE_D3D11), 1) gfx/common/d3d11_common.o \ gfx/drivers_font/d3d11_font.o ifeq ($(HAVE_MENU_COMMON), 1) - OBJ += menu/drivers_display/menu_display_d3d11.o - endif + OBJ += menu/drivers_display/menu_display_d3d11.o + endif DEFINES += -DHAVE_D3D11 HAVE_SLANG = 1 HAVE_GLSLANG = 1 @@ -1669,8 +1694,8 @@ ifeq ($(HAVE_NETWORKING), 1) endif # Netplay - DEFINES += -DHAVE_NETWORK_CMD - OBJ += network/netplay/netplay_delta.o \ + DEFINES += -DHAVE_NETWORK_CMD + OBJ += network/netplay/netplay_delta.o \ network/netplay/netplay_frontend.o \ network/netplay/netplay_handshake.o \ network/netplay/netplay_init.o \ @@ -1822,8 +1847,8 @@ ifneq ($(findstring Win32,$(OS)),) gfx/display_servers/dispserv_win32.o ifeq ($(HAVE_MENU_COMMON), 1) - OBJ += menu/drivers_display/menu_display_gdi.o - endif + OBJ += menu/drivers_display/menu_display_gdi.o + endif LIBS += -lmsimg32 -lhid -lsetupapi endif diff --git a/config.def.h b/config.def.h index 3ceef8ad7e..bea3214896 100644 --- a/config.def.h +++ b/config.def.h @@ -720,13 +720,15 @@ static const bool playlist_sort_alphabetical = true; /* File format to use when writing playlists to disk */ static const bool playlist_use_old_format = false; +#ifdef HAVE_MENU /* Specify when to display 'core name' inline on playlist entries */ static const unsigned playlist_show_inline_core_name = PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV; -static const bool playlist_show_sublabels = false; - /* Specifies which runtime record to use on playlist sublabels */ static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE; +#endif + +static const bool playlist_show_sublabels = false; /* Show Menu start-up screen on boot. */ static const bool default_menu_show_start_screen = true; diff --git a/configuration.c b/configuration.c index 02a7ed77d2..0757d735a0 100644 --- a/configuration.c +++ b/configuration.c @@ -1778,8 +1778,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("libnx_overclock", &settings->uints.libnx_overclock, true, SWITCH_DEFAULT_CPU_PROFILE, false); #endif +#ifdef HAVE_MENU SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false); SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false); +#endif *size = count; diff --git a/griffin/griffin.c b/griffin/griffin.c index 271878cdd6..49a36d7dde 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1199,6 +1199,8 @@ PLAYLISTS /*============================================================ MENU ============================================================ */ +#include "../menu/menu_shader.c" + #ifdef HAVE_MENU #include "../menu/menu_driver.c" #include "../menu/menu_input.c" @@ -1235,7 +1237,6 @@ MENU #include "../menu/cbs/menu_cbs_up.c" #include "../menu/cbs/menu_cbs_down.c" #include "../menu/cbs/menu_cbs_contentlist_switch.c" -#include "../menu/menu_shader.c" #include "../menu/menu_displaylist.c" #include "../menu/menu_animation.c" #include "../menu/menu_thumbnail_path.c" diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 6b90c1b80f..06fb0f002d 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -58,6 +58,29 @@ UI #include "../ui/drivers/qt/thumbnaildownload.cpp" #include "../ui/drivers/qt/thumbnailpackdownload.cpp" #include "../ui/drivers/qt/playlistthumbnaildownload.cpp" +#ifdef HAVE_MENU +#include "../ui/drivers/qt/settingswidgets.cpp" +#include "../ui/drivers/qt/options/drivers.cpp" +#include "../ui/drivers/qt/options/video.cpp" +#include "../ui/drivers/qt/options/audio.cpp" +#include "../ui/drivers/qt/options/saving.cpp" +#include "../ui/drivers/qt/options/throttle.cpp" +#include "../ui/drivers/qt/options/osd.cpp" +#include "../ui/drivers/qt/options/input.cpp" +#include "../ui/drivers/qt/options/directory.cpp" +#include "../ui/drivers/qt/options/logging.cpp" +#include "../ui/drivers/qt/options/core.cpp" +#include "../ui/drivers/qt/options/configuration.cpp" +#include "../ui/drivers/qt/options/latency.cpp" +#include "../ui/drivers/qt/options/playlists.cpp" +#include "../ui/drivers/qt/options/user.cpp" +#include "../ui/drivers/qt/options/recording.cpp" +#include "../ui/drivers/qt/options/ui.cpp" +#include "../ui/drivers/qt/options/achievements.cpp" +#include "../ui/drivers/qt/options/network.cpp" +#include "../ui/drivers/qt/moc_settingswidgets.cpp" +#include "../ui/drivers/qt/options/moc_options.cpp" +#endif #include "../ui/drivers/moc_ui_qt.cpp" #include "../ui/drivers/qt/moc_coreinfodialog.cpp" #include "../ui/drivers/qt/moc_coreoptionsdialog.cpp" diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 16c6f3169e..bc1950ce50 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -1814,7 +1814,107 @@ true true true - + + + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + false + false + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + false + false + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + + + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + false + false + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + false + false + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + diff --git a/retroarch.c b/retroarch.c index a1308602a7..3b8df25823 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4897,13 +4897,15 @@ bool rarch_write_debug_info(void) gfx_ctx_ident_t ident_info = {0}; const input_driver_t *input_driver; const input_device_driver_t *joypad_driver; - const char *driver = menu_driver_ident(); + const char *driver; +#ifdef HAVE_MENU + driver = menu_driver_ident(); if (string_is_equal(driver, settings->arrays.menu_driver)) filestream_printf(file, " - Menu: %s\n", !string_is_empty(driver) ? driver : "n/a"); else filestream_printf(file, " - Menu: %s (configured for %s)\n", !string_is_empty(driver) ? driver : "n/a", !string_is_empty(settings->arrays.menu_driver) ? settings->arrays.menu_driver : "n/a"); - +#endif driver = #ifdef HAVE_THREADS (video_driver_is_threaded()) ? diff --git a/ui/drivers/qt/options/achievements.cpp b/ui/drivers/qt/options/achievements.cpp new file mode 100644 index 0000000000..76d0acf81f --- /dev/null +++ b/ui/drivers/qt/options/achievements.cpp @@ -0,0 +1,48 @@ +#include "options.h" + +AchievementsCategory::AchievementsCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS); + setCategoryIcon("menu_achievements"); +} + +QVector AchievementsCategory::pages() +{ + QVector pages; + + pages << new AchievementsPage(this); + + return pages; +} + +AchievementsPage::AchievementsPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *AchievementsPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *group = new CheckableSettingsGroup(MENU_ENUM_LABEL_CHEEVOS_ENABLE); + + group->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + group->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_AUTO_SCREENSHOT); + + layout->addWidget(group); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/audio.cpp b/ui/drivers/qt/options/audio.cpp new file mode 100644 index 0000000000..0ba87ed664 --- /dev/null +++ b/ui/drivers/qt/options/audio.cpp @@ -0,0 +1,94 @@ +#include + +#include "options.h" + +AudioCategory::AudioCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS); + setCategoryIcon("menu_audio"); +} + +QVector AudioCategory::pages() +{ + QVector pages; + + pages << new AudioPage(this); + pages << new MenuSoundsPage(this); + + return pages; +} + +AudioPage::AudioPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *AudioPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *outputGroup = new SettingsGroup("Output"); + SettingsGroup *resamplerGroup = new SettingsGroup("Resampler"); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *dspGroup = new SettingsGroup("DSP plugin"); + SettingsGroup *volumeGroup = new SettingsGroup("Volume"); + + QHBoxLayout *volumeLayout = new QHBoxLayout(); + + outputGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE); + outputGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); + outputGroup->addStringLineEdit(MENU_ENUM_LABEL_AUDIO_DEVICE); + outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); + + resamplerGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + resamplerGroup->addUIntComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY); + resamplerGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE); + + syncGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_SYNC); + syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW); + syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA); + + dspGroup->addFileSelector(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN); + + volumeLayout->addWidget(new CheckableIcon(MENU_ENUM_LABEL_AUDIO_MUTE, qApp->style()->standardIcon(QStyle::SP_MediaVolumeMuted))); + volumeLayout->addLayout(new FloatSliderAndSpinBox(MENU_ENUM_LABEL_AUDIO_VOLUME)); + volumeGroup->addRow(volumeLayout); + + layout->addWidget(outputGroup); + layout->addWidget(resamplerGroup); + layout->addWidget(syncGroup); + layout->addWidget(dspGroup); + layout->addWidget(volumeGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +MenuSoundsPage::MenuSoundsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_SOUNDS); +} + +QWidget *MenuSoundsPage::widget() +{ + QWidget *widget = new QWidget(); + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE_MENU); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_OK); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_CANCEL); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_NOTICE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_BGM); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/configuration.cpp b/ui/drivers/qt/options/configuration.cpp new file mode 100644 index 0000000000..017bb97cb5 --- /dev/null +++ b/ui/drivers/qt/options/configuration.cpp @@ -0,0 +1,38 @@ +#include "options.h" + +ConfigurationCategory::ConfigurationCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS); + setCategoryIcon("setting"); +} + +QVector ConfigurationCategory::pages() +{ + QVector pages; + + pages << new ConfigurationPage(this); + + return pages; +} + +ConfigurationPage::ConfigurationPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *ConfigurationPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT); + layout->addCheckBox(MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS); + layout->addCheckBox(MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/core.cpp b/ui/drivers/qt/options/core.cpp new file mode 100644 index 0000000000..755ffced3a --- /dev/null +++ b/ui/drivers/qt/options/core.cpp @@ -0,0 +1,38 @@ +#include "options.h" + +CoreCategory::CoreCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS); + setCategoryIcon("core-options"); +} + +QVector CoreCategory::pages() +{ + QVector pages; + + pages << new CorePage(this); + + return pages; +} + +CorePage::CorePage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *CorePage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT); + layout->addCheckBox(MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN); + layout->addCheckBox(MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE); + layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/directory.cpp b/ui/drivers/qt/options/directory.cpp new file mode 100644 index 0000000000..c665096393 --- /dev/null +++ b/ui/drivers/qt/options/directory.cpp @@ -0,0 +1,58 @@ +#include "options.h" + +DirectoryCategory::DirectoryCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS); + setCategoryIcon("folder"); +} + +QVector DirectoryCategory::pages() +{ + QVector pages; + + pages << new DirectoryPage(this); + + return pages; +} + +DirectoryPage::DirectoryPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *DirectoryPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addDirectorySelector(MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_ASSETS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_DIR_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_INFO_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CURSOR_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_FILTER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_AUDIO_FILTER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_SHADER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_OVERLAY_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_PLAYLIST_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SAVEFILE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SAVESTATE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CACHE_DIRECTORY); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/drivers.cpp b/ui/drivers/qt/options/drivers.cpp new file mode 100644 index 0000000000..64db8534ab --- /dev/null +++ b/ui/drivers/qt/options/drivers.cpp @@ -0,0 +1,45 @@ +#include "options.h" + +DriversCategory::DriversCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS); + setCategoryIcon("menu_drivers"); +} + +QVector DriversCategory::pages() +{ + QVector pages; + + pages << new DriversPage(this); + + return pages; +} + +DriversPage::DriversPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS); +} + +QWidget *DriversPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addStringComboBox(MENU_ENUM_LABEL_INPUT_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_JOYPAD_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_CAMERA_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_LOCATION_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_MENU_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_RECORD_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_MIDI_DRIVER); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/input.cpp b/ui/drivers/qt/options/input.cpp new file mode 100644 index 0000000000..54fa5ccca3 --- /dev/null +++ b/ui/drivers/qt/options/input.cpp @@ -0,0 +1,162 @@ +#include + +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../input/input_driver.h" + +#ifndef CXX_BUILD +} +#endif + +InputCategory::InputCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS); + setCategoryIcon("core-input-remapping-options"); +} + +QVector InputCategory::pages() +{ + QVector pages; + + pages << new InputPage(this); + pages << new HotkeyBindsPage(this); + + return pages; +} + +InputPage::InputPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *InputPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_MAX_USERS); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_HOLD); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_TURBO_PERIOD); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_DUTY_CYCLE); + + widget->setLayout(layout); + + return widget; +} + +HotkeyBindsPage::HotkeyBindsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS); +} + +QWidget *HotkeyBindsPage::widget() +{ + QWidget *widget = new QWidget; + + QHBoxLayout *layout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + FormLayout *rightLayout = new FormLayout; + + unsigned i; + unsigned count = 0; + unsigned half = 40 / 2; /* TODO unhardcode */ + + for (i = 0; i < RARCH_BIND_LIST_END; i++) + { + if (count < half) + { + if (leftLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i))) + count++; + } + else + rightLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i)); + } + + layout->addLayout(leftLayout); + layout->addSpacing(50); + layout->addLayout(rightLayout); + + widget->setLayout(layout); + + return widget; +} + +UserBindsPage::UserBindsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName("User Binds"); +} + +QWidget *UserBindsPage::widget() +{ + QWidget *widget = new QWidget; + + QGridLayout *layout = new QGridLayout; + + unsigned count = 0; + unsigned p, retro_id; + unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + + QComboBox *userCombo = new QComboBox; + QStackedWidget *stack = new QStackedWidget; + + for (p = 0; p < max_users; p++) + { + userCombo->addItem(QString::number(p)); + + QWidget *uWidget = new QWidget(); + FormLayout *form = new FormLayout(); + + for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 20; retro_id++) + { + char descriptor[300]; + const struct retro_keybind *auto_bind = NULL; + const struct retro_keybind *keybind = NULL; + + keybind = &input_config_binds[p][retro_id]; + + auto_bind = (const struct retro_keybind*) + input_config_get_bind_auto(p, retro_id); + + input_config_get_bind_string(descriptor, + keybind, auto_bind, sizeof(descriptor)); + + const struct retro_keybind *keyptr = + &input_config_binds[p][retro_id]; + + QString label = msg_hash_to_str(keyptr->enum_idx); + + form->addRow(QString(msg_hash_to_str(keyptr->enum_idx)), new QPushButton(QString(descriptor))); + } + uWidget->setLayout(form); + + stack->addWidget(uWidget); + } + + connect(userCombo, SIGNAL(activated(int)), stack, SLOT(setCurrentIndex(int))); + + layout->addWidget(userCombo, 0, 0); + layout->addWidget(stack, 1, 0); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/latency.cpp b/ui/drivers/qt/options/latency.cpp new file mode 100644 index 0000000000..664e0785a2 --- /dev/null +++ b/ui/drivers/qt/options/latency.cpp @@ -0,0 +1,57 @@ +#include "options.h" + +LatencyCategory::LatencyCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS); + setCategoryIcon("menu_latency"); +} + +QVector LatencyCategory::pages() +{ + QVector pages; + + pages << new LatencyPage(this); + + return pages; +} + +LatencyPage::LatencyPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *LatencyPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + CheckableSettingsGroup *runAheadGpuSync = new CheckableSettingsGroup(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED); + + { + rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + + if (hardSyncSetting) + { + CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); + + hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); + + layout->addRow(hardSyncGroup); + } + } + + layout->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + layout->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + + runAheadGpuSync->addUIntComboBox(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES); + runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE); + runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS); + layout->addRow(runAheadGpuSync); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/logging.cpp b/ui/drivers/qt/options/logging.cpp new file mode 100644 index 0000000000..734bb480b6 --- /dev/null +++ b/ui/drivers/qt/options/logging.cpp @@ -0,0 +1,37 @@ +#include "options.h" + +LoggingCategory::LoggingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS); + setCategoryIcon("menu_log"); +} + +QVector LoggingCategory::pages() +{ + QVector pages; + + pages << new LoggingPage(this); + + return pages; +} + +LoggingPage::LoggingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *LoggingPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_LOG_VERBOSITY); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL); + layout->addCheckBox(MENU_ENUM_LABEL_PERFCNT_ENABLE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/network.cpp b/ui/drivers/qt/options/network.cpp new file mode 100644 index 0000000000..4d60da0790 --- /dev/null +++ b/ui/drivers/qt/options/network.cpp @@ -0,0 +1,171 @@ +#include + +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include + +#include "../../network/netplay/netplay.h" + +#ifndef CXX_BUILD +} +#endif + +NetworkCategory::NetworkCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS); + setCategoryIcon("menu_network"); +} + +QVector NetworkCategory::pages() +{ + QVector pages; + + pages << new NetplayPage(this); + pages << new UpdaterPage(this); + + return pages; +} + +NetplayPage::NetplayPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_NETPLAY); +} + +QWidget *NetplayPage::widget() +{ + QWidget *widget = new QWidget; + QGridLayout *layout = new QGridLayout; + FormLayout *checksLayout = new FormLayout; + QGroupBox *serverGroup = new QGroupBox("Server"); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *slaveGroup = new SettingsGroup("Slave-Mode"); + SettingsGroup *inputGroup = new SettingsGroup("Input Sharing"); + SettingsGroup *deviceGroup = new SettingsGroup("Device Request"); + FormLayout *serverForm = new FormLayout; + QHBoxLayout *serverLayout = new QHBoxLayout; + QVBoxLayout *mainLayout = new QVBoxLayout; + QGridLayout *requestGrid = new QGridLayout; + unsigned i = 0; + unsigned row = 0; + unsigned column = 0; + + checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE); + checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR); + + serverForm->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS); + serverForm->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT); + serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_PASSWORD); + serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD); + serverForm->addCheckBox(MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL); + + serverLayout->addWidget(createMitmServerGroup()); + serverLayout->addSpacing(30); + serverLayout->addLayout(serverForm); + + serverGroup->setLayout(serverLayout); + + slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES); + slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES); + + syncGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE); + + inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL); + inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG); + + for (i = 0; i < MAX_USERS; i++) + { + if (column % 4 == 0) + { + column = 0; + row++; + } + requestGrid->addWidget(new CheckBox((enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + i)), row, column); + column++; + } + + deviceGroup->addRow(requestGrid); + + layout->addLayout(checksLayout, 0, 0, 1, 2); + layout->addWidget(serverGroup, 1, 0, 1, 2); + layout->addWidget(slaveGroup, 2, 0, 1, 1); + layout->addWidget(syncGroup, 2, 1, 2, 1); + layout->addWidget(inputGroup, 3, 0, 1, 1); + layout->addWidget(deviceGroup, 4, 0, 1, 2); + + mainLayout->addLayout(layout); + + mainLayout->addStretch(); + + widget->setLayout(mainLayout); + + return widget; +} + +QGroupBox *NetplayPage::createMitmServerGroup() +{ + CheckableSettingsGroup *groupBox = new CheckableSettingsGroup(MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER); + QButtonGroup *buttonGroup = new QButtonGroup(this); + + rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); + + unsigned i; + unsigned list_len = ARRAY_SIZE(netplay_mitm_server_list); + + if (!setting) + return nullptr; + + for (i = 0; i < list_len; i++) + { + QRadioButton *radioButton = new QRadioButton(netplay_mitm_server_list[i].description); + + /* find the currently selected server in the list */ + if (string_is_equal(setting->value.target.string, netplay_mitm_server_list[i].name)) + { + radioButton->setChecked(true); + } + + buttonGroup->addButton(radioButton, i); + + groupBox->addRow(radioButton); + } + + connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onRadioButtonClicked(int))); + + return groupBox; +} + +void NetplayPage::onRadioButtonClicked(int id) +{ + rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); + + strlcpy(setting->value.target.string, netplay_mitm_server_list[id].name, setting->size); +} + +UpdaterPage::UpdaterPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS); +} + +QWidget *UpdaterPage::widget() +{ + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addStringLineEdit(MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL); + layout->addStringLineEdit(MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL); + layout->addCheckBox(MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/options.h b/ui/drivers/qt/options/options.h new file mode 100644 index 0000000000..b2549f1964 --- /dev/null +++ b/ui/drivers/qt/options/options.h @@ -0,0 +1,537 @@ +#ifndef OPTIONS_H +#define OPTIONS_H + +#include +#include +#include +#include + +#include "../settingswidgets.h" + +class MainWindow; +class ViewOptionsWidget; + +class OptionsPage : public QObject +{ + Q_OBJECT + +public: + OptionsPage(QObject *parent = nullptr) + : QObject(parent) + { + } + + QString displayName() const + { + return m_displayName; + } + + virtual QWidget *widget() = 0; + virtual void load() {} + virtual void apply() {} + +protected: + void setDisplayName(msg_hash_enums name) + { + m_displayName = msg_hash_to_str(name); + } + + void setDisplayName(const QString& name) + { + m_displayName = name; + } + + QString m_displayName = "General"; +}; + +class OptionsCategory : public QObject +{ + Q_OBJECT +public: + OptionsCategory(QObject *parent = nullptr) : QObject(parent) {} + OptionsCategory(MainWindow *mainwindow, QObject *parent = nullptr) : QObject(parent) {} + virtual QVector pages() = 0; + QString displayName() const { return m_displayName; } + QString categoryIconName() const { return m_categoryIconName; } + virtual void load() + { + for (int i = 0; i < m_pages.size(); i++) + m_pages.at(i)->load(); + } + virtual void apply() + { + for (int i = 0; i < m_pages.size(); i++) + m_pages.at(i)->apply(); + } +protected: + void setDisplayName(msg_hash_enums name) { m_displayName = msg_hash_to_str(name); } + void setCategoryIcon(const QString &categoryIconName) { m_categoryIconName = categoryIconName; } + QString m_displayName; + QString m_categoryIconName = "setting"; + QVector m_pages; +}; + +/*********************************************************** + Drivers +************************************************************/ +class DriversCategory : public OptionsCategory +{ +public: + DriversCategory(QWidget *parent); + QVector pages(); +}; + +class DriversPage : public OptionsPage +{ + Q_OBJECT +public: + DriversPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Video +************************************************************/ +class VideoCategory : public OptionsCategory +{ +public: + VideoCategory(QWidget *parent); + QVector pages(); +}; + +class AspectRatioRadioButton : public QRadioButton +{ + Q_OBJECT +public: + AspectRatioRadioButton(unsigned min, unsigned max, QWidget *parent = 0); +private: + unsigned m_min; + unsigned m_max; +}; + +class AspectRatioGroup : public SettingsGroup +{ + Q_OBJECT +public: + AspectRatioGroup(const QString &title, QWidget *parent = 0); +private slots: + void paintEvent(QPaintEvent *event); + void onAspectRadioToggled(bool checked); + void onAspectRadioClicked(bool checked); +private: + AspectRatioRadioButton *m_radioButton; + UIntComboBox *m_comboBox; +}; + +class VideoPage : public OptionsPage +{ + Q_OBJECT +public: + VideoPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onResolutionComboIndexChanged(const QString& value); +private: + QComboBox *m_resolutionCombo; +}; + +class CrtSwitchresPage : public OptionsPage +{ + Q_OBJECT +public: + CrtSwitchresPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onCrtSuperResolutionComboIndexChanged(int index); +private: + QComboBox *m_crtSuperResolutionCombo; +}; + +/************************************************************ + Audio +************************************************************/ +class AudioCategory : public OptionsCategory +{ +public: + AudioCategory(QWidget *parent); + QVector pages(); +}; + +class AudioPage : public OptionsPage +{ + Q_OBJECT +public: + AudioPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class MenuSoundsPage : public OptionsPage +{ + Q_OBJECT +public: + MenuSoundsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Input +************************************************************/ +class InputCategory : public OptionsCategory +{ +public: + InputCategory(QWidget *parent); + QVector pages(); +}; + +class InputPage : public OptionsPage +{ + Q_OBJECT +public: + InputPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class HotkeyBindsPage : public OptionsPage +{ + Q_OBJECT +public: + HotkeyBindsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class UserBindsPage : public OptionsPage +{ + Q_OBJECT +public: + UserBindsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Latency +************************************************************/ +class LatencyCategory : public OptionsCategory +{ +public: + LatencyCategory(QWidget *parent); + QVector pages(); +}; + +class LatencyPage : public OptionsPage +{ + Q_OBJECT +public: + LatencyPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Core +************************************************************/ +class CoreCategory : public OptionsCategory +{ +public: + CoreCategory(QWidget *parent); + QVector pages(); +}; + +class CorePage : public OptionsPage +{ + Q_OBJECT +public: + CorePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Configuration +************************************************************/ +class ConfigurationCategory : public OptionsCategory +{ +public: + ConfigurationCategory(QWidget *parent); + QVector pages(); +}; + +class ConfigurationPage : public OptionsPage +{ + Q_OBJECT +public: + ConfigurationPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Saving +************************************************************/ +class SavingCategory : public OptionsCategory +{ +public: + SavingCategory(QWidget *parent); + QVector pages(); +}; + +class SavingPage : public OptionsPage +{ + Q_OBJECT +public: + SavingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Logging +************************************************************/ +class LoggingCategory : public OptionsCategory +{ +public: + LoggingCategory(QWidget *parent); + QVector pages(); +}; + +class LoggingPage : public OptionsPage +{ + Q_OBJECT +public: + LoggingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Frame Throttle +************************************************************/ +class FrameThrottleCategory : public OptionsCategory +{ +public: + FrameThrottleCategory(QWidget *parent); + QVector pages(); +}; + +class FrameThrottlePage : public OptionsPage +{ + Q_OBJECT +public: + FrameThrottlePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class RewindPage : public OptionsPage +{ + Q_OBJECT +public: + RewindPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Recording +************************************************************/ +class RecordingCategory : public OptionsCategory +{ +public: + RecordingCategory(QWidget *parent); + QVector pages(); +}; + +class RecordingPage : public OptionsPage +{ + Q_OBJECT +public: + RecordingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + User Interface +************************************************************/ +class UserInterfaceCategory : public OptionsCategory +{ +public: + UserInterfaceCategory(QWidget *parent); + UserInterfaceCategory(MainWindow *mainwindow, QWidget *parent); + QVector pages(); +private: + MainWindow *m_mainwindow; +}; + +class UserInterfacePage : public OptionsPage +{ + Q_OBJECT +public: + UserInterfacePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class ViewsPage : public OptionsPage +{ + Q_OBJECT +public: + ViewsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class QuickMenuPage : public OptionsPage +{ + Q_OBJECT +public: + QuickMenuPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class AppearancePage : public OptionsPage +{ + Q_OBJECT +public: + AppearancePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class DesktopMenuPage : public OptionsPage +{ + Q_OBJECT +public: + DesktopMenuPage(MainWindow *mainwindow, QObject *parent = nullptr); + QWidget *widget(); + void load(); + void apply(); +private: + ViewOptionsWidget *m_widget; +}; + +/************************************************************ + Onscreen Display +************************************************************/ +class OnscreenDisplayCategory : public OptionsCategory +{ +public: + OnscreenDisplayCategory(QWidget *parent); + QVector pages(); +}; + +class OverlayPage : public OptionsPage +{ + Q_OBJECT +public: + OverlayPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class NotificationsPage : public OptionsPage +{ + Q_OBJECT +public: + NotificationsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Achievements +************************************************************/ +class AchievementsCategory : public OptionsCategory +{ +public: + AchievementsCategory(QWidget *parent); + QVector pages(); +}; + +class AchievementsPage : public OptionsPage +{ + Q_OBJECT +public: + AchievementsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Network +************************************************************/ +class NetworkCategory : public OptionsCategory +{ +public: + NetworkCategory(QWidget *parent); + QVector pages(); +}; + +class NetplayPage : public OptionsPage +{ + Q_OBJECT +public: + NetplayPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onRadioButtonClicked(int); +private: + QGroupBox* createMitmServerGroup(); +}; + +class UpdaterPage : public OptionsPage +{ + Q_OBJECT +public: + UpdaterPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Playlists +************************************************************/ +class PlaylistsCategory : public OptionsCategory +{ +public: + PlaylistsCategory(QWidget *parent); + QVector pages(); +}; + +class PlaylistsPage : public OptionsPage +{ + Q_OBJECT +public: + PlaylistsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class AccountsPage : public OptionsPage +{ + Q_OBJECT +public: + AccountsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + User +************************************************************/ +class UserCategory : public OptionsCategory +{ +public: + UserCategory(QWidget *parent); + QVector pages(); +}; + +class UserPage : public OptionsPage +{ + Q_OBJECT +public: + UserPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Directory +************************************************************/ +class DirectoryCategory : public OptionsCategory +{ +public: + DirectoryCategory(QWidget *parent); + QVector pages(); +}; + +class DirectoryPage : public OptionsPage +{ + Q_OBJECT +public: + DirectoryPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +#endif diff --git a/ui/drivers/qt/options/osd.cpp b/ui/drivers/qt/options/osd.cpp new file mode 100644 index 0000000000..311f07c894 --- /dev/null +++ b/ui/drivers/qt/options/osd.cpp @@ -0,0 +1,95 @@ +#include "options.h" + +OnscreenDisplayCategory::OnscreenDisplayCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS); + setCategoryIcon("menu_osd"); +} + +QVector OnscreenDisplayCategory::pages() +{ + QVector pages; + + pages << new OverlayPage(this); + pages << new NotificationsPage(this); + + return pages; +} + +NotificationsPage::NotificationsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS); +} + +QWidget *NotificationsPage::widget() +{ + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *notificationsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_FONT_ENABLE); + CheckableSettingsGroup *bgGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_ENABLE); + + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FPS_SHOW); + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FRAMECOUNT_SHOW); + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_MEMORY_SHOW); + notificationsGroup->addFontSelector(MENU_ENUM_LABEL_VIDEO_FONT_PATH); + notificationsGroup->addFloatSpinBox(MENU_ENUM_LABEL_VIDEO_FONT_SIZE); + notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X); + notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y); + notificationsGroup->addRow("Notification Color: ", new FloatColorButton( + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_RED, + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_GREEN, + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_BLUE)); + + bgGroup->addRow("Notification Background Color: ", new UIntColorButton( + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_RED, + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_GREEN, + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_BLUE)); + bgGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_OPACITY); + + notificationsGroup->addRow(bgGroup); + + layout->addWidget(notificationsGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +OverlayPage::OverlayPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS); +} + +QWidget *OverlayPage::widget() +{ + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *overlayGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE); + CheckableSettingsGroup *inputsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS); + + overlayGroup->addCheckBox(MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED); + overlayGroup->addCheckBox(MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU); + + inputsGroup->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT); + + overlayGroup->addRow(inputsGroup); + + overlayGroup->addFileSelector(MENU_ENUM_LABEL_OVERLAY_PRESET); + overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_OPACITY); + overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_SCALE); + + layout->addWidget(overlayGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/playlists.cpp b/ui/drivers/qt/options/playlists.cpp new file mode 100644 index 0000000000..3670684b5b --- /dev/null +++ b/ui/drivers/qt/options/playlists.cpp @@ -0,0 +1,43 @@ +#include "options.h" + +PlaylistsCategory::PlaylistsCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS); + setCategoryIcon("menu_playlist"); +} + +QVector PlaylistsCategory::pages() +{ + QVector pages; + + pages << new PlaylistsPage(this); + + return pages; +} + +PlaylistsPage::PlaylistsPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *PlaylistsPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + CheckableSettingsGroup *history = new CheckableSettingsGroup(MENU_ENUM_LABEL_HISTORY_LIST_ENABLE); + + history->addUIntSpinBox(MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE); + + layout->addRow(history); + + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME); + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE); + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/recording.cpp b/ui/drivers/qt/options/recording.cpp new file mode 100644 index 0000000000..cf8e354ff1 --- /dev/null +++ b/ui/drivers/qt/options/recording.cpp @@ -0,0 +1,57 @@ +#include "options.h" + +RecordingCategory::RecordingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS); + setCategoryIcon("menu_record"); +} + +QVector RecordingCategory::pages() +{ + QVector pages; + + pages << new RecordingPage(this); + + return pages; +} + +RecordingPage::RecordingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *RecordingPage::widget() +{ + QWidget * widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + SettingsGroup *recordingGroup = new SettingsGroup("Recording"); + SettingsGroup *streamingGroup = new SettingsGroup("Streaming"); + QHBoxLayout *hl = new QHBoxLayout; + + recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_QUALITY); + recordingGroup->addFileSelector(MENU_ENUM_LABEL_RECORD_CONFIG); + recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_THREADS); + recordingGroup->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD); + recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_RECORD); + + hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_STREAMING_MODE)); + hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_VIDEO_STREAM_QUALITY)); + + streamingGroup->addRow(hl); + + streamingGroup->addFileSelector(MENU_ENUM_LABEL_STREAM_CONFIG); + streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_TITLE); + streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_URL); + streamingGroup->addUIntSpinBox(MENU_ENUM_LABEL_UDP_STREAM_PORT); + + layout->addWidget(recordingGroup); + layout->addWidget(streamingGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/saving.cpp b/ui/drivers/qt/options/saving.cpp new file mode 100644 index 0000000000..c91a5378b1 --- /dev/null +++ b/ui/drivers/qt/options/saving.cpp @@ -0,0 +1,65 @@ +#include "options.h" + +SavingCategory::SavingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS); + setCategoryIcon("menu_saving"); +} + +QVector SavingCategory::pages() +{ + QVector pages; + + pages << new SavingPage(this); + + return pages; +} + +SavingPage::SavingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *SavingPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + SettingsGroup *savesGroup = new SettingsGroup("Saves"); + SettingsGroup *savestatesGroup = new SettingsGroup("Savestates"); + CheckableSettingsGroup *autoSavestatesGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE); + SettingsGroup *saveRamGroup = new SettingsGroup("SaveRAM"); + SettingsGroup *systemFilesDirGroup = new SettingsGroup("System Files"); + SettingsGroup *screenshotsDirGroup = new SettingsGroup("Screenshots"); + + savesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE); + savesGroup->addCheckBox(MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE); + + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX); + + autoSavestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD); + + savestatesGroup->addRow(autoSavestatesGroup); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE); + + saveRamGroup->addCheckBox(MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE); + saveRamGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUTOSAVE_INTERVAL); + + systemFilesDirGroup->addCheckBox(MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE); + + screenshotsDirGroup->addCheckBox(MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE); + + layout->addRow(savesGroup); + layout->addRow(savestatesGroup); + layout->addRow(saveRamGroup); + layout->addRow(systemFilesDirGroup); + layout->addRow(screenshotsDirGroup); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/throttle.cpp b/ui/drivers/qt/options/throttle.cpp new file mode 100644 index 0000000000..a59260c30d --- /dev/null +++ b/ui/drivers/qt/options/throttle.cpp @@ -0,0 +1,62 @@ +#include "options.h" + +FrameThrottleCategory::FrameThrottleCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS); + setCategoryIcon("menu_frameskip"); +} + +QVector FrameThrottleCategory::pages() +{ + QVector pages; + + pages << new FrameThrottlePage(this); + pages << new RewindPage(this); + + return pages; +} + +FrameThrottlePage::FrameThrottlePage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS); +} + +QWidget *FrameThrottlePage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addFloatSpinBox(MENU_ENUM_LABEL_FASTFORWARD_RATIO); + layout->addFloatSpinBox(MENU_ENUM_LABEL_SLOWMOTION_RATIO); + layout->addCheckBox(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE); + + widget->setLayout(layout); + + return widget; +} + +RewindPage::RewindPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS); +} + +QWidget *RewindPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_REWIND_ENABLE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_GRANULARITY); + layout->addSizeSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp new file mode 100644 index 0000000000..9f8d659d59 --- /dev/null +++ b/ui/drivers/qt/options/ui.cpp @@ -0,0 +1,288 @@ +#include "options.h" +#include "../viewoptionsdialog.h" + +UserInterfaceCategory::UserInterfaceCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS); + setCategoryIcon("menu_ui"); +} + +UserInterfaceCategory::UserInterfaceCategory(MainWindow *mainwindow, QWidget *parent) : + OptionsCategory(parent) + ,m_mainwindow(mainwindow) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS); + setCategoryIcon("menu_ui"); + + m_pages << new UserInterfacePage(this); + m_pages << new ViewsPage(this); + /* pages << new QuickMenuPage(parent); */ + m_pages << new AppearancePage(this); + m_pages << new DesktopMenuPage(m_mainwindow, this); +} + +QVector UserInterfaceCategory::pages() +{ + return m_pages; +} + +UserInterfacePage::UserInterfacePage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *UserInterfacePage::widget() +{ + QWidget * widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *menuGroup = new SettingsGroup("Menu"); + SettingsGroup *inputGroup = new SettingsGroup("Input"); + SettingsGroup *miscGroup = new SettingsGroup("Miscelaneous"); + CheckableSettingsGroup *desktopGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); + + menuGroup->addCheckBox(MENU_ENUM_LABEL_SHOW_ADVANCED_SETTINGS); + + { + rarch_setting_t *kioskMode = menu_setting_find_enum(MENU_ENUM_LABEL_MENU_ENABLE_KIOSK_MODE); + + /* only on xmb and ozone*/ + if (kioskMode) + { + CheckableSettingsGroup *kioskGroup = new CheckableSettingsGroup(kioskMode, widget); + + kioskGroup->addPasswordLineEdit(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); + + menuGroup->addRow(kioskGroup); + } + + } + + menuGroup->addCheckBox(MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND); + menuGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_LIBRETRO); + + inputGroup->addCheckBox(MENU_ENUM_LABEL_MOUSE_ENABLE); + inputGroup->addCheckBox(MENU_ENUM_LABEL_POINTER_ENABLE); + + menuGroup->addRow(inputGroup); + menuGroup->addCheckBox(MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE); + + miscGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_NONACTIVE); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION); + + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_ENABLE); + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT); + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_MENUBAR_ENABLE); + + /* layout->addCheckBox(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); */ + desktopGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_TOGGLE); + + layout->addWidget(menuGroup); + layout->addWidget(miscGroup); + layout->addWidget(desktopGroup); + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +ViewsPage::ViewsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS); +} + +QWidget *ViewsPage::widget() +{ + QWidget * widget = new QWidget(); + QHBoxLayout *mainLayout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + QVBoxLayout *rightLayout = new QVBoxLayout; + SettingsGroup *quickMenu = new SettingsGroup("Quick Menu"); + QuickMenuPage *quickPage = new QuickMenuPage(this); + SettingsGroup *mainMenu = new SettingsGroup("Main Menu"); + SettingsGroup *tabs = new SettingsGroup("Tabs"); + SettingsGroup *status = new SettingsGroup("Status"); + SettingsGroup *startScreen = new SettingsGroup("StartScreen"); + + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CORE); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT); + /* mainMenu->addCheckBox(MENU_ENUM_LABEL_SHOW_WIMP); */ + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_INFORMATION); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_HELP); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_REBOOT); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN); + + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS); + tabs->addPasswordLineEdit(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_ADD); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS); + + status->addCheckBox(MENU_ENUM_LABEL_TIMEDATE_ENABLE); + status->addUIntComboBox(MENU_ENUM_LABEL_TIMEDATE_STYLE); + status->addCheckBox(MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE); + status->addCheckBox(MENU_ENUM_LABEL_CORE_ENABLE); + + startScreen->addCheckBox(MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN); + + quickMenu->layout()->setContentsMargins(0, 0, 0, 0); + quickMenu->addRow(quickPage->widget()); + + leftLayout->addRow(mainMenu); + leftLayout->addRow(tabs); + leftLayout->addRow(startScreen); + + rightLayout->addWidget(quickMenu); + rightLayout->addWidget(status); + rightLayout->addStretch(); + + mainLayout->addLayout(leftLayout); + mainLayout->addLayout(rightLayout); + + widget->setLayout(mainLayout); + + return widget; +} + +QuickMenuPage::QuickMenuPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS); +} + +QWidget *QuickMenuPage::widget() +{ + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION); + + widget->setLayout(layout); + + return widget; +} + +AppearancePage::AppearancePage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS); +} + +QWidget *AppearancePage::widget() +{ + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addFileSelector(MENU_ENUM_LABEL_MENU_WALLPAPER); + layout->addCheckBox(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); + layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); + layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); + layout->addUIntComboBox(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); + layout->addFileSelector(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); + layout->addCheckBox(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); + layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); + layout->addFontSelector(MENU_ENUM_LABEL_XMB_FONT); + layout->addUIntColorButton("Menu Font Color: ", + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_LAYOUT); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_THEME); + layout->addCheckBox(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); + layout->addUIntComboBox(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); + layout->addCheckBox(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); + + { + rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); + + if (thumbnails) + { + QHBoxLayout *thumbsLayout = new QHBoxLayout; + + rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); + + thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); + + if (leftThumbnails) + thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); + + layout->addRow(thumbsLayout); + } + } + + layout->addCheckBox(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_TICKER_TYPE); + layout->addFloatSpinBox(MENU_ENUM_LABEL_MENU_TICKER_SPEED); + + widget->setLayout(layout); + + return widget; +} + +DesktopMenuPage::DesktopMenuPage(MainWindow *mainwindow, QObject *parent) : + OptionsPage(parent) + ,m_widget(new ViewOptionsWidget(mainwindow)) +{ + setDisplayName("Desktop Menu"); +} + +void DesktopMenuPage::apply() +{ + m_widget->saveViewOptions(); +} + +void DesktopMenuPage::load() +{ + m_widget->loadViewOptions(); +} + +QWidget *DesktopMenuPage::widget() +{ + return m_widget; +} diff --git a/ui/drivers/qt/options/user.cpp b/ui/drivers/qt/options/user.cpp new file mode 100644 index 0000000000..a004785702 --- /dev/null +++ b/ui/drivers/qt/options/user.cpp @@ -0,0 +1,76 @@ +#include "options.h" + +UserCategory::UserCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_SETTINGS); + setCategoryIcon("menu_user"); +} + +QVector UserCategory::pages() +{ + QVector pages; + + pages << new UserPage(this); + pages << new AccountsPage(this); + + return pages; +} + +UserPage::UserPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *UserPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_NICKNAME); + layout->addUIntComboBox(MENU_ENUM_LABEL_USER_LANGUAGE); + + widget->setLayout(layout); + + return widget; +} + +AccountsPage::AccountsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST); +} + +QWidget *AccountsPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *youtubeGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE)); + SettingsGroup *twitchGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH)); + +#ifdef HAVE_CHEEVOS + SettingsGroup *cheevosGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS)); + + cheevosGroup->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + cheevosGroup->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + + layout->addWidget(cheevosGroup); +#endif + + youtubeGroup->addStringLineEdit(MENU_ENUM_LABEL_YOUTUBE_STREAM_KEY); + + layout->addWidget(youtubeGroup); + + twitchGroup->addStringLineEdit(MENU_ENUM_LABEL_TWITCH_STREAM_KEY); + + layout->addWidget(twitchGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp new file mode 100644 index 0000000000..c564241c93 --- /dev/null +++ b/ui/drivers/qt/options/video.cpp @@ -0,0 +1,337 @@ +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../../../gfx/video_display_server.h" +#include "../../../../gfx/video_driver.h" + +#ifndef CXX_BUILD +} +#endif + +VideoCategory::VideoCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS); + setCategoryIcon("menu_video"); +} + +QVector VideoCategory::pages() +{ + QVector pages; + + pages << new VideoPage(this); + pages << new CrtSwitchresPage(this); + + return pages; +} + +VideoPage::VideoPage(QObject *parent) : + OptionsPage(parent) + ,m_resolutionCombo(new QComboBox()) +{ +} + +QWidget *VideoPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *outputGroup = new SettingsGroup("Output"); + SettingsGroup *aspectGroup = new SettingsGroup("Scaling"); + + SettingsGroup *fullscreenGroup = new SettingsGroup("Fullscreen Mode"); + SettingsGroup *windowedGroup = new SettingsGroup("Windowed Mode"); + + QHBoxLayout *fullcreenSizeLayout = new QHBoxLayout; + FormLayout *leftFullscreenSizeForm = new FormLayout; + FormLayout *rightFullscreenSizeForm = new FormLayout; + + QHBoxLayout *windowedSizeLayout = new QHBoxLayout; + FormLayout *leftWindowedSizeForm = new FormLayout; + FormLayout *rightWindowedSizeForm = new FormLayout; + + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + CheckableSettingsGroup *vSyncGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_VSYNC); + + QHBoxLayout *outputScalingLayout = new QHBoxLayout; + QHBoxLayout *modeLayout = new QHBoxLayout; + QHBoxLayout *syncMiscLayout = new QHBoxLayout; + + SettingsGroup *miscGroup = new SettingsGroup("Miscellaneous"); + SettingsGroup *filterGroup = new SettingsGroup("Video Filter"); + + unsigned i, size = 0; + struct video_display_config *list = (struct video_display_config*) video_display_server_get_resolution_list(&size); + + if (list) + { + for (i = 0; i < size; i++) + { + char val_d[256], str[256]; + snprintf(str, sizeof(str), "%dx%d (%d Hz)", list[i].width, list[i].height, list[i].refreshrate); + snprintf(val_d, sizeof(val_d), "%d", i); + + m_resolutionCombo->addItem(str); + + if (list[i].current) + m_resolutionCombo->setCurrentIndex(i); + } + + free(list); + } + + outputGroup->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); + outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX); + outputGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_ROTATION); + outputGroup->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION), m_resolutionCombo); + outputGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE); + + fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN); + fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN); + + leftFullscreenSizeForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_X)); + rightFullscreenSizeForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_Y)); + + fullcreenSizeLayout->addLayout(leftFullscreenSizeForm); + fullcreenSizeLayout->addLayout(rightFullscreenSizeForm); + + fullscreenGroup->addRow(fullcreenSizeLayout); + + aspectGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER); + aspectGroup->addRow(new AspectRatioGroup("Aspect Ratio")); + + leftWindowedSizeForm->addRow("Scale:", new FloatSpinBox(MENU_ENUM_LABEL_VIDEO_SCALE)); + leftWindowedSizeForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_WIDTH)); + + rightWindowedSizeForm->addRow("Opacity:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY)); + rightWindowedSizeForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_HEIGHT)); + + windowedSizeLayout->addLayout(leftWindowedSizeForm); + windowedSizeLayout->addLayout(rightWindowedSizeForm); + + windowedGroup->addRow(windowedSizeLayout); + + windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS); + windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SAVE_POSITION); + + vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL); + vSyncGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC); + vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + syncGroup->addRow(vSyncGroup); + + { + rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + + if (hardSyncSetting) + { + CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); + + hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); + + syncGroup->addRow(hardSyncGroup); + } + } + + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES); + + miscGroup->addCheckBox(MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_THREADED); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SMOOTH); + + syncMiscLayout->addWidget(syncGroup); + syncMiscLayout->addWidget(miscGroup); + + filterGroup->addFileSelector(MENU_ENUM_LABEL_VIDEO_FILTER); + + modeLayout->addWidget(fullscreenGroup); + modeLayout->addWidget(windowedGroup); + + outputScalingLayout->addWidget(outputGroup); + outputScalingLayout->addWidget(aspectGroup); + + layout->addLayout(outputScalingLayout); + layout->addLayout(modeLayout); + layout->addLayout(syncMiscLayout); + layout->addWidget(filterGroup); + + layout->addStretch(); + + connect(m_resolutionCombo, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(onResolutionComboIndexChanged(const QString&))); + + widget->setLayout(layout); + + return widget; +} + +AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : + SettingsGroup(title, parent) + ,m_radioButton(new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) + ,m_comboBox(new UIntComboBox(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) +{ + QHBoxLayout *aspectLayout = new QHBoxLayout; + FormLayout *leftAspectForm = new FormLayout; + FormLayout *rightAspectForm = new FormLayout; + QHBoxLayout *preset = new QHBoxLayout; + //AspectRatioRadioButton *aspectRadioButton = new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9); + QHBoxLayout *custom = new QHBoxLayout; + QVBoxLayout *customRadio = new QVBoxLayout; + QHBoxLayout *config = new QHBoxLayout; + QHBoxLayout *aspectL = new QHBoxLayout; + FormLayout *leftAspect = new FormLayout; + FormLayout *rightAspect = new FormLayout; + + leftAspectForm->addRow("X Pos.:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X)); + leftAspectForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH)); + rightAspectForm->addRow("Y Pos.:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y)); + rightAspectForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT)); + + aspectLayout->addLayout(leftAspectForm); + aspectLayout->addLayout(rightAspectForm); + + preset->addWidget(m_radioButton); + preset->addWidget(m_comboBox); + preset->setStretch(1, 1); + + customRadio->addWidget(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CUSTOM), Qt::AlignTop); + customRadio->addStretch(); + + custom->addLayout(customRadio); + custom->addLayout(aspectLayout); + custom->addStretch(); + + config->addWidget(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CONFIG)); + config->addWidget(new FloatSpinBox(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO)); + config->setStretch(1, 1); + config->setSizeConstraint(QLayout::SetMinimumSize); + + leftAspect->addRow(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CORE)); + leftAspect->addRow(preset); + + rightAspect->addRow(config); + rightAspect->addRow(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_SQUARE)); + + aspectL->addLayout(leftAspect); + aspectL->addStretch(); + aspectL->addSpacing(30); + aspectL->addLayout(rightAspect); + + addRow(aspectL); + addRow(custom); + + connect(m_radioButton, SIGNAL(clicked(bool)), this, SLOT(onAspectRadioClicked(bool))); +} + +void AspectRatioGroup::paintEvent(QPaintEvent *event) +{ + unsigned value = config_get_ptr()->uints.video_aspect_ratio_idx; + + if (ASPECT_RATIO_4_3 >= value || value <= ASPECT_RATIO_32_9) + { + m_comboBox->blockSignals(false); + m_radioButton->setChecked(true); + } + else + { + m_comboBox->blockSignals(true); + } + + SettingsGroup::paintEvent(event); +} + +void AspectRatioGroup::onAspectRadioToggled(bool checked) +{ + if (checked) + m_comboBox->currentIndexChanged(m_comboBox->currentIndex()); + else + m_comboBox->blockSignals(true); +} + +void AspectRatioGroup::onAspectRadioClicked(bool checked) +{ + m_comboBox->blockSignals(false); + m_comboBox->currentIndexChanged(m_comboBox->currentIndex()); + setChecked(true); +} + +CrtSwitchresPage::CrtSwitchresPage(QObject *parent) : + OptionsPage(parent) + ,m_crtSuperResolutionCombo(new QComboBox()) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CRT_SWITCHRES_SETTINGS); +} + +QWidget *CrtSwitchresPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + m_crtSuperResolutionCombo->addItem(msg_hash_to_str(MSG_NATIVE), 0); + m_crtSuperResolutionCombo->addItem("1920", 1920); + m_crtSuperResolutionCombo->addItem("2560", 2560); + m_crtSuperResolutionCombo->addItem("3840", 3840); + + layout->addUIntComboBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION); + layout->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER), m_crtSuperResolutionCombo); + layout->addUIntSpinBox(MENU_ENUM_LABEL_CRT_SWITCH_X_AXIS_CENTERING); + layout->addCheckBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE); + + connect(m_crtSuperResolutionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCrtSuperResolutionComboIndexChanged(int))); + + widget->setLayout(layout); + + return widget; +} + +void VideoPage::onResolutionComboIndexChanged(const QString &text) +{ + char str[100]; + char *pch = NULL; + const char *path = text.toUtf8().constData(); + unsigned width = 0; + unsigned height = 0; + unsigned refreshrate = 0; + + snprintf(str, sizeof(str), "%s", path); + + pch = strtok(str, "x"); + if (pch) + width = strtoul(pch, NULL, 0); + pch = strtok(NULL, " "); + if (pch) + height = strtoul(pch, NULL, 0); + pch = strtok(NULL, "("); + if (pch) + refreshrate = strtoul(pch, NULL, 0); + + if (video_display_server_set_resolution(width, height, + refreshrate, (float)refreshrate, 0, 0, 0)) + { + settings_t *settings = config_get_ptr(); + + video_monitor_set_refresh_rate((float)refreshrate); + + settings->uints.video_fullscreen_x = width; + settings->uints.video_fullscreen_y = height; + } +} + +void CrtSwitchresPage::onCrtSuperResolutionComboIndexChanged(int index) +{ + Q_UNUSED(index) + config_get_ptr()->uints.crt_switch_resolution_super = m_crtSuperResolutionCombo->currentData().value(); +} + +AspectRatioRadioButton::AspectRatioRadioButton(unsigned min, unsigned max, QWidget *parent) : + QRadioButton(parent) + ,m_min(min) + ,m_max(max) +{ +} diff --git a/ui/drivers/qt/settingswidgets.cpp b/ui/drivers/qt/settingswidgets.cpp new file mode 100644 index 0000000000..6454c4fe7d --- /dev/null +++ b/ui/drivers/qt/settingswidgets.cpp @@ -0,0 +1,1187 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "settingswidgets.h" + +#include + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include + +#ifndef CXX_BUILD +} +#endif + +static const QRegularExpression decimalsRegex("%.(\\d)f"); + +inline void handleChange(rarch_setting_t *setting) +{ + + config_get_ptr()->modified = true; + + if (setting->change_handler) + setting->change_handler(setting); + + if (setting->cmd_trigger.idx && !setting->cmd_trigger.triggered) + command_event(setting->cmd_trigger.idx, NULL); +} + +inline void addSublabelAndWhatsThis(QWidget *widget, rarch_setting_t *setting) +{ + struct menu_file_list_cbs cbs = {}; + char tmp[512]; + tmp[0] = '\0'; + + cbs.enum_idx = setting->enum_idx; + + menu_cbs_init_bind_sublabel(&cbs, 0, 0, setting->type, setting->size); + + cbs.action_sublabel(0, 0, 0, 0, 0, tmp, sizeof(tmp)); + + widget->setToolTip(tmp); + + menu_hash_get_help_enum(setting->enum_idx, tmp, sizeof(tmp)); + + if (!string_is_equal(tmp, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE))) + widget->setWhatsThis(tmp); +} + +inline QString formLabel(rarch_setting_t *setting) +{ + return QString(setting->short_description) + ":"; +} + +FormLayout::FormLayout(QWidget *parent) : + QFormLayout(parent) +{ +} + +void FormLayout::addCheckBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(new CheckBox(setting)); +} + +void FormLayout::addUIntRadioButtons(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(new UIntRadioButtons(setting)); +} + +void FormLayout::addUIntComboBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new UIntComboBox(setting)); +} + +void FormLayout::addStringComboBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new StringComboBox(setting)); +} + +void FormLayout::addStringLineEdit(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new StringLineEdit(setting)); +} + +void FormLayout::addPasswordLineEdit(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new PasswordLineEdit(setting)); +} + +void FormLayout::addUIntSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new UIntSpinBox(setting)); +} + +void FormLayout::addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new SizeSpinBox(setting, scale)); +} + +void FormLayout::addFloatSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FloatSpinBox(setting)); +} + +void FormLayout::addDirectorySelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new DirectorySelector(setting)); +} + +void FormLayout::addFileSelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FileSelector(setting)); +} + +void FormLayout::addFontSelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FontSelector(setting)); +} + +void FormLayout::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FloatSliderAndSpinBox(setting)); +} + +void FormLayout::addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b) +{ + rarch_setting_t *red = menu_setting_find_enum(r); + rarch_setting_t *green = menu_setting_find_enum(g); + rarch_setting_t *blue = menu_setting_find_enum(b); + + if (red && green && blue) + addRow(title, new UIntColorButton(red, green, blue)); +} + +bool FormLayout::addBindButton(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (!setting || !setting->short_description) + return false; + + addRow(QString(setting->short_description), new BindButton(setting)); + + return true; +} + +SettingsGroup::SettingsGroup(const QString &title, QWidget *parent) : + QGroupBox(title, parent) + ,m_layout(new FormLayout(this)) +{ +} + +SettingsGroup::SettingsGroup(QWidget *parent) : + QGroupBox(parent) + ,m_layout(new FormLayout(this)) +{ +} + +void SettingsGroup::addWidget(QWidget *widget) +{ + m_layout->addWidget(widget); +} + +void SettingsGroup::addRow(QString label, QWidget *widget) +{ + m_layout->addRow(label, widget); +} + +void SettingsGroup::addRow(QWidget *widget) +{ + m_layout->addRow(widget); +} + +void SettingsGroup::addRow(QLayout *layout) +{ + m_layout->addRow(layout); +} + +void SettingsGroup::addRow(QString label, QLayout *layout) +{ + m_layout->addRow(label, layout); +} + +void SettingsGroup::addCheckBox(msg_hash_enums enum_idx) +{ + m_layout->addCheckBox(enum_idx); +} + +void SettingsGroup::addDirectorySelector(msg_hash_enums enum_idx) +{ + m_layout->addDirectorySelector(enum_idx); +} + +void SettingsGroup::addFileSelector(msg_hash_enums enum_idx) +{ + m_layout->addFileSelector(enum_idx); +} + +void SettingsGroup::addFontSelector(msg_hash_enums enum_idx) +{ + m_layout->addFontSelector(enum_idx); +} + +void SettingsGroup::addStringLineEdit(msg_hash_enums enum_idx) +{ + m_layout->addStringLineEdit(enum_idx); +} + +void SettingsGroup::addPasswordLineEdit(msg_hash_enums enum_idx) +{ + m_layout->addPasswordLineEdit(enum_idx); +} + +void SettingsGroup::addStringComboBox(msg_hash_enums enum_idx) +{ + m_layout->addStringComboBox(enum_idx); +} + +void SettingsGroup::addUIntComboBox(msg_hash_enums enum_idx) +{ + m_layout->addUIntComboBox(enum_idx); +} + +void SettingsGroup::addUIntRadioButtons(msg_hash_enums enum_idx) +{ + m_layout->addUIntRadioButtons(enum_idx); +} + +void SettingsGroup::addUIntSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addUIntSpinBox(enum_idx); +} + +void SettingsGroup::addFloatSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addFloatSpinBox(enum_idx); +} + +void SettingsGroup::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addFloatSliderAndSpinBox(enum_idx); +} + +void SettingsGroup::addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b) +{ + m_layout->addUIntColorButton(title, r, g, b); +} + +void SettingsGroup::addBindButton(msg_hash_enums enum_idx) +{ + m_layout->addBindButton(enum_idx); +} + +CheckBox::CheckBox(rarch_setting_t *setting, QWidget *parent) : + QCheckBox(setting->short_description, parent) + ,m_setting(setting) + ,m_value(setting->value.target.boolean) +{ + QAbstractButton::setChecked(*m_value); + + /* TODO/FIXME only one of these should be necessary */ + connect(this, SIGNAL(toggled(bool)), this, SLOT(onClicked(bool))); + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +CheckBox::CheckBox(const char *setting, QWidget *parent) : + CheckBox(menu_setting_find(setting), parent) +{ +} + +CheckBox::CheckBox(msg_hash_enums enum_idx, QWidget *parent) : + CheckBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +void CheckBox::onClicked(bool checked) +{ + *m_value = checked; + + handleChange(m_setting); +} + +void CheckBox::paintEvent(QPaintEvent *event) +{ + if (*m_value != QAbstractButton::isChecked()) + { + blockSignals(true); + + QAbstractButton::setChecked(*m_value); + + blockSignals(false); + } + + QCheckBox::paintEvent(event); +} + +CheckableSettingsGroup::CheckableSettingsGroup(rarch_setting_t *setting, QWidget *parent) : + SettingsGroup(parent) +{ + if (setting && setting->short_description) + { + m_setting = setting; + m_value = setting->value.target.boolean; + + setTitle(setting->short_description); + + setCheckable(true); + setChecked(*m_value); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); + } +} + +CheckableSettingsGroup::CheckableSettingsGroup(const char *setting, QWidget *parent) : + CheckableSettingsGroup(menu_setting_find(setting), parent) +{ +} + +CheckableSettingsGroup::CheckableSettingsGroup(msg_hash_enums enum_idx, QWidget *parent) : + CheckableSettingsGroup(menu_setting_find_enum(enum_idx), parent) +{ +} + +void CheckableSettingsGroup::onClicked(bool checked) +{ + *m_value = checked; + + handleChange(m_setting); +} + +void CheckableSettingsGroup::paintEvent(QPaintEvent *event) +{ + if (*m_value != isChecked()) + { + blockSignals(true); + + setChecked(*m_value); + + blockSignals(false); + } + + QGroupBox::paintEvent(event); +} + +CheckableIcon::CheckableIcon(const char *setting, const QIcon &icon, QWidget *parent) : + CheckableIcon(menu_setting_find(setting), icon, parent) +{ +} + +CheckableIcon::CheckableIcon(msg_hash_enums enum_idx, const QIcon &icon, QWidget *parent) : + CheckableIcon(menu_setting_find_enum(enum_idx), icon, parent) +{ +} + +CheckableIcon::CheckableIcon(rarch_setting_t *setting, const QIcon &icon, QWidget *parent) : + QToolButton(parent) + ,m_setting(setting) + ,m_value(setting->value.target.boolean) +{ + setIcon(icon); + + setCheckable(true); + + QAbstractButton::setChecked(*m_value); + + connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void CheckableIcon::onToggled(bool checked) +{ + *m_value = QAbstractButton::isChecked(); + + handleChange(m_setting); + + QAbstractButton::setChecked(checked); +} + +void CheckableIcon::paintEvent(QPaintEvent *event) +{ + if (QAbstractButton::isChecked() != *m_value) + { + blockSignals(true); + + QAbstractButton::setChecked(*m_value); + + blockSignals(false); + } + QToolButton::paintEvent(event); +} + +StringLineEdit::StringLineEdit(rarch_setting_t *setting, QWidget *parent) : + QLineEdit(setting->value.target.string) + ,m_setting(setting) + ,m_value(setting->value.target.string) +{ + connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); + + addSublabelAndWhatsThis(this, m_setting); +} + +StringLineEdit::StringLineEdit(const char *setting, QWidget *parent) : + StringLineEdit(menu_setting_find(setting), parent) +{ +} + +void StringLineEdit::onEditingFinished() +{ + strlcpy(m_value, text().toUtf8().data(), m_setting->size); + + handleChange(m_setting); + + setModified(false); +} + +void StringLineEdit::paintEvent(QPaintEvent *event) +{ + if (!isModified() && m_value != text()) + { + setText(m_value); + setModified(false); + } + + QLineEdit::paintEvent(event); +} + +PasswordLineEdit::PasswordLineEdit(rarch_setting_t *setting, QWidget *parent) : + StringLineEdit(setting) +{ + setEchoMode(QLineEdit::Password); +} + +StringComboBox::StringComboBox(rarch_setting_t *setting, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.string) +{ + addItems(QString(setting->values).split("|")); + + connect(this, SIGNAL(currentTextChanged(const QString&)), this, SLOT(onCurrentTextChanged(const QString&))); + + addSublabelAndWhatsThis(this, m_setting); +} + +StringComboBox::StringComboBox(const char *setting, QWidget *parent) : + StringComboBox(menu_setting_find(setting), parent) +{ +} + +void StringComboBox::onCurrentTextChanged(const QString &text) +{ + strlcpy(m_value, text.toUtf8().data(), sizeof(m_value)); + + handleChange(m_setting); +} + +void StringComboBox::paintEvent(QPaintEvent *event) +{ + setCurrentText(m_value); + QComboBox::paintEvent(event); +} + +UIntComboBox::UIntComboBox(rarch_setting_t *setting, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : 999.00; + + populate(min, max); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +UIntComboBox::UIntComboBox(rarch_setting_t *setting, double min, double max, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + populate(min, max); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void UIntComboBox::populate(double min, double max) +{ + float i; + unsigned orig_value = *m_setting->value.target.unsigned_integer; + float step = m_setting->step; + bool checked_found = false; + unsigned count = 0; + + if (m_setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256]; + unsigned val = (unsigned)i; + + *m_setting->value.target.unsigned_integer = val; + + m_setting->get_string_representation(m_setting, val_s, sizeof(val_s)); + + m_hash[i] = QString(val_s); + + addItem(m_hash[i], i); + + if (!checked_found && val == orig_value) + { + setCurrentIndex(count); + checked_found = true; + } + count++; + } + + *m_setting->value.target.unsigned_integer = orig_value; + } +} + +UIntComboBox::UIntComboBox(msg_hash_enums enum_idx, QWidget *parent) : + UIntComboBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +UIntComboBox::UIntComboBox(msg_hash_enums enum_idx, double min, double max, QWidget *parent) : + UIntComboBox(menu_setting_find_enum(enum_idx), min, max, parent) +{ +} + +UIntComboBox::UIntComboBox(const char *setting, QWidget *parent) : + UIntComboBox(menu_setting_find(setting), parent) +{ +} + +void UIntComboBox::onCurrentIndexChanged(int index) +{ + Q_UNUSED(index); + + *m_value = currentData().toUInt(); + + handleChange(m_setting); +} + +void UIntComboBox::paintEvent(QPaintEvent *event) +{ + setCurrentText(m_hash.value(*m_value)); + QComboBox::paintEvent(event); +} + +UIntSpinBox::UIntSpinBox(rarch_setting_t *setting, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + setMinimum(setting->enforce_minrange ? setting->min : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max : INT_MAX); + + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +UIntSpinBox::UIntSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + UIntSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +void UIntSpinBox::onValueChanged(int value) +{ + *m_value = value; + handleChange(m_setting); +} + +void UIntSpinBox::paintEvent(QPaintEvent *event) +{ + if ((unsigned)value() != *m_value) + { + blockSignals(true); + + setValue(*m_value); + + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +SizeSpinBox::SizeSpinBox(rarch_setting_t *setting, unsigned scale, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.sizet) + ,m_scale(scale) +{ + setMinimum(setting->enforce_minrange ? setting->min / m_scale : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max / m_scale : INT_MAX); + + setSingleStep(setting->step / m_scale); + + setValue(*m_value / m_scale); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +SizeSpinBox::SizeSpinBox(msg_hash_enums enum_idx, unsigned scale, QWidget *parent) : + SizeSpinBox(menu_setting_find_enum(enum_idx), scale, parent) +{ +} + +void SizeSpinBox::onValueChanged(int value) +{ + *m_value = value * m_scale; + handleChange(m_setting); +} + +void SizeSpinBox::paintEvent(QPaintEvent *event) +{ + if ((value() * m_scale) != *m_value) + { + blockSignals(true); + + setValue(*m_value / m_scale); + + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +UIntRadioButton::UIntRadioButton(msg_hash_enums enum_idx, unsigned value, QWidget *parent) : + QRadioButton(parent) + ,m_setting(menu_setting_find_enum(enum_idx)) + ,m_target(m_setting->value.target.unsigned_integer) + ,m_value(value) +{ + char val_s[256]; + unsigned orig_value = *m_setting->value.target.unsigned_integer; + + *m_setting->value.target.unsigned_integer = value; + + m_setting->get_string_representation(m_setting, val_s, sizeof(val_s)); + + *m_setting->value.target.unsigned_integer = orig_value; + + setText(val_s); + + if (m_value == orig_value) + setChecked(true); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +UIntRadioButton::UIntRadioButton(const QString &text, rarch_setting_t *setting, unsigned value, QWidget *parent) : + QRadioButton(text, parent) + ,m_setting(setting) + ,m_target(setting->value.target.unsigned_integer) + ,m_value(value) +{ + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +void UIntRadioButton::onClicked(bool) +{ + *m_target = m_value; + handleChange(m_setting); +} + +void UIntRadioButton::paintEvent(QPaintEvent *event) +{ + if (*m_target == m_value) + setChecked(true); + else + setChecked(false); + + QRadioButton::paintEvent(event); +} + +UIntRadioButtons::UIntRadioButtons(rarch_setting_t *setting, QWidget *parent) : + QGroupBox(setting->short_description, parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) + ,m_buttonGroup(new QButtonGroup(this)) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + /* from menu_displaylist */ + float i; + unsigned orig_value = *setting->value.target.unsigned_integer; + float step = setting->step; + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : UINT_MAX; + + bool checked_found = false; + + if (setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256]; + //int val = (int)i; + + *setting->value.target.unsigned_integer = i; + + setting->get_string_representation(setting, val_s, sizeof(val_s)); + + //m_hash[i] = QString(val_s); + + QRadioButton *button = new QRadioButton(QString(val_s), this); + + m_buttonGroup->addButton(button, i); + + layout->addWidget(button); + //addItem(m_hash[i], i); + + if (!checked_found && i == orig_value) + { + button->setChecked(true); + checked_found = true; + } + } + + *setting->value.target.unsigned_integer = orig_value; + } + addSublabelAndWhatsThis(this, m_setting); + connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onButtonClicked(int))); +} + +UIntRadioButtons::UIntRadioButtons(const char *setting, QWidget *parent) : + UIntRadioButtons(menu_setting_find(setting), parent) +{ +} + +UIntRadioButtons::UIntRadioButtons(msg_hash_enums enum_idx, QWidget *parent) : + UIntRadioButtons(menu_setting_find_enum(enum_idx), parent) +{ +} + +void UIntRadioButtons::onButtonClicked(int id) +{ + *m_value = id; + + handleChange(m_setting); +} + +IntSpinBox::IntSpinBox(rarch_setting_t *setting, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.integer) +{ + setMinimum(setting->enforce_minrange ? setting->min : INT_MIN); + setMaximum(setting->enforce_maxrange ? setting->max : INT_MAX); + + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void IntSpinBox::onValueChanged(int value) +{ + *m_value = value; + handleChange(m_setting); +} + +void IntSpinBox::paintEvent(QPaintEvent *event) +{ + if (value() != *m_value) + { + blockSignals(true); + setValue(*m_value); + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +FloatSpinBox::FloatSpinBox(const char *setting, QWidget *parent) : + FloatSpinBox(menu_setting_find(setting), parent) +{ +} + +FloatSpinBox::FloatSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + FloatSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +const QRegularExpression FloatSpinBox::DECIMALS_REGEX = QRegularExpression("%.(\\d)f"); + +FloatSpinBox::FloatSpinBox(rarch_setting_t *setting, QWidget *parent) : + QDoubleSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.fraction) +{ + QRegularExpressionMatch match = DECIMALS_REGEX.match(setting->rounding_fraction); + + if (match.hasMatch()) + setDecimals(match.captured(1).toInt()); + + setMinimum(setting->enforce_minrange ? setting->min : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max : 999.00); + + setValue(*m_value); + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double))); + addSublabelAndWhatsThis(this, m_setting); +} + +void FloatSpinBox::onValueChanged(double value) +{ + *m_value = (float)value; + + handleChange(m_setting); +} + +void FloatSpinBox::paintEvent(QPaintEvent *event) +{ + if ((float)value() != *m_value) + { + blockSignals(true); + + if (*m_value < minimum() || *m_value > maximum()) + *m_value = m_setting->default_value.fraction; + + setValue(*m_value); + + blockSignals(false); + } + + QDoubleSpinBox::paintEvent(event); +} + +PathButton::PathButton(rarch_setting_t *setting, QWidget *parent) : + QPushButton("Browse...", parent) + ,m_setting(setting) + ,m_value(setting->value.target.string) + ,m_dir(setting->default_value.string) +{ + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +PathButton::PathButton(const char *setting, QWidget *parent) : + PathButton(menu_setting_find(setting), parent) +{ +} + +void DirectoryButton::onClicked(bool) +{ + QString dir = QFileDialog::getExistingDirectory( + this, + "Choose " + QString(m_setting->short_description) + " Directory", + QString(m_setting->default_value.string)); + + if (!dir.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(dir).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +void FileButton::onClicked(bool) +{ + QString file = QFileDialog::getOpenFileName( + this, + "Choose File", + QString(m_setting->default_value.string), + QString(m_setting->short_description) + " (*." + QString(m_setting->values) + ")"); + + if (!file.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(file).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +void FontButton::onClicked(bool) +{ + QString file = QFileDialog::getOpenFileName( + this, + "Choose Font", + QString(m_setting->default_value.string), + "TrueType font (*.ttf)"); + + if (!file.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(file).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +DirectorySelector::DirectorySelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new DirectoryButton(setting)); +} + +FileSelector::FileSelector(const char *setting, QWidget *parent) : + FileSelector(menu_setting_find(setting), parent) +{ +} + +FileSelector::FileSelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new FileButton(setting)); +} + +FontSelector::FontSelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new FontButton(setting)); +} + +FloatSlider::FloatSlider(const char *setting, QWidget *parent) : + FloatSlider(menu_setting_find(setting), parent) +{ +} + +FloatSlider::FloatSlider(rarch_setting_t *setting, QWidget *parent) : + QSlider(Qt::Horizontal, parent) + ,m_setting(setting) + ,m_value(setting->value.target.fraction) + ,m_decimalsRegEx("%.(\\d)f") +{ + QRegularExpressionMatch match = m_decimalsRegEx.match(setting->rounding_fraction); + + if (match.hasMatch()) + m_precision = pow(10, match.captured(1).toInt()); + else + m_precision = pow(10, 3); + + setMinimum(setting->enforce_minrange ? setting->min * m_precision : 0.00 * m_precision); + setMaximum(setting->enforce_maxrange ? setting->max * m_precision : 999.00 * m_precision); + + setSingleStep(setting->step * m_precision); + + setValue(*m_value * m_precision); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void FloatSlider::onValueChanged(int value) +{ + *m_value = (float)value / m_precision; + + handleChange(m_setting); +} + +void FloatSlider::paintEvent(QPaintEvent *event) +{ + if (value() / m_precision != *m_value) + { + blockSignals(true); + + setValue(*m_value * m_precision); + + blockSignals(false); + } + + QSlider::paintEvent(event); +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(const char *setting, QWidget *parent) : + FloatSliderAndSpinBox(menu_setting_find(setting), parent) +{ +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + FloatSliderAndSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) + ,m_slider(new FloatSlider(setting)) + ,m_spinBox(new FloatSpinBox(setting)) +{ + addWidget(m_slider); + addWidget(m_spinBox); + + connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); + connect(m_spinBox, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged(double))); +} + +void FloatSliderAndSpinBox::onSliderValueChanged(int value) +{ + Q_UNUSED(value); + + m_spinBox->update(); +} + +void FloatSliderAndSpinBox::onSpinBoxValueChanged(double value) +{ + Q_UNUSED(value); + + m_slider->update(); +} + +BindButton::BindButton(rarch_setting_t *setting, QWidget *parent) : + QPushButton(parent) + ,m_setting(setting) +{ + char val_s[256]; + + setting->get_string_representation(setting, val_s, sizeof(val_s)); + + setText(val_s); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +BindButton::BindButton(msg_hash_enums enum_idx, QWidget *parent) : + BindButton(menu_setting_find_enum(enum_idx), parent) +{ +} + +void BindButton::onClicked(bool checked) +{ + Q_UNUSED(checked); + + m_setting->action_ok(m_setting, false); +} + +ColorButton::ColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent) : + QToolButton(parent) + ,m_red(red) + ,m_green(green) + ,m_blue(blue) + ,m_dialog(new QColorDialog(this)) +{ + setMinimumSize(64, 0); + + m_dialog->setOptions(QColorDialog::NoButtons); + + connect(this, SIGNAL(clicked()), m_dialog, SLOT(open())); + connect(m_dialog, SIGNAL(currentColorChanged(const QColor&)), this, SLOT(onColorChanged(const QColor&))); +} + +ColorButton::ColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(menu_setting_find_enum(red), menu_setting_find_enum(green), menu_setting_find_enum(blue), parent) +{ +} + +/* Stolen from Qt Creator's QtColorButton */ +void ColorButton::paintEvent(QPaintEvent *event) +{ + QToolButton::paintEvent(event); + if (!isEnabled()) + return; + + const int pixSize = 10; + QBrush br(color()); + + QPainter p(this); + const int corr = 5; + QRect r = rect().adjusted(corr, corr, -corr, -corr); + p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr); + p.fillRect(r, br); + + const QColor frameColor1(0, 0, 0, 26); + p.setPen(frameColor1); + p.drawRect(r.adjusted(1, 1, -2, -2)); + const QColor frameColor2(0, 0, 0, 51); + p.setPen(frameColor2); + p.drawRect(r.adjusted(0, 0, -1, -1)); +} + +UIntColorButton::UIntColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +UIntColorButton::UIntColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +void UIntColorButton::onColorChanged(const QColor &color) +{ + if (color.isValid()) + { + *m_red->value.target.unsigned_integer = color.red(); + *m_green->value.target.unsigned_integer = color.green(); + *m_blue->value.target.unsigned_integer = color.blue(); + } +} + +QColor UIntColorButton::color() +{ + return QColor( + *m_red->value.target.unsigned_integer, + *m_green->value.target.unsigned_integer, + *m_blue->value.target.unsigned_integer); +} + +FloatColorButton::FloatColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +void FloatColorButton::onColorChanged(const QColor &color) +{ + if (color.isValid()) + { + *m_red->value.target.fraction = color.red() / 255.0f; + *m_green->value.target.fraction = color.green() / 255.0f; + *m_blue->value.target.fraction = color.blue() / 255.0f; + } +} + +QColor FloatColorButton::color() +{ + return QColor( + *m_red->value.target.fraction * 255, + *m_green->value.target.fraction * 255, + *m_blue->value.target.fraction * 255); +} diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h new file mode 100644 index 0000000000..cf2adaaced --- /dev/null +++ b/ui/drivers/qt/settingswidgets.h @@ -0,0 +1,421 @@ +#ifndef SETTINGSWIDGETS_H +#define SETTINGSWIDGETS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../../configuration.h" +#include "../../../setting_list.h" +#include "../../../menu/menu_setting.h" +#include "../../../menu/menu_cbs.h" + +#ifndef CXX_BUILD +} +#endif + +static const QString FONT_FILTER = QStringLiteral("TrueType font (*.ttf)"); + +class FormLayout : public QFormLayout +{ +public: + FormLayout(QWidget *parent = 0); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024); + void addFloatSpinBox(msg_hash_enums enum_idx); + void addDirectorySelector(msg_hash_enums enum_idx); + void addFileSelector(msg_hash_enums enum_idx); + void addFontSelector(msg_hash_enums enum_idx); + void addCheckBox(msg_hash_enums enum_idx); + void addUIntComboBox(msg_hash_enums enum_idx); + void addUIntRadioButtons(msg_hash_enums enum_idx); + void addStringComboBox(msg_hash_enums enum_idx); + void addStringLineEdit(msg_hash_enums enum_idx); + void addPasswordLineEdit(msg_hash_enums enum_idx); + void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); + void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); + bool addBindButton(msg_hash_enums enum_idx); +}; + +class SettingsGroup : public QGroupBox +{ + Q_OBJECT +public: + SettingsGroup(const QString &title, QWidget *parent = 0); + SettingsGroup(QWidget *parent = 0); + void addWidget(QWidget *widget); + void addRow(QString label, QWidget *widget); + void addRow(QWidget *widget); + void addRow(QLayout *layout); + void addRow(QString label, QLayout *layout); + void addCheckBox(msg_hash_enums enum_idx); + void addFileSelector(msg_hash_enums enum_idx); + void addDirectorySelector(msg_hash_enums enum_idx); + void addFontSelector(msg_hash_enums enum_idx); + void addStringLineEdit(msg_hash_enums enum_idx); + void addPasswordLineEdit(msg_hash_enums enum_idx); + void addStringComboBox(msg_hash_enums enum_idx); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addUIntComboBox(msg_hash_enums enum_idx); + void addUIntRadioButtons(msg_hash_enums enum_idx); + void addFloatSpinBox(msg_hash_enums enum_idx); + void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); + void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); + void addBindButton(msg_hash_enums enum_idx); +private: + FormLayout *m_layout; +}; + +class CheckableSettingsGroup : public SettingsGroup +{ + Q_OBJECT +public: + CheckableSettingsGroup(rarch_setting_t *setting, QWidget *parent = 0); + CheckableSettingsGroup(const char *setting, QWidget *parent = 0); + CheckableSettingsGroup(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool clicked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class CheckBox : public QCheckBox +{ + Q_OBJECT +public: + CheckBox(rarch_setting_t *setting, QWidget *parent = 0); + CheckBox(const char *setting, QWidget *parent = 0); + CheckBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool checked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class CheckableIcon : public QToolButton +{ + Q_OBJECT +public: + CheckableIcon(rarch_setting_t *setting, const QIcon &icon, QWidget *parent = 0); + CheckableIcon(const char *setting, const QIcon &icon, QWidget *parent = 0); + CheckableIcon(msg_hash_enums enum_idx, const QIcon &icon, QWidget *parent = 0); +private slots: + void onToggled(bool checked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class StringLineEdit : public QLineEdit +{ + Q_OBJECT +public: + StringLineEdit(rarch_setting_t *setting, QWidget *parent = 0); + StringLineEdit(const char *setting, QWidget *parent = 0); +private slots: + void onEditingFinished(); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + char *m_value; +}; + +class PasswordLineEdit : public StringLineEdit +{ + Q_OBJECT +public: + PasswordLineEdit(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class StringComboBox : public QComboBox +{ + Q_OBJECT +public: + StringComboBox(rarch_setting_t *setting, QWidget *parent = 0); + StringComboBox(const char *setting, QWidget *parent = 0); +private slots: + void onCurrentTextChanged(const QString &text); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + char *m_value; +}; + +class UIntComboBox : public QComboBox +{ + Q_OBJECT +public: + UIntComboBox(rarch_setting_t *setting, QWidget *parent = 0); + UIntComboBox(rarch_setting_t *setting, double min, double max, QWidget *parent = 0); + UIntComboBox(msg_hash_enums enum_idx, QWidget *parent = 0); + UIntComboBox(msg_hash_enums enum_idx, double min, double max, QWidget *parent = 0); + UIntComboBox(const char *setting, QWidget *parent = 0); +private slots: + void onCurrentIndexChanged(int index); + void paintEvent(QPaintEvent *event); +private: + void populate(double min, double max); + rarch_setting_t *m_setting; + unsigned *m_value; + QHash m_hash; +}; + +class UIntRadioButton : public QRadioButton +{ + Q_OBJECT +public: + UIntRadioButton(const QString &text, rarch_setting_t *setting, unsigned value, QWidget *parent = 0); + UIntRadioButton(msg_hash_enums enum_idx, unsigned value, QWidget *parent = 0); +private slots: + void onClicked(bool); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + unsigned *m_target; + unsigned m_value; +}; + +class UIntRadioButtons : public QGroupBox +{ + Q_OBJECT +public: + UIntRadioButtons(rarch_setting_t *setting, QWidget *parent = 0); + UIntRadioButtons(const char *setting, QWidget *parent = 0); + UIntRadioButtons(msg_hash_enums enum_idx, QWidget *parent = 0); +signals: + void currentUIntChanged(unsigned value); +private slots: + void onButtonClicked(int id); +private: + rarch_setting_t *m_setting; + unsigned *m_value; + QButtonGroup *m_buttonGroup; +}; + +class UIntSpinBox : public QSpinBox +{ + Q_OBJECT +public: + UIntSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + UIntSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + unsigned *m_value; +}; + +class SizeSpinBox : public QSpinBox +{ + Q_OBJECT +public: + SizeSpinBox(rarch_setting_t *setting, unsigned scale = 1024*1024, QWidget *parent = 0); + SizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + size_t *m_value; + unsigned m_scale; +}; + +class IntSpinBox : public QSpinBox +{ + Q_OBJECT +public: + IntSpinBox(rarch_setting_t *setting, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + int *m_value; +}; + +class FloatSpinBox : public QDoubleSpinBox +{ + Q_OBJECT +public: + FloatSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + FloatSpinBox(const char *setting, QWidget *parent = 0); + FloatSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onValueChanged(double value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + float *m_value; + static const QRegularExpression DECIMALS_REGEX; +}; + +class PathButton : public QPushButton +{ + Q_OBJECT +public: + PathButton(rarch_setting_t *setting, QWidget *parent = 0); + PathButton(const char *setting, QWidget *parent = 0); +protected slots: + virtual void onClicked(bool checked = false) { Q_UNUSED( checked); } +protected: + QString m_filter; + rarch_setting_t *m_setting; + char *m_value; + const char *m_dir; +}; + +class DirectoryButton : public PathButton +{ + Q_OBJECT +public: + DirectoryButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class FileButton : public PathButton +{ + Q_OBJECT +public: + FileButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class FontButton : public PathButton +{ + Q_OBJECT +public: + FontButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class DirectorySelector : public QHBoxLayout +{ + Q_OBJECT +public: + DirectorySelector(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class FileSelector : public QHBoxLayout +{ + Q_OBJECT +public: + FileSelector(rarch_setting_t *setting, QWidget *parent = 0); + FileSelector(const char *setting, QWidget *parent = 0); +}; + +class FontSelector : public QHBoxLayout +{ + Q_OBJECT +public: + FontSelector(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class FloatSlider : public QSlider +{ + Q_OBJECT +public: + FloatSlider(rarch_setting_t *setting, QWidget *parent = 0); + FloatSlider(const char *setting, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + float *m_value; + QRegularExpression m_decimalsRegEx; + unsigned int m_precision; +}; + +class FloatSliderAndSpinBox : public QHBoxLayout +{ + Q_OBJECT +public: + FloatSliderAndSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + FloatSliderAndSpinBox(const char *setting, QWidget *parent = 0); + FloatSliderAndSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onSliderValueChanged(int value); + void onSpinBoxValueChanged(double value); +private: + FloatSlider *m_slider; + FloatSpinBox *m_spinBox; +}; + +class BindButton : public QPushButton +{ + Q_OBJECT +public: + BindButton(rarch_setting_t *setting, QWidget *parent = 0); + BindButton(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool checked); +private: + rarch_setting_t *m_setting; +}; + +class ColorButton : public QToolButton +{ + Q_OBJECT +public: + ColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0); + ColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); +protected slots: + virtual void onColorChanged(const QColor& color) { Q_UNUSED(color); } +protected: + virtual QColor color() { return QColor(); } + void paintEvent(QPaintEvent *event); + + rarch_setting_t *m_red, *m_green, *m_blue; + QColorDialog *m_dialog; +}; + +class UIntColorButton : public ColorButton +{ + Q_OBJECT +public: + UIntColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); + UIntColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0); +protected slots: + void onColorChanged(const QColor& color); +protected: + QColor color(); +}; + +class FloatColorButton : public ColorButton +{ + Q_OBJECT +public: + explicit FloatColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); +protected slots: + void onColorChanged(const QColor& color); +protected: + QColor color(); +}; + +#endif diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index e7e43db132..31ff876387 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -12,7 +12,6 @@ static const QString qt_theme_default_stylesheet = QStringLiteral(R"( ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel { background-color:#d4d4d4; } - QLabel#dropIndicator { font-size: 9pt; color: darkgrey; @@ -27,9 +26,13 @@ static const QString qt_theme_default_stylesheet = QStringLiteral(R"( QFrame#playlistWidget, QFrame#browserWidget, QFrame#logWidget { padding: 8px; } - ListWidget { + QListWidget { icon-size: 32px; } + /* color of the icons on the settings dialog */ + /* QLabel#iconColor { + color: black; + } */ )"); static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( @@ -46,7 +49,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( border-right:1px solid rgba(125,125,125,50%); border-bottom:1px solid rgba(25,25,25,75%); } - ListWidget { + QListWidget { icon-size: 32px; } QLabel#dropIndicator { diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 1bc4e164f7..f79df2c354 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -1249,6 +1249,9 @@ void MainWindow::setTheme(Theme theme) default: break; } +#ifdef HAVE_MENU + m_viewOptionsDialog->repaintIcons(); +#endif } void MainWindow::setDefaultCustomProperties() diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index 2b5e3a3ba5..52404998c7 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -12,6 +12,15 @@ #include #include "viewoptionsdialog.h" + +#ifdef HAVE_MENU +#include +#include +#include + +#include "options/options.h" +#endif + #include "../ui_qt.h" #ifndef CXX_BUILD @@ -24,8 +33,187 @@ extern "C" { } #endif +#ifdef HAVE_MENU + +QPixmap getColorizedPixmap(const QPixmap& oldPixmap, const QColor& color) +{ + QPixmap pixmap = oldPixmap; + QBitmap mask = pixmap.createMaskFromColor(Qt::transparent, Qt::MaskInColor); + pixmap.fill(color); + pixmap.setMask(mask); + return pixmap; +} + +QColor getLabelColor(const QString& objectName) +{ + QLabel dummyColor; + dummyColor.setObjectName(objectName); + dummyColor.ensurePolished(); + return dummyColor.palette().color(QPalette::Foreground); +} + ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : QDialog(mainwindow) + , m_optionsList(new QListWidget(this)) + , m_optionsStack(new QStackedWidget(this)) +{ + QGridLayout *layout = new QGridLayout(this); + QLabel *m_headerLabel = new QLabel(this); + // Header label with large font and a bit of spacing (align with group boxes) + QFont headerLabelFont = m_headerLabel->font(); + const int pointSize = headerLabelFont.pointSize(); + QHBoxLayout *headerHLayout = new QHBoxLayout; + const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + int width; + + headerLabelFont.setBold(true); + + // Paranoia: Should a font be set in pixels... + if (pointSize > 0) + headerLabelFont.setPointSize(pointSize + 2); + + m_headerLabel->setFont(headerLabelFont); + + headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_headerLabel); + + addCategory(new DriversCategory(this)); + addCategory(new VideoCategory(this)); + addCategory(new AudioCategory(this)); + addCategory(new InputCategory(this)); + addCategory(new LatencyCategory(this)); + addCategory(new CoreCategory(this)); + addCategory(new ConfigurationCategory(this)); + addCategory(new SavingCategory(this)); + addCategory(new LoggingCategory(this)); + addCategory(new FrameThrottleCategory(this)); + addCategory(new RecordingCategory(this)); + addCategory(new OnscreenDisplayCategory(this)); + addCategory(new UserInterfaceCategory(mainwindow, this)); + addCategory(new AchievementsCategory(this)); + addCategory(new NetworkCategory(this)); + addCategory(new PlaylistsCategory(this)); + addCategory(new UserCategory(this)); + addCategory(new DirectoryCategory(this)); + + width = m_optionsList->sizeHintForColumn(0) + m_optionsList->frameWidth() * 2 + 5; + width += m_optionsList->verticalScrollBar()->sizeHint().width(); + + m_optionsList->setMaximumWidth(width); + m_optionsList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + + layout->addWidget(m_optionsList, 0, 0, 2, 1); + layout->addLayout(headerHLayout, 0, 1); + layout->addWidget(m_optionsStack, 1, 1); + + connect(m_optionsList, SIGNAL(currentRowChanged(int)), m_optionsStack, SLOT(setCurrentIndex(int))); + connect(m_optionsList, SIGNAL(currentTextChanged(const QString&)), m_headerLabel, SLOT(setText(const QString&))); + + connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); +} + +QIcon getIcon(OptionsCategory *category) { + QPixmap pixmap = QPixmap(QString(config_get_ptr()->paths.directory_assets) + "/xmb/monochrome/png/" + category->categoryIconName() + ".png"); + return QIcon(getColorizedPixmap(pixmap, getLabelColor("iconColor"))); +} + +void ViewOptionsDialog::addCategory(OptionsCategory *category) +{ + QTabWidget *tabWidget = new QTabWidget(); + + m_categoryList.append(category); + + for (OptionsPage* page : category->pages()) + { + QWidget *widget = page->widget(); + widget->setAutoFillBackground(false); + tabWidget->addTab(widget, page->displayName()); + } + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) + tabWidget->setTabBarAutoHide(true); +#else + /* TODO remove the tabBar's space */ + if (tabWidget->count() < 2) + tabWidget->tabBar()->hide(); +#endif + m_optionsList->addItem(new QListWidgetItem(getIcon(category), category->displayName())); + m_optionsStack->addWidget(tabWidget); +} + +void ViewOptionsDialog::repaintIcons() +{ + int i; + + for (i = 0; i < m_categoryList.size(); i++) + { + m_optionsList->item(i)->setIcon(getIcon(m_categoryList.at(i))); + } +} + +#else + +ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : + QDialog(mainwindow) + , m_viewOptionsWidget(new ViewOptionsWidget(mainwindow)) +{ + QVBoxLayout *layout = new QVBoxLayout; + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(this, SIGNAL(accepted()), m_viewOptionsWidget, SLOT(onAccepted())); + connect(this, SIGNAL(rejected()), m_viewOptionsWidget, SLOT(onRejected())); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + + layout->setContentsMargins(0, 0, 0, 0); + + layout->addWidget(m_viewOptionsWidget); + layout->addWidget(buttonBox); + + setLayout(layout); +} + +#endif + +void ViewOptionsDialog::showDialog() +{ +#ifndef HAVE_MENU + m_viewOptionsWidget->loadViewOptions(); +#else + int i; + for (i = 0; i < m_categoryList.size(); i++) + { + m_categoryList.at(i)->load(); + } +#endif + show(); + activateWindow(); +} + +void ViewOptionsDialog::hideDialog() +{ + reject(); +} + +void ViewOptionsDialog::onRejected() +{ +#ifdef HAVE_MENU + int i; + + for (i = 0; i < m_categoryList.size(); i++) + { + m_categoryList.at(i)->apply(); + } +#endif +} + +ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : + QWidget(parent) ,m_mainwindow(mainwindow) ,m_settings(mainwindow->settings()) ,m_saveGeometryCheckBox(new QCheckBox(this)) @@ -44,10 +232,8 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : /* ,m_allPlaylistsListMaxCountSpinBox(new QSpinBox(this)) */ /* ,m_allPlaylistsGridMaxCountSpinBox(new QSpinBox(this)) */ { - QFormLayout *form = new QFormLayout(); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + QVBoxLayout *layout = new QVBoxLayout; + QFormLayout *form = new QFormLayout; m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT), MainWindow::THEME_SYSTEM_DEFAULT); m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); @@ -66,14 +252,6 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : form->setFormAlignment(Qt::AlignCenter); form->setLabelAlignment(Qt::AlignCenter); - setLayout(new QVBoxLayout(this)); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); - connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY), m_saveGeometryCheckBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS), m_saveDockPositionsCheckBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB), m_saveLastTabCheckBox); @@ -87,9 +265,11 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); form->addRow(m_highlightColorLabel, m_highlightColorPushButton); - qobject_cast(layout())->addLayout(form); - layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); - layout()->addWidget(buttonBox); + layout->addLayout(form); + + layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + setLayout(layout); loadViewOptions(); @@ -98,13 +278,13 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); } -void ViewOptionsDialog::onThumbnailComboBoxIndexChanged(int index) +void ViewOptionsWidget::onThumbnailComboBoxIndexChanged(int index) { ThumbnailType type = static_cast(m_thumbnailComboBox->currentData().value()); m_mainwindow->setCurrentThumbnailType(type); } -void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) +void ViewOptionsWidget::onThemeComboBoxIndexChanged(int) { MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); @@ -137,7 +317,7 @@ void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) showOrHideHighlightColor(); } -void ViewOptionsDialog::onHighlightColorChoose() +void ViewOptionsWidget::onHighlightColorChoose() { QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); QColor currentHighlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); @@ -155,7 +335,7 @@ void ViewOptionsDialog::onHighlightColorChoose() } } -void ViewOptionsDialog::loadViewOptions() +void ViewOptionsWidget::loadViewOptions() { QColor highlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); @@ -209,7 +389,7 @@ void ViewOptionsDialog::loadViewOptions() m_startupPlaylistComboBox->setCurrentIndex(playlistIndex); } -void ViewOptionsDialog::showOrHideHighlightColor() +void ViewOptionsWidget::showOrHideHighlightColor() { if (m_mainwindow->theme() == MainWindow::THEME_DARK) { @@ -223,7 +403,7 @@ void ViewOptionsDialog::showOrHideHighlightColor() } } -void ViewOptionsDialog::saveViewOptions() +void ViewOptionsWidget::saveViewOptions() { m_settings->setValue("save_geometry", m_saveGeometryCheckBox->isChecked()); m_settings->setValue("save_dock_positions", m_saveDockPositionsCheckBox->isChecked()); @@ -246,29 +426,12 @@ void ViewOptionsDialog::saveViewOptions() m_mainwindow->setThumbnailCacheLimit(m_thumbnailCacheSpinBox->value()); } -void ViewOptionsDialog::onAccepted() +void ViewOptionsWidget::onAccepted() { - MainWindow::Theme newTheme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); - - m_mainwindow->setTheme(newTheme); - saveViewOptions(); } -void ViewOptionsDialog::onRejected() +void ViewOptionsWidget::onRejected() { loadViewOptions(); } - -void ViewOptionsDialog::showDialog() -{ - loadViewOptions(); - setWindowFlags(windowFlags() | Qt::Tool); - show(); - activateWindow(); -} - -void ViewOptionsDialog::hideDialog() -{ - reject(); -} diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 4e9ff4c76a..7116a50f25 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -12,23 +12,28 @@ class QColor; class QLabel; class QSpinBox; -class ViewOptionsDialog : public QDialog +#ifdef HAVE_MENU +class QWidget; +class OptionsCategory; +class QListWidget; +class QStackedWidget; +#endif + +class ViewOptionsWidget : public QWidget { Q_OBJECT public: - ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent = 0); + ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent = 0); public slots: - void showDialog(); - void hideDialog(); void onAccepted(); void onRejected(); + void loadViewOptions(); + void saveViewOptions(); private slots: void onThemeComboBoxIndexChanged(int index); void onThumbnailComboBoxIndexChanged(int index); void onHighlightColorChoose(); private: - void loadViewOptions(); - void saveViewOptions(); void showOrHideHighlightColor(); MainWindow *m_mainwindow; @@ -50,4 +55,31 @@ private: QSpinBox *m_allPlaylistsGridMaxCountSpinBox; }; +class ViewOptionsDialog : public QDialog +{ + Q_OBJECT +public: + ViewOptionsDialog(MainWindow *window, QWidget *parent = 0); + // Make sure the settings dialog starts up as small as possible. + QSize sizeHint() const final { return minimumSize(); } +#ifdef HAVE_MENU + void repaintIcons(); +#endif +public slots: + void showDialog(); + void hideDialog(); +private slots: + void onRejected(); +private: +#ifdef HAVE_MENU + void addCategory(QWidget *widget, QString name, QString icon); + void addCategory(OptionsCategory *category); + QVector m_categoryList; + QListWidget *m_optionsList; + QStackedWidget *m_optionsStack; +#else + ViewOptionsWidget *m_viewOptionsWidget; +#endif +}; + #endif From 022f25df0ca4bc66b41e71cb8369e4605c4fa8b0 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Thu, 28 Mar 2019 18:21:55 +0100 Subject: [PATCH 2/4] dark theme settings update --- ui/drivers/qt/ui_qt_themes.h | 63 ++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index 31ff876387..95b8ad0da7 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -41,6 +41,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( background-color:rgb(53,53,53); selection-background-color:%1; } + QWidget:disabled { + color:rgb(127,127,127); + } QFrame#playlistWidget, QFrame#browserWidget, QStackedWidget#centralWidget, QFrame#logWidget { padding: 8px; background-color:rgb(66,66,66); @@ -62,11 +65,42 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QTextEdit, LogTextEdit { background-color:rgb(25,25,25); } - QSpinBox, QDoubleSpinBox, QCheckBox { + QSpinBox, QDoubleSpinBox, QCheckBox, QRadioButton { background-color:rgb(25,25,25); } - QCheckBox:checked, QCheckBox:unchecked { - background-color:rgb(53,53,53); + QCheckBox:checked, QCheckBox:unchecked, QRadioButton:checked, QRadioButton:unchecked { + background-color:transparent; + } + /* Groupboxes for the settings window, can be restricted later with ViewOptionsDialog QGroupBox */ + QGroupBox { + background-color:rgba(80,80,80,50%); + margin-top:27px; + border:1px solid rgba(25,25,25,127); + border-top-left-radius:0px; + border-top-right-radius:4px; + } + QGroupBox::title { + min-height:28px; + subcontrol-origin:margin; + subcontrol-position:left top; + padding:4px 6px 5px 6px; + margin-left:0px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgb(65,65,65),stop: 0.4 rgb(70,70,70),stop:1 rgb(90,90,90)); + border:1px solid rgba(25,25,25,127); + border-bottom:1px solid rgb(65,65,65); + border-top-left-radius:4px; + border-top-right-radius:4px; + } + QGroupBox::indicator:checked { + background-color:%1; + border:4px solid rgb(45,45,45); + } + QGroupBox::indicator:unchecked { + background-color:rgba(25,25,25,50%); + } + QGroupBox::indicator { + width:16px; + height:16px; } QWidget#shaderParamsWidget { background-color:rgb(25,25,25); @@ -207,23 +241,6 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QDockWidget::float-button { right:25px; } - QGroupBox { - background-color:rgba(66,66,66,50%); - margin-top:27px; - border:1px solid rgba(25,25,25,127); - border-top-left-radius:4px; - border-top-right-radius:4px; - } - QGroupBox::title { - subcontrol-origin:margin; - subcontrol-position:left top; - padding:4px 6px; - margin-left:3px; - background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); - border:1px solid rgba(25,25,25,75); - border-top-left-radius:4px; - border-top-right-radius:4px; - } QTabWidget::pane { background-color:rgba(66,66,66,50%); } @@ -401,6 +418,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( subcontrol-position:top; subcontrol-origin:margin; } + QSlider { + background:transparent; + } QSlider::sub-page { background:%1; } @@ -447,6 +467,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QStatusBar QLabel { background-color:transparent; } + QLabel { + background-color:transparent; + } QSizeGrip { background-color:solid; } From 61fa0a0807f02c7b331dcec4d56dfb05fd328be9 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Mon, 1 Apr 2019 21:31:46 +0200 Subject: [PATCH 3/4] Move thumbnail type selection to grid footer. --- intl/msg_hash_pt_br.h | 2 +- intl/msg_hash_us.h | 2 +- ui/drivers/qt/ui_qt_window.cpp | 34 +++++++++++++++++++++++++++++ ui/drivers/qt/viewoptionsdialog.cpp | 20 ----------------- ui/drivers/qt/viewoptionsdialog.h | 2 -- ui/drivers/ui_qt.h | 3 +++ 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 01c28608ff..887df7ba7b 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -7773,7 +7773,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE, - "Tipo de visualização de miniatura de ícones:" + "Miniatura" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 750eafe636..154d5ca8c6 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -8087,7 +8087,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE, - "Icon view thumbnail type:" + "Thumbnail" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT, diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index f79df2c354..74a617d864 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -366,6 +366,11 @@ MainWindow::MainWindow(QWidget *parent) : QToolButton *searchResetButton = NULL; QHBoxLayout *zoomLayout = new QHBoxLayout(); QLabel *zoomLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ZOOM), m_zoomWidget); + QPushButton *thumbnailTypePushButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE), m_zoomWidget); + QMenu *thumbnailTypeMenu = new QMenu(thumbnailTypePushButton); + QAction *thumbnailTypeBoxartAction = NULL; + QAction *thumbnailTypeScreenshotAction = NULL; + QAction *thumbnailTypeTitleAction = NULL; QPushButton *viewTypePushButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_VIEW), m_zoomWidget); QMenu *viewTypeMenu = new QMenu(viewTypePushButton); QAction *viewTypeIconsAction = NULL; @@ -386,6 +391,15 @@ MainWindow::MainWindow(QWidget *parent) : m_gridProgressWidget = new QWidget(); gridProgressLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PROGRESS), m_gridProgressWidget); + thumbnailTypePushButton->setObjectName("thumbnailTypePushButton"); + thumbnailTypePushButton->setFlat(true); + + thumbnailTypeBoxartAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART)); + thumbnailTypeScreenshotAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT)); + thumbnailTypeTitleAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN)); + + thumbnailTypePushButton->setMenu(thumbnailTypeMenu); + viewTypePushButton->setObjectName("viewTypePushButton"); viewTypePushButton->setFlat(true); @@ -444,6 +458,7 @@ MainWindow::MainWindow(QWidget *parent) : gridFooterLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); gridFooterLayout->addWidget(m_gridProgressWidget); gridFooterLayout->addWidget(m_zoomWidget); + gridFooterLayout->addWidget(thumbnailTypePushButton); gridFooterLayout->addWidget(viewTypePushButton); static_cast(m_playlistViewsAndFooter->layout())->addLayout(gridFooterLayout); @@ -613,6 +628,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onPlaylistWidgetContextMenuRequested(const QPoint&))); connect(m_launchWithComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onLaunchWithComboBoxIndexChanged(int))); connect(m_zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(onZoomValueChanged(int))); + connect(thumbnailTypeBoxartAction, SIGNAL(triggered()), this, SLOT(onBoxartThumbnailClicked())); + connect(thumbnailTypeScreenshotAction, SIGNAL(triggered()), this, SLOT(onScreenshotThumbnailClicked())); + connect(thumbnailTypeTitleAction, SIGNAL(triggered()), this, SLOT(onTitleThumbnailClicked())); connect(viewTypeIconsAction, SIGNAL(triggered()), this, SLOT(onIconViewClicked())); connect(viewTypeListAction, SIGNAL(triggered()), this, SLOT(onListViewClicked())); connect(m_dirModel, SIGNAL(directoryLoaded(const QString&)), this, SLOT(onFileSystemDirLoaded(const QString&))); @@ -830,6 +848,21 @@ void MainWindow::onListViewClicked() setCurrentViewType(VIEW_TYPE_LIST); } +void MainWindow::onBoxartThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_BOXART); +} + +void MainWindow::onScreenshotThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_SCREENSHOT); +} + +void MainWindow::onTitleThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_TITLE_SCREEN); +} + void MainWindow::setIconViewZoom(int zoomValue) { m_zoomSlider->setValue(zoomValue); @@ -2986,6 +3019,7 @@ void MainWindow::closeEvent(QCloseEvent *event) m_settings->setValue("view_type", getCurrentViewTypeString()); m_settings->setValue("file_browser_table_headers", m_fileTableView->horizontalHeader()->saveState()); m_settings->setValue("icon_view_zoom", m_lastZoomSliderValue); + m_settings->setValue("icon_view_thumbnail_type", getCurrentThumbnailTypeString()); QMainWindow::closeEvent(event); } diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index 52404998c7..2bb2cc7731 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -221,7 +221,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : ,m_saveLastTabCheckBox(new QCheckBox(this)) ,m_showHiddenFilesCheckBox(new QCheckBox(this)) ,m_themeComboBox(new QComboBox(this)) - ,m_thumbnailComboBox(new QComboBox(this)) ,m_thumbnailCacheSpinBox(new QSpinBox(this)) ,m_startupPlaylistComboBox(new QComboBox(this)) ,m_highlightColorPushButton(new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CHOOSE), this)) @@ -239,10 +238,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM), MainWindow::THEME_CUSTOM); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART), THUMBNAIL_TYPE_BOXART); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT), THUMBNAIL_TYPE_SCREENSHOT); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN), THUMBNAIL_TYPE_TITLE_SCREEN); - m_thumbnailCacheSpinBox->setSuffix(" MB"); m_thumbnailCacheSpinBox->setRange(0, 99999); @@ -260,7 +255,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : /* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT), m_allPlaylistsListMaxCountSpinBox); */ /* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT), m_allPlaylistsGridMaxCountSpinBox); */ form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST), m_startupPlaylistComboBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE), m_thumbnailComboBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT), m_thumbnailCacheSpinBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); form->addRow(m_highlightColorLabel, m_highlightColorPushButton); @@ -274,16 +268,9 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : loadViewOptions(); connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); - connect(m_thumbnailComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThumbnailComboBoxIndexChanged(int))); connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); } -void ViewOptionsWidget::onThumbnailComboBoxIndexChanged(int index) -{ - ThumbnailType type = static_cast(m_thumbnailComboBox->currentData().value()); - m_mainwindow->setCurrentThumbnailType(type); -} - void ViewOptionsWidget::onThemeComboBoxIndexChanged(int) { MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); @@ -342,7 +329,6 @@ void ViewOptionsWidget::loadViewOptions() QVector > playlists = m_mainwindow->getPlaylists(); QString initialPlaylist = m_settings->value("initial_playlist", m_mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString(); int themeIndex = 0; - int thumbnailIndex = 0; int playlistIndex = 0; int i; @@ -360,11 +346,6 @@ void ViewOptionsWidget::loadViewOptions() if (m_themeComboBox->count() > themeIndex) m_themeComboBox->setCurrentIndex(themeIndex); - thumbnailIndex = m_thumbnailComboBox->findData(m_mainwindow->getThumbnailTypeFromString(m_settings->value("icon_view_thumbnail_type", "boxart").toString())); - - if (m_thumbnailComboBox->count() > thumbnailIndex) - m_thumbnailComboBox->setCurrentIndex(thumbnailIndex); - if (highlightColor.isValid()) { m_highlightColor = highlightColor; @@ -415,7 +396,6 @@ void ViewOptionsWidget::saveViewOptions() /* m_settings->setValue("all_playlists_list_max_count", m_allPlaylistsListMaxCountSpinBox->value()); */ /* m_settings->setValue("all_playlists_grid_max_count", m_allPlaylistsGridMaxCountSpinBox->value()); */ m_settings->setValue("initial_playlist", m_startupPlaylistComboBox->currentData(Qt::UserRole).toString()); - m_settings->setValue("icon_view_thumbnail_type", m_mainwindow->getCurrentThumbnailTypeString()); m_settings->setValue("thumbnail_cache_limit", m_thumbnailCacheSpinBox->value()); if (!m_mainwindow->customThemeString().isEmpty()) diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 7116a50f25..6f7afd6b2f 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -31,7 +31,6 @@ public slots: void saveViewOptions(); private slots: void onThemeComboBoxIndexChanged(int index); - void onThumbnailComboBoxIndexChanged(int index); void onHighlightColorChoose(); private: void showOrHideHighlightColor(); @@ -43,7 +42,6 @@ private: QCheckBox *m_saveLastTabCheckBox; QCheckBox *m_showHiddenFilesCheckBox; QComboBox *m_themeComboBox; - QComboBox *m_thumbnailComboBox; QSpinBox *m_thumbnailCacheSpinBox; QComboBox *m_startupPlaylistComboBox; QPushButton *m_highlightColorPushButton; diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index c7183c3397..d0f1e8e919 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -447,6 +447,9 @@ public slots: void showWelcomeScreen(); void onIconViewClicked(); void onListViewClicked(); + void onBoxartThumbnailClicked(); + void onScreenshotThumbnailClicked(); + void onTitleThumbnailClicked(); void onTabWidgetIndexChanged(int index); void deleteCurrentPlaylistItem(); void onFileDropWidgetContextMenuRequested(const QPoint &pos); From e7373a9cc2b593c2e68d7d5af56ea11e0985d2c0 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Tue, 2 Apr 2019 01:49:30 +0200 Subject: [PATCH 4/4] dark theme pushbutton indicator fix --- ui/drivers/qt/ui_qt_themes.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index 95b8ad0da7..c72531e39a 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -326,6 +326,11 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QPushButton[flat="true"] { background-color:transparent; } + QPushButton[flat="true"]::menu-indicator { + position:relative; + bottom:4px; + right:4px; + } QRadioButton::indicator { width:18px; height:18px;