From 72708c4868df99f65659655d96c16de533b7e201 Mon Sep 17 00:00:00 2001 From: N3xoX1 Date: Wed, 19 Mar 2025 09:30:28 +1030 Subject: [PATCH] Start to add new ui --- .gitmodules | 3 + config/NxEmu.config.development | 1 + external/sciterui | 1 + lang/english/css/base.css | 1 + lang/english/css/main_window.css | 102 ++++++++++++++++++ lang/english/html/main_window.html | 13 +++ lang/english/image/window-icon-32.png | Bin 0 -> 2921 bytes lang/english/image/window-icon.png | Bin 0 -> 31085 bytes nxemu.sln | 11 ++ src/nxemu/main.cpp | 38 +++++-- src/nxemu/nxemu.vcxproj | 18 +++- src/nxemu/nxemu.vcxproj.filters | 6 ++ src/nxemu/settings/ui_settings.cpp | 62 +++++++++-- src/nxemu/settings/ui_settings.h | 7 ++ .../user_interface/sciter_main_window.cpp | 45 ++++++++ src/nxemu/user_interface/sciter_main_window.h | 30 ++++++ 16 files changed, 315 insertions(+), 23 deletions(-) create mode 160000 external/sciterui create mode 100644 lang/english/css/base.css create mode 100644 lang/english/css/main_window.css create mode 100644 lang/english/html/main_window.html create mode 100644 lang/english/image/window-icon-32.png create mode 100644 lang/english/image/window-icon.png create mode 100644 src/nxemu/user_interface/sciter_main_window.cpp create mode 100644 src/nxemu/user_interface/sciter_main_window.h diff --git a/.gitmodules b/.gitmodules index 90b29097..9c4cacc4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,6 @@ [submodule "external/vulkan_utility_libraries"] path = external/vulkan_utility_libraries url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git +[submodule "external/sciterui"] + path = external/sciterui + url = https://github.com/N3xoX1/sciterui.git diff --git a/config/NxEmu.config.development b/config/NxEmu.config.development index 318f44ac..3488e860 100644 --- a/config/NxEmu.config.development +++ b/config/NxEmu.config.development @@ -4,6 +4,7 @@ "ModuleDirectory-x64" : "..\\..\\..\\modules\\x64" }, "UI" : { + "LanguageDirectory" : "..\\..\\..\\lang", "EnableModuleConfiguration" : true } } diff --git a/external/sciterui b/external/sciterui new file mode 160000 index 00000000..bb76cd6d --- /dev/null +++ b/external/sciterui @@ -0,0 +1 @@ +Subproject commit bb76cd6d4d213a647d18361b08b7cbbbe417bf58 diff --git a/lang/english/css/base.css b/lang/english/css/base.css new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/lang/english/css/base.css @@ -0,0 +1 @@ + diff --git a/lang/english/css/main_window.css b/lang/english/css/main_window.css new file mode 100644 index 00000000..5fb7b27d --- /dev/null +++ b/lang/english/css/main_window.css @@ -0,0 +1,102 @@ +html +{ + border: none; + background-color: #232629; +} + +html[window-state="maximized"] +{ + border: window-frame-width solid transparent; +} + +html > header +{ + width: *; + flow: horizontal; + background-color: threedface; + height: window-caption-height; + margin: 0; +} + +html > header > window-caption +{ + display: block; + line-height: window-caption-height; + width: *; + padding: 0 1em; + font-family: 'Segoe UI', Arial, sans-serif; + font-size: 0.9em; + font-weight: 100; +} + +html > header > window-caption span +{ + vertical-align: middle; +} + +html > header > window-caption img +{ + vertical-align: middle; + margin-right: 0.4em; + width: 1.5em; + height: 1.5em; +} + + +html > header > window-buttons +{ + display: block; + flow: horizontal; + width: max-content; + height: *; +} + +html > header > window-buttons > window-button { + behavior: clickable; + display: block; + height: *; + width: window-button-width; + foreground-size: 2em 1.5em; + foreground-repeat: no-repeat; + foreground-position: 50% 50%; + stroke-width: 0; + fill: #000000; + transition: background-color linear 100ms; + padding: 0.25em; +} + +html > header > window-buttons > window-button:hover +{ + background: rgba(0,0,0,0.25); +} + +html > header > window-buttons > window-button[role="window-close"] +{ + foreground-image: url(icon:window-close); +} + +html > header > window-buttons > window-button[role="window-close"]:hover +{ + background: rgb(232,17,35); + fill: #fff; +} + +html > header > window-buttons > window-button[role="window-maximize"] +{ + foreground-image: url(icon:window-maximize); +} + +html[window-state="maximized"] +{ + border-color: transparent; +} + +html[window-state="maximized"] > header > window-buttons > window-button[role="window-maximize"] +{ + foreground-image: url(icon:window-restore); +} + +html > header > window-buttons > window-button[role="window-minimize"] +{ + foreground-image: url(icon:window-minimize); +} \ No newline at end of file diff --git a/lang/english/html/main_window.html b/lang/english/html/main_window.html new file mode 100644 index 00000000..03049e6c --- /dev/null +++ b/lang/english/html/main_window.html @@ -0,0 +1,13 @@ + + + + NxEmu + +
+ NxEmu + + + + +
+ diff --git a/lang/english/image/window-icon-32.png b/lang/english/image/window-icon-32.png new file mode 100644 index 0000000000000000000000000000000000000000..7d6256294c5ad923ecd265eb0084a490853603dd GIT binary patch literal 2921 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 Tdxlyi00000NkvXXu0mjfhOwgT literal 0 HcmV?d00001 diff --git a/lang/english/image/window-icon.png b/lang/english/image/window-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..76a295f3a0853d5613b98d4ff930904ee86a405d GIT binary patch literal 31085 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

UiYDNdk)R1V>zIU|S>YM3^U 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 #include #include #include +#include #include int WINAPI WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInstance*/, _In_ LPSTR /*lpszArgs*/, _In_ int /*nWinMode*/) { - if (!AppInit(&Notification::GetInstance())) - { - return 1; - } + bool Res = AppInit(&Notification::GetInstance()); - std::unique_ptr mainWindow = std::make_unique(stdstr_f("NXEmu %s", VER_FILE_VERSION_STR).ToUTF16().c_str()); - mainWindow->ShowWindow(true); - mainWindow->ProcessAllMessages(); - mainWindow.reset(nullptr); + if (uiSettings.sciterUI && Res) + { + ISciterUI * sciterUI = nullptr; + if (Res && !SciterUIInit(uiSettings.languageDir, uiSettings.languageBase.c_str(), uiSettings.languageCurrent.c_str(), uiSettings.sciterConsole, sciterUI)) + { + Res = false; + } + if (Res) + { + SciterMainWindow window(*sciterUI); + window.Show(); + sciterUI->Run(); + } + if (sciterUI != nullptr) + { + sciterUI->Shutdown(); + } + } + else if (Res) + { + std::unique_ptr mainWindow = std::make_unique(stdstr_f("NXEmu %s", VER_FILE_VERSION_STR).ToUTF16().c_str()); + mainWindow->ShowWindow(true); + mainWindow->ProcessAllMessages(); + mainWindow.reset(nullptr); + } AppCleanup(); Notification::CleanUp(); - return 0; + return Res ? 0 : 1; } \ No newline at end of file diff --git a/src/nxemu/nxemu.vcxproj b/src/nxemu/nxemu.vcxproj index 3d48877f..d70da203 100644 --- a/src/nxemu/nxemu.vcxproj +++ b/src/nxemu/nxemu.vcxproj @@ -13,23 +13,26 @@ {c8659f5a-3afa-4bf0-9409-3b9819e17714} nxemu - 10.0 Application - + - + - stdcpp20 + $(SolutionDir)external\sciterui\include;%(AdditionalIncludeDirectories) - IF NOT EXIST "$(SolutionDir)config\NxEmu.config" (copy "$(SolutionDir)config\NxEmu.config.development" "$(SolutionDir)config\NxEmu.config") + IF NOT EXIST "$(SolutionDir)config\NxEmu.config" (copy "$(SolutionDir)config\NxEmu.config.development" "$(SolutionDir)config\NxEmu.config") + + + xcopy /Y /D "$(SolutionDir)external\sciterui\src\3rd_party\sciter-js-sdk-main\bin\windows.d2d\x64\sciter.dll" "$(OutDir)" + @@ -38,6 +41,7 @@ + @@ -51,6 +55,7 @@ + @@ -58,6 +63,9 @@ + + {847b64ee-2c78-48f9-912b-d700f2a5cb91} + {ec81be93-8316-4db6-8a26-b13fb5b13848} diff --git a/src/nxemu/nxemu.vcxproj.filters b/src/nxemu/nxemu.vcxproj.filters index 5b70f14c..336261d8 100644 --- a/src/nxemu/nxemu.vcxproj.filters +++ b/src/nxemu/nxemu.vcxproj.filters @@ -72,6 +72,9 @@ Source Files\user_interface\wtl_controls + + Source Files\user_interface + @@ -107,6 +110,9 @@ Header Files\user_interface\wtl_controls + + Header Files\user_interface + diff --git a/src/nxemu/settings/ui_settings.cpp b/src/nxemu/settings/ui_settings.cpp index 56b7dbcd..c06de8c6 100644 --- a/src/nxemu/settings/ui_settings.cpp +++ b/src/nxemu/settings/ui_settings.cpp @@ -1,5 +1,6 @@ #include "ui_settings.h" #include +#include #include namespace @@ -7,6 +8,13 @@ namespace struct UISettingsDefaults { static constexpr bool enableModuleConfiguration = false; + static constexpr bool sciterUI = false; + static constexpr const char * defaultLanguageDirValue = "./lang"; + static constexpr const char * defaultLanguageBaseValue = "english"; + static constexpr const char * defaultLanguageCurrentValue = "english"; + static constexpr bool defaultSciterConsole = false; + + static Path GetDefaultLanguageDir(); }; } // namespace @@ -16,21 +24,50 @@ void LoadUISetting(void) { uiSettings = {}; uiSettings.enableModuleConfiguration = UISettingsDefaults::enableModuleConfiguration; + uiSettings.sciterUI = UISettingsDefaults::sciterUI; + uiSettings.languageDir = UISettingsDefaults::GetDefaultLanguageDir(); + uiSettings.languageDirValue = UISettingsDefaults::defaultLanguageDirValue; + uiSettings.languageBase = UISettingsDefaults::defaultLanguageBaseValue; + uiSettings.languageCurrent = UISettingsDefaults::defaultLanguageCurrentValue; + uiSettings.sciterConsole = UISettingsDefaults::defaultSciterConsole; - JsonValue settings = Settings::GetInstance().GetSettings("UI"); + JsonValue jsonSettings = Settings::GetInstance().GetSettings("UI"); - const JsonValue * modConfig = settings.Find("EnableModuleConfiguration"); - if (modConfig != nullptr && modConfig->isBool()) + const JsonValue * node = jsonSettings.Find("EnableModuleConfiguration"); + if (node != nullptr && node->isBool()) { - uiSettings.enableModuleConfiguration = modConfig->asBool(); + uiSettings.enableModuleConfiguration = node->asBool(); } - const JsonValue * recentFiles = settings.Find("RecentFiles"); - if (recentFiles != nullptr && recentFiles->isArray()) + node = jsonSettings.Find("SciterUI"); + if (node != nullptr && node->isBool()) { - for (uint32_t i = 0; i < recentFiles->size(); i++) + uiSettings.sciterUI = node->asBool(); + } + + node = jsonSettings.Find("LanguageDirectory"); + if (node != nullptr && node->isString()) + { + std::string dirValue = node->asString(); + if (!dirValue.empty()) { - const JsonValue & file = (*recentFiles)[i]; + uiSettings.languageDirValue = dirValue; + uiSettings.languageDir = Path(uiSettings.languageDirValue, "").DirectoryNormalize(Path(Path::MODULE_DIRECTORY)); + } + } + + node = jsonSettings.Find("SciterConsole"); + if (node != nullptr && node->isBool()) + { + uiSettings.sciterConsole = node->asBool(); + } + + node = jsonSettings.Find("RecentFiles"); + if (node != nullptr && node->isArray()) + { + for (uint32_t i = 0; i < node->size(); i++) + { + const JsonValue & file = (*node)[i]; if (file.isString()) { uiSettings.recentFiles.push_back(file.asString()); @@ -60,4 +97,11 @@ void SaveUISetting(void) Settings & settings = Settings::GetInstance(); settings.SetSettings("UI", json); settings.Save(); -} \ No newline at end of file +} + +Path UISettingsDefaults::GetDefaultLanguageDir() +{ + Path dir(Path::MODULE_DIRECTORY); + dir.AppendDirectory("lang"); + return dir; +} diff --git a/src/nxemu/settings/ui_settings.h b/src/nxemu/settings/ui_settings.h index 0de5ff9b..3bb07f93 100644 --- a/src/nxemu/settings/ui_settings.h +++ b/src/nxemu/settings/ui_settings.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include @@ -8,6 +9,12 @@ struct UISettings { Stringlist recentFiles; bool enableModuleConfiguration; + bool sciterUI; + Path languageDir; + std::string languageDirValue; + std::string languageBase; + std::string languageCurrent; + bool sciterConsole; }; extern UISettings uiSettings; diff --git a/src/nxemu/user_interface/sciter_main_window.cpp b/src/nxemu/user_interface/sciter_main_window.cpp new file mode 100644 index 00000000..f746bbf1 --- /dev/null +++ b/src/nxemu/user_interface/sciter_main_window.cpp @@ -0,0 +1,45 @@ +#include "sciter_main_window.h" +#include +#include +#include + +SciterMainWindow::SciterMainWindow(ISciterUI& SciterUI) : + m_sciterUI(SciterUI), + m_renderWindow(nullptr) +{ +} +bool SciterMainWindow::Show(void) +{ + enum + { + WINDOW_HEIGHT = 507, + WINDOW_WIDTH = 760, + }; + + if (!m_sciterUI.WindowCreate(nullptr, "main_window.html", 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, m_window)) + { + return false; + } + + m_window->OnDestroySinkAdd(this); + m_window->CenterWindow(); + stdstr_f windowTitle("NxEmu - %s", VER_FILE_VERSION_STR); + SciterElement rootElement(m_window->GetRootElement()); + rootElement.Eval(stdstr_f("Window.this.caption = \"%s\";", windowTitle.c_str()).c_str()); + SciterElement caption(rootElement.FindFirst("[role='window-caption'] > span")); + if (caption.IsValid()) + { + caption.SetHTML((uint8_t *)windowTitle.data(), windowTitle.size()); + } + return true; +} + +void SciterMainWindow::OnWindowDestroy(HWINDOW /*hWnd*/) +{ + m_sciterUI.Stop(); +} + +void * SciterMainWindow::RenderSurface(void) const +{ + return m_renderWindow; +} diff --git a/src/nxemu/user_interface/sciter_main_window.h b/src/nxemu/user_interface/sciter_main_window.h new file mode 100644 index 00000000..87a1f6c5 --- /dev/null +++ b/src/nxemu/user_interface/sciter_main_window.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include + +class SciterMainWindow : + public IWindowDestroySink, + public IRenderWindow +{ + +public: + SciterMainWindow(ISciterUI & SciterUI); + + bool Show(void); + +private: + SciterMainWindow(void) = delete; + SciterMainWindow(const SciterMainWindow&) = delete; + SciterMainWindow& operator=(const SciterMainWindow&) = delete; + + // IWindowDestroySink + void OnWindowDestroy(HWINDOW hWnd); + + // IRenderWindow + void * RenderSurface(void) const; + + ISciterUI & m_sciterUI; + ISciterWindow * m_window; + void * m_renderWindow; +}; +