[cmake, qml] refactor: cmake reorg, match grid behavior to carousel

Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
crueter 2025-09-14 16:00:54 -04:00
parent 1604c102eb
commit 649d48c096
Signed by: crueter
GPG key ID: 425ACD2D4830EBC6
114 changed files with 867 additions and 865 deletions

View file

@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
cmake_minimum_required(VERSION 3.16)
function(EdenModule)
set(oneValueArgs
NAME
URI
NATIVE
)
set(multiValueArgs
LIBRARIES
QML_FILES
SOURCES
)
cmake_parse_arguments(MODULE "" "${oneValueArgs}" "${multiValueArgs}"
"${ARGN}")
set(LIB_NAME Eden${MODULE_NAME})
add_library(${LIB_NAME} STATIC)
message(STATUS "URI for ${MODULE_NAME}: ${MODULE_URI}")
qt_add_qml_module(${LIB_NAME}
URI ${MODULE_URI}
NO_PLUGIN
VERSION 0.1
QML_FILES ${MODULE_QML_FILES}
SOURCES ${MODULE_SOURCES}
${MODULE_UNPARSED_ARGUMENTS}
)
add_library(Eden::${MODULE_NAME} ALIAS ${LIB_NAME})
if (DEFINED MODULE_LIBRARIES)
target_link_libraries(${LIB_NAME} PRIVATE ${MODULE_LIBRARIES})
endif()
endfunction()

View file

@ -18,20 +18,20 @@ set_property(DIRECTORY APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
# Set compilation flags
if (MSVC AND NOT CXX_CLANG)
if (MSVC)
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
# Silence "deprecation" warnings
add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE _SCL_SECURE_NO_WARNINGS)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
# Avoid windows.h junk
add_compile_definitions(NOMINMAX)
add_definitions(-DNOMINMAX)
# Avoid windows.h from including some usually unused libs like winsocks.h, since this might cause some redefinition errors.
add_compile_definitions(WIN32_LEAN_AND_MEAN)
add_definitions(-DWIN32_LEAN_AND_MEAN)
# Ensure that projects are built with Unicode support.
add_compile_definitions(UNICODE _UNICODE)
add_definitions(-DUNICODE -D_UNICODE)
# /W4 - Level 4 warnings
# /MP - Multi-threaded compilation
@ -69,6 +69,10 @@ if (MSVC AND NOT CXX_CLANG)
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
/external:W0 # Sets the default warning level to 0 for external headers, effectively disabling warnings for them.
# Warnings
/W4
/WX-
/we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled
/we4189 # 'identifier': local variable is initialized but not referenced
/we4265 # 'class': class has virtual functions, but destructor is not virtual
@ -93,14 +97,6 @@ if (MSVC AND NOT CXX_CLANG)
/wd4702 # unreachable code (when used with LTO)
)
if (NOT CXX_CLANG)
add_compile_options(
# Warnings
/W4
/WX-
)
endif()
if (USE_CCACHE OR YUZU_USE_PRECOMPILED_HEADERS)
# when caching, we need to use /Z7 to downgrade debug info to use an older but more cacheable format
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
@ -122,13 +118,9 @@ if (MSVC AND NOT CXX_CLANG)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
else()
if (NOT MSVC)
add_compile_options(
-fwrapv
)
endif()
add_compile_options(
-fwrapv
-Werror=all
-Werror=extra
-Werror=shadow
@ -140,19 +132,14 @@ else()
-Wno-missing-field-initializers
)
if (CXX_CLANG OR CXX_ICC) # Clang or AppleClang
if (NOT MSVC)
add_compile_options(
-Werror=shadow-uncaptured-local
-Werror=implicit-fallthrough
-Werror=type-limits
)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID MATCHES IntelLLVM) # Clang or AppleClang
add_compile_options(
-Wno-braced-scalar-init
-Wno-unused-private-field
-Wno-nullability-completeness
-Werror=shadow-uncaptured-local
-Werror=implicit-fallthrough
-Werror=type-limits
)
endif()
@ -160,12 +147,12 @@ else()
add_compile_options("-mcx16")
endif()
if (APPLE AND CXX_CLANG)
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
add_compile_options("-stdlib=libc++")
endif()
# GCC bugs
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CXX_GCC)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# These diagnostics would be great if they worked, but are just completely broken
# and produce bogus errors on external libraries like fmt.
add_compile_options(
@ -181,15 +168,15 @@ else()
# glibc, which may default to 32 bits. glibc allows this to be configured
# by setting _FILE_OFFSET_BITS.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
add_compile_definitions(_FILE_OFFSET_BITS=64)
add_definitions(-D_FILE_OFFSET_BITS=64)
endif()
if (MINGW)
add_compile_definitions(MINGW_HAS_SECURE_API)
add_definitions(-DMINGW_HAS_SECURE_API)
add_compile_options("-msse4.1")
if (MINGW_STATIC_BUILD)
add_compile_definitions(QT_STATICPLUGIN)
add_definitions(-DQT_STATICPLUGIN)
add_compile_options("-static")
endif()
endif()
@ -235,7 +222,7 @@ endif()
if (ENABLE_QT)
add_definitions(-DYUZU_QT_WIDGETS)
add_subdirectory(qt_common)
add_subdirectory(eden)
add_subdirectory(Eden)
endif()
if (ENABLE_WEB_SERVICE)
@ -246,5 +233,3 @@ if (ANDROID)
add_subdirectory(android/app/src/main/jni)
target_include_directories(yuzu-android PRIVATE android/app/src/main)
endif()
include(GenerateDepHashes)

22
src/Eden/CMakeLists.txt Normal file
View file

@ -0,0 +1,22 @@
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui Quick QuickControls2)
qt_standard_project_setup(REQUIRES 6.7)
include(EdenModule)
include_directories(AFTER "${CMAKE_CURRENT_SOURCE_DIR}")
add_subdirectory(Interface)
add_subdirectory(Models)
add_subdirectory(Config)
add_subdirectory(Constants)
add_subdirectory(Items)
add_subdirectory(Util)
add_subdirectory(Main)
add_subdirectory(Native)

View file

@ -0,0 +1,62 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
EdenModule(
NAME Config
URI Eden.Config
QML_FILES
GlobalConfigureDialog.qml
Setting.qml
SectionHeader.qml
pages/SettingsList.qml
pages/global/GlobalTab.qml
pages/global/GlobalTabSwipeView.qml
pages/global/GlobalGeneralPage.qml
pages/global/GlobalSystemPage.qml
pages/global/GlobalCpuPage.qml
pages/global/GlobalGraphicsPage.qml
pages/global/GlobalAudioPage.qml
pages/general/UiGeneralPage.qml
pages/general/UiGameListPage.qml
pages/graphics/RendererPage.qml
pages/graphics/RendererAdvancedPage.qml
pages/graphics/RendererExtensionsPage.qml
pages/system/SystemGeneralPage.qml
pages/system/SystemCorePage.qml
pages/system/FileSystemPage.qml
pages/system/AppletsPage.qml
pages/cpu/CpuGeneralPage.qml
pages/audio/AudioGeneralPage.qml
pages/global/GlobalDebugPage.qml
pages/debug/DebugGeneralPage.qml
pages/debug/DebugGraphicsPage.qml
pages/debug/DebugAdvancedPage.qml
pages/debug/DebugCpuPage.qml
fields/ConfigCheckbox.qml
fields/FieldLabel.qml
fields/ConfigComboBox.qml
fields/ConfigIntLine.qml
fields/ConfigTimeEdit.qml
fields/ConfigIntSpin.qml
fields/ConfigHexEdit.qml
fields/ConfigStringEdit.qml
fields/FieldCheckbox.qml
fields/ConfigIntSlider.qml
fields/BaseField.qml
TestSetting.qml
LIBRARIES Eden::Interface
)

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts
import Eden.Constants
import Eden.Items
import Eden.Native.Interface
import Eden.Interface
import Eden.Util
AnimatedDialog {
@ -34,7 +34,7 @@ AnimatedDialog {
anchors {
top: parent.top
topMargin: 55 * Constants.scalar
topMargin: 55
left: parent.left
bottom: parent.bottom
@ -65,7 +65,7 @@ AnimatedDialog {
top: parent.top
bottom: parent.bottom
leftMargin: 5 * Constants.scalar
leftMargin: 5
}
clip: true

View file

@ -4,8 +4,8 @@ import QtQuick.Layouts
import Eden.Constants
Column {
topPadding: 5 * Constants.scalar
leftPadding: 10 * Constants.scalar
topPadding: 5
leftPadding: 10
RowLayout {
uniformCellSizes: true

View file

@ -36,7 +36,7 @@ Item {
RowLayout {
id: content
height: 50 * Constants.scalar
height: 50
spacing: 0
@ -91,9 +91,9 @@ Item {
anchors {
left: parent.left
leftMargin: 20 * Constants.scalar
leftMargin: 20
right: parent.right
rightMargin: 20 * Constants.scalar
rightMargin: 20
top: content.bottom
topMargin: -height
@ -103,7 +103,7 @@ Item {
text: setting.tooltip
color: Constants.subText
font.pixelSize: 12 * Constants.scalar
font.pixelSize: 12
wrapMode: Text.WordWrap
visible: false

View file

@ -10,12 +10,12 @@ BaseField {
// contentItem: CheckBox {
// id: control
// Layout.rightMargin: 10 * Constants.scalar
// Layout.rightMargin: 10
// Layout.fillWidth: true
// font.pixelSize: 15 * Constants.scalar
// indicator.implicitHeight: 25 * Constants.scalar
// indicator.implicitWidth: 25 * Constants.scalar
// font.pixelSize: 15
// indicator.implicitHeight: 25
// indicator.implicitWidth: 25
// text: setting.label
// checked: setting.value

View file

@ -12,15 +12,15 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
font.pixelSize: 14 * Constants.scalar
font.pixelSize: 14
model: setting.combo
currentIndex: value
background: MaterialTextContainer {
implicitWidth: 120
implicitHeight: 40 * Constants.scalar
implicitHeight: 40
outlineColor: (enabled
&& control.hovered) ? control.Material.primaryTextColor : control.Material.hintTextColor

View file

@ -10,13 +10,13 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
validator: RegularExpressionValidator {
regularExpression: /[0-9a-fA-F]{0,8}/
}
font.pixelSize: 15 * Constants.scalar
font.pixelSize: 15
text: Number(value).toString(16)
suffix: setting.suffix

View file

@ -10,7 +10,7 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
inputMethodHints: Qt.ImhDigitsOnly
validator: IntValidator {
@ -18,7 +18,7 @@ BaseField {
top: setting.max
}
font.pixelSize: 15 * Constants.scalar
font.pixelSize: 15
text: value
suffix: setting.suffix

View file

@ -23,18 +23,18 @@ BaseField {
onMoved: field.value = value
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
snapMode: Slider.SnapAlways
}
Text {
font.pixelSize: 14 * Constants.scalar
font.pixelSize: 14
color: Constants.text
text: field.value + setting.suffix
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
}
}
}

View file

@ -11,12 +11,12 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
from: setting.min
to: setting.max
font.pixelSize: 15 * Constants.scalar
font.pixelSize: 15
value: field.value
label: setting.suffix

View file

@ -10,9 +10,9 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
font.pixelSize: 15 * Constants.scalar
font.pixelSize: 15
text: value
suffix: setting.suffix

View file

@ -11,7 +11,7 @@ BaseField {
enabled: enable
Layout.fillWidth: true
Layout.rightMargin: 10 * Constants.scalar
Layout.rightMargin: 10
inputMethodHints: Qt.ImhDigitsOnly
validator: IntValidator {
@ -19,7 +19,7 @@ BaseField {
top: setting.max
}
font.pixelSize: 15 * Constants.scalar
font.pixelSize: 15
text: value
suffix: setting.suffix

View file

@ -9,8 +9,8 @@ CheckBox {
property var setting
property var other: setting.other === null ? setting : setting.other
indicator.implicitHeight: 25 * Constants.scalar
indicator.implicitWidth: 25 * Constants.scalar
indicator.implicitHeight: 25
indicator.implicitWidth: 25
checked: visible ? other.value : true
onClicked: if (visible)

View file

@ -9,9 +9,9 @@ Text {
text: setting.label
color: Constants.text
font.pixelSize: 14 * Constants.scalar
font.pixelSize: 14
height: 50 * Constants.scalar
height: 50
ToolTip.text: setting.tooltip
Layout.fillWidth: true

View file

@ -3,7 +3,7 @@ import QtQuick.Layouts
import Eden.Config
import Eden.Constants
import Eden.Native.Interface
import Eden.Interface
ColumnLayout {
required property int category
@ -29,8 +29,8 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: 5 * Constants.scalar
spacing: 8 * Constants.scalar
Layout.leftMargin: 5
spacing: 8
model: SettingsInterface.category(category, idInclude, idExclude)

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -21,14 +21,14 @@ Item {
model: tabs
TabButton {
font.pixelSize: 16 * Constants.scalar
font.pixelSize: 16
text: modelData
}
}
background: Rectangle {
color: tabBar.Material.backgroundColor
radius: 8 * Constants.scalar
radius: 8
}
}
}

View file

@ -10,7 +10,7 @@ SwipeView {
right: parent.right
bottom: parent.bottom
leftMargin: 20 * Constants.scalar
topMargin: 10 * Constants.scalar
leftMargin: 20
topMargin: 10
}
}

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import Eden.Native.Interface
import Eden.Interface
import Eden.Config
ScrollView {

View file

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
set_source_files_properties(Constants.qml
PROPERTIES
QT_QML_SINGLETON_TYPE true
)
EdenModule(
NAME Constants
URI Eden.Constants
QML_FILES Constants.qml
)

View file

@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
find_package(Qt6 REQUIRED COMPONENTS Core)
qt_add_library(EdenInterface STATIC)
qt_add_qml_module(EdenInterface
URI Eden.Interface
NO_PLUGIN
SOURCES
SettingsInterface.h SettingsInterface.cpp
QMLSetting.h QMLSetting.cpp
MetaObjectHelper.h
QMLConfig.h
SOURCES TitleManager.h TitleManager.cpp
)
target_link_libraries(EdenInterface PUBLIC Qt6::Quick)
target_link_libraries(EdenInterface PRIVATE Qt6::Core)
add_library(Eden::Interface ALIAS EdenInterface)

View file

@ -1,6 +1,8 @@
#include "QMLSetting.h"
#include "common/settings.h"
#include <QVariant>
QMLSetting::QMLSetting(Settings::BasicSetting *setting, QObject *parent, RequestType request)
: QObject(parent)
, m_setting(setting)

View file

@ -2,7 +2,6 @@
#define QMLSETTING_H
#include <QObject>
#include <QtQmlIntegration>
#include "common/settings_common.h"
enum class RequestType {

View file

@ -7,9 +7,9 @@ SettingsInterface::SettingsInterface(QObject* parent)
: QObject{parent}
, translations{ConfigurationShared::InitializeTranslations(parent)}
, combobox_translations{ConfigurationShared::ComboboxEnumeration(parent)}
{}
{
}
// TODO: idExclude
SettingsModel *SettingsInterface::category(SettingsCategories::Category category,
QList<QString> idInclude,
QList<QString> idExclude)

View file

@ -6,7 +6,7 @@
#include "QMLSetting.h"
#include "qt_common/shared_translation.h"
#include "Native/Models/SettingsModel.h"
#include "Models/SettingsModel.h"
namespace SettingsCategories {
Q_NAMESPACE
@ -53,7 +53,6 @@ Q_ENUM_NS(Category)
class SettingsInterface : public QObject {
Q_OBJECT
QML_SINGLETON
QML_ELEMENT
public:
explicit SettingsInterface(QObject* parent = nullptr);

View file

@ -0,0 +1,40 @@
#include "TitleManager.h"
#include "common/scm_rev.h"
#include <fmt/format.h>
TitleManager::TitleManager(QObject *parent) {}
const QString TitleManager::title() const
{
static const std::string description = std::string(Common::g_build_version);
static const std::string build_id = std::string(Common::g_build_id);
static const std::string compiler = std::string(Common::g_compiler_id);
std::string yuzu_title;
if (Common::g_is_dev_build) {
yuzu_title = fmt::format("Eden Nightly | {}-{} | {}", description, build_id, compiler);
} else {
yuzu_title = fmt::format("Eden | {} | {}", description, compiler);
}
const auto override_title = fmt::format(fmt::runtime(
std::string(Common::g_title_bar_format_idle)),
build_id);
const auto window_title = override_title.empty() ? yuzu_title : override_title;
// TODO(crueter): Running
return QString::fromStdString(window_title);
// if (title_name.empty()) {
// return QString::fromStdString(window_title);
// } else {
// const auto run_title = [window_title, title_name, title_version, gpu_vendor]() {
// if (title_version.empty()) {
// return fmt::format("{} | {} | {}", window_title, title_name, gpu_vendor);
// }
// return fmt::format("{} | {} | {} | {}", window_title, title_name, title_version,
// gpu_vendor);
// }();
// setWindowTitle(QString::fromStdString(run_title));
// }
}

View file

@ -0,0 +1,18 @@
#ifndef TITLEMANAGER_H
#define TITLEMANAGER_H
#include <QObject>
class TitleManager : public QObject
{
Q_OBJECT
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
public:
explicit TitleManager(QObject *parent = nullptr);
const QString title() const;
signals:
void titleChanged();
};
#endif // TITLEMANAGER_H

View file

@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
EdenModule(
NAME Items
URI Eden.Items
QML_FILES
StatusBarButton.qml
BetterMenu.qml
AnimatedDialog.qml
BetterMenuBar.qml
SettingsTabButton.qml
IconButton.qml
VerticalTabBar.qml
fields/BetterSpinBox.qml
fields/BetterTextField.qml
fields/FieldFooter.qml
)

View file

@ -8,8 +8,8 @@ Button {
bottomInset: 0
topInset: 0
leftPadding: 5 * Constants.scalar
rightPadding: 5 * Constants.scalar
leftPadding: 5
rightPadding: 5
width: icon.width
height: icon.height

View file

@ -9,15 +9,15 @@ TabButton {
id: button
implicitHeight: 100 * Constants.scalar
width: 95 * Constants.scalar
implicitHeight: 100
width: 95
contentItem: ColumnLayout {
IconButton {
label: button.label
Layout.maximumHeight: 60 * Constants.scalar
Layout.maximumWidth: 65 * Constants.scalar
Layout.maximumHeight: 60
Layout.maximumWidth: 65
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
@ -25,7 +25,7 @@ TabButton {
}
Text {
font.pixelSize: 16 * Constants.scalar
font.pixelSize: 16
text: label
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter

View file

@ -25,7 +25,7 @@ MouseArea {
Text {
id: txt
font.pixelSize: 12 * Constants.scalar
font.pixelSize: 12
leftPadding: 4
rightPadding: 4

View file

@ -25,14 +25,14 @@ TabBar {
highlight: Item {
z: 2
Rectangle {
radius: 5 * Constants.scalar
radius: 5
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
height: parent.height / 2
width: 5 * Constants.scalar
width: 5
color: Constants.accent
}
@ -41,6 +41,6 @@ TabBar {
background: Rectangle {
color: control.Material.backgroundColor
radius: 8 * Constants.scalar
radius: 8
}
}

View file

@ -38,8 +38,8 @@ SpinBox {
x: control.mirrored ? 0 : control.width - width
implicitWidth: 40 * Constants.scalar
implicitHeight: 40 * Constants.scalar
implicitWidth: 40
implicitHeight: 40
height: parent.height
width: height / 2
@ -52,8 +52,8 @@ SpinBox {
x: control.mirrored ? control.width - width : 0
implicitWidth: 40 * Constants.scalar
implicitHeight: 40 * Constants.scalar
implicitWidth: 40
implicitHeight: 40
height: parent.height
width: height / 2

View file

@ -24,13 +24,13 @@ TextField {
id: txt
text: suffix
font.pixelSize: 14 * Constants.scalar
font.pixelSize: 14
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: 5 * Constants.scalar
rightMargin: 5
}
color: "gray"

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Material
import Eden.Constants
Rectangle {
height: 2 * Constants.scalar
height: 2
color: enabled ? Constants.text : Qt.darker(Constants.text, 1.5)
width: parent.width

View file

@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
EdenModule(
NAME Main
URI Eden.Main
QML_FILES
Main.qml
StatusBar.qml
GameList.qml
GameGridCard.qml
GameGrid.qml
MarqueeText.qml
GameCarouselCard.qml
GameCarousel.qml
LIBRARIES Eden::Interface
)

View file

@ -0,0 +1,87 @@
import QtQuick
import QtQuick.Controls
import Qt.labs.platform
import QtCore
import Eden.Constants
import Eden.Interface
ListView {
id: carousel
focus: true
focusPolicy: Qt.StrongFocus
model: EdenGameList
orientation: ListView.Horizontal
clip: false
flickDeceleration: 1500
snapMode: ListView.SnapToItem
spacing: 20
keyNavigationWraps: true
function increment() {
incrementCurrentIndex()
if (currentIndex === count)
currentIndex = 0
}
function decrement() {
decrementCurrentIndex()
if (currentIndex === -1)
currentIndex = count - 1
}
// TODO(crueter): handle move/displace/add (requires thread worker on game list and a bunch of other shit)
Rectangle {
id: hg
clip: false
z: 3
property var item: carousel.currentItem
anchors {
centerIn: parent
}
height: item === null ? 0 : item.height + 10
width: item === null ? 0 : item.width + 10
color: "transparent"
border {
color: "deepskyblue"
width: 4
}
radius: 8
MarqueeText {
id: container
anchors.bottom: hg.top
anchors.left: hg.left
anchors.right: hg.right
canMarquee: true
text: hg.item === null ? "" : toTitleCase(hg.item.title)
font.pixelSize: 22
font.family: "Monospace"
color: "lightblue"
background: Constants.bg
}
}
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: currentItem === null ? 0 : x + width / 2 - currentItem.width / 2
preferredHighlightEnd: currentItem === null ? 0 : x + width / 2 + currentItem.width / 2
highlightMoveDuration: 300
delegate: GameCarouselCard {
id: game
width: 300
height: 300
}
}

View file

@ -17,7 +17,7 @@ Item {
anchors.fill: parent
color: "transparent"
border {
width: 4 * Constants.scalar
width: 4
color: PathView.isCurrentItem ? "deepskyblue" : "transparent"
}
@ -32,7 +32,7 @@ Item {
anchors {
fill: parent
margins: 10 * Constants.scalar
margins: 10
}
}
}

View file

@ -4,8 +4,7 @@ import Qt.labs.platform
import QtCore
import Eden.Constants
import Eden.Native.Interface
import Eden.Native.Gamepad
import Eden.Interface
GridView {
property var setting
@ -17,25 +16,25 @@ GridView {
clip: true
cellWidth: cellSize
cellHeight: cellSize + 60 * Constants.scalar
cellHeight: cellSize + 20
model: EdenGameList
delegate: GameGridCard {
id: game
width: grid.cellSize - 20 * Constants.scalar
height: grid.cellHeight - 20 * Constants.scalar
width: grid.cellSize - 20
height: grid.cellHeight - 20
}
highlight: Rectangle {
color: "transparent"
z: 5
radius: 16 * Constants.scalar
radius: 16
border {
color: Constants.text
width: 3
color: "deepskyblue"
width: 4
}
}

View file

@ -9,7 +9,7 @@ Rectangle {
id: wrapper
color: Constants.dialog
radius: 16 * Constants.scalar
radius: 16
Image {
id: image
@ -21,13 +21,14 @@ Rectangle {
anchors {
top: parent.top
bottom: nameText.top
left: parent.left
right: parent.right
margins: 4 * Constants.scalar
margins: 10
}
height: parent.height - 40 * Constants.scalar
height: parent.height
MouseArea {
id: mouseArea
@ -50,28 +51,29 @@ Rectangle {
}
}
Text {
MarqueeText {
id: nameText
clip: true
anchors {
bottom: parent.bottom
bottomMargin: 5 * Constants.scalar
bottomMargin: 5
left: parent.left
right: parent.right
leftMargin: 5
rightMargin: 5
}
style: Text.Outline
styleColor: Constants.bg
text: toTitleCase(model.name.replace(/-/g, " "))
text: model.name.replace(/-/g, " ")
wrapMode: Text.WordWrap
horizontalAlignment: Qt.AlignHCenter
font.pixelSize: 18
font.family: "Monospace"
font {
pixelSize: 15 * Constants.scalar
}
color: "lightblue"
background: Constants.dialog
color: "white"
canMarquee: wrapper.GridView.isCurrentItem
}
}

127
src/Eden/Main/GameList.qml Normal file
View file

@ -0,0 +1,127 @@
import QtQuick
import QtQuick.Controls
import Qt.labs.platform
import QtCore
import Eden.Constants
import Eden.Interface
// import Eden.Native.Gamepad
Rectangle {
id: root
property var setting: SettingsInterface.setting("grid_columns")
property int gx: 0
property int gy: 0
readonly property int deadzone: 8000
readonly property int repeatTimeMs: 125
color: Constants.bg
// TODO: use the original yuzu backend for dis
// Gamepad {
// id: gamepad
// // onUpPressed: grid.moveCurrentIndexUp()
// // onDownPressed: grid.moveCurrentIndexDown()
// // onLeftPressed: grid.moveCurrentIndexLeft()
// // onRightPressed: grid.moveCurrentIndexRight()
// onLeftPressed: carousel.decrement()
// onRightPressed: carousel.increment()
// onAPressed: console.log("A pressed")
// onLeftStickMoved: (x, y) => {
// gx = x
// gy = y
// }
// }
// Timer {
// interval: repeatTimeMs
// running: true
// repeat: true
// onTriggered: {
// if (gx > deadzone) {
// gamepad.rightPressed()
// } else if (gx < -deadzone) {
// gamepad.leftPressed()
// }
// if (gy > deadzone) {
// gamepad.downPressed()
// } else if (gy < -deadzone) {
// gamepad.upPressed()
// }
// }
// }
// Timer {
// interval: 16
// running: true
// repeat: true
// onTriggered: gamepad.pollEvents()
// }
FolderDialog {
id: openDir
folder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
onAccepted: {
button.visible = false
view.anchors.bottom = root.bottom
EdenGameList.addDir(folder)
}
}
Item {
id: view
anchors {
bottom: button.top
left: parent.left
right: parent.right
top: parent.top
margins: 8
}
GameGrid {
setting: root.setting
id: grid
anchors.fill: parent
}
// GameCarousel {
// id: carousel
// height: 300
// anchors {
// right: view.right
// left: view.left
// verticalCenter: view.verticalCenter
// }
// }
}
Button {
id: button
font.pixelSize: 25
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
margins: 8
}
text: "Add Directory"
onClicked: openDir.open()
background: Rectangle {
color: button.pressed ? Constants.accentPressed : Constants.accent
radius: 5
}
}
}

View file

@ -9,7 +9,7 @@ ApplicationWindow {
width: Constants.width
height: Constants.height
visible: true
title: qsTr("eden")
title: TitleManager.title
Material.theme: Material.Dark
Material.accent: Material.Red

View file

@ -0,0 +1,129 @@
import QtQuick
import QtQuick.Controls
import Eden.Constants
Item {
id: container
anchors {}
height: txt.contentHeight
clip: true
// TODO(crueter): util?
function toTitleCase(str) {
return str.replace(/\w\S*/g, text => text.charAt(0).toUpperCase(
) + text.substring(1).toLowerCase())
}
property string text
property string spacing: " "
property string combined: text + spacing
property string display: animate ? combined.substring(
step) + combined.substring(
0, step) : text
property int step: 0
property bool animate: canMarquee && txt.contentWidth > parent.width
property bool canMarquee: false
property font font
property color color
property color background
onCanMarqueeChanged: checkMarquee()
function checkMarquee() {
if (canMarquee && txt.contentWidth > width) {
step = 0
delay.start()
} else {
delay.stop()
marquee.stop()
}
}
Timer {
id: marquee
interval: 150
running: false
repeat: true
onTriggered: {
parent.step = (parent.step + 1) % parent.combined.length
if (parent.step === 0) {
stop()
delay.start()
}
}
}
Timer {
id: delay
interval: 1500
repeat: false
onTriggered: {
marquee.start()
}
}
// fake container to gauge contentWidth
Text {
id: txt
visible: false
text: parent.text
font: container.font
onContentWidthChanged: container.checkMarquee()
}
Text {
anchors {
fill: parent
leftMargin: 10
rightMargin: 10
}
color: container.color
font: container.font
text: parent.display
horizontalAlignment: Text.AlignLeft
}
Rectangle {
anchors.fill: parent
z: 2
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
position: 0.0
color: marquee.running ? container.background : "transparent"
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
GradientStop {
position: 0.1
color: "transparent"
}
GradientStop {
position: 0.9
color: "transparent"
}
GradientStop {
position: 1.0
color: marquee.running ? container.background : "transparent"
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
}
}
}

View file

@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
qt_add_library(EdenModels STATIC
GameListModel.h GameListModel.cpp
SettingsModel.h SettingsModel.cpp
)
target_link_libraries(EdenModels
PRIVATE
Qt6::Gui
)
add_library(Eden::Models ALIAS EdenModels)

View file

@ -2,7 +2,7 @@
#define SETTINGSMODEL_H
#include <QAbstractListModel>
#include "Native/Interface/QMLSetting.h"
#include "Interface/QMLSetting.h"
class SettingsModel : public QAbstractListModel {
Q_OBJECT

View file

@ -0,0 +1,65 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
qt_add_executable(eden
main.cpp
icons.qrc
)
set(MODULES
Eden::Util
Eden::Items
Eden::Config
Eden::Interface
Eden::Constants
Eden::Main
Eden::Models
)
# if (ENABLE_SDL2)
# add_subdirectory(Gamepad)
# set(MODULES ${MODULES} Eden::Gamepad)
# endif()
target_link_libraries(eden
PRIVATE
Qt6::Core
Qt6::Widgets
Qt6::Gui
Qt6::Quick
Qt6::QuickControls2
${MODULES}
)
target_link_libraries(eden PRIVATE common core input_common frontend_common qt_common network video_core)
target_link_libraries(eden PRIVATE Boost::headers glad fmt)
target_link_libraries(eden PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
target_link_libraries(eden PRIVATE Vulkan::Headers)
target_compile_definitions(eden PRIVATE
# Use QStringBuilder for string concatenation to reduce
# the overall number of temporary strings created.
-DQT_USE_QSTRINGBUILDER
# Disable implicit type narrowing in signal/slot connect() calls.
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT
# Disable unsafe overloads of QProcess' start() function.
-DQT_NO_PROCESS_COMBINED_ARGUMENT_START
# Disable implicit QString->QUrl conversions to enforce use of proper resolving functions.
-DQT_NO_URL_CAST_FROM_STRING
)
set_target_properties(eden PROPERTIES OUTPUT_NAME "eden")
include(GNUInstallDirs)
install(TARGETS eden
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View file

@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
EdenModule(
NAME Gamepad
URI Eden.Native.Gamepad
SOURCES gamepad.h gamepad.cpp
)

View file

@ -10,5 +10,6 @@
<file>icons/forward.svg</file>
<file>icons/back.svg</file>
<file>icons/help.svg</file>
<file alias="icons/eden.svg">../../../dist/dev.eden_emu.eden.svg</file>
</qresource>
</RCC>

View file

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 435 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 771 B

After

Width:  |  Height:  |  Size: 771 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 695 B

After

Width:  |  Height:  |  Size: 695 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 539 B

Before After
Before After

View file

@ -1,10 +1,11 @@
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "Interface/QMLConfig.h"
#include "Interface/SettingsInterface.h"
#include "Interface/TitleManager.h"
#include "Models/GameListModel.h"
#include "core/core.h"
#include "Native/Interface/QMLConfig.h"
#include "Native/Models/GameListModel.h"
#include "Native/Interface/SettingsInterface.h"
#include <QQuickStyle>
@ -17,6 +18,7 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationName(QStringLiteral("eden-emu"));
QCoreApplication::setApplicationName(QStringLiteral("eden"));
QApplication::setDesktopFileName(QStringLiteral("org.eden-emu.eden"));
QGuiApplication::setWindowIcon(QIcon(":/icons/eden.svg"));
/// Settings, etc
Settings::SetConfiguringGlobal(true);
@ -39,12 +41,20 @@ int main(int argc, char *argv[])
ctx->setContextProperty(QStringLiteral("QtConfig"), QVariant::fromValue(config));
// Enums
qmlRegisterUncreatableMetaObject(SettingsCategories::staticMetaObject, "Eden.Native.Interface", 1, 0, "SettingsCategories", QString());
qmlRegisterUncreatableMetaObject(SettingsCategories::staticMetaObject, "Eden.Interface", 1, 0, "SettingsCategories", QString());
// Directory List
GameListModel *gameListModel = new GameListModel(&app);
ctx->setContextProperty(QStringLiteral("EdenGameList"), gameListModel);
// Settings Interface
SettingsInterface *interface = new SettingsInterface(&engine);
ctx->setContextProperty(QStringLiteral("SettingsInterface"), interface);
// Title Manager
TitleManager *title = new TitleManager(&engine);
ctx->setContextProperty(QStringLiteral("TitleManager"), title);
/// LOAD
QObject::connect(
&engine,

View file

@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
set_source_files_properties(Util.qml
PROPERTIES
QT_QML_SINGLETON_TYPE true
)
EdenModule(
NAME Util
URI Eden.Util
QML_FILES
Util.qml
)

82
src/eden/.gitignore vendored
View file

@ -1,82 +0,0 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
*.qbs.user*
CMakeLists.txt.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# Directories with generated files
.moc/
.obj/
.pch/
.rcc/
.uic/
/build*/

View file

@ -1,9 +0,0 @@
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui Quick QuickControls2)
qt_standard_project_setup(REQUIRES 6.7)
add_subdirectory(Eden)

Some files were not shown because too many files have changed in this diff Show more