diff --git a/external/sciterui b/external/sciterui index 1676af47..c279e41b 160000 --- a/external/sciterui +++ b/external/sciterui @@ -1 +1 @@ -Subproject commit 1676af47dfdbb60f0b7b5fe9930131ff6e5baec7 +Subproject commit c279e41bfc92eaf4a7c093d40526250234d4b139 diff --git a/lang/english/css/base.css b/lang/english/css/base.css index 04d88b16..d6c34b9e 100644 --- a/lang/english/css/base.css +++ b/lang/english/css/base.css @@ -235,6 +235,102 @@ menu li .menu-item-label text-align: left; } +menu li:has-child-of-type(menu) caption +{ + width: *; + text-align: left; +} + +menu li:current caption, +menu li:hover:owns-popup caption +{ + color: #f0f0f0; +} + +menu li .menu-item-glyph +{ + width: 1.15em; + min-width: 1.15em; + max-width: 1.15em; + min-height: 1.15em; + max-height: 1.15em; + margin: 0 0.55em 0 0; + box-sizing: border-box; + display: inline-block; + vertical-align: middle; + flex-shrink: 0; + foreground-image: none; +} + +menu li .menu-item-glyph.menu-item-glyph-spacer +{ + border: 1.5px solid transparent; + border-radius: 3px; + position: relative; +} + +menu li .menu-item-glyph.menu-item-checkbox +{ + border: 1.5px solid var(--color-ui-text-muted, #8c8c8c); + border-radius: 3px; + position: relative; + foreground-image: none; +} + +menu li .menu-item-glyph.menu-item-checkbox.checked +{ + border-color: var(--color-ui-text-primary, #f0f0f0); +} + +menu li .menu-item-glyph.menu-item-icon-svg +{ + border: none; + width: 1.15em; + height: 1.15em; + min-width: 1.15em; + max-width: 1.15em; + padding: 0; +} + +menu li .menu-item-glyph.menu-item-icon-svg svg +{ + width: 1.05em; + height: 1.05em; + display: block; + vertical-align: middle; +} + +menu li .menu-item-glyph.menu-item-icon-svg path +{ + fill: currentColor; +} + +menu li .menu-item-glyph .menu-item-checkmark +{ + position: absolute; + left: 0; + top: 0; + width: *; + height: *; + text-align: center; + vertical-align: middle; + font-size: 0.72em; + line-height: 1.15em; + color: var(--color-ui-text-primary, #f0f0f0); +} + +menu li:current .menu-item-glyph.menu-item-checkbox, +menu li:hover:owns-popup .menu-item-glyph.menu-item-checkbox +{ + border-color: #f0f0f0; +} + +menu li:current .menu-item-glyph .menu-item-checkmark, +menu li:hover:owns-popup .menu-item-glyph .menu-item-checkmark +{ + color: #f0f0f0; +} + menu li .menu-accelerator { width: max-content; diff --git a/lang/english/image/fullscreen.svg b/lang/english/image/fullscreen.svg new file mode 100644 index 00000000..8bbb3feb --- /dev/null +++ b/lang/english/image/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/nxemu/settings/ui_settings.cpp b/src/nxemu/settings/ui_settings.cpp index ca035b86..215900b5 100644 --- a/src/nxemu/settings/ui_settings.cpp +++ b/src/nxemu/settings/ui_settings.cpp @@ -98,6 +98,7 @@ namespace {nullptr, "PerformVulkanCheck", &uiSettings.performVulkanCheck, true}, {nullptr, nullptr, &uiSettings.hasBrokenVulkan, false}, {nullptr, nullptr, &uiSettings.enableAllControllers, false}, + {nullptr, "View\\StartGamesInFullscreen", &uiSettings.startGamesInFullscreen, false}, {NXUISetting::Hotkeys, "Hotkeys", &uiSettings.hotkeys, &g_defaultHotkeys}, }; diff --git a/src/nxemu/settings/ui_settings.h b/src/nxemu/settings/ui_settings.h index 125ea50c..8d4d76a1 100644 --- a/src/nxemu/settings/ui_settings.h +++ b/src/nxemu/settings/ui_settings.h @@ -19,6 +19,7 @@ struct UISettings bool performVulkanCheck; bool hasBrokenVulkan; bool enableAllControllers; + bool startGamesInFullscreen; HotkeyMap hotkeys; }; diff --git a/src/nxemu/user_interface/sciter_main_window.cpp b/src/nxemu/user_interface/sciter_main_window.cpp index 04a6485f..59e7b0e9 100644 --- a/src/nxemu/user_interface/sciter_main_window.cpp +++ b/src/nxemu/user_interface/sciter_main_window.cpp @@ -89,6 +89,7 @@ SciterMainWindow::SciterMainWindow(ISciterUI & sciterUI, const char * windowTitl m_renderWindow(nullptr), m_windowTitle(windowTitle), m_emulationRunning(false), + m_pendingStartInFullscreen(false), m_win32Fullscreen(std::make_unique()) { SettingsStore & settings = SettingsStore::GetInstance(); @@ -110,6 +111,12 @@ SciterMainWindow::SciterMainWindow(ISciterUI & sciterUI, const char * windowTitl m_useMultiCore = settings.GetBool(NXOsSetting::UseMultiCore); m_useSpeedLimit = settings.GetBool(NXOsSetting::UseSpeedLimit); m_speedLimit = settings.GetBool(NXOsSetting::SpeedLimit); + + std::vector resource; + if (m_sciterUI.LoadResource("fullscreen.svg", resource)) + { + m_fullscreenMenuSvg.assign(reinterpret_cast(resource.data()), resource.size()); + } } SciterMainWindow::~SciterMainWindow() @@ -184,7 +191,16 @@ void SciterMainWindow::ResetMenu() } MenuBarItemList viewMenu; - viewMenu.push_back(MenuBarItem(static_cast(GuiAction::ToggleFullscreen),"&Fullscreen",nullptr,HotkeyAccelerator(Hotkey::Fullscreen))); + if (!m_emulationRunning) + { + viewMenu.push_back(MenuBarItem(static_cast(GuiAction::ToggleStartGamesInFullscreen), "&Start games in fullscreen", nullptr, nullptr, uiSettings.startGamesInFullscreen ? MenuBarItem::CheckState::Checked : MenuBarItem::CheckState::Unchecked)); + viewMenu.push_back(MenuBarItem(MenuBarItem::SPLITER)); + } + if (m_emulationRunning) + { + const std::string * fullscreenSvg = m_fullscreenMenuSvg.empty() ? nullptr : &m_fullscreenMenuSvg; + viewMenu.push_back(MenuBarItem(static_cast(GuiAction::ToggleFullscreen), "&Fullscreen", nullptr, HotkeyAccelerator(Hotkey::Fullscreen), MenuBarItem::CheckState::None, fullscreenSvg)); + } MenuBarItemList resetWindowSizeMenu; resetWindowSizeMenu.push_back(MenuBarItem(static_cast(GuiAction::ResetWindowSize720p),"Reset Window Size to 720p")); resetWindowSizeMenu.push_back(MenuBarItem(static_cast(GuiAction::ResetWindowSize900p),"Reset Window Size to 900p")); @@ -359,6 +375,11 @@ void SciterMainWindow::EmulationRunning(const char * /*setting*/, void * userDat SciterMainWindow * impl = (SciterMainWindow *)userData; SettingsStore & settings = SettingsStore::GetInstance(); impl->m_emulationRunning = settings.GetBool(NXCoreSetting::EmulationRunning); + impl->m_pendingStartInFullscreen = impl->m_emulationRunning && uiSettings.startGamesInFullscreen; + if (!impl->m_emulationRunning && impl->m_win32Fullscreen && impl->m_win32Fullscreen->active) + { + impl->ExitFullscreen(); + } if (settings.GetBool(NXCoreSetting::ShuttingDown)) { return; @@ -406,6 +427,11 @@ void SciterMainWindow::EmulationStateChanged(const char * /*setting*/, void * us } else if (state == EmulationState::Running) { + if (impl->m_pendingStartInFullscreen && uiSettings.startGamesInFullscreen) + { + impl->m_pendingStartInFullscreen = false; + impl->EnterFullscreen(); + } impl->m_rootElement.PostEvent(EVENT_EMULATION_RUNNING); impl->ResetMenu(); } @@ -721,6 +747,17 @@ void SciterMainWindow::OnToggleDockedMode() store.SetInt(NXOsSetting::DockedMode, static_cast(docked ? Settings::DockedMode::Handheld : Settings::DockedMode::Docked)); } +void SciterMainWindow::OnToggleStartGamesInFullscreen() +{ + if (m_emulationRunning) + { + return; + } + uiSettings.startGamesInFullscreen = !uiSettings.startGamesInFullscreen; + SaveUISetting(); + ResetMenu(); +} + void SciterMainWindow::OnRecetGame(uint32_t fileIndex) { Stringlist & recentFiles = uiSettings.recentFiles; @@ -771,6 +808,9 @@ void SciterMainWindow::OnGuiAction(GuiAction action) case GuiAction::ToggleFullscreen: ToggleFullscreen(); break; + case GuiAction::ToggleStartGamesInFullscreen: + OnToggleStartGamesInFullscreen(); + break; case GuiAction::ToggleDockedMode: OnToggleDockedMode(); break; @@ -812,9 +852,13 @@ bool SciterMainWindow::OnKeyDown(SCITER_ELEMENT /*element*/, SCITER_ELEMENT /*it } if (strcmp(hotkeyId, Hotkey::Fullscreen) == 0) { - m_win32Fullscreen->pendingSwallowKeyUp = (uint32_t)keyCode; - OnGuiAction(GuiAction::ToggleFullscreen); - return true; + const bool allowFullscreen = m_emulationRunning || (m_win32Fullscreen != nullptr && m_win32Fullscreen->active); + if (allowFullscreen) + { + m_win32Fullscreen->pendingSwallowKeyUp = (uint32_t)keyCode; + OnGuiAction(GuiAction::ToggleFullscreen); + return true; + } } const GuiAction fromKey = HotkeyToGuiAction(hotkeyId); if (fromKey != GuiAction::Invalid) @@ -939,7 +983,7 @@ void SciterMainWindow::ToggleFullscreen() { ExitFullscreen(); } - else + else if (m_emulationRunning) { EnterFullscreen(); } @@ -947,7 +991,7 @@ void SciterMainWindow::ToggleFullscreen() void SciterMainWindow::EnterFullscreen() { - if (m_window == nullptr || !m_win32Fullscreen || m_win32Fullscreen->active) + if (m_window == nullptr || !m_win32Fullscreen || m_win32Fullscreen->active || !m_emulationRunning) { return; } diff --git a/src/nxemu/user_interface/sciter_main_window.h b/src/nxemu/user_interface/sciter_main_window.h index 067f87c8..086ade6e 100644 --- a/src/nxemu/user_interface/sciter_main_window.h +++ b/src/nxemu/user_interface/sciter_main_window.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include #include @@ -37,6 +38,7 @@ class SciterMainWindow : OpenControllersDialog, OpenSystemConfiguration, ToggleFullscreen, + ToggleStartGamesInFullscreen, ToggleDockedMode, ResetWindowSize720p, ResetWindowSize900p, @@ -92,6 +94,7 @@ private: void OnInputConfig(); void OnRecetGame(uint32_t fileIndex); void OnToggleDockedMode(); + void OnToggleStartGamesInFullscreen(); void UpdateStatusBar(); const MenuBarAccelerator * HotkeyAccelerator(const char * name); const char * IsMenuBarAccelerator(uint32_t keyCode, uint32_t keyboardState); @@ -156,6 +159,8 @@ private: bool m_useSpeedLimit; uint32_t m_speedLimit; bool m_emulationRunning; + bool m_pendingStartInFullscreen; + std::string m_fullscreenMenuSvg; #ifdef _WIN32 std::unique_ptr m_win32Fullscreen; #endif