From 1eb899b2402768a90b2faf089a3907bd8807ea5e Mon Sep 17 00:00:00 2001 From: max Date: Sat, 6 Jul 2024 01:29:12 +0200 Subject: [PATCH] gui events fix scroll input handle gui side, move and closed events --- Nerfed.Runtime/Engine.cs | 2 +- Nerfed.Runtime/Gui/Controller.cs | 42 ++++++++++++++++++++++--- Nerfed.Runtime/Input/Devices/Mouse.cs | 10 +++--- Nerfed.Runtime/Window/ScreenMode.cs | 7 +++-- Nerfed.Runtime/Window/Window.cs | 44 +++++++++++++++------------ 5 files changed, 73 insertions(+), 32 deletions(-) diff --git a/Nerfed.Runtime/Engine.cs b/Nerfed.Runtime/Engine.cs index 486b151..f02da70 100644 --- a/Nerfed.Runtime/Engine.cs +++ b/Nerfed.Runtime/Engine.cs @@ -153,8 +153,8 @@ private static void Tick() ProcessSDLEvents(); - Controller.Update((float)Timestep.TotalSeconds); // Tick game here... + Controller.Update((float)Timestep.TotalSeconds); AudioDevice.WakeThread(); accumulatedUpdateTime -= Timestep; diff --git a/Nerfed.Runtime/Gui/Controller.cs b/Nerfed.Runtime/Gui/Controller.cs index b9a5b72..e11c366 100644 --- a/Nerfed.Runtime/Gui/Controller.cs +++ b/Nerfed.Runtime/Gui/Controller.cs @@ -113,7 +113,7 @@ public Controller(GraphicsDevice graphicsDevice, Window mainWindow, Color clearC mainViewport.PlatformHandle = mainWindow.Handle; GCHandle handle = GCHandle.Alloc(mainWindow); mainViewport.PlatformUserData = (IntPtr)handle; - windows.Add(mainWindow, handle); + AddWindow(mainWindow, mainViewport, handle); unsafe { @@ -504,7 +504,11 @@ out int bytesPerPixel #region Window private void CreateWindow(ImGuiViewportPtr vp) { - WindowCreateInfo info = new WindowCreateInfo("Window Title", (uint)vp.Pos.X, (uint)vp.Pos.Y, ScreenMode.Windowed); + // TODO: Handle all flags. + ScreenMode screenMode = vp.Flags.HasFlag(ImGuiViewportFlags.NoDecoration) ? ScreenMode.WindowedBorderless : ScreenMode.Windowed; + bool systemResizable = !vp.Flags.HasFlag(ImGuiViewportFlags.NoDecoration); + + WindowCreateInfo info = new WindowCreateInfo("Window Title", (uint)vp.Pos.X, (uint)vp.Pos.Y, screenMode, systemResizable, false); Window window = new Window(graphicsDevice, info); graphicsDevice.ClaimWindow(window, SwapchainComposition.SDR, PresentMode.Immediate); // What PresentMode do we need? @@ -512,7 +516,7 @@ private void CreateWindow(ImGuiViewportPtr vp) GCHandle handle = GCHandle.Alloc(window); vp.PlatformUserData = (IntPtr)handle; - windows.Add(window, handle); + AddWindow(window, vp, handle); } private void DestroyWindow(ImGuiViewportPtr vp) @@ -528,8 +532,38 @@ private void DestroyWindow(ImGuiViewportPtr vp) windows.Remove(window); } - graphicsDevice.Wait(); + //graphicsDevice.Wait(); window.Dispose(); + + vp.PlatformUserData = IntPtr.Zero; + } + + private void AddWindow(Window window, ImGuiViewportPtr vp, GCHandle handle) + { + window.OnResizedEvent += ((win, w, h) => { + vp.PlatformRequestResize = true; + }); + + window.OnMovedEvent += ((win, x, y) => + { + vp.PlatformRequestMove = true; + }); + + window.OnCloseEvent += (win) => + { + ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); + + for (int i = 0; i < platformIO.Viewports.Capacity; i++) + { + ImGuiViewportPtr vp = platformIO.Viewports[i]; + if(win == (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target) + { + DestroyWindow(vp); + } + } + }; + + windows.Add(window, handle); } private void ShowWindow(ImGuiViewportPtr vp) diff --git a/Nerfed.Runtime/Input/Devices/Mouse.cs b/Nerfed.Runtime/Input/Devices/Mouse.cs index 6386fcd..d87f98b 100644 --- a/Nerfed.Runtime/Input/Devices/Mouse.cs +++ b/Nerfed.Runtime/Input/Devices/Mouse.cs @@ -1,5 +1,5 @@ -using System.Numerics; -using SDL2; +using SDL2; +using System.Numerics; namespace Nerfed.Runtime; @@ -65,6 +65,8 @@ public static int GetWheelHorizontal() internal static void Update() { + wheelX = 0; + wheelY = 0; Array.Copy(buttonStates, lastButtonStates, buttonStates.Length); } @@ -105,8 +107,8 @@ private static void ProcessButtonUpEvent(ref SDL.SDL_MouseButtonEvent ev) private static void ProcessWheelEvent(ref SDL.SDL_MouseWheelEvent ev) { - wheelX += ev.x; - wheelY += ev.y; + wheelX = ev.x; + wheelY = ev.y; } private static void ProcessMotionEvent(ref SDL.SDL_MouseMotionEvent ev) diff --git a/Nerfed.Runtime/Window/ScreenMode.cs b/Nerfed.Runtime/Window/ScreenMode.cs index e9a34ff..3228b38 100644 --- a/Nerfed.Runtime/Window/ScreenMode.cs +++ b/Nerfed.Runtime/Window/ScreenMode.cs @@ -3,6 +3,7 @@ namespace Nerfed.Runtime; public enum ScreenMode { Fullscreen, - BorderlessFullscreen, - Windowed -} + FullscreenBorderless, + Windowed, + WindowedBorderless +} \ No newline at end of file diff --git a/Nerfed.Runtime/Window/Window.cs b/Nerfed.Runtime/Window/Window.cs index 42b9066..56ca056 100644 --- a/Nerfed.Runtime/Window/Window.cs +++ b/Nerfed.Runtime/Window/Window.cs @@ -11,6 +11,10 @@ namespace Nerfed.Runtime; /// public class Window { + public event Action OnResizedEvent; + public event Action OnMovedEvent; + public event Action OnCloseEvent; + internal IntPtr Handle { get; } public ScreenMode ScreenMode { get; private set; } public uint Width { get; private set; } @@ -33,9 +37,7 @@ public class Window public string Title { get; private set;} private bool IsDisposed; - private System.Action SizeChangeCallback = null; - - private static readonly Dictionary windowsById = new Dictionary(); + private static readonly Dictionary windowsById = new Dictionary(); public Window(GraphicsDevice graphicsDevice, WindowCreateInfo windowCreateInfo) { @@ -54,10 +56,14 @@ public Window(GraphicsDevice graphicsDevice, WindowCreateInfo windowCreateInfo) { flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN; } - else if (windowCreateInfo.ScreenMode == ScreenMode.BorderlessFullscreen) + else if (windowCreateInfo.ScreenMode == ScreenMode.FullscreenBorderless) { flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; } + else if(windowCreateInfo.ScreenMode == ScreenMode.WindowedBorderless) + { + flags |= SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS; + } if (windowCreateInfo.SystemResizable) { @@ -104,29 +110,35 @@ internal static void ProcessEvent(ref SDL.SDL_Event ev) case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED: window.ProcessSizeChangedEvent(ref ev.window); break; + case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_MOVED: + window.ProcessMovedChangedEvent(ref ev.window); + break; case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE: window.ProcessCloseEvent(ref ev.window); break; } } - private void ProcessSizeChangedEvent(ref SDL.SDL_WindowEvent ev) + private void ProcessSizeChangedEvent(ref SDL.SDL_WindowEvent ev) { uint newWidth = (uint)ev.data1; uint newHeight = (uint)ev.data2; Width = newWidth; Height = newHeight; - if (SizeChangeCallback != null) - { - SizeChangeCallback(newWidth, newHeight); - } + OnResizedEvent?.Invoke(this, Width, Height); } - private void ProcessCloseEvent(ref SDL.SDL_WindowEvent ev) + private void ProcessMovedChangedEvent(ref SDL.SDL_WindowEvent ev) + { + OnMovedEvent?.Invoke(this, ev.data1, ev.data2); + } + + private void ProcessCloseEvent(ref SDL.SDL_WindowEvent ev) { Engine.GraphicsDevice.UnclaimWindow(this); Dispose(); + OnCloseEvent?.Invoke(this); } /// @@ -140,7 +152,7 @@ public void SetScreenMode(ScreenMode screenMode) { windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN; } - else if (screenMode == ScreenMode.BorderlessFullscreen) + else if (screenMode == ScreenMode.FullscreenBorderless) { windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; } @@ -195,15 +207,7 @@ internal void Show() SDL.SDL_ShowWindow(Handle); } - /// - /// You can specify a method to run when the window size changes. - /// - public void RegisterSizeChangeCallback(System.Action sizeChangeCallback) - { - SizeChangeCallback = sizeChangeCallback; - } - - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { if (!IsDisposed) {