2023-01-29 21:06:11 -05:00

358 lines
9.6 KiB
C#
Executable File

using System.ComponentModel;
using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
namespace GraphicsManager;
public class Window : NativeWindow , IParent
{
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
public TextureManager TextureManager { get; private set; }
private TitleBar? _tb = null;
public TitleBar? CustomeTitleBar
{
get => _tb;
set
{
_tb = value;
//some setting/changeing code
}
}
internal IRenderObject? focused;
public void CenterWindow(int mon)
{
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
int num = (clientArea.Min.X + clientArea.Max.X - Size.X) / 2;
int num2 = (clientArea.Min.Y + clientArea.Max.Y - Size.Y) / 2;
if (num < clientArea.Min.X)
{
num = clientArea.Min.X;
}
if (num2 < clientArea.Min.Y)
{
num2 = clientArea.Min.Y;
}
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
}
internal ContextMenu? ActiveMenu { get; set; } = null;
public IParent? Parent { get; } = null;
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);
public Window(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings)
{
TextureManager = TextureManager.GetTextureManager(Context);
Context.MakeCurrent();
if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());
last = WindowState;
KeyDown += OnKeyDownn;
}
private WindowState last;
private bool fs = false;
private Vector2i os, loc;
private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
{
if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
GLFW.WindowHint(WindowHintBool.AutoIconify, true);
if (WindowState != WindowState.Normal) last = WindowState;
Console.WriteLine(fs);
switch (fs)
{
case false:
loc = Location;
os = Size;
WindowBorder = WindowBorder.Hidden;
Location = new(4090, 0);
fs = true;
break;
case true:
WindowBorder = WindowBorder.Resizable;
Size = os;
Location = loc;
fs = false;
break;
}
}
public Window() : this(new NativeWindowSettings())
{
/*
TextureManager = TextureManager.GetTextureManager(Context);
if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
}
public Vector2i Position { get; } = new Vector2i(0, 0);
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
public ControlList Controls { get; } = new();
#region Cool Math Things
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f)
{
if (hastexture)
{
return new float[20] {
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
};
}
else
{
return new float[12] {
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
IntToFloat(x), IntToFloat(y, true), z,// top l
};
}
}
public Vector3 PointToVector(float x, float y, float z = 0.0f)
{
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
}
public float IntToFloat(float p, bool Invert = false)
{
float Size = (Invert ? this.Size.Y : this.Size.X);
double half = Math.Round((double)Size / (double)2, 1);
double Per = Math.Round((double)1 / half, 15);
if (p == half) return 0.0f;
if (Invert)
{
if (p > half) return (float)(((double)(p - half) * Per) * -1);
else return (float)(1 - (p * Per));
}
else
{
if (p > half) return (float)((double)(p - half) * Per);
else return (float)((1 - (p * Per)) * -1);
}
}
public float FloatToInt(float p, bool Invert = false)
{
float Size = (Invert ? this.Size.Y : this.Size.X);
double half = Math.Round((double)Size / (double)2, 15);
if (p == 0) return (int)half;
if (Invert)
{
if (p < 0)
{
p *= -1;
p++;
return (float)(half * p);
}
else
{
return (float)(half - (p * half));
}
}
else
{
if (p < 0)
{
p *= -1;
p++;
return (float)(Size - (half * p));
}
else
{
return (float)(p * half + half);
}
}
}
#endregion
public void ParentResize(ResizeEventArgs e)
{
base.OnResize(e);
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
BlockDraw = true;
GL.Viewport(0, 0, e.Width, e.Height);
for (int i = 0; i < Controls.Length; i++)
{
if (!Controls[i].Loaded) continue;
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
Controls[i].Size = new(sx, sy);
Controls[i].Location = new(lx, ly);
if (Controls[i] is IParent parent)
{
parent.ParentResize(e);
}
}
DrawFrame();
BlockDraw = false;
}
private int frame = 0;
public void ReportSizeUpdate(IRenderObject Control)
{
}
protected override void OnResize(ResizeEventArgs e)
{
ParentResize(e);
}
protected override void OnClosing(CancelEventArgs e)
{
Context.MakeCurrent();
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
GL.UseProgram(0);
for (int i = 0; i < Controls.Length; i++)
{
Controls[i].Clean();
}
base.OnClosing(e);
}
public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates;
internal bool CanControleUpdate { get; private set; } = true;
public int FPS { get; set; } = 0;
public event Func<Window, Task>? WindowLoaded;
public List<Window> Windows = new();
public void ProcessEvent()
{
ProcessEvents();
}
public void StartRender()
{
Context.MakeCurrent();
initthread = Thread.CurrentThread.ManagedThreadId;
GLFW.PollEvents();
DrawFrame();
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
while (Exists && IsVisible && !IsExiting)
{
GLFW.PollEvents();
if (Windows.Any())
{
foreach (var win in Windows)
{
win.ProcessEvent();
}
}
if (invokes.Any())
{
for (int i = 0; i < invokes.Count; i++) invokes.Dequeue().Invoke();
}
Thread.Sleep(8);
}
}
public void StartRenderAsync()
{
Thread t = new Thread(_ => StartRender());
t.Start();
}
public bool BlockDraw { get; set; } = false;
public void TryDraw()
{
if (!BlockDraw) DrawFrame();
}
private int initthread = 0;
public bool InvokeRequired
{
get
{
return initthread != Thread.CurrentThread.ManagedThreadId;
}
}
private Queue<Action> invokes = new();
public void Invoke(Action A)
{
invokes.Enqueue(A);
}
public Vector2i GetParentRelLocPoint()
{
return new(0);
}
public void DrawFrame()
{
Context.MakeCurrent();
frame++;
Console.WriteLine($"Drawing Frame: {frame}");
GL.Enable(EnableCap.ScissorTest);
GL.Scissor(0, 0, Size.X, Size.Y);
GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, (BackgroundColor.A * -1) + 1);
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
if (needload.Any())
{
BlockDraw = true;
foreach (IRenderObject obj in needload)
{
obj.LoadToParent(this, this);
}
BlockDraw = false;
}
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
for (int i = 0; i < Controls.Length; i++)
{
if (!Controls[i].Loaded) continue;
GL.Disable(EnableCap.ScissorTest);
if (Controls[i] is not Label)
{
GL.Enable(EnableCap.ScissorTest);
GL.Scissor(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y, Controls[i].Size.X, Controls[i].Size.Y);
Controls[i].Draw(0,0,Size.X, Size.Y);
}
else
{
GL.Enable(EnableCap.ScissorTest);
GL.Scissor(0, 0, Size.X, Size.Y);
Controls[i].Draw(0,0,Size.X, Size.Y);
}
}
GL.Disable(EnableCap.ScissorTest);
Context.SwapBuffers();
}
}