diff --git a/Source/Engine/Engine/Screen.cpp b/Source/Engine/Engine/Screen.cpp index 2fc58c7a3..cb2994129 100644 --- a/Source/Engine/Engine/Screen.cpp +++ b/Source/Engine/Engine/Screen.cpp @@ -135,6 +135,36 @@ void Screen::SetCursorLock(CursorLockMode mode) CursorLock = mode; } +void Screen::SetGameWindowMode(GameWindowMode windowMode) +{ +#if !USE_EDITOR + switch (windowMode) + { + case GameWindowMode::Windowed: + if (GetIsFullscreen()) + SetIsFullscreen(false); +#if (PLATFORM_WINDOWS) + Engine::MainWindow->SetBorderless(false, false); +#endif + break; + case GameWindowMode::Fullscreen: + SetIsFullscreen(true); + break; + case GameWindowMode::Borderless: +#if (PLATFORM_WINDOWS) + Engine::MainWindow->SetBorderless(true, false); +#endif + break; + case GameWindowMode::FullscreenBorderless: +#if (PLATFORM_WINDOWS) + Engine::MainWindow->SetBorderless(true, true); +#endif + break; + default: ; + } +#endif +} + void ScreenService::Update() { #if USE_EDITOR diff --git a/Source/Engine/Engine/Screen.h b/Source/Engine/Engine/Screen.h index 532529980..8f7d21766 100644 --- a/Source/Engine/Engine/Screen.h +++ b/Source/Engine/Engine/Screen.h @@ -2,6 +2,7 @@ #pragma once +#include "Engine/Core/Config/PlatformSettingsBase.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Input/Enums.h" #include "Engine/Core/Math/Vector2.h" @@ -80,4 +81,13 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Screen); /// /// The mode. API_PROPERTY() static void SetCursorLock(CursorLockMode mode); + + /// + /// Sets the game window mode. + /// + /// + /// A fullscreen mode switch may not happen immediately. It will be performed before next frame rendering. Will not work in editor. + /// + /// The window mode. + API_PROPERTY() static void SetGameWindowMode(GameWindowMode windowMode); }; diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h index 4220f1054..10b99d1cf 100644 --- a/Source/Engine/Platform/Base/WindowBase.h +++ b/Source/Engine/Platform/Base/WindowBase.h @@ -445,6 +445,15 @@ public: { } + /// + /// Sets the window to be borderless or not and to be fullscreen. + /// + /// Whether or not to have borders on window. + /// Whether or not to make the borderless window fullscreen. + API_FUNCTION() virtual void SetBorderless(bool isBorderless, bool fullscreen) + { + } + /// /// Restores the window state before minimizing or maximizing. /// diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp index 687eeed28..ec5850b13 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.cpp +++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp @@ -260,6 +260,76 @@ void WindowsWindow::Maximize() _isDuringMaximize = false; } +void WindowsWindow::SetBorderless(bool isBorderless, bool fullscreen) +{ + ASSERT(HasHWND()); + + if (IsFullscreen()) + SetIsFullscreen(false); + + // Fixes issue of borderless window not going full screen + if (IsMaximized()) + Restore(); + + _settings.HasBorder = !isBorderless; + + BringToFront(); + + if (isBorderless) + { + LONG lStyle = GetWindowLong(_handle, GWL_STYLE); + lStyle &= ~(WS_THICKFRAME | WS_SYSMENU | WS_OVERLAPPED | WS_BORDER | WS_CAPTION); + lStyle |= WS_POPUP; + lStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; +#if WINDOWS_USE_NEW_BORDER_LESS + if (_settings.IsRegularWindow) + style |= WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU | WS_THICKFRAME | WS_GROUP; +#elif WINDOWS_USE_NEWER_BORDER_LESS + if (_settings.IsRegularWindow) + lStyle |= WS_THICKFRAME | WS_SYSMENU; +#endif + + SetWindowLong(_handle, GWL_STYLE, lStyle); + SetWindowPos(_handle, HWND_TOP, 0, 0,0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + + if (fullscreen) + { + ShowWindow(_handle, SW_SHOWMAXIMIZED); + } + else + { + ShowWindow(_handle, SW_SHOW); + } + } + else + { + LONG lStyle = GetWindowLong(_handle, GWL_STYLE); + lStyle &= ~(WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + if (_settings.AllowMaximize) + lStyle |= WS_MAXIMIZEBOX; + if (_settings.AllowMinimize) + lStyle |= WS_MINIMIZEBOX; + if (_settings.HasSizingFrame) + lStyle |= WS_THICKFRAME; + // Create window style flags + lStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_BORDER | WS_CAPTION; + + SetWindowLong(_handle, GWL_STYLE, lStyle); + SetWindowPos(_handle, nullptr, 0, 0, (int)_settings.Size.X, (int)_settings.Size.Y, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + if (fullscreen) + { + Maximize(); + } + else + { + ShowWindow(_handle, SW_SHOW); + } + } + CheckForWindowResize(); +} + void WindowsWindow::Restore() { ASSERT(HasHWND()); diff --git a/Source/Engine/Platform/Windows/WindowsWindow.h b/Source/Engine/Platform/Windows/WindowsWindow.h index 74e923f86..cbbd8342d 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.h +++ b/Source/Engine/Platform/Windows/WindowsWindow.h @@ -100,6 +100,7 @@ public: void Hide() override; void Minimize() override; void Maximize() override; + void SetBorderless(bool isBorderless, bool fullscreen) override; void Restore() override; bool IsClosed() const override; bool IsForegroundWindow() const override;