Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 84 additions & 14 deletions gui/qt/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <QtCore/QProcess>
#include <QtCore/QRegularExpression>
#include <QtGui/QFont>
#include <QtGui/QPalette>
#include <QtGui/QColor>
#include <QtGui/QWindow>
#include <QtGui/QDesktopServices>
#include <QtGui/QClipboard>
Expand All @@ -36,11 +38,15 @@
#include <QtWidgets/QComboBox>
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QStyle>
#include <QtGui/QStyleHints>
#include <QtWidgets/QStyleFactory>
#include <QtNetwork/QNetworkReply>
#include <QtCore/QSignalBlocker>
#include <QtCore/QScopedValueRollback>
#include <fstream>
#include <iostream>
#include <cmath>

#ifdef Q_OS_MACOS
# include "os/mac/kdmactouchbar.h"
#endif
Expand All @@ -56,6 +62,8 @@
# include <unistd.h>
#endif

using namespace Qt::StringLiterals;

MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new Ui::MainWindow), opts(cliOpts) {
keypadBridge = new QtKeypadBridge(this); // This must be before setupUi for some reason >.>

Expand All @@ -70,8 +78,13 @@

ui->setupUi(this);

m_styleForMode[0] = m_styleForMode[1] = QApplication::style()->name();
darkModeSwitch(isSystemInDarkMode());
{
QSignalBlocker blocker(ui->comboTheme);
ui->comboTheme->setCurrentIndex(static_cast<int>(m_themePreference));
}
connect(ui->comboTheme, &QComboBox::currentIndexChanged, this, &MainWindow::setThemePreference);

applyThemeFromPreference();

setStyleSheet(QStringLiteral("QMainWindow::separator{ width: 0px; height: 0px; }"));

Expand Down Expand Up @@ -160,9 +173,9 @@

// debug actions
connect(ui->buttonRun, &QPushButton::clicked, this, &MainWindow::debugToggle);
connect(ui->checkADLDisasm, &QCheckBox::stateChanged, this, &MainWindow::disasmUpdate);

Check warning on line 176 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 176 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 176 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 176 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
connect(ui->checkADLStack, &QCheckBox::stateChanged, this, &MainWindow::stackUpdate);

Check warning on line 177 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 177 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 177 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 177 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
connect(ui->checkADL, &QCheckBox::stateChanged, [this]{ disasmUpdate(); stackUpdate(); });

Check warning on line 178 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 178 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 178 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 178 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
connect(ui->buttonAddPort, &QPushButton::clicked, this, &MainWindow::portAddSlot);
connect(ui->buttonAddBreakpoint, &QPushButton::clicked, this, &MainWindow::breakAddSlot);
connect(ui->buttonAddWatchpoint, &QPushButton::clicked, this, &MainWindow::watchAddSlot);
Expand Down Expand Up @@ -378,7 +391,7 @@
#ifdef PNG_WRITE_APNG_SUPPORTED
connect(ui->buttonRecordAnimated, &QPushButton::clicked, this, &MainWindow::recordAnimated);
connect(ui->apngSkip, &QSlider::valueChanged, this, &MainWindow::setFrameskip);
connect(ui->checkOptimizeRecording, &QCheckBox::stateChanged, this, &MainWindow::setOptimizeRecord);

Check warning on line 394 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 394 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 394 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 394 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
#else
ui->actionRecordAnimated->setEnabled(false);
ui->buttonRecordAnimated->setEnabled(false);
Expand All @@ -393,13 +406,13 @@
connect(ui->actionReportBug, &QAction::triggered, []{ QDesktopServices::openUrl(QUrl("https://github.com/CE-Programming/CEmu/issues")); });

// other gui actions
connect(ui->checkAllowGroupDrag, &QCheckBox::stateChanged, this, &MainWindow::setDockGroupDrag);

Check warning on line 409 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 409 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 409 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 409 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
connect(ui->buttonRunSetup, &QPushButton::clicked, this, &MainWindow::runSetup);
connect(ui->scaleLCD, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &MainWindow::setLcdScale);
connect(ui->upscaleLCD, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::setLcdUpscale);
connect(ui->fullscreenLCD, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::setLcdFullscreen);
connect(ui->guiSkip, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &MainWindow::setGuiSkip);
connect(ui->checkSkin, &QCheckBox::stateChanged, this, &MainWindow::setSkinToggle);

Check warning on line 415 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 415 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 415 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]

Check warning on line 415 in gui/qt/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / Build: ubuntu-22.04 - x64-Dynamic

‘void QCheckBox::stateChanged(int)’ is deprecated: Use checkStateChanged() instead [-Wdeprecated-declarations]
connect(ui->comboBoxAsicRev, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::setAsicRevision);
connect(ui->checkPythonEdition, &QCheckBox::stateChanged, this, &MainWindow::setPythonEdition);
connect(ui->checkKeypadGhosting, &QCheckBox::stateChanged, this, &MainWindow::setKeypadGhosting);
Expand Down Expand Up @@ -597,6 +610,7 @@
}

setAutoUpdates(m_config->value(SETTING_AUTOUPDATE, CEMU_RELEASE).toBool());
setThemePreference(m_config->value(SETTING_UI_THEME, static_cast<int>(ThemePreference::System)).toInt());
checkVersion();

#ifdef Q_OS_WIN
Expand Down Expand Up @@ -1129,14 +1143,52 @@
}
}

void MainWindow::darkModeSwitch(bool darkMode) {
QApplication::setStyle(m_styleForMode[darkMode]);
if (darkMode != isRunningInDarkMode()) {
m_styleForMode[darkMode] = QStringLiteral("fusion");
QApplication::setStyle(m_styleForMode[darkMode]);
darkMode = isRunningInDarkMode();
void MainWindow::applyThemeFromPreference() {
Qt::ColorScheme scheme = Qt::ColorScheme::Unknown;
bool explicitScheme = false;
switch (m_themePreference) {
case ThemePreference::System:
scheme = Qt::ColorScheme::Unknown;
break;
case ThemePreference::Light:
scheme = Qt::ColorScheme::Light;
explicitScheme = true;
break;
case ThemePreference::Dark:
scheme = Qt::ColorScheme::Dark;
explicitScheme = true;
break;
}
qApp->styleHints()->setColorScheme(scheme);

#if defined(Q_OS_WIN)
if (explicitScheme) {
if (QStyle *fusion = QStyleFactory::create("Fusion"_L1)) {
QApplication::setStyle(fusion);
}
} else {
const auto available = QStyleFactory::keys();
if (available.contains("WindowsVista"_L1, Qt::CaseInsensitive)) {
if (QStyle *vista = QStyleFactory::create("WindowsVista"_L1)) {
QApplication::setStyle(vista);
}
}
}
#elif defined(Q_OS_MACOS)
Q_UNUSED(explicitScheme);
#else
if (explicitScheme) {
if (QStyle *fusion = QStyleFactory::create("Fusion"_L1)) {
QApplication::setStyle(fusion);
}
}
#endif

const bool dark = (qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark);
darkModeSwitch(dark);
}

void MainWindow::darkModeSwitch(bool darkMode) {
m_isInDarkMode = darkMode;
if (darkMode) {
m_cBack.setColor(QPalette::Base, QColor(Qt::blue).lighter(180));
Expand All @@ -1160,12 +1212,29 @@
translateSwitch(QLocale::system());
}
QMainWindow::changeEvent(event);
if (eventType == QEvent::ThemeChange) {
bool darkMode = isSystemInDarkMode();
if (darkMode != m_isInDarkMode) {
darkModeSwitch(darkMode);
}
if (eventType == QEvent::ThemeChange ||
eventType == QEvent::ApplicationPaletteChange ||
eventType == QEvent::PaletteChange) {
const bool dark = (qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark);
darkModeSwitch(dark);
}
}

void MainWindow::setThemePreference(int index) {
const auto pref = static_cast<ThemePreference>(index);

if (ui && ui->comboTheme && ui->comboTheme->currentIndex() != index) {
QSignalBlocker blocker(ui->comboTheme);
ui->comboTheme->setCurrentIndex(index);
}

m_themePreference = pref;

if (m_config && opts.useSettings) {
m_config->setValue(SETTING_UI_THEME, index);
}

applyThemeFromPreference();
}

void MainWindow::showEvent(QShowEvent *e) {
Expand Down Expand Up @@ -1485,6 +1554,7 @@
m_config->remove(SETTING_WINDOW_STATUSBAR);
m_config->remove(SETTING_WINDOW_SEPARATOR);
m_config->remove(SETTING_UI_EDIT_MODE);
m_config->remove(SETTING_UI_THEME);
m_needReload = true;
close();
}
Expand Down
17 changes: 16 additions & 1 deletion gui/qt/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <QtCore/QTimer>
#include <QtCore/QPointer>
#include <QtGui/QShortcut>
#include <QtGui/QPalette>
#include <QtGui/QTextCursor>
#include <QtCore/QTranslator>
#include <QtCore/QStandardPaths>
Expand All @@ -39,6 +40,9 @@
QT_BEGIN_NAMESPACE
class QButtonGroup;
class QLocale;
class QEvent;
class QCloseEvent;
class QObject;
QT_END_NAMESPACE

#ifdef LIBUSB_SUPPORT
Expand Down Expand Up @@ -100,6 +104,7 @@ private slots:
#ifdef LIBUSB_SUPPORT
void usbConnectPhysical(QVariant userData);
#endif
void setThemePreference(int index);

protected:
virtual void changeEvent(QEvent* event) override;
Expand Down Expand Up @@ -228,6 +233,12 @@ private slots:
FULLSCREEN_LCD
};

enum class ThemePreference {
System = 0,
Light = 1,
Dark = 2
};

// emu keypresses
void sendEmuKey(uint16_t key);
void sendEmuLetterKey(char letter);
Expand Down Expand Up @@ -258,6 +269,7 @@ private slots:
void translateExtras(int init);
void translateSwitch(const QLocale &locale);

void applyThemeFromPreference();
// dark mode
void darkModeSwitch(bool darkMode);

Expand Down Expand Up @@ -769,6 +781,8 @@ private slots:
int m_fullscreen = FULLSCREEN_NONE;
uint32_t m_runUntilAddr;

ThemePreference m_themePreference = ThemePreference::System;

QPushButton *m_btnCancelTranser;
QProgressBar *m_progressBar;
QStringList m_docksMemory;
Expand All @@ -790,7 +804,7 @@ private slots:
bool m_timerEmuTriggered = false;
bool m_timerFpsTriggered = false;

QString m_styleForMode[2];


static const char *m_varExtensions[];

Expand Down Expand Up @@ -856,6 +870,7 @@ private slots:
static const QString SETTING_STATUS_INTERVAL;
static const QString SETTING_FIRST_RUN;
static const QString SETTING_UI_EDIT_MODE;
static const QString SETTING_UI_THEME;
static const QString SETTING_PAUSE_FOCUS;
static const QString SETTING_SAVE_ON_CLOSE;
static const QString SETTING_RESTORE_ON_OPEN;
Expand Down
43 changes: 42 additions & 1 deletion gui/qt/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7682,7 +7682,7 @@
</item>
</widget>
</item>
<item row="0" column="8">
<item row="0" column="10">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand Down Expand Up @@ -7771,6 +7771,47 @@
</property>
</spacer>
</item>
<item row="0" column="8">
<widget class="QLabel" name="labelTheme">
<property name="text">
<string>Theme:</string>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QComboBox" name="comboTheme">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<item>
<property name="text">
<string>System Default</string>
</property>
</item>
<item>
<property name="text">
<string>Light</string>
</property>
</item>
<item>
<property name="text">
<string>Dark</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
2 changes: 2 additions & 0 deletions gui/qt/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const QString MainWindow::SETTING_ROM_PATH = QStringLiteral("ro
const QString MainWindow::SETTING_STATUS_INTERVAL = QStringLiteral("status_interval");
const QString MainWindow::SETTING_FIRST_RUN = QStringLiteral("first_run");
const QString MainWindow::SETTING_UI_EDIT_MODE = QStringLiteral("ui_edit_mode");
const QString MainWindow::SETTING_UI_THEME = QStringLiteral("ui_theme");
const QString MainWindow::SETTING_PAUSE_FOCUS = QStringLiteral("pause_on_focus_change");
const QString MainWindow::SETTING_SAVE_ON_CLOSE = QStringLiteral("save_on_close");
const QString MainWindow::SETTING_RESTORE_ON_OPEN = QStringLiteral("restore_on_open");
Expand Down Expand Up @@ -1277,6 +1278,7 @@ void MainWindow::saveSettings() {
m_config->setValue(SETTING_WINDOW_VISUALIZER_CONFIG, m_docksVisualizerConfig);
m_config->setValue(SETTING_WINDOW_KEYHISTORY_DOCKS, m_docksKeyHistory);
m_config->setValue(SETTING_WINDOW_KEYHISTORY_CONFIG, QVariant::fromValue(m_docksKeyHistorySize));
m_config->setValue(SETTING_UI_THEME, static_cast<int>(m_themePreference));

// Disassembly Goto history
{
Expand Down
Loading