diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj
index 50771e6..3f37cf3 100644
--- a/GraphicsManager/GraphicsManager.csproj
+++ b/GraphicsManager/GraphicsManager.csproj
@@ -10,7 +10,7 @@
False
https://git.jacobtech.com/JacobTech.com/GraphicsManager
git
- 1.0.0-alpha8
+ 1.0.0-alpha999991
diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs
index 89276ac..062ea74 100755
--- a/GraphicsManager/Interfaces/IParent.cs
+++ b/GraphicsManager/Interfaces/IParent.cs
@@ -10,8 +10,9 @@ public interface IParent
public Vector2i Size { get; }
public void ParentResize(ResizeEventArgs e);
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f);
- public Vector3 PointToVector(int x, int y, float z = 0.0f);
- public float IntToFloat(int p, bool Invert = false);
+ public Vector3 PointToVector(float x, float y, float z = 0.0f);
+ public float IntToFloat(float p, bool Invert = false);
+ public void TryDraw();
public float FloatToInt(float p, bool Invert = false);
public event Action MouseDown;
public event Action KeyDown;
diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs
index 310e380..f02efc7 100755
--- a/GraphicsManager/Interfaces/IRenderObject.cs
+++ b/GraphicsManager/Interfaces/IRenderObject.cs
@@ -18,6 +18,10 @@ public interface IRenderObject
public IParent? Parent { get; }
public Window? Window { get; }
public bool Visible { get; set; }
+ public object? Tag { get; set; }
public event Func? Clicked;
+ public event Func? MouseLeave;
+ public event Func? MouseEnter;
+ public event Func? WindowLoaded;
}
diff --git a/GraphicsManager/Objects/Core/ControlList.cs b/GraphicsManager/Objects/Core/ControlList.cs
new file mode 100644
index 0000000..e760ada
--- /dev/null
+++ b/GraphicsManager/Objects/Core/ControlList.cs
@@ -0,0 +1,34 @@
+using GraphicsManager.Interfaces;
+
+namespace GraphicsManager.Objects.Core;
+
+public class ControlList
+{
+ private List _internal = new();
+
+ public IRenderObject this[int Index] => _internal[Index];
+
+ public IEnumerable Where(Func func) => _internal.Where(func);
+
+ public int Length => _internal.Count;
+
+ public void Remove(IRenderObject item)
+ {
+ _internal.Remove(item);
+ item.Clean();
+ }
+
+ public void Add(IRenderObject item)
+ {
+ _internal.Add(item);
+ }
+
+ public void Clear()
+ {
+ foreach (IRenderObject con in _internal)
+ {
+ con.Clean();
+ }
+ _internal.Clear();
+ }
+}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs
new file mode 100644
index 0000000..88c53d8
--- /dev/null
+++ b/GraphicsManager/Objects/FlowLayout.cs
@@ -0,0 +1,290 @@
+using System.Timers;
+using GraphicsManager.Enums;
+using GraphicsManager.Interfaces;
+using GraphicsManager.Objects.Core;
+using OpenTK.Mathematics;
+using OpenTK.Windowing.Common;
+using Timer = System.Timers.Timer;
+
+namespace GraphicsManager.Objects;
+
+public class FlowLayout : IRenderObject, IParent
+{
+ private Rectangle _bounds;
+
+ public FlowLayout()
+ {
+ _bounds = new Rectangle();
+ _bounds.Clicked += _bounds_Clicked;
+ t = new(50);
+ t.Enabled = true;
+ t.Elapsed += TOnElapsed;
+ t.Start();
+ }
+
+ private Task _bounds_Clicked(IRenderObject arg)
+ {
+ if (Clicked is not null) _ = Clicked.Invoke(arg);
+ return Task.CompletedTask;
+ }
+
+ public ControlList Controls { get; } = new();
+ public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; }
+ public Color4 BackgroundColor
+ {
+ get
+ {
+ Uniform? u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is null) u4 = new() { Location = 0, Value = new(1, 1, 0, 1) };
+ return new Color4(u4.Value.X, u4.Value.X, u4.Value.X, u4.Value.X);
+ }
+ set
+ {
+ Uniform u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is not null) _bounds.Uniforms.Uniform4.Remove(u4);
+ if (u4 is null) u4 = new() { Location = 0 };
+ u4.Value = new(value.R, value.G, value.B, value.A);
+ _bounds.Uniforms.Uniform4.Add(u4);
+ }
+ }
+ public bool Visible { get => _bounds.Visible; set => _bounds.Visible = value; }
+ public Vector2i Size { get => _bounds.Size; set => _bounds.Size = value; }
+ public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
+ public Vector2i Location { get => _bounds.Location; set => _bounds.Location = value; }
+ public Vector2i Position => Location;
+ public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
+ public Vector2i Distance { get => _bounds.Distance; }
+ public event Func? Clicked;
+ public event Action MouseDown;
+ public event Action KeyDown;
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
+ public IParent? Parent { get; private set; }
+ public Window? Window { get; private set; }
+ public bool Loaded { get; private set; } = false;
+
+ public Vector2 MousePosition => Window!.MousePosition;
+
+ public void LoadToParent(IParent Parent, Window Window)
+ {
+ if (Loaded) return;
+ this.Parent = Parent;
+ this.Window = Window;
+ Loaded = true;
+ _bounds.LoadToParent(Parent, Window);
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ Controls[i].LoadToParent(this, Window);
+ }
+ Window.MouseWheel += WindowOnMouseWheel;
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
+ }
+
+ private bool isrole = false;
+ private MouseWheelEventArgs dis;
+ Timer t;
+ private Queue scrols = new();
+
+ public void TryDraw()
+ {
+ if (!isrole) Parent!.TryDraw();
+ }
+ private void WindowOnMouseWheel(MouseWheelEventArgs obj)
+ {
+ try
+ {
+ isrole = true;
+ dis = obj;
+ if (scrols.Any())
+ {
+ for (int i = 0; i < scrols.Count; i++)
+ {
+ scrols.Dequeue().Invoke();
+ }
+ Parent!.TryDraw();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+
+ }
+
+ public uint HScrollPixels { get; set; } = 30;
+ private void TOnElapsed(object? sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ if (isrole)
+ {
+ scrols.Enqueue(new Action(() =>
+ {
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ Controls[i].Location = new((int)(Controls[i].Location.X),
+ (int)(Controls[i].Location.Y - (dis.OffsetY * HScrollPixels)));
+ }
+ }));
+ }
+
+ isrole = false;
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine(exception);
+ }
+ }
+
+ public void Draw()
+ {
+ if (Loaded)
+ {
+ _bounds.Draw();
+ IEnumerable needload = Controls.Where(a => a.Loaded == false);
+
+ if (needload.Any())
+ {
+ foreach (IRenderObject Control in needload)
+ {
+ Control.LoadToParent(this, Window!);
+ }
+ }
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ Controls[i].Draw();
+ }
+ }
+ }
+
+ public void Clean()
+ {
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ Controls[i].Clean();
+ }
+ _bounds.Clean();
+ }
+
+ public void ParentResize(ResizeEventArgs e)
+ {
+ 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);
+ if (Controls[i] is IParent parent)
+ {
+ parent.ParentResize(e);
+ }
+ }
+ }
+
+ #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)
+ {
+ p += (Invert ? Location.Y : Location.X);
+ IParent? tempp = Parent;
+ while (tempp is not null)
+ {
+ p += (Invert ? tempp.Position.Y : tempp.Position.X);
+ tempp = tempp.Parent;
+ }
+ float Size = (Invert ? Window!.Size.Y : Window!.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)
+ {
+ p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
+ IParent? tempp = Parent;
+ while (tempp is not null)
+ {
+ p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
+ tempp = tempp.Parent;
+ }
+
+ float Size = (Invert ? Window!.Size.Y : Window!.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
+}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs
index c55386a..797f0d3 100755
--- a/GraphicsManager/Objects/Label.cs
+++ b/GraphicsManager/Objects/Label.cs
@@ -36,13 +36,28 @@ public class Label : IRenderObject
{
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
if (!_characters.ContainsKey(Font)) _characters.Add(Font, new Dictionary());
+ float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F, hhh = 0F;
foreach (char character in value)
{
- if (_characters[Font].ContainsKey(character)) continue;
- var f = Texture.TextureForChar(Font, character, Font.Faces.ToArray());
- f.LoadText();
+ if (!_characters[Font].ContainsKey(character))
+ {
+ var f = Texture.TextureForChar(Font, character, Font.Faces.ToArray());
+ f.LoadText();
+ }
+ float w = _characters[Font][character].Size.X * Scale;
+ float xrel = char_x + _characters[Font][character].Bearing.X * Scale;
+ if (character == '\n')
+ {
+ hhh += Font.PixelHeight;
+ char_x = 0f;
+ addy += Font.PixelHeight * Scale;
+ }
+ char_x += (_characters[Font][character].Advance >> 6) * Scale;
+ if (xrel + w > addx) addx = xrel + w;
}
- if (Window is not null && Window.CanControleUpdate && Loaded) Window.DrawFrame();
+
+ Size = new((int)addx, (int)addy);
+ if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
}
}
}
@@ -63,15 +78,15 @@ public class Label : IRenderObject
{
loc_ = value;
if (Window is null || Parent is null) return;
- locc_ = new((int)Window.FloatToInt(Parent.IntToFloat(value.X)), (int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true));
- if (Window.CanControleUpdate && Loaded) Window.DrawFrame();
+ locc_ = new((int)Window.FloatToInt(Parent.IntToFloat(value.X)), (int)Window.FloatToInt(Parent.IntToFloat(value.Y + (int)Font.PixelHeight, true), true));
+ if (Window.CanControleUpdate && Loaded) Parent!.TryDraw();
}
}
public Vector2i Size { get; set; }
public void Clean()
{
-
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
}
public void Draw()
@@ -102,11 +117,13 @@ public class Label : IRenderObject
{
if (!_characters[Font].ContainsKey(c)) break;
Character ch = _characters[Font][c];
-
+ int maxx = 0;
+ int maxy = (int)Font.PixelHeight;
if (c == '\n')
{
hhh += Font.PixelHeight;
char_x = 0f;
+ maxy += (int)Font.PixelHeight;
}
else
{
@@ -116,7 +133,7 @@ public class Label : IRenderObject
float yrel = (ch.Size.Y - ch.Bearing.Y) * Scale;
yrel += hhh;
char_x += (ch.Advance >> 6) * Scale;
-
+ if (xrel + w > maxx) maxx = (int)(xrel + w);
Matrix4 scaleM = Matrix4.CreateScale(new Vector3(w, h, 1.0f));
Matrix4 transRelM = Matrix4.CreateTranslation(new Vector3(xrel, yrel, 0.0f));
@@ -127,6 +144,7 @@ public class Label : IRenderObject
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
}
+
}
GL.Disable(EnableCap.Blend);
@@ -170,10 +188,13 @@ public class Label : IRenderObject
Text = Text;
Location = Location;
Distance = new(window.Size.X - Size.X - Location.X, window.Size.Y - Size.Y - Location.Y);
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
-
-
public event Func? Clicked;
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
public bool Loaded { get; private set; } = false;
}
diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs
index 88b60dd..4319bb6 100755
--- a/GraphicsManager/Objects/Rectangle.cs
+++ b/GraphicsManager/Objects/Rectangle.cs
@@ -74,6 +74,8 @@ public class Rectangle : ITextureObject
{
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.DeleteBuffer(BufferObject);
+ GL.DeleteBuffer(ElementBufferObject);
+ GL.DeleteVertexArray(ArrayObject);
}
public void LoadToParent(IParent Parent, Window Window)
@@ -109,6 +111,7 @@ public class Rectangle : ITextureObject
Window.MouseDown += Window_MouseDown;
Location = Location;
Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
public IParent? Parent { get; private set; }
@@ -130,6 +133,8 @@ public class Rectangle : ITextureObject
{
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.DeleteBuffer(BufferObject);
+ GL.DeleteBuffer(ElementBufferObject);
+ GL.DeleteVertexArray(ArrayObject);
}
public Shader Shader { get; set; } = DefaultShader;
@@ -163,7 +168,7 @@ public class Rectangle : ITextureObject
GL.BindVertexArray(ArrayObject);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
- if (Window is not null && Window.CanControleUpdate && Loaded) Window.DrawFrame();
+ if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
}
}
catch (AccessViolationException v)
@@ -180,6 +185,10 @@ public class Rectangle : ITextureObject
public event Func? Clicked;
public bool Loaded { get; private set; } = false;
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
public Vector2i Distance { get; private set; }
public Vector2i Size
diff --git a/GraphicsManager/Objects/RoundedButton.cs b/GraphicsManager/Objects/RoundedButton.cs
new file mode 100755
index 0000000..3de1545
--- /dev/null
+++ b/GraphicsManager/Objects/RoundedButton.cs
@@ -0,0 +1,137 @@
+using GraphicsManager.Enums;
+using GraphicsManager.Interfaces;
+using GraphicsManager.Objects.Core;
+using OpenTK.Mathematics;
+using OpenTK.Windowing.Common;
+using OpenTK.Windowing.GraphicsLibraryFramework;
+
+namespace GraphicsManager.Objects;
+
+public class RoundedButton : IRenderObject
+{
+ private RoundedRectangle _bounds, _inside;
+ private Label _label;
+ public RoundedButton()
+ {
+ _bounds = new RoundedRectangle();
+ _inside = new RoundedRectangle();
+ _label = new Label();
+ }
+
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
+ public int Radius { get => _bounds.Radius; set { _bounds.Radius = value; _inside.Radius = value; } }
+ public int Border { get; set; } = 2;
+ public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
+ public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } }
+ public Font Font { get => _label.Font; set => _label.Font = value; }
+ public string Text { get => _label.Text; set => _label.Text = value; }
+ public bool Loaded { get; private set; } = false;
+ public Vector2i Size
+ {
+ get
+ {
+ return _bounds.Size;
+ }
+ set
+ {
+ _bounds.Size = value;
+ _inside.Size = new(value.X - (Border * 2), value.Y - (Border * 2));
+ _label.Location = new( Location.X + Border + (((value.X - (Border * 2)) / 2) - (_label.Size.X / 2)), Location.Y + Border + (((value.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
+ }
+ }
+ public Vector2i Location {
+ get => _bounds.Location;
+ set
+ {
+ _bounds.Location = value;
+ _inside.Location = new(value.X + Border, value.Y + Border);
+ _label.Location = new( value.X + Border + (((Size.X - (Border * 2)) / 2) - (_label.Size.X / 2)), value.Y + Border + (((Size.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
+ }
+ }
+ public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
+ public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
+ public Vector2i Distance { get => _bounds.Distance; }
+ public IParent? Parent { get; private set; } = null;
+ public Window? Window { get; private set; } = null;
+
+ public Color4 InsideColor
+ {
+ get
+ {
+ Uniform? u4 = _inside.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is null) u4 = new() { Location = 0, Value = new(1, 1, 0, 1) };
+ return new Color4(u4.Value.X, u4.Value.X, u4.Value.X, u4.Value.X);
+ }
+ set
+ {
+ Uniform u4 = _inside.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is not null) _inside.Uniforms.Uniform4.Remove(u4);
+ if (u4 is null) u4 = new() { Location = 0 };
+ u4.Value = new(value.R, value.G, value.B, value.A);
+ _inside.Uniforms.Uniform4.Add(u4);
+ }
+ }
+ public Color4 BorderColor
+ {
+ get
+ {
+ Uniform u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is null) u4 = new() { Location = 0, Value = new(1, 1, 0, 1) };
+ return new Color4(u4.Value.X, u4.Value.X, u4.Value.X, u4.Value.X);
+ }
+ set
+ {
+ Uniform u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is not null) _bounds.Uniforms.Uniform4.Remove(u4);
+ if (u4 is null) u4 = new() { Location = 0 };
+ u4.Value = new(value.R, value.G, value.B, value.A);
+ _bounds.Uniforms.Uniform4.Add(u4);
+ }
+ }
+ public bool Visible { get; set; } = true;
+ public event Func? Clicked;
+
+ public void Clean()
+ {
+ _bounds.Clean();
+ _inside.Clean();
+ _label.Clean();
+ }
+
+ public void Draw()
+ {
+ if (!Visible || !Loaded) return;
+ _bounds.Draw();
+ _inside.Draw();
+ _label.Draw();
+ }
+
+ public void LoadToParent(IParent Parent, Window Window)
+ {
+ if (Loaded) return;
+ this.Parent = Parent;
+ this.Window = Window;
+ this.Window.MouseDown += Window_MouseDown;
+ Loaded = true;
+ _bounds.LoadToParent(Parent, Window);
+ _inside.LoadToParent(Parent, Window);
+ _label.LoadToParent(Parent, Window);
+ Location = Location;
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
+ }
+
+ private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e)
+ {
+ if (e.Button == MouseButton.Button1 &&
+ Parent?.IntToFloat(Location.X) <= Parent?.IntToFloat((int)Parent?.MousePosition.X!) &&
+ Parent?.IntToFloat(Size.X + Location.X) >= Parent?.IntToFloat((int)Parent?.MousePosition.X!) &&
+ Parent?.IntToFloat(Location.Y + Size.Y, true) <= Parent?.IntToFloat((int)Parent?.MousePosition.Y!, true) &&
+ Parent?.IntToFloat(Location.Y, true) >= Parent?.IntToFloat((int)Parent?.MousePosition.Y!, true))
+ {
+ if (Clicked is not null) Clicked.Invoke(this);
+ }
+ }
+}
diff --git a/GraphicsManager/Objects/RoundedRectangle.cs b/GraphicsManager/Objects/RoundedRectangle.cs
index c38f3e1..6f9d1e9 100755
--- a/GraphicsManager/Objects/RoundedRectangle.cs
+++ b/GraphicsManager/Objects/RoundedRectangle.cs
@@ -20,6 +20,10 @@ public class RoundedRectangle : IRenderObject
{
Points_ = new float[36 + (((sn - 1) * 4) * 3)];
}
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
public Uniforms Uniforms { get; set; } = new() { Uniform4 = new() { new() { Location = 0, Value = new(0,0,0,1) } } };
public int Radius
@@ -119,6 +123,8 @@ public class RoundedRectangle : IRenderObject
{
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.DeleteBuffer(BufferObject);
+ GL.DeleteBuffer(ElementBufferObject);
+ GL.DeleteVertexArray(ArrayObject);
}
public void LoadToParent(IParent Parent, Window Window)
@@ -146,6 +152,7 @@ public class RoundedRectangle : IRenderObject
Window.MouseDown += Window_MouseDown;
Location = Location;
Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
public IParent? Parent { get; private set; }
@@ -199,7 +206,7 @@ public class RoundedRectangle : IRenderObject
GL.BindVertexArray(ArrayObject);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
- if (Window is not null && Window.CanControleUpdate && Loaded) Window.DrawFrame();
+ if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
}
}
catch (AccessViolationException v)
@@ -276,7 +283,7 @@ public class RoundedRectangle : IRenderObject
Vector3 _9 = Parent.PointToVector(value.X + Radius, value.Y + Size.Y, 0);
Vector3 _10 = Parent.PointToVector(value.X, value.Y + Size.Y - Radius, 0);
Vector3 _11 = Parent.PointToVector(value.X, value.Y + Radius, 0);
- int[] ff = new int[]
+ float[] ff = new float[]
{
value.X + Size.X - Radius,
value.X + Size.X - Radius,
@@ -294,14 +301,14 @@ public class RoundedRectangle : IRenderObject
};
for (int j = 0; j < 4; j++)
{
- int start = 90 - (j * 90);
+ float start = 90 - (j * 90);
for (int i = 0; i < Smoothness - 1; i++)
{
- var degpre = (rotation * (i + 1));
- var deg = start - degpre;
- double y = ff[j + 4] - (Math.Sin(MathHelper.DegreesToRadians(deg)) * Radius);
- double x = (Math.Cos(MathHelper.DegreesToRadians(deg)) * Radius) + ff[j];
- Vector3 tri = Parent.PointToVector((int)x, (int)y, 0f);
+ float degpre = (rotation * (i + 1));
+ float deg = start - degpre;
+ float y = (float)(ff[j + 4] - (Math.Sin(MathHelper.DegreesToRadians(deg)) * Radius));
+ float x = (float)(Math.Cos(MathHelper.DegreesToRadians(deg)) * Radius) + ff[j];
+ Vector3 tri = Parent.PointToVector(x, y, 0f);
temp.Add(tri.X);
temp.Add(tri.Y);
temp.Add(tri.Z);
diff --git a/GraphicsManager/Objects/Textbox.cs b/GraphicsManager/Objects/Textbox.cs
index 3e78d28..a0d4578 100755
--- a/GraphicsManager/Objects/Textbox.cs
+++ b/GraphicsManager/Objects/Textbox.cs
@@ -18,6 +18,10 @@ public class Textbox : IRenderObject
_label = new Label();
}
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
public int Radius { get => _bounds.Radius; set { _bounds.Radius = value; _inside.Radius = value; } }
public int Border { get; set; } = 2;
public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
@@ -42,7 +46,7 @@ public class Textbox : IRenderObject
set
{
_bounds.Location = value;
- _label.Location = new(value.X + Radius + 5, value.Y + Size.Y - Radius - 5);
+ _label.Location = new(value.X + Border + 5, Location.Y + Border + (((Size.Y - (Radius * 2)) / 2) - (_label.Size.Y / 2)));
_inside.Location = new(value.X + Border, value.Y + Border);
}
}
@@ -56,7 +60,7 @@ public class Textbox : IRenderObject
{
get
{
- Uniform u4 = _inside.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ Uniform? u4 = _inside.Uniforms.Uniform4.Where(u => u.Location == 0).First();
if (u4 is null) u4 = new() { Location = 0, Value = new(1, 1, 0, 1) };
return new Color4(u4.Value.X, u4.Value.X, u4.Value.X, u4.Value.X);
}
@@ -117,6 +121,7 @@ public class Textbox : IRenderObject
_inside.LoadToParent(Parent, Window);
_label.LoadToParent(Parent, Window);
Location = Location;
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
private void WindowOnTextInput(TextInputEventArgs obj)
diff --git a/GraphicsManager/Objects/UserControl.cs b/GraphicsManager/Objects/UserControl.cs
index 6b8cd8c..1eec56a 100755
--- a/GraphicsManager/Objects/UserControl.cs
+++ b/GraphicsManager/Objects/UserControl.cs
@@ -15,16 +15,37 @@ public class UserControl : IRenderObject, IParent
_bounds = new Rectangle();
_bounds.Clicked += _bounds_Clicked;
}
+
+ public void TryDraw()
+ {
+ Parent!.TryDraw();
+ }
private Task _bounds_Clicked(IRenderObject arg)
{
- _ = Clicked?.Invoke(arg)!;
+ if (Clicked is not null) _ = Clicked.Invoke(arg);
return Task.CompletedTask;
}
- public ICollection Controls { get; } = new List();
+ public ControlList Controls { get; } = new();
public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; }
- public Uniforms Uniforms { get => _bounds.Uniforms; }
+ public Color4 BackgroundColor
+ {
+ get
+ {
+ Uniform? u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is null) u4 = new() { Location = 0, Value = new(1, 1, 0, 1) };
+ return new Color4(u4.Value.X, u4.Value.X, u4.Value.X, u4.Value.X);
+ }
+ set
+ {
+ Uniform u4 = _bounds.Uniforms.Uniform4.Where(u => u.Location == 0).First();
+ if (u4 is not null) _bounds.Uniforms.Uniform4.Remove(u4);
+ if (u4 is null) u4 = new() { Location = 0 };
+ u4.Value = new(value.R, value.G, value.B, value.A);
+ _bounds.Uniforms.Uniform4.Add(u4);
+ }
+ }
public bool Visible { get => _bounds.Visible; set => _bounds.Visible = value; }
public Vector2i Size { get => _bounds.Size; set => _bounds.Size = value; }
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
@@ -35,7 +56,10 @@ public class UserControl : IRenderObject, IParent
public event Func? Clicked;
public event Action MouseDown;
public event Action KeyDown;
-
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
public IParent? Parent { get; private set; }
public Window? Window { get; private set; }
public bool Loaded { get; private set; } = false;
@@ -49,10 +73,11 @@ public class UserControl : IRenderObject, IParent
this.Window = Window;
Loaded = true;
_bounds.LoadToParent(Parent, Window);
- foreach (IRenderObject obj in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- obj.LoadToParent(this, Window);
+ Controls[i].LoadToParent(this, Window);
}
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
public void Draw()
@@ -69,18 +94,18 @@ public class UserControl : IRenderObject, IParent
Control.LoadToParent(this, Window!);
}
}
- foreach (IRenderObject Control in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- Control.Draw();
+ Controls[i].Draw();
}
}
}
public void Clean()
{
- foreach (IRenderObject Control in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- Control.Clean();
+ Controls[i].Clean();
}
_bounds.Clean();
}
@@ -88,26 +113,24 @@ public class UserControl : IRenderObject, IParent
public void ParentResize(ResizeEventArgs e)
{
if (e.Width == 0 && e.Height == 0) return;
- foreach (IRenderObject Control in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- if (Control.Loaded)
+ 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)
{
- bool top = (Control.Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
- bool left = (Control.Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
- bool right = (Control.Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
- bool bottom = (Control.Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
- if (!top && !bottom) { Control.Anchor |= ObjectAnchor.Top; top = true; }
- if (!left && !right) { Control.Anchor |= ObjectAnchor.Left; left = true; }
- int lx = (left ? Control.Location.X : Size.X - Control.Distance.X - Control.Size.X);
- int ly = (top ? Control.Location.Y : Size.Y - Control.Distance.Y - Control.Size.Y);
- int sy = (bottom ? Size.Y - Control.Distance.Y - ly : Control.Size.Y);
- int sx = (right ? Size.X - Control.Distance.X - lx : Control.Size.X);
- Control.Size = new(sx, sy);
- Control.Location = new(lx, ly);
- if (Control is IParent parent)
- {
- parent.ParentResize(e);
- }
+ parent.ParentResize(e);
}
}
}
@@ -135,12 +158,12 @@ public class UserControl : IRenderObject, IParent
}
}
- public Vector3 PointToVector(int x, int y, float z = 0.0f)
+ public Vector3 PointToVector(float x, float y, float z = 0.0f)
{
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
}
- public float IntToFloat(int p, bool Invert = false)
+ public float IntToFloat(float p, bool Invert = false)
{
p += (Invert ? Location.Y : Location.X);
IParent? tempp = Parent;
@@ -149,7 +172,7 @@ public class UserControl : IRenderObject, IParent
p += (Invert ? tempp.Position.Y : tempp.Position.X);
tempp = tempp.Parent;
}
- int Size = (Invert ? Window!.Size.Y : Window!.Size.X);
+ float Size = (Invert ? Window!.Size.Y : Window!.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;
@@ -175,7 +198,7 @@ public class UserControl : IRenderObject, IParent
tempp = tempp.Parent;
}
- int Size = (Invert ? Window!.Size.Y : Window!.Size.X);
+ float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
double half = Math.Round((double)Size / (double)2, 15);
if (p == 0) return (int)half;
if (Invert)
diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs
index fcda7f2..f573459 100755
--- a/GraphicsManager/Window.cs
+++ b/GraphicsManager/Window.cs
@@ -1,5 +1,7 @@
-using GraphicsManager.Enums;
+using System.ComponentModel;
+using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
+using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
@@ -9,6 +11,16 @@ namespace GraphicsManager;
public class Window : NativeWindow , IParent
{
+ protected override void Dispose(bool disposing)
+ {
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ Controls[i].Clean();
+ }
+ Context.MakeNoneCurrent();
+ base.Dispose(disposing);
+ }
+
public IParent? Parent { get; } = null;
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);
public Window(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings)
@@ -22,7 +34,7 @@ public class Window : NativeWindow , IParent
public Vector2i Position { get; } = new Vector2i(0, 0);
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
- public ICollection Controls { get; } = new List();
+ 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)
{
@@ -46,14 +58,14 @@ public class Window : NativeWindow , IParent
}
}
- public Vector3 PointToVector(int x, int y, float z = 0.0f)
+ public Vector3 PointToVector(float x, float y, float z = 0.0f)
{
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
}
- public float IntToFloat(int p, bool Invert = false)
+ public float IntToFloat(float p, bool Invert = false)
{
- int Size = (Invert ? this.Size.Y : this.Size.X);
+ 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;
@@ -71,7 +83,7 @@ public class Window : NativeWindow , IParent
public float FloatToInt(float p, bool Invert = false)
{
- int Size = (Invert ? this.Size.Y : this.Size.X);
+ 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)
@@ -108,25 +120,25 @@ public class Window : NativeWindow , IParent
if (e.Width == 0 && e.Height == 0) return;
base.OnResize(e);
GL.Viewport(0, 0, e.Width, e.Height);
- foreach (IRenderObject Control in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- if (!Control.Loaded) continue;
- bool top = (Control.Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
- bool left = (Control.Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
- bool right = (Control.Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
- bool bottom = (Control.Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
- if (!top && !bottom) { Control.Anchor |= ObjectAnchor.Top; top = true; }
- if (!left && !right) { Control.Anchor |= ObjectAnchor.Left; left = true; }
- int lx = (left ? Control.Location.X : Size.X - Control.Distance.X - Control.Size.X);
- int ly = (top ? Control.Location.Y : Size.Y - Control.Distance.Y - Control.Size.Y);
- int sy = (bottom ? Size.Y - Control.Distance.Y - ly : Control.Size.Y);
- int sx = (right ? Size.X - Control.Distance.X - lx : Control.Size.X);
- Control.Size = new(sx, sy);
- Control.Location = new(lx, ly);
- if (Control is IParent parent)
- {
- parent.ParentResize(e);
- }
+ 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);
+ }
}
}
@@ -135,17 +147,29 @@ public class Window : NativeWindow , IParent
ParentResize(e);
}
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ 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? WindowLoaded;
public void StartRender()
{
Context.MakeCurrent();
ProcessEvents();
DrawFrame();
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
while (Exists && IsVisible && !IsExiting)
{
ProcessEvents();
@@ -154,6 +178,11 @@ public class Window : NativeWindow , IParent
Thread.Sleep(8);
}
}
+
+ public void TryDraw()
+ {
+ DrawFrame();
+ }
public void DrawFrame()
{
@@ -169,9 +198,9 @@ public class Window : NativeWindow , IParent
}
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
- foreach (IRenderObject obj in Controls)
+ for (int i = 0; i < Controls.Length; i++)
{
- if (obj.Loaded) obj.Draw();
+ if (Controls[i].Loaded) Controls[i].Draw();
}
Context.SwapBuffers();