165 lines
5.4 KiB
C#
165 lines
5.4 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Drawing;
|
|
using Dashboard.Drawing;
|
|
using Dashboard.Events;
|
|
using Dashboard.Windowing;
|
|
using OpenTK.Mathematics;
|
|
using OpenTK.Platform;
|
|
using MouseMoveEventArgs = Dashboard.Events.MouseMoveEventArgs;
|
|
using TK = OpenTK.Platform.Toolkit;
|
|
|
|
namespace Dashboard.OpenTK.PAL2
|
|
{
|
|
public class PhysicalWindow : IPhysicalWindow, IDrawQueuePaintable, IEventListener
|
|
{
|
|
public DrawQueue DrawQueue { get; } = new DrawQueue();
|
|
public WindowHandle WindowHandle { get; }
|
|
public IDeviceContext DeviceContext { get; }
|
|
public bool DoubleBuffered => true; // Always true for OpenTK windows.
|
|
|
|
public IWindowManager? WindowManager { get; set; }
|
|
|
|
public string Title
|
|
{
|
|
get => TK.Window.GetTitle(WindowHandle);
|
|
set => TK.Window.SetTitle(WindowHandle, value);
|
|
}
|
|
|
|
public SizeF OuterSize
|
|
{
|
|
get
|
|
{
|
|
TK.Window.GetSize(WindowHandle, out Vector2i size);
|
|
return new SizeF(size.X, size.Y);
|
|
}
|
|
set => TK.Window.SetSize(WindowHandle, new Vector2i((int)value.Width, (int)value.Height));
|
|
}
|
|
|
|
public SizeF ClientSize
|
|
{
|
|
get
|
|
{
|
|
TK.Window.GetClientSize(WindowHandle, out Vector2i size);
|
|
return new SizeF(size.X, size.Y);
|
|
}
|
|
set => TK.Window.SetClientSize(WindowHandle, new Vector2i((int)value.Width, (int)value.Height));
|
|
}
|
|
|
|
public event EventHandler? Painting;
|
|
public event EventHandler<AnimationTickEventArgs>? AnimationTimerEvent;
|
|
public event EventHandler<MouseMoveEventArgs>? MouseMoved;
|
|
public event EventHandler<MouseButtonEventArgs>? MouseButtonDown;
|
|
public event EventHandler<MouseButtonEventArgs>? MouseButtonUp;
|
|
public event EventHandler<MouseScrollEventArgs>? MouseScroll;
|
|
|
|
public PhysicalWindow(WindowHandle window, IDeviceContext dc)
|
|
{
|
|
WindowHandle = window;
|
|
DeviceContext = dc;
|
|
AddWindow(this);
|
|
}
|
|
|
|
public PhysicalWindow(WindowHandle window, OpenGLContextHandle context, ISwapGroup? swapGroup = null)
|
|
{
|
|
WindowHandle = window;
|
|
DeviceContext = new OpenGLDeviceContext(window, context, swapGroup);
|
|
AddWindow(this);
|
|
}
|
|
|
|
public PhysicalWindow(GraphicsApiHints hints)
|
|
{
|
|
WindowHandle = TK.Window.Create(hints);
|
|
DeviceContext = CreateDeviceContext(WindowHandle, hints);
|
|
AddWindow(this);
|
|
}
|
|
|
|
private static IDeviceContext CreateDeviceContext(WindowHandle window, GraphicsApiHints hints)
|
|
{
|
|
switch (hints.Api)
|
|
{
|
|
case GraphicsApi.OpenGL:
|
|
case GraphicsApi.OpenGLES:
|
|
OpenGLContextHandle context = TK.OpenGL.CreateFromWindow(window);
|
|
return new OpenGLDeviceContext(window, context);
|
|
default:
|
|
throw new Exception($"Unknown graphics API {hints.Api}.");
|
|
}
|
|
}
|
|
|
|
private bool _isDisposed = false;
|
|
public void Dispose()
|
|
{
|
|
if (_isDisposed) return;
|
|
_isDisposed = true;
|
|
|
|
RemoveWindow(this);
|
|
|
|
(DeviceContext as IDisposable)?.Dispose();
|
|
TK.Window.Destroy(WindowHandle);
|
|
}
|
|
|
|
protected virtual void OnPaint()
|
|
{
|
|
WindowManager?.Paint();
|
|
Painting?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
public void Paint()
|
|
{
|
|
DrawQueue.Clear();
|
|
OnPaint();
|
|
}
|
|
|
|
protected virtual void OnAnimationTimerEvent(AnimationTickEventArgs ea) =>
|
|
AnimationTimerEvent?.Invoke(this, ea);
|
|
|
|
protected virtual void OnMouseMoved(MouseMoveEventArgs ea) => MouseMoved?.Invoke(this, ea);
|
|
|
|
protected virtual void OnMouseButtonDown(MouseButtonEventArgs ea) => MouseButtonDown?.Invoke(this, ea);
|
|
|
|
protected virtual void OnMouseButtonUp(MouseButtonEventArgs ea) => MouseButtonUp?.Invoke(this, ea);
|
|
|
|
protected virtual void OnMouseScroll(MouseScrollEventArgs ea) => MouseScroll?.Invoke(this, ea);
|
|
|
|
public void SendEvent(EventArgs args)
|
|
{
|
|
}
|
|
|
|
private static readonly ConcurrentDictionary<WindowHandle, PhysicalWindow> _windows =
|
|
new ConcurrentDictionary<WindowHandle, PhysicalWindow>();
|
|
|
|
static PhysicalWindow()
|
|
{
|
|
EventQueue.EventRaised += EventQueueOnEventRaised;
|
|
}
|
|
|
|
private static void AddWindow(PhysicalWindow window)
|
|
{
|
|
_windows.TryAdd(window.WindowHandle, window);
|
|
}
|
|
|
|
private static void RemoveWindow(PhysicalWindow window)
|
|
{
|
|
_windows.TryRemove(window.WindowHandle, out _);
|
|
}
|
|
|
|
private static void EventQueueOnEventRaised(PalHandle? handle, PlatformEventType type, EventArgs args)
|
|
{
|
|
if (handle is not WindowHandle windowHandle)
|
|
return;
|
|
|
|
if (!_windows.TryGetValue(windowHandle, out PhysicalWindow? window))
|
|
return;
|
|
|
|
switch (type)
|
|
{
|
|
case PlatformEventType.MouseMove:
|
|
case PlatformEventType.Scroll:
|
|
case PlatformEventType.MouseUp:
|
|
case PlatformEventType.MouseDown:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|