Instead of calculating the int position to the OpenGL float of -1 to 1 in the code, we hand this responsibility to the shaders using a matrix to scale and translate everything.
154 lines
4.4 KiB
C#
154 lines
4.4 KiB
C#
using GraphicsManager.Enums;
|
|
using GraphicsManager.Interfaces;
|
|
using OpenTK.Graphics.OpenGL4;
|
|
using OpenTK.Mathematics;
|
|
using OpenTK.Windowing.Common;
|
|
|
|
namespace GraphicsManager.Objects.Core;
|
|
|
|
public abstract class ParentBase : Rectangle, IParent
|
|
{
|
|
protected ParentBase(Texture? texture = null)
|
|
: base(texture)
|
|
{
|
|
}
|
|
|
|
public ControlList Controls { get; } = new();
|
|
|
|
public bool BlockDraw { get; set; }
|
|
|
|
public Vector3i Position => Location;
|
|
|
|
public void TryDraw()
|
|
{
|
|
if (!BlockDraw && Parent is not null) Parent.TryDraw();
|
|
}
|
|
|
|
public virtual void ParentResize(ResizeEventArgs e)
|
|
{
|
|
bool PastBlockState = BlockDraw;
|
|
BlockDraw = true;
|
|
if (e.Width == 0 && e.Height == 0) return;
|
|
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, Controls[i].Location.Z);
|
|
if (Controls[i] is IParent parent)
|
|
{
|
|
parent.ParentResize(e);
|
|
}
|
|
}
|
|
Parent!.TryDraw();
|
|
BlockDraw = PastBlockState;
|
|
}
|
|
|
|
public virtual void ReportSizeUpdate(IRenderObject Control)
|
|
{
|
|
|
|
}
|
|
|
|
public override void Draw(int x, int y, int w, int h)
|
|
{
|
|
if (Loaded && Visible && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y)
|
|
{
|
|
int nx = x, ny = y, nw = w, nh = h;
|
|
if (Location.X > nw)
|
|
return;
|
|
else
|
|
{
|
|
nx += Location.X;
|
|
nw -= Location.X;
|
|
if (Size.X < nw)
|
|
nw = Size.X;
|
|
}
|
|
|
|
if (Location.Y > nh)
|
|
return;
|
|
else
|
|
{
|
|
ny += Location.Y;
|
|
nh -= Location.Y;
|
|
if (Size.Y < nh)
|
|
nh = Size.Y;
|
|
}
|
|
if (nw == 0 || nh == 0) return;
|
|
GL.Scissor(nx, Window!.ClientSize.Y - ny - nh, nw, nh);
|
|
base.Draw(nx,ny,nw,nh);
|
|
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
|
|
|
if (needload.Any())
|
|
{
|
|
BlockDraw = true;
|
|
foreach (IRenderObject Control in needload)
|
|
{
|
|
Control.LoadToParent(this, Window!);
|
|
}
|
|
if (this is IFlow flow) flow.ForceScrollUpdate();
|
|
BlockDraw = false;
|
|
}
|
|
for (int i = 0; i < Controls.Length; i++)
|
|
{
|
|
if (Controls[i].Location.X > Size.X || Controls[i].Location.Y > Size.Y) continue;
|
|
GL.Scissor(nx, Window!.ClientSize.Y - ny - nh, nw, nh);
|
|
Controls[i].Draw(nx, ny, nw, nh);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void Clean()
|
|
{
|
|
for (int i = 0; i < Controls.Length; i++)
|
|
{
|
|
Controls[i].Clean();
|
|
}
|
|
base.Clean();
|
|
}
|
|
|
|
public override void LoadToParent(IParent Parent, IWindow Window)
|
|
{
|
|
if (Loaded) return;
|
|
bool PastBlockState = BlockDraw;
|
|
BlockDraw = true;
|
|
base.LoadToParent(Parent, Window);
|
|
for (int i = 0; i < Controls.Length; i++)
|
|
{
|
|
if (Controls[i].Loaded) continue;
|
|
Controls[i].LoadToParent(this, Window);
|
|
if (Controls[i] is IFlow flow) flow.ForceScrollUpdate();
|
|
}
|
|
BlockDraw = PastBlockState;
|
|
}
|
|
|
|
public override Vector3i Location
|
|
{
|
|
get => base.Location;
|
|
set
|
|
{
|
|
BlockDraw = true;
|
|
base.Location = value;
|
|
for (int i = 0; i < Controls.Length; i++)
|
|
{
|
|
Controls[i].Location = Controls[i].Location;
|
|
}
|
|
ParentResize(new());
|
|
if (Parent is not null) Parent.TryDraw();
|
|
BlockDraw = false;
|
|
}
|
|
}
|
|
|
|
public float IntToWindow(float p, bool Y = false)
|
|
{
|
|
return Parent!.IntToWindow((Y ? this.Location.Y : Location.X), Y) + p;
|
|
}
|
|
} |