Qt: Add log window

This commit is contained in:
Stenzek 2024-01-11 19:38:28 +10:00 committed by Connor McLaughlin
parent e908bbfae6
commit ea98203ac5
11 changed files with 549 additions and 19 deletions

View File

@ -21,6 +21,8 @@ target_sources(pcsx2-qt PRIVATE
DisplayWidget.cpp
DisplayWidget.h
EarlyHardwareCheck.cpp
LogWindow.cpp
LogWindow.h
MainWindow.cpp
MainWindow.h
MainWindow.ui

399
pcsx2-qt/LogWindow.cpp Normal file
View File

@ -0,0 +1,399 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
#include "LogWindow.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
#include <QtCore/QLatin1StringView>
#include <QtCore/QUtf8StringView>
#include <QtGui/QIcon>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QScrollBar>
#include <mutex>
// Need a lock so the other threads don't try to write to a deleting window.
LogWindow* g_log_window;
static std::mutex s_log_mutex;
static LOGLEVEL GetWindowLogLevel()
{
#ifdef _DEBUG
return LOGLEVEL_DEBUG;
#else
return (IsDevBuild || Host::GetBaseBoolSettingValue("Logging", "EnableVerbose", false)) ? LOGLEVEL_DEV : LOGLEVEL_INFO;
#endif
}
LogWindow::LogWindow(bool attach_to_main)
: QMainWindow()
, m_attached_to_main_window(attach_to_main)
{
restoreSize();
createUi();
Log::SetHostOutputLevel(GetWindowLogLevel(), &LogWindow::logCallback);
}
LogWindow::~LogWindow()
{
Log::SetHostOutputLevel(LOGLEVEL_NONE, nullptr);
}
void LogWindow::updateSettings()
{
std::unique_lock lock(s_log_mutex);
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !QtHost::InNoGUIMode();
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
const bool curr_enabled = Log::IsHostOutputEnabled();
if (new_enabled == curr_enabled)
{
if (g_log_window && g_log_window->m_attached_to_main_window != attach_to_main)
{
g_log_window->m_attached_to_main_window = attach_to_main;
if (attach_to_main)
g_log_window->reattachToMainWindow();
}
// Update level.
if (new_enabled)
Log::SetHostOutputLevel(GetWindowLogLevel(), &LogWindow::logCallback);
return;
}
if (new_enabled)
{
g_log_window = new LogWindow(attach_to_main);
if (attach_to_main && g_main_window && g_main_window->isVisible())
g_log_window->reattachToMainWindow();
g_log_window->show();
}
else if (g_log_window)
{
g_log_window->m_destroying = true;
g_log_window->close();
g_log_window->deleteLater();
g_log_window = nullptr;
}
}
void LogWindow::destroy()
{
std::unique_lock lock(s_log_mutex);
if (!g_log_window)
return;
g_log_window->m_destroying = true;
g_log_window->close();
g_log_window->deleteLater();
g_log_window = nullptr;
}
void LogWindow::reattachToMainWindow()
{
// Skip when maximized.
if (g_main_window->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen))
return;
resize(width(), g_main_window->height());
const QPoint new_pos = g_main_window->pos() + QPoint(g_main_window->width() + 10, 0);
if (pos() != new_pos)
move(new_pos);
}
void LogWindow::updateWindowTitle()
{
QString title;
const QString& serial = QtHost::GetCurrentGameSerial();
if (QtHost::IsVMValid() && !serial.isEmpty())
{
const QFileInfo fi(QtHost::GetCurrentGamePath());
title = tr("Log Window - %1 [%2]").arg(serial).arg(fi.fileName());
}
else
{
title = tr("Log Window");
}
setWindowTitle(title);
}
void LogWindow::createUi()
{
setWindowIcon(QtHost::GetAppIcon());
updateWindowTitle();
QAction* action;
QMenuBar* menu = new QMenuBar(this);
setMenuBar(menu);
QMenu* log_menu = menu->addMenu("&Log");
action = log_menu->addAction(tr("&Clear"));
connect(action, &QAction::triggered, this, &LogWindow::onClearTriggered);
action = log_menu->addAction(tr("&Save..."));
connect(action, &QAction::triggered, this, &LogWindow::onSaveTriggered);
log_menu->addSeparator();
action = log_menu->addAction(tr("Cl&ose"));
connect(action, &QAction::triggered, this, &LogWindow::close);
QMenu* settings_menu = menu->addMenu(tr("&Settings"));
#if 0
// TODO: These are duplicated with the main window...
action = settings_menu->addAction(tr("Log To &System Console"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableSystemConsole", false);
action = settings_menu->addAction(tr("Log To &Debug Console"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableDebugConsole", false);
action = settings_menu->addAction(tr("Log To &File"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableFileLogging", false);
settings_menu->addSeparator();
#endif
action = settings_menu->addAction(tr("Attach To &Main Window"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "AttachLogWindowToMainWindow", true);
action = settings_menu->addAction(tr("Show &Timestamps"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableTimestamps", true);
settings_menu->addSeparator();
// TODO: Log Level
m_text = new QPlainTextEdit(this);
m_text->setReadOnly(true);
m_text->setUndoRedoEnabled(false);
m_text->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
m_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_text->setWordWrapMode(QTextOption::WrapAnywhere);
#if defined(_WIN32)
QFont font("Consolas");
font.setPointSize(10);
#elif defined(__APPLE__)
QFont font("Monaco");
font.setPointSize(11);
#else
QFont font("Monospace");
font.setStyleHint(QFont::TypeWriter);
#endif
m_text->setFont(font);
setCentralWidget(m_text);
}
void LogWindow::onClearTriggered()
{
m_text->clear();
}
void LogWindow::onSaveTriggered()
{
const QString path = QFileDialog::getSaveFileName(this, tr("Select Log File"), QString(), tr("Log Files (*.txt)"));
if (path.isEmpty())
return;
QFile file(path);
if (!file.open(QFile::WriteOnly | QFile::Text))
{
QMessageBox::critical(this, tr("Error"), tr("Failed to open file for writing."));
return;
}
file.write(m_text->toPlainText().toUtf8());
file.close();
appendMessage(LOGLEVEL_INFO, Color_Default, tr("Log was written to %1.\n").arg(path));
}
void LogWindow::logCallback(LOGLEVEL level, ConsoleColors color, std::string_view message)
{
std::unique_lock lock(s_log_mutex);
if (!g_log_window)
return;
// I don't like the memory allocations here either...
QString qmessage;
qmessage.reserve(message.length() + 1);
qmessage.append(QUtf8StringView(message.data(), message.length()));
qmessage.append(QChar('\n'));
if (g_emu_thread->isOnUIThread())
{
g_log_window->appendMessage(static_cast<u32>(level), static_cast<u32>(color), qmessage);
}
else
{
QMetaObject::invokeMethod(g_log_window, "appendMessage", Qt::QueuedConnection,
Q_ARG(quint32, static_cast<u32>(level)), Q_ARG(quint32, static_cast<u32>(color)),
Q_ARG(const QString&, qmessage));
}
}
void LogWindow::closeEvent(QCloseEvent* event)
{
Log::SetHostOutputLevel(LOGLEVEL_NONE, nullptr);
// Save size when actually closing, disable ourselves if the user closed us.
if (m_destroying)
{
saveSize();
}
else
{
Host::SetBaseBoolSettingValue("Logging", "EnableLogWindow", false);
Host::CommitBaseSettingChanges();
}
QMainWindow::closeEvent(event);
}
void LogWindow::appendMessage(quint32 level, quint32 color, const QString& message)
{
QTextCursor temp_cursor = m_text->textCursor();
QScrollBar* scrollbar = m_text->verticalScrollBar();
const bool cursor_at_end = temp_cursor.atEnd();
const bool scroll_at_end = scrollbar->sliderPosition() == scrollbar->maximum();
temp_cursor.movePosition(QTextCursor::End);
{
static constexpr const QColor qcolors[2][ConsoleColors_Count] = {
// Light theme
{
QColor(0, 0, 0), // Color_Default
QColor(0, 0, 0), // Color_Black
QColor(128, 0, 0), // Color_Red
QColor(0, 128, 0), // Color_Green
QColor(0, 0, 128), // Color_Blue
QColor(160, 0, 160), // Color_Magenta
QColor(160, 120, 0), // Color_Orange
QColor(108, 108, 108), // Color_Gray
QColor(128, 180, 180), // Color_Cyan
QColor(180, 180, 128), // Color_Yellow
QColor(160, 160, 160), // Color_White
QColor(0, 0, 0), // Color_StrongBlack
QColor(128, 0, 0), // Color_StrongRed
QColor(0, 128, 0), // Color_StrongGreen
QColor(0, 0, 128), // Color_StrongBlue
QColor(160, 0, 160), // Color_StrongMagenta
QColor(160, 120, 0), // Color_StrongOrange
QColor(108, 108, 108), // Color_StrongGray
QColor(128, 180, 180), // Color_StrongCyan
QColor(180, 180, 128), // Color_StrongYellow
QColor(160, 160, 160), // Color_StrongWhite
},
// Dark theme
{
QColor(208, 208, 208), // Color_Default
QColor(255, 255, 255), // Color_Black
QColor(180, 0, 0), // Color_Red
QColor(0, 160, 0), // Color_Green
QColor(32, 32, 204), // Color_Blue
QColor(160, 0, 160), // Color_Magenta
QColor(160, 120, 0), // Color_Orange
QColor(128, 128, 128), // Color_Gray
QColor(128, 180, 180), // Color_Cyan
QColor(180, 180, 128), // Color_Yellow
QColor(160, 160, 160), // Color_White
QColor(255, 255, 255), // Color_StrongBlack
QColor(180, 0, 0), // Color_StrongRed
QColor(0, 160, 0), // Color_StrongGreen
QColor(32, 32, 204), // Color_StrongBlue
QColor(160, 0, 160), // Color_StrongMagenta
QColor(160, 120, 0), // Color_StrongOrange
QColor(128, 128, 128), // Color_StrongGray
QColor(128, 180, 180), // Color_StrongCyan
QColor(180, 180, 128), // Color_StrongYellow
QColor(160, 160, 160), // Color_StrongWhite
},
};
static constexpr const QColor timestamp_color = QColor(0xcc, 0xcc, 0xcc);
QTextCharFormat format = temp_cursor.charFormat();
if (Log::AreTimestampsEnabled())
{
const float message_time = Log::GetCurrentMessageTime();
const QString qtimestamp = QStringLiteral("[%1] ").arg(message_time, 10, 'f', 4);
format.setForeground(QBrush(timestamp_color));
temp_cursor.setCharFormat(format);
temp_cursor.insertText(qtimestamp);
}
const bool dark = static_cast<u32>(QtHost::IsDarkApplicationTheme());
// message has \n already
format.setForeground(QBrush(qcolors[static_cast<u32>(dark)][color]));
temp_cursor.setCharFormat(format);
temp_cursor.insertText(message);
}
if (cursor_at_end)
{
if (scroll_at_end)
{
m_text->setTextCursor(temp_cursor);
scrollbar->setSliderPosition(scrollbar->maximum());
}
else
{
// Can't let changing the cursor affect the scroll bar...
const int pos = scrollbar->sliderPosition();
m_text->setTextCursor(temp_cursor);
scrollbar->setSliderPosition(pos);
}
}
}
void LogWindow::saveSize()
{
const int current_width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);
const int current_height = Host::GetBaseIntSettingValue("UI", "LogWindowHeight", DEFAULT_HEIGHT);
const QSize wsize = size();
bool changed = false;
if (current_width != wsize.width())
{
Host::SetBaseIntSettingValue("UI", "LogWindowWidth", wsize.width());
changed = true;
}
if (current_height != wsize.height())
{
Host::SetBaseIntSettingValue("UI", "LogWindowHeight", wsize.height());
changed = true;
}
if (changed)
Host::CommitBaseSettingChanges();
}
void LogWindow::restoreSize()
{
const int width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);
const int height = Host::GetBaseIntSettingValue("UI", "LogWindowHeight", DEFAULT_HEIGHT);
resize(width, height);
}

54
pcsx2-qt/LogWindow.h Normal file
View File

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
#pragma once
#include "common/Console.h"
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPlainTextEdit>
class LogWindow : public QMainWindow
{
Q_OBJECT
public:
LogWindow(bool attach_to_main);
~LogWindow();
static void updateSettings();
static void destroy();
__fi bool isAttachedToMainWindow() const { return m_attached_to_main_window; }
void reattachToMainWindow();
void updateWindowTitle();
private:
void createUi();
static void logCallback(LOGLEVEL level, ConsoleColors color, std::string_view message);
protected:
void closeEvent(QCloseEvent* event);
private Q_SLOTS:
void onClearTriggered();
void onSaveTriggered();
void appendMessage(quint32 level, quint32 color, const QString& message);
private:
static constexpr int DEFAULT_WIDTH = 750;
static constexpr int DEFAULT_HEIGHT = 400;
void saveSize();
void restoreSize();
QPlainTextEdit* m_text;
QMenu* m_level_menu;
bool m_attached_to_main_window = true;
bool m_destroying = false;
};
extern LogWindow* g_log_window;

View File

@ -7,6 +7,7 @@
#include "DisplayWidget.h"
#include "GameList/GameListRefreshThread.h"
#include "GameList/GameListWidget.h"
#include "LogWindow.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
@ -255,7 +256,7 @@ void MainWindow::setupAdditionalUi()
#ifdef ENABLE_RAINTEGRATION
if (Achievements::IsUsingRAIntegration())
{
QMenu* raMenu = new QMenu(QStringLiteral("RAIntegration"), m_ui.menu_Tools);
QMenu* raMenu = new QMenu(QStringLiteral("RAIntegration"), m_ui.menuTools);
connect(raMenu, &QMenu::aboutToShow, this, [this, raMenu]() {
raMenu->clear();
@ -279,7 +280,7 @@ void MainWindow::setupAdditionalUi()
[id = id]() { Host::RunOnCPUThread([id]() { Achievements::RAIntegration::ActivateMenuItem(id); }, false); });
}
});
m_ui.menu_Tools->insertMenu(m_ui.menuInput_Recording->menuAction(), raMenu);
m_ui.menuTools->insertMenu(m_ui.menuInputRecording->menuAction(), raMenu);
}
#endif
}
@ -366,6 +367,14 @@ void MainWindow::connectSignals()
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
#ifdef _WIN32
// Debug console only exists on Windows.
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableDebugConsole, "Logging", "EnableDebugConsole", false);
#else
m_ui.menuTools->removeAction(m_ui.actionEnableDebugConsole);
m_ui.actionEnableDebugConsole->deleteLater();
m_ui.actionEnableDebugConsole = nullptr;
#endif
#ifndef PCSX2_DEVBUILD
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableVerboseLogging, "Logging", "EnableVerbose", false);
#else
@ -375,6 +384,7 @@ void MainWindow::connectSignals()
#endif
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogWindow, "Logging", "EnableLogWindow", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableFileLogging, "Logging", "EnableFileLogging", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogTimestamps, "Logging", "EnableTimestamps", true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableCDVDVerboseReads, "EmuCore", "CdvdVerboseReads", false);
@ -508,6 +518,11 @@ void MainWindow::recreate()
new_main_window->show();
deleteLater();
// Recreate log window as well. Then make sure we're still on top.
LogWindow::updateSettings();
new_main_window->raise();
new_main_window->activateWindow();
// Reload the sources we just closed.
g_emu_thread->reloadInputSources();
@ -579,6 +594,8 @@ void MainWindow::destroySubWindows()
}
SettingsWindow::closeGamePropertiesDialogs();
LogWindow::destroy();
}
void MainWindow::onScreenshotActionTriggered()
@ -920,6 +937,9 @@ void MainWindow::updateWindowTitle()
if (container->windowTitle() != display_title)
container->setWindowTitle(display_title);
}
if (g_log_window)
g_log_window->updateWindowTitle();
}
void MainWindow::updateWindowState(bool force_visible)
@ -1192,6 +1212,8 @@ void MainWindow::checkForSettingChanges()
updateDisplayWidgetCursor();
updateWindowState();
LogWindow::updateSettings();
}
std::optional<WindowInfo> MainWindow::getWindowInfo()
@ -2041,6 +2063,22 @@ void MainWindow::dropEvent(QDropEvent* event)
}
}
void MainWindow::moveEvent(QMoveEvent* event)
{
QMainWindow::moveEvent(event);
if (g_log_window && g_log_window->isAttachedToMainWindow())
g_log_window->reattachToMainWindow();
}
void MainWindow::resizeEvent(QResizeEvent* event)
{
QMainWindow::resizeEvent(event);
if (g_log_window && g_log_window->isAttachedToMainWindow())
g_log_window->reattachToMainWindow();
}
void MainWindow::registerForDeviceNotifications()
{
#ifdef _WIN32

View File

@ -197,15 +197,14 @@ protected:
void changeEvent(QEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent* event) override;
void moveEvent(QMoveEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
#ifdef _WIN32
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
#endif
private:
static void setStyleFromSettings();
static void setIconThemeFromStyle();
void setupAdditionalUi();
void connectSignals();
void createRendererSwitchMenu();

View File

@ -146,7 +146,7 @@
<addaction name="actionEnableIOPConsoleLogging"/>
<addaction name="actionEnableCDVDVerboseReads"/>
</widget>
<widget class="QMenu" name="menu_View">
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
@ -176,11 +176,11 @@
<addaction name="actionGridViewZoomOut"/>
<addaction name="actionGridViewRefreshCovers"/>
</widget>
<widget class="QMenu" name="menu_Tools">
<widget class="QMenu" name="menuTools">
<property name="title">
<string>&amp;Tools</string>
</property>
<widget class="QMenu" name="menuInput_Recording">
<widget class="QMenu" name="menuInputRecording">
<property name="title">
<string>Input Recording</string>
</property>
@ -206,10 +206,12 @@
<addaction name="actionReloadPatches"/>
<addaction name="separator"/>
<addaction name="actionToggleSoftwareRendering"/>
<addaction name="menuInput_Recording"/>
<addaction name="menuInputRecording"/>
<addaction name="actionToolsVideoCapture"/>
<addaction name="separator"/>
<addaction name="actionEnableSystemConsole"/>
<addaction name="actionEnableDebugConsole"/>
<addaction name="actionEnableLogWindow"/>
<addaction name="actionEnableFileLogging"/>
<addaction name="actionEnableVerboseLogging"/>
<addaction name="separator"/>
@ -219,8 +221,8 @@
</widget>
<addaction name="menuSystem"/>
<addaction name="menuSettings"/>
<addaction name="menu_View"/>
<addaction name="menu_Tools"/>
<addaction name="menuView"/>
<addaction name="menuTools"/>
<addaction name="menuDebug"/>
<addaction name="menuHelp"/>
</widget>
@ -901,6 +903,22 @@
<string>Enable System Console</string>
</property>
</action>
<action name="actionEnableDebugConsole">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable Debug Console</string>
</property>
</action>
<action name="actionEnableLogWindow">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable Log Window</string>
</property>
</action>
<action name="actionEnableVerboseLogging">
<property name="checkable">
<bool>true</bool>

View File

@ -4,6 +4,7 @@
#include "AutoUpdaterDialog.h"
#include "DisplayWidget.h"
#include "GameList/GameListWidget.h"
#include "LogWindow.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtProgressCallback.h"
@ -101,11 +102,6 @@ EmuThread::EmuThread(QThread* ui_thread)
EmuThread::~EmuThread() = default;
bool EmuThread::isOnEmuThread() const
{
return QThread::currentThread() == this;
}
void EmuThread::start()
{
pxAssertRel(!g_emu_thread, "Emu thread does not exist");
@ -1918,6 +1914,9 @@ int main(int argc, char* argv[])
// Set theme before creating any windows.
QtHost::UpdateApplicationTheme();
// Start logging early.
LogWindow::updateSettings();
// Start up the CPU thread.
QtHost::HookSignals();
EmuThread::start();
@ -1942,7 +1941,11 @@ int main(int argc, char* argv[])
// Don't bother showing the window in no-gui mode.
if (!s_nogui_mode)
{
g_main_window->show();
g_main_window->raise();
g_main_window->activateWindow();
}
// Initialize big picture mode if requested.
if (s_start_fullscreen_ui)

View File

@ -63,7 +63,8 @@ public:
__fi bool isSurfaceless() const { return m_is_surfaceless; }
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui; }
bool isOnEmuThread() const;
__fi bool isOnEmuThread() const { return (QThread::currentThread() == this); }
__fi bool isOnUIThread() const { return (QThread::currentThread() == m_ui_thread); }
bool shouldRenderToMain() const;
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
@ -237,6 +238,9 @@ namespace QtHost
/// Sets application theme according to settings.
void UpdateApplicationTheme();
/// Returns true if the application theme is using dark colours.
bool IsDarkApplicationTheme();
/// Sets the icon theme, based on the current style (light/dark).
void SetIconThemeFromStyle();

View File

@ -476,9 +476,14 @@ void QtHost::SetStyleFromSettings()
}
}
void QtHost::SetIconThemeFromStyle()
bool QtHost::IsDarkApplicationTheme()
{
QPalette palette = qApp->palette();
bool dark = palette.windowText().color().value() > palette.window().color().value();
return (palette.windowText().color().value() > palette.window().color().value());
}
void QtHost::SetIconThemeFromStyle()
{
const bool dark = IsDarkApplicationTheme();
QIcon::setThemeName(dark ? QStringLiteral("white") : QStringLiteral("black"));
}

View File

@ -89,6 +89,7 @@
<ItemGroup>
<ClCompile Include="ColorPickerButton.cpp" />
<ClCompile Include="EarlyHardwareCheck.cpp" />
<ClCompile Include="LogWindow.cpp" />
<ClCompile Include="QtProgressCallback.cpp" />
<ClCompile Include="Settings\DebugSettingsWidget.cpp" />
<ClCompile Include="Settings\FolderSettingsWidget.cpp" />
@ -172,6 +173,7 @@
<QtMoc Include="Settings\DEV9UiCommon.h" />
<QtMoc Include="QtProgressCallback.h" />
<QtMoc Include="ColorPickerButton.h" />
<QtMoc Include="LogWindow.h" />
<ClInclude Include="Settings\ControllerSettingWidgetBinder.h" />
<QtMoc Include="Settings\FolderSettingsWidget.h" />
<QtMoc Include="Settings\DebugSettingsWidget.h" />
@ -262,6 +264,7 @@
<ClCompile Include="$(IntDir)moc_ColorPickerButton.cpp" />
<ClCompile Include="$(IntDir)moc_CoverDownloadDialog.cpp" />
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp" />
<ClCompile Include="$(IntDir)moc_LogWindow.cpp" />
<ClCompile Include="$(IntDir)moc_MainWindow.cpp" />
<ClCompile Include="$(IntDir)moc_QtHost.cpp" />
<ClCompile Include="$(IntDir)moc_QtProgressCallback.cpp" />

View File

@ -342,6 +342,10 @@
<ClCompile Include="$(IntDir)moc_SetupWizardDialog.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="LogWindow.cpp" />
<ClCompile Include="$(IntDir)moc_LogWindow.cpp">
<Filter>moc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
@ -499,6 +503,7 @@
<QtMoc Include="Settings\GamePatchSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="LogWindow.h" />
</ItemGroup>
<ItemGroup>
<QtResource Include="resources\resources.qrc">