223 lines
6.0 KiB
C#
223 lines
6.0 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 int LastX { get; private set; }
|
|
public int LastY { get; private set; }
|
|
public int LastSX { get; private set; }
|
|
public int LastSY { get; private set; }
|
|
public int LastSW { get; private set; }
|
|
public int LastSH { get; private set; }
|
|
|
|
public Vector3i Position => Location;
|
|
|
|
public virtual void ParentResize()
|
|
{
|
|
BlockDraw = true;
|
|
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, ly, sy, sx;
|
|
bool UpdateDistance = false;
|
|
if ((Controls[i].Anchor & ObjectAnchor.PreventWidthChange) == ObjectAnchor.PreventWidthChange)
|
|
{
|
|
UpdateDistance = true;
|
|
lx = Controls[i].Location.X + ((Size.X - Controls[i].Distance.X - Controls[i].Size.X - Controls[i].Location.X) / 2);
|
|
sx = Controls[i].Size.X;
|
|
}
|
|
else
|
|
{
|
|
lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
|
sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
|
}
|
|
if ((Controls[i].Anchor & ObjectAnchor.PreventHeightChange) == ObjectAnchor.PreventHeightChange)
|
|
{
|
|
UpdateDistance = true;
|
|
ly = Controls[i].Location.Y + ((Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y - Controls[i].Location.Y) / 2);
|
|
sy = Controls[i].Size.Y;
|
|
}
|
|
else
|
|
{
|
|
ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
|
sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
|
}
|
|
|
|
bool mooved = false;
|
|
if (sx != Controls[i].Size.X || sy != Controls[i].Size.Y)
|
|
{
|
|
mooved = true;
|
|
Controls[i].SetSize(sx, sy);
|
|
}
|
|
if (lx != Controls[i].Location.X || ly != Controls[i].Location.Y)
|
|
{
|
|
mooved = true;
|
|
Controls[i].SetLocation(lx, ly);
|
|
}
|
|
if (UpdateDistance)
|
|
{
|
|
Controls[i].ForceDistanceUpdate(this);
|
|
}
|
|
if (mooved && Controls[i] is IParent parent)
|
|
{
|
|
parent.ParentResize();
|
|
}
|
|
}
|
|
if (Parent is not null) Parent.TryDraw();
|
|
BlockDraw = false;
|
|
}
|
|
|
|
public virtual void ReportSizeUpdate(IRenderObject Control)
|
|
{
|
|
|
|
}
|
|
|
|
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
|
{
|
|
if (Loaded && Visible && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y)
|
|
{
|
|
if (Location.X - sx + x > sw || Location.Y - sy + y > sh)
|
|
{
|
|
NotifiNotVisible();
|
|
return;
|
|
}
|
|
|
|
if (Location.X - sx + x > -1)
|
|
{
|
|
int add = Location.X - sx + x;
|
|
sx += add;
|
|
sw -= add;
|
|
if (Size.X < sw)
|
|
sw = Size.X;
|
|
}
|
|
else
|
|
{
|
|
if (Size.X + Location.X - sx + x < sw)
|
|
sw = Size.X + Location.X - sx + x;
|
|
}
|
|
if (Location.Y - sy + y > -1)
|
|
{
|
|
int add = Location.Y - sy + y;
|
|
sy += add;
|
|
sh -= add;
|
|
if (Size.Y < sh)
|
|
sh = Size.Y;
|
|
}
|
|
else
|
|
{
|
|
if (Size.Y + Location.Y - sy + y < sh)
|
|
sh = Size.Y + Location.Y - sy + y;
|
|
}
|
|
|
|
x += Location.X;
|
|
y += Location.Y;
|
|
|
|
if (sw <= 0 || sh <= 0)
|
|
{
|
|
NotifiNotVisible();
|
|
return;
|
|
}
|
|
base.Draw(x,y,sx,sy,sw,sh);
|
|
LastX = x;
|
|
LastY = y;
|
|
LastSX = sx;
|
|
LastSY = sy;
|
|
LastSW = sw;
|
|
LastSH = sh;
|
|
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(sx, Window!.CS.Y - sy - sh, sw, sh);
|
|
Controls[i].Draw(x,y,sx,sy,sw,sh);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IgnoreVisForChildren { get; set; }
|
|
|
|
|
|
public override void NotifiNotVisible()
|
|
{
|
|
base.NotifiNotVisible();
|
|
for (int i = 0; i < Controls.Length; i++)
|
|
{
|
|
Controls[i].NotifiNotVisible();
|
|
}
|
|
}
|
|
|
|
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();
|
|
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;
|
|
}
|
|
} |