From 6e7467b56e2bb183a5d0236457bd70aa8fa0f6af Mon Sep 17 00:00:00 2001 From: JacobTech Date: Tue, 24 Jan 2023 09:27:15 -0500 Subject: [PATCH] Got my code back --- GraphicsManager/ContextMenu.cs | 16 +- GraphicsManager/Globals/EXT.cs | 23 +++ GraphicsManager/GraphicsManager.csproj | 2 +- GraphicsManager/Objects/Core/ControlList.cs | 17 +- GraphicsManager/Objects/Core/Font.cs | 61 ++++++- GraphicsManager/Objects/Core/Texture.cs | 84 +++++++-- .../Objects/Core/TextureManager.cs | 52 ++++++ GraphicsManager/Objects/FlowLayout.cs | 170 ++++++++++++++++-- GraphicsManager/Objects/Label.cs | 50 +++++- GraphicsManager/Objects/RoundedRectangle.cs | 2 +- GraphicsManager/Objects/Textbox.cs | 73 +++++++- GraphicsManager/Objects/UserControl.cs | 5 + GraphicsManager/Window.cs | 29 ++- 13 files changed, 519 insertions(+), 65 deletions(-) create mode 100644 GraphicsManager/Globals/EXT.cs create mode 100644 GraphicsManager/Objects/Core/TextureManager.cs diff --git a/GraphicsManager/ContextMenu.cs b/GraphicsManager/ContextMenu.cs index 7649d1e..bf56208 100644 --- a/GraphicsManager/ContextMenu.cs +++ b/GraphicsManager/ContextMenu.cs @@ -50,9 +50,18 @@ public class ContextMenu : Window } - public void HideContext(Window Parent) + protected override void OnFocusedChanged(FocusedChangedEventArgs e) { - if (Parent.ActiveMenu != this) return; + base.OnFocusedChanged(e); + if (!e.IsFocused && w is not null) HideContext(w,true); + } + + private Window? w = null; + + public void HideContext(Window Parent, bool force = false) + { + if (Parent.ActiveMenu == this && !false) return; + w = null; Parent.ActiveMenu = null; Context.MakeCurrent(); IsVisible = false; @@ -60,9 +69,11 @@ public class ContextMenu : Window public void ShowContext(Window Parent) { + w = Parent; if (Parent.ActiveMenu == this) { Location = new((int)Parent.Location.X + (int)Parent.MousePosition.X, (int)Parent.Location.Y + (int)Parent.MousePosition.Y); + IsVisible = true; Focus(); return; } @@ -74,6 +85,7 @@ public class ContextMenu : Window Context.MakeCurrent(); Location = new((int)Parent.Location.X + (int)Parent.MousePosition.X, (int)Parent.Location.Y + (int)Parent.MousePosition.Y); IsVisible = true; + Focus(); GL.Viewport(0, 0, this.Size.X, this.Size.Y); DrawFrame(); } diff --git a/GraphicsManager/Globals/EXT.cs b/GraphicsManager/Globals/EXT.cs new file mode 100644 index 0000000..d3ecebc --- /dev/null +++ b/GraphicsManager/Globals/EXT.cs @@ -0,0 +1,23 @@ +namespace GraphicsManager.Globals; + +public static class EXT +{ + public static T[] RemoveAt(this T[] source, int index) + { + if (source.Length == 1) return Array.Empty(); + T[] dest = new T[source.Length - 1]; + if( index > 0 ) + Array.Copy(source, 0, dest, 0, index); + + if( index < source.Length - 1 ) + Array.Copy(source, index + 1, dest, index, source.Length - index - 1); + + return dest; + } + + public static T[] Add(this T[] source, T Object) + { + T[] dest = new T[source.Length + 1]; + return source.Concat(new T[1] { Object }).ToArray(); + } +} \ No newline at end of file diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj index d54d7d2..881576d 100644 --- a/GraphicsManager/GraphicsManager.csproj +++ b/GraphicsManager/GraphicsManager.csproj @@ -10,7 +10,7 @@ False https://git.jacobtech.com/JacobTech.com/GraphicsManager git - 1.0.1-beta01 + 1.0.4-alpha09 diff --git a/GraphicsManager/Objects/Core/ControlList.cs b/GraphicsManager/Objects/Core/ControlList.cs index 7bbc774..ac87a53 100644 --- a/GraphicsManager/Objects/Core/ControlList.cs +++ b/GraphicsManager/Objects/Core/ControlList.cs @@ -5,11 +5,16 @@ namespace GraphicsManager.Objects.Core; public class ControlList { private List _internal = new(); + private bool Clearing = false; public IRenderObject this[int Index] => _internal[Index]; public IRenderObject this[uint Index] => _internal[(int)Index]; public IEnumerable Where(Func func) => _internal.Where(func); + + public bool Contains(IRenderObject Control) => _internal.Contains(Control); + + public int IndexOf(IRenderObject Control) => _internal.IndexOf(Control); public int Length => _internal.Count; @@ -20,7 +25,9 @@ public class ControlList { _internal.Remove(item); item.Clean(); - if (ControlRemoved is not null) _ = ControlRemoved.Invoke(); + item = null!; + GC.Collect(); + if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke(); } public void Add(IRenderObject item) @@ -31,11 +38,15 @@ public class ControlList public void Clear() { - foreach (IRenderObject con in _internal) + Clearing = true; + for (int i = 0; i< _internal.Count; i++) { - con.Clean(); + _internal[i].Clean(); + _internal[i] = null!; } _internal.Clear(); + GC.Collect(); + Clearing = false; if (ControlRemoved is not null) _ = ControlRemoved.Invoke(); } } \ No newline at end of file diff --git a/GraphicsManager/Objects/Core/Font.cs b/GraphicsManager/Objects/Core/Font.cs index 5e9ea14..62beb56 100755 --- a/GraphicsManager/Objects/Core/Font.cs +++ b/GraphicsManager/Objects/Core/Font.cs @@ -15,10 +15,11 @@ public class Font internal static List? _SystemPre = null; private static List AllFonts = new(); private static bool Backup = false; - + private static int addsystem = 0; internal void AddSystemFontFace(string path) { Console.WriteLine("Added font: " + path); + addsystem++; if (!AllFileFonts.ContainsKey(path)) AllFileFonts.Add(path, new(lib, path, 0)); if (!_Faces.Contains(AllFileFonts[path])) { @@ -27,6 +28,15 @@ public class Font ft._Faces.Add(AllFileFonts[path]); } } + + if (addsystem == _SystemPre!.Count) + { + addsystem++; + foreach (Font ft in AllFonts) + { + ft._Faces.Add(AllMemoryFonts.Last().Value); + } + } } private Font() @@ -68,6 +78,37 @@ public class Font { } } + + if (OperatingSystem.IsWindows()) + { + try + { + string folder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts); + + string GetFonts(string dir) + { + DirectoryInfo di = new(dir); + string files = ""; + foreach (FileInfo file in di.GetFiles()) + { + if (!file.FullName.EndsWith(".otf") && !file.FullName.EndsWith(".ttf")) continue; + if (files == "") files = file.FullName; + else files += Environment.NewLine + file.FullName; + } + foreach (DirectoryInfo direc in di.GetDirectories()) + { + files += GetFonts(direc.FullName); + } + return files; + } + + _SystemPre = GetFonts(folder).Split(Environment.NewLine).ToList(); + } + catch + { + + } + } } } public void SetEmbeddedFont(string Font, Assembly? Assembly = null) @@ -108,20 +149,22 @@ public class Font ? Tools.GetResourceBytes(Base + Font) : Tools.GetResourceBytes(Assembly!, $"{Base}{Font}")); byte[] hash = SHA256.HashData(f); - if (AllMemoryFonts.ContainsKey(hash)) AllMemoryFonts.Add(hash, new(lib, f, 0)); + if (!AllMemoryFonts.ContainsKey(hash)) AllMemoryFonts.Add(hash, new(lib, f, 0)); fontclass._Faces.Insert(0, AllMemoryFonts[hash]); return fontclass; } - private static Font? Cache = null; - public static Font MakeFontFromSystem(uint PixelHeight = 20) + //private static Font? Cache = null; + private static List Caches = new(); + public static Font MakeFontFromSystem(uint PixelHeight = 12) { - if (Cache is null) + if (!Caches.Where(s => s.PixelHeight == PixelHeight).Any()) { - Cache = new() { PixelHeight = PixelHeight }; - AllFonts.Add(Cache); + Font f = new() { PixelHeight = PixelHeight }; + Caches.Add(f); + AllFonts.Add(f); } - return Cache; + return Caches.Where(s => s.PixelHeight == PixelHeight).First(); } public static Font MakeFontFromFile(string Font) { @@ -150,7 +193,7 @@ public class Font } private bool HasTopFont = false; - public uint PixelHeight { get; set; } = 20; + public uint PixelHeight { get; set; } = 12; public string Name { get; private set; } = default!; public bool Embeded { get; private set; } public Assembly? Assembly { get; private set; } diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs index 108556d..53e212a 100755 --- a/GraphicsManager/Objects/Core/Texture.cs +++ b/GraphicsManager/Objects/Core/Texture.cs @@ -27,7 +27,7 @@ public class Texture public static readonly Dictionary TextureShader = new (); public int handel; - public Texture(byte[] File) + internal Texture(byte[] File) { Image image = Image.Load(File); image.Mutate(x => x.Flip(FlipMode.Vertical)); @@ -60,6 +60,10 @@ public class Texture internal static Character GetChar(Font l, char charter) { + try + { + + int last = 0; for (int i = 0; i < l.Fonts.Count; i++) { @@ -68,13 +72,15 @@ public class Texture try { l.Fonts[i].SetPixelSizes(0, l.PixelHeight); + l.Fonts[i].SelectCharmap(Encoding.Unicode); last = i; } catch (Exception e) { + Console.WriteLine($"no"); continue; } - l.Fonts[i].SelectCharmap(Encoding.Unicode); + ushort temp = ((ushort)charter); if (l.Fonts[i].GetCharIndex(temp) == 0) continue; l.Fonts[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); @@ -94,21 +100,25 @@ public class Texture continue; } } + List bad = new(); for (int i = 0; i < Font._SystemPre.Count; i++) { try { - Face tmp = new(Font.lib, Font._SystemPre[i], 0); + Face tmp; try { + tmp = new(Font.lib, Font._SystemPre[i], 0); tmp.SetPixelSizes(0, l.PixelHeight); + tmp.SelectCharmap(Encoding.Unicode); } catch (Exception e) { - tmp.Dispose(); + Console.WriteLine($"Removing bad font1: {Font._SystemPre[i]}"); + bad.Add(Font._SystemPre[i]); continue; } - tmp.SelectCharmap(Encoding.Unicode); + ushort temp2 = ((ushort)charter); if (tmp.GetCharIndex(temp2) == 0) { @@ -118,7 +128,13 @@ public class Texture tmp.LoadChar(temp2, LoadFlags.Render, LoadTarget.Normal); GlyphSlot glyph2 = tmp.Glyph; FTBitmap bitmap2 = glyph2.Bitmap; + if (bad.Any()) Console.WriteLine($"Purge 1: {bad.Count}"); + foreach (string str in bad) + { + Font._SystemPre.Remove(str); + } l.AddSystemFontFace(Font._SystemPre[i]); + return new() { Size = new Vector2(bitmap2.Width, bitmap2.Rows), @@ -128,8 +144,20 @@ public class Texture } catch (Exception ex) { + Console.WriteLine($"Removing bad font2: {Font._SystemPre[i]}"); + bad.Add(Font._SystemPre[i]); Console.WriteLine(ex); } + if (bad.Any()) Console.WriteLine($"Purge 2: {bad.Count}"); + foreach (string str in bad) + { + Font._SystemPre.Remove(str); + } + } + if (bad.Any()) Console.WriteLine($"Purge 3: {bad.Count}"); + foreach (string str in bad) + { + Font._SystemPre.Remove(str); } l.Fonts[last].SetPixelSizes(0, l.PixelHeight); @@ -145,13 +173,24 @@ public class Texture Bearing = new Vector2(glyph22.BitmapLeft, glyph22.BitmapTop), Advance = (int)glyph22.Advance.X.Value, }; - + } + catch (Exception e) + { + Console.WriteLine(1); + Console.WriteLine(e); + throw; + } } internal static Texture TextureForChar(IGLFWGraphicsContext con, Font l, char charter) { + try + { + + Texture? t = null; int last = 0; + for (int i = 0; i < l.Fonts.Count; i++) { try @@ -165,13 +204,12 @@ public class Texture } catch (Exception e) { + Console.WriteLine("should never happen"); continue; } - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - - GL.ActiveTexture(TextureUnit.Texture0); + l.Fonts[i].SelectCharmap(Encoding.Unicode); ushort temp = ((ushort)charter); if (l.Fonts[i].GetCharIndex(temp) == 0) continue; @@ -179,6 +217,8 @@ public class Texture GlyphSlot glyph = l.Fonts[i].Glyph; FTBitmap bitmap = glyph.Bitmap; t = new(); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + GL.ActiveTexture(TextureUnit.Texture0); t.handel = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, t.handel); GL.TexImage2D(TextureTarget.Texture2D, 0, @@ -199,6 +239,7 @@ public class Texture } catch (Exception ex) { + Console.WriteLine("How?"); Console.WriteLine(ex); continue; } @@ -210,20 +251,20 @@ public class Texture { try { - Face tmp = new(Font.lib, Font._SystemPre[i], 0); + Face tmp; try { + tmp = new(Font.lib, Font._SystemPre[i], 0); tmp.SetPixelSizes(0, l.PixelHeight); + tmp.SelectCharmap(Encoding.Unicode); } - catch (Exception e) + catch { - tmp.Dispose(); + Console.WriteLine("Could happen"); continue; } - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - - GL.ActiveTexture(TextureUnit.Texture0); - tmp.SelectCharmap(Encoding.Unicode); + + ushort temp2 = ((ushort)charter); if (tmp.GetCharIndex(temp2) == 0) { @@ -235,6 +276,9 @@ public class Texture FTBitmap bitmap2 = glyph2.Bitmap; l.AddSystemFontFace(Font._SystemPre[i]); t = new(); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + + GL.ActiveTexture(TextureUnit.Texture0); t.handel = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, t.handel); GL.TexImage2D(TextureTarget.Texture2D, 0, @@ -253,6 +297,7 @@ public class Texture } catch (Exception ex) { + Console.WriteLine("may never happen"); Console.WriteLine(ex); } } @@ -290,6 +335,13 @@ public class Texture } return t; + } + catch (Exception e) + { + Console.WriteLine(2); + Console.WriteLine(e); + throw; + } } public void LoadText() diff --git a/GraphicsManager/Objects/Core/TextureManager.cs b/GraphicsManager/Objects/Core/TextureManager.cs new file mode 100644 index 0000000..2de58b9 --- /dev/null +++ b/GraphicsManager/Objects/Core/TextureManager.cs @@ -0,0 +1,52 @@ +using System.Runtime.Intrinsics.Arm; +using System.Security.Cryptography; +using GraphicsManager.Structs; +using OpenTK.Windowing.Desktop; + +namespace GraphicsManager.Objects.Core; + +public class TextureManager +{ + public static readonly Dictionary TextureManagers = new(); + + public readonly Dictionary TextureHashMap = new(); + + public static TextureManager GetTextureManager(IGLFWGraphicsContext context) + { + if (context is null) throw new ArgumentNullException(nameof(context)); + if (!TextureManagers.ContainsKey(context)) + { + TextureManager tmp = new(context); + TextureManagers.Add(context, tmp); + return tmp; + } + + return TextureManagers[context]; + } + + public IGLFWGraphicsContext Context { get; private set; } + + private TextureManager(IGLFWGraphicsContext context) + { + Context = context; + } + + public IReadOnlyList Textures { get => TextureHashMap.Values.ToList().AsReadOnly(); } + + public void RemoveTexture(Texture Texture) + { + foreach(KeyValuePair item in TextureHashMap.Where(kvp => kvp.Value == Texture).ToList()) + { + TextureHashMap.Remove(item.Key); + } + } + + public Texture AddTexture(byte[] Texture) + { + byte[] hash = SHA256.HashData(Texture); + if (TextureHashMap.ContainsKey(hash)) return TextureHashMap[hash]; + Context.MakeCurrent(); + TextureHashMap.Add(hash, new(Texture)); + return TextureHashMap[hash]; + } +} \ No newline at end of file diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs index 72ea478..c1ee967 100644 --- a/GraphicsManager/Objects/FlowLayout.cs +++ b/GraphicsManager/Objects/FlowLayout.cs @@ -17,7 +17,7 @@ public class FlowLayout : IRenderObject, IParent { _bounds = new Rectangle(); _bounds.Clicked += _bounds_Clicked; - t = new(50); + t = new(33); t.Enabled = true; t.Elapsed += TOnElapsed; t.Start(); @@ -27,6 +27,66 @@ public class FlowLayout : IRenderObject, IParent _bounds.MouseLeave += BoundsOnMouseLeave; } + public void ScrollToControl(IRenderObject Control) + { + if (Controls.Length < 1 || !Controls.Contains(Control)) throw new Exception("Control does not exist"); + if (Control.Location.Y >= 0 && (Control.Location.Y + Control.Size.Y) <= Size.Y) return; + int index = Controls.IndexOf(Control); + bool startbottom = false; + if (Controls.Length - 1 - index < index) startbottom = true; + int loc = 0; + if ((Control.Location.Y + Control.Size.Y) >= Size.Y) loc = Size.Y - Control.Size.Y; + int start = loc + Control.Size.Y; + BlockDraw = true; + if (startbottom) + { + for (int i = index + 1; i < Controls.Length; i++) + { + start += Controls[i].Size.Y; + } + + for (int i = Controls.Length - 1; i >= 0; i--) + { + start -= Controls[i].Size.Y; + Controls[i].Location = new(Controls[i].Location.X, start); + } + } + else + { + for (int i = index; i >= 0; i--) + { + start -= Controls[i].Size.Y; + } + for (int i = 0; i < Controls.Length; i++) + { + start += Controls[i].Size.Y; + Controls[i].Location = new(Controls[i].Location.X, start); + } + } + + for (int i = Controls.Length - 1; i >= 0; i--) + { + if (Controls[i].Location.Y + Controls[i].Size.Y < 0 || Controls[i].Location.Y > Size.Y) + { + Controls[i].Visible = false; + } + } + BlockDraw = false; + if (Parent is not null) Parent.TryDraw(); + } + + public void ScrollToTop() + { + if (Controls.Length < 1) return; + ScrollToControl(Controls[0]); + } + + public void ScrollToBottom() + { + if (Controls.Length < 1) return; + ScrollToControl(Controls[Controls.Length - 1]); + } + public void ReportSizeUpdate(IRenderObject Control) { if (BlockDraw) return; @@ -100,8 +160,17 @@ public class FlowLayout : IRenderObject, IParent { BlockDraw = true; _bounds.Visible = value; - for (int i = 0; i < Controls.Length; i++) - Controls[i].Visible = value; + if (!value) + for (int i = 0; i < Controls.Length; i++) + Controls[i].Visible = value; + else + { + for (int i = 0; i < Controls.Length; i++) + if (Controls[i].Location.Y > Size.Y || Controls[i].Location.Y + Controls[i].Size.Y < 0) + Controls[i].Visible = false; + else + Controls[i].Visible = true; + } if (Parent is not null) Parent.TryDraw(); BlockDraw = false; } @@ -183,9 +252,9 @@ public class FlowLayout : IRenderObject, IParent } public bool BlockDraw { get; set; } = false; - private MouseWheelEventArgs dis; Timer t; private Queue scrols = new(); + private int dist = 0; public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; } public void TryDraw() @@ -198,7 +267,7 @@ public class FlowLayout : IRenderObject, IParent { if (!inside) return; BlockDraw = true; - dis = obj; + dist += (int)obj.OffsetY; if (scrols.Any()) { for (int i = 0; i < scrols.Count; i++) @@ -224,28 +293,93 @@ public class FlowLayout : IRenderObject, IParent { scrols.Enqueue(new Action(() => { + BlockDraw = true; + int current = dist; + dist = 0; if (Controls.Length < 1) return; - bool down = dis.OffsetY < 0;//scrole wheel dir + bool down = current < 0;//scrole wheel dir bool moved = false; - if (down && ((Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y) > Size.Y)) //can go down + float totoaldist = (current * HScrollPixels); + if (down && (!Controls[Controls.Length-1].Visible || (Controls[Controls.Length-1].Visible && Controls[Controls.Length-1].Location.Y + Controls[Controls.Length-1].Size.Y > Size.Y))) //put chat up { moved = true; + int found = -1; + bool lfound = false; for (int i = 0; i < Controls.Length; i++) { - Controls[i].Location = new((int)(Controls[i].Location.X), - (int)(Controls[i].Location.Y + (dis.OffsetY * HScrollPixels))); + if (found == -1) + { + if (!Controls[i].Visible) continue; + else + { + if ((Controls[i].Location.Y + Controls[i].Size.Y) + totoaldist < 0) + { + BlockDraw = true; + Controls[i].Visible = false; + continue; + } + + found = Controls[i].Location.Y + (int)totoaldist; + } + } + + if (!lfound) + { + BlockDraw = true; + Controls[i].Location = new(0, found); + found += Controls[i].Size.Y; + + if (Controls[i].Location.Y <= Size.Y) Controls[i].Visible = true; + else + { + lfound = true; + Controls[i].Visible = false; + } + continue; + } + BlockDraw = true; + if (Controls[i].Visible) Controls[i].Visible = false; } } - if (!down && (Controls[0].Location.Y < 0)) // can go up + if (!down && (!Controls[0].Visible || (Controls[0].Visible && Controls[0].Location.Y < 0))) // put chat down { moved = true; - float newy = Controls[0].Location.Y + (dis.OffsetY * HScrollPixels); - if (newy > 0) newy = 0; - Controls[0].Location = new(0, (int)newy); - for (int i = 1; i < Controls.Length; i++) + int found = -1; + int lfound = -1; + for (int i = Controls.Length - 1; i >= 0; i--) { - Controls[i].Location = new(0, - (int)(Controls[i - 1].Location.Y + Controls[i - 1].Size.Y)); + if (found == -1) + { + if (!Controls[i].Visible) continue; + else + { + if (Controls[i].Location.Y + totoaldist > Size.Y) + { + BlockDraw = true; + Controls[i].Visible = false; + continue; + } + + found = Controls[i].Location.Y + (int)totoaldist + Controls[i].Size.Y; + } + } + + if (lfound == -1) + { + BlockDraw = true; + found -= Controls[i].Size.Y; + Controls[i].Location = new(0, found); + + if (Controls[i].Location.Y + Controls[i].Size.Y >= 0) Controls[i].Visible = true; + else + { + lfound = i; + Controls[i].Visible = false; + } + continue; + } + BlockDraw = true; + if (Controls[i].Visible) Controls[i].Visible = false; } } @@ -253,6 +387,7 @@ public class FlowLayout : IRenderObject, IParent { Parent!.TryDraw(); } + })); } @@ -273,10 +408,13 @@ public class FlowLayout : IRenderObject, IParent if (needload.Any()) { + BlockDraw = true; foreach (IRenderObject Control in needload) { Control.LoadToParent(this, Window!); } + + BlockDraw = false; } for (int i = 0; i < Controls.Length; i++) { diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs index a13701d..09b524e 100755 --- a/GraphicsManager/Objects/Label.cs +++ b/GraphicsManager/Objects/Label.cs @@ -41,7 +41,7 @@ public class Label : IRenderObject set { _Visible = value; - if (Parent is not null) Parent.TryDraw(); + if (Parent is not null && Loaded) Parent.TryDraw(); } } @@ -59,6 +59,34 @@ public class Label : IRenderObject } public int VBO { get; private set; } public Vector2 DIR { get; set; } = new Vector2(1f, 0f); + + 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; + 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; @@ -74,7 +102,7 @@ public class Label : IRenderObject character = value[i]; else character = PasswordChar.Value; - Character cha = Texture.GetChar(Font, character); + if (character == '\n') { @@ -82,6 +110,7 @@ public class Label : IRenderObject addy += Font.PixelHeight * Scale; 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; @@ -119,7 +148,12 @@ public class Label : IRenderObject public void Clean() { + GL.DeleteBuffer(VBO); + Size = new(0, 0); + GL.DeleteVertexArray(VAO); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + Loaded = false; + Visible = false; } public void Draw() @@ -153,21 +187,23 @@ public class Label : IRenderObject c = Text[i]; else c = PasswordChar.Value; - if (!_characters[Window!.Context][Font].ContainsKey(c)) + bool n = (c == '\n'); + if (!_characters[Window!.Context][Font].ContainsKey(c) && !n) { var f = Texture.TextureForChar(Window!.Context, Font, c); f.LoadText(); } - if (!_characters[Window!.Context][Font].ContainsKey(c)) continue; - Character ch = _characters[Window!.Context][Font][c]; + int maxx = 0; - if (c == '\n') + if (n) { - hhh += Font.PixelHeight; + hhh += Font.PixelHeight * Scale; 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; diff --git a/GraphicsManager/Objects/RoundedRectangle.cs b/GraphicsManager/Objects/RoundedRectangle.cs index 7e79d04..ecc2c35 100755 --- a/GraphicsManager/Objects/RoundedRectangle.cs +++ b/GraphicsManager/Objects/RoundedRectangle.cs @@ -199,7 +199,7 @@ public class RoundedRectangle : IRenderObject { if (mouseinside && e.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this); if (mouseinside && e.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!); - if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!); + if (!mouseinside && ContextMenu is not null && Window!.ActiveMenu != ContextMenu) ContextMenu.HideContext(Window!); } ~RoundedRectangle() diff --git a/GraphicsManager/Objects/Textbox.cs b/GraphicsManager/Objects/Textbox.cs index 0678b5b..23002a6 100755 --- a/GraphicsManager/Objects/Textbox.cs +++ b/GraphicsManager/Objects/Textbox.cs @@ -1,6 +1,8 @@ -using GraphicsManager.Enums; +using System.Timers; +using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; +using OpenTK.Graphics.GL; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.GraphicsLibraryFramework; @@ -11,16 +13,24 @@ public class Textbox : IRenderObject { private RoundedRectangle _bounds, _inside; private Label _label; + private Label _watermark; public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; } public Textbox() { _bounds = new RoundedRectangle(); _inside = new RoundedRectangle(); _label = new Label(); + _watermark = new() + { + Color = new(128, 128, 128, 255) + }; + _bounds.MouseEnter += BoundsOnMouseEnter; _bounds.MouseLeave += BoundsOnMouseLeave; } + private int currentc = 0; + public event Func? WindowLoaded; public event Func? MouseEnter; public event Func? MouseLeave; @@ -30,7 +40,37 @@ public class Textbox : IRenderObject public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } } public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } } public Font Font { get => _label.Font; set => _label.Font = value; } - public string Text { get => _label.Text; set => _label.Text = value; } + public string Text + { + get => _label.Text; + set + { + if (!string.IsNullOrEmpty(value)) + { + if (!_label.Visible) _label.Visible = true; + if (_watermark.Visible) _watermark.Visible = false; + } + else + { + if (_label.Visible) _label.Visible = false; + if (!_watermark.Visible) _watermark.Visible = true; + } + _label.Text = value; + } + } + + public Font WatermarkFont { get => _watermark!.Font; set => _watermark.Font = value; } + public string WatermarkText + { + get + { + return _watermark.Text; + } + set + { + _watermark.Text = value; + } + } public char? PasswordChar { get => _label.PasswordChar; set => _label.PasswordChar = value; } public bool Loaded { get; private set; } = false; public Vector2i Size @@ -50,7 +90,8 @@ public class Textbox : IRenderObject set { _bounds.Location = value; - _label.Location = new(value.X + Border + 5, Location.Y + Border + (((Size.Y - (Radius * 2)) / 2) - (_label.Size.Y / 2))); + _label.Location = new(value.X + Border + 5, Location.Y + Border + Border + (((Size.Y - (Radius * 2)) / 2) - (_label.Size.Y / 2))); + _watermark.Location = _label.Location; _inside.Location = new(value.X + Border, value.Y + Border); } } @@ -61,6 +102,8 @@ public class Textbox : IRenderObject public Window? Window { get; private set; } = null; public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; } public Color4 BorderColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; } + public Color4 TextColor { get => _label.Color; set => _label.Color = value; } + public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; } public bool Visible { @@ -69,7 +112,24 @@ public class Textbox : IRenderObject { _bounds.Visible = value; _inside.Visible = value; - _label.Visible = value; + if (value) + { + if (!string.IsNullOrEmpty(_label.Text)) + { + _label.Visible = true; + _watermark.Visible = false; + } + else + { + _label.Visible = false; + _watermark.Visible = true; + } + } + else + { + _label.Visible = value; + _watermark.Visible = value; + } } } public event Func? Clicked; @@ -90,6 +150,7 @@ public class Textbox : IRenderObject _bounds.Clean(); _inside.Clean(); _label.Clean(); + _watermark.Clean(); } public void Draw() @@ -97,7 +158,8 @@ public class Textbox : IRenderObject if (!Visible || !Loaded) return; _bounds.Draw(); _inside.Draw(); - _label.Draw(); + if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(); + else _watermark.Draw(); } public void LoadToParent(IParent Parent, Window Window) @@ -112,6 +174,7 @@ public class Textbox : IRenderObject _bounds.LoadToParent(Parent, Window); _inside.LoadToParent(Parent, Window); _label.LoadToParent(Parent, Window); + _watermark.LoadToParent(Parent, Window); Location = Location; if (WindowLoaded is not null) WindowLoaded.Invoke(this); } diff --git a/GraphicsManager/Objects/UserControl.cs b/GraphicsManager/Objects/UserControl.cs index d075e41..fb129bb 100755 --- a/GraphicsManager/Objects/UserControl.cs +++ b/GraphicsManager/Objects/UserControl.cs @@ -40,7 +40,9 @@ public class UserControl : IRenderObject, IParent BlockDraw = true; _bounds.Visible = value; for (int i = 0; i < Controls.Length; i++) + { Controls[i].Visible = value; + } if (Parent is not null) Parent.TryDraw(); BlockDraw = false; } @@ -130,10 +132,13 @@ public class UserControl : IRenderObject, IParent if (needload.Any()) { + BlockDraw = true; foreach (IRenderObject Control in needload) { Control.LoadToParent(this, Window!); } + + BlockDraw = false; } for (int i = 0; i < Controls.Length; i++) { diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs index 22b0d9f..4f6cc84 100755 --- a/GraphicsManager/Window.cs +++ b/GraphicsManager/Window.cs @@ -7,6 +7,7 @@ using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.Desktop; +using OpenTK.Windowing.GraphicsLibraryFramework; namespace GraphicsManager; @@ -22,13 +23,33 @@ public class Window : NativeWindow , IParent base.Dispose(disposing); } + public TextureManager TextureManager { get; private set; } + internal IRenderObject? focused; + public void CenterWindow(int mon) + { + Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea; + int num = (clientArea.Min.X + clientArea.Max.X - Size.X) / 2; + int num2 = (clientArea.Min.Y + clientArea.Max.Y - Size.Y) / 2; + if (num < clientArea.Min.X) + { + num = clientArea.Min.X; + } + + if (num2 < clientArea.Min.Y) + { + num2 = clientArea.Min.Y; + } + + ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y); + } internal ContextMenu? ActiveMenu { get; set; } = null; public IParent? Parent { get; } = null; public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f); public Window(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings) { + TextureManager = TextureManager.GetTextureManager(Context); Context.MakeCurrent(); Texture.TextureShader.Add(Context, new("RectangleTexture", true)); Objects.Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); @@ -38,7 +59,7 @@ public class Window : NativeWindow , IParent public Window() : base(new NativeWindowSettings()) { - + TextureManager = TextureManager.GetTextureManager(Context); } public Vector2i Position { get; } = new Vector2i(0, 0); public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255); @@ -187,14 +208,12 @@ public class Window : NativeWindow , IParent { Context.MakeCurrent(); initthread = Thread.CurrentThread.ManagedThreadId; - ProcessEvents(); + GLFW.PollEvents(); DrawFrame(); if (WindowLoaded is not null) WindowLoaded.Invoke(this); while (Exists && IsVisible && !IsExiting) { - ProcessEvents(); - bool u = (Rendertype & Rendertype.ControlUpdates) == Rendertype.ControlUpdates; - if (!u) DrawFrame(); + GLFW.PollEvents(); if (invokes.Any()) { for (int i = 0; i < invokes.Count; i++) invokes.Dequeue().Invoke();