From 42c66ce696ec8ccc0c3441e1356e6108c6d8acba Mon Sep 17 00:00:00 2001 From: JacobTech Date: Fri, 6 Jan 2023 01:59:16 -0500 Subject: [PATCH] New Features & Fixes Fixed some events not triggering correctly Added TabControl render object --- GraphicsManager/GraphicsManager.csproj | 2 +- GraphicsManager/Interfaces/IParent.cs | 4 - GraphicsManager/Objects/Core/ControlList.cs | 1 + GraphicsManager/Objects/Core/Texture.cs | 19 +- GraphicsManager/Objects/Label.cs | 22 +- GraphicsManager/Objects/Rectangle.cs | 8 +- GraphicsManager/Objects/RoundedButton.cs | 23 +- GraphicsManager/Objects/RoundedRectangle.cs | 8 +- GraphicsManager/Objects/TabControl.cs | 282 ++++++++++++++++++++ GraphicsManager/Objects/UserControl.cs | 6 +- 10 files changed, 322 insertions(+), 53 deletions(-) create mode 100644 GraphicsManager/Objects/TabControl.cs diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj index 0280f25..f4c0d1f 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-alpha99999999999996 + 1.0.0-alpha99999999999999996 diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs index cac7e48..1340e61 100755 --- a/GraphicsManager/Interfaces/IParent.cs +++ b/GraphicsManager/Interfaces/IParent.cs @@ -15,9 +15,5 @@ public interface IParent public void TryDraw(); public void ReportSizeUpdate(IRenderObject Control); public float FloatToInt(float p, bool Invert = false); - public event Action MouseDown; - public event Action KeyDown; - public Vector2 MousePosition { get; } - public Vector2i Position { get; } } diff --git a/GraphicsManager/Objects/Core/ControlList.cs b/GraphicsManager/Objects/Core/ControlList.cs index d0385c3..7bbc774 100644 --- a/GraphicsManager/Objects/Core/ControlList.cs +++ b/GraphicsManager/Objects/Core/ControlList.cs @@ -7,6 +7,7 @@ public class ControlList private List _internal = new(); public IRenderObject this[int Index] => _internal[Index]; + public IRenderObject this[uint Index] => _internal[(int)Index]; public IEnumerable Where(Func func) => _internal.Where(func); diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs index 1421cdc..a2f637c 100755 --- a/GraphicsManager/Objects/Core/Texture.cs +++ b/GraphicsManager/Objects/Core/Texture.cs @@ -53,14 +53,14 @@ public class Texture { try { -try -{ - faces[i].SetPixelSizes(0, l.PixelHeight); -} -catch (Exception e) -{ - continue; -} + try + { + faces[i].SetPixelSizes(0, l.PixelHeight); + } + catch (Exception e) + { + continue; + } faces[i].SelectCharmap(Encoding.Unicode); ushort temp = ((ushort)charter); if (faces[i].GetCharIndex(temp) == 0) continue; @@ -72,8 +72,9 @@ catch (Exception e) { Size = new Vector2(bitmap.Width, bitmap.Rows), Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop), - Advance = (int)glyph.Advance.X.Value, + Advance = glyph.Advance.X.Value, }; + return t; } catch (Exception ex) { diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs index 9ace535..32150be 100755 --- a/GraphicsManager/Objects/Label.cs +++ b/GraphicsManager/Objects/Label.cs @@ -57,7 +57,7 @@ public class Label : IRenderObject { if (value is null) value = string.Empty; text = value; - float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F, hhh = 0F; + float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F; for (int i = 0; i < value.Length; i++) { char character; @@ -66,16 +66,17 @@ public class Label : IRenderObject else character = PasswordChar.Value; Character cha = Texture.GetChar(Font, character, Font.Faces.ToArray()); - float w = cha.Size.X * Scale; - float xrel = char_x + cha.Bearing.X * Scale; + if (character == '\n') { - hhh += Font.PixelHeight; char_x = 0f; addy += Font.PixelHeight * Scale; + continue; } + float w = cha.Size.X * Scale; + float xrel = char_x + cha.Bearing.X * Scale; char_x += (cha.Advance >> 6) * Scale; - if (xrel + w > addx) addx = xrel + w; + if ((xrel + w) >= addx) addx = (xrel + w); } Size = new((int)addx, (int)addy); @@ -150,12 +151,10 @@ public class Label : IRenderObject } Character ch = _characters[Window!.Context][Font][c]; int maxx = 0; - int maxy = (int)Font.PixelHeight; if (c == '\n') { hhh += Font.PixelHeight; char_x = 0f; - maxy += (int)Font.PixelHeight; } else { @@ -165,7 +164,6 @@ 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)); @@ -236,10 +234,10 @@ public class Label : IRenderObject private bool mouseinside = false; private void WindowOnMouseMove(MouseMoveEventArgs obj) { - if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true) && - Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true)) + if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) && + Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true)) { if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this); mouseinside = true; diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs index 647f41e..8af1ceb 100755 --- a/GraphicsManager/Objects/Rectangle.cs +++ b/GraphicsManager/Objects/Rectangle.cs @@ -116,10 +116,10 @@ public class Rectangle : ITextureObject private bool mouseinside = false; private void WindowOnMouseMove(MouseMoveEventArgs e) { - if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true) && - Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true)) + if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) && + Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true)) { if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this); mouseinside = true; diff --git a/GraphicsManager/Objects/RoundedButton.cs b/GraphicsManager/Objects/RoundedButton.cs index 38a230d..2e1d5a9 100755 --- a/GraphicsManager/Objects/RoundedButton.cs +++ b/GraphicsManager/Objects/RoundedButton.cs @@ -10,7 +10,7 @@ namespace GraphicsManager.Objects; public class RoundedButton : IRenderObject { private RoundedRectangle _bounds, _inside; - private Label _label; + internal Label _label; public RoundedButton() { _bounds = new RoundedRectangle(); @@ -18,6 +18,13 @@ public class RoundedButton : IRenderObject _label = new Label(); _bounds.MouseEnter += BoundsOnMouseEnter; _bounds.MouseLeave += BoundsOnMouseLeave; + _bounds.Clicked += BoundsOnClicked; + } + + private Task BoundsOnClicked(IRenderObject arg) + { + if (Clicked is not null) _ = Clicked.Invoke(this); + return Task.CompletedTask; } private Task BoundsOnMouseLeave(IRenderObject arg) @@ -73,6 +80,7 @@ public class RoundedButton : IRenderObject public Window? Window { get; private set; } = null; public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; } public Color4 BorderColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; } + public Color4 FontColor { get => _label.Color; set => _label.Color = value; } public bool Visible { get => _bounds.Visible; @@ -100,7 +108,6 @@ public class RoundedButton : IRenderObject if (Loaded) return; this.Parent = Parent; this.Window = Window; - this.Window.MouseDown += Window_MouseDown; Loaded = true; _bounds.LoadToParent(Parent, Window); _inside.LoadToParent(Parent, Window); @@ -108,16 +115,4 @@ public class RoundedButton : IRenderObject 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 996290f..cebfef1 100755 --- a/GraphicsManager/Objects/RoundedRectangle.cs +++ b/GraphicsManager/Objects/RoundedRectangle.cs @@ -158,10 +158,10 @@ public class RoundedRectangle : IRenderObject private bool mouseinside = false; private void WindowOnMouseMove(MouseMoveEventArgs obj) { - if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Parent?.MousePosition.X!) && - Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true) && - Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Parent?.MousePosition.Y!, true)) + if (Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) && + Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) && + Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true)) { if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this); mouseinside = true; diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs new file mode 100644 index 0000000..7197d63 --- /dev/null +++ b/GraphicsManager/Objects/TabControl.cs @@ -0,0 +1,282 @@ +using GraphicsManager.Enums; +using GraphicsManager.Interfaces; +using GraphicsManager.Objects.Core; +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using SixLabors.ImageSharp.Processing; + +namespace GraphicsManager.Objects; + +public class TabControl : IRenderObject, IParent +{ + public Rectangle _bounds; + + public TabControl() + { + _bounds = new(); + } + + private ControlList Buttonts = new(); + private ControlList Controls = new(); + + public void AddPage(string Title, UserControl page) + { + RoundedButton tmp; + uint loc = (uint)Buttonts.Length; + int locc = 0, loccc = 0; + if (loc != 0) + { + locc = Buttonts[loc - 1].Location.X; + loccc = Buttonts[loc - 1].Size.X; + } + Buttonts.Add(tmp = new RoundedButton() + { + Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border), + Font = TitleFont, + Text = Title, + Tag = loc, + BorderColor = this.BorderColor, + InsideColor = this.InsideColor, + FontColor = this.TextColor + }); + + if (loc == PageIndex) tmp.BorderColor = this.SelectedColor; + tmp.Clicked += TmpOnClicked; + tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2)); + page.Anchor = ObjectAnchor.All; + page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace); + page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border); + if (PageIndex != loc) page.Visible = false; + Controls.Add(page); + } + + private Task TmpOnClicked(IRenderObject arg) + { + PageIndex = (uint)arg.Tag!; + return Task.CompletedTask; + } + + public Color4 TextColor { get; set; } = new(255, 255, 255, 255); + public Color4 BorderColor { get; set; } = new(40, 40, 40, 255); + public Color4 SelectedColor { get; set; } = Color4.DarkCyan; + public Color4 InsideColor { get; set; } = new(0, 0, 0, 255); + public Color4 BackgroundColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; } + public int TextBorder { get; set; } = 5; + public int TabSpace { get; set; } = 5; + public int Border { get; set; } = 10; + public IParent? Parent { get; private set; } = null; + public Font TitleFont { get; set; } = Label.DefaultFont; + public Window? Window { get; private set; } = null; + public bool Visible { get => _bounds.Visible; set => _bounds.Visible = value; } + public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; } + public object? Tag { get => _bounds.Tag; set => _bounds.Tag = value; } + public Vector2i Size { get => _bounds.Size; set => _bounds.Size = value; } + public Vector2i Location { get => _bounds.Location; set => _bounds.Location = value; } + public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; } + public Vector2i Distance { get => _bounds.Distance; } + public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; } + public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; } + private uint pgi = 0; + public uint PageIndex + { + get + { + return pgi; + } + set + { + pgi = value; + res = true; + for (int i = 0; i < Buttonts.Length; i++) + ((RoundedButton)Buttonts[i]).BorderColor = BorderColor; + ((RoundedButton)Buttonts[value]).BorderColor = SelectedColor; + if (Parent is not null) Parent.TryDraw(); + } + } + public Vector2i Position => Location; + public bool Loaded { get; private set; } = false; + + public void TryDraw() + { + if (!res) Parent!.TryDraw(); + } + + public void ReportSizeUpdate(IRenderObject Control) + { + + } + + public void ParentResize(ResizeEventArgs e) + { + res = true; + if (e.Width == 0 && e.Height == 0) return; + if (Controls.Length >= PageIndex) return; + if (!Controls[PageIndex].Loaded) return; + bool top = (Controls[PageIndex].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top; + bool left = (Controls[PageIndex].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left; + bool right = (Controls[PageIndex].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right; + bool bottom = (Controls[PageIndex].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom; + if (!top && !bottom) { Controls[PageIndex].Anchor |= ObjectAnchor.Top; top = true; } + if (!left && !right) { Controls[PageIndex].Anchor |= ObjectAnchor.Left; left = true; } + int lx = (left ? Controls[PageIndex].Location.X : Size.X - Controls[PageIndex].Distance.X - Controls[PageIndex].Size.X); + int ly = (top ? Controls[PageIndex].Location.Y : Size.Y - Controls[PageIndex].Distance.Y - Controls[PageIndex].Size.Y); + int sy = (bottom ? Size.Y - Controls[PageIndex].Distance.Y - ly : Controls[PageIndex].Size.Y); + int sx = (right ? Size.X - Controls[PageIndex].Distance.X - lx : Controls[PageIndex].Size.X); + Controls[PageIndex].Size = new(sx, sy); + Controls[PageIndex].Location = new(lx, ly); + if (Controls[PageIndex] is IParent parent) + { + parent.ParentResize(e); + } + Parent!.TryDraw(); + res = false; + } + + private bool res = false; + public void LoadToParent(IParent Parent, Window Window) + { + if (Loaded) return; + this.Parent = Parent; + this.Window = Window; + res = true; + Loaded = true; + _bounds.LoadToParent(Parent, Window); + for (int i = 0; i < Controls.Length; i++) + { + Controls[i].LoadToParent(this, Window); + } + for (int i = 0; i < Buttonts.Length; i++) + { + Buttonts[i].LoadToParent(this, Window); + } + + res = false; + if (WindowLoaded is not null) WindowLoaded.Invoke(this); + } + + public void Draw() + { + if (Loaded && Visible) + { + _bounds.Draw(); + if (!(Controls.Length >= (PageIndex))) return; + if (!Controls[PageIndex].Loaded) return; + Controls[PageIndex].Draw(); + for (int i = 0; i < Buttonts.Length; i++) + Buttonts[i].Draw(); + } + } + + public void Clean() + { + for (int i = 0; i < Controls.Length; i++) + { + Controls[i].Clean(); + } + for (int i = 0; i < Buttonts.Length; i++) + { + Buttonts[i].Clean(); + } + _bounds.Clean(); + } + + public event Func? Clicked; + public event Func? MouseLeave; + public event Func? MouseEnter; + public event Func? WindowLoaded; + + #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/UserControl.cs b/GraphicsManager/Objects/UserControl.cs index 7475cd2..f5b7276 100755 --- a/GraphicsManager/Objects/UserControl.cs +++ b/GraphicsManager/Objects/UserControl.cs @@ -72,8 +72,6 @@ public class UserControl : IRenderObject, IParent 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; @@ -82,9 +80,7 @@ public class UserControl : IRenderObject, IParent 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;