Browse Source

improved frontend abstractor, fix UI settings save

Signed-off-by: crueter <crueter@eden-emu.dev>
pull/3016/head
crueter 2 weeks ago
parent
commit
03b77b466d
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 1
      src/CMakeLists.txt
  2. 2
      src/Eden/Config/pages/general/UiGameListPage.qml
  3. 6
      src/Eden/Config/pages/global/GlobalGeneralPage.qml
  4. 70
      src/Eden/Interface/SettingsInterface.h
  5. 1
      src/Eden/Native/CMakeLists.txt
  6. 40
      src/Eden/Native/LibQtCommon.cpp
  7. 3
      src/frontend_common/config.cpp
  8. 8
      src/qt_common/CMakeLists.txt
  9. 37
      src/qt_common/abstract/frontend.h
  10. 12
      src/qt_common/config/qt_config.cpp
  11. 3
      src/qt_common/externals/CMakeLists.txt
  12. 4
      src/qt_common/externals/cpmfile.json
  13. 8
      src/qt_common/qt_common.cpp
  14. 8
      src/qt_common/qt_common.h
  15. 38
      src/qt_common/util/content.cpp
  16. 2
      src/qt_common/util/fs.cpp
  17. 15
      src/qt_common/util/game.cpp
  18. 4
      src/qt_common/util/path.cpp
  19. 1
      src/yuzu/CMakeLists.txt
  20. 29
      src/yuzu/libqt_common.cpp
  21. 2
      src/yuzu/util/util.cpp

1
src/CMakeLists.txt

@ -245,6 +245,7 @@ if (ENABLE_QT)
endif() endif()
if (ENABLE_QT_QML) if (ENABLE_QT_QML)
set(QML_IMPORT_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING "")
add_subdirectory(Eden) add_subdirectory(Eden)
endif() endif()

2
src/Eden/Config/pages/general/UiGameListPage.qml

@ -1,6 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@ -15,7 +14,6 @@ PageScrollView {
ui.apply() ui.apply()
} }
// TODO: language, theme
ColumnLayout { ColumnLayout {
width: scroll.width - scroll.effectiveScrollBarWidth width: scroll.width - scroll.effectiveScrollBarWidth

6
src/Eden/Config/pages/global/GlobalGeneralPage.qml

@ -1,13 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick import QtQuick
import Eden.Config import Eden.Config
GlobalTab { GlobalTab {
property alias swipe: swipe property alias swipe: swipe
tabs: ["General", "Hotkeys", "Game List"]
tabs: ["General", "Game List", "Hotkeys"]
GlobalTabSwipeView { GlobalTabSwipeView {
id: swipe id: swipe
@ -15,7 +15,7 @@ GlobalTab {
// TODO: platform-specific stuff // TODO: platform-specific stuff
UiGeneralPage {} UiGeneralPage {}
Item {}
UiGameListPage {} UiGameListPage {}
Item {}
} }
} }

70
src/Eden/Interface/SettingsInterface.h

@ -15,41 +15,41 @@ namespace SettingsCategories {
Q_NAMESPACE Q_NAMESPACE
enum class Category { enum class Category {
Android = static_cast<u32>(Settings::Category::Android),
Audio = static_cast<u32>(Settings::Category::Audio),
Core = static_cast<u32>(Settings::Category::Core),
Cpu = static_cast<u32>(Settings::Category::Cpu),
CpuDebug = static_cast<u32>(Settings::Category::CpuDebug),
CpuUnsafe = static_cast<u32>(Settings::Category::CpuUnsafe),
Overlay = static_cast<u32>(Settings::Category::Overlay),
Renderer = static_cast<u32>(Settings::Category::Renderer),
RendererAdvanced = static_cast<u32>(Settings::Category::RendererAdvanced),
RendererExtensions = static_cast<u32>(Settings::Category::RendererExtensions),
RendererDebug = static_cast<u32>(Settings::Category::RendererDebug),
System = static_cast<u32>(Settings::Category::System),
SystemAudio = static_cast<u32>(Settings::Category::SystemAudio),
DataStorage = static_cast<u32>(Settings::Category::DataStorage),
Debugging = static_cast<u32>(Settings::Category::Debugging),
DebuggingGraphics = static_cast<u32>(Settings::Category::DebuggingGraphics),
GpuDriver = static_cast<u32>(Settings::Category::GpuDriver),
Miscellaneous = static_cast<u32>(Settings::Category::Miscellaneous),
Network = static_cast<u32>(Settings::Category::Network),
WebService = static_cast<u32>(Settings::Category::WebService),
AddOns = static_cast<u32>(Settings::Category::AddOns),
Controls = static_cast<u32>(Settings::Category::Controls),
Ui = static_cast<u32>(Settings::Category::Ui),
UiAudio = static_cast<u32>(Settings::Category::UiAudio),
UiGeneral = static_cast<u32>(Settings::Category::UiGeneral),
UiLayout = static_cast<u32>(Settings::Category::UiLayout),
UiGameList = static_cast<u32>(Settings::Category::UiGameList),
Screenshots = static_cast<u32>(Settings::Category::Screenshots),
Shortcuts = static_cast<u32>(Settings::Category::Shortcuts),
Multiplayer = static_cast<u32>(Settings::Category::Multiplayer),
Services = static_cast<u32>(Settings::Category::Services),
Paths = static_cast<u32>(Settings::Category::Paths),
Linux = static_cast<u32>(Settings::Category::Linux),
LibraryApplet = static_cast<u32>(Settings::Category::LibraryApplet),
MaxEnum = static_cast<u32>(Settings::Category::MaxEnum),
Android = u32(Settings::Category::Android),
Audio = u32(Settings::Category::Audio),
Core = u32(Settings::Category::Core),
Cpu = u32(Settings::Category::Cpu),
CpuDebug = u32(Settings::Category::CpuDebug),
CpuUnsafe = u32(Settings::Category::CpuUnsafe),
Overlay = u32(Settings::Category::Overlay),
Renderer = u32(Settings::Category::Renderer),
RendererAdvanced = u32(Settings::Category::RendererAdvanced),
RendererExtensions = u32(Settings::Category::RendererExtensions),
RendererDebug = u32(Settings::Category::RendererDebug),
System = u32(Settings::Category::System),
SystemAudio = u32(Settings::Category::SystemAudio),
DataStorage = u32(Settings::Category::DataStorage),
Debugging = u32(Settings::Category::Debugging),
DebuggingGraphics = u32(Settings::Category::DebuggingGraphics),
GpuDriver = u32(Settings::Category::GpuDriver),
Miscellaneous = u32(Settings::Category::Miscellaneous),
Network = u32(Settings::Category::Network),
WebService = u32(Settings::Category::WebService),
AddOns = u32(Settings::Category::AddOns),
Controls = u32(Settings::Category::Controls),
Ui = u32(Settings::Category::Ui),
UiAudio = u32(Settings::Category::UiAudio),
UiGeneral = u32(Settings::Category::UiGeneral),
UiLayout = u32(Settings::Category::UiLayout),
UiGameList = u32(Settings::Category::UiGameList),
Screenshots = u32(Settings::Category::Screenshots),
Shortcuts = u32(Settings::Category::Shortcuts),
Multiplayer = u32(Settings::Category::Multiplayer),
Services = u32(Settings::Category::Services),
Paths = u32(Settings::Category::Paths),
Linux = u32(Settings::Category::Linux),
LibraryApplet = u32(Settings::Category::LibraryApplet),
MaxEnum = u32(Settings::Category::MaxEnum),
}; };
Q_ENUM_NS(Category) Q_ENUM_NS(Category)
} }

1
src/Eden/Native/CMakeLists.txt

@ -8,6 +8,7 @@ qt_add_executable(eden
main.cpp main.cpp
icons.qrc icons.qrc
EdenApplication.h EdenApplication.cpp EdenApplication.h EdenApplication.cpp
LibQtCommon.cpp
) )
set(MODULES set(MODULES

40
src/Eden/Native/LibQtCommon.cpp

@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "CarboxylQuickInterface.h"
#include "CarboxylApplication.h"
#include "qt_common/abstract/frontend.h"
namespace QtCommon::Frontend {
StandardButton ShowMessage(Icon icon, const QString& title, const QString& text,
StandardButtons buttons, QObject* parent) {
auto res = g_carboxylApp->interface()->showMessageBox(
CarboxylEnums::Icon(int(icon)), title, text,
QPlatformDialogHelper::StandardButton(int(buttons)), parent);
return StandardButton(res);
}
const QString GetOpenFileName(const QString& title, const QString& dir, const QString& filter,
QString* selectedFilter, Options options) {
// TODO
// return QFileDialog::getOpenFileName((QWidget *) rootObject, title, dir, filter,
// selectedFilter, QFileDialog::Options(int(options)));
return QString();
}
const QString GetSaveFileName(const QString& title, const QString& dir, const QString& filter,
QString* selectedFilter, Options options) {
// return QFileDialog::getSaveFileName((QWidget *) rootObject, title, dir, filter,
// selectedFilter, QFileDialog::Options(int(options)));
return QString();
}
const QString GetExistingDirectory(const QString& caption, const QString& dir, Options options) {
// return QFileDialog::getExistingDirectory((QWidget *) rootObject, caption, dir,
// QFileDialog::Options(int(options)));
return QString();
}
} // namespace QtCommon::Frontend

3
src/frontend_common/config.cpp

@ -4,7 +4,8 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "config.h"
#include <algorithm>
#include <array>
#include "common/assert.h" #include "common/assert.h"
#include "common/fs/fs.h" #include "common/fs/fs.h"
#include "common/fs/path_util.h" #include "common/fs/path_util.h"

8
src/qt_common/CMakeLists.txt

@ -23,7 +23,7 @@ add_library(qt_common STATIC
util/applet.h util/applet.cpp util/applet.h util/applet.cpp
util/compress.h util/compress.cpp util/compress.h util/compress.cpp
abstract/frontend.h abstract/frontend.cpp
abstract/frontend.h
abstract/qt_progress_dialog.h abstract/qt_progress_dialog.cpp abstract/qt_progress_dialog.h abstract/qt_progress_dialog.cpp
qt_string_lookup.h qt_string_lookup.h
@ -54,11 +54,6 @@ if (USE_DISCORD_PRESENCE)
target_compile_definitions(qt_common PUBLIC USE_DISCORD_PRESENCE) target_compile_definitions(qt_common PUBLIC USE_DISCORD_PRESENCE)
endif() endif()
# TODO(crueter)
if (ENABLE_QT_WIDGETS)
target_link_libraries(qt_common PRIVATE Qt6::Widgets)
endif()
target_compile_definitions(qt_common PUBLIC target_compile_definitions(qt_common PUBLIC
# Use QStringBuilder for string concatenation to reduce # Use QStringBuilder for string concatenation to reduce
# the overall number of temporary strings created. # the overall number of temporary strings created.
@ -87,6 +82,7 @@ find_package(frozen)
target_link_libraries(qt_common PRIVATE core input_common) target_link_libraries(qt_common PRIVATE core input_common)
target_link_libraries(qt_common PRIVATE gamemode::headers) target_link_libraries(qt_common PRIVATE gamemode::headers)
target_link_libraries(qt_common PRIVATE Qt6::Core Qt6::Concurrent SimpleIni::SimpleIni QuaZip::QuaZip) target_link_libraries(qt_common PRIVATE Qt6::Core Qt6::Concurrent SimpleIni::SimpleIni QuaZip::QuaZip)
target_link_libraries(qt_common PRIVATE Qt6::Widgets)
target_link_libraries(qt_common PUBLIC frozen::frozen-headers Vulkan::UtilityHeaders) target_link_libraries(qt_common PUBLIC frozen::frozen-headers Vulkan::UtilityHeaders)
if (NOT APPLE AND ENABLE_OPENGL) if (NOT APPLE AND ENABLE_OPENGL)

37
src/qt_common/abstract/frontend.h

@ -7,12 +7,6 @@
#include <QGuiApplication> #include <QGuiApplication>
#include "qt_common/qt_common.h" #include "qt_common/qt_common.h"
#ifdef YUZU_QT_WIDGETS
#include <QFileDialog>
#include <QWidget>
#include <QMessageBox>
#endif
/** /**
* manages common functionality e.g. message boxes and such for Qt/QML * manages common functionality e.g. message boxes and such for Qt/QML
*/ */
@ -20,15 +14,6 @@ namespace QtCommon::Frontend {
Q_NAMESPACE Q_NAMESPACE
#ifdef YUZU_QT_WIDGETS
using Options = QFileDialog::Options;
using Option = QFileDialog::Option;
using StandardButton = QMessageBox::StandardButton;
using StandardButtons = QMessageBox::StandardButtons;
using Icon = QMessageBox::Icon;
#else
enum Option { enum Option {
ShowDirsOnly = 0x00000001, ShowDirsOnly = 0x00000001,
DontResolveSymlinks = 0x00000002, DontResolveSymlinks = 0x00000002,
@ -83,7 +68,7 @@ typedef StandardButton Button;
Q_DECLARE_FLAGS(StandardButtons, StandardButton) Q_DECLARE_FLAGS(StandardButtons, StandardButton)
Q_FLAG_NS(StandardButtons) Q_FLAG_NS(StandardButtons)
enum Icon {
enum class Icon {
// keep this in sync with QMessageDialogOptions::StandardIcon // keep this in sync with QMessageDialogOptions::StandardIcon
NoIcon = 0, NoIcon = 0,
Information = 1, Information = 1,
@ -93,8 +78,6 @@ enum Icon {
}; };
Q_ENUM_NS(Icon) Q_ENUM_NS(Icon)
#endif
// TODO(crueter) widgets-less impl, choices et al. // TODO(crueter) widgets-less impl, choices et al.
StandardButton ShowMessage(Icon icon, StandardButton ShowMessage(Icon icon,
const QString &title, const QString &title,
@ -106,16 +89,28 @@ StandardButton ShowMessage(Icon icon,
inline StandardButton level(QObject *parent, \ inline StandardButton level(QObject *parent, \
const QString &title, \ const QString &title, \
const QString &text, \ const QString &text, \
StandardButtons buttons = StandardButton::Ok) \
StandardButtons buttons) \
{ \ { \
return ShowMessage(Icon::level, title, text, buttons, parent); \ return ShowMessage(Icon::level, title, text, buttons, parent); \
} \ } \
inline StandardButton level(QObject *parent, \
const QString &title, \
const QString &text, \
int buttons = StandardButton::Ok) \
{ \
return ShowMessage(Icon::level, title, text, StandardButtons(buttons), parent); \
} \
inline StandardButton level(const QString title, \ inline StandardButton level(const QString title, \
const QString &text, \ const QString &text, \
StandardButtons buttons \
= StandardButton::Ok) \
StandardButtons buttons) \
{ \ { \
return ShowMessage(Icon::level, title, text, buttons, rootObject); \ return ShowMessage(Icon::level, title, text, buttons, rootObject); \
} \
inline StandardButton level(const QString &title, \
const QString &text, \
int buttons = StandardButton::Ok) \
{ \
return ShowMessage(Icon::level, title, text, StandardButtons(buttons), rootObject); \
} }
UTIL_OVERRIDES(Information) UTIL_OVERRIDES(Information)

12
src/qt_common/config/qt_config.cpp

@ -5,6 +5,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings_common.h"
#include "input_common/main.h" #include "input_common/main.h"
#include "qt_config.h" #include "qt_config.h"
#include "uisettings.h" #include "uisettings.h"
@ -561,11 +562,12 @@ void QtConfig::SaveMultiplayerValues() {
} }
std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) { std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) {
auto& map = Settings::values.linkage.by_category;
if (map.contains(category)) {
return Settings::values.linkage.by_category[category];
}
return UISettings::values.linkage.by_category[category];
// This solution sucks, but by_category is unreliable because the settings backend
// mangles category mapping for some reason.
static auto list = Settings::values.linkage.by_category[category];
auto uilist = UISettings::values.linkage.by_category[category];
list.insert(list.end(), uilist.begin(), uilist.end());
return list;
} }
void QtConfig::ReadQtControlPlayerValues(std::size_t player_index) { void QtConfig::ReadQtControlPlayerValues(std::size_t player_index) {

3
src/qt_common/externals/CMakeLists.txt

@ -22,4 +22,7 @@ AddJsonPackage(frozen)
# TODO # TODO
if (ENABLE_QT_QML) if (ENABLE_QT_QML)
AddJsonPackage(carboxyl) AddJsonPackage(carboxyl)
if (NOT MSVC)
target_compile_options(CarboxylBase PUBLIC -Wno-shadow)
endif()
endif() endif()

4
src/qt_common/externals/cpmfile.json

@ -19,8 +19,8 @@
"package": "Carboxyl", "package": "Carboxyl",
"repo": "crueter/Carboxyl", "repo": "crueter/Carboxyl",
"git_host": "git.crueter.xyz", "git_host": "git.crueter.xyz",
"sha": "8fb8d80f90",
"hash": "3b1f259060f9685f90071ac03eb1fef68370a3b9ec7c311a94d22fefa0b703140883c846818a363ab1bee0807f44759ba7a91e05107b2adcd3f9048efe447a6a",
"sha": "ea2f2fa4bc",
"hash": "4b2102379c1e5de68263cd68b705c2524fd220c6707964cb586f4b6c3e221083348c022128f6c61682d7e12c8cfd67a3723ccb7023d28b7560ce3542d6b75545",
"bundled": "true", "bundled": "true",
"options": [ "options": [
"CARBOXYL_DEMO OFF" "CARBOXYL_DEMO OFF"

8
src/qt_common/qt_common.cpp

@ -52,11 +52,7 @@ using namespace Common::Literals;
namespace QtCommon { namespace QtCommon {
#ifdef YUZU_QT_WIDGETS
QWidget* rootObject = nullptr;
#else
QObject* rootObject = nullptr; QObject* rootObject = nullptr;
#endif
std::unique_ptr<Core::System> system = nullptr; std::unique_ptr<Core::System> system = nullptr;
std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr; std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr;
@ -193,11 +189,7 @@ static void RemoveCachedContents() {
} }
#ifdef YUZU_QT_WIDGETS
void Init(QWidget * root)
#else
void Init(QObject* root) void Init(QObject* root)
#endif
{ {
system = std::make_unique<Core::System>(); system = std::make_unique<Core::System>();
rootObject = root; rootObject = root;

8
src/qt_common/qt_common.h

@ -14,11 +14,7 @@
namespace QtCommon { namespace QtCommon {
#ifdef YUZU_QT_WIDGETS
extern QWidget *rootObject;
#else
extern QObject *rootObject; extern QObject *rootObject;
#endif
extern std::unique_ptr<Core::System> system; extern std::unique_ptr<Core::System> system;
extern std::shared_ptr<FileSys::RealVfsFilesystem> vfs; extern std::shared_ptr<FileSys::RealVfsFilesystem> vfs;
@ -31,11 +27,7 @@ Core::Frontend::WindowSystemType GetWindowSystemType();
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window); Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window);
#ifdef YUZU_QT_WIDGETS
void Init(QWidget *root);
#else
void Init(QObject *root); void Init(QObject *root);
#endif
const QString tr(const char *str); const QString tr(const char *str);
const QString tr(const std::string &str); const QString tr(const std::string &str);

38
src/qt_common/util/content.cpp

@ -26,16 +26,14 @@ bool CheckGameFirmware(u64 program_id, QObject* parent)
{ {
if (FirmwareManager::GameRequiresFirmware(program_id) if (FirmwareManager::GameRequiresFirmware(program_id)
&& !FirmwareManager::CheckFirmwarePresence(*system)) { && !FirmwareManager::CheckFirmwarePresence(*system)) {
auto result = QtCommon::Frontend::ShowMessage(
QMessageBox::Warning,
auto result = QtCommon::Frontend::Warning(
tr("Game Requires Firmware"), tr("Game Requires Firmware"),
tr("The game you are trying to launch requires firmware to boot or to get past the " tr("The game you are trying to launch requires firmware to boot or to get past the "
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>" "opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
"dump and install firmware</a>, or press \"OK\" to launch anyways."), "dump and install firmware</a>, or press \"OK\" to launch anyways."),
QMessageBox::Ok | QMessageBox::Cancel,
parent);
QtCommon::Frontend::Ok | QtCommon::Frontend::Cancel);
return result == QMessageBox::Ok;
return result == QtCommon::Frontend::Ok;
} }
return true; return true;
@ -47,7 +45,7 @@ void InstallFirmware(const QString& location, bool recursive)
tr("Cancel"), tr("Cancel"),
0, 0,
100, 100,
rootObject);
(QWidget *)rootObject);
progress.setWindowModality(Qt::WindowModal); progress.setWindowModality(Qt::WindowModal);
progress.setMinimumDuration(100); progress.setMinimumDuration(100);
progress.setAutoClose(false); progress.setAutoClose(false);
@ -62,7 +60,7 @@ void InstallFirmware(const QString& location, bool recursive)
QString failedTitle = tr("Firmware Install Failed"); QString failedTitle = tr("Firmware Install Failed");
QString successTitle = tr("Firmware Install Succeeded"); QString successTitle = tr("Firmware Install Succeeded");
QMessageBox::Icon icon;
QtCommon::Frontend::Icon icon;
FirmwareInstallResult result; FirmwareInstallResult result;
const auto ShowMessage = [&]() { const auto ShowMessage = [&]() {
@ -104,7 +102,7 @@ void InstallFirmware(const QString& location, bool recursive)
if (out.size() <= 0) { if (out.size() <= 0) {
result = FirmwareInstallResult::NoNCAs; result = FirmwareInstallResult::NoNCAs;
icon = QMessageBox::Warning;
icon = QtCommon::Frontend::Icon::Warning;
ShowMessage(); ShowMessage();
return; return;
} }
@ -114,7 +112,7 @@ void InstallFirmware(const QString& location, bool recursive)
if (sysnand_content_vdir->IsWritable() if (sysnand_content_vdir->IsWritable()
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
result = FirmwareInstallResult::FailedDelete; result = FirmwareInstallResult::FailedDelete;
icon = QMessageBox::Critical;
icon = QtCommon::Frontend::Icon::Critical;
ShowMessage(); ShowMessage();
return; return;
} }
@ -145,7 +143,7 @@ void InstallFirmware(const QString& location, bool recursive)
if (callback(100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) { if (callback(100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
result = FirmwareInstallResult::FailedCorrupted; result = FirmwareInstallResult::FailedCorrupted;
icon = QMessageBox::Warning;
icon = QtCommon::Frontend::Icon::Warning;
ShowMessage(); ShowMessage();
return; return;
} }
@ -153,7 +151,7 @@ void InstallFirmware(const QString& location, bool recursive)
if (!success) { if (!success) {
result = FirmwareInstallResult::FailedCopy; result = FirmwareInstallResult::FailedCopy;
icon = QMessageBox::Critical;
icon = QtCommon::Frontend::Icon::Critical;
ShowMessage(); ShowMessage();
return; return;
} }
@ -225,7 +223,7 @@ void VerifyGameContents(const std::string& game_path)
tr("Cancel"), tr("Cancel"),
0, 0,
100, 100,
rootObject);
(QWidget *)rootObject);
progress.setWindowModality(Qt::WindowModal); progress.setWindowModality(Qt::WindowModal);
progress.setMinimumDuration(100); progress.setMinimumDuration(100);
progress.setAutoClose(false); progress.setAutoClose(false);
@ -294,7 +292,7 @@ void VerifyInstalledContents()
tr("Cancel"), tr("Cancel"),
0, 0,
100, 100,
rootObject);
(QWidget *)rootObject);
progress.setWindowModality(Qt::WindowModal); progress.setWindowModality(Qt::WindowModal);
progress.setMinimumDuration(100); progress.setMinimumDuration(100);
progress.setAutoClose(false); progress.setAutoClose(false);
@ -377,18 +375,18 @@ void ClearDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& u
{ {
auto result = QtCommon::Frontend::Warning(tr("Really clear data?"), auto result = QtCommon::Frontend::Warning(tr("Really clear data?"),
tr("Important data may be lost!"), tr("Important data may be lost!"),
QMessageBox::Yes | QMessageBox::No);
QtCommon::Frontend::Yes | QtCommon::Frontend::No);
if (result != QMessageBox::Yes)
if (result != QtCommon::Frontend::Yes)
return; return;
result = QtCommon::Frontend::Warning( result = QtCommon::Frontend::Warning(
tr("Are you REALLY sure?"), tr("Are you REALLY sure?"),
tr("Once deleted, your data will NOT come back!\n" tr("Once deleted, your data will NOT come back!\n"
"Only do this if you're 100% sure you want to delete this data."), "Only do this if you're 100% sure you want to delete this data."),
QMessageBox::Yes | QMessageBox::No);
QtCommon::Frontend::Yes | QtCommon::Frontend::No);
if (result != QMessageBox::Yes)
if (result != QtCommon::Frontend::Yes)
return; return;
QtCommon::Frontend::QtProgressDialog dialog(tr("Clearing..."), QString(), 0, 0); QtCommon::Frontend::QtProgressDialog dialog(tr("Clearing..."), QString(), 0, 0);
@ -415,7 +413,7 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
return; return;
QtProgressDialog* progress = new QtProgressDialog( QtProgressDialog* progress = new QtProgressDialog(
tr("Exporting data. This may take a while..."), tr("Cancel"), 0, 100, rootObject);
tr("Exporting data. This may take a while..."), tr("Cancel"), 0, 100, (QWidget*)rootObject);
progress->setWindowTitle(tr("Exporting")); progress->setWindowTitle(tr("Exporting"));
progress->setWindowModality(Qt::WindowModal); progress->setWindowModality(Qt::WindowModal);
@ -486,11 +484,11 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir,
"proceed?"), "proceed?"),
StandardButton::Yes | StandardButton::No); StandardButton::Yes | StandardButton::No);
if (button != QMessageBox::Yes)
if (button != QtCommon::Frontend::Yes)
return; return;
QtProgressDialog* progress = new QtProgressDialog( QtProgressDialog* progress = new QtProgressDialog(
tr("Importing data. This may take a while..."), tr("Cancel"), 0, 100, rootObject);
tr("Importing data. This may take a while..."), tr("Cancel"), 0, 100, (QWidget *)rootObject);
progress->setWindowTitle(tr("Importing")); progress->setWindowTitle(tr("Importing"));
progress->setWindowModality(Qt::WindowModal); progress->setWindowModality(Qt::WindowModal);

2
src/qt_common/util/fs.cpp

@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include <filesystem> #include <filesystem>
#include <QDir>
#include "common/fs/ryujinx_compat.h" #include "common/fs/ryujinx_compat.h"
#include "common/fs/symlink.h" #include "common/fs/symlink.h"
#include "fs.h" #include "fs.h"

15
src/qt_common/util/game.cpp

@ -11,7 +11,6 @@
#include "qt_common/abstract/frontend.h" #include "qt_common/abstract/frontend.h"
#include "qt_common/config/uisettings.h" #include "qt_common/config/uisettings.h"
#include "qt_common/qt_common.h" #include "qt_common/qt_common.h"
#include "yuzu/util/util.h"
#include <QDesktopServices> #include <QDesktopServices>
#include <QStandardPaths> #include <QStandardPaths>
@ -406,29 +405,31 @@ void ResetMetadata(bool show_message)
inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QString& game_title) inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QString& game_title)
{ {
int result = 0; int result = 0;
QMessageBox::StandardButtons buttons;
using namespace QtCommon::Frontend;
int buttons;
switch (imsg) { switch (imsg) {
case ShortcutMessages::Fullscreen: case ShortcutMessages::Fullscreen:
buttons = QMessageBox::Yes | QMessageBox::No;
buttons = Yes | No;
result result
= QtCommon::Frontend::Information(tr("Create Shortcut"), = QtCommon::Frontend::Information(tr("Create Shortcut"),
tr("Do you want to launch the game in fullscreen?"), tr("Do you want to launch the game in fullscreen?"),
buttons); buttons);
return result == QMessageBox::Yes;
return result == Yes;
case ShortcutMessages::Success: case ShortcutMessages::Success:
QtCommon::Frontend::Information(tr("Shortcut Created"), QtCommon::Frontend::Information(tr("Shortcut Created"),
tr("Successfully created a shortcut to %1").arg(game_title)); tr("Successfully created a shortcut to %1").arg(game_title));
return false; return false;
case ShortcutMessages::Volatile: case ShortcutMessages::Volatile:
buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel;
buttons = Ok | Cancel;
result = QtCommon::Frontend::Warning( result = QtCommon::Frontend::Warning(
tr("Shortcut may be Volatile!"), tr("Shortcut may be Volatile!"),
tr("This will create a shortcut to the current AppImage. This may " tr("This will create a shortcut to the current AppImage. This may "
"not work well if you update. Continue?"), "not work well if you update. Continue?"),
buttons); buttons);
return result == QMessageBox::Ok;
return result == Ok;
default: default:
buttons = QMessageBox::Ok;
buttons = Ok;
QtCommon::Frontend::Critical(tr("Failed to Create Shortcut"), QtCommon::Frontend::Critical(tr("Failed to Create Shortcut"),
tr("Failed to create a shortcut to %1").arg(game_title), tr("Failed to create a shortcut to %1").arg(game_title),
buttons); buttons);

4
src/qt_common/util/path.cpp

@ -17,11 +17,11 @@ bool OpenShaderCache(u64 program_id, QObject *parent)
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)}; const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
if (!Common::FS::CreateDirs(shader_cache_folder_path)) { if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
QtCommon::Frontend::ShowMessage(QMessageBox::Warning,
QtCommon::Frontend::ShowMessage(QtCommon::Frontend::Icon::Warning,
tr("Error Opening Shader Cache"), tr("Error Opening Shader Cache"),
tr("Failed to create or open shader cache for this title, " tr("Failed to create or open shader cache for this title, "
"ensure your app data directory has write permissions."), "ensure your app data directory has write permissions."),
QMessageBox::Ok,
QtCommon::Frontend::Ok,
parent); parent);
} }

1
src/yuzu/CMakeLists.txt

@ -233,6 +233,7 @@ add_executable(yuzu
data_widget.ui data_widget.ui
ryujinx_dialog.h ryujinx_dialog.cpp ryujinx_dialog.ui ryujinx_dialog.h ryujinx_dialog.cpp ryujinx_dialog.ui
main_window.h main_window.cpp main_window.h main_window.cpp
libqt_common.cpp
) )
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")

29
src/qt_common/abstract/frontend.cpp → src/yuzu/libqt_common.cpp

@ -1,24 +1,19 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include "frontend.h"
#include "qt_common/qt_common.h"
#ifdef YUZU_QT_WIDGETS
#include <QFileDialog> #include <QFileDialog>
#endif
#include <QMessageBox>
#include "qt_common/abstract/frontend.h"
#include "qt_common/qt_common.h"
namespace QtCommon::Frontend { namespace QtCommon::Frontend {
StandardButton ShowMessage( StandardButton ShowMessage(
Icon icon, const QString &title, const QString &text, StandardButtons buttons, QObject *parent) Icon icon, const QString &title, const QString &text, StandardButtons buttons, QObject *parent)
{ {
#ifdef YUZU_QT_WIDGETS
QMessageBox *box = new QMessageBox(icon, title, text, buttons, (QWidget *) parent);
return static_cast<QMessageBox::StandardButton>(box->exec());
#endif
// TODO(crueter): If Qt Widgets is disabled...
// need a way to reference icon/buttons too
QMessageBox *box = new QMessageBox(QMessageBox::Icon(int(icon)), title, text, QMessageBox::StandardButtons(int(buttons)), (QWidget *) parent);
return StandardButton(box->exec());
} }
const QString GetOpenFileName(const QString &title, const QString GetOpenFileName(const QString &title,
@ -27,9 +22,7 @@ const QString GetOpenFileName(const QString &title,
QString *selectedFilter, QString *selectedFilter,
Options options) Options options)
{ {
#ifdef YUZU_QT_WIDGETS
return QFileDialog::getOpenFileName(rootObject, title, dir, filter, selectedFilter, options);
#endif
return QFileDialog::getOpenFileName((QWidget *) rootObject, title, dir, filter, selectedFilter, QFileDialog::Options(int(options)));
} }
const QString GetSaveFileName(const QString &title, const QString GetSaveFileName(const QString &title,
@ -38,16 +31,12 @@ const QString GetSaveFileName(const QString &title,
QString *selectedFilter, QString *selectedFilter,
Options options) Options options)
{ {
#ifdef YUZU_QT_WIDGETS
return QFileDialog::getSaveFileName(rootObject, title, dir, filter, selectedFilter, options);
#endif
return QFileDialog::getSaveFileName((QWidget *) rootObject, title, dir, filter, selectedFilter, QFileDialog::Options(int(options)));
} }
const QString GetExistingDirectory(const QString& caption, const QString& dir, const QString GetExistingDirectory(const QString& caption, const QString& dir,
Options options) { Options options) {
#ifdef YUZU_QT_WIDGETS
return QFileDialog::getExistingDirectory(rootObject, caption, dir, options);
#endif
return QFileDialog::getExistingDirectory((QWidget *) rootObject, caption, dir, QFileDialog::Options(int(options)));
} }
} // namespace QtCommon::Frontend } // namespace QtCommon::Frontend

2
src/yuzu/util/util.cpp

@ -52,7 +52,7 @@ const std::optional<Common::UUID> GetProfileID() {
.display_options = {}, .display_options = {},
.purpose = Service::AM::Frontend::UserSelectionPurpose::General, .purpose = Service::AM::Frontend::UserSelectionPurpose::General,
}; };
QtProfileSelectionDialog dialog(*QtCommon::system, QtCommon::rootObject, parameters);
QtProfileSelectionDialog dialog(*QtCommon::system, (QWidget *)QtCommon::rootObject, parameters);
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
dialog.setWindowModality(Qt::WindowModal); dialog.setWindowModality(Qt::WindowModal);

Loading…
Cancel
Save