2727#include < QtCore/QRegularExpression>
2828#include < QtCore/QTemporaryFile>
2929#include < QtGui/QFont>
30+ #include < QtGui/QPalette>
31+ #include < QtGui/QColor>
3032#include < QtGui/QWindow>
3133#include < QtGui/QDesktopServices>
3234#include < QtGui/QClipboard>
3739#include < QtWidgets/QComboBox>
3840#include < QtWidgets/QScrollBar>
3941#include < QtWidgets/QMessageBox>
42+ #include < QtWidgets/QStyle>
43+ #include < QtWidgets/QStyleFactory>
4044#include < QtNetwork/QNetworkReply>
45+ #include < QtCore/QSignalBlocker>
46+ #include < QtCore/QScopedValueRollback>
4147#include < fstream>
4248#include < iostream>
4349#include < cmath>
4450
51+ namespace {
52+ QPalette createFusionDarkPalette (const QPalette &base) {
53+ QPalette palette = base;
54+ palette.setColor (QPalette::Window, QColor (53 , 53 , 53 ));
55+ palette.setColor (QPalette::WindowText, Qt::white);
56+ palette.setColor (QPalette::Base, QColor (25 , 25 , 25 ));
57+ palette.setColor (QPalette::AlternateBase, QColor (53 , 53 , 53 ));
58+ palette.setColor (QPalette::ToolTipBase, Qt::white);
59+ palette.setColor (QPalette::ToolTipText, Qt::white);
60+ palette.setColor (QPalette::Text, Qt::white);
61+ palette.setColor (QPalette::Button, QColor (53 , 53 , 53 ));
62+ palette.setColor (QPalette::ButtonText, Qt::white);
63+ palette.setColor (QPalette::BrightText, Qt::red);
64+ palette.setColor (QPalette::Link, QColor (42 , 130 , 218 ));
65+ palette.setColor (QPalette::Highlight, QColor (76 , 163 , 224 ));
66+ palette.setColor (QPalette::HighlightedText, Qt::black);
67+
68+ static constexpr QColor disabledColor (127 , 127 , 127 );
69+ palette.setColor (QPalette::Disabled, QPalette::Text, disabledColor);
70+ palette.setColor (QPalette::Disabled, QPalette::ButtonText, disabledColor);
71+ palette.setColor (QPalette::PlaceholderText, disabledColor);
72+ return palette;
73+ }
74+ }
75+
4576#ifdef Q_OS_MACOS
4677# include " os/mac/kdmactouchbar.h"
4778#endif
@@ -71,8 +102,30 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
71102
72103 ui->setupUi (this );
73104
74- m_styleForMode[0 ] = m_styleForMode[1 ] = QApplication::style ()->name ();
75- darkModeSwitch (isSystemInDarkMode ());
105+ m_styleForMode[0 ] = QApplication::style ()->objectName ();
106+ if (m_styleForMode[0 ].isEmpty ()) {
107+ m_styleForMode[0 ] = QApplication::style ()->name ();
108+ }
109+ if (m_styleForMode[0 ].isEmpty ()) {
110+ m_styleForMode[0 ] = QStringLiteral (" fusion" );
111+ }
112+ m_styleForMode[1 ] = QStringLiteral (" fusion" );
113+
114+ if (const QStyle *fusionStyle = QStyleFactory::create (QStringLiteral (" Fusion" ))) {
115+ m_fusionLightPalette = fusionStyle->standardPalette ();
116+ delete fusionStyle;
117+ } else {
118+ m_fusionLightPalette = QApplication::style ()->standardPalette ();
119+ }
120+ m_fusionDarkPalette = createFusionDarkPalette (m_fusionLightPalette);
121+
122+ {
123+ QSignalBlocker blocker (ui->comboTheme );
124+ ui->comboTheme ->setCurrentIndex (static_cast <int >(m_themePreference));
125+ }
126+ connect (ui->comboTheme , &QComboBox::currentIndexChanged, this , &MainWindow::setThemePreference);
127+
128+ applyThemeFromPreference ();
76129
77130 setStyleSheet (QStringLiteral (" QMainWindow::separator{ width: 0px; height: 0px; }" ));
78131
@@ -598,6 +651,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
598651 }
599652
600653 setAutoUpdates (m_config->value (SETTING_AUTOUPDATE, CEMU_RELEASE).toBool ());
654+ setThemePreference (m_config->value (SETTING_UI_THEME, static_cast <int >(ThemePreference::System)).toInt ());
601655 checkVersion ();
602656
603657#ifdef Q_OS_WIN
@@ -1130,14 +1184,40 @@ void MainWindow::translateExtras(int init) {
11301184 }
11311185}
11321186
1133- void MainWindow::darkModeSwitch (bool darkMode) {
1134- QApplication::setStyle (m_styleForMode[darkMode]);
1135- if (darkMode != isRunningInDarkMode ()) {
1136- m_styleForMode[darkMode] = QStringLiteral (" fusion" );
1137- QApplication::setStyle (m_styleForMode[darkMode]);
1138- darkMode = isRunningInDarkMode ();
1187+ static void repolishAfterThemeChanged () {
1188+ const auto widgets = QApplication::allWidgets ();
1189+ for (QWidget *w : widgets) {
1190+ if (QStyle *st = w->style ()) {
1191+ st->unpolish (w);
1192+ st->polish (w);
1193+ }
1194+ w->update ();
1195+ }
1196+ }
1197+
1198+ void MainWindow::applyThemeFromPreference () {
1199+ switch (m_themePreference) {
1200+ case ThemePreference::System:
1201+ QApplication::setStyle (m_styleForMode[0 ]);
1202+ QApplication::setPalette (QApplication::style ()->standardPalette ());
1203+ break ;
1204+ case ThemePreference::Light:
1205+ QApplication::setStyle (m_styleForMode[1 ]);
1206+ QApplication::setPalette (m_fusionLightPalette);
1207+ break ;
1208+ case ThemePreference::Dark:
1209+ QApplication::setStyle (m_styleForMode[1 ]);
1210+ QApplication::setPalette (m_fusionDarkPalette);
1211+ break ;
11391212 }
11401213
1214+ const bool dark = m_themePreference == ThemePreference::Dark || (m_themePreference == ThemePreference::System && isSystemInDarkMode ());
1215+ darkModeSwitch (dark);
1216+
1217+ repolishAfterThemeChanged ();
1218+ }
1219+
1220+ void MainWindow::darkModeSwitch (bool darkMode) {
11411221 m_isInDarkMode = darkMode;
11421222 if (darkMode) {
11431223 m_cBack.setColor (QPalette::Base, QColor (Qt::blue).lighter (180 ));
@@ -1162,13 +1242,27 @@ void MainWindow::changeEvent(QEvent* event) {
11621242 }
11631243 QMainWindow::changeEvent (event);
11641244 if (eventType == QEvent::ThemeChange) {
1165- bool darkMode = isSystemInDarkMode ();
1166- if (darkMode != m_isInDarkMode) {
1167- darkModeSwitch (darkMode);
1168- }
1245+ applyThemeFromPreference ();
11691246 }
11701247}
11711248
1249+ void MainWindow::setThemePreference (int index) {
1250+ const auto pref = static_cast <ThemePreference>(index);
1251+
1252+ if (ui && ui->comboTheme && ui->comboTheme ->currentIndex () != index) {
1253+ QSignalBlocker blocker (ui->comboTheme );
1254+ ui->comboTheme ->setCurrentIndex (index);
1255+ }
1256+
1257+ m_themePreference = pref;
1258+
1259+ if (m_config && opts.useSettings ) {
1260+ m_config->setValue (SETTING_UI_THEME, index);
1261+ }
1262+
1263+ applyThemeFromPreference ();
1264+ }
1265+
11721266void MainWindow::showEvent (QShowEvent *e) {
11731267 if (!m_setup) {
11741268 e->ignore ();
@@ -1486,6 +1580,7 @@ void MainWindow::resetGui() {
14861580 m_config->remove (SETTING_WINDOW_STATUSBAR);
14871581 m_config->remove (SETTING_WINDOW_SEPARATOR);
14881582 m_config->remove (SETTING_UI_EDIT_MODE);
1583+ m_config->remove (SETTING_UI_THEME);
14891584 m_needReload = true ;
14901585 close ();
14911586}
0 commit comments