diff --git a/src/citron/configuration/configure.ui b/src/citron/configuration/configure.ui
index b42f7cf44..fa192dc2f 100644
--- a/src/citron/configuration/configure.ui
+++ b/src/citron/configuration/configure.ui
@@ -6,72 +6,718 @@
0
0
- 650
- 650
+ 1400
+ 900
- 0
- 650
+ 1200
+ 800
citron Configuration
+
+
+ 0
+ 0
+
+
+
+ QDialog {
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QWidget {
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QStackedWidget {
+ background-color: #2b2b2b;
+ border: 1px solid #3d3d3d;
+ border-radius: 8px;
+ margin: 0px;
+ padding: 0px;
+}
+
+QScrollArea {
+ background-color: #2b2b2b;
+ border: none;
+ border-radius: 8px;
+}
+
+QScrollArea > QWidget > QWidget {
+ background-color: #2b2b2b;
+}
+
+QScrollBar:vertical {
+ background-color: #3d3d3d;
+ width: 14px;
+ border-radius: 7px;
+ margin: 2px;
+}
+
+QScrollBar::handle:vertical {
+ background-color: #5d5d5d;
+ border-radius: 6px;
+ min-height: 30px;
+ margin: 1px;
+}
+
+QScrollBar::handle:vertical:hover {
+ background-color: #4a9eff;
+}
+
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
+ border: none;
+ background: none;
+ height: 0px;
+}
+
+QScrollBar:horizontal {
+ background-color: #3d3d3d;
+ height: 14px;
+ border-radius: 7px;
+ margin: 2px;
+}
+
+QScrollBar::handle:horizontal {
+ background-color: #5d5d5d;
+ border-radius: 6px;
+ min-width: 30px;
+ margin: 1px;
+}
+
+QScrollBar::handle:horizontal:hover {
+ background-color: #4a9eff;
+}
+
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {
+ border: none;
+ background: none;
+ width: 0px;
+}
+
+QPushButton.tabButton {
+ background-color: #383838;
+ color: #ffffff;
+ padding: 10px 14px;
+ margin: 2px;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ min-width: 85px;
+ max-width: 160px;
+ font-weight: 500;
+ border: 1px solid #3d3d3d;
+ text-align: center;
+}
+
+QPushButton.tabButton:checked {
+ background-color: #4a9eff;
+ color: #ffffff;
+ font-weight: bold;
+ border-color: #4a9eff;
+}
+
+QPushButton.tabButton:hover:!checked {
+ background-color: #4d4d4d;
+ border-color: #5d5d5d;
+}
+
+QPushButton.tabButton:pressed {
+ background-color: #2980b9;
+}
+
+QTabWidget {
+ background-color: #2b2b2b;
+ border: none;
+}
+
+QTabWidget::pane {
+ border: 1px solid #3d3d3d;
+ background-color: #2b2b2b;
+ border-radius: 8px;
+ margin: 0px;
+ padding: 0px;
+}
+
+QTabWidget::tab-bar {
+ alignment: left;
+}
+
+QTabBar {
+ background-color: #2b2b2b;
+ border: none;
+}
+
+QTabBar::tab {
+ background-color: #383838;
+ color: #ffffff;
+ padding: 12px 20px;
+ margin-right: 2px;
+ margin-bottom: 2px;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px;
+ min-width: 100px;
+ font-weight: 500;
+ border: 1px solid #3d3d3d;
+ border-bottom: none;
+}
+
+QTabBar::tab:selected {
+ background-color: #4a9eff;
+ color: #ffffff;
+ font-weight: bold;
+ border-color: #4a9eff;
+}
+
+QTabBar::tab:hover:!selected {
+ background-color: #4d4d4d;
+ border-color: #5d5d5d;
+}
+
+QTabBar QToolButton {
+ background-color: #383838;
+ border: 1px solid #3d3d3d;
+ border-radius: 4px;
+ padding: 4px;
+ margin: 2px;
+}
+
+QTabBar QToolButton:hover {
+ background-color: #4d4d4d;
+ border-color: #4a9eff;
+}
+
+QTabBar::scroller {
+ width: 30px;
+}
+
+QGroupBox {
+ font-weight: bold;
+ border: 1px solid #3d3d3d;
+ border-radius: 8px;
+ margin-top: 12px;
+ padding-top: 12px;
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ left: 12px;
+ padding: 0 8px 0 8px;
+ color: #ffffff;
+ font-weight: bold;
+}
+
+QCheckBox {
+ color: #ffffff;
+ spacing: 10px;
+ padding: 4px;
+ background-color: transparent;
+}
+
+QCheckBox::indicator {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #5d5d5d;
+ border-radius: 4px;
+ background-color: #3d3d3d;
+}
+
+QCheckBox::indicator:checked {
+ background-color: #4a9eff;
+ border-color: #4a9eff;
+}
+
+QCheckBox::indicator:hover {
+ border-color: #4a9eff;
+}
+
+QComboBox {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 8px 12px;
+ color: #ffffff;
+ min-width: 120px;
+ min-height: 28px;
+ selection-background-color: #4a9eff;
+}
+
+QComboBox:hover {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 25px;
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ background-color: transparent;
+}
+
+QComboBox::down-arrow {
+ width: 12px;
+ height: 12px;
+ background-color: #ffffff;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #3d3d3d;
+ border: 1px solid #4a9eff;
+ selection-background-color: #4a9eff;
+ color: #ffffff;
+ outline: none;
+}
+
+QComboBox QAbstractItemView::item {
+ padding: 8px;
+ border: none;
+ background-color: transparent;
+}
+
+QComboBox QAbstractItemView::item:selected {
+ background-color: #4a9eff;
+ color: #ffffff;
+}
+
+QComboBox QAbstractItemView::item:hover {
+ background-color: #5dafff;
+ color: #ffffff;
+}
+
+QLineEdit {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 8px 12px;
+ color: #ffffff;
+ min-height: 20px;
+ selection-background-color: #4a9eff;
+}
+
+QLineEdit:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QPushButton {
+ background-color: #4a9eff;
+ color: #ffffff;
+ border: none;
+ padding: 10px 20px;
+ border-radius: 6px;
+ font-weight: bold;
+ min-height: 20px;
+}
+
+QPushButton:hover {
+ background-color: #5dafff;
+}
+
+QPushButton:pressed {
+ background-color: #2980b9;
+}
+
+QPushButton:disabled {
+ background-color: #5d5d5d;
+ color: #8d8d8d;
+}
+
+QToolButton {
+ background-color: #4a9eff;
+ color: #ffffff;
+ border: none;
+ padding: 8px 12px;
+ border-radius: 6px;
+ font-weight: bold;
+ min-width: 32px;
+ min-height: 24px;
+}
+
+QToolButton:hover {
+ background-color: #5dafff;
+}
+
+QToolButton:pressed {
+ background-color: #2980b9;
+}
+
+QLabel {
+ color: #ffffff;
+ background-color: transparent;
+ padding: 2px;
+}
+
+QListWidget {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ color: #ffffff;
+ padding: 4px;
+}
+
+QListWidget::item {
+ padding: 8px;
+ border-radius: 4px;
+ margin: 1px;
+}
+
+QListWidget::item:selected {
+ background-color: #4a9eff;
+ color: #ffffff;
+}
+
+QListWidget::item:hover:!selected {
+ background-color: #4d4d4d;
+}
+
+QSlider::groove:horizontal {
+ border: 1px solid #5d5d5d;
+ height: 8px;
+ background-color: #3d3d3d;
+ border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+ background-color: #4a9eff;
+ border: 1px solid #4a9eff;
+ width: 18px;
+ margin: -5px 0;
+ border-radius: 9px;
+}
+
+QSlider::handle:horizontal:hover {
+ background-color: #5dafff;
+}
+
+QSpinBox, QDoubleSpinBox {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 6px;
+ color: #ffffff;
+ min-height: 20px;
+}
+
+QSpinBox:focus, QDoubleSpinBox:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QRadioButton {
+ color: #ffffff;
+ spacing: 8px;
+ padding: 4px;
+}
+
+QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border: 2px solid #5d5d5d;
+ border-radius: 8px;
+ background-color: #3d3d3d;
+}
+
+QRadioButton::indicator:checked {
+ background-color: #4a9eff;
+ border-color: #4a9eff;
+}
+
+QRadioButton::indicator:hover {
+ border-color: #4a9eff;
+}
+
+
+
+ 8
+
+
+ 12
+
+
+ 12
+
+
+ 12
+
+
+ 12
+
-
-
+
+
+ 8
+
-
-
-
-
- 120
- 0
-
+
+
+ 4
-
-
- 120
- 16777215
-
-
-
+
-
+
+
+ General
+
+
+ true
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ UI
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ System
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ CPU
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Graphics
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Graphics (Adv)
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Audio
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Input
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Hotkeys
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Network
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Web
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Filesystem
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Profiles
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Applets
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Logging
+
+
+ true
+
+
+ tabButton
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
+
+
+
+ 0
+ 0
+
+
- -1
+ 0
-
-
+
+
+ 12
+
- 0
+ 8
- 0
+ 8
- 0
+ 8
0
-
-
-
-
- Some settings are only available when a game is not running.
-
-
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+ QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok
diff --git a/src/citron/configuration/configure_dialog.cpp b/src/citron/configuration/configure_dialog.cpp
index f99512e3f..0743da933 100644
--- a/src/citron/configuration/configure_dialog.cpp
+++ b/src/citron/configuration/configure_dialog.cpp
@@ -1,7 +1,14 @@
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include
+#include
+#include
+#include
+#include
+#include
+#include
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
@@ -28,6 +35,18 @@
#include "citron/hotkeys.h"
#include "citron/uisettings.h"
+// Helper function to create a scroll area for a widget
+QScrollArea* CreateScrollArea(QWidget* widget) {
+ auto* scroll_area = new QScrollArea();
+ scroll_area->setWidget(widget);
+ scroll_area->setWidgetResizable(true);
+ scroll_area->setFrameShape(QFrame::NoFrame);
+ scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scroll_area->setStyleSheet(QLatin1String("QScrollArea { border: none; background-color: #2b2b2b; }"));
+ return scroll_area;
+}
+
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
InputCommon::InputSubsystem* input_subsystem,
std::vector& vk_device_records,
@@ -58,23 +77,69 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
web_tab{std::make_unique(this)} {
Settings::SetConfiguringGlobal(true);
+ // Set window flags to include maximize button and make it resizable
+ setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
+ Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
+
ui->setupUi(this);
- ui->tabWidget->addTab(applets_tab.get(), tr("Applets"));
- ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
- ui->tabWidget->addTab(cpu_tab.get(), tr("CPU"));
- ui->tabWidget->addTab(debug_tab_tab.get(), tr("Debug"));
- ui->tabWidget->addTab(filesystem_tab.get(), tr("Filesystem"));
- ui->tabWidget->addTab(general_tab.get(), tr("General"));
- ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
- ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("GraphicsAdvanced"));
- ui->tabWidget->addTab(hotkeys_tab.get(), tr("Hotkeys"));
- ui->tabWidget->addTab(input_tab.get(), tr("Controls"));
- ui->tabWidget->addTab(profile_tab.get(), tr("Profiles"));
- ui->tabWidget->addTab(network_tab.get(), tr("Network"));
- ui->tabWidget->addTab(system_tab.get(), tr("System"));
- ui->tabWidget->addTab(ui_tab.get(), tr("Game List"));
- ui->tabWidget->addTab(web_tab.get(), tr("Web"));
+ // Set size policy and enable resizing
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // Get screen geometry and set to fullscreen
+ QScreen* screen = QApplication::primaryScreen();
+ if (screen) {
+ QRect screenGeometry = screen->availableGeometry();
+ setGeometry(screenGeometry);
+ showMaximized(); // Start maximized/fullscreen
+ }
+
+ // Create button group for exclusive tab selection
+ tab_button_group = std::make_unique(this);
+ tab_button_group->setExclusive(true);
+
+ // Add tab buttons to the button group and connect to stacked widget
+ tab_button_group->addButton(ui->generalTabButton, 0);
+ tab_button_group->addButton(ui->uiTabButton, 1);
+ tab_button_group->addButton(ui->systemTabButton, 2);
+ tab_button_group->addButton(ui->cpuTabButton, 3);
+ tab_button_group->addButton(ui->graphicsTabButton, 4);
+ tab_button_group->addButton(ui->graphicsAdvancedTabButton, 5);
+ tab_button_group->addButton(ui->audioTabButton, 6);
+ tab_button_group->addButton(ui->inputTabButton, 7);
+ tab_button_group->addButton(ui->hotkeysTabButton, 8);
+ tab_button_group->addButton(ui->networkTabButton, 9);
+ tab_button_group->addButton(ui->webTabButton, 10);
+ tab_button_group->addButton(ui->filesystemTabButton, 11);
+ tab_button_group->addButton(ui->profilesTabButton, 12);
+ tab_button_group->addButton(ui->appletsTabButton, 13);
+ tab_button_group->addButton(ui->loggingTabButton, 14);
+
+ // Add pages to stacked widget wrapped in scroll areas in the same order as button group
+ ui->stackedWidget->addWidget(CreateScrollArea(general_tab.get())); // 0
+ ui->stackedWidget->addWidget(CreateScrollArea(ui_tab.get())); // 1
+ ui->stackedWidget->addWidget(CreateScrollArea(system_tab.get())); // 2
+ ui->stackedWidget->addWidget(CreateScrollArea(cpu_tab.get())); // 3
+ ui->stackedWidget->addWidget(CreateScrollArea(graphics_tab.get())); // 4
+ ui->stackedWidget->addWidget(CreateScrollArea(graphics_advanced_tab.get())); // 5
+ ui->stackedWidget->addWidget(CreateScrollArea(audio_tab.get())); // 6
+ ui->stackedWidget->addWidget(CreateScrollArea(input_tab.get())); // 7
+ ui->stackedWidget->addWidget(CreateScrollArea(hotkeys_tab.get())); // 8
+ ui->stackedWidget->addWidget(CreateScrollArea(network_tab.get())); // 9
+ ui->stackedWidget->addWidget(CreateScrollArea(web_tab.get())); // 10
+ ui->stackedWidget->addWidget(CreateScrollArea(filesystem_tab.get()));// 11
+ ui->stackedWidget->addWidget(CreateScrollArea(profile_tab.get())); // 12
+ ui->stackedWidget->addWidget(CreateScrollArea(applets_tab.get())); // 13
+ ui->stackedWidget->addWidget(CreateScrollArea(debug_tab_tab.get())); // 14
+
+ // Connect button group to stacked widget
+ connect(tab_button_group.get(), QOverload::of(&QButtonGroup::idClicked),
+ [this](int id) {
+ ui->stackedWidget->setCurrentIndex(id);
+ if (id == 14) { // Logging tab
+ debug_tab_tab->SetCurrentIndex(0);
+ }
+ });
web_tab->SetWebServiceConfigEnabled(enable_web_config);
hotkeys_tab->Populate(registry);
@@ -84,27 +149,22 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
general_tab->SetResetCallback([&] { this->close(); });
SetConfiguration();
- PopulateSelectionList();
- connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this](int index) {
- if (index != -1) {
- debug_tab_tab->SetCurrentIndex(0);
- }
- });
connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
- connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
- &ConfigureDialog::UpdateVisibleTabs);
if (system.IsPoweredOn()) {
- QPushButton* apply_button = ui->buttonBox->addButton(QDialogButtonBox::Apply);
- connect(apply_button, &QAbstractButton::clicked, this,
- &ConfigureDialog::HandleApplyButtonClicked);
+ QPushButton* apply_button = ui->buttonBox->button(QDialogButtonBox::Apply);
+ if (apply_button) {
+ connect(apply_button, &QAbstractButton::clicked, this,
+ &ConfigureDialog::HandleApplyButtonClicked);
+ }
}
- adjustSize();
- ui->selectorList->setCurrentRow(0);
+ // Set initial tab to General (index 0)
+ ui->stackedWidget->setCurrentIndex(0);
+ ui->generalTabButton->setChecked(true);
- // Selects the leftmost button on the bottom bar (Cancel as of writing)
+ // Focus on the OK button by default
ui->buttonBox->setFocus();
}
@@ -141,16 +201,12 @@ void ConfigureDialog::changeEvent(QEvent* event) {
}
void ConfigureDialog::RetranslateUI() {
- const int old_row = ui->selectorList->currentRow();
- const int old_index = ui->tabWidget->currentIndex();
+ const int old_index = ui->stackedWidget->currentIndex();
ui->retranslateUi(this);
- PopulateSelectionList();
- ui->selectorList->setCurrentRow(old_row);
-
- UpdateVisibleTabs();
- ui->tabWidget->setCurrentIndex(old_index);
+ SetConfiguration();
+ ui->stackedWidget->setCurrentIndex(old_index);
}
void ConfigureDialog::HandleApplyButtonClicked() {
@@ -158,56 +214,12 @@ void ConfigureDialog::HandleApplyButtonClicked() {
ApplyConfiguration();
}
-Q_DECLARE_METATYPE(QList);
-
-void ConfigureDialog::PopulateSelectionList() {
- const std::array>, 6> items{
- {{tr("General"),
- {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}},
- {tr("System"),
- {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(),
- applets_tab.get()}},
- {tr("CPU"), {cpu_tab.get()}},
- {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get()}},
- {tr("Audio"), {audio_tab.get()}},
- {tr("Controls"), input_tab->GetSubTabs()}},
- };
-
- [[maybe_unused]] const QSignalBlocker blocker(ui->selectorList);
-
- ui->selectorList->clear();
- for (const auto& entry : items) {
- auto* const item = new QListWidgetItem(entry.first);
- item->setData(Qt::UserRole, QVariant::fromValue(entry.second));
-
- ui->selectorList->addItem(item);
- }
-}
-
void ConfigureDialog::OnLanguageChanged(const QString& locale) {
emit LanguageChanged(locale);
- // Reloading the game list is needed to force retranslation.
+ // Reloading the game list is needed to force retranslation.
UISettings::values.is_game_list_reload_pending = true;
// first apply the configuration, and then restore the display
ApplyConfiguration();
RetranslateUI();
SetConfiguration();
}
-
-void ConfigureDialog::UpdateVisibleTabs() {
- const auto items = ui->selectorList->selectedItems();
- if (items.isEmpty()) {
- return;
- }
-
- [[maybe_unused]] const QSignalBlocker blocker(ui->tabWidget);
-
- ui->tabWidget->clear();
-
- const auto tabs = qvariant_cast>(items[0]->data(Qt::UserRole));
-
- for (auto* const tab : tabs) {
- LOG_DEBUG(Frontend, "{}", tab->accessibleName().toStdString());
- ui->tabWidget->addTab(tab, tab->accessibleName());
- }
-}
diff --git a/src/citron/configuration/configure_dialog.h b/src/citron/configuration/configure_dialog.h
index 6c5275748..b074541e4 100644
--- a/src/citron/configuration/configure_dialog.h
+++ b/src/citron/configuration/configure_dialog.h
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -6,6 +7,7 @@
#include
#include
#include
+#include
#include "configuration/shared_widget.h"
#include "citron/configuration/configuration_shared.h"
#include "citron/configuration/shared_translation.h"
@@ -66,8 +68,6 @@ private:
void HandleApplyButtonClicked();
void SetConfiguration();
- void UpdateVisibleTabs();
- void PopulateSelectionList();
std::unique_ptr ui;
HotkeyRegistry& registry;
@@ -75,6 +75,7 @@ private:
Core::System& system;
std::unique_ptr builder;
std::vector tab_group;
+ std::unique_ptr tab_button_group;
std::unique_ptr applets_tab;
std::unique_ptr audio_tab;
diff --git a/src/citron/configuration/configure_graphics.ui b/src/citron/configuration/configure_graphics.ui
index d09415d70..0455ec29c 100644
--- a/src/citron/configuration/configure_graphics.ui
+++ b/src/citron/configuration/configure_graphics.ui
@@ -6,8 +6,8 @@
0
0
- 541
- 759
+ 800
+ 600
@@ -16,120 +16,345 @@
Graphics
+
+ QWidget {
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QGroupBox {
+ font-weight: bold;
+ border: 1px solid #3d3d3d;
+ border-radius: 8px;
+ margin-top: 12px;
+ padding-top: 12px;
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ left: 12px;
+ padding: 0 8px 0 8px;
+ color: #ffffff;
+ font-weight: bold;
+}
+
+QComboBox {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 8px 12px;
+ color: #ffffff;
+ min-width: 200px;
+ min-height: 28px;
+ selection-background-color: #4a9eff;
+}
+
+QComboBox:hover {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 25px;
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ background-color: transparent;
+}
+
+QComboBox::down-arrow {
+ width: 12px;
+ height: 12px;
+ background-color: #ffffff;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #3d3d3d;
+ border: 1px solid #4a9eff;
+ selection-background-color: #4a9eff;
+ color: #ffffff;
+ outline: none;
+ padding: 4px;
+}
+
+QComboBox QAbstractItemView::item {
+ padding: 8px;
+ border: none;
+ background-color: transparent;
+ min-height: 20px;
+}
+
+QComboBox QAbstractItemView::item:selected {
+ background-color: #4a9eff;
+ color: #ffffff;
+}
+
+QComboBox QAbstractItemView::item:hover {
+ background-color: #5dafff;
+ color: #ffffff;
+}
+
+QCheckBox {
+ color: #ffffff;
+ spacing: 12px;
+ padding: 6px;
+ background-color: transparent;
+ min-height: 24px;
+}
+
+QCheckBox::indicator {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #5d5d5d;
+ border-radius: 4px;
+ background-color: #3d3d3d;
+}
+
+QCheckBox::indicator:checked {
+ background-color: #4a9eff;
+ border-color: #4a9eff;
+}
+
+QCheckBox::indicator:hover {
+ border-color: #4a9eff;
+}
+
+QPushButton {
+ background-color: #4a9eff;
+ color: #ffffff;
+ border: none;
+ padding: 10px 20px;
+ border-radius: 6px;
+ font-weight: bold;
+ min-height: 20px;
+}
+
+QPushButton:hover {
+ background-color: #5dafff;
+}
+
+QPushButton:pressed {
+ background-color: #2980b9;
+}
+
+QLabel {
+ color: #ffffff;
+ background-color: transparent;
+ padding: 4px;
+ min-width: 120px;
+}
+
+QSlider::groove:horizontal {
+ border: 1px solid #5d5d5d;
+ height: 8px;
+ background-color: #3d3d3d;
+ border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+ background-color: #4a9eff;
+ border: 1px solid #4a9eff;
+ width: 18px;
+ margin: -5px 0;
+ border-radius: 9px;
+}
+
+QSlider::handle:horizontal:hover {
+ background-color: #5dafff;
+}
+
+QSpinBox, QDoubleSpinBox {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 6px;
+ color: #ffffff;
+ min-height: 20px;
+}
+
+QSpinBox:focus, QDoubleSpinBox:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+
+
+ 20
+
+
+ 24
+
+
+ 24
+
+
+ 24
+
+
+ 24
+
-
-
-
-
-
-
- API Settings
-
-
-
-
-
-
-
- 0
+
+
+ API Settings
+
+
+
+ 16
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
-
+
+
+
+ 16
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+ -
+
+
+ Graphics Settings
+
+
+
+ 16
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
-
+
+
+
+ 12
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ -
+
+
+
+ 16
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
-
- 0
+
+ Background Color:
-
- 0
+
+
+ 120
+ 0
+
-
- 0
+
+
+ -
+
+
+
+ 0
+ 0
+
-
-
-
-
-
-
- -
-
-
-
- 16777215
- 16777215
-
-
-
- Graphics Settings
-
-
-
-
-
-
-
- 0
+
+
+ 80
+ 40
+
-
- 0
+
+
+ 80
+ 40
+
-
- 0
+
+
-
- 0
-
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
-
- 0
- 0
-
-
-
- Background Color:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 40
- 16777215
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
diff --git a/src/citron/configuration/configure_ui.cpp b/src/citron/configuration/configure_ui.cpp
index f71532b67..2876e048a 100644
--- a/src/citron/configuration/configure_ui.cpp
+++ b/src/citron/configuration/configure_ui.cpp
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "citron/configuration/configure_ui.h"
@@ -18,6 +19,8 @@
#include
#include
#include
+#include
+#include
#include "common/common_types.h"
#include "common/fs/path_util.h"
diff --git a/src/citron/configuration/configure_ui.ui b/src/citron/configuration/configure_ui.ui
index b8e648381..0d889fe34 100644
--- a/src/citron/configuration/configure_ui.ui
+++ b/src/citron/configuration/configure_ui.ui
@@ -6,25 +6,197 @@
0
0
- 363
- 603
+ 1200
+ 800
+
+
+ 1000
+ 600
+
+
Form
UI
-
+
+ QWidget {
+ background-color: #2b2b2b;
+ color: #ffffff;
+}
+
+QGroupBox {
+ font-weight: bold;
+ border: 1px solid #3d3d3d;
+ border-radius: 8px;
+ margin-top: 12px;
+ padding-top: 12px;
+ background-color: #2b2b2b;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ left: 12px;
+ padding: 0 8px 0 8px;
+ color: #ffffff;
+}
+
+QCheckBox {
+ color: #ffffff;
+ spacing: 12px;
+ padding: 6px;
+ background-color: transparent;
+ min-height: 24px;
+}
+
+QCheckBox::indicator {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #5d5d5d;
+ border-radius: 4px;
+ background-color: #3d3d3d;
+}
+
+QCheckBox::indicator:checked {
+ background-color: #4a9eff;
+ border-color: #4a9eff;
+}
+
+QCheckBox::indicator:hover {
+ border-color: #4a9eff;
+}
+
+QComboBox {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 8px 12px;
+ color: #ffffff;
+ min-width: 160px;
+ min-height: 28px;
+}
+
+QComboBox:hover {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 24px;
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+}
+
+QComboBox::down-arrow {
+ width: 12px;
+ height: 12px;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #3d3d3d;
+ border: 1px solid #4a9eff;
+ selection-background-color: #4a9eff;
+ color: #ffffff;
+}
+
+QLineEdit {
+ background-color: #3d3d3d;
+ border: 1px solid #5d5d5d;
+ border-radius: 6px;
+ padding: 8px 12px;
+ color: #ffffff;
+ min-height: 28px;
+}
+
+QLineEdit:focus {
+ border-color: #4a9eff;
+ background-color: #404040;
+}
+
+QToolButton {
+ background-color: #4a9eff;
+ color: #ffffff;
+ border: none;
+ padding: 8px 12px;
+ border-radius: 6px;
+ font-weight: bold;
+ min-width: 40px;
+ min-height: 32px;
+}
+
+QToolButton:hover {
+ background-color: #5dafff;
+}
+
+QToolButton:pressed {
+ background-color: #2980b9;
+}
+
+QLabel {
+ color: #ffffff;
+ background-color: transparent;
+ padding: 4px;
+ min-width: 140px;
+}
+
+
+
+
+ 32
+
+
+ 32
+
+
+ 32
+
+
+ 32
+
+
+ 32
+
-
-
-
- General
+
+
+ 20
-
-
-
-
+
-
+
+
+ General
+
+
+
+ 500
+ 0
+
+
+
+
+ 12
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
-
@@ -33,54 +205,112 @@
true
+
+ color: #cccccc; font-size: 11px;
+
-
-
+
+
+ 16
+
-
Interface language:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
+
+
+ 16
+
-
Theme:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
-
-
- -
-
-
- Game List
-
-
-
-
-
+
+
+ -
+
+
+ Game List
+
+
+
+ 500
+ 0
+
+
+
+
+ 12
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
-
Show Compatibility List
+
+
+ 0
+ 32
+
+
-
@@ -88,6 +318,12 @@
Show Add-Ons Column
+
+
+ 0
+ 32
+
+
-
@@ -95,6 +331,12 @@
Show Size Column
+
+
+ 0
+ 32
+
+
-
@@ -102,6 +344,12 @@
Show File Types Column
+
+
+ 0
+ 32
+
+
-
@@ -109,95 +357,224 @@
Show Play Time Column
+
+
+ 0
+ 32
+
+
-
-
+
+
+ 16
+
-
Game Icon Size:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
+
+
+ 16
+
-
Folder Icon Size:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
+
+
+ 16
+
-
Row 1 Text:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
+
+
+ 16
+
-
Row 2 Text:
+
+
+ 140
+ 0
+
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
-
-
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
-
-
-
- Screenshots
+
+
+ 20
-
-
-
-
+
-
+
+
+ Screenshots
+
+
+
+ 500
+ 0
+
+
+
+
+ 16
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
+
+ 20
+
-
Ask Where To Save Screenshots (Windows Only)
+
+
+ 0
+ 32
+
+
-
-
+
+
+ 12
+
-
-
+
- Screenshots Path:
+ Screenshots Path:
+
+
+
+ 140
+ 0
+
-
-
+
+
+
+ 0
+ 0
+
+
+
-
@@ -209,57 +586,71 @@
-
-
+
- 6
+ 12
-
-
-
-
-
-
-
- TextLabel
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- true
-
-
-
-
-
- -
-
+
-
+
Resolution:
+
+
+ 80
+ 0
+
+
+
+
+ -
+
+
+ TextLabel
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ 120
+ 0
+
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+