diff --git a/GraphicsManager/Enums/FontSize.cs b/GraphicsManager/Enums/FontSize.cs
new file mode 100644
index 0000000..5bb8f3a
--- /dev/null
+++ b/GraphicsManager/Enums/FontSize.cs
@@ -0,0 +1,14 @@
+namespace GraphicsManager.Enums;
+
+public enum FontSize : byte
+{
+ Thin,
+ ExtraLight,
+ Light,
+ Regular,
+ Medium,
+ SemiBold,
+ Bold,
+ ExtraBold,
+ Black,
+}
\ No newline at end of file
diff --git a/GraphicsManager/Enums/TextLocation.cs b/GraphicsManager/Enums/TextLocation.cs
new file mode 100644
index 0000000..1d51044
--- /dev/null
+++ b/GraphicsManager/Enums/TextLocation.cs
@@ -0,0 +1,9 @@
+namespace GraphicsManager.Enums;
+
+public enum TextLocation
+{
+ TopLeft,
+ PxLeft,
+ TrueCenterLeft,
+ PostiveTureCenterLeft
+}
\ No newline at end of file
diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj
index efd6e32..749a9bd 100644
--- a/GraphicsManager/GraphicsManager.csproj
+++ b/GraphicsManager/GraphicsManager.csproj
@@ -10,7 +10,7 @@
False
https://git.jacobtech.com/JacobTech.com/GraphicsManager
git
- 1.0.5-alpha08
+ 1.0.6-alpha89
@@ -39,6 +39,7 @@
+
diff --git a/GraphicsManager/Interfaces/ILabel.cs b/GraphicsManager/Interfaces/ILabel.cs
new file mode 100644
index 0000000..e548576
--- /dev/null
+++ b/GraphicsManager/Interfaces/ILabel.cs
@@ -0,0 +1,6 @@
+namespace GraphicsManager.Interfaces;
+
+public interface ILabel : IRenderObject
+{
+
+}
\ No newline at end of file
diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs
index f447683..f350a99 100755
--- a/GraphicsManager/Interfaces/IParent.cs
+++ b/GraphicsManager/Interfaces/IParent.cs
@@ -1,14 +1,16 @@
-using OpenTK.Mathematics;
+using GraphicsManager.Objects.Core;
+using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
namespace GraphicsManager.Interfaces;
public interface IParent
{
public Vector2 LocationAsFloat { get; }
+ public ControlList Controls { get; }
public IParent? Parent { get; }
public Vector2i Size { get; }
- public Vector2i GetParentRelLocPoint();
public void ParentResize(ResizeEventArgs e);
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f);
public Vector3 PointToVector(float x, float y, float z = 0.0f);
@@ -17,4 +19,5 @@ public interface IParent
public void ReportSizeUpdate(IRenderObject Control);
public float FloatToInt(float p, bool Invert = false);
public Vector2i Position { get; }
+ public MouseCursor HoverMouse { get; set; }
}
diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs
index ab8dfb1..e7957a5 100755
--- a/GraphicsManager/Interfaces/IRenderObject.cs
+++ b/GraphicsManager/Interfaces/IRenderObject.cs
@@ -1,15 +1,19 @@
using GraphicsManager.Enums;
using OpenTK.Mathematics;
+using OpenTK.Windowing.Common.Input;
namespace GraphicsManager.Interfaces;
public interface IRenderObject
{
+ public void ForceDistanceUpdate();
+ public void ForceDistanceUpdate(IParent parent);
public ContextMenu? ContextMenu { get; set; }
public ObjectAnchor Anchor { get; set; }
public bool Loaded { get; }
public void LoadToParent(IParent Parent, Window Window);
public void Draw(int x, int y, int w, int h);
+ public MouseCursor HoverMouse { get; set; }
public void Clean();
public void Focus();
public void UnFocus();
@@ -17,8 +21,7 @@ public interface IRenderObject
public Vector2i Location { get; set; }
public Vector2 SizeAsFloat { get; }
public Vector2 LocationAsFloat { get; }
- public Vector2i ScissorLocation { get; }
- public Vector2i Distance { get; }
+ public Vector2i Distance { get; set; }
public IParent? Parent { get; }
public Window? Window { get; }
public bool Visible { get; set; }
diff --git a/GraphicsManager/Interfaces/ITextureObject.cs b/GraphicsManager/Interfaces/ITextureObject.cs
index 4fb3848..6e72de8 100755
--- a/GraphicsManager/Interfaces/ITextureObject.cs
+++ b/GraphicsManager/Interfaces/ITextureObject.cs
@@ -9,5 +9,5 @@ namespace GraphicsManager.Interfaces;
public interface ITextureObject : IRenderObject
{
- public Texture? Texture { get; }
+ public List Textures { get; }
}
diff --git a/GraphicsManager/Objects/Core/ControlList.cs b/GraphicsManager/Objects/Core/ControlList.cs
index ac87a53..420f3cd 100644
--- a/GraphicsManager/Objects/Core/ControlList.cs
+++ b/GraphicsManager/Objects/Core/ControlList.cs
@@ -4,7 +4,7 @@ namespace GraphicsManager.Objects.Core;
public class ControlList
{
- private List _internal = new();
+ internal List _internal = new();
private bool Clearing = false;
public IRenderObject this[int Index] => _internal[Index];
@@ -21,11 +21,14 @@ public class ControlList
internal event Func? ControlAdded;
internal event Func? ControlRemoved;
- public void Remove(IRenderObject item)
+ public void Remove(IRenderObject item, bool purge = true)
{
_internal.Remove(item);
- item.Clean();
- item = null!;
+ if (purge)
+ {
+ item.Clean();
+ item = null!;
+ }
GC.Collect();
if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke();
}
@@ -36,13 +39,16 @@ public class ControlList
_internal.Add(item);
}
- public void Clear()
+ public void Clear(bool purge = true)
{
Clearing = true;
for (int i = 0; i< _internal.Count; i++)
{
- _internal[i].Clean();
- _internal[i] = null!;
+ if (purge)
+ {
+ _internal[i].Clean();
+ _internal[i] = null!;
+ }
}
_internal.Clear();
GC.Collect();
diff --git a/GraphicsManager/Objects/Core/Font.cs b/GraphicsManager/Objects/Core/Font.cs
index 62beb56..ac4ece6 100755
--- a/GraphicsManager/Objects/Core/Font.cs
+++ b/GraphicsManager/Objects/Core/Font.cs
@@ -16,6 +16,7 @@ public class Font
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);
@@ -39,6 +40,8 @@ public class Font
}
}
+
+
private Font()
{
Name = null!;
@@ -50,7 +53,7 @@ public class Font
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)
+ if (_SystemPre is null && CanScanSystem)
{
_SystemPre = new();
if (OperatingSystem.IsLinux())
@@ -76,6 +79,9 @@ public class Font
}
catch
{
+ string folder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
+ _SystemPre = new();
+ Tools.AddFontsToList(ref _SystemPre, folder);
}
}
@@ -84,25 +90,8 @@ public class Font
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();
+ _SystemPre = new();
+ Tools.AddFontsToList(ref _SystemPre, folder);
}
catch
{
@@ -156,6 +145,7 @@ public class Font
//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())
@@ -165,7 +155,7 @@ public class Font
AllFonts.Add(f);
}
return Caches.Where(s => s.PixelHeight == PixelHeight).First();
- }
+ }*/
public static Font MakeFontFromFile(string Font)
{
_ = Font ?? throw new ArgumentNullException(nameof(Font));
@@ -193,7 +183,8 @@ public class Font
}
private bool HasTopFont = false;
- public uint PixelHeight { get; set; } = 12;
+ //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
new file mode 100644
index 0000000..a26a4d8
--- /dev/null
+++ b/GraphicsManager/Objects/Core/FontFamily.cs
@@ -0,0 +1,136 @@
+using System.Diagnostics;
+using GraphicsManager.Enums;
+using SixLabors.Fonts;
+
+namespace GraphicsManager.Objects.Core;
+
+public class FontFamily
+{
+ private static uint index = 0;
+ public event Func? ReloadUI;
+ private FontSize fs = FontSize.Thin;
+ private uint ph = 12;
+ private bool i;
+ internal Dictionary> InternalFonts = new();
+ internal Dictionary> InternalFontsi = new();
+ internal Font Font = null!;
+
+
+
+ public static Task LoadFontFamily()
+ {
+ FontFamily f = new();
+ foreach (string font in Tools.GetFontList($"fc-list ':'family='{Tools.GetFamilyList("fc-list ':' family")[index]}' 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("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);
+ }
+ 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("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;
+ }
+
+ private FontFamily()
+ {
+ }
+}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/Core/FontInteraction.cs b/GraphicsManager/Objects/Core/FontInteraction.cs
new file mode 100644
index 0000000..335ec2c
--- /dev/null
+++ b/GraphicsManager/Objects/Core/FontInteraction.cs
@@ -0,0 +1,149 @@
+using GraphicsManager.Enums;
+
+namespace GraphicsManager.Objects.Core;
+
+public class FontInteraction
+{
+ public FontFamily Family { get; private set; }
+ public Font CurrentFont { get; private set; }
+ private FontSize fs = FontSize.Thin;
+ private uint ph = 12;
+ private bool i;
+ private uint epx = 0;
+ public event Func? ReloadUI;
+
+ public FontInteraction Clone()
+ {
+ return (FontInteraction)this.MemberwiseClone();
+ }
+
+ public static FontInteraction Load(FontFamily family)
+ {
+ FontInteraction c = new(family);
+ c.FontSize = FontSize.Regular;
+ return c;
+ }
+ private FontInteraction(FontFamily Family)
+ {
+ this.Family = Family;
+ }
+
+ public uint PixelHeight
+ {
+ get => ph;
+ set
+ {
+ ph = value;
+ if (ReloadUI is not null) ReloadUI.Invoke();
+ }
+ }
+
+ public uint ExtraLinePixels
+ {
+ get => epx;
+ set
+ {
+ epx = value;
+ if (ReloadUI is not null) ReloadUI.Invoke();
+ }
+ }
+
+ public bool Italic
+ {
+ get => i;
+ set
+ {
+ if (i != value)
+ {
+ if (value)
+ {
+ if (Family.InternalFontsi.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;
+ }
+ }
+
+ 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;
+ }
+ }
+ CurrentFont = Family.InternalFonts[fs].Item2!;
+ if (ReloadUI is not null) ReloadUI.Invoke();
+ }
+ }
+ //Font.PixelHeight = this.PixelHeight;
+ }
+ }
+ }
+
+ private static Tuple gcl(Dictionary> thisList, FontSize thisValue, out FontSize fs)
+ {
+ Dictionary>.KeyCollection keys = thisList.Keys;
+ FontSize nearest = thisValue -
+ keys.Where(k => k <= thisValue)
+ .Min(k => thisValue - k);
+ fs = nearest;
+ return thisList[nearest];
+ }
+
+ public FontSize FontSize
+ {
+ get => fs;
+ set
+ {
+ Tuple f = Italic switch
+ {
+ true => gcl(Family.InternalFontsi, value, out fs),
+ false => gcl(Family.InternalFonts, value, out fs),
+ };
+ 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;
+ }
+ }
+
+ CurrentFont = Italic switch
+ {
+ true => Family.InternalFontsi[fs].Item2!,
+ false => Family.InternalFonts[fs].Item2!,
+ };
+ //Font.PixelHeight = this.PixelHeight;
+
+ if (ReloadUI is not null) ReloadUI.Invoke();
+ }
+ }
+}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/Core/Shader.cs b/GraphicsManager/Objects/Core/Shader.cs
index 8d79551..1547a2a 100755
--- a/GraphicsManager/Objects/Core/Shader.cs
+++ b/GraphicsManager/Objects/Core/Shader.cs
@@ -48,8 +48,11 @@ public class Shader : IDisposable
GL.DeleteShader(VertexShader);
}
- public Shader(string ShaderSource, bool Embeded = false, Assembly? Assembly = null)
+ public bool ForTexture { get; private set; } = false;
+
+ public Shader(string ShaderSource, bool Embeded = false, Assembly? Assembly = null, bool Texture = false)
{
+ ForTexture = Texture;
VertexShader = GL.CreateShader(ShaderType.VertexShader);
string Base = "GraphicsManager.Resources.Shaders.";
if (Assembly is not null) Base = string.Empty;
@@ -93,6 +96,12 @@ public class Shader : IDisposable
{
return GL.GetAttribLocation(Handle, attribName);
}
+
+ public int GetUniformLocation(string attribName)
+ {
+ return GL.GetUniformLocation(Handle, attribName);
+ }
+
public void SetInt(string name, int value)
{
diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs
index 4f2fd0f..2fc1a99 100755
--- a/GraphicsManager/Objects/Core/Texture.cs
+++ b/GraphicsManager/Objects/Core/Texture.cs
@@ -1,10 +1,16 @@
-using GraphicsManager.Globals;
-using GraphicsManager.Structs;
-using OpenTK.Graphics.ES30;
+using GraphicsManager.Structs;
using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop;
using SharpFont;
using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Formats.Bmp;
+using SixLabors.ImageSharp.Formats.Gif;
+using SixLabors.ImageSharp.Formats.Jpeg;
+using SixLabors.ImageSharp.Formats.Pbm;
+using SixLabors.ImageSharp.Formats.Png;
+using SixLabors.ImageSharp.Formats.Tga;
+using SixLabors.ImageSharp.Formats.Tiff;
+using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using GL = OpenTK.Graphics.OpenGL4.GL;
@@ -19,7 +25,6 @@ using TextureParameterName = OpenTK.Graphics.OpenGL4.TextureParameterName;
using TextureTarget = OpenTK.Graphics.OpenGL4.TextureTarget;
using TextureUnit = OpenTK.Graphics.OpenGL4.TextureUnit;
using TextureWrapMode = OpenTK.Graphics.OpenGL4.TextureWrapMode;
-using VertexAttribPointerType = OpenTK.Graphics.OpenGL4.VertexAttribPointerType;
namespace GraphicsManager.Objects.Core;
@@ -27,51 +32,125 @@ public class Texture
{
public static readonly Dictionary TextureShader = new ();
- public int handel;
- public int Location { get; set; } = 1;
-
- internal Texture(byte[] File, bool Rounded = false)
+ private static Configuration imgcfg = new(
+ new PngConfigurationModule(),
+ new JpegConfigurationModule(),
+ new GifConfigurationModule(),
+ new BmpConfigurationModule(),
+ new PbmConfigurationModule(),
+ new TgaConfigurationModule(),
+ new TiffConfigurationModule(),
+ new WebpConfigurationModule())
{
- Image image = Image.Load(File);
- if (Rounded)
- {
- image.Mutate(x =>
- {
- x.Flip(FlipMode.Vertical);
- if (image.Width <= image.Height) x.ConvertToAvatar(image.Width, image.Width/2);
- else x.ConvertToAvatar(image.Height, image.Height/2);
- });
- }
- else
- {
- image.Mutate(x =>
- {
- x.Flip(FlipMode.Vertical);
- });
- }
-
+ PreferContiguousImageBuffers = true
+ };
- Span pixels = new byte[4 * image.Width * image.Height].AsSpan();
- image.CopyPixelDataTo(pixels);
+ public int handel;
+ public Vector2i? RawSize = null;
+ public int Location { get; set; } = 1;
+
+ private Texture(byte[] pixels, int Width, int Height)
+ {
handel = GL.GenTexture();
+ RawSize = new(Width, Height);
GL.BindTexture(TextureTarget.Texture2D, handel);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels.ToArray());
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
}
+
+ private Texture(Image image, Memory m)
+ {
+ handel = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, handel);
+ RawSize = new(image.Width, image.Height);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, ref m.Span[0]);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
+ }
+
+
+ internal static Texture GetTexture(Stream File)
+ {
+ try
+ {
+ Image image = Image.Load(imgcfg, File);
+ image.Mutate(x =>
+ {
+ x.Flip(FlipMode.Vertical);
+ });
+ byte[] pixels = new byte[4 * image.Width * image.Height];
+ image.CopyPixelDataTo(pixels);
+ Texture t = new(pixels, image.Width, image.Height);
+ pixels = Array.Empty();
+ image.Dispose();
+ return t;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+
+ internal static Texture GetTexture(Stream File, TextureManager tm, bool Missing)
+ {
+ try
+ {
+ Image image = Image.Load(imgcfg, File);
+ image.Mutate(x =>
+ {
+ x.Flip(FlipMode.Vertical);
+ });
+ File.Position = 0;
+ Texture? t;
+ if (image.DangerousTryGetSinglePixelMemory(out Memory m))
+ {
+ t = new(image, m);
+ image.Dispose();
+ m = null;
+ }
+ else
+ {
+ _ = image.DangerousTryGetSinglePixelMemory(out Memory mm);
+ if (Missing)
+ {
+ File.Position = 0;
+ Console.WriteLine("Getting texture from stream failed, switching to Missing.png.");
+ image.Dispose();
+ t = GetTexture(Tools.GetResourceStream("GraphicsManager.Resources.Textures.Missing.png"), tm, false);
+ }
+ else
+ {
+ File.Position = 0;
+ Console.WriteLine("Getting texture from stream failed, switching to fallback.");
+ t = GetTexture(File);
+ }
+
+ }
+ return t;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
private Texture()
{
}
- internal static Character GetChar(Font l, char charter)
+ internal static Character GetChar(Font l, char charter, uint PH)
{
try
{
-
int last = 0;
for (int i = 0; i < l.Fonts.Count; i++)
@@ -80,17 +159,16 @@ public class Texture
{
try
{
- l.Fonts[i].SetPixelSizes(0, l.PixelHeight);
+ l.Fonts[i].SetPixelSizes(0, PH);
l.Fonts[i].SelectCharmap(Encoding.Unicode);
last = i;
}
- catch (Exception e)
+ catch
{
- Console.WriteLine($"no");
continue;
}
- ushort temp = ((ushort)charter);
+ 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;
@@ -101,12 +179,12 @@ public class Texture
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);
- continue;
}
}
List bad = new();
@@ -118,7 +196,7 @@ public class Texture
try
{
tmp = new(Font.lib, Font._SystemPre[i], 0);
- tmp.SetPixelSizes(0, l.PixelHeight);
+ tmp.SetPixelSizes(0, PH);
tmp.SelectCharmap(Encoding.Unicode);
}
catch (Exception e)
@@ -149,6 +227,7 @@ public class Texture
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)
@@ -168,7 +247,7 @@ public class Texture
{
Font._SystemPre.Remove(str);
}
- l.Fonts[last].SetPixelSizes(0, l.PixelHeight);
+ l.Fonts[last].SetPixelSizes(0, PH);
l.Fonts[last].SelectCharmap(Encoding.Unicode);
ushort temp22 = ((ushort)charter);
@@ -181,17 +260,17 @@ public class Texture
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)
};
}
catch (Exception e)
{
- Console.WriteLine(1);
Console.WriteLine(e);
throw;
}
}
- internal static Texture TextureForChar(IGLFWGraphicsContext con, Font l, char charter)
+ internal static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter)
{
try
{
@@ -200,7 +279,7 @@ public class Texture
Texture? t = null;
int last = 0;
- for (int i = 0; i < l.Fonts.Count; i++)
+ for (int i = 0; i < l.CurrentFont.Fonts.Count; i++)
{
try
{
@@ -208,7 +287,7 @@ public class Texture
if (Label._characters[con][l].ContainsKey(charter)) return Label._characters[con][l][(ushort)charter].Texture;
try
{
- l.Fonts[i].SetPixelSizes(0, l.PixelHeight);
+ l.CurrentFont.Fonts[i].SetPixelSizes(0, l.PixelHeight);
last = i;
}
catch (Exception e)
@@ -219,11 +298,11 @@ public class Texture
- l.Fonts[i].SelectCharmap(Encoding.Unicode);
+ l.CurrentFont.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);
- GlyphSlot glyph = l.Fonts[i].Glyph;
+ 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;
FTBitmap bitmap = glyph.Bitmap;
t = new();
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
@@ -244,6 +323,7 @@ public class Texture
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);
@@ -286,7 +366,7 @@ public class Texture
tmp.LoadChar(temp2, LoadFlags.Render, LoadTarget.Normal);
GlyphSlot glyph2 = tmp.Glyph;
FTBitmap bitmap2 = glyph2.Bitmap;
- l.AddSystemFontFace(Font._SystemPre[i]);
+ l.CurrentFont.AddSystemFontFace(Font._SystemPre[i]);
t = new();
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
@@ -306,6 +386,7 @@ public class Texture
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);
@@ -319,16 +400,16 @@ public class Texture
}
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.Fonts[last].SetPixelSizes(0, l.PixelHeight);
+ l.CurrentFont.Fonts[last].SetPixelSizes(0, l.PixelHeight);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
GL.ActiveTexture(TextureUnit.Texture0);
- l.Fonts[last].SelectCharmap(Encoding.Unicode);
+ l.CurrentFont.Fonts[last].SelectCharmap(Encoding.Unicode);
ushort temp = ((ushort)charter);
- l.Fonts[last].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
- GlyphSlot glyph = l.Fonts[0].Glyph;
+ 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;
@@ -348,6 +429,7 @@ public class Texture
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);
@@ -357,15 +439,21 @@ public class Texture
}
catch (Exception e)
{
- Console.WriteLine(2);
Console.WriteLine(e);
throw;
}
}
- public void Use(TextureUnit unit = TextureUnit.Texture0)
+ public Texture Clone()
{
- GL.ActiveTexture(unit);
+ return (Texture)MemberwiseClone();
+ }
+
+ public TextureUnit Unit = TextureUnit.Texture0;
+
+ public void Use()
+ {
+ GL.ActiveTexture(Unit);
GL.BindTexture(TextureTarget.Texture2D, handel);
}
}
diff --git a/GraphicsManager/Objects/Core/TextureManager.cs b/GraphicsManager/Objects/Core/TextureManager.cs
index 568ecd5..14f785a 100644
--- a/GraphicsManager/Objects/Core/TextureManager.cs
+++ b/GraphicsManager/Objects/Core/TextureManager.cs
@@ -9,7 +9,7 @@ public class TextureManager
{
public static readonly Dictionary TextureManagers = new();
- public readonly Dictionary TextureHashMap = new();
+ private List _textures = new();
public static TextureManager GetTextureManager(IGLFWGraphicsContext context)
{
@@ -31,16 +31,21 @@ public class TextureManager
Context = context;
}
- public IReadOnlyList Textures { get => TextureHashMap.Values.ToList().AsReadOnly(); }
+ public IReadOnlyList Textures { get => _textures.AsReadOnly(); }
public void RemoveTexture(Texture Texture)
{
- foreach(KeyValuePair item in TextureHashMap.Where(kvp => kvp.Value == Texture).ToList())
- {
- TextureHashMap.Remove(item.Key);
- }
+ _textures.Remove(Texture);
}
+ public Texture AddTexture(Stream TextureStream, bool UseMissing = true)
+ {
+ Context.MakeCurrent();
+ Texture t = Texture.GetTexture(TextureStream, this, UseMissing);
+ _textures.Add(t);
+ return t;
+ }
+ /*
public Texture AddTexture(byte[] Texture, bool Rounded = false)
{
List hash2 = SHA256.HashData(Texture).ToList();
@@ -50,5 +55,5 @@ public class TextureManager
Context.MakeCurrent();
TextureHashMap.Add(hash, new(Texture, Rounded));
return TextureHashMap[hash];
- }
+ }*/
}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs
index 5ba5f66..e4b73fa 100644
--- a/GraphicsManager/Objects/FlowLayout.cs
+++ b/GraphicsManager/Objects/FlowLayout.cs
@@ -5,6 +5,7 @@ using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using Timer = System.Timers.Timer;
namespace GraphicsManager.Objects;
@@ -125,7 +126,35 @@ public class FlowLayout : IRenderObject, IParent
{
if (Controls.Length > 0) arg.Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y);
else arg.Location = new(0, 0);
+ if (arg is IParent par2)
+ {
+ for (int i = 0; i < par2.Controls.Length; i++)
+ {
+ par2.Controls[i].Distance = new(
+ par2.Size.X - par2.Controls[i].Size.X - par2.Controls[i].Location.X,
+ par2.Size.Y - par2.Controls[i].Size.Y - par2.Controls[i].Location.Y);
+
+ }
+ }
arg.Size = new(Size.X, arg.Size.Y);
+ if (arg is IParent par)
+ {
+ for (int i = 0; i < par.Controls.Length; i++)
+ {
+ bool top = (par.Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
+ bool left = (par.Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
+ bool right = (par.Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
+ bool bottom = (par.Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
+ if (!top && !bottom) { par.Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
+ if (!left && !right) { par.Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
+ int lx = (left ? par.Controls[i].Location.X : Size.X - par.Controls[i].Distance.X - par.Controls[i].Size.X);
+ int ly = (top ? par.Controls[i].Location.Y : Size.Y - par.Controls[i].Distance.Y - par.Controls[i].Size.Y);
+ int sy = (bottom ? Size.Y - par.Controls[i].Distance.Y - ly : par.Controls[i].Size.Y);
+ int sx = (right ? Size.X - par.Controls[i].Distance.X - lx : par.Controls[i].Size.X);
+ par.Controls[i].Size = new(sx, sy);
+ par.Controls[i].Location = new(lx, ly);
+ }
+ }
arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top;
return Task.CompletedTask;
}
@@ -141,6 +170,12 @@ public class FlowLayout : IRenderObject, IParent
if (MouseLeave is not null) _ = MouseLeave.Invoke(this);
return Task.CompletedTask;
}
+
+ public MouseCursor HoverMouse
+ {
+ get => _bounds.HoverMouse;
+ set => _bounds.HoverMouse = value;
+ }
private bool inside = false;
private Task BoundsOnMouseEnter(IRenderObject arg)
@@ -217,11 +252,11 @@ public class FlowLayout : IRenderObject, IParent
BlockDraw = false;
}
}
- public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+ //public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
public Vector2i Position => Location;
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
- public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value; }
+ public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
public event Func? Clicked;
public event Action MouseDown;
public event Action KeyDown;
@@ -251,6 +286,17 @@ public class FlowLayout : IRenderObject, IParent
Window.MouseWheel += WindowOnMouseWheel;
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
+ }
public bool BlockDraw { get; set; } = false;
Timer t;
@@ -400,11 +446,48 @@ public class FlowLayout : IRenderObject, IParent
}
}
+ public bool dw;
+
public void Draw(int x, int y, int w, int h)
{
if (Loaded)
{
- _bounds.Draw(x,y,w,h);
+ int nx = x, ny = y, nw = w, nh = h;
+
+
+ if (Location.X > nw)
+ return;
+ else
+ {
+ nx += Location.X;
+ nw -= Location.X;
+ if (Size.X < nw)
+ nw = Size.X;
+ }
+
+ if (Location.Y > nh)
+ return;
+ else
+ {
+ ny += Location.Y;
+ nh -= Location.Y;
+ if (Size.Y < nh)
+ nh = Size.Y;
+ }
+ if (dw) Console.WriteLine("Flowlayout\nLoc: {0}\nSize: {1}\n\nX: {2}\nY: {3}\nW: {4}\nH:{5}\n\nX: {6}\nY: {7}\nW: {8}\nH:{9}",
+ Location,
+ Size,
+ x,
+ y,
+ w,
+ h,
+ nx,
+ ny,
+ nw,
+ nh);
+ if (nw ==0 || nh == 0) return;
+ GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
+ _bounds.Draw(nx,ny,nw,nh);
IEnumerable needload = Controls.Where(a => a.Loaded == false);
if (needload.Any())
@@ -419,25 +502,15 @@ public class FlowLayout : IRenderObject, IParent
}
for (int i = 0; i < Controls.Length; i++)
{
- Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y);
- Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y);
- if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y);
- if (laff.X < x) laff = new(x, laff.Y);
- if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y);
- if (laff.Y < y) laff = new(laff.X, y);
- if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y);
- if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y);
- GL.Scissor(laff.X, laff.Y, saff.X, saff.Y);
- Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
+ if (Controls[i] is not IParent)
+ {
+ GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
+ }
+ Controls[i].Draw(nx, ny, nw, nh);
}
}
}
-
- public Vector2i GetParentRelLocPoint()
- {
- return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
- }
-
+
public void Clean()
{
for (int i = 0; i < Controls.Length; i++)
diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs
index a001f78..fb5b35e 100755
--- a/GraphicsManager/Objects/Label.cs
+++ b/GraphicsManager/Objects/Label.cs
@@ -5,6 +5,7 @@ using GraphicsManager.Structs;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
using SharpFont;
@@ -12,10 +13,21 @@ using Encoding = SharpFont.Encoding;
namespace GraphicsManager.Objects;
-public class Label : IRenderObject
+public class Label : ILabel
{
public static readonly Dictionary DefaultTextShader = new();
- public static readonly Font DefaultFont = Font.MakeFontFromSystem();
+ //public static readonly Font DefaultFont = Core.Font.MakeFontFromSystem();
+
+ public Label(FontFamily fontFamily)
+ {
+ Font = FontInteraction.Load(fontFamily);
+ }
+
+ public Label(FontInteraction interaction)
+ {
+ Font = interaction;
+ }
+
public ContextMenu? ContextMenu { get; set; } = null;
public IParent? Parent { get; private set; }
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
@@ -45,7 +57,7 @@ public class Label : IRenderObject
}
}
- public static readonly Dictionary>> _characters = new();
+ public static readonly Dictionary>> _characters = new();
private string text = string.Empty;
public int VAO { get; private set; }
@@ -60,6 +72,9 @@ public class Label : IRenderObject
public int VBO { get; private set; }
public Vector2 DIR { get; set; } = new Vector2(1f, 0f);
+ public int TrueHeight = 0;
+ public int PostiveTrueHeight = 0;
+
public Vector2i GetSizeOfChar(int Index)
{
float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F;
@@ -76,9 +91,10 @@ public class Label : IRenderObject
{
char_x = 0f;
addy += Font.PixelHeight * Scale;
+ addy += Font.ExtraLinePixels;
continue;
}
- Character cha = Texture.GetChar(Font, character);
+ Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight);
float w = cha.Size.X * Scale;
float xrel = char_x + cha.Bearing.X * Scale;
char_x += (cha.Advance >> 6) * Scale;
@@ -94,7 +110,9 @@ public class Label : IRenderObject
{
if (value is null) value = string.Empty;
text = value;
- float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F;
+ int line = 0;
+ double nl = 0;
+ double addy = 0f, addy2 =0f, addx = 0F, char_x = 0F;
for (int i = 0; i < value.Length; i++)
{
char character;
@@ -102,22 +120,30 @@ public class Label : IRenderObject
character = value[i];
else
character = PasswordChar.Value;
-
-
+
if (character == '\n')
{
char_x = 0f;
- addy += Font.PixelHeight * Scale;
+ nl = addy;
+ line++;
continue;
}
- Character cha = Texture.GetChar(Font, character);
- float w = cha.Size.X * Scale;
- float xrel = char_x + cha.Bearing.X * Scale;
+ Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight);
+ double w = cha.Size.X * Scale;
+ double xrel = char_x + cha.Bearing.X * Scale;
+ double yrel = ((cha.Size.Y - cha.Bearing.Y) * Scale) + (Font.PixelHeight * Scale);
+ yrel += nl;
char_x += (cha.Advance >> 6) * Scale;
if ((xrel + w) >= addx) addx = (xrel + w);
+ if (yrel > addy) addy = yrel;
+ if (line == 0)
+ {
+ if (addy2 < cha.Bearing.Y) addy2 = cha.Bearing.Y;
+ }
}
-
- Size = new((int)addx, (int)addy);
+ Size = new((int)addx, (int)addy + (int)(line * Font.ExtraLinePixels));
+ PostiveTrueHeight = (int)addy2;
+ TrueHeight = (int)(addy - (Font.PixelHeight - addy2));
if (Loaded)
{
@@ -141,11 +167,12 @@ public class Label : IRenderObject
}
}
public Shader Shader { get; set; } = null!;
- public Font Font { get; set; } = DefaultFont;
+ public FontInteraction Font { get; }
public float Scale { get; set; } = 1.0f;
public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
- public Vector2i Distance { get; internal set; }
+ public Vector2i Distance { get; set; }
private Vector2i loc_ = new();
+ private int maxy = 0, maxx = 0;
public Vector2i Location
{
get
@@ -158,7 +185,7 @@ public class Label : IRenderObject
if (Window is null || Parent is null) return;
if (Window.CanControleUpdate && Loaded)
{
- ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
+ // = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
Parent!.TryDraw();
if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
}
@@ -170,7 +197,7 @@ public class Label : IRenderObject
set
{
_size = value;
- if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
+ //if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
}
}
@@ -199,7 +226,7 @@ public class Label : IRenderObject
public void Draw(int x, int y, int ww, int hh)
{
- if (Visible & Loaded)
+ if (Visible && Loaded && this.Font is not null)
{
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
Shader.Use();
@@ -214,7 +241,7 @@ public class Label : IRenderObject
float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X);
Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad);
- Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Window.FloatToInt(Parent!.IntToFloat(0)), loc_.Y + Font.PixelHeight + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
+ Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Window.FloatToInt(Parent!.IntToFloat(0)), loc_.Y + (Font.PixelHeight * Scale) + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
float char_x = 0.0f;
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
@@ -231,13 +258,14 @@ public class Label : IRenderObject
bool n = (c == '\n');
if (!_characters[Window!.Context][Font].ContainsKey(c) && !n)
{
- var f = Texture.TextureForChar(Window!.Context, Font, c);
+ Texture f = Texture.TextureForChar(Window!.Context, Font, c);
}
int maxx = 0;
if (n)
{
hhh += Font.PixelHeight * Scale;
+ hhh += Font.ExtraLinePixels;
char_x = 0f;
}
else
@@ -261,9 +289,14 @@ public class Label : IRenderObject
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
}
}
-
- GL.Disable(EnableCap.Blend);
- }
+ }
+ }
+ public void ForceDistanceUpdate()
+ {
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
}
public Window? Window { get; private set; }
private static Dictionary> GlobalBuffers = new();
@@ -339,22 +372,39 @@ public class Label : IRenderObject
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
}
+ public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
+
private bool mouseinside = false;
private void WindowOnMouseMove(MouseMoveEventArgs obj)
{
if (Visible &&
- Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
{
- if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this);
- mouseinside = true;
+ if (!mouseinside)
+ {
+ if (Window!.CurrentTop is null || Window!.CurrentTop == this)
+ {
+ Window!.Cursor = HoverMouse;
+ if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
+ mouseinside = true;
+ }
+ else
+ {
+ mouseinside = false;
+ }
+ }
}
else
{
- if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
- mouseinside = false;
+ if (mouseinside)
+ {
+ if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
+ if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
+ mouseinside = false;
+ }
}
}
diff --git a/GraphicsManager/Objects/RainbowLabel.cs b/GraphicsManager/Objects/RainbowLabel.cs
new file mode 100755
index 0000000..5dba769
--- /dev/null
+++ b/GraphicsManager/Objects/RainbowLabel.cs
@@ -0,0 +1,494 @@
+using GraphicsManager.Enums;
+using GraphicsManager.Interfaces;
+using GraphicsManager.Objects.Core;
+using GraphicsManager.Structs;
+using OpenTK.Graphics.OpenGL4;
+using OpenTK.Mathematics;
+using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
+using OpenTK.Windowing.Desktop;
+using OpenTK.Windowing.GraphicsLibraryFramework;
+using SharpFont;
+using Encoding = SharpFont.Encoding;
+
+namespace GraphicsManager.Objects;
+
+public class RainbowLabel : ILabel
+{
+ public RainbowLabel(FontFamily fontFamily)
+ {
+ Font = FontInteraction.Load(fontFamily);
+ }
+
+ public RainbowLabel(FontInteraction interaction)
+ {
+ Font = interaction;
+ }
+
+ public ContextMenu? ContextMenu { get; set; } = null;
+ public IParent? Parent { get; private set; }
+ public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
+ private Vector2 laf = new(), saf = new();
+
+ public Vector2 LocationAsFloat { get { return laf; } }
+ public Vector2 SizeAsFloat { get { return saf; } }
+ private char? pc = null;
+ public char? PasswordChar
+ {
+ get => pc;
+ set
+ {
+ pc = value;
+ if (Parent is not null) Parent.TryDraw();
+ }
+ }
+ private bool _Visible = true;
+
+ public bool Visible
+ {
+ get => _Visible;
+ set
+ {
+ _Visible = value;
+ if (Parent is not null && Loaded) Parent.TryDraw();
+ }
+ }
+
+ private string text = string.Empty;
+ public int VAO { get; private set; }
+
+ public void Focus()
+ {
+
+ }
+ public void UnFocus()
+ {
+
+ }
+ public int VBO { get; private set; }
+ public Vector2 DIR { get; set; } = new Vector2(1f, 0f);
+
+ public int TrueHeight = 0;
+ public int PostiveTrueHeight = 0;
+
+ public Vector2i GetSizeOfChar(int Index)
+ {
+ float addy = Font.PixelHeight * Scale, addx = 0F, char_x = 0F;
+ for (int i = 0; i < Index + 1; i++)
+ {
+ char character;
+ if (PasswordChar is null)
+ character = Text[i];
+ else
+ character = PasswordChar.Value;
+
+
+ if (character == '\n')
+ {
+ char_x = 0f;
+ addy += Font.PixelHeight * Scale;
+ addy += Font.ExtraLinePixels;
+ continue;
+ }
+ Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight);
+ float w = cha.Size.X * Scale;
+ float xrel = char_x + cha.Bearing.X * Scale;
+ char_x += (cha.Advance >> 6) * Scale;
+ if ((xrel + w) >= addx) addx = (xrel + w);
+ }
+
+ return new((int)addx, (int)addy);
+ }
+ public string Text
+ {
+ get => text;
+ set
+ {
+ if (value is null) value = string.Empty;
+ text = value;
+ int line = 0;
+ double nl = 0;
+ double addy = 0f, addy2 =0f, addx = 0F, char_x = 0F;
+ for (int i = 0; i < value.Length; i++)
+ {
+ char character;
+ if (PasswordChar is null)
+ character = value[i];
+ else
+ character = PasswordChar.Value;
+
+ if (character == '\n')
+ {
+ char_x = 0f;
+ nl = addy;
+ line++;
+ continue;
+ }
+ Character cha = Texture.GetChar(Font.CurrentFont, character, Font.PixelHeight);
+ double w = cha.Size.X * Scale;
+ double xrel = char_x + cha.Bearing.X * Scale;
+ double yrel = ((cha.Size.Y - cha.Bearing.Y) * Scale) + (Font.PixelHeight * Scale);
+ yrel += nl;
+ char_x += (cha.Advance >> 6) * Scale;
+ if ((xrel + w) >= addx) addx = (xrel + w);
+ if (yrel > addy) addy = yrel;
+ if (line == 0)
+ {
+ if (addy2 < cha.Bearing.Y) addy2 = cha.Bearing.Y;
+ }
+ }
+ Size = new((int)addx, (int)addy);
+ PostiveTrueHeight = (int)addy2;
+ TrueHeight = (int)(addy - (Font.PixelHeight - addy2));
+ if (Loaded)
+ {
+
+ if (Window is not null && Window.CanControleUpdate)
+ {
+ if (!Window.Context.IsCurrent)
+ {
+ try
+ {
+ Window.Context.MakeCurrent();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+ Parent!.TryDraw();
+ }
+ }
+ }
+ }
+ public Shader Shader { get; set; } = null!;
+ public FontInteraction Font { get; }
+ public float Scale { get; set; } = 1.0f;
+ public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
+ public Vector2i Distance { get; set; }
+ private Vector2i loc_ = new();
+ private int maxy = 0, maxx = 0;
+ public Vector2i Location
+ {
+ get
+ {
+ return loc_;
+ }
+ set
+ {
+ loc_ = value;
+ if (Window is null || Parent is null) return;
+ if (Window.CanControleUpdate && Loaded)
+ {
+ // = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
+ Parent!.TryDraw();
+ if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
+ }
+ }
+ }
+
+ private Vector2i _size;
+ public Vector2i Size { get => _size;
+ set
+ {
+ _size = value;
+ //if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
+ }
+ }
+
+ public void Clean()
+ {
+ Tuple tup = GlobalBuffers[Window!.Context];
+ if (tup.Item3 - 1 == 0)
+ {
+ //Broken, I may fix latter
+
+ //if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
+ //GL.DeleteBuffer(VBO);
+ //GL.DeleteVertexArray(VAO);
+ //GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+ //GlobalBuffers.Remove(Window!.Context);
+ }
+ else
+ {
+ GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1);
+ }
+ Size = new(0, 0);
+ Loaded = false;
+ Visible = false;
+ }
+ public Vector2i ScissorLocation { get; private set; }
+
+ public void Draw(int x, int y, int ww, int hh)
+ {
+ if (Visible && Loaded && this.Font is not null)
+ {
+ if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
+ Shader.Use();
+ GL.Enable(EnableCap.Blend);
+ //GL.Uniform4(2, Color);
+ Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f);
+ GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
+ GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+ GL.UniformMatrix4(1, false, ref projectionM);
+
+ GL.BindVertexArray(VAO);
+
+ float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X);
+ Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad);
+ Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Window.FloatToInt(Parent!.IntToFloat(0)), loc_.Y + (Font.PixelHeight * Scale) + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
+ float char_x = 0.0f;
+
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+ GL.ActiveTexture(TextureUnit.Texture0);
+
+ float hhh = 0f;
+ for (int i = 0; i < Text.Length; i++)
+ {
+ var col = SetCol(i);
+ GL.Uniform4(2, col);
+ char c;
+ if (PasswordChar is null)
+ c = Text[i];
+ else
+ c = PasswordChar.Value;
+ bool n = (c == '\n');
+ if (!Label._characters[Window!.Context][Font].ContainsKey(c) && !n)
+ {
+ Texture f = Texture.TextureForChar(Window!.Context, Font, c);
+ }
+
+ int maxx = 0;
+ if (n)
+ {
+ hhh += Font.PixelHeight * Scale;
+ hhh += Font.ExtraLinePixels;
+ char_x = 0f;
+ }
+ else
+ {
+ if (!Label._characters[Window!.Context][Font].ContainsKey(c)) continue;
+ Character ch = Label._characters[Window!.Context][Font][c];
+ float w = ch.Size.X * Scale;
+ float h = ch.Size.Y * Scale;
+ float xrel = char_x + ch.Bearing.X * Scale;
+ float yrel = (ch.Size.Y - ch.Bearing.Y) * Scale;
+ yrel += hhh;
+ char_x += (ch.Advance >> 6) * Scale;
+ Matrix4 scaleM = Matrix4.CreateScale(new Vector3(w, h, 1.0f));
+ Matrix4 transRelM = Matrix4.CreateTranslation(new Vector3(xrel, yrel, 0.0f));
+
+ Matrix4 modelM = scaleM * transRelM * rotateM * transOriginM;
+ GL.UniformMatrix4(0, false, ref modelM);
+
+ ch.Texture.Use();
+
+ GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
+ }
+ }
+ }
+ }
+ public void ForceDistanceUpdate()
+ {
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ }
+ public Color4 SetCol(int index)
+ {
+ double onefith = Math.Round((double)Text.Length / 5);
+ double twofith = Math.Round(onefith * 2);
+ double threefith = Math.Round(onefith * 3);
+ double fourfith = Math.Round(onefith * 4);
+ if (onefith < 1)
+ {
+ return Text.Length switch
+ {
+ 1 => new Color4(255,0,0,255),
+ 2 => index switch
+ {
+ 0 => new Color4(255, 0, 0, 255),
+ 1 => new Color4(255, 255, 0, 255)
+ },
+ 3 => index switch
+ {
+ 0 => new Color4(255, 0, 0, 255),
+ 1 => new Color4(255, 255, 0, 255),
+ 2 => new Color4(0, 255, 0, 255)
+ },
+ 4 => index switch
+ {
+ 0 => new Color4(255, 0, 0, 255),
+ 1 => new Color4(255, 255, 0, 255),
+ 2 => new Color4(0, 255, 0, 255),
+ 3 => new Color4(0, 255, 255, 255)
+ },
+ 5 => index switch
+ {
+ 0 => new Color4(255, 0, 0, 255),
+ 1 => new Color4(255, 255, 0, 255),
+ 2 => new Color4(0, 255, 0, 255),
+ 3 => new Color4(0, 255, 255, 255),
+ 4 => new Color4(0, 0, 255, 255)
+ }
+ };
+ }
+ else
+ {
+ double n = index + 1;
+ if (n <= onefith)
+ {
+ n = index / onefith;
+ if (n > 1) n = 1;
+ return new Color4(255, (byte)(n * 255),0,255);
+ }
+ else if (n <= twofith)
+ {
+ n = (index - onefith) / onefith;
+ if (n > 1) n = 1;
+ return new Color4((byte)(255 - (n * 255)), 255,0,255);
+ }
+ else if (n <= threefith)
+ {
+ n = (index - twofith) / onefith;
+ if (n > 1) n = 1;
+ return new Color4(0, 255,(byte)(n * 255),255);
+ }
+ else if (n <= fourfith)
+ {
+ n = (index - threefith) / onefith;
+ if (n > 1) n = 1;
+ return new Color4(0, (byte)(255 - (n * 255)),255,255);
+ }
+ else
+ {
+ n = (index - fourfith) / onefith;
+ if (n > 1)
+ {
+ n -= 1;
+ return new Color4(255, 0,(byte)(255 - (n * 255)),255);
+ }
+ else return new Color4((byte)(n * 255), 0,255,255);
+ }
+ }
+ }
+ public Window? Window { get; private set; }
+ private static Dictionary> GlobalBuffers = new();
+ public void LoadToParent(IParent window, Window win)
+ {
+ if (Loaded) return;
+ if (!Label._characters.ContainsKey(win!.Context)) Label._characters.Add(win!.Context, new());
+ if (!Label._characters[win!.Context].ContainsKey(Font)) Label._characters[win!.Context].Add(Font, new Dictionary());
+ if (Shader is null) Shader = Label.DefaultTextShader[win.Context];
+ Parent = window;
+ Window = win;
+ Window.MouseMove += WindowOnMouseMove;
+ Window.MouseDown += WindowOnMouseDown;
+ if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
+ if (!GlobalBuffers.ContainsKey(win.Context))
+ {
+ float[] vquad =
+ {
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f
+ };
+ int _VBO = GL.GenBuffer();
+ GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO);
+ GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw);
+ int _VAO = GL.GenVertexArray();
+ GL.BindVertexArray(_VAO);
+ GL.EnableVertexAttribArray(0);
+ GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0);
+ GL.EnableVertexAttribArray(1);
+ GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4);
+ GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0));
+ }
+
+ Tuple tup = GlobalBuffers[win.Context];
+ VBO = tup.Item1;
+ VAO = tup.Item2;
+ GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1);
+
+
+
+/*
+ VBO = GL.GenBuffer();
+ GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
+ GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw);
+
+ VAO = GL.GenVertexArray();
+ GL.BindVertexArray(VAO);
+ GL.EnableVertexAttribArray(0);
+ GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0);
+ GL.EnableVertexAttribArray(1);
+ GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4);
+*/
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+ GL.BindVertexArray(0);
+
+ Loaded = true;
+ Text = Text;
+ Location = Location;
+ Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
+ }
+
+ private void WindowOnMouseDown(MouseButtonEventArgs obj)
+ {
+ if (mouseinside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
+ if (mouseinside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
+ if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
+ }
+
+ public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
+
+ private bool mouseinside = false;
+ private void WindowOnMouseMove(MouseMoveEventArgs obj)
+ {
+ if (Visible &&
+ Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
+ Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
+ {
+ if (!mouseinside)
+ {
+ if (Window!.CurrentTop is null || Window!.CurrentTop == this)
+ {
+ Window!.Cursor = HoverMouse;
+ if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
+ mouseinside = true;
+ }
+ else
+ {
+ mouseinside = false;
+ }
+ }
+ }
+ else
+ {
+ if (mouseinside)
+ {
+ if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
+ if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
+ mouseinside = false;
+ }
+ }
+ }
+
+ public event Func? Clicked;
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
+
+ public bool Loaded { get; private set; } = false;
+}
diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs
index 55556f7..9844c65 100755
--- a/GraphicsManager/Objects/Rectangle.cs
+++ b/GraphicsManager/Objects/Rectangle.cs
@@ -4,6 +4,7 @@ using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
@@ -12,19 +13,21 @@ namespace GraphicsManager.Objects;
public class Rectangle : ITextureObject
{
public static readonly Dictionary DefaultShader = new();
+ public static readonly Dictionary DefaultAlphaShader = new();
+ public static readonly Dictionary DefaultAlphaTextureShader = new();
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
- public Texture? Texture { get; set; }
+ public List Textures { get; set; } = new();
public ContextMenu? ContextMenu { get; set; } = null;
public event Func? FilesDroped;
public Rectangle(Texture? texture = null)
{
- Texture = texture;
+ if (texture is not null) Textures.Add(texture);;
if (Points_ is null)
{
- bool tex = (Texture is null);
+ bool tex = (texture is null);
Points_ = new float[(tex ? 12 : 20)];
if (!tex)
{
@@ -67,26 +70,41 @@ public class Rectangle : ITextureObject
}
}
+ public Action? OnDrawAction;
+ public Action? OnDrawExitAction;
+
public void Draw(int x, int y, int w, int h)
{
if (Visible && Loaded)
{
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
- if (Texture is not null) Texture.Use();
- Shader.Use();
- if (Texture is null) GL.Uniform4(0, BackgroundColor);
- if (Texture is not null)
+ foreach (Texture tex in Textures)
{
- GL.Enable(EnableCap.Blend);
- GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
- GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+ tex.Use();
+ }
+ Shader.Use();
+ if (!Textures.Any() || Shader.Handle == DefaultAlphaShader[Window!.Context].Handle)
+ {
+ GL.Uniform4(0, BackgroundColor);
}
GL.BindVertexArray(ArrayObject);
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedInt, 0);
- if (Texture is not null) GL.Disable(EnableCap.Blend);
}
}
+
+ public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
+ }
public void Clean()
{
@@ -101,20 +119,24 @@ public class Rectangle : ITextureObject
if (Loaded) return;
this.Parent = Parent;
this.Window = Window;
- if (Shader is null) Shader = DefaultShader[Window.Context];
+ if (Shader is null)
+ {
+ if (!Textures.Any())Shader = DefaultShader[Window.Context];
+ else Shader = Texture.TextureShader[Window.Context];
+ }
int pos = Points.Length - 3;
- if (Texture is not null) pos -= 2;
+ if (Textures.Any()) pos -= 2;
pos = 4;
- if (Texture is not null) pos += 2;
+ if (Textures.Any()) pos += 2;
BufferObject = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
ArrayObject = GL.GenVertexArray();
GL.BindVertexArray(ArrayObject);
int add = 3;
- if (Texture is not null) add = 5;
+ if (Textures.Any()) add = 5;
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
- if (Texture is not null)
+ if (Textures.Any() && !Shader.ForTexture)
{
Shader = Texture.TextureShader[Window.Context];
}
@@ -130,7 +152,7 @@ public class Rectangle : ITextureObject
Window.MouseMove += WindowOnMouseMove;
Window.FileDrop += WindowOnFileDrop;
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 (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
@@ -149,13 +171,28 @@ public class Rectangle : ITextureObject
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
{
- if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this);
- mouseinside = true;
+ if (!mouseinside)
+ {
+ if (Window!.CurrentTop is null || Window!.CurrentTop == this)
+ {
+ Window!.Cursor = HoverMouse;
+ if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
+ mouseinside = true;
+ }
+ else
+ {
+ mouseinside = false;
+ }
+ }
}
else
{
- if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
- mouseinside = false;
+ if (mouseinside)
+ {
+ if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
+ if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
+ mouseinside = false;
+ }
}
}
@@ -201,11 +238,12 @@ public class Rectangle : ITextureObject
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
GL.BindVertexArray(ArrayObject);
int add = 3;
- if (Texture is not null)
+ if (Textures.Any())
{
add = 5;
- GL.VertexAttribPointer(Texture.Location, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
- GL.EnableVertexAttribArray(Texture.Location);
+ GL.EnableVertexAttribArray(Textures.First().Location);
+ GL.VertexAttribPointer(Textures.First().Location, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
+
}
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
GL.EnableVertexAttribArray(0);
@@ -230,12 +268,12 @@ public class Rectangle : ITextureObject
public event Func? Clicked;
- public bool Loaded { get; private set; } = false;
+ public bool Loaded { get; private set; }
public event Func? WindowLoaded;
public event Func? MouseEnter;
public event Func? MouseLeave;
- public object? Tag { get; set; } = null;
- public Vector2i Distance { get; internal set; }
+ public object? Tag { get; set; }
+ public Vector2i Distance { get; set; }
public Vector2i Size
{
@@ -251,10 +289,9 @@ public class Rectangle : ITextureObject
float[] temp = Points;
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
temp[0] = saf.X;
- temp[(Texture is null ? 3 : 5)] = saf.X;
- temp[(Texture is null ? 4 : 6)] = saf.Y;
- temp[(Texture is null ? 7 : 11)] = saf.Y;
- ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
+ temp[(!Textures.Any()? 3 : 5)] = saf.X;
+ temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
+ temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
Points = temp;
}
}
@@ -271,23 +308,18 @@ public class Rectangle : ITextureObject
if (Window is null || Parent is null) return;
float[] temp = Points;
laf = new Vector2(Parent.IntToFloat(value.X, false), Parent.IntToFloat(value.Y, true));
- temp[(Texture is null ? 6 : 10)] = laf.X;
- temp[(Texture is null ? 9 : 15)] = laf.X;
+ temp[(!Textures.Any() ? 6 : 10)] = laf.X;
+ temp[(!Textures.Any() ? 9 : 15)] = laf.X;
temp[1] = laf.Y;
- temp[(Texture is null ? 10 : 16)] = laf.Y;
+ temp[(!Textures.Any() ? 10 : 16)] = laf.Y;
saf = new Vector2(Parent.IntToFloat(Size.X + value.X, false), Parent.IntToFloat(Size.Y + value.Y, true));
temp[0] = saf.X;
- temp[(Texture is null ? 3 : 5)] = saf.X;
- temp[(Texture is null ? 4 : 6)] = saf.Y;
- temp[(Texture is null ? 7 : 11)] = saf.Y;
- ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)),
- //ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y);
- //(int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true)
- //);
+ temp[(!Textures.Any() ? 3 : 5)] = saf.X;
+ temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
+ temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
Points = temp;
}
}
- public Vector2i ScissorLocation { get; private set; }
private Vector2 laf = new(), saf = new();
public Vector2 LocationAsFloat { get { return laf; } }
diff --git a/GraphicsManager/Objects/RoundedButton.cs b/GraphicsManager/Objects/RoundedButton.cs
index 3929bd8..0143751 100755
--- a/GraphicsManager/Objects/RoundedButton.cs
+++ b/GraphicsManager/Objects/RoundedButton.cs
@@ -2,8 +2,7 @@
using GraphicsManager.Interfaces;
using GraphicsManager.Objects.Core;
using OpenTK.Mathematics;
-using OpenTK.Windowing.Common;
-using OpenTK.Windowing.GraphicsLibraryFramework;
+using OpenTK.Windowing.Common.Input;
namespace GraphicsManager.Objects;
@@ -11,11 +10,27 @@ public class RoundedButton : IRenderObject
{
private RoundedRectangle _bounds, _inside;
internal Label _label;
- public RoundedButton()
+ public RoundedButton(FontFamily family)
{
_bounds = new RoundedRectangle();
_inside = new RoundedRectangle();
- _label = new Label();
+ _label = new Label(family);
+ _bounds.MouseEnter += BoundsOnMouseEnter;
+ _bounds.MouseLeave += BoundsOnMouseLeave;
+ _bounds.Clicked += BoundsOnClicked;
+ }
+
+ public MouseCursor HoverMouse
+ {
+ get => _bounds.HoverMouse;
+ set => _bounds.HoverMouse = value;
+ }
+
+ public RoundedButton(FontInteraction family)
+ {
+ _bounds = new RoundedRectangle();
+ _inside = new RoundedRectangle();
+ _label = new Label(family);
_bounds.MouseEnter += BoundsOnMouseEnter;
_bounds.MouseLeave += BoundsOnMouseLeave;
_bounds.Clicked += BoundsOnClicked;
@@ -47,7 +62,7 @@ public class RoundedButton : IRenderObject
public int Border { get; set; } = 2;
public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } }
- public Font Font { get => _label.Font; set => _label.Font = value; }
+ public FontInteraction Font { get => _label.Font; }
public string Text { get => _label.Text; set => _label.Text = value; }
public bool Loaded { get; private set; } = false;
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
@@ -64,6 +79,18 @@ public class RoundedButton : IRenderObject
_label.Location = new( Location.X + Border + (((value.X - (Border * 2)) / 2) - (_label.Size.X / 2)), Location.Y + Border + (((value.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
}
}
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ _bounds.ForceDistanceUpdate(parent);
+ }
+
public Vector2i Location {
get => _bounds.Location;
set
@@ -73,11 +100,11 @@ public class RoundedButton : IRenderObject
_label.Location = new( value.X + Border + (((Size.X - (Border * 2)) / 2) - (_label.Size.X / 2)), value.Y + Border + (((Size.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
}
}
- public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+ //public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
- public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value;}
+ public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value;}
public IParent? Parent { get; private set; } = null;
public Window? Window { get; private set; } = null;
public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; }
diff --git a/GraphicsManager/Objects/RoundedRectangle.cs b/GraphicsManager/Objects/RoundedRectangle.cs
index 0597a9d..16e18fb 100755
--- a/GraphicsManager/Objects/RoundedRectangle.cs
+++ b/GraphicsManager/Objects/RoundedRectangle.cs
@@ -5,6 +5,7 @@ using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.GraphicsLibraryFramework;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
namespace GraphicsManager.Objects;
@@ -114,10 +115,8 @@ public class RoundedRectangle : IRenderObject
if (Visible && Loaded)
{
GL.Enable(EnableCap.Multisample);
- GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
GL.Hint(HintTarget.PolygonSmoothHint, HintMode.Nicest);
- GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
Shader.Use();
GL.Uniform4(0, BackgroundColor);
GL.BindVertexArray(ArrayObject);
@@ -168,13 +167,28 @@ public class RoundedRectangle : IRenderObject
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
{
- if (MouseEnter is not null && !mouseinside) _ = MouseEnter.Invoke(this);
- mouseinside = true;
+ if (!mouseinside)
+ {
+ if (Window!.CurrentTop is null || Window!.CurrentTop == this)
+ {
+ Window!.Cursor = HoverMouse;
+ if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
+ mouseinside = true;
+ }
+ else
+ {
+ mouseinside = false;
+ }
+ }
}
else
{
- if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
- mouseinside = false;
+ if (mouseinside)
+ {
+ if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
+ if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
+ mouseinside = false;
+ }
}
}
@@ -248,12 +262,25 @@ public class RoundedRectangle : IRenderObject
3, 22, 23,
3, 4, 23};
public BufferUsageHint Hint { get; set; } = BufferUsageHint.StaticDraw;
+
+ public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
+ }
public event Func? Clicked;
public bool Loaded { get; private set; } = false;
- public Vector2i Distance { get; internal set; }
+ public Vector2i Distance { get; set; }
public Vector2i Size
{
@@ -268,7 +295,7 @@ public class RoundedRectangle : IRenderObject
Parent.ReportSizeUpdate(this);
Location = Location;
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
- ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
+ //ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
}
}
@@ -333,11 +360,11 @@ public class RoundedRectangle : IRenderObject
//ScissorLocation = Parent.GetParentRelLocPoint() + value;
//ScissorLocation = Parent.GetParentRelLocPoint() + value;// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)),
//ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y);
- ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));
+ //ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));
Points = temp.ToArray();
}
}
- public Vector2i ScissorLocation { get; private set; }
+ //public Vector2i ScissorLocation { get; private set; }
private Vector2 laf = new(), saf = new();
public Vector2 LocationAsFloat { get { return laf; } }
diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs
index bf4e469..8cd4d9e 100644
--- a/GraphicsManager/Objects/TabControl.cs
+++ b/GraphicsManager/Objects/TabControl.cs
@@ -4,6 +4,7 @@ using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using SixLabors.ImageSharp.Processing;
namespace GraphicsManager.Objects;
@@ -12,13 +13,27 @@ public class TabControl : IRenderObject, IParent
{
public Rectangle _bounds;
- public TabControl()
+ public TabControl(FontFamily fam)
{
+ TitleFont = FontInteraction.Load(fam);
_bounds = new();
}
+
+ public TabControl(FontInteraction fam)
+ {
+ TitleFont = fam;
+ _bounds = new();
+ }
+
+ public MouseCursor HoverMouse
+ {
+ get => _bounds.HoverMouse;
+ set => _bounds.HoverMouse = value;
+ }
+
private ControlList Buttonts = new();
- private ControlList Controls = new();
+ public ControlList Controls { get; } = new();
public void AddPage(string Title, UserControl page)
{
@@ -30,10 +45,9 @@ public class TabControl : IRenderObject, IParent
locc = Buttonts[loc - 1].Location.X;
loccc = Buttonts[loc - 1].Size.X;
}
- Buttonts.Add(tmp = new RoundedButton()
+ Buttonts.Add(tmp = new RoundedButton(TitleFont.Family)
{
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
- Font = TitleFont,
Text = Title,
Tag = loc,
BorderColor = this.BorderColor,
@@ -61,10 +75,9 @@ public class TabControl : IRenderObject, IParent
locc = Buttonts[loc - 1].Location.X;
loccc = Buttonts[loc - 1].Size.X;
}
- Buttonts.Add(tmp = new RoundedButton()
+ Buttonts.Add(tmp = new RoundedButton(TitleFont)
{
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
- Font = TitleFont,
Text = Title,
Tag = loc,
BorderColor = this.BorderColor,
@@ -88,6 +101,17 @@ public class TabControl : IRenderObject, IParent
PageIndex = (uint)arg.Tag!;
return Task.CompletedTask;
}
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ _bounds.ForceDistanceUpdate(parent);
+ }
public Color4 TextColor { get; set; } = new(255, 255, 255, 255);
public Color4 BorderColor { get; set; } = new(40, 40, 40, 255);
@@ -98,7 +122,7 @@ public class TabControl : IRenderObject, IParent
public int TabSpace { get; set; } = 5;
public int Border { get; set; } = 10;
public IParent? Parent { get; private set; } = null;
- public Font TitleFont { get; set; } = Label.DefaultFont;
+ public FontInteraction TitleFont { get; set; } = null!;
public Window? Window { get; private set; } = null;
public bool Visible
@@ -125,9 +149,9 @@ public class TabControl : IRenderObject, IParent
public Vector2i Size { get => _bounds.Size; set => _bounds.Size = value; }
public Vector2i Location { get => _bounds.Location; set => _bounds.Location = value; }
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
- public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value; }
+ public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
- public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+ //public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
private uint pgi = 0;
public uint PageIndex
@@ -251,19 +275,14 @@ public class TabControl : IRenderObject, IParent
_bounds.Draw(x,y,w,h);
if (!(Controls.Length >= (PageIndex))) return;
if (!Controls[PageIndex].Loaded) return;
- GL.Scissor(Controls[PageIndex].ScissorLocation.X, Controls[PageIndex].ScissorLocation.Y, Controls[PageIndex].Size.X, Controls[PageIndex].Size.Y);
+ // GL.Scissor(Controls[PageIndex].ScissorLocation.X, Controls[PageIndex].ScissorLocation.Y, Controls[PageIndex].Size.X, Controls[PageIndex].Size.Y);
Controls[PageIndex].Draw(x,y,w,h);
- GL.Scissor(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
+ //GL.Scissor(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
for (int i = 0; i < Buttonts.Length; i++)
Buttonts[i].Draw(x,y,w,h);
}
}
- public Vector2i GetParentRelLocPoint()
- {
- return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
- }
-
public void Clean()
{
for (int i = 0; i < Controls.Length; i++)
diff --git a/GraphicsManager/Objects/Textbox.cs b/GraphicsManager/Objects/Textbox.cs
index c144216..5b53ca6 100755
--- a/GraphicsManager/Objects/Textbox.cs
+++ b/GraphicsManager/Objects/Textbox.cs
@@ -1,12 +1,10 @@
-using System.Timers;
-using System.Timers;
-using GraphicsManager.Enums;
+using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects.Core;
-using OpenTK.Graphics.GL;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using OpenTK.Windowing.GraphicsLibraryFramework;
namespace GraphicsManager.Objects;
@@ -17,12 +15,34 @@ public class Textbox : IRenderObject
private Label _label;
private Label _watermark;
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
- public Textbox()
+
+ public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
+ public Textbox(FontFamily LabelFam, FontFamily WaterFam)
{
_bounds = new RoundedRectangle();
_inside = new RoundedRectangle();
- _label = new Label();
- _watermark = new()
+ _label = new Label(LabelFam);
+ _watermark = new(WaterFam)
+ {
+ Color = new(128, 128, 128, 255)
+ };
+
+ _bounds.MouseEnter += BoundsOnMouseEnter;
+ _bounds.MouseLeave += BoundsOnMouseLeave;
+ }
+
+ public MouseCursor HoverMouse
+ {
+ get => _bounds.HoverMouse;
+ set => _bounds.HoverMouse = value;
+ }
+
+ public Textbox(FontInteraction LabelFam, FontInteraction WaterFam)
+ {
+ _bounds = new RoundedRectangle();
+ _inside = new RoundedRectangle();
+ _label = new Label(LabelFam);
+ _watermark = new(WaterFam)
{
Color = new(128, 128, 128, 255)
};
@@ -41,27 +61,68 @@ public class Textbox : IRenderObject
public int Border { get; set; } = 2;
public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } }
- public Font Font { get => _label.Font; set => _label.Font = value; }
+ public FontInteraction Font { get => _label.Font; }
public string Text
{
get => _label.Text;
set
{
+ int oldh = _label.TrueHeight;
+ _label.Text = value;
if (!string.IsNullOrEmpty(value))
{
- if (!_label.Visible) _label.Visible = true;
+ bool f = false;
+ if (!_label.Visible)
+ {
+ f = true;
+ _label.Visible = true;
+ _label.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2)),
+ TextLocation.TopLeft or _ => new(Location.X + Border + 5, Location.Y + Border + 5)
+ };
+ _watermark.Location = _label.Location;
+ }
if (_watermark.Visible) _watermark.Visible = false;
+ if (!f && TextLocation == TextLocation.TrueCenterLeft && oldh != _label.TrueHeight)
+ {
+ _label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight));
+ _watermark.Location = _label.Location;
+ }
}
else
{
if (_label.Visible) _label.Visible = false;
- if (!_watermark.Visible) _watermark.Visible = true;
+ if (!_watermark.Visible)
+ {
+ _watermark.Visible = true;
+ _watermark.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2)),
+ TextLocation.TopLeft or _ => new(Location.X + Border + 5, Location.Y + Border + 5)
+ };
+ _label.Location = _label.Location;
+ }
}
- _label.Text = value;
}
}
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ _bounds.ForceDistanceUpdate(parent);
+ }
- public Font WatermarkFont { get => _watermark!.Font; set => _watermark.Font = value; }
+ public FontInteraction WatermarkFont { get => _watermark!.Font!; }
public string WatermarkText
{
get
@@ -92,14 +153,34 @@ public class Textbox : IRenderObject
set
{
_bounds.Location = value;
- _label.Location = new(value.X + Border + 5, Location.Y + Border + Border + (((Size.Y - (Radius * 2)) / 2) - (_label.Size.Y / 2)));
- _watermark.Location = _label.Location;
+ if (_watermark.Visible && !string.IsNullOrEmpty(_watermark.Text))
+ {
+ _watermark.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2)),
+ TextLocation.TopLeft or _ => new(value.X + Border + 5, value.Y + Border + 5)
+ };
+ _label.Location = _watermark.Location;
+ }
+ else
+ {
+ _label.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2)),
+ TextLocation.TopLeft or _ => new(value.X + Border + 5, value.Y + Border + 5)
+ };
+ _watermark.Location = _label.Location;
+ }
_inside.Location = new(value.X + Border, value.Y + Border);
}
}
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
- public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value; }
+ public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
public IParent? Parent { get; private set; } = null;
public Window? Window { get; private set; } = null;
public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; }
@@ -156,7 +237,7 @@ public class Textbox : IRenderObject
}
private Vector2i? l = null, s = null;
- public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+ //public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
public void Draw(int x, int y, int w, int h)
{
@@ -169,18 +250,9 @@ public class Textbox : IRenderObject
(int)Window.FloatToInt(Parent.IntToFloat(_inside.Location.Y, true), true));
s = new(_inside.Size.X - _label.Location.X + Location.X,
_inside.Size.Y);
- Console.WriteLine(_inside.Location.Y);
- Console.WriteLine($"x:{l.Value.X} y:{l.Value.Y} xx:{s.Value.X} yy:{s.Value.Y}");
l = new(l.Value.X, 0);
s = new(s.Value.X, Window.Size.Y);
}
- GL.Disable(EnableCap.ScissorTest);
- GL.Enable(EnableCap.ScissorTest);
- GL.Scissor(l.Value.X,
- l.Value.Y,
- s.Value.X,
- s.Value.Y
- );
if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(x,y,w,h);
else _watermark.Draw(x,y,w,h);
}
diff --git a/GraphicsManager/Objects/TexturedTextBox.cs b/GraphicsManager/Objects/TexturedTextBox.cs
new file mode 100755
index 0000000..ec8679d
--- /dev/null
+++ b/GraphicsManager/Objects/TexturedTextBox.cs
@@ -0,0 +1,393 @@
+using GraphicsManager.Enums;
+using GraphicsManager.Interfaces;
+using GraphicsManager.Objects.Core;
+using OpenTK.Graphics.OpenGL4;
+using OpenTK.Mathematics;
+using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
+using OpenTK.Windowing.GraphicsLibraryFramework;
+
+namespace GraphicsManager.Objects;
+
+public class TexturedTextBox : IRenderObject
+{
+ private Rectangle[] _bounds;
+ private Label _label;
+ private Label _watermark;
+ public ContextMenu? ContextMenu { get; set; }
+
+ public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
+
+ public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontFamily LabelFam, FontFamily WaterFam)
+ {
+ _label = new Label(LabelFam);
+ _watermark = new(WaterFam)
+ {
+ Color = new(128, 128, 128, 255)
+ };
+ _bounds = new Rectangle[] {new(Left), new(Middle), new(Right) };
+ }
+
+ public MouseCursor HoverMouse
+ {
+ get => _bounds[0].HoverMouse;
+ set
+ {
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].HoverMouse = value;
+ }
+
+ _watermark.HoverMouse = value;
+ _label.HoverMouse = value;
+ }
+ }
+
+ public int Border { get; set; } = 2;
+
+ public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontInteraction LabelFam, FontInteraction WaterFam)
+ {
+ _label = new Label(LabelFam);
+ _watermark = new(WaterFam)
+ {
+ Color = new(128, 128, 128, 255)
+ };
+ _bounds = new Rectangle[] {new(Left), new(Middle), new(Right) };
+ }
+
+ private bool mouseinside;
+
+ private void WindowOnMouseMove(MouseMoveEventArgs e)
+ {
+ if (Visible &&
+ Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
+ Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
+ {
+ if (!mouseinside)
+ {
+ if (Window!.CurrentTop is null || Window!.CurrentTop == this)
+ {
+ Window!.Cursor = HoverMouse;
+ if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
+ mouseinside = true;
+ }
+ else
+ {
+ mouseinside = false;
+ }
+ }
+ }
+ else
+ {
+ if (mouseinside)
+ {
+ if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
+ if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
+ mouseinside = false;
+ }
+ }
+ }
+
+ //private int CurrentIndex = 0;
+
+ public event Func? WindowLoaded;
+ public event Func? MouseEnter;
+ public event Func? MouseLeave;
+ public object? Tag { get; set; } = null;
+ public ObjectAnchor Anchor { get; set; }
+ public FontInteraction Font { get => _label.Font; }
+ public string Text
+ {
+ get => _label.Text;
+ set
+ {
+ int old = _label.TrueHeight;
+ _label.Text = value;
+ if (!string.IsNullOrEmpty(value))
+ {
+ bool f = false;
+ if (!_label.Visible)
+ {
+ f = true;
+ _label.Visible = true;
+ _label.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2)),
+ _ => new(Location.X + Border + 5, Location.Y + Border + 5)
+ };
+ _watermark.Location = _label.Location;
+ }
+ if (_watermark.Visible) _watermark.Visible = false;
+ if (!f && TextLocation == TextLocation.TrueCenterLeft && old != _label.TrueHeight)
+ {
+ _label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight));
+ _watermark.Location = _label.Location;
+ }
+ }
+ else
+ {
+ if (_label.Visible) _label.Visible = false;
+ if (!_watermark.Visible)
+ {
+ _watermark.Visible = true;
+ _watermark.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2)),
+ _ => new(Location.X + Border + 5, Location.Y + Border + 5)
+ };
+ _label.Location = _label.Location;
+ }
+ }
+ }
+ }
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
+ }
+
+ public FontInteraction WatermarkFont { get => _watermark.Font; }
+ 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; }
+ private Vector2i _size;
+ public Vector2i Size
+ {
+ get
+ {
+ return _size;
+ }
+ set
+ {
+ if (_size == value) return;
+ _bounds[0].Size = new(value.Y);
+ _bounds[1].Size = new(value.X - (_bounds[0].Size.X * 2), value.Y);
+ _bounds[2].Size = _bounds[0].Size;
+ if (_size.X != value.X)
+ {
+ _bounds[1].Location = new(value.Y, 0);
+ _bounds[2].Location = new(_bounds[1].Size.X + _bounds[1].Location.X, 0);
+ }
+ _size = value;
+ }
+ }
+ public Vector2i Location {
+ get => _bounds[0].Location;
+ set
+ {
+ Vector2i diff = _bounds[0].Location - value;
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].Location -= diff;
+ }
+ if (_watermark.Visible && !string.IsNullOrEmpty(_watermark.Text))
+ {
+ _watermark.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2)),
+ _ => new(value.X + Border + 5, value.Y + Border + 5)
+ };
+ _label.Location = _watermark.Location;
+ }
+ else
+ {
+ _label.Location = TextLocation switch
+ {
+ TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
+ TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
+ TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2)),
+ _ => new(value.X + Border + 5, value.Y + Border + 5)
+ };
+ _watermark.Location = _label.Location;
+ }
+ }
+ }
+
+ public Vector2 SizeAsFloat { get; } = new();
+ public Vector2 LocationAsFloat { get => _bounds[0].LocationAsFloat; }
+ public Vector2i Distance { get; set; }
+ public IParent? Parent { get; private set; }
+ public Window? Window { get; private set; }
+ public Color4 TextColor { get => _label.Color; set => _label.Color = value; }
+ public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; }
+
+ public bool Visible
+ {
+ get => _bounds[0].Visible;
+ set
+ {
+ if (value == _bounds[0].Visible) return;
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].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;
+
+ public void Clean()
+ {
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].Clean();
+ }
+ _label.Clean();
+ _watermark.Clean();
+ }
+
+ //private Vector2i? l, s;
+
+ public void Draw(int x, int y, int w, int h)
+ {
+ if (!Visible || !Loaded) return;
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].Draw(x,y,w,h);
+ }
+ int nx = x, ny = y, nw = w, nh = h;
+ if (Location.X + Border > nw)
+ return;
+ else
+ {
+ nx += (Location.X + Border);
+ nw -= (Location.X + Border);
+ if (Size.X - Border < nw)
+ nw = Size.X - Border;
+ }
+
+ if (Location.Y + Border > nh)
+ return;
+ else
+ {
+ ny += (Location.Y + Border);
+ nh -= (Location.Y + Border);
+ if (Size.Y - Border < nh)
+ nh = Size.Y - Border;
+ }
+ if (nh < 1 || nw < 1) return;
+ GL.Scissor(nx,ny,nw,nh);
+ if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(nx,ny,nw,nh);
+ else _watermark.Draw(nx,ny,nw,nh);
+ }
+
+ public void LoadToParent(IParent parent, Window window)
+ {
+ if (Loaded) return;
+ Parent = parent;
+ Window = window;
+ Window.MouseDown += Window_MouseDown;
+ Window.KeyDown += Window_KeyDown;
+ Window.TextInput += WindowOnTextInput;
+ Loaded = true;
+ if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
+ for (int i = 0; i < _bounds.Length; i++)
+ {
+ _bounds[i].LoadToParent(Parent, Window);
+ }
+ _label.LoadToParent(Parent, Window);
+ _watermark.LoadToParent(Parent, Window);
+ Window.MouseMove += WindowOnMouseMove;
+ Location = Location;
+ if (WindowLoaded is not null) WindowLoaded.Invoke(this);
+ }
+
+ private void WindowOnTextInput(TextInputEventArgs obj)
+ {
+ if (!use) return;
+ Text += obj.AsString;
+ }
+
+ private bool use;
+ public event Func? KeyPress;
+
+ public void UnFocus()
+ {
+ use = false;
+ if (Window is not null && Window.focused == this)
+ Window.focused = null;
+ }
+ public void Focus()
+ {
+ if (Window is not null)
+ {
+ if (Window.focused is not null)
+ {
+ Window.focused.UnFocus();
+ }
+
+ Window.focused = this;
+ use = true;
+ }
+ }
+ private void Window_KeyDown(KeyboardKeyEventArgs obj)
+ {
+ if (!use) return;
+ if (obj.Key == Keys.CapsLock || obj.Key == Keys.Menu || obj.Key == Keys.LeftSuper || obj.Key == Keys.RightSuper || obj.Key == Keys.End || obj.Key == Keys.Home || obj.Key == Keys.PageDown || obj.Key == Keys.PageUp || obj.Key == Keys.Insert || obj.Key == Keys.Up || obj.Key == Keys.Down || obj.Key == Keys.Left || obj.Key == Keys.Right) return;
+ if (obj.Key == Keys.Backspace || obj.Key == Keys.Delete)
+ {
+ if (!(Text.Length > 0)) return;
+ Text = Text.Remove(Text.Length - 1, 1);
+ }
+
+ if (obj.Key == Keys.V && obj.Control && Window is not null) Text += Window.ClipboardString;
+ if (KeyPress is not null) _ = KeyPress.Invoke(obj);
+ }
+
+ private void Window_MouseDown(MouseButtonEventArgs e)
+ {
+ if (Visible &&
+ e.Button == MouseButton.Button1 &&
+ Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
+ Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((int)Window?.MousePosition.Y!, true) &&
+ Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((int)Window?.MousePosition.Y!, true))
+ {
+ use = true;
+ Focus();
+ if (Clicked is not null) Clicked.Invoke(this);
+ }
+ else use = false;
+ }
+}
diff --git a/GraphicsManager/Objects/UserControl.cs b/GraphicsManager/Objects/UserControl.cs
index fbcb67f..f75bb08 100755
--- a/GraphicsManager/Objects/UserControl.cs
+++ b/GraphicsManager/Objects/UserControl.cs
@@ -4,6 +4,7 @@ using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
namespace GraphicsManager.Objects;
@@ -19,6 +20,19 @@ public class UserControl : IRenderObject, IParent
_bounds.MouseLeave += BoundsOnMouseLeave;
}
+ public MouseCursor HoverMouse
+ {
+ get => _bounds.HoverMouse;
+ set
+ {
+ _bounds.HoverMouse = value;
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ if (Controls[i].HoverMouse == MouseCursor.Default) Controls[i].HoverMouse = value;
+ }
+ }
+ }
+
public void TryDraw()
{
if (!BlockDraw && Parent is not null) Parent.TryDraw();
@@ -65,8 +79,13 @@ public class UserControl : IRenderObject, IParent
{
BlockDraw = true;
_bounds.Size = value;
- ParentResize(new());
- if (Parent is not null) Parent.TryDraw();
+
+ if (Parent is not null)
+ {
+ if (Loaded) ParentResize(new(Parent.Size));
+ Parent.TryDraw();
+ }
+ else ParentResize(new());
BlockDraw = false;
}
}
@@ -93,11 +112,23 @@ public class UserControl : IRenderObject, IParent
BlockDraw = false;
}
}
- public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+
+ public void ForceDistanceUpdate()
+ {
+ if (Parent is null) return;
+ ForceDistanceUpdate(Parent);
+ }
+
+ public void ForceDistanceUpdate(IParent parent)
+ {
+ _bounds.ForceDistanceUpdate(parent);
+ }
+
+ //public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
public Vector2i Position => Location;
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
- public Vector2i Distance { get => _bounds.Distance; }
+ public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
public event Func? Clicked;
public event Func? WindowLoaded;
public event Func? MouseEnter;
@@ -125,11 +156,46 @@ public class UserControl : IRenderObject, IParent
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
}
+ public bool dw;
+
public void Draw(int x, int y, int w, int h)
{
if (Loaded)
{
- _bounds.Draw(x,y,w,h);
+ int nx = x, ny = y, nw = w, nh = h;
+ if (Location.X > nw)
+ return;
+ else
+ {
+ nx += Location.X;
+ nw -= Location.X;
+ if (Size.X < nw)
+ nw = Size.X;
+ }
+
+ if (Location.Y > nh)
+ return;
+ else
+ {
+ ny += Location.Y;
+ nh -= Location.Y;
+ if (Size.Y < nh)
+ nh = Size.Y;
+ }
+ if (dw) Console.WriteLine("UserControl\nLoc: {0}\nSize: {1}\n\nX: {2}\nY: {3}\nW: {4}\nH:{5}\n\nX: {6}\nY: {7}\nW: {8}\nH:{9}",
+ Location,
+ Size,
+ x,
+ y,
+ w,
+ h,
+ nx,
+ ny,
+ nw,
+ nh);
+ if (nw == 0 || nh == 0) return;
+ GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
+ _bounds.Draw(nx,ny,nw,nh);
IEnumerable needload = Controls.Where(a => a.Loaded == false);
@@ -145,25 +211,15 @@ public class UserControl : IRenderObject, IParent
}
for (int i = 0; i < Controls.Length; i++)
{
- Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y);
- Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y);
- if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y);
- if (laff.X < x) laff = new(x, laff.Y);
- if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y);
- if (laff.Y < y) laff = new(laff.X, y);
- if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y);
- if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y);
- GL.Scissor(laff.X, laff.Y, saff.X, saff.Y);
- Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
+ if (Controls[i] is not IParent)
+ {
+ GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
+ }
+ Controls[i].Draw(nx, ny, nw, nh);
}
}
}
- public Vector2i GetParentRelLocPoint()
- {
- return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
- }
-
public void Clean()
{
for (int i = 0; i < Controls.Length; i++)
diff --git a/GraphicsManager/Resources/Shaders/AlphaChannel.frag b/GraphicsManager/Resources/Shaders/AlphaChannel.frag
new file mode 100755
index 0000000..7d8fbd2
--- /dev/null
+++ b/GraphicsManager/Resources/Shaders/AlphaChannel.frag
@@ -0,0 +1,13 @@
+#version 330
+out vec4 outputColor;
+
+in vec4 vertexColor;
+in vec2 texCoord;
+
+uniform sampler2D texture1;
+
+void main(void)
+{
+ float obj = texture(texture1, texCoord).r;
+ outputColor = vec4(vertexColor.r, vertexColor.g, vertexColor.b, vertexColor.a*obj);
+}
\ No newline at end of file
diff --git a/GraphicsManager/Resources/Shaders/AlphaChannel.vert b/GraphicsManager/Resources/Shaders/AlphaChannel.vert
new file mode 100755
index 0000000..b436dab
--- /dev/null
+++ b/GraphicsManager/Resources/Shaders/AlphaChannel.vert
@@ -0,0 +1,12 @@
+#version 330
+layout(location = 0) in vec3 aPosition;
+layout(location = 1) in vec2 aTexCoord;
+out vec2 texCoord;
+out vec4 vertexColor;
+uniform vec4 objColor;
+void main(void)
+{
+ texCoord = aTexCoord;
+ gl_Position = vec4(aPosition, 1.0);
+ vertexColor = objColor;
+}
\ No newline at end of file
diff --git a/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag
new file mode 100755
index 0000000..ba4c6ee
--- /dev/null
+++ b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag
@@ -0,0 +1,14 @@
+#version 460
+out vec4 outputColor;
+
+in vec2 texCoord;
+
+layout(binding = 0) uniform sampler2D texture1;
+layout(binding = 1) uniform sampler2D texture2;
+
+void main(void)
+{
+ float obj = texture(texture1, texCoord).r;
+ vec4 text = texture(texture2, 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
new file mode 100755
index 0000000..d5a61d1
--- /dev/null
+++ b/GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert
@@ -0,0 +1,9 @@
+#version 460
+layout(location = 0) in vec3 aPosition;
+layout(location = 1) in vec2 aTexCoord;
+out vec2 texCoord;
+void main(void)
+{
+ texCoord = aTexCoord;
+ gl_Position = vec4(aPosition, 1.0);
+}
\ No newline at end of file
diff --git a/GraphicsManager/Resources/Textures/Missing.png b/GraphicsManager/Resources/Textures/Missing.png
new file mode 100644
index 0000000..ccac780
Binary files /dev/null and b/GraphicsManager/Resources/Textures/Missing.png differ
diff --git a/GraphicsManager/Structs/Character.cs b/GraphicsManager/Structs/Character.cs
index 2325118..1312d4c 100755
--- a/GraphicsManager/Structs/Character.cs
+++ b/GraphicsManager/Structs/Character.cs
@@ -9,4 +9,5 @@ public struct Character
public Vector2 Size { get; set; }
public Vector2 Bearing { get; set; }
public int Advance { get; set; }
+ public double AdvanceY { get; set; }
}
diff --git a/GraphicsManager/Tools.cs b/GraphicsManager/Tools.cs
index ce3dad6..50cde9c 100755
--- a/GraphicsManager/Tools.cs
+++ b/GraphicsManager/Tools.cs
@@ -1,9 +1,61 @@
-using System.Reflection;
+using System.Diagnostics;
+using System.Reflection;
namespace GraphicsManager;
public class Tools
{
+ public static void AddFontsToList(ref List List, string folder)
+ {
+ DirectoryInfo di = new(folder);
+ foreach (FileInfo file in di.GetFiles())
+ {
+ if (!file.FullName.EndsWith(".otf") && !file.FullName.EndsWith(".ttf")) continue;
+
+ List.Add(file.FullName);
+ }
+ foreach (DirectoryInfo direc in di.GetDirectories())
+ {
+ AddFontsToList(ref List, direc.FullName);
+ }
+ }
+
+ public static string[] GetFamilyList(string Command)
+ {
+ Process proc = new()
+ {
+ StartInfo = new()
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{Command}\"",
+ RedirectStandardOutput = true,
+ }
+ };
+ proc.Start();
+ proc.WaitForExit();
+ List bbb = proc.StandardOutput.ReadToEnd().Split($"{Environment.NewLine}").ToList();
+ bbb.RemoveAt(bbb.Count - 1);
+ return bbb.ToArray();
+ }
+
+ public static string[] GetFontList(string Command)
+ {
+ Process proc = new()
+ {
+ StartInfo = new()
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{Command}\"",
+ RedirectStandardOutput = true,
+ }
+ };
+ proc.Start();
+ proc.WaitForExit();
+ List bbb = proc.StandardOutput.ReadToEnd().Split($": {Environment.NewLine}").ToList();
+ bbb.RemoveAt(bbb.Count - 1);
+ return bbb.ToArray();
+ }
+
public static byte[] GetResourceBytes(Assembly Assembly, string Resource)
{
Stream str = Assembly.GetManifestResourceStream(Resource)!;
@@ -14,6 +66,12 @@ public class Tools
ms.Dispose();
return result;
}
+
+ public static Stream GetResourceStream(Assembly Assembly, string Resource)
+ {
+ Stream str = Assembly.GetManifestResourceStream(Resource)!;
+ return str;
+ }
public static string GetResourceString(Assembly Assembly, string Resource)
{
@@ -25,6 +83,8 @@ public class Tools
return result;
}
+ public static Stream GetResourceStream(string Resource) => GetResourceStream(typeof(Tools).Assembly, Resource);
+
public static byte[] GetResourceBytes(string Resource) => GetResourceBytes(typeof(Tools).Assembly, Resource);
public static string GetResourceString(string Resource) => GetResourceString(typeof(Tools).Assembly, Resource);
diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs
index bd12fd1..f798a9c 100755
--- a/GraphicsManager/Window.cs
+++ b/GraphicsManager/Window.cs
@@ -6,6 +6,7 @@ using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
+using OpenTK.Windowing.Common.Input;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
@@ -32,6 +33,7 @@ public class Window : NativeWindow , IParent
}
internal IRenderObject? focused;
+ public IRenderObject? CurrentTop { get; set;}
public void CenterWindow(int mon)
{
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
@@ -52,46 +54,66 @@ public class Window : NativeWindow , IParent
internal 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 Window(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings)
{
TextureManager = TextureManager.GetTextureManager(Context);
Context.MakeCurrent();
- if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
+ 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 (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());
last = WindowState;
KeyDown += OnKeyDownn;
}
-
-private WindowState last;
-private bool fs = false;
-private Vector2i os, loc;
-private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
-{
- if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
- GLFW.WindowHint(WindowHintBool.AutoIconify, true);
- if (WindowState != WindowState.Normal) last = WindowState;
- Console.WriteLine(fs);
- switch (fs)
+
+ private WindowState last;
+ private bool fs = false;
+ private Vector2i os, loc;
+ public bool CustomF11 = true;
+ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
{
- case false:
- loc = Location;
- os = Size;
- WindowBorder = WindowBorder.Hidden;
- Location = new(4090, 0);
- fs = true;
- break;
- case true:
- WindowBorder = WindowBorder.Resizable;
-
- Size = os;
- Location = loc;
- fs = false;
- break;
+ if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
+ if (CustomF11)
+ {
+ GLFW.WindowHint(WindowHintBool.AutoIconify, true);
+ if (WindowState != WindowState.Normal) last = WindowState;
+ switch (fs)
+ {
+ case false:
+ loc = Location;
+ os = Size;
+ WindowBorder = WindowBorder.Hidden;
+ Location = new(4090, 0);
+ fs = true;
+ break;
+ case true:
+ WindowBorder = WindowBorder.Resizable;
+ GLFW.RestoreWindow(this.WindowPtr);
+ Size = os;
+ Location = loc;
+ fs = false;
+ break;
+ }
+ }
+ else
+ {
+ switch (fs)
+ {
+ case false:
+ WindowState = WindowState.Fullscreen;
+ fs = true;
+ break;
+ case true:
+ WindowState = WindowState.Normal;
+ fs = false;
+ break;
+ }
+ }
}
-}
public Window() : this(new NativeWindowSettings())
{
@@ -186,35 +208,39 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
}
#endregion
+ public void ForceUpdate(ResizeEventArgs e)
+ {
+ BlockDraw = true;
+ for (int i = 0; i < Controls.Length; i++)
+ {
+ if (!Controls[i].Loaded) continue;
+ bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
+ bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
+ bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
+ bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
+ if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
+ if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
+ int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
+ int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
+ int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
+ int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
+ Controls[i].Size = new(sx, sy);
+ Controls[i].Location = new(lx, ly);
+ if (Controls[i] is IParent parent)
+ {
+ parent.ParentResize(e);
+ }
+ }
+ DrawFrame();
+ BlockDraw = false;
+ }
+
public void ParentResize(ResizeEventArgs e)
{
base.OnResize(e);
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
- BlockDraw = true;
-
GL.Viewport(0, 0, e.Width, e.Height);
- for (int i = 0; i < Controls.Length; i++)
- {
- if (!Controls[i].Loaded) continue;
- bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
- bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
- bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
- bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
- if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
- if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
- int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
- int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
- int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
- int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
- Controls[i].Size = new(sx, sy);
- Controls[i].Location = new(lx, ly);
- if (Controls[i] is IParent parent)
- {
- parent.ParentResize(e);
- }
- }
- DrawFrame();
- BlockDraw = false;
+ ForceUpdate(e);
}
private int frame = 0;
@@ -307,19 +333,17 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
{
invokes.Enqueue(A);
}
-
- public Vector2i GetParentRelLocPoint()
- {
- return new(0);
- }
public void DrawFrame()
{
Context.MakeCurrent();
frame++;
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.Scissor(0, 0, Size.X, Size.Y);
+
GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, (BackgroundColor.A * -1) + 1);
IEnumerable needload = Controls.Where(a => a.Loaded == false);
@@ -337,21 +361,9 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
for (int i = 0; i < Controls.Length; i++)
{
if (!Controls[i].Loaded) continue;
- GL.Disable(EnableCap.ScissorTest);
- if (Controls[i] is not Label)
- {
- GL.Enable(EnableCap.ScissorTest);
- GL.Scissor(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y, Controls[i].Size.X, Controls[i].Size.Y);
- Controls[i].Draw(0,0,Size.X, Size.Y);
- }
- else
- {
- GL.Enable(EnableCap.ScissorTest);
- GL.Scissor(0, 0, Size.X, Size.Y);
- Controls[i].Draw(0,0,Size.X, Size.Y);
- }
+ GL.Scissor(0, 0, Size.X, Size.Y);
+ Controls[i].Draw(0,0,Size.X, Size.Y);
}
- GL.Disable(EnableCap.ScissorTest);
Context.SwapBuffers();
}