MoonWorks/src/Window.cs

175 lines
4.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2022-12-13 08:52:35 +00:00
using MoonWorks.Graphics;
2021-01-19 19:24:23 +00:00
using SDL2;
2022-02-25 21:23:31 +00:00
namespace MoonWorks
2021-01-19 19:24:23 +00:00
{
/// <summary>
2023-09-19 20:19:41 +00:00
/// Represents a window in the client operating system. <br/>
/// Every Game has a MainWindow automatically. <br/>
/// You can create additional Windows if you desire. They must be Claimed by the GraphicsDevice to be rendered to.
/// </summary>
2022-02-25 21:23:31 +00:00
public class Window : IDisposable
2022-02-23 05:14:32 +00:00
{
2022-02-23 00:44:39 +00:00
internal IntPtr Handle { get; }
2022-03-02 22:46:55 +00:00
public ScreenMode ScreenMode { get; private set; }
public uint Width { get; private set; }
public uint Height { get; private set; }
2022-12-13 08:52:35 +00:00
internal Texture SwapchainTexture { get; set; } = null;
2021-01-19 19:24:23 +00:00
public bool Claimed { get; internal set; }
public MoonWorks.Graphics.TextureFormat SwapchainFormat { get; internal set; }
2022-02-23 00:44:39 +00:00
private bool IsDisposed;
private static Dictionary<uint, Window> idLookup = new Dictionary<uint, Window>();
2021-01-19 19:24:23 +00:00
private System.Action<uint, uint> SizeChangeCallback = null;
public Window(WindowCreateInfo windowCreateInfo, SDL.SDL_WindowFlags flags)
{
2022-02-23 05:14:32 +00:00
if (windowCreateInfo.ScreenMode == ScreenMode.Fullscreen)
{
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
2022-02-23 05:14:32 +00:00
}
else if (windowCreateInfo.ScreenMode == ScreenMode.BorderlessFullscreen)
2022-02-23 05:14:32 +00:00
{
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
2022-02-23 05:14:32 +00:00
}
2021-01-19 19:24:23 +00:00
if (windowCreateInfo.SystemResizable)
{
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;
}
if (windowCreateInfo.StartMaximized)
{
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_MAXIMIZED;
}
2022-02-23 05:14:32 +00:00
ScreenMode = windowCreateInfo.ScreenMode;
2021-01-19 19:24:23 +00:00
SDL.SDL_GetDesktopDisplayMode(0, out var displayMode);
2022-02-23 05:14:32 +00:00
Handle = SDL.SDL_CreateWindow(
windowCreateInfo.WindowTitle,
SDL.SDL_WINDOWPOS_CENTERED,
SDL.SDL_WINDOWPOS_CENTERED,
windowCreateInfo.ScreenMode == ScreenMode.Windowed ? (int) windowCreateInfo.WindowWidth : displayMode.w,
windowCreateInfo.ScreenMode == ScreenMode.Windowed ? (int) windowCreateInfo.WindowHeight : displayMode.h,
flags
2022-02-23 05:14:32 +00:00
);
2022-02-23 06:16:06 +00:00
/* Requested size might be different in fullscreen, so let's just get the area */
SDL.SDL_GetWindowSize(Handle, out var width, out var height);
Width = (uint) width;
Height = (uint) height;
idLookup.Add(SDL.SDL_GetWindowID(Handle), this);
2022-02-23 05:14:32 +00:00
}
2021-01-19 19:24:23 +00:00
2023-09-19 20:19:41 +00:00
/// <summary>
/// Changes the ScreenMode of this window.
/// </summary>
public void SetScreenMode(ScreenMode screenMode)
2022-02-23 05:14:32 +00:00
{
SDL.SDL_WindowFlags windowFlag = 0;
2021-01-19 19:24:23 +00:00
2022-02-23 05:14:32 +00:00
if (screenMode == ScreenMode.Fullscreen)
{
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
}
else if (screenMode == ScreenMode.BorderlessFullscreen)
2022-02-23 05:14:32 +00:00
{
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
}
2021-01-19 19:24:23 +00:00
2022-02-23 05:14:32 +00:00
SDL.SDL_SetWindowFullscreen(Handle, (uint) windowFlag);
if (screenMode == ScreenMode.Windowed)
{
SDL.SDL_SetWindowPosition(Handle, SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED);
}
ScreenMode = screenMode;
2022-02-23 05:14:32 +00:00
}
2021-02-24 21:03:39 +00:00
2022-02-23 05:14:32 +00:00
/// <summary>
2023-09-19 20:19:41 +00:00
/// Resizes the window. <br/>
2022-02-23 05:14:32 +00:00
/// Note that you are responsible for recreating any graphics resources that need to change as a result of the size change.
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
public void SetWindowSize(uint width, uint height)
{
SDL.SDL_SetWindowSize(Handle, (int) width, (int) height);
2022-03-02 22:46:55 +00:00
Width = width;
Height = height;
if (ScreenMode == ScreenMode.Windowed)
{
SDL.SDL_SetWindowPosition(Handle, SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED);
}
2022-02-23 05:14:32 +00:00
}
2022-02-23 00:44:39 +00:00
internal static Window Lookup(uint windowID)
{
return idLookup.ContainsKey(windowID) ? idLookup[windowID] : null;
}
internal void Show()
{
SDL.SDL_ShowWindow(Handle);
}
internal void HandleSizeChange(uint width, uint height)
2022-07-28 23:06:50 +00:00
{
Width = width;
Height = height;
if (SizeChangeCallback != null)
{
SizeChangeCallback(width, height);
}
}
2023-09-19 20:19:41 +00:00
/// <summary>
/// You can specify a method to run when the window size changes.
/// </summary>
public void RegisterSizeChangeCallback(System.Action<uint, uint> sizeChangeCallback)
{
SizeChangeCallback = sizeChangeCallback;
2022-07-28 23:06:50 +00:00
}
2022-02-23 00:44:39 +00:00
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
// dispose managed state (managed objects)
}
idLookup.Remove(SDL.SDL_GetWindowID(Handle));
2022-02-23 00:44:39 +00:00
SDL.SDL_DestroyWindow(Handle);
IsDisposed = true;
}
}
2022-02-25 21:23:31 +00:00
~Window()
2022-02-23 00:44:39 +00:00
{
2022-02-23 05:14:32 +00:00
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
2022-02-23 00:44:39 +00:00
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
2021-01-19 19:24:23 +00:00
}