From 13dc6cb8209c420a6875e151e670f6af983fe2ba Mon Sep 17 00:00:00 2001 From: JacobTech Date: Wed, 27 Mar 2024 20:53:07 -0400 Subject: [PATCH] OpenGL Version --- GraphicsManager/ContextMenu.cs | 99 ------ GraphicsManager/FPSWindow.cs | 8 +- GraphicsManager/Globals/EXT.cs | 13 + GraphicsManager/GraphicsManager.csproj | 2 +- GraphicsManager/Interfaces/IFlow.cs | 6 + GraphicsManager/Interfaces/IRenderObject.cs | 3 +- GraphicsManager/Interfaces/IWindow.cs | 8 +- GraphicsManager/Objects/BetterContextMenu.cs | 160 ++++++++++ GraphicsManager/Objects/Core/Font.cs | 181 +---------- GraphicsManager/Objects/Core/FontFamily.cs | 152 ++++----- .../Objects/Core/FontInteraction.cs | 239 +++++++++++---- GraphicsManager/Objects/Core/ParentBase.cs | 12 +- GraphicsManager/Objects/Core/Texture.cs | 289 ++++-------------- .../Objects/Core/TextureManager.cs | 6 +- GraphicsManager/Objects/FlowLayout.cs | 260 ++++++++-------- GraphicsManager/Objects/Label.cs | 25 +- GraphicsManager/Objects/RainbowLabel.cs | 12 +- GraphicsManager/Objects/Rectangle.cs | 194 ++++++++++-- GraphicsManager/Objects/TabControl.cs | 2 +- .../Shaders/AlphaChannelTexture.frag | 10 +- .../Shaders/AlphaChannelTexture.vert | 2 +- GraphicsManager/Resources/Shaders/Label.frag | 8 +- GraphicsManager/Resources/Shaders/Label.vert | 10 +- GraphicsManager/Structs/Character.cs | 1 + GraphicsManager/Window.cs | 32 +- 25 files changed, 878 insertions(+), 856 deletions(-) delete mode 100644 GraphicsManager/ContextMenu.cs create mode 100644 GraphicsManager/Interfaces/IFlow.cs create mode 100644 GraphicsManager/Objects/BetterContextMenu.cs diff --git a/GraphicsManager/ContextMenu.cs b/GraphicsManager/ContextMenu.cs deleted file mode 100644 index 46cca8b..0000000 --- a/GraphicsManager/ContextMenu.cs +++ /dev/null @@ -1,99 +0,0 @@ -using GraphicsManager.Enums; -using GraphicsManager.Interfaces; -using GraphicsManager.Objects; -using GraphicsManager.Objects.Core; -using OpenTK.Windowing.Desktop; -using OpenTK.Windowing.Common; -using OpenTK.Graphics.OpenGL4; -using OpenTK.Windowing.GraphicsLibraryFramework; - -namespace GraphicsManager; - -public class ContextMenu : Window -{ - private static NativeWindowSettings set = new() - { - Title = nameof(ContextMenu), - WindowBorder = WindowBorder.Hidden, - APIVersion = new Version(3, 2), - StartFocused = false, - Size = new OpenTK.Mathematics.Vector2i(400, 5), - StartVisible = false, - SharedContext = null - }; - - private FlowLayout fl; - - public ControlList Items => ((FlowLayout)(Controls[0])).Controls; - - public event Func? OnItemClick; - - public ContextMenu(int Width) : base(set) - { - this.Size = new(Width, 5); - Controls.Add(fl = new FlowLayout(){Size = new(Width,5), Anchor = ObjectAnchor.All}); - Items.ControlAdded += ItemsOnControlAdded; - BackgroundColor = new(0, 0, 0, 0); - } - - private Task ItemsOnControlAdded(int index, IRenderObject arg) - { - arg.Clicked += ArgOnClicked; - this.Context.MakeCurrent(); - fl.Size = new(this.Size.X, arg.Location.Y + arg.Size.Y); - this.Size = fl.Size; - GL.Viewport(0,0, this.Size.X, this.Size.Y); - return Task.CompletedTask; - } - - protected override void OnResize(ResizeEventArgs e) - { - - } - - protected override void OnFocusedChanged(FocusedChangedEventArgs e) - { - base.OnFocusedChanged(e); - if (!e.IsFocused && w is not null) HideContext(w,true); - } - - private IWindow? w = null; - - public void HideContext(IWindow Parent, bool force = false) - { - if (Parent.ActiveMenu == this && !false) return; - w = null; - Parent.ActiveMenu = null; - Context.MakeCurrent(); - IsVisible = false; - } - - public void ShowContext(IWindow 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; - } - if (Parent.ActiveMenu is not null) - { - Parent.ActiveMenu.HideContext(Parent); - } - Parent.ActiveMenu = this; - 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(); - } - - private Task ArgOnClicked(IRenderObject arg) - { - if (OnItemClick is not null) _ = OnItemClick.Invoke(arg); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/GraphicsManager/FPSWindow.cs b/GraphicsManager/FPSWindow.cs index 3484ff1..4ff49ac 100755 --- a/GraphicsManager/FPSWindow.cs +++ b/GraphicsManager/FPSWindow.cs @@ -16,6 +16,8 @@ public class FPSWindow : GameWindow , IWindow { public TextureManager TextureManager { get; private set; } private TitleBar? _tb = null; + + public bool ShowMissingChar { get; set; } public TitleBar? CustomeTitleBar { @@ -46,13 +48,12 @@ public class FPSWindow : GameWindow , IWindow ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y); } - public ContextMenu? ActiveMenu { get; set; } = null; public IParent? Parent { get; } = null; public MouseCursor HoverMouse { get; set; } = MouseCursor.Default; public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f); public FPSWindow(NativeWindowSettings nativeWindowSettings, GameWindowSettings gws) : base(gws,nativeWindowSettings) { - TextureManager = TextureManager.GetTextureManager(Context); + TextureManager = TextureManager.GetTextureManager(Context, this); Context.MakeCurrent(); if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true, Texture:true)); if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); @@ -260,7 +261,7 @@ public class FPSWindow : GameWindow , IWindow public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates; - public bool CanControleUpdate { get; private set; } = true; + public bool CanControleUpdate { get; set; } = true; public int FPS { get; set; } = 0; public event Func? WindowLoaded; @@ -385,6 +386,7 @@ public class FPSWindow : GameWindow , IWindow BlockDraw = false; } + GL.Scissor(0, 0, Size.X, Size.Y); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); for (int i = 0; i < Controls.Length; i++) { diff --git a/GraphicsManager/Globals/EXT.cs b/GraphicsManager/Globals/EXT.cs index 5c34a42..72061c8 100644 --- a/GraphicsManager/Globals/EXT.cs +++ b/GraphicsManager/Globals/EXT.cs @@ -21,6 +21,19 @@ public static class EXT return dest; } + public static void PrintArray(this Tarr[] arr, string Name, int col) where Tarr : IComparable + { + Console.WriteLine("Array {0}:", Name); + for (int i = 0; i < arr.Length / col; i++) + { + for (int j = 0; j < col; j++) + { + Console.Write(String.Format("{0:0.00}", arr[(i * col) + j])+ '\t'); + } + Console.WriteLine(); + } + } + public static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext context, int size, float cornerRadius) { return context.Resize(new ResizeOptions diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj index bc33c55..4079dab 100644 --- a/GraphicsManager/GraphicsManager.csproj +++ b/GraphicsManager/GraphicsManager.csproj @@ -10,7 +10,7 @@ False https://git.jacobtech.com/JacobTech.com/GraphicsManager git - 1.0.7-alpha69 + 1.0.8-alpha82 diff --git a/GraphicsManager/Interfaces/IFlow.cs b/GraphicsManager/Interfaces/IFlow.cs new file mode 100644 index 0000000..37a212b --- /dev/null +++ b/GraphicsManager/Interfaces/IFlow.cs @@ -0,0 +1,6 @@ +namespace GraphicsManager.Interfaces; + +public interface IFlow : IParent +{ + void ForceScrollUpdate(); +} \ No newline at end of file diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs index 279697b..db26e0c 100755 --- a/GraphicsManager/Interfaces/IRenderObject.cs +++ b/GraphicsManager/Interfaces/IRenderObject.cs @@ -1,4 +1,5 @@ using GraphicsManager.Enums; +using GraphicsManager.Objects; using OpenTK.Mathematics; using OpenTK.Windowing.Common.Input; @@ -8,7 +9,7 @@ public interface IRenderObject { public void ForceDistanceUpdate(); public void ForceDistanceUpdate(IParent parent); - public ContextMenu? ContextMenu { get; set; } + public BetterContextMenu? ContextMenu { get; set; } public ObjectAnchor Anchor { get; set; } public bool MouseInside { get; set; } public bool IgnoreHover { get; set; } diff --git a/GraphicsManager/Interfaces/IWindow.cs b/GraphicsManager/Interfaces/IWindow.cs index 8f63143..b77c6c7 100644 --- a/GraphicsManager/Interfaces/IWindow.cs +++ b/GraphicsManager/Interfaces/IWindow.cs @@ -9,6 +9,8 @@ public interface IWindow : IParent public IRenderObject? HoveringControl { get; set; } public IGLFWGraphicsContext Context { get; } + public bool ShowMissingChar { get; } + public event Action MouseDown; public event Action FileDrop; @@ -28,7 +30,9 @@ public interface IWindow : IParent public Vector2 MousePosition { get; set; } - public ContextMenu? ActiveMenu { get; set; } - public bool CanControleUpdate { get; } + + void Invoke(Action A); + + bool InvokeRequired { get; } } \ No newline at end of file diff --git a/GraphicsManager/Objects/BetterContextMenu.cs b/GraphicsManager/Objects/BetterContextMenu.cs new file mode 100644 index 0000000..9fe2cb2 --- /dev/null +++ b/GraphicsManager/Objects/BetterContextMenu.cs @@ -0,0 +1,160 @@ +using GraphicsManager.Interfaces; +using GraphicsManager.Objects.Core; +using OpenTK.Mathematics; + +namespace GraphicsManager.Objects; + +public class BetterContextMenu : UserControl +{ + public Vector4i Margins + { + get + { + return mg; + } + set + { + mg = value; + BlockDraw = true; + fl.Location = new(mg.W, mg.X, Location.Z); + if (AutoSizeWidth || AutoSizeHeight) + { + int x = 0, y = 0; + if (AutoSizeWidth && AutoSizeHeight) + { + for (int i = 0; i < Controls.Length; i++) + { + y += Controls[i].Size.Y; + x += Controls[i].Size.X + fl.SpaceBetweenObjects; + } + + x -= fl.SpaceBetweenObjects; + fl.Size = new(x, y); + Size = new(mg.Y + mg.W + x, mg.X + mg.Z + y); + } + else if (AutoSizeWidth) + { + for (int i = 0; i < Controls.Length; i++) + { + x += Controls[i].Size.X + fl.SpaceBetweenObjects; + } + + x -= fl.SpaceBetweenObjects; + fl.Size = new(x, fl.Size.Y); + Size = new(mg.Y + mg.W + x, Size.Y); + } + else + { + for (int i = 0; i < Controls.Length; i++) + { + y += Controls[i].Size.Y; + } + + fl.Size = new(fl.Size.X, y); + Size = new(Size.X, mg.X + mg.Z + y); + } + } + + BlockDraw = false; + TryDraw(); + } + } + private FlowLayout fl = new() + { + BackgroundColor = Color4.Transparent + }; + + private Vector4i mg; + + public int SpaceBetweenObjects + { + get => fl.SpaceBetweenObjects; + set => fl.SpaceBetweenObjects = value; + } + + public void ShowContext(IWindow ParentWindow) + { + if (!Visible) + { + if (Parent is null) + { + ParentWindow.Controls.Add(this); + LoadToParent(ParentWindow, ParentWindow); + } + } + if (Size.Y + (int)ParentWindow.MousePosition.Y > ParentWindow.Size.Y) Location = new((int)ParentWindow.MousePosition.X, ParentWindow.Size.Y - Size.Y, Location.Z); + else Location = new((int)ParentWindow.MousePosition.X, (int)ParentWindow.MousePosition.Y, Location.Z); + Visible = true; + TryDraw(); + } + + public void HideContext(IWindow Parent) + { + if (!Visible) return; + Visible = false; + TryDraw(); + } + + public bool AutoSizeWidth { get; set; } = true; + public bool AutoSizeHeight { get; set; } = true; + + + public BetterContextMenu() + { + Controls.Add(fl); + base.Visible = false; + } + + public BetterContextMenu(Texture t) + :base(t) + { + Controls.Add(fl); + base.Visible = false; + } + + public void AddLine() + { + AddLine(new(255,255,255,255)); + } + + public void AddLine(Color4 color, int Height = 1) + { + Rectangle r = new() + { + BackgroundColor = color, + Size = new(fl.Size.X, Height) + }; + AddOption(r); + } + + public void AddLabel(ILabel label) + { + AddOption(label); + } + + public Label AddLabel(FontInteraction fi, string text, Color4 color) + { + Label l; + AddLabel(l=new Label(fi){ Text = text, Color = color}); + return l; + } + + public void AddOption(IRenderObject obj) + { + int x = fl.Size.X, y = fl.Size.Y; + if (AutoSizeWidth && obj.Size.X > fl.Size.X) + { + Size = new(obj.Size.X + mg.Y + mg.W, Size.Y); + x = obj.Size.X; + } + + if (AutoSizeHeight) + { + Size = new(Size.X, Size.Y + SpaceBetweenObjects + obj.Size.Y); + y += obj.Size.Y + SpaceBetweenObjects; + } + + fl.Size = new(x, y); + fl.Controls.Add(obj); + } +} \ No newline at end of file diff --git a/GraphicsManager/Objects/Core/Font.cs b/GraphicsManager/Objects/Core/Font.cs index ac4ece6..5adb3f6 100755 --- a/GraphicsManager/Objects/Core/Font.cs +++ b/GraphicsManager/Objects/Core/Font.cs @@ -7,185 +7,36 @@ namespace GraphicsManager.Objects.Core; public class Font { - private List _Faces = new(); internal static Library lib = new(); - public IReadOnlyList Fonts => _Faces.AsReadOnly(); - internal static Dictionary AllFileFonts = new(); - internal static Dictionary AllMemoryFonts = new(); - internal static List? _SystemPre = null; - private static List AllFonts = new(); - private static bool Backup = false; - private static int addsystem = 0; - public static bool CanScanSystem = true; - 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])) - { - foreach (Font ft in AllFonts) - { - ft._Faces.Add(AllFileFonts[path]); - } - } - - if (addsystem == _SystemPre!.Count) - { - addsystem++; - foreach (Font ft in AllFonts) - { - ft._Faces.Add(AllMemoryFonts.Last().Value); - } - } - } - + public Face Face { get; private set; } private Font() { - Name = null!; - Assembly = null!; - Embeded = false; - //TODO add more systemfont dection methods - if (!Backup) - { - AllMemoryFonts.Add(SHA256.HashData(Tools.GetResourceBytes("GraphicsManager.Resources.Fonts.TektonPro-Regular.otf")), new Face(lib, Tools.GetResourceBytes("GraphicsManager.Resources.Fonts.TektonPro-Regular.otf"), 0)); - Backup = true; - } - if (_SystemPre is null && CanScanSystem) - { - _SystemPre = new(); - if (OperatingSystem.IsLinux()) - { - try - { - Process proc = new() - { - StartInfo = new() - { - FileName = "/bin/bash", - Arguments = "-c \"fc-list ':' file\"", - RedirectStandardOutput = true, - } - }; - proc.Start(); - proc.WaitForExit(); - string[] files = proc.StandardOutput.ReadToEnd().Split($": {Environment.NewLine}"); - for (int i = 0; i < files.Length; i++) - { - _SystemPre.Add(files[i]); - } - } - catch - { - string folder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts); - _SystemPre = new(); - Tools.AddFontsToList(ref _SystemPre, folder); - } - } - - if (OperatingSystem.IsWindows()) - { - try - { - string folder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts); - _SystemPre = new(); - Tools.AddFontsToList(ref _SystemPre, folder); - } - catch - { - - } - } - } - } - public void SetEmbeddedFont(string Font, Assembly? Assembly = null) - { - _ = Font ?? throw new ArgumentNullException(nameof(Font)); - string Base = "GraphicsManager.Resources.Fonts."; - if (Assembly is not null) Base = string.Empty; - byte[] f = (Assembly is null - ? 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 (!_Faces.Contains(AllMemoryFonts[hash])) _Faces.Insert(0, AllMemoryFonts[hash]); - else - { - _Faces.Remove(AllMemoryFonts[hash]); - _Faces.Insert(0, AllMemoryFonts[hash]); - } - this.Assembly = Assembly; - this.Embeded = true; - this.Name = Font; } - public static Font MakeEmbeddedFont(string Font, Assembly? Assembly = null) + internal static Font MakeFontFromFile(string Font) { - _ = Font ?? throw new ArgumentNullException(nameof(Font)); - Font fontclass = new Font() + try { - Assembly = Assembly, - Embeded = true, - Name = Font, - HasTopFont = true - }; - AllFonts.Add(fontclass); - string Base = "GraphicsManager.Resources.Fonts."; - if (Assembly is not null) Base = string.Empty; - byte[] f = (Assembly is null - ? 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)); - fontclass._Faces.Insert(0, AllMemoryFonts[hash]); - return fontclass; - } - - //private static Font? Cache = null; - private static List Caches = new(); - /* - public static Font MakeFontFromSystem(uint PixelHeight = 12) - { - if (!Caches.Where(s => s.PixelHeight == PixelHeight).Any()) - { - Font f = new() { PixelHeight = PixelHeight }; - Caches.Add(f); - AllFonts.Add(f); + _ = Font ?? throw new ArgumentNullException(nameof(Font)); + Font fontclass = new Font(); + fontclass.Face = new Face(lib, Font, 0); + return fontclass; } - return Caches.Where(s => s.PixelHeight == PixelHeight).First(); - }*/ - public static Font MakeFontFromFile(string Font) - { - _ = Font ?? throw new ArgumentNullException(nameof(Font)); - Font fontclass = new Font() + catch (Exception e) { - Assembly = null, - Embeded = false, - Name = Font, - HasTopFont = true - }; - AllFonts.Add(fontclass); - fontclass._Faces.Insert(0, new Face(lib, Font, 0)); - return fontclass; + Console.WriteLine(e); + throw; + } } - public void SetFontFile(string Font) + + internal static Font MakeFontFromStream(MemoryStream Font) { _ = Font ?? throw new ArgumentNullException(nameof(Font)); - if (HasTopFont) _Faces[0] = new Face(lib, Font, 0); - else _Faces.Insert(0, new Face(lib, Font, 0)); - HasTopFont = true; - this.Assembly = null; - this.Embeded = false; - this.Name = Font; + Font fontclass = new Font(); + fontclass.Face = new Face(lib, Font.ToArray(), 0); + return fontclass; } - - private bool HasTopFont = false; - //private uint ph = 12; - //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/FontFamily.cs b/GraphicsManager/Objects/Core/FontFamily.cs index a26a4d8..dce4af0 100644 --- a/GraphicsManager/Objects/Core/FontFamily.cs +++ b/GraphicsManager/Objects/Core/FontFamily.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.IO.Compression; using GraphicsManager.Enums; using SixLabors.Fonts; @@ -8,128 +9,93 @@ public class FontFamily { private static uint index = 0; public event Func? ReloadUI; + public required string Family { get; init; } private FontSize fs = FontSize.Thin; - private uint ph = 12; - private bool i; internal Dictionary> InternalFonts = new(); internal Dictionary> InternalFontsi = new(); - internal Font Font = null!; - + internal bool IsZip = false; + internal Dictionary> SInternalFonts = new(); + internal Dictionary> SInternalFontsi = new(); + internal static List AllFams = new(); - - public static Task LoadFontFamily() + public static Task LoadFontFamilyTask(Stream FamilyZip, string Family, string extra = "-") { - FontFamily f = new(); - foreach (string font in Tools.GetFontList($"fc-list ':'family='{Tools.GetFamilyList("fc-list ':' family")[index]}' file")) + return Task.FromResult(LoadFontFamily(FamilyZip, Family, extra)); + } + + public static FontFamily LoadFontFamily(Stream FamilyZip, string Family, string extra = "-") + { + extra = extra.ToLower(); + FontFamily f = new() { - string fd = font.ToLower(); + Family = Family + }; + AllFams.Add(f); + using ZipArchive archive = new ZipArchive(FamilyZip, ZipArchiveMode.Read, false); + f.IsZip = true; + + foreach (ZipArchiveEntry font in archive.Entries) + { + string fd = font.Name.ToLower(); string[] fda = fd.Split('.'); fd = fda[fda.Length - 2]; - + void tryadd(FontSize s, bool i = false) { + var memoryStream = new MemoryStream(); + font.Open().CopyTo(memoryStream); if (i) { - if (!f.InternalFontsi.ContainsKey(s)) - f.InternalFontsi.Add(s, new(font, null)); + if (!f.SInternalFontsi.ContainsKey(s)) + f.SInternalFontsi.Add(s, new(memoryStream, null)); } else { - if (!f.InternalFonts.ContainsKey(s)) - f.InternalFonts.Add(s, new(font, null)); + if (!f.SInternalFonts.ContainsKey(s)) + f.SInternalFonts.Add(s, new(memoryStream, null)); } } if (fd.EndsWith("italic")) { - if (fd.EndsWith("thinitalic")) tryadd(FontSize.Thin, true); - else if (fd.EndsWith("extralightitalic")) tryadd(FontSize.ExtraLight, true); - else if (fd.EndsWith("lightitalic")) tryadd(FontSize.Light, true); - else if (fd.EndsWith("regularitalic")) tryadd(FontSize.Regular, true); - else if (fd.EndsWith("mediumitalic")) tryadd(FontSize.Medium, true); - else if (fd.EndsWith("semibolditalic")) tryadd(FontSize.SemiBold, true); - else if (fd.EndsWith("bolditalic")) tryadd(FontSize.Bold, true); - else if (fd.EndsWith("extrabolditalic")) tryadd(FontSize.ExtraBold, true); - else if (fd.EndsWith("blackitalic")) tryadd(FontSize.Black, true); - else tryadd(FontSize.Regular, true); + if (fd.EndsWith(extra + "thinitalic")) tryadd(FontSize.Thin, true); + if (fd.EndsWith(extra + "extralightitalic")) tryadd(FontSize.ExtraLight, true); + if (fd.EndsWith(extra + "lightitalic")) tryadd(FontSize.Light, true); + if (fd.EndsWith(extra + "italic")) tryadd(FontSize.Regular, true); + if (fd.EndsWith(extra + "mediumitalic")) tryadd(FontSize.Medium, true); + if (fd.EndsWith(extra + "semibolditalic")) tryadd(FontSize.SemiBold, true); + if (fd.EndsWith(extra + "bolditalic")) tryadd(FontSize.Bold, true); + if (fd.EndsWith(extra + "extrabolditalic")) tryadd(FontSize.ExtraBold, true); + if (fd.EndsWith(extra + "blackitalic")) tryadd(FontSize.Black, true); } else { - if (fd.EndsWith("thin")) tryadd(FontSize.Thin); - else if (fd.EndsWith("extralight")) tryadd(FontSize.ExtraLight); - else if (fd.EndsWith("light")) tryadd(FontSize.Light); - else if (fd.EndsWith("regular")) tryadd(FontSize.Regular); - else if (fd.EndsWith("medium")) tryadd(FontSize.Medium); - else if (fd.EndsWith("semibold")) tryadd(FontSize.SemiBold); - else if (fd.EndsWith("bold")) tryadd(FontSize.Bold); - else if (fd.EndsWith("extrabold")) tryadd(FontSize.ExtraBold); - else if (fd.EndsWith("black")) tryadd(FontSize.Black); - else tryadd(FontSize.Regular); - } - } - - index++; - return Task.FromResult(f); - } - - - public static Task LoadFontFamily(string Family) - { - FontFamily f = new(); - foreach (string font in Tools.GetFontList($"fc-list ':'family='{Family}' file")) - { - string fd = font.ToLower(); - string[] fda = fd.Split('.'); - fd = fda[fda.Length - 2]; - - void tryadd(FontSize s, bool i = false) - { - if (i) - { - if (!f.InternalFontsi.ContainsKey(s)) - f.InternalFontsi.Add(s, new(font, null)); - } - else - { - if (!f.InternalFonts.ContainsKey(s)) - f.InternalFonts.Add(s, new(font, null)); - } + if (fd.EndsWith(extra + "thin")) tryadd(FontSize.Thin); + if (fd.EndsWith(extra + "extralight")) tryadd(FontSize.ExtraLight); + if (fd.EndsWith(extra + "light")) tryadd(FontSize.Light); + if (fd.EndsWith(extra + "regular")) tryadd(FontSize.Regular); + if (fd.EndsWith(extra + "medium")) tryadd(FontSize.Medium); + if (fd.EndsWith(extra + "semibold")) tryadd(FontSize.SemiBold); + if (fd.EndsWith(extra + "bold")) tryadd(FontSize.Bold); + if (fd.EndsWith(extra + "extrabold")) tryadd(FontSize.ExtraBold); + if (fd.EndsWith(extra + "black")) tryadd(FontSize.Black); } - if (fd.EndsWith("italic")) - { - if (fd.EndsWith("thinitalic")) tryadd(FontSize.Thin, true); - if (fd.EndsWith("extralightitalic")) tryadd(FontSize.ExtraLight, true); - if (fd.EndsWith("lightitalic")) tryadd(FontSize.Light, true); - if (fd.EndsWith("regularitalic")) tryadd(FontSize.Regular, true); - if (fd.EndsWith("mediumitalic")) tryadd(FontSize.Medium, true); - if (fd.EndsWith("semibolditalic")) tryadd(FontSize.SemiBold, true); - if (fd.EndsWith("bolditalic")) tryadd(FontSize.Bold, true); - if (fd.EndsWith("extrabolditalic")) tryadd(FontSize.ExtraBold, true); - if (fd.EndsWith("blackitalic")) tryadd(FontSize.Black, true); - } - else - { - if (fd.EndsWith("thin")) tryadd(FontSize.Thin); - if (fd.EndsWith("extralight")) tryadd(FontSize.ExtraLight); - if (fd.EndsWith("light")) tryadd(FontSize.Light); - if (fd.EndsWith("regular")) tryadd(FontSize.Regular); - if (fd.EndsWith("medium")) tryadd(FontSize.Medium); - if (fd.EndsWith("semibold")) tryadd(FontSize.SemiBold); - if (fd.EndsWith("bold")) tryadd(FontSize.Bold); - if (fd.EndsWith("extrabold")) tryadd(FontSize.ExtraBold); - if (fd.EndsWith("black")) tryadd(FontSize.Black); - } } - return Task.FromResult(f); - } - - public static async Task LoadFontFamily(string Dir, string Family) - { - FontFamily f = new(); + return f; } + public static Task LoadFontFamily(string Dir, string Family, string extra = "-") + { + FontFamily f = new() + { + Family = Family + }; + AllFams.Add(f); + return Task.FromResult(f); + } + private FontFamily() { } diff --git a/GraphicsManager/Objects/Core/FontInteraction.cs b/GraphicsManager/Objects/Core/FontInteraction.cs index 335ec2c..a0c7b68 100644 --- a/GraphicsManager/Objects/Core/FontInteraction.cs +++ b/GraphicsManager/Objects/Core/FontInteraction.cs @@ -1,20 +1,27 @@ using GraphicsManager.Enums; +using SharpFont; namespace GraphicsManager.Objects.Core; public class FontInteraction { - public FontFamily Family { get; private set; } - public Font CurrentFont { get; private set; } + public Font[] CurrentFonts { get; private set; } private FontSize fs = FontSize.Thin; private uint ph = 12; private bool i; private uint epx = 0; + internal List _Faces = new(); public event Func? ReloadUI; + internal List Families_ { get; } = new(); + public IReadOnlyList Families + { + get => Families_.AsReadOnly(); + } public FontInteraction Clone() { - return (FontInteraction)this.MemberwiseClone(); + var c = (FontInteraction)this.MemberwiseClone(); + return c; } public static FontInteraction Load(FontFamily family) @@ -23,9 +30,17 @@ public class FontInteraction c.FontSize = FontSize.Regular; return c; } + + private FontInteraction(FontFamily Family) { - this.Family = Family; + Families_.Add(Family); + } + + public void AddFamily(FontFamily Family) + { + Families_.Add(Family); + FontSize = FontSize; } public uint PixelHeight @@ -55,50 +70,112 @@ public class FontInteraction { if (i != value) { - if (value) + CurrentFonts = new Font[Families_.Count]; + for (int j = 0; j < Families_.Count; j++) { - if (Family.InternalFontsi.TryGetValue(FontSize, out Tuple? f)) + if (Families_[j].IsZip) { - i = value; - if (f.Item2 is null) + if (value) { - switch (Italic) + if (Families_[j].SInternalFontsi.TryGetValue(FontSize, out Tuple? f)) { - case true: - Family.InternalFontsi[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFontsi[fs].Item1)); - break; - case false: - Family.InternalFonts[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFonts[fs].Item1)); - break; - } - } + 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; + } + } - CurrentFont = (Family.InternalFontsi[fs].Item2!); - if (ReloadUI is not null) ReloadUI.Invoke(); - } - } - else - { - if (Family.InternalFonts.TryGetValue(FontSize, out Tuple? f)) - { - i = value; - if (f.Item2 is null) - { - switch (Italic) - { - case true: - Family.InternalFontsi[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFontsi[fs].Item1)); - break; - case false: - Family.InternalFonts[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFonts[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)); + break; + case false: + Families_[j].SInternalFonts[fs] = new(f.Item1, + Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1)); + break; + } + } + + CurrentFonts[j] = Families_[j].SInternalFonts[fs].Item2!; + if (ReloadUI is not null) ReloadUI.Invoke(); + } + } + } + else + { + if (value) + { + 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(); } } - CurrentFont = Family.InternalFonts[fs].Item2!; - if (ReloadUI is not null) ReloadUI.Invoke(); } } - //Font.PixelHeight = this.PixelHeight; } } } @@ -113,36 +190,78 @@ public class FontInteraction return thisList[nearest]; } + 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); + fs = nearest; + return thisList[nearest]; + } + public FontSize FontSize { get => fs; set { - Tuple f = Italic switch + CurrentFonts = new Font[Families_.Count]; + for (int j = 0; j < Families_.Count; j++) { - true => gcl(Family.InternalFontsi, value, out fs), - false => gcl(Family.InternalFonts, value, out fs), - }; - if (f.Item2 is null) - { - switch (Italic) + if (Families_[j].IsZip) { - case true: - Family.InternalFontsi[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFontsi[fs].Item1)); - break; - case false: - Family.InternalFonts[fs] = new(f.Item1, Font.MakeFontFromFile(Family.InternalFonts[fs].Item1)); - break; + 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)); + break; + case false: + Families_[j].SInternalFonts[fs] = new(f.Item1, Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1)); + break; + } + } + + CurrentFonts[j] = Italic switch + { + true => Families_[j].SInternalFontsi[fs].Item2!, + false => Families_[j].SInternalFonts[fs].Item2!, + }; + } + else + { + 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!, + }; } } - - CurrentFont = Italic switch - { - true => Family.InternalFontsi[fs].Item2!, - false => Family.InternalFonts[fs].Item2!, - }; - //Font.PixelHeight = this.PixelHeight; - if (ReloadUI is not null) ReloadUI.Invoke(); } } diff --git a/GraphicsManager/Objects/Core/ParentBase.cs b/GraphicsManager/Objects/Core/ParentBase.cs index ee44711..293b350 100644 --- a/GraphicsManager/Objects/Core/ParentBase.cs +++ b/GraphicsManager/Objects/Core/ParentBase.cs @@ -60,7 +60,7 @@ public abstract class ParentBase : Rectangle, IParent public override void Draw(int x, int y, int w, int h) { - if (Loaded && Visible) + 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) @@ -94,15 +94,13 @@ public abstract class ParentBase : Rectangle, IParent { Control.LoadToParent(this, Window!); } - + if (this is IFlow flow) flow.ForceScrollUpdate(); BlockDraw = false; } for (int i = 0; i < Controls.Length; i++) { - if (Controls[i] is not IParent) - { - GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh); - } + if (Controls[i].Location.X > Size.X || Controls[i].Location.Y > Size.Y) continue; + GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh); Controls[i].Draw(nx, ny, nw, nh); } } @@ -125,7 +123,9 @@ public abstract class ParentBase : Rectangle, IParent base.LoadToParent(Parent, Window); for (int i = 0; i < Controls.Length; i++) { + if (Controls[i].Loaded) continue; Controls[i].LoadToParent(this, Window); + if (Controls[i] is IFlow flow) flow.ForceScrollUpdate(); } BlockDraw = PastBlockState; } diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs index e3f5c05..4574fa1 100755 --- a/GraphicsManager/Objects/Core/Texture.cs +++ b/GraphicsManager/Objects/Core/Texture.cs @@ -146,166 +146,92 @@ public class Texture { } - internal static Character GetChar(Font l, char charter, uint PH) + internal static Character GetChar(Face face, char charter) + { + ushort temp = (charter); + if (face.GetCharIndex(temp) == 0) + { + return new() + { + Size = new Vector2(0, 0), + Bearing = new Vector2(0, 0), + Advance = 0, + AdvanceY = ((Math.Abs(face.Descender) / (double)face.UnitsPerEM) * 16) + }; + } + face.LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); + GlyphSlot glyph = face.Glyph; + FTBitmap bitmap = glyph.Bitmap; + + return new() + { + Size = new Vector2(bitmap.Width, bitmap.Rows), + Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop), + Advance = glyph.Advance.X.Value, + AdvanceY = ((Math.Abs(face.Descender) / (double)face.UnitsPerEM) * 16) + }; + } + + internal static Character GetChar(FontInteraction l, char charter) { try { - - int last = 0; - for (int i = 0; i < l.Fonts.Count; i++) - { - try + for (int i = 0; i < l.CurrentFonts.Length; i++) { try { - l.Fonts[i].SetPixelSizes(0, PH); - l.Fonts[i].SelectCharmap(Encoding.Unicode); - last = i; + l.CurrentFonts[i].Face.SetPixelSizes(0, l.PixelHeight); + l.CurrentFonts[i].Face.SelectCharmap(Encoding.Unicode); } catch { continue; } - ushort temp = (charter); - if (l.Fonts[i].GetCharIndex(temp) == 0) continue; - l.Fonts[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); - GlyphSlot glyph = l.Fonts[i].Glyph; - FTBitmap bitmap = glyph.Bitmap; - - return new() - { - Size = new Vector2(bitmap.Width, bitmap.Rows), - Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop), - Advance = glyph.Advance.X.Value, - AdvanceY = ((Math.Abs(l.Fonts[last].Descender) / (double)l.Fonts[last].UnitsPerEM) * 16) - }; - } - catch (Exception ex) - { - Console.WriteLine(ex); - } - } - List bad = new(); - for (int i = 0; i < Font._SystemPre.Count; i++) - { - try - { - Face tmp; - try - { - tmp = new(Font.lib, Font._SystemPre[i], 0); - tmp.SetPixelSizes(0, PH); - tmp.SelectCharmap(Encoding.Unicode); - } - catch (Exception e) - { - Console.WriteLine($"Removing bad font1: {Font._SystemPre[i]}"); - bad.Add(Font._SystemPre[i]); - continue; - } - - ushort temp2 = ((ushort)charter); - if (tmp.GetCharIndex(temp2) == 0) - { - tmp.Dispose(); - continue; - } - 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), - Bearing = new Vector2(glyph2.BitmapLeft, glyph2.BitmapTop), - Advance = glyph2.Advance.X.Value, - AdvanceY = ((Math.Abs(l.Fonts[last].Descender) / (double)l.Fonts[last].UnitsPerEM) * 16) - }; - } - 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, PH); - - l.Fonts[last].SelectCharmap(Encoding.Unicode); - ushort temp22 = ((ushort)charter); - l.Fonts[last].LoadChar(temp22, LoadFlags.Render, LoadTarget.Normal); - GlyphSlot glyph22 = l.Fonts[0].Glyph; - FTBitmap bitmap22 = glyph22.Bitmap; + if (l.CurrentFonts[i].Face.GetCharIndex(temp) == 0) continue; - return new() - { - Size = new Vector2(bitmap22.Width, bitmap22.Rows), - Bearing = new Vector2(glyph22.BitmapLeft, glyph22.BitmapTop), - Advance = (int)glyph22.Advance.X.Value, - AdvanceY = ((Math.Abs(l.Fonts[last].Descender) / (double)l.Fonts[last].UnitsPerEM) * 16) - }; + return GetChar(l.CurrentFonts[i].Face, charter); + } } catch (Exception e) { Console.WriteLine(e); throw; } + return GetChar(l.CurrentFonts[0].Face, (char)1); } + private static Dictionary BadChars = new(); + + internal static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter) { try { - - - Texture? t = null; - int last = 0; - - for (int i = 0; i < l.CurrentFont.Fonts.Count; i++) - { - try + ushort temp = ((ushort)charter); + for (int i = 0; i < l.CurrentFonts.Length; i++) { if (!Label._characters[con].ContainsKey(l)) Label._characters[con].Add(l, new Dictionary()); if (Label._characters[con][l].ContainsKey(charter)) return Label._characters[con][l][(ushort)charter].Texture; try { - l.CurrentFont.Fonts[i].SetPixelSizes(0, l.PixelHeight); - last = i; + l.CurrentFonts[i].Face.SetPixelSizes(0, l.PixelHeight); } catch (Exception e) { Console.WriteLine("should never happen"); continue; } + l.CurrentFonts[i].Face.SelectCharmap(Encoding.Unicode); - - - l.CurrentFont.Fonts[i].SelectCharmap(Encoding.Unicode); - ushort temp = ((ushort)charter); - if (l.CurrentFont.Fonts[i].GetCharIndex(temp) == 0) continue; - l.CurrentFont.Fonts[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); - GlyphSlot glyph = l.CurrentFont.Fonts[i].Glyph; + if (l.CurrentFonts[i].Face.GetCharIndex(temp) == 0) continue; + l.CurrentFonts[i].Face.LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); + GlyphSlot glyph = l.CurrentFonts[i].Face.Glyph; FTBitmap bitmap = glyph.Bitmap; - t = new(); + Texture t = new(); + t.Unit = TextureUnit.Texture9; GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.ActiveTexture(TextureUnit.Texture0); + GL.ActiveTexture(TextureUnit.Texture9); t.handel = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, t.handel); GL.TexImage2D(TextureTarget.Texture2D, 0, @@ -327,114 +253,25 @@ public class Texture Label._characters[con][l].Add(temp, cha); return t; - } - catch (Exception ex) - { - Console.WriteLine("How?"); - Console.WriteLine(ex); - continue; - } - } - - if (t is null) - { - for (int i = 0; i < Font._SystemPre.Count; i++) - { - try - { - Face tmp; - try - { - tmp = new(Font.lib, Font._SystemPre[i], 0); - tmp.SetPixelSizes(0, l.PixelHeight); - tmp.SelectCharmap(Encoding.Unicode); - } - catch - { - Console.WriteLine("Could happen"); - continue; - } - - - ushort temp2 = ((ushort)charter); - if (tmp.GetCharIndex(temp2) == 0) - { - tmp.Dispose(); - continue; - } - tmp.LoadChar(temp2, LoadFlags.Render, LoadTarget.Normal); - GlyphSlot glyph2 = tmp.Glyph; - FTBitmap bitmap2 = glyph2.Bitmap; - l.CurrentFont.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, - PixelInternalFormat.R8, bitmap2.Width, bitmap2.Rows, 0, - PixelFormat.Red, PixelType.UnsignedByte, bitmap2.Buffer); - GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - Character cha2 = new() - { - Size = new Vector2(bitmap2.Width, bitmap2.Rows), - Bearing = new Vector2(glyph2.BitmapLeft, glyph2.BitmapTop), - Advance = (int)glyph2.Advance.X.Value, - Texture = t, - AdvanceY = glyph2.Advance.Y.Value - }; - - Label._characters[con][l].Add(temp2, cha2); - return t; - } - catch (Exception ex) - { - Console.WriteLine("may never happen"); - Console.WriteLine(ex); - } - } - if (!Label._characters[con].ContainsKey(l)) Label._characters[con].Add(l, new Dictionary()); - if (Label._characters[con][l].ContainsKey(charter)) return Label._characters[con][l][(ushort)charter].Texture; - l.CurrentFont.Fonts[last].SetPixelSizes(0, l.PixelHeight); + } - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - - GL.ActiveTexture(TextureUnit.Texture0); - l.CurrentFont.Fonts[last].SelectCharmap(Encoding.Unicode); - ushort temp = ((ushort)charter); - l.CurrentFont.Fonts[last].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal); - GlyphSlot glyph = l.CurrentFont.Fonts[0].Glyph; - FTBitmap bitmap = glyph.Bitmap; - if (t is null) t = new(); - else return t; - t.handel = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, t.handel); - GL.TexImage2D(TextureTarget.Texture2D, 0, - PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0, - PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer); - GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - - Character cha = new() + if (!BadChars.ContainsKey(l)) { - Size = new Vector2(bitmap.Width, bitmap.Rows), - Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop), - Advance = (int)glyph.Advance.X.Value, - Texture = t, - AdvanceY = glyph.Advance.Y.Value - }; - - Label._characters[con][l].Add(temp, cha); - } - - return t; + BadChars.Add(l, TextureManager.TextureManagers[con].AddTexture(Tools.GetResourceStream("GraphicsManager.Resources.Textures.BadChar.png"))); + Label._characters[con][l].Add(temp, new() + { + Size = Label._characters[con][l].First().Value.Size, + Bearing = Label._characters[con][l].First().Value.Bearing, + Advance = Label._characters[con][l].First().Value.Advance, + Texture = BadChars[l], + AdvanceY = Label._characters[con][l].First().Value.AdvanceY + }); + if (TextureManager.TextureManagers[con].Window.ShowMissingChar) + Console.WriteLine($"Missing font for '{charter}:{(uint)charter}' in Family {l.Families[0].Family}"); + } + + return BadChars[l]; } catch (Exception e) { diff --git a/GraphicsManager/Objects/Core/TextureManager.cs b/GraphicsManager/Objects/Core/TextureManager.cs index 14f785a..61cc412 100644 --- a/GraphicsManager/Objects/Core/TextureManager.cs +++ b/GraphicsManager/Objects/Core/TextureManager.cs @@ -1,5 +1,7 @@ +using System.Runtime.CompilerServices; using System.Runtime.Intrinsics.Arm; using System.Security.Cryptography; +using GraphicsManager.Interfaces; using GraphicsManager.Structs; using OpenTK.Windowing.Desktop; @@ -10,13 +12,15 @@ public class TextureManager public static readonly Dictionary TextureManagers = new(); private List _textures = new(); + public IWindow Window { get; private set; } - public static TextureManager GetTextureManager(IGLFWGraphicsContext context) + public static TextureManager GetTextureManager(IGLFWGraphicsContext context, IWindow win) { if (context is null) throw new ArgumentNullException(nameof(context)); if (!TextureManagers.ContainsKey(context)) { TextureManager tmp = new(context); + tmp.Window = win; TextureManagers.Add(context, tmp); return tmp; } diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs index b9a6cf9..85e6043 100644 --- a/GraphicsManager/Objects/FlowLayout.cs +++ b/GraphicsManager/Objects/FlowLayout.cs @@ -1,3 +1,4 @@ +using System.Security.Cryptography; using System.Timers; using GraphicsManager.Enums; using GraphicsManager.Interfaces; @@ -9,21 +10,40 @@ using Timer = System.Timers.Timer; namespace GraphicsManager.Objects; -public class FlowLayout : ParentBase +public class FlowLayout : ParentBase, IFlow { public FlowLayout(Texture? texture = null) :base(texture) { AllowHoverFromBehind = true; - t = new(33); + t = new(50); t.Enabled = true; t.Elapsed += TOnElapsed; - t.Start(); Controls.ControlAdded += ControlsOnControlAdded; Controls.ControlRemoved += ControlsOnControlRemoved; } + + public int SpaceBetweenObjects { get; set; } = 0; - public void ScrollToControl(IRenderObject Control) + public void ForceScrollUpdate() + { + ScrollSum = 0; + for (int i = 0; i < Controls.Length; i++) + { + ScrollSum += (uint)Controls[i].Size.Y + (uint)SpaceBetweenObjects; + } + + ScrollSum -= (uint)SpaceBetweenObjects; + } + + public double ScrollUpdatesInterval + { + get => t.Interval; + set => t.Interval = value; + } + + [Obsolete("Not Working", true)] + 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; @@ -34,6 +54,7 @@ public class FlowLayout : ParentBase if ((Control.Location.Y + Control.Size.Y) >= Size.Y) loc = Size.Y - Control.Size.Y; int start = loc + Control.Size.Y; BlockDraw = true; + bool top = false; if (startbottom) { for (int i = index + 1; i < Controls.Length; i++) @@ -60,12 +81,20 @@ public class FlowLayout : ParentBase } } + uint c = ScrollSum; 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; } + + c -= (uint)Controls[i].Size.Y; + if (!top && Controls[i].Location.Y <= 0) + { + top = true; + ScrollValueBackEnd = c - (uint)Controls[i].Location.Y; + } } BlockDraw = false; if (Parent is not null) Parent.TryDraw(); @@ -73,52 +102,57 @@ public class FlowLayout : ParentBase public void ScrollToTop() { - if (Controls.Length < 1) return; - ScrollToControl(Controls[0]); + ScrollValue = 0; } public void ScrollToBottom() { - if (Controls.Length < 1) return; - ScrollToControl(Controls[Controls.Length - 1]); + ScrollValue = MaxScrollValue; } public override void ReportSizeUpdate(IRenderObject Control) { - if (BlockDraw) return; BlockDraw = true; - bool notfount = true; - for (int i = 0; i < Controls.Length; i++) + int index = Controls.IndexOf(Control); + if (index < Controls.Length - 1) { - if (Controls[i] != Control && notfount) continue; - else + int dif = Control.Location.Y + Control.Size.Y - Controls[index + 1].Location.Y; + Vector3i v3i = new(0, dif, 0); + for (int i = index + 1; i < Controls.Length; i++) { - if (notfount) - { - notfount = false; - continue; - } - - Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y, Controls[i].Location.Z); + Controls[i].Location += v3i; } } - + else + { + ForceScrollUpdate(); + } BlockDraw = false; } private Task ControlsOnControlRemoved() { + ScrollSum = 0; if (Controls.Length < 1) return Task.CompletedTask; if (Controls[0].Location.Y > 0) Controls[0].Location = new(0); + bool top = false; for (int i = 1; i < Controls.Length; i++) { Controls[i].Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y, Controls[i].Location.Z); + if (Controls[i].Location.Y >= 0 && !top) + { + top = true; + ScrollValueBackEnd = ScrollSum - (uint)Controls[i].Location.Y; + } + ScrollSum += (uint)Controls[i].Size.Y; } + return Task.CompletedTask; } private Task ControlsOnControlAdded(int index, IRenderObject arg) { + ScrollSum += (uint)arg.Size.Y; if (Controls.Length > 0) { if (index < Controls.Length) @@ -130,7 +164,7 @@ public class FlowLayout : ParentBase Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y, arg.Location.Z); } } - else arg.Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y, arg.Location.Z); + else arg.Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y + SpaceBetweenObjects, arg.Location.Z); } else arg.Location = new(0); if (arg is IParent par2) @@ -143,7 +177,7 @@ public class FlowLayout : ParentBase } } - arg.Size = new(Size.X, arg.Size.Y); + if (arg is not ILabel) arg.Size = new(Size.X, arg.Size.Y); if (arg is IParent par) { for (int i = 0; i < par.Controls.Length; i++) @@ -162,7 +196,7 @@ public class FlowLayout : ParentBase par.Controls[i].Location = new(lx, ly, par.Controls[i].Location.Z); } } - arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top; + if (arg is not ILabel) arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top; return Task.CompletedTask; } @@ -172,7 +206,7 @@ public class FlowLayout : ParentBase set { BlockDraw = true; - base.Size = value; + base.Size = value; for (int i = 0; i < Controls.Length; i++) { Controls[i].Size = new(value.X, Controls[i].Size.Y); @@ -192,7 +226,6 @@ public class FlowLayout : ParentBase } Timer t; - private Queue scrols = new(); private int dist = 0; private void WindowOnMouseWheel(MouseWheelEventArgs obj) @@ -200,16 +233,8 @@ public class FlowLayout : ParentBase try { if (!MouseInside) return; - BlockDraw = true; - dist += (int)obj.OffsetY; - if (scrols.Any()) - { - for (int i = 0; i < scrols.Count; i++) - { - scrols.Dequeue().Invoke(); - } - - } + dist += (int)(obj.OffsetY * HScrollPixels); + if (!t.Enabled) t.Start(); } catch (Exception e) { @@ -219,113 +244,74 @@ public class FlowLayout : ParentBase } public uint HScrollPixels { get; set; } = 30; + + private uint ScrollValueBackEnd { get; set; } = 0; + + public event Func? FlowUpdate; + + public uint ScrollValue + { + get => ScrollValueBackEnd; + set + { + if (FlowUpdate is not null) FlowUpdate.Invoke(true, ScrollValueBackEnd, value); + if (!Loaded || value > MaxScrollValue || value == ScrollValueBackEnd) + { + dist = 0; + return; + } + BlockDraw = true; + Vector3i v3i = new(0, (int)(value - ScrollValueBackEnd), 0); + for (int i = 0; i < Controls.Length; i++) + { + Controls[i].Location -= v3i; + } + + BlockDraw = false; + if (Parent is not null) Parent.TryDraw(); + dist = 0; + ScrollValueBackEnd = value; + } + } + + public uint MaxScrollValue + { + get + { + if (ScrollSum > Size.Y) return (uint)(ScrollSum - Size.Y); + return 0; + } + } + + private uint ss = 0; + + public uint ScrollSum + { + get => ss; + private set + { + ss = value; + } + } + private bool scroleip = false; private void TOnElapsed(object? sender, ElapsedEventArgs e) { try { - if (BlockDraw) + if (!scroleip && dist != 0) { - scrols.Enqueue(new Action(() => - { - BlockDraw = true; - int current = dist; - dist = 0; - if (Controls.Length < 1) return; - bool down = current < 0;//scrole wheel dir - bool moved = false; - 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++) - { - 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, Controls[i].Location.Z); - 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].Visible || (Controls[0].Visible && Controls[0].Location.Y < 0))) // put chat down - { - moved = true; - int found = -1; - int lfound = -1; - for (int i = Controls.Length - 1; i >= 0; i--) - { - 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, Controls[i].Location.Z); - - 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; - } - } - - if (moved) - { - Parent!.TryDraw(); - } - - })); + scroleip = true; + var n = ScrollValue - dist; + if (n < 0) n = 0; + if (n > MaxScrollValue) n = MaxScrollValue; + Window!.Invoke(() =>ScrollValue = (uint)n); + scroleip = false; + } + else + { + scroleip = false; + t.Stop(); } - - BlockDraw = false; } catch (Exception exception) { diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs index 0c3d53d..aae8ec1 100755 --- a/GraphicsManager/Objects/Label.cs +++ b/GraphicsManager/Objects/Label.cs @@ -28,7 +28,7 @@ public class Label : ILabel Font = interaction; } - public ContextMenu? ContextMenu { get; set; } = null; + 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(); @@ -94,7 +94,7 @@ public class Label : ILabel addy += Font.ExtraLinePixels; continue; } - Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight); + 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; @@ -128,7 +128,7 @@ public class Label : ILabel line++; continue; } - Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight); + 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); @@ -154,14 +154,19 @@ public class Label : ILabel try { Window.Context.MakeCurrent(); + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + } catch (Exception e) { Console.WriteLine(e); } } - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - Parent!.TryDraw(); + + if (Window.Context.IsCurrent) + { + Parent!.TryDraw(); + } } } } @@ -245,7 +250,7 @@ public class Label : ILabel float char_x = 0.0f; GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.ActiveTexture(TextureUnit.Texture0); + GL.ActiveTexture(TextureUnit.Texture9); float hhh = 0f; for (int i = 0; i < Text.Length; i++) @@ -297,6 +302,7 @@ public class Label : ILabel 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(); @@ -362,15 +368,16 @@ public class Label : ILabel Loaded = true; Text = Text; Location = Location; - 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 (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) ContextMenu.ShowContext(Window!); - if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!); + 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; diff --git a/GraphicsManager/Objects/RainbowLabel.cs b/GraphicsManager/Objects/RainbowLabel.cs index 2bb8acf..a51fd6b 100755 --- a/GraphicsManager/Objects/RainbowLabel.cs +++ b/GraphicsManager/Objects/RainbowLabel.cs @@ -25,7 +25,7 @@ public class RainbowLabel : ILabel Font = interaction; } - public ContextMenu? ContextMenu { get; set; } = null; + 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(); @@ -90,7 +90,7 @@ public class RainbowLabel : ILabel addy += Font.ExtraLinePixels; continue; } - Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight); + 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; @@ -124,7 +124,7 @@ public class RainbowLabel : ILabel line++; continue; } - Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight); + 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); @@ -241,7 +241,7 @@ public class RainbowLabel : ILabel float char_x = 0.0f; GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - GL.ActiveTexture(TextureUnit.Texture0); + GL.ActiveTexture(TextureUnit.Texture9); float hhh = 0f; for (int i = 0; i < Text.Length; i++) @@ -443,8 +443,8 @@ public class RainbowLabel : ILabel 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) ContextMenu.ShowContext(Window!); - if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!); + 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; diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs index 93b62fc..2c3d57c 100755 --- a/GraphicsManager/Objects/Rectangle.cs +++ b/GraphicsManager/Objects/Rectangle.cs @@ -48,7 +48,7 @@ public class Rectangle : ITextureObject } public List Textures { get; set; } = new(); - public ContextMenu? ContextMenu { get; set; } = null; + public BetterContextMenu? ContextMenu { get; set; } = null; public event Func? FilesDroped; public Rectangle(Texture? texture) @@ -70,7 +70,7 @@ public class Rectangle : ITextureObject private Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255); - public Color4 BackgroundColor + public virtual Color4 BackgroundColor { get => _BackgroundColor; set @@ -96,7 +96,7 @@ public class Rectangle : ITextureObject public virtual void Draw(int x, int y, int w, int h) { - if (Visible && Loaded) + 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(); @@ -237,8 +237,8 @@ public class Rectangle : ITextureObject private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e) { 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 && e.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!); + if (e.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!); } ~Rectangle() @@ -265,6 +265,7 @@ public class Rectangle : ITextureObject { if (Loaded) { + GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); GL.BindVertexArray(ArrayObject); int add = 3; @@ -315,6 +316,8 @@ public class Rectangle : ITextureObject if (Textures.Count == 0) return; TextureDisplay old = td; td = value; + float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; + float diff = 0; switch (old) { default: @@ -330,8 +333,7 @@ public class Rectangle : ITextureObject }; break; case TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter or TextureDisplay.TextureHorizontalCenter: - float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; - float diff = 0; + if (Window is not null) { diff = Window.IntToFloat(Size.Y) + 1; @@ -342,14 +344,14 @@ public class Rectangle : ITextureObject } Points = new float[] { - saf.X, laf.Y, 0, Textures[0].MaxText.X, Textures[0].MaxText.Y, - saf.X, saf.Y, 0, Textures[0].MaxText.X, 0, - laf.X, saf.Y, 0, 0, 0, - laf.X, laf.Y, 0, 0, Textures[0].MaxText.Y, - saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y, - saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0, - laf.X + diff, saf.Y, 0, per, 0, - laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y, + saf.X, laf.Y, 0, Textures[0].MaxText.X, Textures[0].MaxText.Y, //4 + saf.X, saf.Y, 0, Textures[0].MaxText.X, 0, //9 + laf.X, saf.Y, 0, 0, 0, //14 + laf.X, laf.Y, 0, 0, Textures[0].MaxText.Y, //19 + saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y, //24 + saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0, //29 + laf.X + diff, saf.Y, 0, per, 0, //34 + laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y, //39 }; Indexs = new ushort[] { @@ -361,6 +363,58 @@ public class Rectangle : ITextureObject 2, 3, 6 }; break; + + case TextureDisplay.Center: + per = (float)Textures[0].RawSize!.Value.X / 3;; + diff = 0; + if (Window is not null) + { + if (Size.X > Textures[0].RawSize!.Value.X) + diff = (Window.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3; + else + diff = (Window.IntToFloat(Size.X) + 1) / 3; + } + Points = new float[] + { + saf.X, laf.Y, 0, Textures[0].MaxText.X, Textures[0].MaxText.Y, //4 + saf.X, saf.Y, 0, Textures[0].MaxText.X, 0, //9 + laf.X, saf.Y, 0, 0, 0, //14 + laf.X, laf.Y, 0, 0, Textures[0].MaxText.Y, //19 + saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y, //24 + saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0, //29 + laf.X + diff, saf.Y, 0, per, 0, //34 + laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y, //39 + saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y, //24 + saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0, //29 + laf.X + diff, saf.Y, 0, per, 0, //34 + laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y, //39 + saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y, //24 + saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0, //29 + laf.X + diff, saf.Y, 0, per, 0, //34 + laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y, //39 + }; + Indexs = new ushort[] + { + 0, 4, 11, + 4, 11, 12, + 4, 5, 12, + 5, 12, 13, + 1, 5, 6, + 5, 6, 13, + 10, 11, 12, + 10, 12, 15, + 12, 13, 14, + 12, 14, 15, + 6, 7, 13, + 7, 13, 14, + 3, 9, 10, + 9, 10, 15, + 8, 9, 14, + 9, 14, 15, + 2, 7, 8, + 7, 8, 14, + }; + break; } break; } @@ -368,6 +422,15 @@ public class Rectangle : ITextureObject } } + private static void SetPoint(float[] temp, int start, float X, float Y, float Z, float Tx, float Ty) + { + temp[start] = X; + temp[start + 1] = Y; + temp[start + 2] = Z; + temp[start + 3] = Tx; + temp[start + 4] = Ty; + } + public virtual Vector2i Size { get @@ -385,8 +448,8 @@ public class Rectangle : ITextureObject : TextureDisplay switch { TextureDisplay.Clamped => new float[20], - TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter - or TextureDisplay.Center or TextureDisplay.TextureHorizontalCenter => new float[40], + TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter or TextureDisplay.TextureHorizontalCenter => new float[40], + TextureDisplay.Center => new float[80], _ => new float[20] }; saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true)); @@ -411,6 +474,15 @@ public class Rectangle : ITextureObject float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X; if (TextureDisplay == TextureDisplay.TextureHorizontalCenter) diff = Window.IntToFloat(Textures[0].RawSize!.Value.Y); + if (TextureDisplay == TextureDisplay.Center) + { + if (s.X > Textures[0].RawSize!.Value.X) + diff = (Window.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3; + else + diff = (Window.IntToFloat(s.X) + 1) / 3; + per = Textures[0].MaxText.X / 3; + } + switch (TextureDisplay) { case TextureDisplay.Clamped: @@ -448,6 +520,43 @@ public class Rectangle : ITextureObject 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 = (Window.IntToFloat(Window.Size.Y - dy, true) + 1) / 3; + diff = (Window.IntToFloat(dx) + 1) / 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) { @@ -551,7 +660,7 @@ public class Rectangle : ITextureObject Points = temp; } } - + public virtual Vector3i Location { get @@ -567,8 +676,8 @@ public class Rectangle : ITextureObject : TextureDisplay switch { TextureDisplay.Clamped => new float[20], - TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter - or TextureDisplay.Center => new float[40], + TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter => new float[40], + TextureDisplay.Center => new float[80], _ => new float[20] }; laf = new Vector2(Parent.IntToFloat(value.X, false), Parent.IntToFloat(value.Y, true)); @@ -591,6 +700,14 @@ public class Rectangle : ITextureObject Vector2i s = Size; float diff = Window.IntToFloat(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.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3; + else + diff = (Window.IntToFloat(s.X) + 1) / 3; + per = Textures[0].MaxText.X / 3; + } switch (TextureDisplay) { case TextureDisplay.Clamped: @@ -628,6 +745,41 @@ public class Rectangle : ITextureObject 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 = (Window.IntToFloat(Window.Size.Y - dy, true) + 1) / 3; + diff = (Window.IntToFloat(dx) + 1) / 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) { @@ -727,9 +879,7 @@ public class Rectangle : ITextureObject break; } } - Points = temp; - } } diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs index b7601de..5c5be76 100644 --- a/GraphicsManager/Objects/TabControl.cs +++ b/GraphicsManager/Objects/TabControl.cs @@ -34,7 +34,7 @@ public class TabControl : ParentBase, IParent locc = Buttonts[loc - 1].Location.X; loccc = Buttonts[loc - 1].Size.X; } - Buttonts.Add(tmp = new RoundedButton(t, TitleFont.Family) + Buttonts.Add(tmp = new RoundedButton(t, TitleFont) { Location = new(locc+ loccc + (TabSpace * (int)loc) + Border, Border, Location.Z), Text = Title, diff --git a/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag index ba4c6ee..79d2db5 100755 --- a/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag +++ b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag @@ -1,14 +1,14 @@ -#version 460 +#version 330 out vec4 outputColor; in vec2 texCoord; -layout(binding = 0) uniform sampler2D texture1; -layout(binding = 1) uniform sampler2D texture2; +uniform sampler2D bob; +uniform sampler2D smith; void main(void) { - float obj = texture(texture1, texCoord).r; - vec4 text = texture(texture2, texCoord); + float obj = texture(bob, texCoord).r; + vec4 text = texture(smith, texCoord); outputColor = vec4(text.r, text.g, text.b, text.a*obj); } \ No newline at end of file diff --git a/GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert index d5a61d1..013d06b 100755 --- a/GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert +++ b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert @@ -1,4 +1,4 @@ -#version 460 +#version 330 layout(location = 0) in vec3 aPosition; layout(location = 1) in vec2 aTexCoord; out vec2 texCoord; diff --git a/GraphicsManager/Resources/Shaders/Label.frag b/GraphicsManager/Resources/Shaders/Label.frag index b348052..6c28bfa 100755 --- a/GraphicsManager/Resources/Shaders/Label.frag +++ b/GraphicsManager/Resources/Shaders/Label.frag @@ -1,10 +1,10 @@ -#version 460 +#version 330 in vec2 vUV; -layout (binding=0) uniform sampler2D u_texture; +uniform sampler2D u_texture; -layout (location = 2) uniform vec4 textColor; +uniform vec4 textColor; out vec4 fragColor; @@ -12,5 +12,5 @@ void main() { vec2 uv = vUV.xy; float text = texture(u_texture, uv).r; - fragColor = vec4(textColor.rgba*text); + fragColor = vec4(textColor.r*text, textColor.g*text, textColor.b*text, textColor.a*text); } \ No newline at end of file diff --git a/GraphicsManager/Resources/Shaders/Label.vert b/GraphicsManager/Resources/Shaders/Label.vert index d2ab3c8..af30ccc 100755 --- a/GraphicsManager/Resources/Shaders/Label.vert +++ b/GraphicsManager/Resources/Shaders/Label.vert @@ -1,12 +1,12 @@ -#version 460 +#version 330 -layout (location = 0) in vec2 in_pos; -layout (location = 1) in vec2 in_uv; +in vec2 in_pos; +in vec2 in_uv; out vec2 vUV; -layout (location = 0) uniform mat4 model; -layout (location = 1) uniform mat4 projection; +uniform mat4 model; +uniform mat4 projection; void main() { diff --git a/GraphicsManager/Structs/Character.cs b/GraphicsManager/Structs/Character.cs index 1312d4c..2af5935 100755 --- a/GraphicsManager/Structs/Character.cs +++ b/GraphicsManager/Structs/Character.cs @@ -7,6 +7,7 @@ public struct Character { public Texture Texture { get; set; } public Vector2 Size { get; set; } + public bool Bad { get; set; } public Vector2 Bearing { get; set; } public int Advance { get; set; } public double AdvanceY { get; set; } diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs index adeecc5..42cee06 100755 --- a/GraphicsManager/Window.cs +++ b/GraphicsManager/Window.cs @@ -26,6 +26,8 @@ public class Window : NativeWindow , IWindow //some setting/changeing code } } + + public bool ShowMissingChar { get; set; } public IRenderObject? focused { get; set; } public void CenterWindow(int mon) @@ -45,20 +47,32 @@ public class Window : NativeWindow , IWindow ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y); } - - public ContextMenu? ActiveMenu { get; set; } = null; public IParent? Parent { get; } = null; public MouseCursor HoverMouse { get; set; } = MouseCursor.Default; public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f); + public bool LogFrames { get; set; } = true; public Window(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings) { - TextureManager = TextureManager.GetTextureManager(Context); + TextureManager = TextureManager.GetTextureManager(Context, this); Context.MakeCurrent(); if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true, Texture:true)); if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); if (!Rectangle.DefaultAlphaShader.ContainsKey(Context)) Rectangle.DefaultAlphaShader.Add(Context, new("AlphaChannel", true, Texture:true)); - if (!Rectangle.DefaultAlphaTextureShader.ContainsKey(Context)) Rectangle.DefaultAlphaTextureShader.Add(Context, new("AlphaChannelTexture", true, Texture:true)); - if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true)); + if (!Rectangle.DefaultAlphaTextureShader.ContainsKey(Context)) + { + Rectangle.DefaultAlphaTextureShader.Add(Context, new("AlphaChannelTexture", true, Texture:true)); + Rectangle.DefaultAlphaTextureShader[Context].Use(); + Rectangle.DefaultAlphaTextureShader[Context].SetInt("bob", 0); + Rectangle.DefaultAlphaTextureShader[Context].SetInt("smith", 1); + } + + if (!Label.DefaultTextShader.ContainsKey(Context)) + { + Label.DefaultTextShader.Add(Context, new("Label", true)); + Label.DefaultTextShader[Context].Use(); + Label.DefaultTextShader[Context].SetInt("u_texture", 9); + Label.DefaultTextShader[Context].SetInt("textColor", 2); + } if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new()); last = WindowState; KeyDown += OnKeyDownn; @@ -403,13 +417,13 @@ public class Window : NativeWindow , IWindow { Context.MakeCurrent(); frame++; - Console.WriteLine($"Drawing Frame: {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 * -1) + 1); + GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, BackgroundColor.A); IEnumerable needload = Controls.Where(a => a.Loaded == false); if (needload.Any()) @@ -421,8 +435,8 @@ public class Window : NativeWindow , IWindow } BlockDraw = false; } - - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + GL.Scissor(0,0,Size.X, Size.Y); + GL.Clear(ClearBufferMask.ColorBufferBit); for (int i = 0; i < Controls.Length; i++) { if (!Controls[i].Loaded) continue;