diff --git a/GraphicsManager/FPSWindow.cs b/GraphicsManager/FPSWindow.cs index a7a0ba9..63c873f 100755 --- a/GraphicsManager/FPSWindow.cs +++ b/GraphicsManager/FPSWindow.cs @@ -205,7 +205,7 @@ public class FPSWindow : GameWindow , IWindow } #endregion - public void ForceUpdate(ResizeEventArgs e) + public void ForceUpdate() { BlockDraw = true; for (int i = 0; i < Controls.Length; i++) @@ -225,19 +225,15 @@ public class FPSWindow : GameWindow , IWindow Controls[i].Location = new(lx, ly, Controls[i].Location.Z); if (Controls[i] is IParent parent) { - parent.ParentResize(e); + parent.ParentResize(); } } BlockDraw = false; } - public void ParentResize(ResizeEventArgs e) + public void ParentResize() { - base.OnResize(e); - if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return; - GL.Viewport(0, 0, e.Width, e.Height); - Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f); - ForceUpdate(e); + ForceUpdate(); } private int frame = 0; @@ -249,7 +245,11 @@ public class FPSWindow : GameWindow , IWindow protected override void OnResize(ResizeEventArgs e) { - ParentResize(e); + base.OnResize(e); + if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return; + GL.Viewport(0, 0, e.Width, e.Height); + Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f); + ParentResize(); } protected override void OnClosing(CancelEventArgs e) @@ -400,7 +400,7 @@ public class FPSWindow : GameWindow , IWindow { if (!Controls[i].Loaded) continue; GL.Scissor(0, 0, Size.X, Size.Y); - Controls[i].Draw(0,0,Size.X, Size.Y); + Controls[i].Draw(0,0,0,0,Size.X, Size.Y); } Context.SwapBuffers(); base.OnRenderFrame(args); diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj index 2ec1245..b5db482 100644 --- a/GraphicsManager/GraphicsManager.csproj +++ b/GraphicsManager/GraphicsManager.csproj @@ -10,7 +10,7 @@ False https://git.jacobtech.com/JacobTech.com/GraphicsManager git - 1.0.9-alpha83 + 1.1.0-alpha50 diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs index 55545d9..6a0c332 100755 --- a/GraphicsManager/Interfaces/IParent.cs +++ b/GraphicsManager/Interfaces/IParent.cs @@ -11,7 +11,7 @@ public interface IParent public ControlList Controls { get; } public IParent? Parent { get; } public Vector2i Size { get; } - public void ParentResize(ResizeEventArgs e); + public void ParentResize(); public float IntToWindow(float p, bool Y = false); public void TryDraw(); public void ReportSizeUpdate(IRenderObject Control); diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs index 0ba326c..b2749a7 100755 --- a/GraphicsManager/Interfaces/IRenderObject.cs +++ b/GraphicsManager/Interfaces/IRenderObject.cs @@ -1,5 +1,6 @@ using GraphicsManager.Enums; using GraphicsManager.Objects; +using GraphicsManager.Objects.Core; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.Common.Input; @@ -17,13 +18,19 @@ public interface IRenderObject public bool AllowHoverFromBehind { get; set; } public bool Loaded { get; } public void LoadToParent(IParent Parent, IWindow Window); - public void Draw(int x, int y, int w, int h); + public void Draw(int x, int y, int sx, int sy, int sw, int sh); public MouseCursor HoverMouse { get; set; } + public void SetSize(int wh); + public void SetSize(int w, int h); + public void SetLocation(int xy); + public void SetLocation(int x, int y); + public void SetLocation(int x, int y, int z); public void Clean(); public void Focus(); public void UnFocus(); public void SendKeyEvent(KeyboardKeyEventArgs KeyArgs); public void SendClipEvent(string Text); + public void SendFilesEvent(string[] Files); public Vector2i Size { get; set; } public Vector3i Location { get; set; } public Vector2 SizeAsFloat { get; } @@ -33,9 +40,11 @@ public interface IRenderObject public IWindow? Window { get; } public bool Visible { get; set; } public object? Tag { get; set; } + public List SubHitBoxes { get; } public event Func? Clicked; public event Func? MouseLeave; + public event Func? FilesDroped; public event Func? MouseEnter; public event Func? SizeChanged; public event Func? WindowLoaded; diff --git a/GraphicsManager/Objects/Core/ControlList.cs b/GraphicsManager/Objects/Core/ControlList.cs index 6928fc8..909e576 100644 --- a/GraphicsManager/Objects/Core/ControlList.cs +++ b/GraphicsManager/Objects/Core/ControlList.cs @@ -18,8 +18,9 @@ public class ControlList public int Length => _internal.Count; - internal event Func? ControlAdded; - internal event Func? ControlRemoved; + public event Func? ControlAdded; + public event Func? ControlAfterAdded; + public event Func? ControlRemoved; public void Remove(IRenderObject item, bool purge = true) { @@ -43,12 +44,14 @@ public class ControlList { if (ControlAdded is not null) ControlAdded.Invoke(_internal.Count, item).Wait(); _internal.Add(item); + if (ControlAfterAdded is not null) ControlAfterAdded.Invoke(_internal.Count-1, item).Wait(); } public void Insert(int index, IRenderObject item) { if (ControlAdded is not null) ControlAdded.Invoke(index, item).Wait(); _internal.Insert(index, item); + if (ControlAfterAdded is not null) ControlAfterAdded.Invoke(index, item).Wait(); } public void Clear(bool purge = true) diff --git a/GraphicsManager/Objects/Core/Font.cs b/GraphicsManager/Objects/Core/Font.cs index 5adb3f6..0b0e849 100755 --- a/GraphicsManager/Objects/Core/Font.cs +++ b/GraphicsManager/Objects/Core/Font.cs @@ -39,4 +39,12 @@ public class Font fontclass.Face = new Face(lib, Font.ToArray(), 0); return fontclass; } + + internal static Font MakeFontFromByteArray(byte[] Font) + { + _ = Font ?? throw new ArgumentNullException(nameof(Font)); + Font fontclass = new Font(); + fontclass.Face = new Face(lib, Font, 0); + return fontclass; + } } diff --git a/GraphicsManager/Objects/Core/FontFamily.cs b/GraphicsManager/Objects/Core/FontFamily.cs index de7c7d7..f153656 100644 --- a/GraphicsManager/Objects/Core/FontFamily.cs +++ b/GraphicsManager/Objects/Core/FontFamily.cs @@ -8,14 +8,16 @@ namespace GraphicsManager.Objects.Core; public class FontFamily { private static uint index = 0; - public event Func? ReloadUI; + public event Func? ReloadUI; + public static bool MemoryFont; + public static string FontPath = Path.GetTempPath(); public required string Family { get; init; } private FontSize fs = FontSize.Thin; - internal Dictionary> InternalFonts = new(); - internal Dictionary> InternalFontsi = new(); - internal bool IsZip = false; - internal Dictionary> SInternalFonts = new(); - internal Dictionary> SInternalFontsi = new(); + //internal Dictionary InternalFonts = new(); + //internal Dictionary InternalFontsi = new(); + //internal bool IsZip = false; + internal Dictionary InternalFonts = new(); + internal Dictionary InternalFontsi = new(); internal static List AllFams = new(); public static Task LoadFontFamilyTask(Stream FamilyZip, string Family, string extra = "-") @@ -25,14 +27,13 @@ public class FontFamily public static FontFamily LoadFontFamily(Stream FamilyZip, string Family, string extra = "-") { - extra = extra.ToLower(); + extra = extra.ToLower(); FontFamily f = new() { Family = Family }; AllFams.Add(f); using ZipArchive archive = new ZipArchive(FamilyZip, ZipArchiveMode.Read, false); - f.IsZip = true; foreach (ZipArchiveEntry font in archive.Entries) { @@ -42,20 +43,57 @@ public class FontFamily void tryadd(FontSize s, bool i = false) { - var memoryStream = new MemoryStream(); - var ss = font.Open(); - ss.CopyTo(memoryStream); - if (i) + if (MemoryFont) { - if (!f.SInternalFontsi.ContainsKey(s)) - f.SInternalFontsi.Add(s, new(memoryStream, null)); + using (var ss = font.Open()) + { + using (var memoryStream = new MemoryStream()) + { + ss.CopyTo(memoryStream); + byte[] fontBytes = memoryStream.ToArray(); + + if (i) + { + if (!f.InternalFontsi.ContainsKey(s)) + { + f.InternalFontsi.Add(s, Font.MakeFontFromByteArray(fontBytes)); + } + } + else + { + if (!f.InternalFonts.ContainsKey(s)) + { + f.InternalFonts.Add(s, Font.MakeFontFromByteArray(fontBytes)); + } + } + } + } } else { - if (!f.SInternalFonts.ContainsKey(s)) - f.SInternalFonts.Add(s, new(memoryStream, null)); + string p = FontPath; + if (!Directory.Exists(p)) Directory.CreateDirectory(p); + p = Path.Combine(p, "GM_Familys"); + if (!Directory.Exists(p)) Directory.CreateDirectory(p); + p = Path.Combine(p, Family); + if (!Directory.Exists(p)) Directory.CreateDirectory(p); + p = Path.Combine(p, Path.GetRandomFileName()); + font.ExtractToFile(p, true); + if (i) + { + if (!f.InternalFontsi.ContainsKey(s)) + { + f.InternalFontsi.Add(s, Font.MakeFontFromFile(p)); + } + } + else + { + if (!f.InternalFonts.ContainsKey(s)) + { + f.InternalFonts.Add(s, Font.MakeFontFromFile(p)); + } + } } - ss.Dispose(); } if (fd.EndsWith("italic")) @@ -84,7 +122,7 @@ public class FontFamily } } -FamilyZip.Dispose(); + FamilyZip.Dispose(); return f; } diff --git a/GraphicsManager/Objects/Core/FontInteraction.cs b/GraphicsManager/Objects/Core/FontInteraction.cs index f0933c0..52a0ac6 100644 --- a/GraphicsManager/Objects/Core/FontInteraction.cs +++ b/GraphicsManager/Objects/Core/FontInteraction.cs @@ -73,108 +73,22 @@ public class FontInteraction CurrentFonts = new Font[Families_.Count]; for (int j = 0; j < Families_.Count; j++) { - if (Families_[j].IsZip) + if (value) { - if (value) + if (Families_[j].InternalFontsi.TryGetValue(FontSize, out Font? f)) { - if (Families_[j].SInternalFontsi.TryGetValue(FontSize, out Tuple? f)) - { - i = value; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].SInternalFontsi[fs] = new(f.Item1, - Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1)); - break; - case false: - Families_[j].SInternalFonts[fs] = new(f.Item1, - Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1)); - break; - } - } - - CurrentFonts[j] = (Families_[j].SInternalFontsi[fs].Item2!); - if (ReloadUI is not null) ReloadUI.Invoke(); - } - } - else - { - if (Families_[j].SInternalFonts.TryGetValue(FontSize, out Tuple? f)) - { - i = value; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].SInternalFontsi[fs] = new(f.Item1, - Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1)); - Families_[j].SInternalFontsi[fs].Item1.Dispose(); - break; - case false: - Families_[j].SInternalFonts[fs] = new(f.Item1, - Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1)); - Families_[j].SInternalFonts[fs].Item1.Dispose(); - break; - } - } - - CurrentFonts[j] = Families_[j].SInternalFonts[fs].Item2!; - if (ReloadUI is not null) ReloadUI.Invoke(); - } + i = value; + CurrentFonts[j] = (Families_[j].InternalFontsi[fs]); + if (ReloadUI is not null) ReloadUI.Invoke(); } } else { - if (value) + if (Families_[j].InternalFonts.TryGetValue(FontSize, out Font? f)) { - if (Families_[j].InternalFontsi.TryGetValue(FontSize, out Tuple? f)) - { - i = value; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].InternalFontsi[fs] = new(f.Item1, - Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1)); - break; - case false: - Families_[j].InternalFonts[fs] = new(f.Item1, - Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1)); - break; - } - } - - CurrentFonts[j] = (Families_[j].InternalFontsi[fs].Item2!); - if (ReloadUI is not null) ReloadUI.Invoke(); - } - } - else - { - if (Families_[j].InternalFonts.TryGetValue(FontSize, out Tuple? f)) - { - i = value; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].InternalFontsi[fs] = new(f.Item1, - Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1)); - break; - case false: - Families_[j].InternalFonts[fs] = new(f.Item1, - Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1)); - break; - } - } - - CurrentFonts[j] = Families_[j].InternalFonts[fs].Item2!; - if (ReloadUI is not null) ReloadUI.Invoke(); - } + i = value; + CurrentFonts[j] = Families_[j].InternalFonts[fs]; + if (ReloadUI is not null) ReloadUI.Invoke(); } } } @@ -185,9 +99,7 @@ public class FontInteraction private static Tuple gcl(Dictionary> thisList, FontSize thisValue, out FontSize fs) { Dictionary>.KeyCollection keys = thisList.Keys; - FontSize nearest = thisValue - - keys.Where(k => k <= thisValue) - .Min(k => thisValue - k); + FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First(); fs = nearest; return thisList[nearest]; } @@ -195,9 +107,15 @@ public class FontInteraction private static Tuple Sgcl(Dictionary> thisList, FontSize thisValue, out FontSize fs) { Dictionary>.KeyCollection keys = thisList.Keys; - FontSize nearest = thisValue - - keys.Where(k => k <= thisValue) - .Min(k => thisValue - k); + FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First(); + fs = nearest; + return thisList[nearest]; + } + + private static Font Sgcl(Dictionary thisList, FontSize thisValue, out FontSize fs) + { + Dictionary.KeyCollection keys = thisList.Keys; + FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First(); fs = nearest; return thisList[nearest]; } @@ -210,61 +128,17 @@ public class FontInteraction CurrentFonts = new Font[Families_.Count]; for (int j = 0; j < Families_.Count; j++) { - if (Families_[j].IsZip) + Font f = Italic switch { - Tuple f = Italic switch - { - true => Sgcl(Families_[j].SInternalFontsi, value, out fs), - false => Sgcl(Families_[j].SInternalFonts, value, out fs), - }; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].SInternalFontsi[fs] = new(f.Item1, Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1)); - Families_[j].SInternalFontsi[fs].Item1.Dispose(); - break; - case false: - Families_[j].SInternalFonts[fs] = new(f.Item1, Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1)); - Families_[j].SInternalFonts[fs].Item1.Dispose(); - break; - } - } + true => Sgcl(Families_[j].InternalFontsi, value, out fs), + false => Sgcl(Families_[j].InternalFonts, value, out fs), + }; - CurrentFonts[j] = Italic switch - { - true => Families_[j].SInternalFontsi[fs].Item2!, - false => Families_[j].SInternalFonts[fs].Item2!, - }; - } - else + CurrentFonts[j] = Italic switch { - Tuple f = Italic switch - { - true => gcl(Families_[j].InternalFontsi, value, out fs), - false => gcl(Families_[j].InternalFonts, value, out fs), - }; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Families_[j].InternalFontsi[fs] = new(f.Item1, - Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1)); - break; - case false: - Families_[j].InternalFonts[fs] = - new(f.Item1, Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1)); - break; - } - } - CurrentFonts[j] = Italic switch - { - true => Families_[j].InternalFontsi[fs].Item2!, - false => Families_[j].InternalFonts[fs].Item2!, - }; - } + true => Families_[j].InternalFontsi[fs], + false => Families_[j].InternalFonts[fs], + }; } if (ReloadUI is not null) ReloadUI.Invoke(); } diff --git a/GraphicsManager/Objects/Core/LabelBase.cs b/GraphicsManager/Objects/Core/LabelBase.cs new file mode 100644 index 0000000..4d1c432 --- /dev/null +++ b/GraphicsManager/Objects/Core/LabelBase.cs @@ -0,0 +1,623 @@ +using System.Text; +using GraphicsManager.Enums; +using GraphicsManager.Interfaces; +using GraphicsManager.Structs; +using OpenTK.Graphics.OpenGL4; +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Common.Input; +using OpenTK.Windowing.Desktop; +using OpenTK.Windowing.GraphicsLibraryFramework; + +namespace GraphicsManager.Objects.Core; + +public class LabelBase : ILabel +{ + public LabelBase(FontFamily fontFamily) + { + Font = FontInteraction.Load(fontFamily); + } + + public LabelBase(FontInteraction interaction) + { + Font = interaction; + } + + public BetterContextMenu? ContextMenu { get; set; } = null; + public IParent? Parent { get; protected set; } + public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top; + protected Vector2 laf = new(), saf = new(); + + public Vector2 LocationAsFloat { get { return laf; } } + public Vector2 SizeAsFloat { get { return saf; } } + protected Vector2i? msize = null; + public virtual Vector2i? MaxSize + { + get => msize; + set + { + msize = value; + StringBuilder sb = new(); + float max_x = 0, lines = 1, char_x = 0F; + for (int i = 0; i < Text.Length; i++) + { + char c; + if (PasswordChar is null) + c = Text[i]; + else + c = PasswordChar.Value; + bool n = (c == '\n'); + + if (n) + { + lines++; + sb.Append(c); + char_x = 0f; + } + else + { + Character ch; + if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); + else ch = Texture.GetChar(Font, c); + if (i > 0 && text[i-1] == ' ') + { + int addc = 0; + float word_char_x = char_x; + while (MaxSize is not null) + { + if (addc + i == Text.Length) break; + if (text[addc + i] == ' ') break; + Character ch2; + if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context); + else ch2 = Texture.GetChar(Font, c); + word_char_x += (ch2.Advance >> 6) * Scale; + if (word_char_x > MaxSize.Value.X) + { + char_x = 0f; + lines++; + sb.Append('\n'); + break; + } + addc++; + } + } + sb.Append(c); + float w = ch.Size.X * Scale; + float xrel = char_x + ch.Bearing.X * Scale; + char_x += (ch.Advance >> 6) * Scale; + if ((xrel + w) >= max_x) max_x = (xrel + w); + } + } + text_Calculated = sb.ToString(); + Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); + } + } + protected char? pc; + public char? PasswordChar + { + get => pc; + set + { + pc = value; + if (Parent is not null) Parent.TryDraw(); + } + } + protected bool _Visible = true; + + public virtual bool Visible + { + get => _Visible; + set + { + _Visible = value; + if (Parent is not null && Loaded) Parent.TryDraw(); + } + } + + public static readonly Dictionary>> _characters = new(); + protected string text = string.Empty; + protected string text_Calculated = string.Empty; + public int VAO { get; protected set; } + + public virtual void Focus() + { + + } + public virtual void UnFocus() + { + + } + public int VBO { get; protected set; } + public virtual Vector2 DIR { get; set; } = new Vector2(1f, 0f); + + public virtual Vector2i GetSizeOfChar(int Index) + { + float mx = 0, my = 0; + char character; + if (PasswordChar is null) + character = Text[Index]; + else + character = PasswordChar.Value; + + + if (character == '\n') + { + mx = 0f; + my += Font.PixelHeight * Scale; + } + else + { + Character cha; + if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context); + else cha = Texture.GetChar(Font, character); + mx = cha.Size.X * Scale; + my = cha.Size.Y * Scale; + } + return new((int)mx, (int)my); + } + + public virtual Vector2i GetBearingOfChar(int Index) + { + float mx = 0, my = 0; + char character; + if (PasswordChar is null) + character = Text[Index]; + else + character = PasswordChar.Value; + + if (character == '\n') + { + mx = 0f; + my += Font.PixelHeight * Scale; + } + else + { + Character cha; + if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context); + else cha = Texture.GetChar(Font, character); + mx = cha.Bearing.X * Scale; + my = cha.Bearing.Y * Scale; + } + return new((int)mx, (int)my); + } + + public List SubHitBoxes { get; } = new(); + + public virtual string Text + { + get => text; + set + { + if (value is null) value = string.Empty; + text = value; + StringBuilder sb = new(); + text_Calculated = string.Empty; + float max_x = 0, lines = 1, char_x = 0F; + for (int i = 0; i < Text.Length; i++) + { + char c; + if (PasswordChar is null) + c = Text[i]; + else + c = PasswordChar.Value; + bool n = (c == '\n'); + + if (n) + { + lines++; + char_x = 0f; + sb.Append(c); + } + else + { + Character ch; + if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); + else ch = Texture.GetChar(Font, c); + if (MaxSize is not null && i > 0 && text[i-1] == ' ') + { + int addc = 0; + float word_char_x = char_x; + while (true) + { + if (addc + i == Text.Length) break; + if (text[addc + i] == ' ') break; + Character ch2; + if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context); + else ch2 = Texture.GetChar(Font, c); + word_char_x += (ch2.Advance >> 6) * Scale; + if (word_char_x > MaxSize.Value.X) + { + char_x = 0f; + lines++; + sb.Append('\n'); + break; + } + addc++; + } + } + + sb.Append(c); + float w = ch.Size.X * Scale; + float xrel = char_x + ch.Bearing.X * Scale; + char_x += (ch.Advance >> 6) * Scale; + if ((xrel + w) >= max_x) max_x = (xrel + w); + } + } + + text_Calculated = sb.ToString(); + Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); + if (Loaded) + { + + if (Window is not null && Window.CanControleUpdate) + { + if (!Window.Context.IsCurrent) + { + try + { + Window.Context.MakeCurrent(); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + if (Window.Context.IsCurrent) + { + Parent!.TryDraw(); + } + } + } + } + } + public virtual uint LineHeight + { + get + { + return (uint)((Font.PixelHeight * (Font.CurrentFonts[0].Face.Height / (float)Font.CurrentFonts[0].Face.UnitsPerEM)) * Scale); + } + } + public Shader Shader { get; set; } = null!; + public FontInteraction Font { get; protected set; } + public virtual float Scale { get; set; } = 1.0f; + public virtual Vector2i Distance { get; set; } + protected Vector3i loc_; + public virtual Vector3i Location + { + get + { + return loc_; + } + set + { + SetLocation(value.X, value.Y, value.Z); + } + } + + public virtual void SetLocation(int xy) + { + SetLocation(xy, xy, 0); + } + + public virtual void SetLocation(int x, int y) + { + SetLocation(x, y, 0); + } + + public virtual void SetLocation(int x, int y, int z) + { + loc_.X = x; + loc_.Y = y; + loc_.Z = z; + if (Window is null || Parent is null) return; + if (Window.CanControleUpdate && Loaded) + { + Parent!.TryDraw(); + if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); + } + } + + public virtual void SetSize(int wh) + { + SetSize(wh, wh); + } + + public virtual void SetSize(int w, int h) + { + _size.X = w; + _size.Y = h; + } + + protected Vector2i _size; + public virtual Vector2i Size { get => _size; + set + { + _size = value; + //if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); + } + } + + public virtual Vector2i GetCharLocation(int index) + { + float max_x = 0, lines = 0, char_x = 0F; + for (int i = 0; i < index; i++) + { + char c; + if (PasswordChar is null) + c = text_Calculated[i]; + else + c = PasswordChar.Value; + bool n = (c == '\n'); + + if (n) + { + lines++; + char_x = 0f; + } + else + { + Character ch; + if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); + else ch = Texture.GetChar(Font, c); + float w = ch.Size.X * Scale; + float xrel = char_x + ch.Bearing.X * Scale; + char_x += (ch.Advance >> 6) * Scale; + max_x = (xrel + w); + } + } + return new((int)char_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); + } + + public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs) + { + + } + + public virtual void SendClipEvent(string ClipString) + { + + } + + public virtual void Clean() + { + Tuple tup = GlobalBuffers[Window!.Context]; + if (tup.Item3 - 1 == 0) + { + //Broken, I may fix latter + + //if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); + //GL.DeleteBuffer(VBO); + //GL.DeleteVertexArray(VAO); + //GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + //GlobalBuffers.Remove(Window!.Context); + } + else + { + GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1); + } + Size = new(0, 0); + Loaded = false; + Visible = false; + } + + public event Func? SizeChanged; + + public virtual void Draw(int x, int y, int sx, int sy, int sw, int sh) + { + if (Visible && Loaded && this.Font is not null) + { + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); + Shader.Use(); + GL.Uniform4(Shader.GetUniformLocation("textColor"), new Color4(255,255,255,255)); + GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); + GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); + Shader.SetMatrixF4("projection", Window.WindowSizeMatrix); + + GL.BindVertexArray(VAO); + + float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X); + Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad); + Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f)); + float char_x = 0.0f; + + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + GL.ActiveTexture((Shader.GetUniformLocation("u_texture") switch + { + 0 => TextureUnit.Texture0, + 1 => TextureUnit.Texture1, + 2 => TextureUnit.Texture2, + 3 => TextureUnit.Texture3, + 4 => TextureUnit.Texture4, + 5 => TextureUnit.Texture5, + 6 => TextureUnit.Texture6, + 7 => TextureUnit.Texture7, + 8 => TextureUnit.Texture8, + 9 => TextureUnit.Texture9, + })); + + float hhh = 0f; + for (int i = 0; i < text_Calculated.Length; i++) + { + char c; + if (PasswordChar is null) + c = text_Calculated[i]; + else + c = PasswordChar.Value; + bool n = (c == '\n'); + if (!_characters[Window!.Context][Font].ContainsKey(c) && !n) + { + _ = Texture.TextureForChar(Window!.Context, Font, c, Shader); + } + + if (n) + { + hhh += LineHeight; + hhh += Font.ExtraLinePixels; + char_x = 0f; + } + else + { + if (!_characters[Window!.Context][Font].ContainsKey(c)) continue; + Character ch = _characters[Window!.Context][Font][c]; + + float w = ch.Size.X * Scale; + float h = ch.Size.Y * Scale; + float xrel = char_x + ch.Bearing.X * Scale; + float yrel = (ch.Size.Y - ch.Bearing.Y) * Scale; + yrel += hhh; + char_x += (ch.Advance >> 6) * Scale; + Matrix4 scaleM = Matrix4.CreateScale(new Vector3(w, h, 1.0f)); + Matrix4 transRelM = Matrix4.CreateTranslation(new Vector3(xrel, yrel, 0.0f)); + + Matrix4 modelM = scaleM * transRelM * rotateM * transOriginM; + GL.UniformMatrix4(0, false, ref modelM); + + ch.Texture.Use(); + + GL.DrawArrays(PrimitiveType.Triangles, 0, 6); + } + } + } + } + public virtual void ForceDistanceUpdate() + { + } + + + public virtual void ForceDistanceUpdate(IParent parent) + { + if (parent is IWindow w) Distance = new(w.CS.X - Size.X - Location.X, w.CS.Y - Size.Y - Location.Y); + else Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y); + } + public IWindow? Window { get; protected set; } + protected static Dictionary> GlobalBuffers = new(); + public bool IgnoreHover { get; set; } + public bool AllowHoverFromBehind { get; set; } + public event Func? FilesDroped; + + public void SendFilesEvent(string[] Files) + { + if (FilesDroped is not null) _ = FilesDroped.Invoke(this, Files); + } + public virtual void LoadToParent(IParent window, IWindow win) + { + if (Loaded) return; + if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new()); + if (!_characters[win!.Context].ContainsKey(Font)) _characters[win!.Context].Add(Font, new Dictionary()); + if (Shader is null) Shader = Label.DefaultTextShader[win.Context]; + Parent = window; + Window = win; + Window.MouseDown += WindowOnMouseDown; + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); + if (!GlobalBuffers.ContainsKey(win.Context)) + { + float[] vquad = + { + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f + }; + int _VBO = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO); + GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); + int _VAO = GL.GenVertexArray(); + GL.BindVertexArray(_VAO); + GL.EnableVertexAttribArray(0); + GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); + GL.EnableVertexAttribArray(1); + GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); + GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0)); + } + + Tuple tup = GlobalBuffers[win.Context]; + VBO = tup.Item1; + VAO = tup.Item2; + GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1); + + + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.BindVertexArray(0); + + Loaded = true; + Text = Text; + Location = Location; + if (Distance.X == 0 && Distance.Y == 0) ForceDistanceUpdate(Parent); + if (WindowLoaded is not null) WindowLoaded.Invoke(this); + } + + private void WindowOnMouseDown(MouseButtonEventArgs obj) + { + if (MouseInside && obj.Button == MouseButton.Button1) + { + bool subnothit = true; + if (SubHitBoxes.Count > 0) + { + foreach (SubHitBox hb in SubHitBoxes) + { + if (hb.MouseInside) + { + hb.SendClick(); + subnothit = false; + } + } + } + if (subnothit && Clicked is not null) _ = Clicked.Invoke(this); + } + if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!); + if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!); + } + + public MouseCursor HoverMouse { get; set; } = MouseCursor.Default; + + protected bool mi; + + public virtual bool MouseInside + { + get => mi; + set + { + if (Window is null) return; + if (Window.HoveringControl == this && value) + { + mi = value; + if (MouseEnter is not null) MouseEnter.Invoke(this); + } + + if (Window.HoveringControl != this && !value) + { + mi = value; + if (MouseLeave is not null) MouseLeave.Invoke(this); + } + } + } + + public event Func? Clicked; + public event Func? WindowLoaded; + public event Func? MouseEnter; + public event Func? MouseLeave; + public object? Tag { get; set; } = null; + + private bool l = false; + + protected virtual void InvokeWindowLoaded() + { + if (WindowLoaded is not null) WindowLoaded.Invoke(this); + } + + public bool Loaded + { + get => l; + protected set + { + l = value; + } + } +} \ No newline at end of file diff --git a/GraphicsManager/Objects/Core/ParentBase.cs b/GraphicsManager/Objects/Core/ParentBase.cs index ea49c09..d915677 100644 --- a/GraphicsManager/Objects/Core/ParentBase.cs +++ b/GraphicsManager/Objects/Core/ParentBase.cs @@ -24,11 +24,9 @@ public abstract class ParentBase : Rectangle, IParent if (!BlockDraw && Parent is not null) Parent.TryDraw(); } - public virtual void ParentResize(ResizeEventArgs e) + public virtual void ParentResize() { - 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; @@ -42,15 +40,24 @@ public abstract class ParentBase : Rectangle, IParent 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) + bool mooved = false; + if (sx != Controls[i].Size.X || sy != Controls[i].Size.Y) { - parent.ParentResize(e); + 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 (mooved && Controls[i] is IParent parent) + { + parent.ParentResize(); } } - Parent!.TryDraw(); - BlockDraw = PastBlockState; + if (Parent is not null) Parent.TryDraw(); + BlockDraw = false; } public virtual void ReportSizeUpdate(IRenderObject Control) @@ -58,41 +65,45 @@ public abstract class ParentBase : Rectangle, IParent } - public override void Draw(int x, int y, int w, int h) + 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) { - int nx = x, ny = y, nw = w, nh = h; - if (Location.X > nw) + if (Location.X - sx + x > sw || Location.Y - sy + y > sh) return; - else - { - nx += Location.X; - nw -= Location.X; - if (Size.X < nw) - nw = Size.X; - } - if (Location.Y > nh) - return; - else - { - if (Location.Y > -1) - { - ny += Location.Y; - nh -= Location.Y; - if (Size.Y < nh) - nh = Size.Y; - } - else - { - if (Size.Y + Location.Y < nh) - nh = Size.Y + Location.Y; - } - } - if (nw == 0 || nh == 0) return; - GL.Scissor(nx, Window!.CS.Y - ny - nh, nw, nh); - base.Draw(nx,ny,nw,nh); + 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) return; + base.Draw(x,y,sx,sy,sw,sh); IEnumerable needload = Controls.Where(a => a.Loaded == false); if (needload.Any()) @@ -108,8 +119,8 @@ public abstract class ParentBase : Rectangle, IParent 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!.CS.Y - ny - nh, nw, nh); - Controls[i].Draw(nx, ny, nw, nh); + GL.Scissor(sx, Window!.CS.Y - sy - sh, sw, sh); + Controls[i].Draw(x,y,sx,sy,sw,sh); } } } @@ -149,7 +160,7 @@ public abstract class ParentBase : Rectangle, IParent { Controls[i].Location = Controls[i].Location; } - ParentResize(new()); + ParentResize(); if (Parent is not null) Parent.TryDraw(); BlockDraw = false; } diff --git a/GraphicsManager/Objects/Core/RoundedButton.cs b/GraphicsManager/Objects/Core/RoundedButton.cs index e23d8ae..50b9e09 100644 --- a/GraphicsManager/Objects/Core/RoundedButton.cs +++ b/GraphicsManager/Objects/Core/RoundedButton.cs @@ -60,11 +60,11 @@ public class RoundedButton : Rectangle base.Clean(); } - public override void Draw(int x, int y, int w, int h) + public override void Draw(int x, int y, int sx, int sy, int sw, int sh) { if (!Visible || !Loaded) return; - base.Draw(x,y,w,h); - _label.Draw(x,y,w,h); + base.Draw(x,y,sx,sy,sw,sh); + _label.Draw(x,y,sx,sy,sw,sh); } public override void LoadToParent(IParent Parent, IWindow Window) diff --git a/GraphicsManager/Objects/Core/Shader.cs b/GraphicsManager/Objects/Core/Shader.cs index b8d8e43..3ebe3a8 100755 --- a/GraphicsManager/Objects/Core/Shader.cs +++ b/GraphicsManager/Objects/Core/Shader.cs @@ -115,6 +115,12 @@ public class Shader : IDisposable GL.UniformMatrix4(_uniformLocations[name], true, ref data); } + public void SetMatrix4(int loc, Matrix4 data) + { + GL.UseProgram(Handle); + GL.UniformMatrix4(loc, true, ref data); + } + public void SetMatrixF4(string name, Matrix4 data) { GL.UseProgram(Handle); diff --git a/GraphicsManager/Objects/Core/SubHitBox.cs b/GraphicsManager/Objects/Core/SubHitBox.cs new file mode 100644 index 0000000..c20002f --- /dev/null +++ b/GraphicsManager/Objects/Core/SubHitBox.cs @@ -0,0 +1,41 @@ +using OpenTK.Mathematics; +using OpenTK.Windowing.Common.Input; + +namespace GraphicsManager.Objects.Core; + +public class SubHitBox +{ + public virtual Vector2i Size { get; set; } + public virtual Vector2i Location { get; set; } + public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default; + private bool mi = false; + + internal virtual bool MouseInside + { + get + { + return mi; + } + set + { + if (mi == value) return; + mi = value; + if (value && MouseEnter is not null) MouseEnter.Invoke(this).Wait(); + if (!value && MouseLeave is not null) MouseLeave.Invoke(this).Wait(); + } + } + + public event Func? Clicked; + public event Func? MouseLeave; + public event Func? MouseEnter; + + internal void SendClick() + { + if (Clicked is not null) _ = Clicked.Invoke(this); + } + + public override string ToString() + { + return base.ToString()+ $": {{X: {Location.X}, Y: {Location.Y}, Width: {Size.X}, Height: {Size.Y}}}"; + } +} \ No newline at end of file diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs index a241774..f64ef6c 100755 --- a/GraphicsManager/Objects/Core/Texture.cs +++ b/GraphicsManager/Objects/Core/Texture.cs @@ -146,7 +146,7 @@ public class Texture { } - internal static Character GetChar(Face face, char charter) + public static Character GetChar(Face face, char charter) { ushort temp = (charter); if (face.GetCharIndex(temp) == 0) @@ -172,7 +172,7 @@ public class Texture }; } - internal static Character GetChar(FontInteraction l, char charter, IGLFWGraphicsContext con) + public static Character GetChar(FontInteraction l, char charter, IGLFWGraphicsContext con) { try { @@ -203,7 +203,7 @@ public class Texture return GetChar(l.CurrentFonts[0].Face, (char)1); } - internal static Character GetChar(FontInteraction l, char charter) + public static Character GetChar(FontInteraction l, char charter) { try { @@ -235,7 +235,7 @@ public class Texture private static Dictionary BadChars = new(); - internal static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter, Shader s) + public static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter, Shader s) { try { diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs index 903adef..a9d738b 100644 --- a/GraphicsManager/Objects/FlowLayout.cs +++ b/GraphicsManager/Objects/FlowLayout.cs @@ -199,21 +199,26 @@ public class FlowLayout : ParentBase, IFlow if (arg is not ILabel) arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top; return Task.CompletedTask; } - + + public override void SetSize(int w, int h) + { + BlockDraw = true; + base.SetSize(w, h); + for (int i = 0; i < Controls.Length; i++) + { + Controls[i].SetSize(w, Controls[i].Size.Y); + } + ParentResize(); + if (Parent is not null) Parent.TryDraw(); + BlockDraw = false; + } + public override Vector2i Size { get => base.Size; set { - BlockDraw = true; - base.Size = value; - for (int i = 0; i < Controls.Length; i++) - { - Controls[i].Size = new(value.X, Controls[i].Size.Y); - } - ParentResize(new()); - if (Parent is not null) Parent.TryDraw(); - BlockDraw = false; + SetSize(value.X, value.Y); } } diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs index 33ddd5b..76d48f0 100755 --- a/GraphicsManager/Objects/Label.cs +++ b/GraphicsManager/Objects/Label.cs @@ -1,4 +1,5 @@ -using GraphicsManager.Enums; +using System.Text; +using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; using GraphicsManager.Structs; @@ -11,353 +12,27 @@ using OpenTK.Windowing.GraphicsLibraryFramework; namespace GraphicsManager.Objects; -public class Label : ILabel +public class Label : LabelBase { public static readonly Dictionary DefaultTextShader = new(); - public Label(FontFamily fontFamily) + public Label(FontFamily fontFamily):base(fontFamily) { Font = FontInteraction.Load(fontFamily); } - public Label(FontInteraction interaction) + public Label(FontInteraction interaction):base(interaction) { Font = interaction; } - public BetterContextMenu? ContextMenu { get; set; } = null; - public IParent? Parent { get; private set; } - public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top; - private Vector2 laf = new(), saf = new(); - - public Vector2 LocationAsFloat { get { return laf; } } - public Vector2 SizeAsFloat { get { return saf; } } - private Vector2i? msize = null; - public Vector2i? MaxSize - { - get => msize; - set - { - msize = value; - text_Calculated = string.Empty; - float max_x = 0, lines = 1, char_x = 0F; - for (int i = 0; i < Text.Length; i++) - { - char c; - if (PasswordChar is null) - c = Text[i]; - else - c = PasswordChar.Value; - bool n = (c == '\n'); - - if (n) - { - lines++; - text_Calculated += c; - char_x = 0f; - } - else - { - Character ch; - if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); - else ch = Texture.GetChar(Font, c); - if (i > 0 && text[i-1] == ' ') - { - int addc = 0; - float word_char_x = char_x; - while (MaxSize is not null) - { - if (addc + i == Text.Length) break; - if (text[addc + i] == ' ') break; - Character ch2; - if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context); - else ch2 = Texture.GetChar(Font, c); - word_char_x += (ch2.Advance >> 6) * Scale; - if (word_char_x > MaxSize.Value.X) - { - char_x = 0f; - lines++; - text_Calculated += '\n'; - break; - } - addc++; - } - } - text_Calculated += c; - float w = ch.Size.X * Scale; - float xrel = char_x + ch.Bearing.X * Scale; - char_x += (ch.Advance >> 6) * Scale; - if ((xrel + w) >= max_x) max_x = (xrel + w); - } - } - Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); - } - } - private char? pc; - public char? PasswordChar - { - get => pc; - set - { - pc = value; - if (Parent is not null) Parent.TryDraw(); - } - } - private bool _Visible = true; - - public bool Visible - { - get => _Visible; - set - { - _Visible = value; - if (Parent is not null && Loaded) Parent.TryDraw(); - } - } - - public static readonly Dictionary>> _characters = new(); - private string text = string.Empty; - private string text_Calculated = string.Empty; - public int VAO { get; private set; } - - public void Focus() - { - - } - public void UnFocus() - { - - } - public int VBO { get; private set; } - public Vector2 DIR { get; set; } = new Vector2(1f, 0f); - - public Vector2i GetSizeOfChar(int Index) - { - float mx = 0, my = 0; - char character; - if (PasswordChar is null) - character = Text[Index]; - else - character = PasswordChar.Value; - - - if (character == '\n') - { - mx = 0f; - my += Font.PixelHeight * Scale; - } - else - { - Character cha; - if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context); - else cha = Texture.GetChar(Font, character); - mx = cha.Size.X * Scale; - my = cha.Size.Y * Scale; - } - return new((int)mx, (int)my); - } - - public string Text - { - get => text; - set - { - if (value is null) value = string.Empty; - text = value; - text_Calculated = string.Empty; - float max_x = 0, lines = 1, char_x = 0F; - for (int i = 0; i < Text.Length; i++) - { - char c; - if (PasswordChar is null) - c = Text[i]; - else - c = PasswordChar.Value; - bool n = (c == '\n'); - - if (n) - { - lines++; - char_x = 0f; - text_Calculated += c; - } - else - { - Character ch; - if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); - else ch = Texture.GetChar(Font, c); - if (MaxSize is not null && i > 0 && text[i-1] == ' ') - { - int addc = 0; - float word_char_x = char_x; - while (true) - { - if (addc + i == Text.Length) break; - if (text[addc + i] == ' ') break; - Character ch2; - if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context); - else ch2 = Texture.GetChar(Font, c); - word_char_x += (ch2.Advance >> 6) * Scale; - if (word_char_x > MaxSize.Value.X) - { - char_x = 0f; - lines++; - text_Calculated += '\n'; - break; - } - addc++; - } - } - - text_Calculated += c; - float w = ch.Size.X * Scale; - float xrel = char_x + ch.Bearing.X * Scale; - char_x += (ch.Advance >> 6) * Scale; - if ((xrel + w) >= max_x) max_x = (xrel + w); - } - } - - - Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); - if (Loaded) - { - - if (Window is not null && Window.CanControleUpdate) - { - if (!Window.Context.IsCurrent) - { - try - { - Window.Context.MakeCurrent(); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - if (Window.Context.IsCurrent) - { - Parent!.TryDraw(); - } - } - } - } - } - public uint LineHeight - { - get - { - return (uint)((Font.PixelHeight * (Font.CurrentFonts[0].Face.Height / (float)Font.CurrentFonts[0].Face.UnitsPerEM)) * Scale); - } - } - public Shader Shader { get; set; } = null!; - public FontInteraction Font { get; } - public float Scale { get; set; } = 1.0f; public Color4 Color { get; set; } = new Color4(255, 255, 255, 255); - public Vector2i Distance { get; set; } - private Vector3i loc_; - public Vector3i Location - { - get - { - return loc_; - } - set - { - loc_ = value; - if (Window is null || Parent is null) return; - if (Window.CanControleUpdate && Loaded) - { - Parent!.TryDraw(); - if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); - } - } - } - - private Vector2i _size; - public Vector2i Size { get => _size; - set - { - _size = value; - //if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); - } - } - - public Vector2i GetCharLocation(int index) - { - float max_x = 0, lines = 0, char_x = 0F; - for (int i = 0; i < index; i++) - { - char c; - if (PasswordChar is null) - c = text_Calculated[i]; - else - c = PasswordChar.Value; - bool n = (c == '\n'); - - if (n) - { - lines++; - char_x = 0f; - } - else - { - Character ch; - if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context); - else ch = Texture.GetChar(Font, c); - float w = ch.Size.X * Scale; - float xrel = char_x + ch.Bearing.X * Scale; - char_x += (ch.Advance >> 6) * Scale; - max_x = (xrel + w); - } - } - return new((int)char_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels)); - } - - public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs) - { - - } - - public virtual void SendClipEvent(string ClipString) - { - - } - - public void Clean() - { - Tuple tup = GlobalBuffers[Window!.Context]; - if (tup.Item3 - 1 == 0) - { - //Broken, I may fix latter - - //if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); - //GL.DeleteBuffer(VBO); - //GL.DeleteVertexArray(VAO); - //GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - //GlobalBuffers.Remove(Window!.Context); - } - else - { - GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1); - } - Size = new(0, 0); - Loaded = false; - Visible = false; - } - - public event Func? SizeChanged; - - public void Draw(int x, int y, int ww, int hh) + public override void Draw(int x, int y, int sx, int sy, int sw, int sh) { if (Visible && Loaded && this.Font is not null) { if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); Shader.Use(); - GL.Enable(EnableCap.Blend); GL.Uniform4(Shader.GetUniformLocation("textColor"), Color); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); @@ -429,106 +104,4 @@ public class Label : ILabel } } } - public void ForceDistanceUpdate() - { - } - - public void ForceDistanceUpdate(IParent parent) - { - Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y); - } - public IWindow? Window { get; private set; } - private static Dictionary> GlobalBuffers = new(); - public bool IgnoreHover { get; set; } - public bool AllowHoverFromBehind { get; set; } - public void LoadToParent(IParent window, IWindow win) - { - if (Loaded) return; - if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new()); - if (!_characters[win!.Context].ContainsKey(Font)) _characters[win!.Context].Add(Font, new Dictionary()); - if (Shader is null) Shader = DefaultTextShader[win.Context]; - Parent = window; - Window = win; - Window.MouseDown += WindowOnMouseDown; - if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); - if (!GlobalBuffers.ContainsKey(win.Context)) - { - float[] vquad = - { - 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f - }; - int _VBO = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO); - GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); - int _VAO = GL.GenVertexArray(); - GL.BindVertexArray(_VAO); - GL.EnableVertexAttribArray(0); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); - GL.EnableVertexAttribArray(1); - GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); - GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0)); - } - - Tuple tup = GlobalBuffers[win.Context]; - VBO = tup.Item1; - VAO = tup.Item2; - GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1); - - - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - GL.BindVertexArray(0); - - Loaded = true; - Text = Text; - Location = Location; - if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); - if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); - if (WindowLoaded is not null) WindowLoaded.Invoke(this); - } - - private void WindowOnMouseDown(MouseButtonEventArgs obj) - { - if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this); - if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!); - if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!); - } - - public MouseCursor HoverMouse { get; set; } = MouseCursor.Default; - - private bool mi; - - public bool MouseInside - { - get => mi; - set - { - if (Window is null) return; - if (Window.HoveringControl == this && value) - { - mi = value; - if (MouseEnter is not null) MouseEnter.Invoke(this); - } - - if (Window.HoveringControl != this && !value) - { - mi = value; - if (MouseLeave is not null) MouseLeave.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; } } diff --git a/GraphicsManager/Objects/ProgressBar.cs b/GraphicsManager/Objects/ProgressBar.cs index 74be45f..b5c2bf8 100644 --- a/GraphicsManager/Objects/ProgressBar.cs +++ b/GraphicsManager/Objects/ProgressBar.cs @@ -146,10 +146,10 @@ public class ProgressBar : ParentBase } } - public override void Draw(int x, int y, int w, int h) + public override void Draw(int x, int y, int sx, int sy, int sw, int sh) { if (UpdateOnDraw) UpdateProgress(); - base.Draw(x, y, w, h); + base.Draw(x, y, sx,sy, sw, sh); } public void UpdateProgress() diff --git a/GraphicsManager/Objects/RainbowLabel.cs b/GraphicsManager/Objects/RainbowLabel.cs deleted file mode 100755 index ca73060..0000000 --- a/GraphicsManager/Objects/RainbowLabel.cs +++ /dev/null @@ -1,505 +0,0 @@ -using GraphicsManager.Enums; -using GraphicsManager.Interfaces; -using GraphicsManager.Objects.Core; -using GraphicsManager.Structs; -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; -using OpenTK.Windowing.Common; -using OpenTK.Windowing.Common.Input; -using OpenTK.Windowing.Desktop; -using OpenTK.Windowing.GraphicsLibraryFramework; -using SharpFont; -using Encoding = SharpFont.Encoding; - -namespace GraphicsManager.Objects; - -public class RainbowLabel : ILabel -{ - public RainbowLabel(FontFamily fontFamily) - { - Font = FontInteraction.Load(fontFamily); - } - - public RainbowLabel(FontInteraction interaction) - { - Font = interaction; - } - - public BetterContextMenu? ContextMenu { get; set; } = null; - public IParent? Parent { get; private set; } - public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top; - private Vector2 laf = new(), saf = new(); - - public Vector2 LocationAsFloat { get { return laf; } } - public Vector2 SizeAsFloat { get { return saf; } } - private char? pc = null; - public char? PasswordChar - { - get => pc; - set - { - pc = value; - if (Parent is not null) Parent.TryDraw(); - } - } - private bool _Visible = true; - - public bool Visible - { - get => _Visible; - set - { - _Visible = value; - if (Parent is not null && Loaded) Parent.TryDraw(); - } - } - - private string text = string.Empty; - public int VAO { get; private set; } - - public void Focus() - { - - } - public void UnFocus() - { - - } - public int VBO { get; private set; } - public Vector2 DIR { get; set; } = new Vector2(1f, 0f); - - public int TrueHeight = 0; - public int PostiveTrueHeight = 0; - - public Vector2i GetSizeOfChar(int Index) - { - float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F; - for (int i = 0; i < Index + 1; i++) - { - char character; - if (PasswordChar is null) - character = Text[i]; - else - character = PasswordChar.Value; - - - if (character == '\n') - { - char_x = 0f; - addy += Font.PixelHeight * Scale; - addy += Font.ExtraLinePixels; - continue; - } - Character cha = Texture.GetChar(Font, character); - 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); - } - - return new((int)addx, (int)addy); - } - public string Text - { - get => text; - set - { - if (value is null) value = string.Empty; - text = value; - int line = 0; - double nl = 0; - double addy = 0f, addy2 =0f, addx = 0F, char_x = 0F; - for (int i = 0; i < value.Length; i++) - { - char character; - if (PasswordChar is null) - character = value[i]; - else - character = PasswordChar.Value; - - if (character == '\n') - { - char_x = 0f; - nl = addy; - line++; - continue; - } - Character cha = Texture.GetChar(Font, character); - double w = cha.Size.X * Scale; - double xrel = char_x + cha.Bearing.X * Scale; - double yrel = ((cha.Size.Y - cha.Bearing.Y) * Scale) + (Font.PixelHeight * Scale); - yrel += nl; - char_x += (cha.Advance >> 6) * Scale; - if ((xrel + w) >= addx) addx = (xrel + w); - if (yrel > addy) addy = yrel; - if (line == 0) - { - if (addy2 < cha.Bearing.Y) addy2 = cha.Bearing.Y; - } - } - Size = new((int)addx, (int)addy); - PostiveTrueHeight = (int)addy2; - TrueHeight = (int)(addy - (Font.PixelHeight - addy2)); - if (Loaded) - { - - if (Window is not null && Window.CanControleUpdate) - { - if (!Window.Context.IsCurrent) - { - try - { - Window.Context.MakeCurrent(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - Parent!.TryDraw(); - } - } - } - } - public Shader Shader { get; set; } = null!; - public FontInteraction Font { get; } - public float Scale { get; set; } = 1.0f; - public Color4 Color { get; set; } = new Color4(255, 255, 255, 255); - public Vector2i Distance { get; set; } - private Vector3i loc_ = new(); - private int maxy = 0, maxx = 0; - public Vector3i Location - { - get - { - return loc_; - } - set - { - loc_ = value; - if (Window is null || Parent is null) return; - if (Window.CanControleUpdate && Loaded) - { - // = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); - Parent!.TryDraw(); - if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); - } - } - } - - private Vector2i _size; - public Vector2i Size { get => _size; - set - { - _size = value; - //if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); - } - } - - public void Clean() - { - Tuple tup = GlobalBuffers[Window!.Context]; - if (tup.Item3 - 1 == 0) - { - //Broken, I may fix latter - - //if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); - //GL.DeleteBuffer(VBO); - //GL.DeleteVertexArray(VAO); - //GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - //GlobalBuffers.Remove(Window!.Context); - } - else - { - GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1); - } - Size = new(0, 0); - Loaded = false; - Visible = false; - } - public Vector2i ScissorLocation { get; private set; } - - public event Func? SizeChanged; - - public void Draw(int x, int y, int ww, int hh) - { - if (Visible && Loaded && this.Font is not null) - { - if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); - Shader.Use(); - GL.Enable(EnableCap.Blend); - //GL.Uniform4(2, Color); - Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f); - GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); - GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); - GL.UniformMatrix4(1, false, ref projectionM); - - GL.BindVertexArray(VAO); - - float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X); - Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad); - Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f)); - float char_x = 0.0f; - - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.ActiveTexture((Shader.GetUniformLocation("u_texture") switch - { - 0 => TextureUnit.Texture0, - 1 => TextureUnit.Texture1, - 2 => TextureUnit.Texture2, - 3 => TextureUnit.Texture3, - 4 => TextureUnit.Texture4, - 5 => TextureUnit.Texture5, - 6 => TextureUnit.Texture6, - 7 => TextureUnit.Texture7, - 8 => TextureUnit.Texture8, - 9 => TextureUnit.Texture9, - })); - - float hhh = 0f; - for (int i = 0; i < Text.Length; i++) - { - var col = SetCol(i); - GL.Uniform4(2, col); - char c; - if (PasswordChar is null) - c = Text[i]; - else - c = PasswordChar.Value; - bool n = (c == '\n'); - if (!Label._characters[Window!.Context][Font].ContainsKey(c) && !n) - { - Texture f = Texture.TextureForChar(Window!.Context, Font, c, Shader); - } - - int maxx = 0; - if (n) - { - hhh += Font.PixelHeight * Scale; - hhh += Font.ExtraLinePixels; - char_x = 0f; - } - else - { - if (!Label._characters[Window!.Context][Font].ContainsKey(c)) continue; - Character ch = Label._characters[Window!.Context][Font][c]; - float w = ch.Size.X * Scale; - float h = ch.Size.Y * Scale; - float xrel = char_x + ch.Bearing.X * Scale; - float yrel = (ch.Size.Y - ch.Bearing.Y) * Scale; - yrel += hhh; - char_x += (ch.Advance >> 6) * Scale; - Matrix4 scaleM = Matrix4.CreateScale(new Vector3(w, h, 1.0f)); - Matrix4 transRelM = Matrix4.CreateTranslation(new Vector3(xrel, yrel, 0.0f)); - - Matrix4 modelM = scaleM * transRelM * rotateM * transOriginM; - GL.UniformMatrix4(0, false, ref modelM); - - ch.Texture.Use(); - - GL.DrawArrays(PrimitiveType.Triangles, 0, 6); - } - } - } - } - - public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs) - { - - } - - public virtual void SendClipEvent(string ClipString) - { - - } - public void ForceDistanceUpdate() - { - } - - public void ForceDistanceUpdate(IParent parent) - { - } - public Color4 SetCol(int index) - { - double onefith = Math.Round((double)Text.Length / 5); - double twofith = Math.Round(onefith * 2); - double threefith = Math.Round(onefith * 3); - double fourfith = Math.Round(onefith * 4); - if (onefith < 1) - { - return Text.Length switch - { - 1 => new Color4(255,0,0,255), - 2 => index switch - { - 0 => new Color4(255, 0, 0, 255), - 1 => new Color4(255, 255, 0, 255) - }, - 3 => index switch - { - 0 => new Color4(255, 0, 0, 255), - 1 => new Color4(255, 255, 0, 255), - 2 => new Color4(0, 255, 0, 255) - }, - 4 => index switch - { - 0 => new Color4(255, 0, 0, 255), - 1 => new Color4(255, 255, 0, 255), - 2 => new Color4(0, 255, 0, 255), - 3 => new Color4(0, 255, 255, 255) - }, - 5 => index switch - { - 0 => new Color4(255, 0, 0, 255), - 1 => new Color4(255, 255, 0, 255), - 2 => new Color4(0, 255, 0, 255), - 3 => new Color4(0, 255, 255, 255), - 4 => new Color4(0, 0, 255, 255) - } - }; - } - else - { - double n = index + 1; - if (n <= onefith) - { - n = index / onefith; - if (n > 1) n = 1; - return new Color4(255, (byte)(n * 255),0,255); - } - else if (n <= twofith) - { - n = (index - onefith) / onefith; - if (n > 1) n = 1; - return new Color4((byte)(255 - (n * 255)), 255,0,255); - } - else if (n <= threefith) - { - n = (index - twofith) / onefith; - if (n > 1) n = 1; - return new Color4(0, 255,(byte)(n * 255),255); - } - else if (n <= fourfith) - { - n = (index - threefith) / onefith; - if (n > 1) n = 1; - return new Color4(0, (byte)(255 - (n * 255)),255,255); - } - else - { - n = (index - fourfith) / onefith; - if (n > 1) - { - n -= 1; - return new Color4(255, 0,(byte)(255 - (n * 255)),255); - } - else return new Color4((byte)(n * 255), 0,255,255); - } - } - } - public IWindow? Window { get; private set; } - private static Dictionary> GlobalBuffers = new(); - public void LoadToParent(IParent window, IWindow win) - { - if (Loaded) return; - if (!Label._characters.ContainsKey(win!.Context)) Label._characters.Add(win!.Context, new()); - if (!Label._characters[win!.Context].ContainsKey(Font)) Label._characters[win!.Context].Add(Font, new Dictionary()); - if (Shader is null) Shader = Label.DefaultTextShader[win.Context]; - Parent = window; - Window = win; - Window.MouseDown += WindowOnMouseDown; - if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); - if (!GlobalBuffers.ContainsKey(win.Context)) - { - float[] vquad = - { - 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f - }; - int _VBO = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO); - GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); - int _VAO = GL.GenVertexArray(); - GL.BindVertexArray(_VAO); - GL.EnableVertexAttribArray(0); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); - GL.EnableVertexAttribArray(1); - GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); - GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0)); - } - - Tuple tup = GlobalBuffers[win.Context]; - VBO = tup.Item1; - VAO = tup.Item2; - GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1); - - - -/* - VBO = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); - GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); - - VAO = GL.GenVertexArray(); - GL.BindVertexArray(VAO); - GL.EnableVertexAttribArray(0); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); - GL.EnableVertexAttribArray(1); - GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); -*/ - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - GL.BindVertexArray(0); - - Loaded = true; - Text = Text; - 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); - } - - private void WindowOnMouseDown(MouseButtonEventArgs obj) - { - if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this); - if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!); - if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!); - } - - public MouseCursor HoverMouse { get; set; } = MouseCursor.Default; - - private bool mi = false; - public bool MouseInside - { - get => mi; - set - { - if (Window is null) return; - if (Window.HoveringControl == this && value) - { - mi = value; - if (MouseEnter is not null) MouseEnter.Invoke(this); - } - - if (Window.HoveringControl != this && !value) - { - mi = value; - if (MouseLeave is not null) MouseLeave.Invoke(this); - } - } - } - public bool AllowHoverFromBehind { get; set; } - public bool IgnoreHover { get; set; } - 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 6fd5305..1b6e083 100755 --- a/GraphicsManager/Objects/Rectangle.cs +++ b/GraphicsManager/Objects/Rectangle.cs @@ -5,6 +5,7 @@ using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; +using OpenTK.Platform.Windows; using OpenTK.Windowing.Common; using OpenTK.Windowing.Common.Input; using OpenTK.Windowing.Desktop; @@ -50,7 +51,6 @@ public class Rectangle : ITextureObject public List Textures { get; set; } = new(); public BetterContextMenu? ContextMenu { get; set; } = null; - public event Func? FilesDroped; public Rectangle(Texture? texture) { @@ -92,7 +92,6 @@ public class Rectangle : ITextureObject } } - public Action? OnDrawAction; public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs) { @@ -102,23 +101,21 @@ public class Rectangle : ITextureObject { } - //public Action? OnDrawExitAction; - public virtual void Draw(int x, int y, int w, int h) + public virtual void Draw(int x, int y, int sx, int sy, int sw, int sh) { if (Visible && Loaded && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y) { - if (OnDrawAction is not null) OnDrawAction.Invoke(); if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); foreach (Texture tex in Textures) { tex.Use(); } Shader.Use(); - Shader.SetMatrix4("windowMatrix", Window.WindowSizeMatrix); + Shader.SetMatrix4(Shader.GetUniformLocation("windowMatrix"), Window.WindowSizeMatrix); if (!Textures.Any() || Shader.Handle == DefaultAlphaShader[Window!.Context].Handle) { - GL.Uniform4(0, BackgroundColor); + GL.Uniform4(Shader.GetUniformLocation("objColor"), BackgroundColor); } GL.BindVertexArray(ArrayObject); GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedShort, 0); @@ -126,6 +123,12 @@ public class Rectangle : ITextureObject } public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default; + public List SubHitBoxes { get; } = new(); + public event Func? FilesDroped; + public void SendFilesEvent(string[] Files) + { + if (FilesDroped is not null) _ = FilesDroped.Invoke(this, Files); + } public void ForceDistanceUpdate() { @@ -135,7 +138,8 @@ public class Rectangle : ITextureObject public void ForceDistanceUpdate(IParent parent) { - Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y); + if (parent is IWindow w) Distance = new(w.CS.X - Size.X - Location.X, w.CS.Y - Size.Y - Location.Y); + else Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y); } public virtual void Clean() @@ -168,8 +172,8 @@ public class Rectangle : ITextureObject Loaded = true; Window.MouseDown += Window_MouseDown; Window.FileDrop += WindowOnFileDrop; - Location = Location; - if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); + SetLocation(loc_.X, loc_.Y, loc_.Z); + if (Distance.X == 0 && Distance.Y == 0) ForceDistanceUpdate(Parent); if (WindowLoaded is not null) WindowLoaded.Invoke(this); } @@ -187,7 +191,7 @@ public class Rectangle : ITextureObject private void WindowOnFileDrop(FileDropEventArgs obj) { if (!MouseInside) return; - if (FilesDroped is not null) _ = FilesDroped.Invoke(obj.FileNames); + if (FilesDroped is not null) _ = FilesDroped.Invoke(this, obj.FileNames); } private bool mi = false; @@ -456,227 +460,465 @@ public class Rectangle : ITextureObject } set { - size_ = value; - if (Window is null || Parent is null) return; - Parent.ReportSizeUpdate(this); - //float[] temp = Points; - float[] temp = Textures.Count == 0 - ? new float[12] - : TextureDisplay switch - { - TextureDisplay.Clamped => new float[20], - TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter or TextureDisplay.TextureHorizontalCenter => new float[40], - TextureDisplay.Center => new float[80], - _ => new float[20] - }; - saf = new Vector2(Parent.IntToWindow(value.X + loc_.X, false), Parent.IntToWindow(value.Y + loc_.Y, true)); - temp[2] = Location.Z; - temp[(!Textures.Any() ? 5 : 7)] = Location.Z; - temp[(!Textures.Any() ? 8 : 12)] = Location.Z; - temp[(!Textures.Any() ? 11 : 17)] = Location.Z; - - temp[0] = saf.X; // top r - temp[1] = laf.Y; - temp[(!Textures.Any()? 3 : 5)] = saf.X; // bot r - temp[(!Textures.Any() ? 4 : 6)] = saf.Y; - temp[(!Textures.Any() ? 6 : 10)] = laf.X;//bot l - temp[(!Textures.Any() ? 7 : 11)] = saf.Y; - temp[(!Textures.Any() ? 9 : 15)] = laf.X;//top l - temp[(!Textures.Any() ? 10 : 16)] = laf.Y; + SetSize(value.X, value.Y); + } + } - if (Textures.Count > 0) + public virtual void SetSize(int wh) + { + SetSize(wh, wh); + } + public virtual void SetSize(int w, int h) + { + size_.X = w; + size_.Y = h; + if (Window is null || Parent is null) return; + Parent.ReportSizeUpdate(this); + float[] temp = Textures.Count == 0 + ? new float[12] + : TextureDisplay switch { - Vector2i s = value; - float diff = Window.IntToWindow(s.Y) + 1; - float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; - if (TextureDisplay == TextureDisplay.TextureHorizontalCenter) - diff = Window.IntToWindow(Textures[0].RawSize!.Value.Y); - if (TextureDisplay == TextureDisplay.Center) - { - if (s.X > Textures[0].RawSize!.Value.X) - diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3; + TextureDisplay.Clamped => new float[20], + TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter or TextureDisplay.TextureHorizontalCenter => new float[40], + TextureDisplay.Center => new float[80], + _ => new float[20] + }; + saf.X = Parent.IntToWindow(w + loc_.X); + saf.Y = Parent.IntToWindow(h + loc_.Y, true); + temp[2] = Location.Z; + temp[(!Textures.Any() ? 5 : 7)] = Location.Z; + temp[(!Textures.Any() ? 8 : 12)] = Location.Z; + temp[(!Textures.Any() ? 11 : 17)] = Location.Z; + + temp[0] = saf.X; // top r + temp[1] = laf.Y; + temp[(!Textures.Any()? 3 : 5)] = saf.X; // bot r + temp[(!Textures.Any() ? 4 : 6)] = saf.Y; + temp[(!Textures.Any() ? 6 : 10)] = laf.X;//bot l + temp[(!Textures.Any() ? 7 : 11)] = saf.Y; + temp[(!Textures.Any() ? 9 : 15)] = laf.X;//top l + temp[(!Textures.Any() ? 10 : 16)] = laf.Y; + + if (Textures.Count > 0) + { + float diff = Window.IntToWindow(h) + 1; + float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; + if (TextureDisplay == TextureDisplay.TextureHorizontalCenter) + diff = Window.IntToWindow(Textures[0].RawSize!.Value.Y); + if (TextureDisplay == TextureDisplay.Center) + { + if (w> Textures[0].RawSize!.Value.X) + diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3; + else + diff = (Window.IntToWindow(w) + 1) / 3; + per = Textures[0].MaxText.X / 3; + } + + switch (TextureDisplay) + { + case TextureDisplay.Clamped: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + break; + case TextureDisplay.HorizontalCenter: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X - diff; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = Textures[0].MaxText.X - per; + temp[24] = 1; + + temp[25] = saf.X - diff; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = Textures[0].MaxText.X - per; + temp[29] = 0; + + temp[30] = laf.X + diff; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = per; + temp[34] = 0; + + temp[35] = laf.X + diff; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = per; + temp[39] = 1; + break; + case TextureDisplay.Center: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + + int dy, dx; + if (h > Textures[0].RawSize!.Value.Y) + dy = Textures[0].RawSize!.Value.Y; else - diff = (Window.IntToWindow(s.X) + 1) / 3; + dy = h; + if (w > Textures[0].RawSize!.Value.X) + dx = Textures[0].RawSize!.Value.X; + else + dx = w; + + if (dy > dx) dy = dx; + else dx = dy; + + float diffy = (dy + 1) / (float)3; + diff = (dx + 1) / (float)3; + per = Textures[0].MaxText.X / 3; - } - - switch (TextureDisplay) - { - case TextureDisplay.Clamped: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - break; - case TextureDisplay.HorizontalCenter: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - temp[20] = saf.X - diff; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = Textures[0].MaxText.X - per; - temp[24] = 1; - - temp[25] = saf.X - diff; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = Textures[0].MaxText.X - per; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - break; - case TextureDisplay.Center: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - - int dy, dx; - if (s.Y > Textures[0].RawSize!.Value.Y) - dy = Textures[0].RawSize!.Value.Y; - else - dy = s.Y; - if (s.X > Textures[0].RawSize!.Value.X) - dx = Textures[0].RawSize!.Value.X; - else - dx = s.X; - - if (dy > dx) dy = dx; - else dx = dy; - - float diffy = (dy + 1) / (float)3; - diff = (dx + 1) / (float)3; - - per = Textures[0].MaxText.X / 3; - - SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per)); - SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per); - SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]); - SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]); - SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]); - SetPoint(temp, 45, temp[10], temp[21], temp[2], temp[13], temp[24]); - SetPoint(temp, 50, temp[35], temp[1], temp[2], temp[38], temp[4]); - SetPoint(temp, 55, temp[30], temp[1], temp[2], temp[33], temp[4]); - SetPoint(temp, 60, temp[30], temp[21], temp[2], temp[33], temp[24]); - SetPoint(temp, 65, temp[30], temp[26], temp[2], temp[33], temp[29]); - SetPoint(temp, 70, temp[35], temp[26], temp[2], temp[38], temp[29]); - SetPoint(temp, 75, temp[35], temp[21], temp[2], temp[38], temp[24]); - break; - case TextureDisplay.ProgressHorizontalCenter: - if (s.X > s.Y) + + SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per)); + SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per); + SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]); + SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]); + SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]); + SetPoint(temp, 45, temp[10], temp[21], temp[2], temp[13], temp[24]); + SetPoint(temp, 50, temp[35], temp[1], temp[2], temp[38], temp[4]); + SetPoint(temp, 55, temp[30], temp[1], temp[2], temp[33], temp[4]); + SetPoint(temp, 60, temp[30], temp[21], temp[2], temp[33], temp[24]); + SetPoint(temp, 65, temp[30], temp[26], temp[2], temp[33], temp[29]); + SetPoint(temp, 70, temp[35], temp[26], temp[2], temp[38], temp[29]); + SetPoint(temp, 75, temp[35], temp[21], temp[2], temp[38], temp[24]); + break; + case TextureDisplay.ProgressHorizontalCenter: + if (w > h) + { + if (w > h+ h) { - if (s.X > s.Y + s.Y) - { - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - temp[20] = saf.X - diff; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = Textures[0].MaxText.X - per; - temp[24] = 1; - - temp[25] = saf.X - diff; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = 1 - per; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - } - else - { - temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = temp[3]; - temp[19] = Textures[0].MaxText.Y; - //start last 33% of texture - temp[20] = saf.X; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = temp[3]; - temp[24] = 1; - - temp[25] = saf.X; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = temp[3]; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - } + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X - diff; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = Textures[0].MaxText.X - per; + temp[24] = 1; + + temp[25] = saf.X - diff; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = 1 - per; + temp[29] = 0; + + temp[30] = laf.X + diff; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = per; + temp[34] = 0; + + temp[35] = laf.X + diff; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = per; + temp[39] = 1; } else { - //first 33% of texture - temp[3] = ((s.X/(float)s.Y)*per); + temp[3] = (0.666666f + (((w - h) / (float)h)* per)) * Textures[0].MaxText.X; temp[4] = Textures[0].MaxText.Y; temp[8] = temp[3]; temp[19] = Textures[0].MaxText.Y; + //start last 33% of texture temp[20] = saf.X; // top r temp[21] = laf.Y; temp[22] = 0; temp[23] = temp[3]; - temp[24] = Textures[0].MaxText.Y; - + temp[24] = 1; + temp[25] = saf.X; // bot r temp[26] = saf.Y; temp[27] = 0; temp[28] = temp[3]; temp[29] = 0; - - temp[30] = saf.X; // bot l + + temp[30] = laf.X + diff; // bot l temp[31] = saf.Y; temp[32] = 0; - temp[33] = temp[3]; + temp[33] = per; temp[34] = 0; - - temp[35] = saf.X; // top l + + temp[35] = laf.X + diff; // top l temp[36] = laf.Y; temp[37] = 0; - temp[38] = temp[3]; - temp[39] = Textures[0].MaxText.Y; + temp[38] = per; + temp[39] = 1; } - break; - } + } + else + { + //first 33% of texture + temp[3] = ((w/(float)h)*per); + temp[4] = Textures[0].MaxText.Y; + temp[8] = temp[3]; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = temp[3]; + temp[24] = Textures[0].MaxText.Y; + + temp[25] = saf.X; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = temp[3]; + temp[29] = 0; + + temp[30] = saf.X; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = temp[3]; + temp[34] = 0; + + temp[35] = saf.X; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = temp[3]; + temp[39] = Textures[0].MaxText.Y; + } + break; } - - Points = temp; - if (SizeChanged is not null) SizeChanged.Invoke(this); } + + Points = temp; + temp = Array.Empty(); + if (SizeChanged is not null) SizeChanged.Invoke(this); + } + + public virtual void SetLocation(int x, int y) + { + SetLocation(x, y, Location.Z); + } + public virtual void SetLocation(int xy) + { + SetLocation(xy, xy, 0); + } + public virtual void SetLocation(int x, int y, int z) + { + loc_.X = x; + loc_.Y = y; + loc_.Z = z; + if (Window is null || Parent is null) return; + float[] temp = Textures.Count == 0 + ? new float[12] + : TextureDisplay switch + { + TextureDisplay.Clamped => new float[20], + TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter => new float[40], + TextureDisplay.Center => new float[80], + _ => new float[20] + }; + laf.X = Parent.IntToWindow(x); + laf.Y = Parent.IntToWindow(y, true); + temp[2] = z; + temp[(!Textures.Any() ? 5 : 7)] = z; + temp[(!Textures.Any() ? 8 : 12)] = z; + temp[(!Textures.Any() ? 11 : 17)] = z; + + temp[(!Textures.Any() ? 6 : 10)] = laf.X; + temp[(!Textures.Any() ? 9 : 15)] = laf.X; + temp[1] = laf.Y; + temp[(!Textures.Any() ? 10 : 16)] = laf.Y; + saf.X = Parent.IntToWindow(Size.X + x); + saf.Y = Parent.IntToWindow(Size.Y + y, true); + temp[0] = saf.X; + temp[(!Textures.Any() ? 3 : 5)] = saf.X; + temp[(!Textures.Any() ? 4 : 6)] = saf.Y; + temp[(!Textures.Any() ? 7 : 11)] = saf.Y; + if (Textures.Count > 0) + { + Vector2i s = Size; + float diff = Window.IntToWindow(s.Y) + 1; + float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; + if (TextureDisplay == TextureDisplay.Center) + { + if (s.X > Textures[0].RawSize!.Value.X) + diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3; + else + diff = (Window.IntToWindow(s.X) + 1) / 3; + per = Textures[0].MaxText.X / 3; + } + switch (TextureDisplay) + { + case TextureDisplay.Clamped: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + break; + case TextureDisplay.HorizontalCenter: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X - diff; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = Textures[0].MaxText.X - per; + temp[24] = 1; + + temp[25] = saf.X - diff; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = Textures[0].MaxText.X - per; + temp[29] = 0; + + temp[30] = laf.X + diff; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = per; + temp[34] = 0; + + temp[35] = laf.X + diff; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = per; + temp[39] = 1; + break; + case TextureDisplay.Center: + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + + int dy, dx; + if (s.Y > Textures[0].RawSize!.Value.Y) + dy = Textures[0].RawSize!.Value.Y; + else + dy = s.Y; + if (s.X > Textures[0].RawSize!.Value.X) + dx = Textures[0].RawSize!.Value.X; + else + dx = s.X; + + if (dy > dx) dy = dx; + else dx = dy; + + float diffy = (dy + 1) / (float)3; + diff = (dx + 1) / (float)3; + + SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per)); + SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per); + SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]); + SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]); + SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]); + SetPoint(temp, 45, temp[10], temp[21], temp[2], temp[13], temp[24]); + SetPoint(temp, 50, temp[35], temp[1], temp[2], temp[38], temp[4]); + SetPoint(temp, 55, temp[30], temp[1], temp[2], temp[33], temp[4]); + SetPoint(temp, 60, temp[30], temp[21], temp[2], temp[33], temp[24]); + SetPoint(temp, 65, temp[30], temp[26], temp[2], temp[33], temp[29]); + SetPoint(temp, 70, temp[35], temp[26], temp[2], temp[38], temp[29]); + SetPoint(temp, 75, temp[35], temp[21], temp[2], temp[38], temp[24]); + break; + case TextureDisplay.ProgressHorizontalCenter: + if (s.X > s.Y) + { + if (s.X > s.Y + s.Y) + { + temp[3] = Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = Textures[0].MaxText.X; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X - diff; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = Textures[0].MaxText.X - per; + temp[24] = 1; + + temp[25] = saf.X - diff; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = 1 - per; + temp[29] = 0; + + temp[30] = laf.X + diff; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = per; + temp[34] = 0; + + temp[35] = laf.X + diff; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = per; + temp[39] = 1; + } + else + { + temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X; + temp[4] = Textures[0].MaxText.Y; + temp[8] = temp[3]; + temp[19] = Textures[0].MaxText.Y; + //start last 33% of texture + temp[20] = saf.X; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = temp[3]; + temp[24] = 1; + + temp[25] = saf.X; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = temp[3]; + temp[29] = 0; + + temp[30] = laf.X + diff; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = per; + temp[34] = 0; + + temp[35] = laf.X + diff; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = per; + temp[39] = 1; + } + } + else + { + //first 33% of texture + temp[3] = ((s.X/(float)s.Y)*per); + temp[4] = Textures[0].MaxText.Y; + temp[8] = temp[3]; + temp[19] = Textures[0].MaxText.Y; + temp[20] = saf.X; // top r + temp[21] = laf.Y; + temp[22] = 0; + temp[23] = temp[3]; + temp[24] = Textures[0].MaxText.Y; + + temp[25] = saf.X; // bot r + temp[26] = saf.Y; + temp[27] = 0; + temp[28] = temp[3]; + temp[29] = 0; + + temp[30] = saf.X; // bot l + temp[31] = saf.Y; + temp[32] = 0; + temp[33] = temp[3]; + temp[34] = 0; + + temp[35] = saf.X; // top l + temp[36] = laf.Y; + temp[37] = 0; + temp[38] = temp[3]; + temp[39] = Textures[0].MaxText.Y; + } + break; + } + } + Points = temp; + temp = Array.Empty(); } public virtual Vector3i Location @@ -687,217 +929,7 @@ public class Rectangle : ITextureObject } set { - loc_ = value; - if (Window is null || Parent is null) return; - float[] temp = Textures.Count == 0 - ? new float[12] - : TextureDisplay switch - { - TextureDisplay.Clamped => new float[20], - TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter => new float[40], - TextureDisplay.Center => new float[80], - _ => new float[20] - }; - laf = new Vector2(Parent.IntToWindow(value.X, false), Parent.IntToWindow(value.Y, true)); - temp[2] = value.Z; - temp[(!Textures.Any() ? 5 : 7)] = value.Z; - temp[(!Textures.Any() ? 8 : 12)] = value.Z; - temp[(!Textures.Any() ? 11 : 17)] = value.Z; - - temp[(!Textures.Any() ? 6 : 10)] = laf.X; - temp[(!Textures.Any() ? 9 : 15)] = laf.X; - temp[1] = laf.Y; - temp[(!Textures.Any() ? 10 : 16)] = laf.Y; - saf = new Vector2(Parent.IntToWindow(Size.X + value.X, false), Parent.IntToWindow(Size.Y + value.Y, true)); - temp[0] = saf.X; - temp[(!Textures.Any() ? 3 : 5)] = saf.X; - temp[(!Textures.Any() ? 4 : 6)] = saf.Y; - temp[(!Textures.Any() ? 7 : 11)] = saf.Y; - if (Textures.Count > 0) - { - Vector2i s = Size; - float diff = Window.IntToWindow(s.Y) + 1; - float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; - if (TextureDisplay == TextureDisplay.Center) - { - if (s.X > Textures[0].RawSize!.Value.X) - diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3; - else - diff = (Window.IntToWindow(s.X) + 1) / 3; - per = Textures[0].MaxText.X / 3; - } - switch (TextureDisplay) - { - case TextureDisplay.Clamped: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - break; - case TextureDisplay.HorizontalCenter: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - temp[20] = saf.X - diff; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = Textures[0].MaxText.X - per; - temp[24] = 1; - - temp[25] = saf.X - diff; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = Textures[0].MaxText.X - per; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - break; - case TextureDisplay.Center: - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - - int dy, dx; - if (s.Y > Textures[0].RawSize!.Value.Y) - dy = Textures[0].RawSize!.Value.Y; - else - dy = s.Y; - if (s.X > Textures[0].RawSize!.Value.X) - dx = Textures[0].RawSize!.Value.X; - else - dx = s.X; - - if (dy > dx) dy = dx; - else dx = dy; - - float diffy = (dy + 1) / (float)3; - diff = (dx + 1) / (float)3; - - SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per)); - SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per); - SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]); - SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]); - SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]); - SetPoint(temp, 45, temp[10], temp[21], temp[2], temp[13], temp[24]); - SetPoint(temp, 50, temp[35], temp[1], temp[2], temp[38], temp[4]); - SetPoint(temp, 55, temp[30], temp[1], temp[2], temp[33], temp[4]); - SetPoint(temp, 60, temp[30], temp[21], temp[2], temp[33], temp[24]); - SetPoint(temp, 65, temp[30], temp[26], temp[2], temp[33], temp[29]); - SetPoint(temp, 70, temp[35], temp[26], temp[2], temp[38], temp[29]); - SetPoint(temp, 75, temp[35], temp[21], temp[2], temp[38], temp[24]); - break; - case TextureDisplay.ProgressHorizontalCenter: - if (s.X > s.Y) - { - if (s.X > s.Y + s.Y) - { - temp[3] = Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = Textures[0].MaxText.X; - temp[19] = Textures[0].MaxText.Y; - temp[20] = saf.X - diff; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = Textures[0].MaxText.X - per; - temp[24] = 1; - - temp[25] = saf.X - diff; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = 1 - per; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - } - else - { - temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X; - temp[4] = Textures[0].MaxText.Y; - temp[8] = temp[3]; - temp[19] = Textures[0].MaxText.Y; - //start last 33% of texture - temp[20] = saf.X; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = temp[3]; - temp[24] = 1; - - temp[25] = saf.X; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = temp[3]; - temp[29] = 0; - - temp[30] = laf.X + diff; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = per; - temp[34] = 0; - - temp[35] = laf.X + diff; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = per; - temp[39] = 1; - } - } - else - { - //first 33% of texture - temp[3] = ((s.X/(float)s.Y)*per); - temp[4] = Textures[0].MaxText.Y; - temp[8] = temp[3]; - temp[19] = Textures[0].MaxText.Y; - temp[20] = saf.X; // top r - temp[21] = laf.Y; - temp[22] = 0; - temp[23] = temp[3]; - temp[24] = Textures[0].MaxText.Y; - - temp[25] = saf.X; // bot r - temp[26] = saf.Y; - temp[27] = 0; - temp[28] = temp[3]; - temp[29] = 0; - - temp[30] = saf.X; // bot l - temp[31] = saf.Y; - temp[32] = 0; - temp[33] = temp[3]; - temp[34] = 0; - - temp[35] = saf.X; // top l - temp[36] = laf.Y; - temp[37] = 0; - temp[38] = temp[3]; - temp[39] = Textures[0].MaxText.Y; - } - break; - } - } - Points = temp; + SetLocation(value.X, value.Y, value.Z); } } diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs index 5c5be76..71e39c0 100644 --- a/GraphicsManager/Objects/TabControl.cs +++ b/GraphicsManager/Objects/TabControl.cs @@ -141,10 +141,9 @@ public class TabControl : ParentBase, IParent } } - public override void ParentResize(ResizeEventArgs e) + public override void ParentResize() { BlockDraw = 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; @@ -161,7 +160,7 @@ public class TabControl : ParentBase, IParent Controls[PageIndex].Location = new(lx, ly, Controls[PageIndex].Location.Z); if (Controls[PageIndex] is IParent parent) { - parent.ParentResize(e); + parent.ParentResize(); } for (int i = 0; i < Buttonts.Length; i++) { @@ -180,7 +179,7 @@ public class TabControl : ParentBase, IParent Buttonts[i].Location = new(lx, ly, Buttonts[i].Location.Z); if (Buttonts[i] is IParent parent2) { - parent2.ParentResize(e); + parent2.ParentResize(); } } Parent!.TryDraw(); @@ -201,16 +200,16 @@ public class TabControl : ParentBase, IParent BlockDraw = false; } - public override void Draw(int x, int y, int w, int h) + public override void Draw(int x, int y, int sx, int sy, int sw, int sh) { if (Loaded && Visible) { - base.Draw(x,y,w,h); + base.Draw(x,y,sx,sy,sw,sh); if (!(Controls.Length >= (PageIndex))) return; if (!Controls[PageIndex].Loaded) return; - Controls[PageIndex].Draw(x,y,w,h); + Controls[PageIndex].Draw(x,y,sx,sy,sw,sh); for (int i = 0; i < Buttonts.Length; i++) - Buttonts[i].Draw(x,y,w,h); + Buttonts[i].Draw(x,y,sx,sy,sw,sh); } } diff --git a/GraphicsManager/Resources/Shaders/Label.vert b/GraphicsManager/Resources/Shaders/Label.vert index af30ccc..f43eb92 100755 --- a/GraphicsManager/Resources/Shaders/Label.vert +++ b/GraphicsManager/Resources/Shaders/Label.vert @@ -1,7 +1,7 @@ #version 330 -in vec2 in_pos; -in vec2 in_uv; +layout (location = 0) in vec2 in_pos; +layout (location = 1) in vec2 in_uv; out vec2 vUV; diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs index c20d3a4..f7b55fb 100755 --- a/GraphicsManager/Window.cs +++ b/GraphicsManager/Window.cs @@ -77,6 +77,14 @@ public class Window : NativeWindow , IWindow WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, Size.X, Size.Y, 0, 1, -1); KeyDown += OnKeyDownn; TextInput += OnTextInputEvent; + FileDrop += OnFileDrop; + GL.Enable(EnableCap.Blend); + GL.Enable(EnableCap.ScissorTest); + } + + private void OnFileDrop(FileDropEventArgs obj) + { + } private void OnTextInputEvent(TextInputEventArgs obj) @@ -136,28 +144,20 @@ public class Window : NativeWindow , IWindow } } - 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 Window() : this(new NativeWindowSettings()) { } public Vector3i Position { get; } = new(0); public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255); public ControlList Controls { get; } = new(); - public Vector2i CS { get; private set; } = new(0, 0); + public Vector2i CS { get; set; } = new(0, 0); public float IntToWindow(float p, bool Y = false) { return p; } - public void ForceUpdate(ResizeEventArgs e) + public virtual void ForceUpdate() { BlockDraw = true; for (int i = 0; i < Controls.Length; i++) @@ -169,15 +169,15 @@ public class Window : NativeWindow , IWindow 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); + int lx = (left ? Controls[i].Location.X : CS.X - Controls[i].Distance.X - Controls[i].Size.X); + int ly = (top ? Controls[i].Location.Y : CS.Y - Controls[i].Distance.Y - Controls[i].Size.Y); + int sy = (bottom ? CS.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y); + int sx = (right ? CS.X - Controls[i].Distance.X - lx : Controls[i].Size.X); + Controls[i].SetSize(sx, sy); + Controls[i].SetLocation(lx, ly); if (Controls[i] is IParent parent) { - parent.ParentResize(e); + parent.ParentResize(); } } DrawFrame(); @@ -186,15 +186,9 @@ public class Window : NativeWindow , IWindow public Matrix4 WindowSizeMatrix { get; set; } - public void ParentResize(ResizeEventArgs e) + public virtual void ParentResize() { - base.OnResize(e); - - if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return; - WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, e.Width, e.Height, 0, 1, -1); - GL.Viewport(0, 0, e.Width, e.Height); - CS = e.Size; - ForceUpdate(e); + ForceUpdate(); } private int frame = 0; @@ -204,9 +198,22 @@ public class Window : NativeWindow , IWindow } + public void SetWindowSize(Vector2i s) + { + WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, s.X, s.Y, 0, 1, -1); + GL.Viewport(0, 0, s.X, s.Y); + CS = s; + ClientSize = CS; + ParentResize(); + } + protected override void OnResize(ResizeEventArgs e) { - ParentResize(e); + base.OnResize(e); + WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, e.Width, e.Height, 0, 1, -1); + GL.Viewport(0, 0, e.Width, e.Height); + CS = e.Size; + ParentResize(); } protected override void OnClosing(CancelEventArgs e) @@ -233,7 +240,7 @@ public class Window : NativeWindow , IWindow { ProcessEvents(10); } - public void StartRender() + public virtual void StartRender() { Context.MakeCurrent(); initthread = Thread.CurrentThread.ManagedThreadId; @@ -260,10 +267,12 @@ public class Window : NativeWindow , IWindow } public IRenderObject? HoveringControl { get; set; } + public SubHitBox? HoveringHitBox { get; set; } private void WhenMouseMove(MouseMoveEventArgs obj) { IRenderObject? cb = null; + SubHitBox? cbhb = null; IRenderObject? checkcontrol(IRenderObject render, int add_x = 0, int addy = 0, IRenderObject? CurrentBest = null) { void ClearHoverChain(IRenderObject ChainObject) @@ -276,7 +285,17 @@ public class Window : NativeWindow , IWindow } } - if (ChainObject.AllowHoverFromBehind) ChainObject.MouseInside = false; + if (ChainObject.AllowHoverFromBehind) + { + ChainObject.MouseInside = false; + if (ChainObject.SubHitBoxes.Count > 0) + { + foreach (SubHitBox shb in ChainObject.SubHitBoxes) + { + shb.MouseInside = false; + } + } + } } if (!render.Visible || @@ -297,13 +316,35 @@ public class Window : NativeWindow , IWindow CurrentBest = checkcontrol(p.Controls._internal[i], add_x + render.Location.X, addy + render.Location.Y, CurrentBest); } } + + if (CurrentBest is null) { + cbhb = null; CurrentBest = render; } else { - if (CurrentBest.Location.Z < render.Location.Z) CurrentBest = render; + if (CurrentBest.Location.Z < render.Location.Z) + { + cbhb = null; + CurrentBest = render; + } + } + + if (render == CurrentBest && CurrentBest.SubHitBoxes.Count > 0) + { + foreach (SubHitBox hb in CurrentBest.SubHitBoxes) + { + if (render.Location.X + hb.Location.X + add_x > obj.X || + render.Location.Y + hb.Location.Y + addy > obj.Y || + render.Location.X + hb.Location.X + hb.Size.X + add_x < obj.X || + render.Location.Y + hb.Location.Y + hb.Size.Y + addy < obj.Y) + { + continue; + } + cbhb = hb; + } } return CurrentBest; @@ -325,6 +366,19 @@ public class Window : NativeWindow , IWindow else Cursor = HoverMouse; if (old is not null) old.MouseInside = false; } + + if (cbhb != HoveringHitBox) + { + SubHitBox? old = HoveringHitBox; + HoveringHitBox = cbhb; + if (cbhb is not null) + { + cbhb.MouseInside = true; + Cursor = cbhb.HoverMouse; + } + else Cursor = HoverMouse; + if (old is not null) old.MouseInside = false; + } } public void StartRenderAsync() @@ -357,16 +411,13 @@ public class Window : NativeWindow , IWindow invokes.Enqueue(A); } - public void DrawFrame() + public virtual void DrawFrame() { Context.MakeCurrent(); frame++; if (LogFrames) Console.WriteLine($"Drawing Frame: {frame}"); - GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); - GL.Enable(EnableCap.ScissorTest); - GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, BackgroundColor.A); IEnumerable needload = Controls.Where(a => a.Loaded == false); @@ -385,9 +436,8 @@ public class Window : NativeWindow , IWindow { if (!Controls[i].Loaded) continue; GL.Scissor(0, 0, CS.X, CS.Y); - Controls[i].Draw(0,0,CS.X, CS.Y); + Controls[i].Draw(0,0,0,0,CS.X, CS.Y); } Context.SwapBuffers(); - } } \ No newline at end of file