Bugs & Features.
Mainly bug fixes with a few new shaders and controls.
This commit is contained in:
parent
b88cea7363
commit
448e0f670f
14
GraphicsManager/Enums/FontSize.cs
Normal file
14
GraphicsManager/Enums/FontSize.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace GraphicsManager.Enums;
|
||||
|
||||
public enum FontSize : byte
|
||||
{
|
||||
Thin,
|
||||
ExtraLight,
|
||||
Light,
|
||||
Regular,
|
||||
Medium,
|
||||
SemiBold,
|
||||
Bold,
|
||||
ExtraBold,
|
||||
Black,
|
||||
}
|
9
GraphicsManager/Enums/TextLocation.cs
Normal file
9
GraphicsManager/Enums/TextLocation.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace GraphicsManager.Enums;
|
||||
|
||||
public enum TextLocation
|
||||
{
|
||||
TopLeft,
|
||||
PxLeft,
|
||||
TrueCenterLeft,
|
||||
PostiveTureCenterLeft
|
||||
}
|
@ -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" />
|
||||
|
6
GraphicsManager/Interfaces/ILabel.cs
Normal file
6
GraphicsManager/Interfaces/ILabel.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace GraphicsManager.Interfaces;
|
||||
|
||||
public interface ILabel : IRenderObject
|
||||
{
|
||||
|
||||
}
|
@ -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; }
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -9,5 +9,5 @@ namespace GraphicsManager.Interfaces;
|
||||
|
||||
public interface ITextureObject : IRenderObject
|
||||
{
|
||||
public Texture? Texture { get; }
|
||||
public List<Texture> Textures { get; }
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
136
GraphicsManager/Objects/Core/FontFamily.cs
Normal file
136
GraphicsManager/Objects/Core/FontFamily.cs
Normal 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()
|
||||
{
|
||||
}
|
||||
}
|
149
GraphicsManager/Objects/Core/FontInteraction.cs
Normal file
149
GraphicsManager/Objects/Core/FontInteraction.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
}*/
|
||||
}
|
@ -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()
|
||||
|
@ -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;
|
||||
|
494
GraphicsManager/Objects/RainbowLabel.cs
Executable file
494
GraphicsManager/Objects/RainbowLabel.cs
Executable 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;
|
||||
}
|
@ -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; } }
|
||||
|
@ -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; }
|
||||
|
@ -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; } }
|
||||
|
@ -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++)
|
||||
|
@ -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);
|
||||
}
|
||||
|
393
GraphicsManager/Objects/TexturedTextBox.cs
Executable file
393
GraphicsManager/Objects/TexturedTextBox.cs
Executable 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;
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
13
GraphicsManager/Resources/Shaders/AlphaChannel.frag
Executable file
13
GraphicsManager/Resources/Shaders/AlphaChannel.frag
Executable 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);
|
||||
}
|
12
GraphicsManager/Resources/Shaders/AlphaChannel.vert
Executable file
12
GraphicsManager/Resources/Shaders/AlphaChannel.vert
Executable 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;
|
||||
}
|
14
GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag
Executable file
14
GraphicsManager/Resources/Shaders/AlphaChannelTexture.frag
Executable 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);
|
||||
}
|
9
GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert
Executable file
9
GraphicsManager/Resources/Shaders/AlphaChannelTexture.vert
Executable 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);
|
||||
}
|
BIN
GraphicsManager/Resources/Textures/Missing.png
Normal file
BIN
GraphicsManager/Resources/Textures/Missing.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 B |
@ -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; }
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,13 +54,16 @@ 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;
|
||||
@ -68,12 +73,14 @@ public class Window : NativeWindow , IParent
|
||||
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();
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user