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;