Bugs & Features.

Mainly bug fixes with a few new shaders and controls.
This commit is contained in:
JacobTech 2023-08-21 10:57:06 -04:00
parent b88cea7363
commit 448e0f670f
32 changed files with 2120 additions and 336 deletions

View File

@ -0,0 +1,14 @@
namespace GraphicsManager.Enums;
public enum FontSize : byte
{
Thin,
ExtraLight,
Light,
Regular,
Medium,
SemiBold,
Bold,
ExtraBold,
Black,
}

View File

@ -0,0 +1,9 @@
namespace GraphicsManager.Enums;
public enum TextLocation
{
TopLeft,
PxLeft,
TrueCenterLeft,
PostiveTureCenterLeft
}

View File

@ -10,7 +10,7 @@
<IncludeSymbols>False</IncludeSymbols>
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.5-alpha08</Version>
<Version>1.0.6-alpha89</Version>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
@ -39,6 +39,7 @@
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" />
</ItemGroup>
<Target Name="CustomActionsAfterPack" AfterTargets="Pack">
<Message Text="Actions AfterPack: $(PackageId).$(PackageVersion).nupkg" Importance="high" />
<Exec Command="nuget push -Source https://nuget.jacobtech.com/v3/index.json bin/Release/$(PackageId).$(PackageVersion).nupkg" />

View File

@ -0,0 +1,6 @@
namespace GraphicsManager.Interfaces;
public interface ILabel : IRenderObject
{
}

View File

@ -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; }
}

View File

@ -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; }

View File

@ -9,5 +9,5 @@ namespace GraphicsManager.Interfaces;
public interface ITextureObject : IRenderObject
{
public Texture? Texture { get; }
public List<Texture> Textures { get; }
}

View File

@ -4,7 +4,7 @@ namespace GraphicsManager.Objects.Core;
public class ControlList
{
private List<IRenderObject> _internal = new();
internal List<IRenderObject> _internal = new();
private bool Clearing = false;
public IRenderObject this[int Index] => _internal[Index];
@ -21,11 +21,14 @@ public class ControlList
internal event Func<IRenderObject, Task>? ControlAdded;
internal event Func<Task>? ControlRemoved;
public void Remove(IRenderObject item)
public void Remove(IRenderObject item, bool purge = true)
{
_internal.Remove(item);
if (purge)
{
item.Clean();
item = null!;
}
GC.Collect();
if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke();
}
@ -36,14 +39,17 @@ 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++)
{
if (purge)
{
_internal[i].Clean();
_internal[i] = null!;
}
}
_internal.Clear();
GC.Collect();
Clearing = false;

View File

@ -16,6 +16,7 @@ public class Font
private static List<Font> 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<Font> 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; }

View File

@ -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<Task>? ReloadUI;
private FontSize fs = FontSize.Thin;
private uint ph = 12;
private bool i;
internal Dictionary<FontSize, Tuple<string, Font?>> InternalFonts = new();
internal Dictionary<FontSize, Tuple<string, Font?>> InternalFontsi = new();
internal Font Font = null!;
public static Task<FontFamily> 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<FontFamily> 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<FontFamily> LoadFontFamily(string Dir, string Family)
{
FontFamily f = new();
return f;
}
private FontFamily()
{
}
}

View File

@ -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<Task>? 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<string, Font?>? 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<string, Font?>? 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<string, Font?> gcl(Dictionary<FontSize, Tuple<string, Font?>> thisList, FontSize thisValue, out FontSize fs)
{
Dictionary<FontSize, Tuple<string, Font?>>.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<string, Font?> 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();
}
}
}

View File

@ -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;
@ -94,6 +97,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)
{
int location = GL.GetUniformLocation(Handle, name);

View File

@ -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,35 +32,29 @@ public class Texture
{
public static readonly Dictionary<IGLFWGraphicsContext, Shader> TextureShader = new ();
private static Configuration imgcfg = new(
new PngConfigurationModule(),
new JpegConfigurationModule(),
new GifConfigurationModule(),
new BmpConfigurationModule(),
new PbmConfigurationModule(),
new TgaConfigurationModule(),
new TiffConfigurationModule(),
new WebpConfigurationModule())
{
PreferContiguousImageBuffers = true
};
public int handel;
public Vector2i? RawSize = null;
public int Location { get; set; } = 1;
internal Texture(byte[] File, bool Rounded = false)
private Texture(byte[] pixels, int Width, int Height)
{
Image<Rgba32> image = Image.Load<Rgba32>(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);
});
}
Span<byte> pixels = new byte[4 * image.Width * image.Height].AsSpan();
image.CopyPixelDataTo(pixels);
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);
@ -63,16 +62,96 @@ public class Texture
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
}
private Texture(Image<Rgba32> image, Memory<Rgba32> 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<Rgba32> image = Image.Load<Rgba32>(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<byte>();
image.Dispose();
return t;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
internal static Texture GetTexture(Stream File, TextureManager tm, bool Missing)
{
try
{
Image<Rgba32> image = Image.Load<Rgba32>(imgcfg, File);
image.Mutate(x =>
{
x.Flip(FlipMode.Vertical);
});
File.Position = 0;
Texture? t;
if (image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> m))
{
t = new(image, m);
image.Dispose();
m = null;
}
else
{
_ = image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> 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<string> 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<uint, Character>());
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);
}
}

View File

@ -9,7 +9,7 @@ public class TextureManager
{
public static readonly Dictionary<IGLFWGraphicsContext, TextureManager> TextureManagers = new();
public readonly Dictionary<byte[], Texture> TextureHashMap = new();
private List<Texture> _textures = new();
public static TextureManager GetTextureManager(IGLFWGraphicsContext context)
{
@ -31,16 +31,21 @@ public class TextureManager
Context = context;
}
public IReadOnlyList<Texture> Textures { get => TextureHashMap.Values.ToList().AsReadOnly(); }
public IReadOnlyList<Texture> Textures { get => _textures.AsReadOnly(); }
public void RemoveTexture(Texture Texture)
{
foreach(KeyValuePair<byte[], Texture> 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<byte> hash2 = SHA256.HashData(Texture).ToList();
@ -50,5 +55,5 @@ public class TextureManager
Context.MakeCurrent();
TextureHashMap.Add(hash, new(Texture, Rounded));
return TextureHashMap[hash];
}
}*/
}

View File

@ -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;
}
@ -142,6 +171,12 @@ public class FlowLayout : IRenderObject, IParent
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<IRenderObject, Task>? Clicked;
public event Action<MouseButtonEventArgs> MouseDown;
public event Action<KeyboardKeyEventArgs> KeyDown;
@ -252,6 +287,17 @@ public class FlowLayout : IRenderObject, IParent
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;
private Queue<Action> scrols = new();
@ -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<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
if (needload.Any())
@ -419,23 +502,13 @@ 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);
}
}
}
public Vector2i GetParentRelLocPoint()
if (Controls[i] is not IParent)
{
return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
}
Controls[i].Draw(nx, ny, nw, nh);
}
}
}
public void Clean()

View File

@ -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<IGLFWGraphicsContext, Shader> 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<IGLFWGraphicsContext, Dictionary<Font, Dictionary<uint, Character>>> _characters = new();
public static readonly Dictionary<IGLFWGraphicsContext, Dictionary<FontInteraction, Dictionary<uint, Character>>> _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;
@ -103,21 +121,29 @@ public class Label : IRenderObject
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,10 +289,15 @@ 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<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
public void LoadToParent(IParent window, Window win)
@ -339,6 +372,8 @@ 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)
{
@ -348,15 +383,30 @@ public class Label : 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);
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<IRenderObject, Task>? Clicked;
public event Func<IRenderObject, Task>? WindowLoaded;

View File

@ -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<int, int, int> 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<IGLFWGraphicsContext, Tuple<int, int, int>> 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<uint, Character>());
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<int, int, int> 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<IRenderObject, Task>? Clicked;
public event Func<IRenderObject, Task>? WindowLoaded;
public event Func<IRenderObject, Task>? MouseEnter;
public event Func<IRenderObject, Task>? MouseLeave;
public object? Tag { get; set; } = null;
public bool Loaded { get; private set; } = false;
}

View File

@ -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<IGLFWGraphicsContext, Shader> DefaultShader = new();
public static readonly Dictionary<IGLFWGraphicsContext, Shader> DefaultAlphaShader = new();
public static readonly Dictionary<IGLFWGraphicsContext, Shader> DefaultAlphaTextureShader = new();
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
public Texture? Texture { get; set; }
public List<Texture> Textures { get; set; } = new();
public ContextMenu? ContextMenu { get; set; } = null;
public event Func<string[], Task>? 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,27 +70,42 @@ 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()
{
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
@ -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,15 +171,30 @@ 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);
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 IParent? Parent { get; private set; }
public Window? Window { get; private set; }
@ -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<IRenderObject, Task>? Clicked;
public bool Loaded { get; private set; } = false;
public bool Loaded { get; private set; }
public event Func<IRenderObject, Task>? WindowLoaded;
public event Func<IRenderObject, Task>? MouseEnter;
public event Func<IRenderObject, Task>? 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; } }

View File

@ -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; }

View File

@ -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,15 +167,30 @@ 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);
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 IParent? Parent { get; private set; }
public Window? Window { get; private set; }
@ -249,11 +263,24 @@ public class RoundedRectangle : IRenderObject
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<IRenderObject, Task>? 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; } }

View File

@ -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,
@ -89,6 +102,17 @@ public class TabControl : IRenderObject, IParent
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);
public Color4 SelectedColor { get; set; } = Color4.DarkCyan;
@ -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++)

View File

@ -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 Font WatermarkFont { get => _watermark!.Font; set => _watermark.Font = value; }
public void ForceDistanceUpdate()
{
if (Parent is null) return;
ForceDistanceUpdate(Parent);
}
public void ForceDistanceUpdate(IParent parent)
{
_bounds.ForceDistanceUpdate(parent);
}
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)));
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);
}

View File

@ -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<IRenderObject, Task>? WindowLoaded;
public event Func<IRenderObject, Task>? MouseEnter;
public event Func<IRenderObject, Task>? 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<IRenderObject, Task>? 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<KeyboardKeyEventArgs, Task>? 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;
}
}

View File

@ -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<IRenderObject, Task>? Clicked;
public event Func<IRenderObject, Task>? WindowLoaded;
public event Func<IRenderObject, Task>? 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<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
@ -145,23 +211,13 @@ 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);
}
}
}
public Vector2i GetParentRelLocPoint()
if (Controls[i] is not IParent)
{
return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
}
Controls[i].Draw(nx, ny, nw, nh);
}
}
}
public void Clean()

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

View File

@ -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; }
}

View File

@ -1,9 +1,61 @@
using System.Reflection;
using System.Diagnostics;
using System.Reflection;
namespace GraphicsManager;
public class Tools
{
public static void AddFontsToList(ref List<string> 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<string> 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<string> 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)!;
@ -15,6 +67,12 @@ public class Tools
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)
{
Stream str = Assembly.GetManifestResourceStream(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);

View File

@ -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,28 +54,33 @@ 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)
{
private WindowState last;
private bool fs = false;
private Vector2i os, loc;
public bool CustomF11 = true;
private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
{
if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
if (CustomF11)
{
GLFW.WindowHint(WindowHintBool.AutoIconify, true);
if (WindowState != WindowState.Normal) last = WindowState;
Console.WriteLine(fs);
switch (fs)
{
case false:
@ -85,13 +92,28 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
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,13 +208,9 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
}
#endregion
public void ParentResize(ResizeEventArgs e)
public void ForceUpdate(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;
@ -217,6 +235,14 @@ private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
BlockDraw = false;
}
public void ParentResize(ResizeEventArgs e)
{
base.OnResize(e);
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
GL.Viewport(0, 0, e.Width, e.Height);
ForceUpdate(e);
}
private int frame = 0;
public void ReportSizeUpdate(IRenderObject Control)
@ -308,18 +334,16 @@ 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<IRenderObject> 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.Disable(EnableCap.ScissorTest);
Context.SwapBuffers();
}