Rendering Optimizations
This commit is contained in:
parent
3595cfc27d
commit
ec6d6064b1
@ -205,7 +205,7 @@ public class FPSWindow : GameWindow , IWindow
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void ForceUpdate(ResizeEventArgs e)
|
||||
public void ForceUpdate()
|
||||
{
|
||||
BlockDraw = true;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
@ -225,19 +225,15 @@ public class FPSWindow : GameWindow , IWindow
|
||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
||||
if (Controls[i] is IParent parent)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
parent.ParentResize();
|
||||
}
|
||||
}
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
||||
public void ParentResize(ResizeEventArgs e)
|
||||
public void ParentResize()
|
||||
{
|
||||
base.OnResize(e);
|
||||
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
||||
GL.Viewport(0, 0, e.Width, e.Height);
|
||||
Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
|
||||
ForceUpdate(e);
|
||||
ForceUpdate();
|
||||
}
|
||||
|
||||
private int frame = 0;
|
||||
@ -249,7 +245,11 @@ public class FPSWindow : GameWindow , IWindow
|
||||
|
||||
protected override void OnResize(ResizeEventArgs e)
|
||||
{
|
||||
ParentResize(e);
|
||||
base.OnResize(e);
|
||||
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
||||
GL.Viewport(0, 0, e.Width, e.Height);
|
||||
Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
|
||||
ParentResize();
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
@ -400,7 +400,7 @@ public class FPSWindow : GameWindow , IWindow
|
||||
{
|
||||
if (!Controls[i].Loaded) continue;
|
||||
GL.Scissor(0, 0, Size.X, Size.Y);
|
||||
Controls[i].Draw(0,0,Size.X, Size.Y);
|
||||
Controls[i].Draw(0,0,0,0,Size.X, Size.Y);
|
||||
}
|
||||
Context.SwapBuffers();
|
||||
base.OnRenderFrame(args);
|
||||
|
@ -10,7 +10,7 @@
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Version>1.0.9-alpha83</Version>
|
||||
<Version>1.1.0-alpha50</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
@ -11,7 +11,7 @@ public interface IParent
|
||||
public ControlList Controls { get; }
|
||||
public IParent? Parent { get; }
|
||||
public Vector2i Size { get; }
|
||||
public void ParentResize(ResizeEventArgs e);
|
||||
public void ParentResize();
|
||||
public float IntToWindow(float p, bool Y = false);
|
||||
public void TryDraw();
|
||||
public void ReportSizeUpdate(IRenderObject Control);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using GraphicsManager.Enums;
|
||||
using GraphicsManager.Objects;
|
||||
using GraphicsManager.Objects.Core;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Windowing.Common;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
@ -17,13 +18,19 @@ public interface IRenderObject
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public bool Loaded { get; }
|
||||
public void LoadToParent(IParent Parent, IWindow Window);
|
||||
public void Draw(int x, int y, int w, int h);
|
||||
public void Draw(int x, int y, int sx, int sy, int sw, int sh);
|
||||
public MouseCursor HoverMouse { get; set; }
|
||||
public void SetSize(int wh);
|
||||
public void SetSize(int w, int h);
|
||||
public void SetLocation(int xy);
|
||||
public void SetLocation(int x, int y);
|
||||
public void SetLocation(int x, int y, int z);
|
||||
public void Clean();
|
||||
public void Focus();
|
||||
public void UnFocus();
|
||||
public void SendKeyEvent(KeyboardKeyEventArgs KeyArgs);
|
||||
public void SendClipEvent(string Text);
|
||||
public void SendFilesEvent(string[] Files);
|
||||
public Vector2i Size { get; set; }
|
||||
public Vector3i Location { get; set; }
|
||||
public Vector2 SizeAsFloat { get; }
|
||||
@ -33,9 +40,11 @@ public interface IRenderObject
|
||||
public IWindow? Window { get; }
|
||||
public bool Visible { get; set; }
|
||||
public object? Tag { get; set; }
|
||||
public List<SubHitBox> SubHitBoxes { get; }
|
||||
|
||||
public event Func<IRenderObject, Task>? Clicked;
|
||||
public event Func<IRenderObject, Task>? MouseLeave;
|
||||
public event Func<IRenderObject, string[], Task>? FilesDroped;
|
||||
public event Func<IRenderObject, Task>? MouseEnter;
|
||||
public event Func<IRenderObject, Task>? SizeChanged;
|
||||
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||
|
@ -18,8 +18,9 @@ public class ControlList
|
||||
|
||||
public int Length => _internal.Count;
|
||||
|
||||
internal event Func<int, IRenderObject, Task>? ControlAdded;
|
||||
internal event Func<Task>? ControlRemoved;
|
||||
public event Func<int, IRenderObject, Task>? ControlAdded;
|
||||
public event Func<int, IRenderObject, Task>? ControlAfterAdded;
|
||||
public event Func<Task>? ControlRemoved;
|
||||
|
||||
public void Remove(IRenderObject item, bool purge = true)
|
||||
{
|
||||
@ -43,12 +44,14 @@ public class ControlList
|
||||
{
|
||||
if (ControlAdded is not null) ControlAdded.Invoke(_internal.Count, item).Wait();
|
||||
_internal.Add(item);
|
||||
if (ControlAfterAdded is not null) ControlAfterAdded.Invoke(_internal.Count-1, item).Wait();
|
||||
}
|
||||
|
||||
public void Insert(int index, IRenderObject item)
|
||||
{
|
||||
if (ControlAdded is not null) ControlAdded.Invoke(index, item).Wait();
|
||||
_internal.Insert(index, item);
|
||||
if (ControlAfterAdded is not null) ControlAfterAdded.Invoke(index, item).Wait();
|
||||
}
|
||||
|
||||
public void Clear(bool purge = true)
|
||||
|
@ -39,4 +39,12 @@ public class Font
|
||||
fontclass.Face = new Face(lib, Font.ToArray(), 0);
|
||||
return fontclass;
|
||||
}
|
||||
|
||||
internal static Font MakeFontFromByteArray(byte[] Font)
|
||||
{
|
||||
_ = Font ?? throw new ArgumentNullException(nameof(Font));
|
||||
Font fontclass = new Font();
|
||||
fontclass.Face = new Face(lib, Font, 0);
|
||||
return fontclass;
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,15 @@ public class FontFamily
|
||||
{
|
||||
private static uint index = 0;
|
||||
public event Func<Task>? ReloadUI;
|
||||
public static bool MemoryFont;
|
||||
public static string FontPath = Path.GetTempPath();
|
||||
public required string Family { get; init; }
|
||||
private FontSize fs = FontSize.Thin;
|
||||
internal Dictionary<FontSize, Tuple<string, Font?>> InternalFonts = new();
|
||||
internal Dictionary<FontSize, Tuple<string, Font?>> InternalFontsi = new();
|
||||
internal bool IsZip = false;
|
||||
internal Dictionary<FontSize, Tuple<MemoryStream, Font?>> SInternalFonts = new();
|
||||
internal Dictionary<FontSize, Tuple<MemoryStream, Font?>> SInternalFontsi = new();
|
||||
//internal Dictionary<FontSize, Font> InternalFonts = new();
|
||||
//internal Dictionary<FontSize, Font> InternalFontsi = new();
|
||||
//internal bool IsZip = false;
|
||||
internal Dictionary<FontSize, Font> InternalFonts = new();
|
||||
internal Dictionary<FontSize, Font> InternalFontsi = new();
|
||||
internal static List<FontFamily> AllFams = new();
|
||||
|
||||
public static Task<FontFamily> LoadFontFamilyTask(Stream FamilyZip, string Family, string extra = "-")
|
||||
@ -32,7 +34,6 @@ public class FontFamily
|
||||
};
|
||||
AllFams.Add(f);
|
||||
using ZipArchive archive = new ZipArchive(FamilyZip, ZipArchiveMode.Read, false);
|
||||
f.IsZip = true;
|
||||
|
||||
foreach (ZipArchiveEntry font in archive.Entries)
|
||||
{
|
||||
@ -42,20 +43,57 @@ public class FontFamily
|
||||
|
||||
void tryadd(FontSize s, bool i = false)
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
var ss = font.Open();
|
||||
if (MemoryFont)
|
||||
{
|
||||
using (var ss = font.Open())
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
ss.CopyTo(memoryStream);
|
||||
byte[] fontBytes = memoryStream.ToArray();
|
||||
|
||||
if (i)
|
||||
{
|
||||
if (!f.SInternalFontsi.ContainsKey(s))
|
||||
f.SInternalFontsi.Add(s, new(memoryStream, null));
|
||||
if (!f.InternalFontsi.ContainsKey(s))
|
||||
{
|
||||
f.InternalFontsi.Add(s, Font.MakeFontFromByteArray(fontBytes));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!f.SInternalFonts.ContainsKey(s))
|
||||
f.SInternalFonts.Add(s, new(memoryStream, null));
|
||||
if (!f.InternalFonts.ContainsKey(s))
|
||||
{
|
||||
f.InternalFonts.Add(s, Font.MakeFontFromByteArray(fontBytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string p = FontPath;
|
||||
if (!Directory.Exists(p)) Directory.CreateDirectory(p);
|
||||
p = Path.Combine(p, "GM_Familys");
|
||||
if (!Directory.Exists(p)) Directory.CreateDirectory(p);
|
||||
p = Path.Combine(p, Family);
|
||||
if (!Directory.Exists(p)) Directory.CreateDirectory(p);
|
||||
p = Path.Combine(p, Path.GetRandomFileName());
|
||||
font.ExtractToFile(p, true);
|
||||
if (i)
|
||||
{
|
||||
if (!f.InternalFontsi.ContainsKey(s))
|
||||
{
|
||||
f.InternalFontsi.Add(s, Font.MakeFontFromFile(p));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!f.InternalFonts.ContainsKey(s))
|
||||
{
|
||||
f.InternalFonts.Add(s, Font.MakeFontFromFile(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
ss.Dispose();
|
||||
}
|
||||
|
||||
if (fd.EndsWith("italic"))
|
||||
|
@ -72,112 +72,26 @@ public class FontInteraction
|
||||
{
|
||||
CurrentFonts = new Font[Families_.Count];
|
||||
for (int j = 0; j < Families_.Count; j++)
|
||||
{
|
||||
if (Families_[j].IsZip)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (Families_[j].SInternalFontsi.TryGetValue(FontSize, out Tuple<MemoryStream, Font?>? f))
|
||||
if (Families_[j].InternalFontsi.TryGetValue(FontSize, out Font? f))
|
||||
{
|
||||
i = value;
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].SInternalFontsi[fs] = new(f.Item1,
|
||||
Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1));
|
||||
break;
|
||||
case false:
|
||||
Families_[j].SInternalFonts[fs] = new(f.Item1,
|
||||
Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentFonts[j] = (Families_[j].SInternalFontsi[fs].Item2!);
|
||||
CurrentFonts[j] = (Families_[j].InternalFontsi[fs]);
|
||||
if (ReloadUI is not null) ReloadUI.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Families_[j].SInternalFonts.TryGetValue(FontSize, out Tuple<MemoryStream, Font?>? f))
|
||||
if (Families_[j].InternalFonts.TryGetValue(FontSize, out Font? f))
|
||||
{
|
||||
i = value;
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].SInternalFontsi[fs] = new(f.Item1,
|
||||
Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1));
|
||||
Families_[j].SInternalFontsi[fs].Item1.Dispose();
|
||||
break;
|
||||
case false:
|
||||
Families_[j].SInternalFonts[fs] = new(f.Item1,
|
||||
Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1));
|
||||
Families_[j].SInternalFonts[fs].Item1.Dispose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentFonts[j] = Families_[j].SInternalFonts[fs].Item2!;
|
||||
CurrentFonts[j] = Families_[j].InternalFonts[fs];
|
||||
if (ReloadUI is not null) ReloadUI.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (Families_[j].InternalFontsi.TryGetValue(FontSize, out Tuple<string, Font?>? f))
|
||||
{
|
||||
i = value;
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].InternalFontsi[fs] = new(f.Item1,
|
||||
Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1));
|
||||
break;
|
||||
case false:
|
||||
Families_[j].InternalFonts[fs] = new(f.Item1,
|
||||
Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentFonts[j] = (Families_[j].InternalFontsi[fs].Item2!);
|
||||
if (ReloadUI is not null) ReloadUI.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Families_[j].InternalFonts.TryGetValue(FontSize, out Tuple<string, Font?>? f))
|
||||
{
|
||||
i = value;
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].InternalFontsi[fs] = new(f.Item1,
|
||||
Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1));
|
||||
break;
|
||||
case false:
|
||||
Families_[j].InternalFonts[fs] = new(f.Item1,
|
||||
Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentFonts[j] = Families_[j].InternalFonts[fs].Item2!;
|
||||
if (ReloadUI is not null) ReloadUI.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,9 +99,7 @@ public class FontInteraction
|
||||
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);
|
||||
FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First();
|
||||
fs = nearest;
|
||||
return thisList[nearest];
|
||||
}
|
||||
@ -195,9 +107,15 @@ public class FontInteraction
|
||||
private static Tuple<MemoryStream, Font?> Sgcl(Dictionary<FontSize, Tuple<MemoryStream, Font?>> thisList, FontSize thisValue, out FontSize fs)
|
||||
{
|
||||
Dictionary<FontSize, Tuple<MemoryStream, Font?>>.KeyCollection keys = thisList.Keys;
|
||||
FontSize nearest = thisValue -
|
||||
keys.Where(k => k <= thisValue)
|
||||
.Min(k => thisValue - k);
|
||||
FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First();
|
||||
fs = nearest;
|
||||
return thisList[nearest];
|
||||
}
|
||||
|
||||
private static Font Sgcl(Dictionary<FontSize, Font> thisList, FontSize thisValue, out FontSize fs)
|
||||
{
|
||||
Dictionary<FontSize, Font>.KeyCollection keys = thisList.Keys;
|
||||
FontSize nearest = keys.OrderBy(k => Math.Abs(k - thisValue)).First();
|
||||
fs = nearest;
|
||||
return thisList[nearest];
|
||||
}
|
||||
@ -210,62 +128,18 @@ public class FontInteraction
|
||||
CurrentFonts = new Font[Families_.Count];
|
||||
for (int j = 0; j < Families_.Count; j++)
|
||||
{
|
||||
if (Families_[j].IsZip)
|
||||
Font f = Italic switch
|
||||
{
|
||||
Tuple<MemoryStream, Font?> f = Italic switch
|
||||
{
|
||||
true => Sgcl(Families_[j].SInternalFontsi, value, out fs),
|
||||
false => Sgcl(Families_[j].SInternalFonts, value, out fs),
|
||||
true => Sgcl(Families_[j].InternalFontsi, value, out fs),
|
||||
false => Sgcl(Families_[j].InternalFonts, value, out fs),
|
||||
};
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].SInternalFontsi[fs] = new(f.Item1, Font.MakeFontFromStream(Families_[j].SInternalFontsi[fs].Item1));
|
||||
Families_[j].SInternalFontsi[fs].Item1.Dispose();
|
||||
break;
|
||||
case false:
|
||||
Families_[j].SInternalFonts[fs] = new(f.Item1, Font.MakeFontFromStream(Families_[j].SInternalFonts[fs].Item1));
|
||||
Families_[j].SInternalFonts[fs].Item1.Dispose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentFonts[j] = Italic switch
|
||||
{
|
||||
true => Families_[j].SInternalFontsi[fs].Item2!,
|
||||
false => Families_[j].SInternalFonts[fs].Item2!,
|
||||
true => Families_[j].InternalFontsi[fs],
|
||||
false => Families_[j].InternalFonts[fs],
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
Tuple<string, Font?> f = Italic switch
|
||||
{
|
||||
true => gcl(Families_[j].InternalFontsi, value, out fs),
|
||||
false => gcl(Families_[j].InternalFonts, value, out fs),
|
||||
};
|
||||
if (f.Item2 is null)
|
||||
{
|
||||
switch (Italic)
|
||||
{
|
||||
case true:
|
||||
Families_[j].InternalFontsi[fs] = new(f.Item1,
|
||||
Font.MakeFontFromFile(Families_[j].InternalFontsi[fs].Item1));
|
||||
break;
|
||||
case false:
|
||||
Families_[j].InternalFonts[fs] =
|
||||
new(f.Item1, Font.MakeFontFromFile(Families_[j].InternalFonts[fs].Item1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
CurrentFonts[j] = Italic switch
|
||||
{
|
||||
true => Families_[j].InternalFontsi[fs].Item2!,
|
||||
false => Families_[j].InternalFonts[fs].Item2!,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (ReloadUI is not null) ReloadUI.Invoke();
|
||||
}
|
||||
}
|
||||
|
623
GraphicsManager/Objects/Core/LabelBase.cs
Normal file
623
GraphicsManager/Objects/Core/LabelBase.cs
Normal file
@ -0,0 +1,623 @@
|
||||
using System.Text;
|
||||
using GraphicsManager.Enums;
|
||||
using GraphicsManager.Interfaces;
|
||||
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;
|
||||
|
||||
namespace GraphicsManager.Objects.Core;
|
||||
|
||||
public class LabelBase : ILabel
|
||||
{
|
||||
public LabelBase(FontFamily fontFamily)
|
||||
{
|
||||
Font = FontInteraction.Load(fontFamily);
|
||||
}
|
||||
|
||||
public LabelBase(FontInteraction interaction)
|
||||
{
|
||||
Font = interaction;
|
||||
}
|
||||
|
||||
public BetterContextMenu? ContextMenu { get; set; } = null;
|
||||
public IParent? Parent { get; protected set; }
|
||||
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
||||
protected Vector2 laf = new(), saf = new();
|
||||
|
||||
public Vector2 LocationAsFloat { get { return laf; } }
|
||||
public Vector2 SizeAsFloat { get { return saf; } }
|
||||
protected Vector2i? msize = null;
|
||||
public virtual Vector2i? MaxSize
|
||||
{
|
||||
get => msize;
|
||||
set
|
||||
{
|
||||
msize = value;
|
||||
StringBuilder sb = new();
|
||||
float max_x = 0, lines = 1, char_x = 0F;
|
||||
for (int i = 0; i < Text.Length; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = Text[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
sb.Append(c);
|
||||
char_x = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
if (i > 0 && text[i-1] == ' ')
|
||||
{
|
||||
int addc = 0;
|
||||
float word_char_x = char_x;
|
||||
while (MaxSize is not null)
|
||||
{
|
||||
if (addc + i == Text.Length) break;
|
||||
if (text[addc + i] == ' ') break;
|
||||
Character ch2;
|
||||
if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context);
|
||||
else ch2 = Texture.GetChar(Font, c);
|
||||
word_char_x += (ch2.Advance >> 6) * Scale;
|
||||
if (word_char_x > MaxSize.Value.X)
|
||||
{
|
||||
char_x = 0f;
|
||||
lines++;
|
||||
sb.Append('\n');
|
||||
break;
|
||||
}
|
||||
addc++;
|
||||
}
|
||||
}
|
||||
sb.Append(c);
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
if ((xrel + w) >= max_x) max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
text_Calculated = sb.ToString();
|
||||
Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
}
|
||||
}
|
||||
protected char? pc;
|
||||
public char? PasswordChar
|
||||
{
|
||||
get => pc;
|
||||
set
|
||||
{
|
||||
pc = value;
|
||||
if (Parent is not null) Parent.TryDraw();
|
||||
}
|
||||
}
|
||||
protected bool _Visible = true;
|
||||
|
||||
public virtual bool Visible
|
||||
{
|
||||
get => _Visible;
|
||||
set
|
||||
{
|
||||
_Visible = value;
|
||||
if (Parent is not null && Loaded) Parent.TryDraw();
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly Dictionary<IGLFWGraphicsContext, Dictionary<FontInteraction, Dictionary<uint, Character>>> _characters = new();
|
||||
protected string text = string.Empty;
|
||||
protected string text_Calculated = string.Empty;
|
||||
public int VAO { get; protected set; }
|
||||
|
||||
public virtual void Focus()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual void UnFocus()
|
||||
{
|
||||
|
||||
}
|
||||
public int VBO { get; protected set; }
|
||||
public virtual Vector2 DIR { get; set; } = new Vector2(1f, 0f);
|
||||
|
||||
public virtual Vector2i GetSizeOfChar(int Index)
|
||||
{
|
||||
float mx = 0, my = 0;
|
||||
char character;
|
||||
if (PasswordChar is null)
|
||||
character = Text[Index];
|
||||
else
|
||||
character = PasswordChar.Value;
|
||||
|
||||
|
||||
if (character == '\n')
|
||||
{
|
||||
mx = 0f;
|
||||
my += Font.PixelHeight * Scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character cha;
|
||||
if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context);
|
||||
else cha = Texture.GetChar(Font, character);
|
||||
mx = cha.Size.X * Scale;
|
||||
my = cha.Size.Y * Scale;
|
||||
}
|
||||
return new((int)mx, (int)my);
|
||||
}
|
||||
|
||||
public virtual Vector2i GetBearingOfChar(int Index)
|
||||
{
|
||||
float mx = 0, my = 0;
|
||||
char character;
|
||||
if (PasswordChar is null)
|
||||
character = Text[Index];
|
||||
else
|
||||
character = PasswordChar.Value;
|
||||
|
||||
if (character == '\n')
|
||||
{
|
||||
mx = 0f;
|
||||
my += Font.PixelHeight * Scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character cha;
|
||||
if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context);
|
||||
else cha = Texture.GetChar(Font, character);
|
||||
mx = cha.Bearing.X * Scale;
|
||||
my = cha.Bearing.Y * Scale;
|
||||
}
|
||||
return new((int)mx, (int)my);
|
||||
}
|
||||
|
||||
public List<SubHitBox> SubHitBoxes { get; } = new();
|
||||
|
||||
public virtual string Text
|
||||
{
|
||||
get => text;
|
||||
set
|
||||
{
|
||||
if (value is null) value = string.Empty;
|
||||
text = value;
|
||||
StringBuilder sb = new();
|
||||
text_Calculated = string.Empty;
|
||||
float max_x = 0, lines = 1, char_x = 0F;
|
||||
for (int i = 0; i < Text.Length; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = Text[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
char_x = 0f;
|
||||
sb.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
if (MaxSize is not null && i > 0 && text[i-1] == ' ')
|
||||
{
|
||||
int addc = 0;
|
||||
float word_char_x = char_x;
|
||||
while (true)
|
||||
{
|
||||
if (addc + i == Text.Length) break;
|
||||
if (text[addc + i] == ' ') break;
|
||||
Character ch2;
|
||||
if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context);
|
||||
else ch2 = Texture.GetChar(Font, c);
|
||||
word_char_x += (ch2.Advance >> 6) * Scale;
|
||||
if (word_char_x > MaxSize.Value.X)
|
||||
{
|
||||
char_x = 0f;
|
||||
lines++;
|
||||
sb.Append('\n');
|
||||
break;
|
||||
}
|
||||
addc++;
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(c);
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
if ((xrel + w) >= max_x) max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
|
||||
text_Calculated = sb.ToString();
|
||||
Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
if (Loaded)
|
||||
{
|
||||
|
||||
if (Window is not null && Window.CanControleUpdate)
|
||||
{
|
||||
if (!Window.Context.IsCurrent)
|
||||
{
|
||||
try
|
||||
{
|
||||
Window.Context.MakeCurrent();
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (Window.Context.IsCurrent)
|
||||
{
|
||||
Parent!.TryDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public virtual uint LineHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return (uint)((Font.PixelHeight * (Font.CurrentFonts[0].Face.Height / (float)Font.CurrentFonts[0].Face.UnitsPerEM)) * Scale);
|
||||
}
|
||||
}
|
||||
public Shader Shader { get; set; } = null!;
|
||||
public FontInteraction Font { get; protected set; }
|
||||
public virtual float Scale { get; set; } = 1.0f;
|
||||
public virtual Vector2i Distance { get; set; }
|
||||
protected Vector3i loc_;
|
||||
public virtual Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return loc_;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetLocation(value.X, value.Y, value.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetLocation(int xy)
|
||||
{
|
||||
SetLocation(xy, xy, 0);
|
||||
}
|
||||
|
||||
public virtual void SetLocation(int x, int y)
|
||||
{
|
||||
SetLocation(x, y, 0);
|
||||
}
|
||||
|
||||
public virtual void SetLocation(int x, int y, int z)
|
||||
{
|
||||
loc_.X = x;
|
||||
loc_.Y = y;
|
||||
loc_.Z = z;
|
||||
if (Window is null || Parent is null) return;
|
||||
if (Window.CanControleUpdate && Loaded)
|
||||
{
|
||||
Parent!.TryDraw();
|
||||
if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetSize(int wh)
|
||||
{
|
||||
SetSize(wh, wh);
|
||||
}
|
||||
|
||||
public virtual void SetSize(int w, int h)
|
||||
{
|
||||
_size.X = w;
|
||||
_size.Y = h;
|
||||
}
|
||||
|
||||
protected Vector2i _size;
|
||||
public virtual 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 virtual Vector2i GetCharLocation(int index)
|
||||
{
|
||||
float max_x = 0, lines = 0, char_x = 0F;
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = text_Calculated[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
char_x = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
return new((int)char_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
}
|
||||
|
||||
public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SendClipEvent(string ClipString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual 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 event Func<IRenderObject, Task>? SizeChanged;
|
||||
|
||||
public virtual void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (Visible && Loaded && this.Font is not null)
|
||||
{
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
Shader.Use();
|
||||
GL.Uniform4(Shader.GetUniformLocation("textColor"), new Color4(255,255,255,255));
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
Shader.SetMatrixF4("projection", Window.WindowSizeMatrix);
|
||||
|
||||
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 + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f));
|
||||
float char_x = 0.0f;
|
||||
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
GL.ActiveTexture((Shader.GetUniformLocation("u_texture") switch
|
||||
{
|
||||
0 => TextureUnit.Texture0,
|
||||
1 => TextureUnit.Texture1,
|
||||
2 => TextureUnit.Texture2,
|
||||
3 => TextureUnit.Texture3,
|
||||
4 => TextureUnit.Texture4,
|
||||
5 => TextureUnit.Texture5,
|
||||
6 => TextureUnit.Texture6,
|
||||
7 => TextureUnit.Texture7,
|
||||
8 => TextureUnit.Texture8,
|
||||
9 => TextureUnit.Texture9,
|
||||
}));
|
||||
|
||||
float hhh = 0f;
|
||||
for (int i = 0; i < text_Calculated.Length; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = text_Calculated[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
if (!_characters[Window!.Context][Font].ContainsKey(c) && !n)
|
||||
{
|
||||
_ = Texture.TextureForChar(Window!.Context, Font, c, Shader);
|
||||
}
|
||||
|
||||
if (n)
|
||||
{
|
||||
hhh += LineHeight;
|
||||
hhh += Font.ExtraLinePixels;
|
||||
char_x = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_characters[Window!.Context][Font].ContainsKey(c)) continue;
|
||||
Character ch = _characters[Window!.Context][Font][c];
|
||||
|
||||
float w = ch.Size.X * Scale;
|
||||
float h = ch.Size.Y * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
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 virtual void ForceDistanceUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public virtual void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
if (parent is IWindow w) Distance = new(w.CS.X - Size.X - Location.X, w.CS.Y - Size.Y - Location.Y);
|
||||
else Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
}
|
||||
public IWindow? Window { get; protected set; }
|
||||
protected static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||
public bool IgnoreHover { get; set; }
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public event Func<IRenderObject, string[], Task>? FilesDroped;
|
||||
|
||||
public void SendFilesEvent(string[] Files)
|
||||
{
|
||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(this, Files);
|
||||
}
|
||||
public virtual void LoadToParent(IParent window, IWindow win)
|
||||
{
|
||||
if (Loaded) return;
|
||||
if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new());
|
||||
if (!_characters[win!.Context].ContainsKey(Font)) _characters[win!.Context].Add(Font, new Dictionary<uint, Character>());
|
||||
if (Shader is null) Shader = Label.DefaultTextShader[win.Context];
|
||||
Parent = window;
|
||||
Window = win;
|
||||
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);
|
||||
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
GL.BindVertexArray(0);
|
||||
|
||||
Loaded = true;
|
||||
Text = Text;
|
||||
Location = Location;
|
||||
if (Distance.X == 0 && Distance.Y == 0) ForceDistanceUpdate(Parent);
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
}
|
||||
|
||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||
{
|
||||
if (MouseInside && obj.Button == MouseButton.Button1)
|
||||
{
|
||||
bool subnothit = true;
|
||||
if (SubHitBoxes.Count > 0)
|
||||
{
|
||||
foreach (SubHitBox hb in SubHitBoxes)
|
||||
{
|
||||
if (hb.MouseInside)
|
||||
{
|
||||
hb.SendClick();
|
||||
subnothit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subnothit && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
}
|
||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!);
|
||||
if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
protected bool mi;
|
||||
|
||||
public virtual bool MouseInside
|
||||
{
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (Window is null) return;
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
private bool l = false;
|
||||
|
||||
protected virtual void InvokeWindowLoaded()
|
||||
{
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
}
|
||||
|
||||
public bool Loaded
|
||||
{
|
||||
get => l;
|
||||
protected set
|
||||
{
|
||||
l = value;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,11 +24,9 @@ public abstract class ParentBase : Rectangle, IParent
|
||||
if (!BlockDraw && Parent is not null) Parent.TryDraw();
|
||||
}
|
||||
|
||||
public virtual void ParentResize(ResizeEventArgs e)
|
||||
public virtual void ParentResize()
|
||||
{
|
||||
bool PastBlockState = BlockDraw;
|
||||
BlockDraw = true;
|
||||
if (e.Width == 0 && e.Height == 0) return;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
if (!Controls[i].Loaded) continue;
|
||||
@ -42,15 +40,24 @@ public abstract class ParentBase : Rectangle, IParent
|
||||
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
||||
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
||||
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||
Controls[i].Size = new(sx, sy);
|
||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
||||
if (Controls[i] is IParent parent)
|
||||
bool mooved = false;
|
||||
if (sx != Controls[i].Size.X || sy != Controls[i].Size.Y)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
mooved = true;
|
||||
Controls[i].SetSize(sx, sy);
|
||||
}
|
||||
if (lx != Controls[i].Location.X || ly != Controls[i].Location.Y)
|
||||
{
|
||||
mooved = true;
|
||||
Controls[i].SetLocation(lx, ly);
|
||||
}
|
||||
if (mooved && Controls[i] is IParent parent)
|
||||
{
|
||||
parent.ParentResize();
|
||||
}
|
||||
}
|
||||
Parent!.TryDraw();
|
||||
BlockDraw = PastBlockState;
|
||||
if (Parent is not null) Parent.TryDraw();
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
||||
public virtual void ReportSizeUpdate(IRenderObject Control)
|
||||
@ -58,41 +65,45 @@ public abstract class ParentBase : Rectangle, IParent
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (Loaded && Visible && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y)
|
||||
{
|
||||
int nx = x, ny = y, nw = w, nh = h;
|
||||
if (Location.X > nw)
|
||||
if (Location.X - sx + x > sw || Location.Y - sy + y > sh)
|
||||
return;
|
||||
|
||||
if (Location.X - sx + x > -1)
|
||||
{
|
||||
int add = Location.X - sx + x;
|
||||
sx += add;
|
||||
sw -= add;
|
||||
if (Size.X < sw)
|
||||
sw = Size.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
nx += Location.X;
|
||||
nw -= Location.X;
|
||||
if (Size.X < nw)
|
||||
nw = Size.X;
|
||||
if (Size.X + Location.X - sx + x < sw)
|
||||
sw = Size.X + Location.X - sx + x;
|
||||
}
|
||||
if (Location.Y - sy + y > -1)
|
||||
{
|
||||
int add = Location.Y - sy + y;
|
||||
sy += add;
|
||||
sh -= add;
|
||||
if (Size.Y < sh)
|
||||
sh = Size.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Size.Y + Location.Y - sy + y < sh)
|
||||
sh = Size.Y + Location.Y - sy + y;
|
||||
}
|
||||
|
||||
if (Location.Y > nh)
|
||||
return;
|
||||
else
|
||||
{
|
||||
if (Location.Y > -1)
|
||||
{
|
||||
ny += Location.Y;
|
||||
nh -= Location.Y;
|
||||
if (Size.Y < nh)
|
||||
nh = Size.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Size.Y + Location.Y < nh)
|
||||
nh = Size.Y + Location.Y;
|
||||
}
|
||||
}
|
||||
if (nw == 0 || nh == 0) return;
|
||||
GL.Scissor(nx, Window!.CS.Y - ny - nh, nw, nh);
|
||||
base.Draw(nx,ny,nw,nh);
|
||||
x += Location.X;
|
||||
y += Location.Y;
|
||||
|
||||
if (sw <= 0 || sh <= 0) return;
|
||||
base.Draw(x,y,sx,sy,sw,sh);
|
||||
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
||||
|
||||
if (needload.Any())
|
||||
@ -108,8 +119,8 @@ public abstract class ParentBase : Rectangle, IParent
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
if (Controls[i].Location.X > Size.X || Controls[i].Location.Y > Size.Y) continue;
|
||||
GL.Scissor(nx, Window!.CS.Y - ny - nh, nw, nh);
|
||||
Controls[i].Draw(nx, ny, nw, nh);
|
||||
GL.Scissor(sx, Window!.CS.Y - sy - sh, sw, sh);
|
||||
Controls[i].Draw(x,y,sx,sy,sw,sh);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,7 +160,7 @@ public abstract class ParentBase : Rectangle, IParent
|
||||
{
|
||||
Controls[i].Location = Controls[i].Location;
|
||||
}
|
||||
ParentResize(new());
|
||||
ParentResize();
|
||||
if (Parent is not null) Parent.TryDraw();
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
@ -60,11 +60,11 @@ public class RoundedButton : Rectangle
|
||||
base.Clean();
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (!Visible || !Loaded) return;
|
||||
base.Draw(x,y,w,h);
|
||||
_label.Draw(x,y,w,h);
|
||||
base.Draw(x,y,sx,sy,sw,sh);
|
||||
_label.Draw(x,y,sx,sy,sw,sh);
|
||||
}
|
||||
|
||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
||||
|
@ -115,6 +115,12 @@ public class Shader : IDisposable
|
||||
GL.UniformMatrix4(_uniformLocations[name], true, ref data);
|
||||
}
|
||||
|
||||
public void SetMatrix4(int loc, Matrix4 data)
|
||||
{
|
||||
GL.UseProgram(Handle);
|
||||
GL.UniformMatrix4(loc, true, ref data);
|
||||
}
|
||||
|
||||
public void SetMatrixF4(string name, Matrix4 data)
|
||||
{
|
||||
GL.UseProgram(Handle);
|
||||
|
41
GraphicsManager/Objects/Core/SubHitBox.cs
Normal file
41
GraphicsManager/Objects/Core/SubHitBox.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
|
||||
namespace GraphicsManager.Objects.Core;
|
||||
|
||||
public class SubHitBox
|
||||
{
|
||||
public virtual Vector2i Size { get; set; }
|
||||
public virtual Vector2i Location { get; set; }
|
||||
public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
private bool mi = false;
|
||||
|
||||
internal virtual bool MouseInside
|
||||
{
|
||||
get
|
||||
{
|
||||
return mi;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mi == value) return;
|
||||
mi = value;
|
||||
if (value && MouseEnter is not null) MouseEnter.Invoke(this).Wait();
|
||||
if (!value && MouseLeave is not null) MouseLeave.Invoke(this).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public event Func<SubHitBox, Task>? Clicked;
|
||||
public event Func<SubHitBox, Task>? MouseLeave;
|
||||
public event Func<SubHitBox, Task>? MouseEnter;
|
||||
|
||||
internal void SendClick()
|
||||
{
|
||||
if (Clicked is not null) _ = Clicked.Invoke(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString()+ $": {{X: {Location.X}, Y: {Location.Y}, Width: {Size.X}, Height: {Size.Y}}}";
|
||||
}
|
||||
}
|
@ -146,7 +146,7 @@ public class Texture
|
||||
{
|
||||
}
|
||||
|
||||
internal static Character GetChar(Face face, char charter)
|
||||
public static Character GetChar(Face face, char charter)
|
||||
{
|
||||
ushort temp = (charter);
|
||||
if (face.GetCharIndex(temp) == 0)
|
||||
@ -172,7 +172,7 @@ public class Texture
|
||||
};
|
||||
}
|
||||
|
||||
internal static Character GetChar(FontInteraction l, char charter, IGLFWGraphicsContext con)
|
||||
public static Character GetChar(FontInteraction l, char charter, IGLFWGraphicsContext con)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -203,7 +203,7 @@ public class Texture
|
||||
return GetChar(l.CurrentFonts[0].Face, (char)1);
|
||||
}
|
||||
|
||||
internal static Character GetChar(FontInteraction l, char charter)
|
||||
public static Character GetChar(FontInteraction l, char charter)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -235,7 +235,7 @@ public class Texture
|
||||
private static Dictionary<FontInteraction, Texture> BadChars = new();
|
||||
|
||||
|
||||
internal static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter, Shader s)
|
||||
public static Texture TextureForChar(IGLFWGraphicsContext con, FontInteraction l, char charter, Shader s)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -200,20 +200,25 @@ public class FlowLayout : ParentBase, IFlow
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override void SetSize(int w, int h)
|
||||
{
|
||||
BlockDraw = true;
|
||||
base.SetSize(w, h);
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
Controls[i].SetSize(w, Controls[i].Size.Y);
|
||||
}
|
||||
ParentResize();
|
||||
if (Parent is not null) Parent.TryDraw();
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
||||
public override Vector2i Size
|
||||
{
|
||||
get => base.Size;
|
||||
set
|
||||
{
|
||||
BlockDraw = true;
|
||||
base.Size = value;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
Controls[i].Size = new(value.X, Controls[i].Size.Y);
|
||||
}
|
||||
ParentResize(new());
|
||||
if (Parent is not null) Parent.TryDraw();
|
||||
BlockDraw = false;
|
||||
SetSize(value.X, value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using GraphicsManager.Enums;
|
||||
using System.Text;
|
||||
using GraphicsManager.Enums;
|
||||
using GraphicsManager.Interfaces;
|
||||
using GraphicsManager.Objects.Core;
|
||||
using GraphicsManager.Structs;
|
||||
@ -11,353 +12,27 @@ using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
|
||||
namespace GraphicsManager.Objects;
|
||||
|
||||
public class Label : ILabel
|
||||
public class Label : LabelBase
|
||||
{
|
||||
public static readonly Dictionary<IGLFWGraphicsContext, Shader> DefaultTextShader = new();
|
||||
|
||||
public Label(FontFamily fontFamily)
|
||||
public Label(FontFamily fontFamily):base(fontFamily)
|
||||
{
|
||||
Font = FontInteraction.Load(fontFamily);
|
||||
}
|
||||
|
||||
public Label(FontInteraction interaction)
|
||||
public Label(FontInteraction interaction):base(interaction)
|
||||
{
|
||||
Font = interaction;
|
||||
}
|
||||
|
||||
public BetterContextMenu? ContextMenu { get; set; } = null;
|
||||
public IParent? Parent { get; private set; }
|
||||
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
||||
private Vector2 laf = new(), saf = new();
|
||||
|
||||
public Vector2 LocationAsFloat { get { return laf; } }
|
||||
public Vector2 SizeAsFloat { get { return saf; } }
|
||||
private Vector2i? msize = null;
|
||||
public Vector2i? MaxSize
|
||||
{
|
||||
get => msize;
|
||||
set
|
||||
{
|
||||
msize = value;
|
||||
text_Calculated = string.Empty;
|
||||
float max_x = 0, lines = 1, char_x = 0F;
|
||||
for (int i = 0; i < Text.Length; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = Text[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
text_Calculated += c;
|
||||
char_x = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
if (i > 0 && text[i-1] == ' ')
|
||||
{
|
||||
int addc = 0;
|
||||
float word_char_x = char_x;
|
||||
while (MaxSize is not null)
|
||||
{
|
||||
if (addc + i == Text.Length) break;
|
||||
if (text[addc + i] == ' ') break;
|
||||
Character ch2;
|
||||
if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context);
|
||||
else ch2 = Texture.GetChar(Font, c);
|
||||
word_char_x += (ch2.Advance >> 6) * Scale;
|
||||
if (word_char_x > MaxSize.Value.X)
|
||||
{
|
||||
char_x = 0f;
|
||||
lines++;
|
||||
text_Calculated += '\n';
|
||||
break;
|
||||
}
|
||||
addc++;
|
||||
}
|
||||
}
|
||||
text_Calculated += c;
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
if ((xrel + w) >= max_x) max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
}
|
||||
}
|
||||
private char? pc;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly Dictionary<IGLFWGraphicsContext, Dictionary<FontInteraction, Dictionary<uint, Character>>> _characters = new();
|
||||
private string text = string.Empty;
|
||||
private string text_Calculated = 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 Vector2i GetSizeOfChar(int Index)
|
||||
{
|
||||
float mx = 0, my = 0;
|
||||
char character;
|
||||
if (PasswordChar is null)
|
||||
character = Text[Index];
|
||||
else
|
||||
character = PasswordChar.Value;
|
||||
|
||||
|
||||
if (character == '\n')
|
||||
{
|
||||
mx = 0f;
|
||||
my += Font.PixelHeight * Scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character cha;
|
||||
if (Window is not null) cha = Texture.GetChar(Font, character, Window.Context);
|
||||
else cha = Texture.GetChar(Font, character);
|
||||
mx = cha.Size.X * Scale;
|
||||
my = cha.Size.Y * Scale;
|
||||
}
|
||||
return new((int)mx, (int)my);
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => text;
|
||||
set
|
||||
{
|
||||
if (value is null) value = string.Empty;
|
||||
text = value;
|
||||
text_Calculated = string.Empty;
|
||||
float max_x = 0, lines = 1, char_x = 0F;
|
||||
for (int i = 0; i < Text.Length; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = Text[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
char_x = 0f;
|
||||
text_Calculated += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
if (MaxSize is not null && i > 0 && text[i-1] == ' ')
|
||||
{
|
||||
int addc = 0;
|
||||
float word_char_x = char_x;
|
||||
while (true)
|
||||
{
|
||||
if (addc + i == Text.Length) break;
|
||||
if (text[addc + i] == ' ') break;
|
||||
Character ch2;
|
||||
if (Window is not null) ch2 = Texture.GetChar(Font, text[addc + i], Window.Context);
|
||||
else ch2 = Texture.GetChar(Font, c);
|
||||
word_char_x += (ch2.Advance >> 6) * Scale;
|
||||
if (word_char_x > MaxSize.Value.X)
|
||||
{
|
||||
char_x = 0f;
|
||||
lines++;
|
||||
text_Calculated += '\n';
|
||||
break;
|
||||
}
|
||||
addc++;
|
||||
}
|
||||
}
|
||||
|
||||
text_Calculated += c;
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
if ((xrel + w) >= max_x) max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Size = new((int)max_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
if (Loaded)
|
||||
{
|
||||
|
||||
if (Window is not null && Window.CanControleUpdate)
|
||||
{
|
||||
if (!Window.Context.IsCurrent)
|
||||
{
|
||||
try
|
||||
{
|
||||
Window.Context.MakeCurrent();
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (Window.Context.IsCurrent)
|
||||
{
|
||||
Parent!.TryDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public uint LineHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return (uint)((Font.PixelHeight * (Font.CurrentFonts[0].Face.Height / (float)Font.CurrentFonts[0].Face.UnitsPerEM)) * Scale);
|
||||
}
|
||||
}
|
||||
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 Vector3i loc_;
|
||||
public Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return loc_;
|
||||
}
|
||||
set
|
||||
{
|
||||
loc_ = value;
|
||||
if (Window is null || Parent is null) return;
|
||||
if (Window.CanControleUpdate && Loaded)
|
||||
{
|
||||
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 Vector2i GetCharLocation(int index)
|
||||
{
|
||||
float max_x = 0, lines = 0, char_x = 0F;
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
char c;
|
||||
if (PasswordChar is null)
|
||||
c = text_Calculated[i];
|
||||
else
|
||||
c = PasswordChar.Value;
|
||||
bool n = (c == '\n');
|
||||
|
||||
if (n)
|
||||
{
|
||||
lines++;
|
||||
char_x = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Character ch;
|
||||
if (Window is not null) ch = Texture.GetChar(Font, c, Window.Context);
|
||||
else ch = Texture.GetChar(Font, c);
|
||||
float w = ch.Size.X * Scale;
|
||||
float xrel = char_x + ch.Bearing.X * Scale;
|
||||
char_x += (ch.Advance >> 6) * Scale;
|
||||
max_x = (xrel + w);
|
||||
}
|
||||
}
|
||||
return new((int)char_x, (int)(lines * LineHeight) + (int)(lines * Font.ExtraLinePixels));
|
||||
}
|
||||
|
||||
public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SendClipEvent(string ClipString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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 event Func<IRenderObject, Task>? SizeChanged;
|
||||
|
||||
public void Draw(int x, int y, int ww, int hh)
|
||||
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (Visible && Loaded && this.Font is not null)
|
||||
{
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
Shader.Use();
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Uniform4(Shader.GetUniformLocation("textColor"), Color);
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
@ -429,106 +104,4 @@ public class Label : ILabel
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ForceDistanceUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
}
|
||||
public IWindow? Window { get; private set; }
|
||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||
public bool IgnoreHover { get; set; }
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public void LoadToParent(IParent window, IWindow win)
|
||||
{
|
||||
if (Loaded) return;
|
||||
if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new());
|
||||
if (!_characters[win!.Context].ContainsKey(Font)) _characters[win!.Context].Add(Font, new Dictionary<uint, Character>());
|
||||
if (Shader is null) Shader = DefaultTextShader[win.Context];
|
||||
Parent = window;
|
||||
Window = win;
|
||||
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);
|
||||
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
GL.BindVertexArray(0);
|
||||
|
||||
Loaded = true;
|
||||
Text = Text;
|
||||
Location = Location;
|
||||
if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||
if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
}
|
||||
|
||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||
{
|
||||
if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!);
|
||||
if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
private bool mi;
|
||||
|
||||
public bool MouseInside
|
||||
{
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (Window is null) return;
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
|
@ -146,10 +146,10 @@ public class ProgressBar : ParentBase
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (UpdateOnDraw) UpdateProgress();
|
||||
base.Draw(x, y, w, h);
|
||||
base.Draw(x, y, sx,sy, sw, sh);
|
||||
}
|
||||
|
||||
public void UpdateProgress()
|
||||
|
@ -1,505 +0,0 @@
|
||||
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 BetterContextMenu? ContextMenu { get; set; } = null;
|
||||
public IParent? Parent { get; private set; }
|
||||
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
||||
private Vector2 laf = new(), saf = new();
|
||||
|
||||
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, character);
|
||||
float w = cha.Size.X * Scale;
|
||||
float xrel = char_x + cha.Bearing.X * Scale;
|
||||
char_x += (cha.Advance >> 6) * Scale;
|
||||
if ((xrel + w) >= addx) addx = (xrel + w);
|
||||
}
|
||||
|
||||
return new((int)addx, (int)addy);
|
||||
}
|
||||
public string Text
|
||||
{
|
||||
get => text;
|
||||
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, character);
|
||||
double w = cha.Size.X * Scale;
|
||||
double xrel = char_x + cha.Bearing.X * Scale;
|
||||
double yrel = ((cha.Size.Y - cha.Bearing.Y) * Scale) + (Font.PixelHeight * Scale);
|
||||
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 Vector3i loc_ = new();
|
||||
private int maxy = 0, maxx = 0;
|
||||
public Vector3i 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 event Func<IRenderObject, Task>? SizeChanged;
|
||||
|
||||
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 + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f));
|
||||
float char_x = 0.0f;
|
||||
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
GL.ActiveTexture((Shader.GetUniformLocation("u_texture") switch
|
||||
{
|
||||
0 => TextureUnit.Texture0,
|
||||
1 => TextureUnit.Texture1,
|
||||
2 => TextureUnit.Texture2,
|
||||
3 => TextureUnit.Texture3,
|
||||
4 => TextureUnit.Texture4,
|
||||
5 => TextureUnit.Texture5,
|
||||
6 => TextureUnit.Texture6,
|
||||
7 => TextureUnit.Texture7,
|
||||
8 => TextureUnit.Texture8,
|
||||
9 => TextureUnit.Texture9,
|
||||
}));
|
||||
|
||||
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, Shader);
|
||||
}
|
||||
|
||||
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 virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SendClipEvent(string ClipString)
|
||||
{
|
||||
|
||||
}
|
||||
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 IWindow? Window { get; private set; }
|
||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||
public void LoadToParent(IParent window, IWindow 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.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 && Window!.HoveringControl == this) ContextMenu.ShowContext(Window!);
|
||||
if (obj.Button != MouseButton.Button2 && ContextMenu is not null && ContextMenu.Visible) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
private bool mi = false;
|
||||
public bool MouseInside
|
||||
{
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (Window is null) return;
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public bool IgnoreHover { get; set; }
|
||||
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;
|
||||
}
|
@ -5,6 +5,7 @@ using GraphicsManager.Interfaces;
|
||||
using GraphicsManager.Objects.Core;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Platform.Windows;
|
||||
using OpenTK.Windowing.Common;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
using OpenTK.Windowing.Desktop;
|
||||
@ -50,7 +51,6 @@ public class Rectangle : ITextureObject
|
||||
|
||||
public List<Texture> Textures { get; set; } = new();
|
||||
public BetterContextMenu? ContextMenu { get; set; } = null;
|
||||
public event Func<string[], Task>? FilesDroped;
|
||||
|
||||
public Rectangle(Texture? texture)
|
||||
{
|
||||
@ -92,7 +92,6 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
}
|
||||
|
||||
public Action? OnDrawAction;
|
||||
public virtual void SendKeyEvent(KeyboardKeyEventArgs KeyArgs)
|
||||
{
|
||||
|
||||
@ -102,23 +101,21 @@ public class Rectangle : ITextureObject
|
||||
{
|
||||
|
||||
}
|
||||
//public Action? OnDrawExitAction;
|
||||
|
||||
public virtual void Draw(int x, int y, int w, int h)
|
||||
public virtual void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (Visible && Loaded && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y)
|
||||
{
|
||||
if (OnDrawAction is not null) OnDrawAction.Invoke();
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
foreach (Texture tex in Textures)
|
||||
{
|
||||
tex.Use();
|
||||
}
|
||||
Shader.Use();
|
||||
Shader.SetMatrix4("windowMatrix", Window.WindowSizeMatrix);
|
||||
Shader.SetMatrix4(Shader.GetUniformLocation("windowMatrix"), Window.WindowSizeMatrix);
|
||||
if (!Textures.Any() || Shader.Handle == DefaultAlphaShader[Window!.Context].Handle)
|
||||
{
|
||||
GL.Uniform4(0, BackgroundColor);
|
||||
GL.Uniform4(Shader.GetUniformLocation("objColor"), BackgroundColor);
|
||||
}
|
||||
GL.BindVertexArray(ArrayObject);
|
||||
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedShort, 0);
|
||||
@ -126,6 +123,12 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
|
||||
public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
public List<SubHitBox> SubHitBoxes { get; } = new();
|
||||
public event Func<IRenderObject, string[], Task>? FilesDroped;
|
||||
public void SendFilesEvent(string[] Files)
|
||||
{
|
||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(this, Files);
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate()
|
||||
{
|
||||
@ -135,7 +138,8 @@ public class Rectangle : ITextureObject
|
||||
|
||||
public void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
if (parent is IWindow w) Distance = new(w.CS.X - Size.X - Location.X, w.CS.Y - Size.Y - Location.Y);
|
||||
else Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
}
|
||||
|
||||
public virtual void Clean()
|
||||
@ -168,8 +172,8 @@ public class Rectangle : ITextureObject
|
||||
Loaded = true;
|
||||
Window.MouseDown += Window_MouseDown;
|
||||
Window.FileDrop += WindowOnFileDrop;
|
||||
Location = Location;
|
||||
if (Distance.X == 0 && Distance.Y == 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||
SetLocation(loc_.X, loc_.Y, loc_.Z);
|
||||
if (Distance.X == 0 && Distance.Y == 0) ForceDistanceUpdate(Parent);
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
}
|
||||
|
||||
@ -187,7 +191,7 @@ public class Rectangle : ITextureObject
|
||||
private void WindowOnFileDrop(FileDropEventArgs obj)
|
||||
{
|
||||
if (!MouseInside) return;
|
||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(obj.FileNames);
|
||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(this, obj.FileNames);
|
||||
}
|
||||
|
||||
private bool mi = false;
|
||||
@ -456,10 +460,20 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
set
|
||||
{
|
||||
size_ = value;
|
||||
SetSize(value.X, value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetSize(int wh)
|
||||
{
|
||||
SetSize(wh, wh);
|
||||
}
|
||||
public virtual void SetSize(int w, int h)
|
||||
{
|
||||
size_.X = w;
|
||||
size_.Y = h;
|
||||
if (Window is null || Parent is null) return;
|
||||
Parent.ReportSizeUpdate(this);
|
||||
//float[] temp = Points;
|
||||
float[] temp = Textures.Count == 0
|
||||
? new float[12]
|
||||
: TextureDisplay switch
|
||||
@ -469,7 +483,8 @@ public class Rectangle : ITextureObject
|
||||
TextureDisplay.Center => new float[80],
|
||||
_ => new float[20]
|
||||
};
|
||||
saf = new Vector2(Parent.IntToWindow(value.X + loc_.X, false), Parent.IntToWindow(value.Y + loc_.Y, true));
|
||||
saf.X = Parent.IntToWindow(w + loc_.X);
|
||||
saf.Y = Parent.IntToWindow(h + loc_.Y, true);
|
||||
temp[2] = Location.Z;
|
||||
temp[(!Textures.Any() ? 5 : 7)] = Location.Z;
|
||||
temp[(!Textures.Any() ? 8 : 12)] = Location.Z;
|
||||
@ -486,17 +501,16 @@ public class Rectangle : ITextureObject
|
||||
|
||||
if (Textures.Count > 0)
|
||||
{
|
||||
Vector2i s = value;
|
||||
float diff = Window.IntToWindow(s.Y) + 1;
|
||||
float diff = Window.IntToWindow(h) + 1;
|
||||
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
|
||||
if (TextureDisplay == TextureDisplay.TextureHorizontalCenter)
|
||||
diff = Window.IntToWindow(Textures[0].RawSize!.Value.Y);
|
||||
if (TextureDisplay == TextureDisplay.Center)
|
||||
{
|
||||
if (s.X > Textures[0].RawSize!.Value.X)
|
||||
if (w> Textures[0].RawSize!.Value.X)
|
||||
diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3;
|
||||
else
|
||||
diff = (Window.IntToWindow(s.X) + 1) / 3;
|
||||
diff = (Window.IntToWindow(w) + 1) / 3;
|
||||
per = Textures[0].MaxText.X / 3;
|
||||
}
|
||||
|
||||
@ -544,14 +558,14 @@ public class Rectangle : ITextureObject
|
||||
temp[19] = Textures[0].MaxText.Y;
|
||||
|
||||
int dy, dx;
|
||||
if (s.Y > Textures[0].RawSize!.Value.Y)
|
||||
if (h > Textures[0].RawSize!.Value.Y)
|
||||
dy = Textures[0].RawSize!.Value.Y;
|
||||
else
|
||||
dy = s.Y;
|
||||
if (s.X > Textures[0].RawSize!.Value.X)
|
||||
dy = h;
|
||||
if (w > Textures[0].RawSize!.Value.X)
|
||||
dx = Textures[0].RawSize!.Value.X;
|
||||
else
|
||||
dx = s.X;
|
||||
dx = w;
|
||||
|
||||
if (dy > dx) dy = dx;
|
||||
else dx = dy;
|
||||
@ -575,9 +589,9 @@ public class Rectangle : ITextureObject
|
||||
SetPoint(temp, 75, temp[35], temp[21], temp[2], temp[38], temp[24]);
|
||||
break;
|
||||
case TextureDisplay.ProgressHorizontalCenter:
|
||||
if (s.X > s.Y)
|
||||
if (w > h)
|
||||
{
|
||||
if (s.X > s.Y + s.Y)
|
||||
if (w > h+ h)
|
||||
{
|
||||
temp[3] = Textures[0].MaxText.X;
|
||||
temp[4] = Textures[0].MaxText.Y;
|
||||
@ -609,7 +623,7 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
else
|
||||
{
|
||||
temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X;
|
||||
temp[3] = (0.666666f + (((w - h) / (float)h)* per)) * Textures[0].MaxText.X;
|
||||
temp[4] = Textures[0].MaxText.Y;
|
||||
temp[8] = temp[3];
|
||||
temp[19] = Textures[0].MaxText.Y;
|
||||
@ -642,7 +656,7 @@ public class Rectangle : ITextureObject
|
||||
else
|
||||
{
|
||||
//first 33% of texture
|
||||
temp[3] = ((s.X/(float)s.Y)*per);
|
||||
temp[3] = ((w/(float)h)*per);
|
||||
temp[4] = Textures[0].MaxText.Y;
|
||||
temp[8] = temp[3];
|
||||
temp[19] = Textures[0].MaxText.Y;
|
||||
@ -675,19 +689,23 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
|
||||
Points = temp;
|
||||
temp = Array.Empty<float>();
|
||||
if (SizeChanged is not null) SizeChanged.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector3i Location
|
||||
public virtual void SetLocation(int x, int y)
|
||||
{
|
||||
get
|
||||
{
|
||||
return loc_;
|
||||
SetLocation(x, y, Location.Z);
|
||||
}
|
||||
set
|
||||
public virtual void SetLocation(int xy)
|
||||
{
|
||||
loc_ = value;
|
||||
SetLocation(xy, xy, 0);
|
||||
}
|
||||
public virtual void SetLocation(int x, int y, int z)
|
||||
{
|
||||
loc_.X = x;
|
||||
loc_.Y = y;
|
||||
loc_.Z = z;
|
||||
if (Window is null || Parent is null) return;
|
||||
float[] temp = Textures.Count == 0
|
||||
? new float[12]
|
||||
@ -698,17 +716,19 @@ public class Rectangle : ITextureObject
|
||||
TextureDisplay.Center => new float[80],
|
||||
_ => new float[20]
|
||||
};
|
||||
laf = new Vector2(Parent.IntToWindow(value.X, false), Parent.IntToWindow(value.Y, true));
|
||||
temp[2] = value.Z;
|
||||
temp[(!Textures.Any() ? 5 : 7)] = value.Z;
|
||||
temp[(!Textures.Any() ? 8 : 12)] = value.Z;
|
||||
temp[(!Textures.Any() ? 11 : 17)] = value.Z;
|
||||
laf.X = Parent.IntToWindow(x);
|
||||
laf.Y = Parent.IntToWindow(y, true);
|
||||
temp[2] = z;
|
||||
temp[(!Textures.Any() ? 5 : 7)] = z;
|
||||
temp[(!Textures.Any() ? 8 : 12)] = z;
|
||||
temp[(!Textures.Any() ? 11 : 17)] = z;
|
||||
|
||||
temp[(!Textures.Any() ? 6 : 10)] = laf.X;
|
||||
temp[(!Textures.Any() ? 9 : 15)] = laf.X;
|
||||
temp[1] = laf.Y;
|
||||
temp[(!Textures.Any() ? 10 : 16)] = laf.Y;
|
||||
saf = new Vector2(Parent.IntToWindow(Size.X + value.X, false), Parent.IntToWindow(Size.Y + value.Y, true));
|
||||
saf.X = Parent.IntToWindow(Size.X + x);
|
||||
saf.Y = Parent.IntToWindow(Size.Y + y, true);
|
||||
temp[0] = saf.X;
|
||||
temp[(!Textures.Any() ? 3 : 5)] = saf.X;
|
||||
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
|
||||
@ -898,6 +918,18 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
}
|
||||
Points = temp;
|
||||
temp = Array.Empty<float>();
|
||||
}
|
||||
|
||||
public virtual Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return loc_;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetLocation(value.X, value.Y, value.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,10 +141,9 @@ public class TabControl : ParentBase, IParent
|
||||
}
|
||||
}
|
||||
|
||||
public override void ParentResize(ResizeEventArgs e)
|
||||
public override void ParentResize()
|
||||
{
|
||||
BlockDraw = true;
|
||||
if (e.Width == 0 && e.Height == 0) return;
|
||||
if (!(Controls.Length >= PageIndex)) return;
|
||||
if (!Controls[PageIndex].Loaded) return;
|
||||
bool top = (Controls[PageIndex].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
|
||||
@ -161,7 +160,7 @@ public class TabControl : ParentBase, IParent
|
||||
Controls[PageIndex].Location = new(lx, ly, Controls[PageIndex].Location.Z);
|
||||
if (Controls[PageIndex] is IParent parent)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
parent.ParentResize();
|
||||
}
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
{
|
||||
@ -180,7 +179,7 @@ public class TabControl : ParentBase, IParent
|
||||
Buttonts[i].Location = new(lx, ly, Buttonts[i].Location.Z);
|
||||
if (Buttonts[i] is IParent parent2)
|
||||
{
|
||||
parent2.ParentResize(e);
|
||||
parent2.ParentResize();
|
||||
}
|
||||
}
|
||||
Parent!.TryDraw();
|
||||
@ -201,16 +200,16 @@ public class TabControl : ParentBase, IParent
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
if (Loaded && Visible)
|
||||
{
|
||||
base.Draw(x,y,w,h);
|
||||
base.Draw(x,y,sx,sy,sw,sh);
|
||||
if (!(Controls.Length >= (PageIndex))) return;
|
||||
if (!Controls[PageIndex].Loaded) return;
|
||||
Controls[PageIndex].Draw(x,y,w,h);
|
||||
Controls[PageIndex].Draw(x,y,sx,sy,sw,sh);
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
Buttonts[i].Draw(x,y,w,h);
|
||||
Buttonts[i].Draw(x,y,sx,sy,sw,sh);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#version 330
|
||||
|
||||
in vec2 in_pos;
|
||||
in vec2 in_uv;
|
||||
layout (location = 0) in vec2 in_pos;
|
||||
layout (location = 1) in vec2 in_uv;
|
||||
|
||||
out vec2 vUV;
|
||||
|
||||
|
@ -77,6 +77,14 @@ public class Window : NativeWindow , IWindow
|
||||
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, Size.X, Size.Y, 0, 1, -1);
|
||||
KeyDown += OnKeyDownn;
|
||||
TextInput += OnTextInputEvent;
|
||||
FileDrop += OnFileDrop;
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
}
|
||||
|
||||
private void OnFileDrop(FileDropEventArgs obj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnTextInputEvent(TextInputEventArgs obj)
|
||||
@ -136,28 +144,20 @@ public class Window : NativeWindow , IWindow
|
||||
}
|
||||
}
|
||||
|
||||
public Window() : this(new NativeWindowSettings())
|
||||
{
|
||||
/*
|
||||
TextureManager = TextureManager.GetTextureManager(Context);
|
||||
if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
|
||||
if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
|
||||
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
|
||||
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
|
||||
}
|
||||
public Window() : this(new NativeWindowSettings()) { }
|
||||
public Vector3i Position { get; } = new(0);
|
||||
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
|
||||
|
||||
public ControlList Controls { get; } = new();
|
||||
|
||||
public Vector2i CS { get; private set; } = new(0, 0);
|
||||
public Vector2i CS { get; set; } = new(0, 0);
|
||||
|
||||
public float IntToWindow(float p, bool Y = false)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
public void ForceUpdate(ResizeEventArgs e)
|
||||
public virtual void ForceUpdate()
|
||||
{
|
||||
BlockDraw = true;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
@ -169,15 +169,15 @@ public class Window : NativeWindow , IWindow
|
||||
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
|
||||
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
|
||||
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
|
||||
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
||||
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
||||
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
||||
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||
Controls[i].Size = new(sx, sy);
|
||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
||||
int lx = (left ? Controls[i].Location.X : CS.X - Controls[i].Distance.X - Controls[i].Size.X);
|
||||
int ly = (top ? Controls[i].Location.Y : CS.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
||||
int sy = (bottom ? CS.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
||||
int sx = (right ? CS.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||
Controls[i].SetSize(sx, sy);
|
||||
Controls[i].SetLocation(lx, ly);
|
||||
if (Controls[i] is IParent parent)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
parent.ParentResize();
|
||||
}
|
||||
}
|
||||
DrawFrame();
|
||||
@ -186,15 +186,9 @@ public class Window : NativeWindow , IWindow
|
||||
|
||||
public Matrix4 WindowSizeMatrix { get; set; }
|
||||
|
||||
public void ParentResize(ResizeEventArgs e)
|
||||
public virtual void ParentResize()
|
||||
{
|
||||
base.OnResize(e);
|
||||
|
||||
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
||||
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, e.Width, e.Height, 0, 1, -1);
|
||||
GL.Viewport(0, 0, e.Width, e.Height);
|
||||
CS = e.Size;
|
||||
ForceUpdate(e);
|
||||
ForceUpdate();
|
||||
}
|
||||
|
||||
private int frame = 0;
|
||||
@ -204,9 +198,22 @@ public class Window : NativeWindow , IWindow
|
||||
|
||||
}
|
||||
|
||||
public void SetWindowSize(Vector2i s)
|
||||
{
|
||||
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, s.X, s.Y, 0, 1, -1);
|
||||
GL.Viewport(0, 0, s.X, s.Y);
|
||||
CS = s;
|
||||
ClientSize = CS;
|
||||
ParentResize();
|
||||
}
|
||||
|
||||
protected override void OnResize(ResizeEventArgs e)
|
||||
{
|
||||
ParentResize(e);
|
||||
base.OnResize(e);
|
||||
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, e.Width, e.Height, 0, 1, -1);
|
||||
GL.Viewport(0, 0, e.Width, e.Height);
|
||||
CS = e.Size;
|
||||
ParentResize();
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
@ -233,7 +240,7 @@ public class Window : NativeWindow , IWindow
|
||||
{
|
||||
ProcessEvents(10);
|
||||
}
|
||||
public void StartRender()
|
||||
public virtual void StartRender()
|
||||
{
|
||||
Context.MakeCurrent();
|
||||
initthread = Thread.CurrentThread.ManagedThreadId;
|
||||
@ -260,10 +267,12 @@ public class Window : NativeWindow , IWindow
|
||||
}
|
||||
|
||||
public IRenderObject? HoveringControl { get; set; }
|
||||
public SubHitBox? HoveringHitBox { get; set; }
|
||||
|
||||
private void WhenMouseMove(MouseMoveEventArgs obj)
|
||||
{
|
||||
IRenderObject? cb = null;
|
||||
SubHitBox? cbhb = null;
|
||||
IRenderObject? checkcontrol(IRenderObject render, int add_x = 0, int addy = 0, IRenderObject? CurrentBest = null)
|
||||
{
|
||||
void ClearHoverChain(IRenderObject ChainObject)
|
||||
@ -276,7 +285,17 @@ public class Window : NativeWindow , IWindow
|
||||
}
|
||||
}
|
||||
|
||||
if (ChainObject.AllowHoverFromBehind) ChainObject.MouseInside = false;
|
||||
if (ChainObject.AllowHoverFromBehind)
|
||||
{
|
||||
ChainObject.MouseInside = false;
|
||||
if (ChainObject.SubHitBoxes.Count > 0)
|
||||
{
|
||||
foreach (SubHitBox shb in ChainObject.SubHitBoxes)
|
||||
{
|
||||
shb.MouseInside = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!render.Visible ||
|
||||
@ -297,13 +316,35 @@ public class Window : NativeWindow , IWindow
|
||||
CurrentBest = checkcontrol(p.Controls._internal[i], add_x + render.Location.X, addy + render.Location.Y, CurrentBest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (CurrentBest is null)
|
||||
{
|
||||
cbhb = null;
|
||||
CurrentBest = render;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CurrentBest.Location.Z < render.Location.Z) CurrentBest = render;
|
||||
if (CurrentBest.Location.Z < render.Location.Z)
|
||||
{
|
||||
cbhb = null;
|
||||
CurrentBest = render;
|
||||
}
|
||||
}
|
||||
|
||||
if (render == CurrentBest && CurrentBest.SubHitBoxes.Count > 0)
|
||||
{
|
||||
foreach (SubHitBox hb in CurrentBest.SubHitBoxes)
|
||||
{
|
||||
if (render.Location.X + hb.Location.X + add_x > obj.X ||
|
||||
render.Location.Y + hb.Location.Y + addy > obj.Y ||
|
||||
render.Location.X + hb.Location.X + hb.Size.X + add_x < obj.X ||
|
||||
render.Location.Y + hb.Location.Y + hb.Size.Y + addy < obj.Y)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cbhb = hb;
|
||||
}
|
||||
}
|
||||
|
||||
return CurrentBest;
|
||||
@ -325,6 +366,19 @@ public class Window : NativeWindow , IWindow
|
||||
else Cursor = HoverMouse;
|
||||
if (old is not null) old.MouseInside = false;
|
||||
}
|
||||
|
||||
if (cbhb != HoveringHitBox)
|
||||
{
|
||||
SubHitBox? old = HoveringHitBox;
|
||||
HoveringHitBox = cbhb;
|
||||
if (cbhb is not null)
|
||||
{
|
||||
cbhb.MouseInside = true;
|
||||
Cursor = cbhb.HoverMouse;
|
||||
}
|
||||
else Cursor = HoverMouse;
|
||||
if (old is not null) old.MouseInside = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartRenderAsync()
|
||||
@ -357,16 +411,13 @@ public class Window : NativeWindow , IWindow
|
||||
invokes.Enqueue(A);
|
||||
}
|
||||
|
||||
public void DrawFrame()
|
||||
public virtual void DrawFrame()
|
||||
{
|
||||
Context.MakeCurrent();
|
||||
frame++;
|
||||
if (LogFrames) Console.WriteLine($"Drawing Frame: {frame}");
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
|
||||
GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, BackgroundColor.A);
|
||||
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
||||
|
||||
@ -385,9 +436,8 @@ public class Window : NativeWindow , IWindow
|
||||
{
|
||||
if (!Controls[i].Loaded) continue;
|
||||
GL.Scissor(0, 0, CS.X, CS.Y);
|
||||
Controls[i].Draw(0,0,CS.X, CS.Y);
|
||||
Controls[i].Draw(0,0,0,0,CS.X, CS.Y);
|
||||
}
|
||||
Context.SwapBuffers();
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user