Compare commits
No commits in common. "ecf4e808ea7fef534c1f5c59977b1c3003b02e0a" and "448e0f670f12154d489accda6c0400c8662e1e3d" have entirely different histories.
ecf4e808ea
...
448e0f670f
@ -36,7 +36,7 @@ public class ContextMenu : Window
|
|||||||
BackgroundColor = new(0, 0, 0, 0);
|
BackgroundColor = new(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ItemsOnControlAdded(int index, IRenderObject arg)
|
private Task ItemsOnControlAdded(IRenderObject arg)
|
||||||
{
|
{
|
||||||
arg.Clicked += ArgOnClicked;
|
arg.Clicked += ArgOnClicked;
|
||||||
this.Context.MakeCurrent();
|
this.Context.MakeCurrent();
|
||||||
@ -57,9 +57,9 @@ public class ContextMenu : Window
|
|||||||
if (!e.IsFocused && w is not null) HideContext(w,true);
|
if (!e.IsFocused && w is not null) HideContext(w,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IWindow? w = null;
|
private Window? w = null;
|
||||||
|
|
||||||
public void HideContext(IWindow Parent, bool force = false)
|
public void HideContext(Window Parent, bool force = false)
|
||||||
{
|
{
|
||||||
if (Parent.ActiveMenu == this && !false) return;
|
if (Parent.ActiveMenu == this && !false) return;
|
||||||
w = null;
|
w = null;
|
||||||
@ -68,7 +68,7 @@ public class ContextMenu : Window
|
|||||||
IsVisible = false;
|
IsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowContext(IWindow Parent)
|
public void ShowContext(Window Parent)
|
||||||
{
|
{
|
||||||
w = Parent;
|
w = Parent;
|
||||||
if (Parent.ActiveMenu == this)
|
if (Parent.ActiveMenu == this)
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
namespace GraphicsManager.Enums;
|
|
||||||
|
|
||||||
public enum TextureDisplay : byte
|
|
||||||
{
|
|
||||||
Clamped,
|
|
||||||
HorizontalCenter,
|
|
||||||
TextureHorizontalCenter,
|
|
||||||
VerticalCenter,
|
|
||||||
Center,
|
|
||||||
ProgressHorizontalCenter,
|
|
||||||
}
|
|
@ -1,398 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using GraphicsManager.Enums;
|
|
||||||
using GraphicsManager.Interfaces;
|
|
||||||
using GraphicsManager.Objects;
|
|
||||||
using GraphicsManager.Objects.Core;
|
|
||||||
using OpenTK.Graphics.OpenGL4;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
using OpenTK.Windowing.Common;
|
|
||||||
using OpenTK.Windowing.Common.Input;
|
|
||||||
using OpenTK.Windowing.Desktop;
|
|
||||||
using OpenTK.Windowing.GraphicsLibraryFramework;
|
|
||||||
|
|
||||||
namespace GraphicsManager;
|
|
||||||
|
|
||||||
public class FPSWindow : GameWindow , IWindow
|
|
||||||
{
|
|
||||||
public TextureManager TextureManager { get; private set; }
|
|
||||||
private TitleBar? _tb = null;
|
|
||||||
|
|
||||||
public TitleBar? CustomeTitleBar
|
|
||||||
{
|
|
||||||
get => _tb;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_tb = value;
|
|
||||||
//some setting/changeing code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRenderObject? focused { get; set; }
|
|
||||||
public void CenterWindow(int mon)
|
|
||||||
{
|
|
||||||
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
|
|
||||||
int num = (clientArea.Min.X + clientArea.Max.X - Size.X) / 2;
|
|
||||||
int num2 = (clientArea.Min.Y + clientArea.Max.Y - Size.Y) / 2;
|
|
||||||
if (num < clientArea.Min.X)
|
|
||||||
{
|
|
||||||
num = clientArea.Min.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num2 < clientArea.Min.Y)
|
|
||||||
{
|
|
||||||
num2 = clientArea.Min.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContextMenu? ActiveMenu { get; set; } = null;
|
|
||||||
public IParent? Parent { get; } = null;
|
|
||||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
|
||||||
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);
|
|
||||||
public FPSWindow(NativeWindowSettings nativeWindowSettings, GameWindowSettings gws) : base(gws,nativeWindowSettings)
|
|
||||||
{
|
|
||||||
TextureManager = TextureManager.GetTextureManager(Context);
|
|
||||||
Context.MakeCurrent();
|
|
||||||
if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true, Texture:true));
|
|
||||||
if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
|
|
||||||
if (!Rectangle.DefaultAlphaShader.ContainsKey(Context)) Rectangle.DefaultAlphaShader.Add(Context, new("AlphaChannel", true, Texture:true));
|
|
||||||
if (!Rectangle.DefaultAlphaTextureShader.ContainsKey(Context)) Rectangle.DefaultAlphaTextureShader.Add(Context, new("AlphaChannelTexture", true, Texture:true));
|
|
||||||
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
|
|
||||||
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());
|
|
||||||
last = WindowState;
|
|
||||||
KeyDown += OnKeyDownn;
|
|
||||||
}
|
|
||||||
|
|
||||||
private WindowState last;
|
|
||||||
private bool fs = false;
|
|
||||||
private Vector2i os, loc;
|
|
||||||
public bool CustomF11 = true;
|
|
||||||
private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
|
|
||||||
{
|
|
||||||
if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
|
|
||||||
if (CustomF11)
|
|
||||||
{
|
|
||||||
GLFW.WindowHint(WindowHintBool.AutoIconify, true);
|
|
||||||
if (WindowState != WindowState.Normal) last = WindowState;
|
|
||||||
switch (fs)
|
|
||||||
{
|
|
||||||
case false:
|
|
||||||
loc = Location;
|
|
||||||
os = Size;
|
|
||||||
WindowBorder = WindowBorder.Hidden;
|
|
||||||
Location = new(4090, 0);
|
|
||||||
fs = true;
|
|
||||||
break;
|
|
||||||
case true:
|
|
||||||
WindowBorder = WindowBorder.Resizable;
|
|
||||||
GLFW.RestoreWindow(this.WindowPtr);
|
|
||||||
Size = os;
|
|
||||||
Location = loc;
|
|
||||||
fs = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (fs)
|
|
||||||
{
|
|
||||||
case false:
|
|
||||||
WindowState = WindowState.Fullscreen;
|
|
||||||
fs = true;
|
|
||||||
break;
|
|
||||||
case true:
|
|
||||||
WindowState = WindowState.Normal;
|
|
||||||
fs = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FPSWindow() : this(new NativeWindowSettings(), new GameWindowSettings())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public Vector3i Position { get; } = new(0);
|
|
||||||
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
|
|
||||||
|
|
||||||
public ControlList Controls { get; } = new();
|
|
||||||
#region Cool Math Things
|
|
||||||
public float[] RctToFloat(int x, int y, int Width, int Height, bool hasTexture = false, float z = 0.0f)
|
|
||||||
{
|
|
||||||
if (hasTexture)
|
|
||||||
{
|
|
||||||
return new float[20] {
|
|
||||||
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
|
||||||
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
|
|
||||||
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
|
|
||||||
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new float[12] {
|
|
||||||
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
|
|
||||||
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
|
|
||||||
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
|
|
||||||
IntToFloat(x), IntToFloat(y, true), z,// top l
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3 PointToVector(float x, float y, float z = 0.0f)
|
|
||||||
{
|
|
||||||
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float IntToFloat(float p, bool Invert = false)
|
|
||||||
{
|
|
||||||
float Size = (Invert ? this.Size.Y : this.Size.X);
|
|
||||||
double half = Math.Round((double)Size / (double)2, 1);
|
|
||||||
double Per = Math.Round((double)1 / half, 15);
|
|
||||||
if (p == half) return 0.0f;
|
|
||||||
if (Invert)
|
|
||||||
{
|
|
||||||
if (p > half) return (float)(((double)(p - half) * Per) * -1);
|
|
||||||
else return (float)(1 - (p * Per));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p > half) return (float)((double)(p - half) * Per);
|
|
||||||
else return (float)((1 - (p * Per)) * -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float FloatToInt(float p, bool Invert = false)
|
|
||||||
{
|
|
||||||
float Size = (Invert ? this.Size.Y : this.Size.X);
|
|
||||||
double half = Math.Round((double)Size / (double)2, 15);
|
|
||||||
if (p == 0) return (int)half;
|
|
||||||
if (Invert)
|
|
||||||
{
|
|
||||||
if (p < 0)
|
|
||||||
{
|
|
||||||
p *= -1;
|
|
||||||
p++;
|
|
||||||
return (float)(half * p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (float)(half - (p * half));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p < 0)
|
|
||||||
{
|
|
||||||
p *= -1;
|
|
||||||
p++;
|
|
||||||
return (float)(Size - (half * p));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (float)(p * half + half);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void ForceUpdate(ResizeEventArgs e)
|
|
||||||
{
|
|
||||||
BlockDraw = true;
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
if (!Controls[i].Loaded) continue;
|
|
||||||
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
|
|
||||||
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
|
|
||||||
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
|
|
||||||
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
|
|
||||||
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
|
|
||||||
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
|
|
||||||
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
|
||||||
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
|
||||||
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
|
||||||
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
|
||||||
Controls[i].Size = new(sx, sy);
|
|
||||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
|
||||||
if (Controls[i] is IParent parent)
|
|
||||||
{
|
|
||||||
parent.ParentResize(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockDraw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ParentResize(ResizeEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnResize(e);
|
|
||||||
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
|
||||||
GL.Viewport(0, 0, e.Width, e.Height);
|
|
||||||
Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
|
|
||||||
ForceUpdate(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int frame = 0;
|
|
||||||
|
|
||||||
public void ReportSizeUpdate(IRenderObject Control)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResize(ResizeEventArgs e)
|
|
||||||
{
|
|
||||||
ParentResize(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnClosing(CancelEventArgs e)
|
|
||||||
{
|
|
||||||
Context.MakeCurrent();
|
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
|
||||||
GL.BindVertexArray(0);
|
|
||||||
GL.UseProgram(0);
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
Controls[i].Clean();
|
|
||||||
}
|
|
||||||
base.OnClosing(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates;
|
|
||||||
|
|
||||||
public bool CanControleUpdate { get; private set; } = true;
|
|
||||||
|
|
||||||
public int FPS { get; set; } = 0;
|
|
||||||
public event Func<FPSWindow, Task>? WindowLoaded;
|
|
||||||
public List<Window> Windows = new();
|
|
||||||
|
|
||||||
public IRenderObject? HoveringControl { get; set; }
|
|
||||||
|
|
||||||
private void WhenMouseMove(MouseMoveEventArgs obj)
|
|
||||||
{
|
|
||||||
IRenderObject? cb = null;
|
|
||||||
IRenderObject? checkcontrol(IRenderObject render, int add_x = 0, int addy = 0, IRenderObject? CurrentBest = null)
|
|
||||||
{
|
|
||||||
void ClearHoverChain(IRenderObject ChainObject)
|
|
||||||
{
|
|
||||||
if (ChainObject is IParent parent)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < parent.Controls.Length; i++)
|
|
||||||
{
|
|
||||||
ClearHoverChain(parent.Controls._internal[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ChainObject.AllowHoverFromBehind) ChainObject.MouseInside = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!render.Visible ||
|
|
||||||
render.IgnoreHover ||
|
|
||||||
render.Location.X + add_x > obj.X ||
|
|
||||||
render.Location.Y + addy > obj.Y ||
|
|
||||||
render.Location.X + render.Size.X + add_x < obj.X ||
|
|
||||||
render.Location.Y + render.Size.Y + addy < obj.Y)
|
|
||||||
{
|
|
||||||
ClearHoverChain(render);
|
|
||||||
return CurrentBest;
|
|
||||||
}
|
|
||||||
if (render.AllowHoverFromBehind) render.MouseInside = true;
|
|
||||||
if (render is IParent p)
|
|
||||||
{
|
|
||||||
for (int i = p.Controls.Length - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
CurrentBest = checkcontrol(p.Controls._internal[i], add_x + render.Location.X, addy + render.Location.Y, CurrentBest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CurrentBest is null)
|
|
||||||
{
|
|
||||||
CurrentBest = render;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (CurrentBest.Location.Z < render.Location.Z) CurrentBest = render;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CurrentBest;
|
|
||||||
}
|
|
||||||
for (int i = Controls.Length - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
cb = checkcontrol(Controls._internal[i],0,0,cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb != HoveringControl)
|
|
||||||
{
|
|
||||||
IRenderObject? old = HoveringControl;
|
|
||||||
HoveringControl = cb;
|
|
||||||
if (cb is not null)
|
|
||||||
{
|
|
||||||
cb.MouseInside = true;
|
|
||||||
Cursor = cb.HoverMouse;
|
|
||||||
}
|
|
||||||
else Cursor = HoverMouse;
|
|
||||||
if (old is not null) old.MouseInside = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool BlockDraw { get; set; }
|
|
||||||
|
|
||||||
public void TryDraw()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private int initthread;
|
|
||||||
|
|
||||||
public bool InvokeRequired
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return initthread != Thread.CurrentThread.ManagedThreadId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Queue<Action> invokes = new();
|
|
||||||
|
|
||||||
public void Invoke(Action A)
|
|
||||||
{
|
|
||||||
invokes.Enqueue(A);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRenderFrame(FrameEventArgs args)
|
|
||||||
{
|
|
||||||
Context.MakeCurrent();
|
|
||||||
frame++;
|
|
||||||
Console.WriteLine($"Drawing Frame: {frame}");
|
|
||||||
GL.Enable(EnableCap.Blend);
|
|
||||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
|
||||||
GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
|
||||||
GL.Enable(EnableCap.ScissorTest);
|
|
||||||
|
|
||||||
GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, (BackgroundColor.A * -1) + 1);
|
|
||||||
if (invokes.Any())
|
|
||||||
{
|
|
||||||
for (int i = 0; i < invokes.Count; i++) invokes.Dequeue().Invoke();
|
|
||||||
}
|
|
||||||
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
|
||||||
|
|
||||||
if (needload.Any())
|
|
||||||
{
|
|
||||||
BlockDraw = true;
|
|
||||||
foreach (IRenderObject obj in needload)
|
|
||||||
{
|
|
||||||
obj.LoadToParent(this, this);
|
|
||||||
}
|
|
||||||
BlockDraw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
if (!Controls[i].Loaded) continue;
|
|
||||||
GL.Scissor(0, 0, Size.X, Size.Y);
|
|
||||||
Controls[i].Draw(0,0,Size.X, Size.Y);
|
|
||||||
}
|
|
||||||
Context.SwapBuffers();
|
|
||||||
base.OnRenderFrame(args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<FileVersion>1.0.0.0</FileVersion>
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<IncludeSymbols>False</IncludeSymbols>
|
<IncludeSymbols>False</IncludeSymbols>
|
||||||
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
|
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<Version>1.0.7-alpha69</Version>
|
<Version>1.0.6-alpha89</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
@ -12,12 +12,12 @@ public interface IParent
|
|||||||
public IParent? Parent { get; }
|
public IParent? Parent { get; }
|
||||||
public Vector2i Size { get; }
|
public Vector2i Size { get; }
|
||||||
public void ParentResize(ResizeEventArgs e);
|
public void ParentResize(ResizeEventArgs e);
|
||||||
public float[] RctToFloat(int x, int y, int Width, int Height, bool hasTexture = false, float z = 0.0f);
|
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f);
|
||||||
public Vector3 PointToVector(float x, float y, float z = 0.0f);
|
public Vector3 PointToVector(float x, float y, float z = 0.0f);
|
||||||
public float IntToFloat(float p, bool Invert = false);
|
public float IntToFloat(float p, bool Invert = false);
|
||||||
public void TryDraw();
|
public void TryDraw();
|
||||||
public void ReportSizeUpdate(IRenderObject Control);
|
public void ReportSizeUpdate(IRenderObject Control);
|
||||||
public float FloatToInt(float p, bool Invert = false);
|
public float FloatToInt(float p, bool Invert = false);
|
||||||
public Vector3i Position { get; }
|
public Vector2i Position { get; }
|
||||||
public MouseCursor HoverMouse { get; set; }
|
public MouseCursor HoverMouse { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -10,23 +10,20 @@ public interface IRenderObject
|
|||||||
public void ForceDistanceUpdate(IParent parent);
|
public void ForceDistanceUpdate(IParent parent);
|
||||||
public ContextMenu? ContextMenu { get; set; }
|
public ContextMenu? ContextMenu { get; set; }
|
||||||
public ObjectAnchor Anchor { get; set; }
|
public ObjectAnchor Anchor { get; set; }
|
||||||
public bool MouseInside { get; set; }
|
|
||||||
public bool IgnoreHover { get; set; }
|
|
||||||
public bool AllowHoverFromBehind { get; set; }
|
|
||||||
public bool Loaded { get; }
|
public bool Loaded { get; }
|
||||||
public void LoadToParent(IParent Parent, IWindow Window);
|
public void LoadToParent(IParent Parent, Window Window);
|
||||||
public void Draw(int x, int y, int w, int h);
|
public void Draw(int x, int y, int w, int h);
|
||||||
public MouseCursor HoverMouse { get; set; }
|
public MouseCursor HoverMouse { get; set; }
|
||||||
public void Clean();
|
public void Clean();
|
||||||
public void Focus();
|
public void Focus();
|
||||||
public void UnFocus();
|
public void UnFocus();
|
||||||
public Vector2i Size { get; set; }
|
public Vector2i Size { get; set; }
|
||||||
public Vector3i Location { get; set; }
|
public Vector2i Location { get; set; }
|
||||||
public Vector2 SizeAsFloat { get; }
|
public Vector2 SizeAsFloat { get; }
|
||||||
public Vector2 LocationAsFloat { get; }
|
public Vector2 LocationAsFloat { get; }
|
||||||
public Vector2i Distance { get; set; }
|
public Vector2i Distance { get; set; }
|
||||||
public IParent? Parent { get; }
|
public IParent? Parent { get; }
|
||||||
public IWindow? Window { get; }
|
public Window? Window { get; }
|
||||||
public bool Visible { get; set; }
|
public bool Visible { get; set; }
|
||||||
public object? Tag { get; set; }
|
public object? Tag { get; set; }
|
||||||
|
|
||||||
|
@ -4,14 +4,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GraphicsManager.Enums;
|
|
||||||
|
|
||||||
namespace GraphicsManager.Interfaces;
|
namespace GraphicsManager.Interfaces;
|
||||||
|
|
||||||
public interface ITextureObject : IRenderObject
|
public interface ITextureObject : IRenderObject
|
||||||
{
|
{
|
||||||
public List<Texture> Textures { get; }
|
public List<Texture> Textures { get; }
|
||||||
|
|
||||||
public TextureDisplay TextureDisplay { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
using OpenTK.Mathematics;
|
|
||||||
using OpenTK.Windowing.Common;
|
|
||||||
using OpenTK.Windowing.Desktop;
|
|
||||||
|
|
||||||
namespace GraphicsManager.Interfaces;
|
|
||||||
|
|
||||||
public interface IWindow : IParent
|
|
||||||
{
|
|
||||||
public IRenderObject? HoveringControl { get; set; }
|
|
||||||
public IGLFWGraphicsContext Context { get; }
|
|
||||||
|
|
||||||
public event Action<MouseButtonEventArgs> MouseDown;
|
|
||||||
|
|
||||||
public event Action<FileDropEventArgs> FileDrop;
|
|
||||||
|
|
||||||
public event Action<MouseWheelEventArgs> MouseWheel;
|
|
||||||
|
|
||||||
public event Action<KeyboardKeyEventArgs> KeyDown;
|
|
||||||
|
|
||||||
public event Action<TextInputEventArgs> TextInput;
|
|
||||||
public Vector2i Location { get; set; }
|
|
||||||
|
|
||||||
public IRenderObject? focused { get; set; }
|
|
||||||
|
|
||||||
public string ClipboardString { get; set; }
|
|
||||||
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
public Vector2 MousePosition { get; set; }
|
|
||||||
|
|
||||||
public ContextMenu? ActiveMenu { get; set; }
|
|
||||||
|
|
||||||
public bool CanControleUpdate { get; }
|
|
||||||
}
|
|
@ -18,7 +18,7 @@ public class ControlList
|
|||||||
|
|
||||||
public int Length => _internal.Count;
|
public int Length => _internal.Count;
|
||||||
|
|
||||||
internal event Func<int, IRenderObject, Task>? ControlAdded;
|
internal event Func<IRenderObject, Task>? ControlAdded;
|
||||||
internal event Func<Task>? ControlRemoved;
|
internal event Func<Task>? ControlRemoved;
|
||||||
|
|
||||||
public void Remove(IRenderObject item, bool purge = true)
|
public void Remove(IRenderObject item, bool purge = true)
|
||||||
@ -33,24 +33,12 @@ public class ControlList
|
|||||||
if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke();
|
if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MoveControlToEnd(IRenderObject item)
|
|
||||||
{
|
|
||||||
_internal.Remove(item);
|
|
||||||
_internal.Add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(IRenderObject item)
|
public void Add(IRenderObject item)
|
||||||
{
|
{
|
||||||
if (ControlAdded is not null) ControlAdded.Invoke(_internal.Count, item).Wait();
|
if (ControlAdded is not null) ControlAdded.Invoke(item).Wait();
|
||||||
_internal.Add(item);
|
_internal.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Insert(int index, IRenderObject item)
|
|
||||||
{
|
|
||||||
if (ControlAdded is not null) ControlAdded.Invoke(index, item).Wait();
|
|
||||||
_internal.Insert(index, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear(bool purge = true)
|
public void Clear(bool purge = true)
|
||||||
{
|
{
|
||||||
Clearing = true;
|
Clearing = true;
|
||||||
|
@ -1,244 +0,0 @@
|
|||||||
using GraphicsManager.Enums;
|
|
||||||
using GraphicsManager.Interfaces;
|
|
||||||
using OpenTK.Graphics.OpenGL4;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
using OpenTK.Windowing.Common;
|
|
||||||
|
|
||||||
namespace GraphicsManager.Objects.Core;
|
|
||||||
|
|
||||||
public abstract class ParentBase : Rectangle, IParent
|
|
||||||
{
|
|
||||||
protected ParentBase(Texture? texture = null)
|
|
||||||
: base(texture)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControlList Controls { get; } = new();
|
|
||||||
|
|
||||||
public bool BlockDraw { get; set; }
|
|
||||||
|
|
||||||
public Vector3i Position => Location;
|
|
||||||
|
|
||||||
public void TryDraw()
|
|
||||||
{
|
|
||||||
if (!BlockDraw && Parent is not null) Parent.TryDraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void ParentResize(ResizeEventArgs e)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
|
|
||||||
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
|
|
||||||
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
|
|
||||||
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
|
|
||||||
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
|
|
||||||
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
|
|
||||||
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
|
||||||
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
|
||||||
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
|
||||||
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
|
||||||
Controls[i].Size = new(sx, sy);
|
|
||||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
|
||||||
if (Controls[i] is IParent parent)
|
|
||||||
{
|
|
||||||
parent.ParentResize(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Parent!.TryDraw();
|
|
||||||
BlockDraw = PastBlockState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void ReportSizeUpdate(IRenderObject Control)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
if (Loaded && Visible)
|
|
||||||
{
|
|
||||||
int nx = x, ny = y, nw = w, nh = h;
|
|
||||||
if (Location.X > nw)
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nx += Location.X;
|
|
||||||
nw -= Location.X;
|
|
||||||
if (Size.X < nw)
|
|
||||||
nw = Size.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Location.Y > nh)
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ny += Location.Y;
|
|
||||||
nh -= Location.Y;
|
|
||||||
if (Size.Y < nh)
|
|
||||||
nh = Size.Y;
|
|
||||||
}
|
|
||||||
if (nw == 0 || nh == 0) return;
|
|
||||||
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
|
||||||
base.Draw(nx,ny,nw,nh);
|
|
||||||
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
|
||||||
|
|
||||||
if (needload.Any())
|
|
||||||
{
|
|
||||||
BlockDraw = true;
|
|
||||||
foreach (IRenderObject Control in needload)
|
|
||||||
{
|
|
||||||
Control.LoadToParent(this, Window!);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockDraw = false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
if (Controls[i] is not IParent)
|
|
||||||
{
|
|
||||||
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
|
||||||
}
|
|
||||||
Controls[i].Draw(nx, ny, nw, nh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Clean()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
Controls[i].Clean();
|
|
||||||
}
|
|
||||||
base.Clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
|
||||||
{
|
|
||||||
if (Loaded) return;
|
|
||||||
bool PastBlockState = BlockDraw;
|
|
||||||
BlockDraw = true;
|
|
||||||
base.LoadToParent(Parent, Window);
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
Controls[i].LoadToParent(this, Window);
|
|
||||||
}
|
|
||||||
BlockDraw = PastBlockState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector3i Location
|
|
||||||
{
|
|
||||||
get => base.Location;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
BlockDraw = true;
|
|
||||||
base.Location = value;
|
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
Controls[i].Location = Controls[i].Location;
|
|
||||||
}
|
|
||||||
ParentResize(new());
|
|
||||||
if (Parent is not null) Parent.TryDraw();
|
|
||||||
BlockDraw = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Cool Math Things
|
|
||||||
public float[] RctToFloat(int x, int y, int Width, int Height, bool hasTexture = false, float z = 0.0f)
|
|
||||||
{
|
|
||||||
if (hasTexture)
|
|
||||||
{
|
|
||||||
return new [] {
|
|
||||||
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
|
||||||
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
|
|
||||||
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
|
|
||||||
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new [] {
|
|
||||||
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
|
|
||||||
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
|
|
||||||
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
|
|
||||||
IntToFloat(x), IntToFloat(y, true), z,// top l
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3 PointToVector(float x, float y, float z = 0.0f)
|
|
||||||
{
|
|
||||||
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float IntToFloat(float p, bool Invert = false)
|
|
||||||
{
|
|
||||||
p += (Invert ? Location.Y : Location.X);
|
|
||||||
IParent? TempParentObject = Parent;
|
|
||||||
while (TempParentObject is not null)
|
|
||||||
{
|
|
||||||
p += (Invert ? TempParentObject.Position.Y : TempParentObject.Position.X);
|
|
||||||
TempParentObject = TempParentObject.Parent;
|
|
||||||
}
|
|
||||||
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
|
||||||
double half = Math.Round((double)Size / (double)2, 1);
|
|
||||||
double Per = Math.Round((double)1 / half, 15);
|
|
||||||
if (p == half) return 0.0f;
|
|
||||||
if (Invert)
|
|
||||||
{
|
|
||||||
if (p > half) return (float)(((double)(p - half) * Per) * -1);
|
|
||||||
else return (float)(1 - (p * Per));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p > half) return (float)((double)(p - half) * Per);
|
|
||||||
else return (float)((1 - (p * Per)) * -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float FloatToInt(float p, bool Invert = false)
|
|
||||||
{
|
|
||||||
p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
|
|
||||||
IParent? tempp = Parent;
|
|
||||||
while (tempp is not null)
|
|
||||||
{
|
|
||||||
p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
|
|
||||||
tempp = tempp.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
|
||||||
double half = Math.Round((double)Size / (double)2, 15);
|
|
||||||
if (p == 0) return (int)half;
|
|
||||||
if (Invert)
|
|
||||||
{
|
|
||||||
if (p < 0)
|
|
||||||
{
|
|
||||||
p *= -1;
|
|
||||||
p++;
|
|
||||||
return (float)(half * p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (float)(half - (p * half));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p < 0)
|
|
||||||
{
|
|
||||||
p *= -1;
|
|
||||||
p++;
|
|
||||||
return (float)(Size - (half * p));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (float)(p * half + half);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
using GraphicsManager.Interfaces;
|
|
||||||
using GraphicsManager.Objects.Core;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
|
||||||
|
|
||||||
public class RoundedButton : Rectangle
|
|
||||||
{
|
|
||||||
internal Label _label;
|
|
||||||
public RoundedButton(Texture t, FontFamily family)
|
|
||||||
:base(t)
|
|
||||||
{
|
|
||||||
_label = new Label(family);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoundedButton(Texture t, FontInteraction family)
|
|
||||||
:base(t)
|
|
||||||
{
|
|
||||||
_label = new Label(family);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FontInteraction Font { get => _label.Font; }
|
|
||||||
public string Text { get => _label.Text; set => _label.Text = value; }
|
|
||||||
public override Vector2i Size
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return base.Size;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
base.Size = value;
|
|
||||||
_label.Location = new(Location.X + (((value.X) / 2) - (_label.Size.X / 2)), Location.Y + (((value.Y) / 2) - (_label.Size.Y / 2)), Location.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector3i Location {
|
|
||||||
get => base.Location;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
base.Location = value;
|
|
||||||
_label.Location = new(value.X + (((Size.X) / 2) - (_label.Size.X / 2)), value.Y + (((Size.Y) / 2) - (_label.Size.Y / 2)), value.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color4 FontColor { get => _label.Color; set => _label.Color = value; }
|
|
||||||
public override bool Visible
|
|
||||||
{
|
|
||||||
get => base.Visible;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_label.Visible = value;
|
|
||||||
base.Visible = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Clean()
|
|
||||||
{
|
|
||||||
_label.Clean();
|
|
||||||
base.Clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
if (!Visible || !Loaded) return;
|
|
||||||
base.Draw(x,y,w,h);
|
|
||||||
_label.Draw(x,y,w,h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
|
||||||
{
|
|
||||||
if (Loaded) return;
|
|
||||||
base.LoadToParent(Parent, Window);
|
|
||||||
_label.LoadToParent(Parent, Window);
|
|
||||||
Location = Location;
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,7 +48,6 @@ public class Texture
|
|||||||
public int handel;
|
public int handel;
|
||||||
public Vector2i? RawSize = null;
|
public Vector2i? RawSize = null;
|
||||||
public int Location { get; set; } = 1;
|
public int Location { get; set; } = 1;
|
||||||
public Vector2 MaxText = new(1f);
|
|
||||||
|
|
||||||
private Texture(byte[] pixels, int Width, int Height)
|
private Texture(byte[] pixels, int Width, int Height)
|
||||||
{
|
{
|
||||||
@ -60,6 +59,7 @@ public class Texture
|
|||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||||
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Texture(Image<Rgba32> image, Memory<Rgba32> m)
|
private Texture(Image<Rgba32> image, Memory<Rgba32> m)
|
||||||
@ -72,6 +72,7 @@ public class Texture
|
|||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||||
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,22 +5,27 @@ using GraphicsManager.Objects.Core;
|
|||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using OpenTK.Mathematics;
|
using OpenTK.Mathematics;
|
||||||
using OpenTK.Windowing.Common;
|
using OpenTK.Windowing.Common;
|
||||||
|
using OpenTK.Windowing.Common.Input;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
public class FlowLayout : ParentBase
|
public class FlowLayout : IRenderObject, IParent
|
||||||
{
|
{
|
||||||
public FlowLayout(Texture? texture = null)
|
private Rectangle _bounds;
|
||||||
:base(texture)
|
|
||||||
|
public FlowLayout()
|
||||||
{
|
{
|
||||||
AllowHoverFromBehind = true;
|
_bounds = new Rectangle();
|
||||||
|
_bounds.Clicked += _bounds_Clicked;
|
||||||
t = new(33);
|
t = new(33);
|
||||||
t.Enabled = true;
|
t.Enabled = true;
|
||||||
t.Elapsed += TOnElapsed;
|
t.Elapsed += TOnElapsed;
|
||||||
t.Start();
|
t.Start();
|
||||||
Controls.ControlAdded += ControlsOnControlAdded;
|
Controls.ControlAdded += ControlsOnControlAdded;
|
||||||
Controls.ControlRemoved += ControlsOnControlRemoved;
|
Controls.ControlRemoved += ControlsOnControlRemoved;
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScrollToControl(IRenderObject Control)
|
public void ScrollToControl(IRenderObject Control)
|
||||||
@ -44,7 +49,7 @@ public class FlowLayout : ParentBase
|
|||||||
for (int i = Controls.Length - 1; i >= 0; i--)
|
for (int i = Controls.Length - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
start -= Controls[i].Size.Y;
|
start -= Controls[i].Size.Y;
|
||||||
Controls[i].Location = new(Controls[i].Location.X, start, Controls[i].Location.Z);
|
Controls[i].Location = new(Controls[i].Location.X, start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -56,7 +61,7 @@ public class FlowLayout : ParentBase
|
|||||||
for (int i = 0; i < Controls.Length; i++)
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
{
|
{
|
||||||
start += Controls[i].Size.Y;
|
start += Controls[i].Size.Y;
|
||||||
Controls[i].Location = new(Controls[i].Location.X, start, Controls[i].Location.Z);
|
Controls[i].Location = new(Controls[i].Location.X, start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +88,7 @@ public class FlowLayout : ParentBase
|
|||||||
ScrollToControl(Controls[Controls.Length - 1]);
|
ScrollToControl(Controls[Controls.Length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReportSizeUpdate(IRenderObject Control)
|
public void ReportSizeUpdate(IRenderObject Control)
|
||||||
{
|
{
|
||||||
if (BlockDraw) return;
|
if (BlockDraw) return;
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
@ -99,7 +104,7 @@ public class FlowLayout : ParentBase
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y, Controls[i].Location.Z);
|
Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,30 +114,18 @@ public class FlowLayout : ParentBase
|
|||||||
private Task ControlsOnControlRemoved()
|
private Task ControlsOnControlRemoved()
|
||||||
{
|
{
|
||||||
if (Controls.Length < 1) return Task.CompletedTask;
|
if (Controls.Length < 1) return Task.CompletedTask;
|
||||||
if (Controls[0].Location.Y > 0) Controls[0].Location = new(0);
|
if (Controls[0].Location.Y > 0) Controls[0].Location = new(0, 0);
|
||||||
for (int i = 1; i < Controls.Length; i++)
|
for (int i = 1; i < Controls.Length; i++)
|
||||||
{
|
{
|
||||||
Controls[i].Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y, Controls[i].Location.Z);
|
Controls[i].Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ControlsOnControlAdded(int index, IRenderObject arg)
|
private Task ControlsOnControlAdded(IRenderObject arg)
|
||||||
{
|
{
|
||||||
if (Controls.Length > 0)
|
if (Controls.Length > 0) arg.Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y);
|
||||||
{
|
else arg.Location = new(0, 0);
|
||||||
if (index < Controls.Length)
|
|
||||||
{
|
|
||||||
arg.Location = Controls[index].Location;
|
|
||||||
Controls[index].Location = new(arg.Location.X, arg.Location.Y + arg.Size.Y, arg.Location.Z);
|
|
||||||
for (int i = index + 1; i < Controls.Length; i++)
|
|
||||||
{
|
|
||||||
Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y, arg.Location.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else arg.Location = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y, arg.Location.Z);
|
|
||||||
}
|
|
||||||
else arg.Location = new(0);
|
|
||||||
if (arg is IParent par2)
|
if (arg is IParent par2)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < par2.Controls.Length; i++)
|
for (int i = 0; i < par2.Controls.Length; i++)
|
||||||
@ -159,20 +152,71 @@ public class FlowLayout : ParentBase
|
|||||||
int sy = (bottom ? Size.Y - par.Controls[i].Distance.Y - ly : par.Controls[i].Size.Y);
|
int sy = (bottom ? Size.Y - par.Controls[i].Distance.Y - ly : par.Controls[i].Size.Y);
|
||||||
int sx = (right ? Size.X - par.Controls[i].Distance.X - lx : par.Controls[i].Size.X);
|
int sx = (right ? Size.X - par.Controls[i].Distance.X - lx : par.Controls[i].Size.X);
|
||||||
par.Controls[i].Size = new(sx, sy);
|
par.Controls[i].Size = new(sx, sy);
|
||||||
par.Controls[i].Location = new(lx, ly, par.Controls[i].Location.Z);
|
par.Controls[i].Location = new(lx, ly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top;
|
arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Vector2i Size
|
private Task _bounds_Clicked(IRenderObject arg)
|
||||||
{
|
{
|
||||||
get => base.Size;
|
if (Clicked is not null) _ = Clicked.Invoke(arg);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
private Task BoundsOnMouseLeave(IRenderObject arg)
|
||||||
|
{
|
||||||
|
inside = false;
|
||||||
|
if (MouseLeave is not null) _ = MouseLeave.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse
|
||||||
|
{
|
||||||
|
get => _bounds.HoverMouse;
|
||||||
|
set => _bounds.HoverMouse = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool inside = false;
|
||||||
|
private Task BoundsOnMouseEnter(IRenderObject arg)
|
||||||
|
{
|
||||||
|
inside = true;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControlList Controls { get; } = new();
|
||||||
|
public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; }
|
||||||
|
public Color4 BackgroundColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; }
|
||||||
|
public bool Visible
|
||||||
|
{
|
||||||
|
get => _bounds.Visible;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
base.Size = value;
|
_bounds.Visible = value;
|
||||||
|
if (!value)
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
Controls[i].Visible = value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
if (Controls[i].Location.Y > Size.Y || Controls[i].Location.Y + Controls[i].Size.Y < 0)
|
||||||
|
Controls[i].Visible = false;
|
||||||
|
else
|
||||||
|
Controls[i].Visible = true;
|
||||||
|
}
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Vector2i Size
|
||||||
|
{
|
||||||
|
get => _bounds.Size;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
_bounds.Size = value;
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
{
|
{
|
||||||
Controls[i].Size = new(value.X, Controls[i].Size.Y);
|
Controls[i].Size = new(value.X, Controls[i].Size.Y);
|
||||||
@ -183,23 +227,92 @@ public class FlowLayout : ParentBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public Vector2i Location
|
||||||
|
{
|
||||||
|
get => _bounds.Location;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
_bounds.Location = value;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Location = Controls[i].Location;
|
||||||
|
}
|
||||||
|
ParentResize(new());
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
|
||||||
|
|
||||||
|
public Vector2i Position => Location;
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
|
||||||
|
public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
public event Action<MouseButtonEventArgs> MouseDown;
|
||||||
|
public event Action<KeyboardKeyEventArgs> KeyDown;
|
||||||
|
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 IParent? Parent { get; private set; }
|
||||||
|
public Window? Window { get; private set; }
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
|
||||||
public Vector2 MousePosition => Window!.MousePosition;
|
public Vector2 MousePosition => Window!.MousePosition;
|
||||||
|
|
||||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
{
|
{
|
||||||
base.LoadToParent(Parent,Window);
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
|
BlockDraw = true;
|
||||||
|
Loaded = true;
|
||||||
|
_bounds.LoadToParent(Parent, Window);
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].LoadToParent(this, Window);
|
||||||
|
}
|
||||||
|
BlockDraw = false;
|
||||||
Window.MouseWheel += WindowOnMouseWheel;
|
Window.MouseWheel += WindowOnMouseWheel;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool BlockDraw { get; set; } = false;
|
||||||
Timer t;
|
Timer t;
|
||||||
private Queue<Action> scrols = new();
|
private Queue<Action> scrols = new();
|
||||||
private int dist = 0;
|
private int dist = 0;
|
||||||
|
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
|
||||||
|
|
||||||
|
public void TryDraw()
|
||||||
|
{
|
||||||
|
if (!BlockDraw) Parent!.TryDraw();
|
||||||
|
}
|
||||||
private void WindowOnMouseWheel(MouseWheelEventArgs obj)
|
private void WindowOnMouseWheel(MouseWheelEventArgs obj)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!MouseInside) return;
|
if (!inside) return;
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
dist += (int)obj.OffsetY;
|
dist += (int)obj.OffsetY;
|
||||||
if (scrols.Any())
|
if (scrols.Any())
|
||||||
@ -260,7 +373,7 @@ public class FlowLayout : ParentBase
|
|||||||
if (!lfound)
|
if (!lfound)
|
||||||
{
|
{
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
Controls[i].Location = new(0, found, Controls[i].Location.Z);
|
Controls[i].Location = new(0, found);
|
||||||
found += Controls[i].Size.Y;
|
found += Controls[i].Size.Y;
|
||||||
|
|
||||||
if (Controls[i].Location.Y <= Size.Y) Controls[i].Visible = true;
|
if (Controls[i].Location.Y <= Size.Y) Controls[i].Visible = true;
|
||||||
@ -302,7 +415,7 @@ public class FlowLayout : ParentBase
|
|||||||
{
|
{
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
found -= Controls[i].Size.Y;
|
found -= Controls[i].Size.Y;
|
||||||
Controls[i].Location = new(0, found, Controls[i].Location.Z);
|
Controls[i].Location = new(0, found);
|
||||||
|
|
||||||
if (Controls[i].Location.Y + Controls[i].Size.Y >= 0) Controls[i].Visible = true;
|
if (Controls[i].Location.Y + Controls[i].Size.Y >= 0) Controls[i].Visible = true;
|
||||||
else
|
else
|
||||||
@ -332,4 +445,201 @@ public class FlowLayout : ParentBase
|
|||||||
Console.WriteLine(exception);
|
Console.WriteLine(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool dw;
|
||||||
|
|
||||||
|
public void Draw(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (Loaded)
|
||||||
|
{
|
||||||
|
int nx = x, ny = y, nw = w, nh = h;
|
||||||
|
|
||||||
|
|
||||||
|
if (Location.X > nw)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nx += Location.X;
|
||||||
|
nw -= Location.X;
|
||||||
|
if (Size.X < nw)
|
||||||
|
nw = Size.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Location.Y > nh)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ny += Location.Y;
|
||||||
|
nh -= Location.Y;
|
||||||
|
if (Size.Y < nh)
|
||||||
|
nh = Size.Y;
|
||||||
|
}
|
||||||
|
if (dw) Console.WriteLine("Flowlayout\nLoc: {0}\nSize: {1}\n\nX: {2}\nY: {3}\nW: {4}\nH:{5}\n\nX: {6}\nY: {7}\nW: {8}\nH:{9}",
|
||||||
|
Location,
|
||||||
|
Size,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
nw,
|
||||||
|
nh);
|
||||||
|
if (nw ==0 || nh == 0) return;
|
||||||
|
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
||||||
|
_bounds.Draw(nx,ny,nw,nh);
|
||||||
|
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
||||||
|
|
||||||
|
if (needload.Any())
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
foreach (IRenderObject Control in needload)
|
||||||
|
{
|
||||||
|
Control.LoadToParent(this, Window!);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
if (Controls[i] is not IParent)
|
||||||
|
{
|
||||||
|
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
||||||
|
}
|
||||||
|
Controls[i].Draw(nx, ny, nw, nh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Clean();
|
||||||
|
}
|
||||||
|
_bounds.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ParentResize(ResizeEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Width == 0 && e.Height == 0) return;
|
||||||
|
BlockDraw = true;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
if (!Controls[i].Loaded) continue;
|
||||||
|
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
|
||||||
|
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
|
||||||
|
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
|
||||||
|
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
|
||||||
|
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
|
||||||
|
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
|
||||||
|
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
||||||
|
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
||||||
|
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
||||||
|
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||||
|
Controls[i].Size = new(sx, sy);
|
||||||
|
Controls[i].Location = new(lx, ly);
|
||||||
|
if (Controls[i] is IParent parent)
|
||||||
|
{
|
||||||
|
parent.ParentResize(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Parent!.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Cool Math Things
|
||||||
|
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f)
|
||||||
|
{
|
||||||
|
if (hastexture)
|
||||||
|
{
|
||||||
|
return new float[20] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new float[12] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z,// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 PointToVector(float x, float y, float z = 0.0f)
|
||||||
|
{
|
||||||
|
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float IntToFloat(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? Location.Y : Location.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.Position.Y : tempp.Position.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 1);
|
||||||
|
double Per = Math.Round((double)1 / half, 15);
|
||||||
|
if (p == half) return 0.0f;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p > half) return (float)(((double)(p - half) * Per) * -1);
|
||||||
|
else return (float)(1 - (p * Per));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p > half) return (float)((double)(p - half) * Per);
|
||||||
|
else return (float)((1 - (p * Per)) * -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float FloatToInt(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 15);
|
||||||
|
if (p == 0) return (int)half;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(half * p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(half - (p * half));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(Size - (half * p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(p * half + half);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -171,9 +171,9 @@ public class Label : ILabel
|
|||||||
public float Scale { get; set; } = 1.0f;
|
public float Scale { get; set; } = 1.0f;
|
||||||
public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
||||||
public Vector2i Distance { get; set; }
|
public Vector2i Distance { get; set; }
|
||||||
private Vector3i loc_ = new();
|
private Vector2i loc_ = new();
|
||||||
private int maxy = 0, maxx = 0;
|
private int maxy = 0, maxx = 0;
|
||||||
public Vector3i Location
|
public Vector2i Location
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -298,11 +298,9 @@ public class Label : ILabel
|
|||||||
public void ForceDistanceUpdate(IParent parent)
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public IWindow? Window { get; private set; }
|
public Window? Window { get; private set; }
|
||||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||||
public bool IgnoreHover { get; set; }
|
public void LoadToParent(IParent window, Window win)
|
||||||
public bool AllowHoverFromBehind { get; set; }
|
|
||||||
public void LoadToParent(IParent window, IWindow win)
|
|
||||||
{
|
{
|
||||||
if (Loaded) return;
|
if (Loaded) return;
|
||||||
if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new());
|
if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new());
|
||||||
@ -310,6 +308,7 @@ public class Label : ILabel
|
|||||||
if (Shader is null) Shader = DefaultTextShader[win.Context];
|
if (Shader is null) Shader = DefaultTextShader[win.Context];
|
||||||
Parent = window;
|
Parent = window;
|
||||||
Window = win;
|
Window = win;
|
||||||
|
Window.MouseMove += WindowOnMouseMove;
|
||||||
Window.MouseDown += WindowOnMouseDown;
|
Window.MouseDown += WindowOnMouseDown;
|
||||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||||
@ -368,31 +367,43 @@ public class Label : ILabel
|
|||||||
|
|
||||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||||
{
|
{
|
||||||
if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
if (mouseinside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
if (mouseinside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||||
if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||||
|
|
||||||
private bool mi = false;
|
private bool mouseinside = false;
|
||||||
|
private void WindowOnMouseMove(MouseMoveEventArgs obj)
|
||||||
public bool MouseInside
|
|
||||||
{
|
{
|
||||||
get => mi;
|
if (Visible &&
|
||||||
set
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
|
||||||
{
|
{
|
||||||
if (Window is null) return;
|
if (!mouseinside)
|
||||||
if (Window.HoveringControl == this && value)
|
|
||||||
{
|
{
|
||||||
mi = value;
|
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
{
|
||||||
|
Window!.Cursor = HoverMouse;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
mouseinside = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (Window.HoveringControl != this && !value)
|
|
||||||
{
|
{
|
||||||
mi = value;
|
mouseinside = false;
|
||||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseinside)
|
||||||
|
{
|
||||||
|
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||||
|
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||||
|
mouseinside = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,166 +0,0 @@
|
|||||||
using GraphicsManager.Enums;
|
|
||||||
using GraphicsManager.Objects.Core;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
|
||||||
|
|
||||||
public class ProgressBar : ParentBase
|
|
||||||
{
|
|
||||||
private Rectangle ProgresRct;
|
|
||||||
|
|
||||||
public Color4 ProgressColor
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ProgresRct.BackgroundColor;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ProgresRct.BackgroundColor = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateOnDraw { get; set; }
|
|
||||||
|
|
||||||
public ProgressBar()
|
|
||||||
{
|
|
||||||
ProgresRct = new()
|
|
||||||
{
|
|
||||||
Location = new((int)gap, (int)gap, 0),
|
|
||||||
IgnoreHover = true,
|
|
||||||
BackgroundColor = Color4.Green,
|
|
||||||
Anchor = ObjectAnchor.All
|
|
||||||
};
|
|
||||||
Controls.Add(ProgresRct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProgressBar(Texture Background, Texture Progress)
|
|
||||||
:base(Background)
|
|
||||||
{
|
|
||||||
ProgresRct = new(Progress)
|
|
||||||
{
|
|
||||||
Location = new((int)gap, (int)gap, 0),
|
|
||||||
IgnoreHover = true,
|
|
||||||
BackgroundColor = Color4.Green,
|
|
||||||
TextureDisplay = TextureDisplay.ProgressHorizontalCenter,
|
|
||||||
Anchor = ObjectAnchor.All
|
|
||||||
};
|
|
||||||
TextureDisplay = TextureDisplay.VerticalCenter;
|
|
||||||
Controls.Add(ProgresRct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProgressBar(Texture Background)
|
|
||||||
:base(Background)
|
|
||||||
{
|
|
||||||
ProgresRct = new(Background)
|
|
||||||
{
|
|
||||||
Location = new((int)gap, (int)gap, 0),
|
|
||||||
IgnoreHover = true,
|
|
||||||
BackgroundColor = Color4.Green,
|
|
||||||
TextureDisplay = TextureDisplay.ProgressHorizontalCenter,
|
|
||||||
Anchor = ObjectAnchor.All,
|
|
||||||
};
|
|
||||||
TextureDisplay = TextureDisplay.VerticalCenter;
|
|
||||||
Controls.Add(ProgresRct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Shader InnerShader
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ProgresRct.Shader;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ProgresRct.Shader = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector2i Size
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return base.Size;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
base.Size = value;
|
|
||||||
if (!UpdateOnDraw) UpdateProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector3i Location
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return base.Location;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Vector3i diff = value - base.Location;
|
|
||||||
ProgresRct.Location -= diff;
|
|
||||||
base.Location = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ulong mpv = 100, pv = 0;
|
|
||||||
private uint gap = 5;
|
|
||||||
|
|
||||||
public ulong MaxProgressValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return mpv;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
mpv = value;
|
|
||||||
if (!UpdateOnDraw) UpdateProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ulong ProgressValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value > MaxProgressValue) pv = MaxProgressValue;
|
|
||||||
else pv = value;
|
|
||||||
if (!UpdateOnDraw) UpdateProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint ProgressGap
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return gap;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
gap = value;
|
|
||||||
if (!UpdateOnDraw) UpdateProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
if (UpdateOnDraw) UpdateProgress();
|
|
||||||
base.Draw(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateProgress()
|
|
||||||
{
|
|
||||||
double percent = (double)ProgressValue / MaxProgressValue;
|
|
||||||
long MaxPixels = Size.X - gap - gap;
|
|
||||||
if (ProgresRct.Location.X != gap)
|
|
||||||
{
|
|
||||||
ProgresRct.Location = new((int)gap, (int)gap, 0);
|
|
||||||
ProgresRct.Size = new((int)(MaxPixels * percent), (int)(Size.Y - gap - gap));
|
|
||||||
}
|
|
||||||
else ProgresRct.Size = new((int)(MaxPixels * percent), ProgresRct.Size.Y);
|
|
||||||
}
|
|
||||||
}
|
|
@ -167,9 +167,9 @@ public class RainbowLabel : ILabel
|
|||||||
public float Scale { get; set; } = 1.0f;
|
public float Scale { get; set; } = 1.0f;
|
||||||
public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
public Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
||||||
public Vector2i Distance { get; set; }
|
public Vector2i Distance { get; set; }
|
||||||
private Vector3i loc_ = new();
|
private Vector2i loc_ = new();
|
||||||
private int maxy = 0, maxx = 0;
|
private int maxy = 0, maxx = 0;
|
||||||
public Vector3i Location
|
public Vector2i Location
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -374,9 +374,9 @@ public class RainbowLabel : ILabel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public IWindow? Window { get; private set; }
|
public Window? Window { get; private set; }
|
||||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||||
public void LoadToParent(IParent window, IWindow win)
|
public void LoadToParent(IParent window, Window win)
|
||||||
{
|
{
|
||||||
if (Loaded) return;
|
if (Loaded) return;
|
||||||
if (!Label._characters.ContainsKey(win!.Context)) Label._characters.Add(win!.Context, new());
|
if (!Label._characters.ContainsKey(win!.Context)) Label._characters.Add(win!.Context, new());
|
||||||
@ -384,6 +384,7 @@ public class RainbowLabel : ILabel
|
|||||||
if (Shader is null) Shader = Label.DefaultTextShader[win.Context];
|
if (Shader is null) Shader = Label.DefaultTextShader[win.Context];
|
||||||
Parent = window;
|
Parent = window;
|
||||||
Window = win;
|
Window = win;
|
||||||
|
Window.MouseMove += WindowOnMouseMove;
|
||||||
Window.MouseDown += WindowOnMouseDown;
|
Window.MouseDown += WindowOnMouseDown;
|
||||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||||
@ -442,35 +443,47 @@ public class RainbowLabel : ILabel
|
|||||||
|
|
||||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||||
{
|
{
|
||||||
if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
if (mouseinside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
if (mouseinside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||||
if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||||
|
|
||||||
private bool mi = false;
|
private bool mouseinside = false;
|
||||||
public bool MouseInside
|
private void WindowOnMouseMove(MouseMoveEventArgs obj)
|
||||||
{
|
{
|
||||||
get => mi;
|
if (Visible &&
|
||||||
set
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
|
||||||
{
|
{
|
||||||
if (Window is null) return;
|
if (!mouseinside)
|
||||||
if (Window.HoveringControl == this && value)
|
|
||||||
{
|
{
|
||||||
mi = value;
|
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
{
|
||||||
|
Window!.Cursor = HoverMouse;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
mouseinside = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseinside)
|
||||||
|
{
|
||||||
|
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||||
|
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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>? Clicked;
|
||||||
public event Func<IRenderObject, Task>? WindowLoaded;
|
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||||
public event Func<IRenderObject, Task>? MouseEnter;
|
public event Func<IRenderObject, Task>? MouseEnter;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Diagnostics;
|
using GraphicsManager.Enums;
|
||||||
using GraphicsManager.Enums;
|
|
||||||
using GraphicsManager.Interfaces;
|
using GraphicsManager.Interfaces;
|
||||||
using GraphicsManager.Objects.Core;
|
using GraphicsManager.Objects.Core;
|
||||||
using OpenTK.Graphics.OpenGL4;
|
using OpenTK.Graphics.OpenGL4;
|
||||||
@ -19,56 +18,36 @@ public class Rectangle : ITextureObject
|
|||||||
|
|
||||||
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
||||||
|
|
||||||
public Vector3i GetWindowLocation()
|
|
||||||
{
|
|
||||||
if (!Loaded) return Location;
|
|
||||||
Vector3i loc = Location;
|
|
||||||
IParent? p = Parent;
|
|
||||||
while (p is not null)
|
|
||||||
{
|
|
||||||
loc += p.Position;
|
|
||||||
p = p.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3i GetParentLocation(IParent par)
|
|
||||||
{
|
|
||||||
if (!Loaded) return Location;
|
|
||||||
Vector3i loc = Location;
|
|
||||||
IParent? p = Parent;
|
|
||||||
while (p is not null && p != par)
|
|
||||||
{
|
|
||||||
loc += p.Position;
|
|
||||||
p = p.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Texture> Textures { get; set; } = new();
|
public List<Texture> Textures { get; set; } = new();
|
||||||
public ContextMenu? ContextMenu { get; set; } = null;
|
public ContextMenu? ContextMenu { get; set; } = null;
|
||||||
public event Func<string[], Task>? FilesDroped;
|
public event Func<string[], Task>? FilesDroped;
|
||||||
|
|
||||||
public Rectangle(Texture? texture)
|
public Rectangle(Texture? texture = null)
|
||||||
{
|
{
|
||||||
if (texture is not null) Textures.Add(texture);;
|
if (texture is not null) Textures.Add(texture);;
|
||||||
}
|
if (Points_ is null)
|
||||||
public Rectangle()
|
|
||||||
{
|
{
|
||||||
|
bool tex = (texture is null);
|
||||||
|
Points_ = new float[(tex ? 12 : 20)];
|
||||||
|
if (!tex)
|
||||||
|
{
|
||||||
|
Points[3] = 1.0f;
|
||||||
|
Points[4] = 1.0f;
|
||||||
|
Points[8] = 1.0f;
|
||||||
|
Points[19] = 1.0f;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public virtual void Focus()
|
}
|
||||||
|
public void Focus()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
public virtual void UnFocus()
|
public void UnFocus()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255);
|
public Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255);
|
||||||
|
|
||||||
public Color4 BackgroundColor
|
public Color4 BackgroundColor
|
||||||
{
|
{
|
||||||
@ -81,7 +60,7 @@ public class Rectangle : ITextureObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _Visible = true;
|
private bool _Visible = true;
|
||||||
public virtual bool Visible
|
public bool Visible
|
||||||
{
|
{
|
||||||
get => _Visible;
|
get => _Visible;
|
||||||
set
|
set
|
||||||
@ -92,13 +71,13 @@ public class Rectangle : ITextureObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Action? OnDrawAction;
|
public Action? OnDrawAction;
|
||||||
//public Action? OnDrawExitAction;
|
public Action? OnDrawExitAction;
|
||||||
|
|
||||||
public virtual void Draw(int x, int y, int w, int h)
|
public void Draw(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (Visible && Loaded)
|
if (Visible && Loaded)
|
||||||
{
|
{
|
||||||
if (OnDrawAction is not null) OnDrawAction.Invoke();
|
|
||||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
foreach (Texture tex in Textures)
|
foreach (Texture tex in Textures)
|
||||||
{
|
{
|
||||||
@ -110,11 +89,11 @@ public class Rectangle : ITextureObject
|
|||||||
GL.Uniform4(0, BackgroundColor);
|
GL.Uniform4(0, BackgroundColor);
|
||||||
}
|
}
|
||||||
GL.BindVertexArray(ArrayObject);
|
GL.BindVertexArray(ArrayObject);
|
||||||
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedShort, 0);
|
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedInt, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||||
|
|
||||||
public void ForceDistanceUpdate()
|
public void ForceDistanceUpdate()
|
||||||
{
|
{
|
||||||
@ -127,7 +106,7 @@ public class Rectangle : ITextureObject
|
|||||||
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Clean()
|
public void Clean()
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||||
GL.DeleteBuffer(BufferObject);
|
GL.DeleteBuffer(BufferObject);
|
||||||
@ -135,7 +114,7 @@ public class Rectangle : ITextureObject
|
|||||||
GL.DeleteVertexArray(ArrayObject);
|
GL.DeleteVertexArray(ArrayObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void LoadToParent(IParent Parent, IWindow Window)
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
{
|
{
|
||||||
if (Loaded) return;
|
if (Loaded) return;
|
||||||
this.Parent = Parent;
|
this.Parent = Parent;
|
||||||
@ -145,100 +124,86 @@ public class Rectangle : ITextureObject
|
|||||||
if (!Textures.Any())Shader = DefaultShader[Window.Context];
|
if (!Textures.Any())Shader = DefaultShader[Window.Context];
|
||||||
else Shader = Texture.TextureShader[Window.Context];
|
else Shader = Texture.TextureShader[Window.Context];
|
||||||
}
|
}
|
||||||
|
int pos = Points.Length - 3;
|
||||||
|
if (Textures.Any()) pos -= 2;
|
||||||
|
pos = 4;
|
||||||
|
if (Textures.Any()) pos += 2;
|
||||||
|
|
||||||
BufferObject = GL.GenBuffer();
|
BufferObject = GL.GenBuffer();
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||||
ArrayObject = GL.GenVertexArray();
|
ArrayObject = GL.GenVertexArray();
|
||||||
|
GL.BindVertexArray(ArrayObject);
|
||||||
|
int add = 3;
|
||||||
|
if (Textures.Any()) add = 5;
|
||||||
|
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
|
||||||
if (Textures.Any() && !Shader.ForTexture)
|
if (Textures.Any() && !Shader.ForTexture)
|
||||||
{
|
{
|
||||||
Shader = Texture.TextureShader[Window.Context];
|
Shader = Texture.TextureShader[Window.Context];
|
||||||
}
|
}
|
||||||
|
GL.EnableVertexAttribArray(0);
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||||
|
GL.BufferData(BufferTarget.ArrayBuffer, Points.Length * sizeof(float), Points, Hint);
|
||||||
|
GL.BindVertexArray(ArrayObject);
|
||||||
ElementBufferObject = GL.GenBuffer();
|
ElementBufferObject = GL.GenBuffer();
|
||||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
||||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(ushort), Indexs, Hint);
|
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
Window.MouseDown += Window_MouseDown;
|
Window.MouseDown += Window_MouseDown;
|
||||||
|
Window.MouseMove += WindowOnMouseMove;
|
||||||
Window.FileDrop += WindowOnFileDrop;
|
Window.FileDrop += WindowOnFileDrop;
|
||||||
Location = Location;
|
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);
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TransferOwners(IWindow w, IParent p)
|
|
||||||
{
|
|
||||||
if (Parent is not null)
|
|
||||||
{
|
|
||||||
Parent.Controls._internal.Remove(this);
|
|
||||||
Window = w;
|
|
||||||
Parent = p;
|
|
||||||
}
|
|
||||||
p.Controls.Add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WindowOnFileDrop(FileDropEventArgs obj)
|
private void WindowOnFileDrop(FileDropEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!MouseInside) return;
|
if (!mouseinside) return;
|
||||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(obj.FileNames);
|
if (FilesDroped is not null) _ = FilesDroped.Invoke(obj.FileNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool mi = false;
|
private bool mouseinside = false;
|
||||||
|
private void WindowOnMouseMove(MouseMoveEventArgs e)
|
||||||
public bool MouseInside
|
|
||||||
{
|
{
|
||||||
get => mi;
|
if (Visible &&
|
||||||
set
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
|
||||||
{
|
{
|
||||||
if (Window is null) return;
|
if (!mouseinside)
|
||||||
if (AllowHoverFromBehind)
|
|
||||||
{
|
{
|
||||||
mi = value;
|
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||||
if (value && MouseEnter is not null) MouseEnter.Invoke(this);
|
{
|
||||||
if (!value && MouseLeave is not null) MouseLeave.Invoke(this);
|
Window!.Cursor = HoverMouse;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
mouseinside = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Window.HoveringControl == this && value)
|
mouseinside = false;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseinside)
|
||||||
|
{
|
||||||
|
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||||
|
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IParent? Parent { get; private set; }
|
public IParent? Parent { get; private set; }
|
||||||
public IWindow? Window { get; private set; }
|
public Window? Window { get; private set; }
|
||||||
private bool ahfb = false;
|
|
||||||
|
|
||||||
public bool AllowHoverFromBehind
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ahfb;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ahfb = value;
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
if (MouseInside && Window is not null && Window.HoveringControl != this)
|
|
||||||
{
|
|
||||||
mi = false;
|
|
||||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e)
|
private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
if (MouseInside && e.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
if (mouseinside && e.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||||
if (MouseInside && e.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
if (mouseinside && e.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||||
if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Rectangle()
|
~Rectangle()
|
||||||
@ -252,19 +217,24 @@ public class Rectangle : ITextureObject
|
|||||||
public Shader Shader { get; set; } = null;
|
public Shader Shader { get; set; } = null;
|
||||||
public int ElementBufferObject { get; private set; }
|
public int ElementBufferObject { get; private set; }
|
||||||
public int BufferObject { get; private set; }
|
public int BufferObject { get; private set; }
|
||||||
public bool IgnoreHover { get; set; }
|
|
||||||
public int ArrayObject { get; private set; }
|
public int ArrayObject { get; private set; }
|
||||||
private Vector2i size_ = new();
|
private float[] Points_;
|
||||||
private Vector3i loc_ = new();
|
private Vector2i size_ = new(), loc_ = new();
|
||||||
|
|
||||||
public float[] Points
|
public float[] Points
|
||||||
{
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Points_;
|
||||||
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
Points_ = value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Loaded)
|
if (Loaded)
|
||||||
{
|
{
|
||||||
|
//Distance = new(Parent!.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||||
GL.BindVertexArray(ArrayObject);
|
GL.BindVertexArray(ArrayObject);
|
||||||
int add = 3;
|
int add = 3;
|
||||||
@ -281,7 +251,7 @@ public class Rectangle : ITextureObject
|
|||||||
GL.BufferData(BufferTarget.ArrayBuffer, value.Length * sizeof(float), value, Hint);
|
GL.BufferData(BufferTarget.ArrayBuffer, value.Length * sizeof(float), value, Hint);
|
||||||
GL.BindVertexArray(ArrayObject);
|
GL.BindVertexArray(ArrayObject);
|
||||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
||||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(ushort), Indexs, Hint);
|
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
|
||||||
if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
|
if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,9 +262,12 @@ public class Rectangle : ITextureObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ushort[] Indexs { get; set; } = new ushort[6] { 0, 1, 3, 1, 2, 3 };
|
public uint[] Indexs { get; set; } = new uint[6] { 0, 1, 3, 1, 2, 3 };
|
||||||
public BufferUsageHint Hint { get; set; } = BufferUsageHint.StaticDraw;
|
public BufferUsageHint Hint { get; set; } = BufferUsageHint.StaticDraw;
|
||||||
|
|
||||||
|
|
||||||
public event Func<IRenderObject, Task>? Clicked;
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
|
||||||
public bool Loaded { get; private set; }
|
public bool Loaded { get; private set; }
|
||||||
public event Func<IRenderObject, Task>? WindowLoaded;
|
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||||
public event Func<IRenderObject, Task>? MouseEnter;
|
public event Func<IRenderObject, Task>? MouseEnter;
|
||||||
@ -302,73 +275,7 @@ public class Rectangle : ITextureObject
|
|||||||
public object? Tag { get; set; }
|
public object? Tag { get; set; }
|
||||||
public Vector2i Distance { get; set; }
|
public Vector2i Distance { get; set; }
|
||||||
|
|
||||||
private TextureDisplay td = TextureDisplay.Clamped;
|
public Vector2i Size
|
||||||
|
|
||||||
public TextureDisplay TextureDisplay
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return td;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (Textures.Count == 0) return;
|
|
||||||
TextureDisplay old = td;
|
|
||||||
td = value;
|
|
||||||
switch (old)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case TextureDisplay.Clamped:
|
|
||||||
Points = new float[]
|
|
||||||
{
|
|
||||||
saf.X, laf.Y, 0, Textures[0].MaxText.X, Textures[0].MaxText.Y,
|
|
||||||
saf.X, saf.Y, 0, Textures[0].MaxText.X, 0,
|
|
||||||
laf.X, saf.Y, 0, 0, 0,
|
|
||||||
laf.X, laf.Y, 0, 0, Textures[0].MaxText.Y,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter or TextureDisplay.TextureHorizontalCenter:
|
|
||||||
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
|
|
||||||
float diff = 0;
|
|
||||||
if (Window is not null)
|
|
||||||
{
|
|
||||||
diff = Window.IntToFloat(Size.Y) + 1;
|
|
||||||
if (value == TextureDisplay.TextureHorizontalCenter)
|
|
||||||
{
|
|
||||||
diff = Window.IntToFloat(Textures[0].RawSize!.Value.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Points = new float[]
|
|
||||||
{
|
|
||||||
saf.X, laf.Y, 0, Textures[0].MaxText.X, Textures[0].MaxText.Y,
|
|
||||||
saf.X, saf.Y, 0, Textures[0].MaxText.X, 0,
|
|
||||||
laf.X, saf.Y, 0, 0, 0,
|
|
||||||
laf.X, laf.Y, 0, 0, Textures[0].MaxText.Y,
|
|
||||||
saf.X - diff, laf.Y, 0, Textures[0].MaxText.X-per, Textures[0].MaxText.Y,
|
|
||||||
saf.X - diff, saf.Y, 0, Textures[0].MaxText.X-per, 0,
|
|
||||||
laf.X + diff, saf.Y, 0, per, 0,
|
|
||||||
laf.X + diff, laf.Y, 0, per, Textures[0].MaxText.Y,
|
|
||||||
};
|
|
||||||
Indexs = new ushort[]
|
|
||||||
{
|
|
||||||
0, 1, 4,
|
|
||||||
1, 4, 5,
|
|
||||||
4, 5, 6,
|
|
||||||
4, 6, 7,
|
|
||||||
3, 6, 7,
|
|
||||||
2, 3, 6
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Parent is not null) Parent.TryDraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Vector2i Size
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -379,180 +286,17 @@ public class Rectangle : ITextureObject
|
|||||||
size_ = value;
|
size_ = value;
|
||||||
if (Window is null || Parent is null) return;
|
if (Window is null || Parent is null) return;
|
||||||
Parent.ReportSizeUpdate(this);
|
Parent.ReportSizeUpdate(this);
|
||||||
//float[] temp = Points;
|
float[] temp = Points;
|
||||||
float[] temp = Textures.Count == 0
|
|
||||||
? new float[12]
|
|
||||||
: TextureDisplay switch
|
|
||||||
{
|
|
||||||
TextureDisplay.Clamped => new float[20],
|
|
||||||
TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter
|
|
||||||
or TextureDisplay.Center or TextureDisplay.TextureHorizontalCenter => new float[40],
|
|
||||||
_ => new float[20]
|
|
||||||
};
|
|
||||||
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
|
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
|
||||||
temp[2] = Location.Z;
|
temp[0] = saf.X;
|
||||||
temp[(!Textures.Any() ? 5 : 7)] = Location.Z;
|
temp[(!Textures.Any()? 3 : 5)] = saf.X;
|
||||||
temp[(!Textures.Any() ? 8 : 12)] = Location.Z;
|
|
||||||
temp[(!Textures.Any() ? 11 : 17)] = Location.Z;
|
|
||||||
|
|
||||||
temp[0] = saf.X; // top r
|
|
||||||
temp[1] = laf.Y;
|
|
||||||
temp[(!Textures.Any()? 3 : 5)] = saf.X; // bot r
|
|
||||||
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
|
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
|
||||||
temp[(!Textures.Any() ? 6 : 10)] = laf.X;//bot l
|
|
||||||
temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
|
temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
|
||||||
temp[(!Textures.Any() ? 9 : 15)] = laf.X;//top l
|
|
||||||
temp[(!Textures.Any() ? 10 : 16)] = laf.Y;
|
|
||||||
|
|
||||||
if (Textures.Count > 0)
|
|
||||||
{
|
|
||||||
Vector2i s = value;
|
|
||||||
float diff = Window.IntToFloat(s.Y) + 1;
|
|
||||||
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
|
|
||||||
if (TextureDisplay == TextureDisplay.TextureHorizontalCenter)
|
|
||||||
diff = Window.IntToFloat(Textures[0].RawSize!.Value.Y);
|
|
||||||
switch (TextureDisplay)
|
|
||||||
{
|
|
||||||
case TextureDisplay.Clamped:
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
break;
|
|
||||||
case TextureDisplay.HorizontalCenter:
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X - diff; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = Textures[0].MaxText.X - per;
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X - diff; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = Textures[0].MaxText.X - per;
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
break;
|
|
||||||
case TextureDisplay.ProgressHorizontalCenter:
|
|
||||||
if (s.X > s.Y)
|
|
||||||
{
|
|
||||||
if (s.X > s.Y + s.Y)
|
|
||||||
{
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X - diff; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = Textures[0].MaxText.X - per;
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X - diff; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = 1 - per;
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = temp[3];
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
//start last 33% of texture
|
|
||||||
temp[20] = saf.X; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = temp[3];
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = temp[3];
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//first 33% of texture
|
|
||||||
temp[3] = ((s.X/(float)s.Y)*per);
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = temp[3];
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = temp[3];
|
|
||||||
temp[24] = Textures[0].MaxText.Y;
|
|
||||||
|
|
||||||
temp[25] = saf.X; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = temp[3];
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = saf.X; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = temp[3];
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = saf.X; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = temp[3];
|
|
||||||
temp[39] = Textures[0].MaxText.Y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Points = temp;
|
Points = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Vector3i Location
|
public Vector2i Location
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -562,21 +306,8 @@ public class Rectangle : ITextureObject
|
|||||||
{
|
{
|
||||||
loc_ = value;
|
loc_ = value;
|
||||||
if (Window is null || Parent is null) return;
|
if (Window is null || Parent is null) return;
|
||||||
float[] temp = Textures.Count == 0
|
float[] temp = Points;
|
||||||
? new float[12]
|
|
||||||
: TextureDisplay switch
|
|
||||||
{
|
|
||||||
TextureDisplay.Clamped => new float[20],
|
|
||||||
TextureDisplay.HorizontalCenter or TextureDisplay.ProgressHorizontalCenter
|
|
||||||
or TextureDisplay.Center => new float[40],
|
|
||||||
_ => new float[20]
|
|
||||||
};
|
|
||||||
laf = new Vector2(Parent.IntToFloat(value.X, false), Parent.IntToFloat(value.Y, true));
|
laf = new Vector2(Parent.IntToFloat(value.X, false), Parent.IntToFloat(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;
|
|
||||||
|
|
||||||
temp[(!Textures.Any() ? 6 : 10)] = laf.X;
|
temp[(!Textures.Any() ? 6 : 10)] = laf.X;
|
||||||
temp[(!Textures.Any() ? 9 : 15)] = laf.X;
|
temp[(!Textures.Any() ? 9 : 15)] = laf.X;
|
||||||
temp[1] = laf.Y;
|
temp[1] = laf.Y;
|
||||||
@ -586,153 +317,9 @@ public class Rectangle : ITextureObject
|
|||||||
temp[(!Textures.Any() ? 3 : 5)] = saf.X;
|
temp[(!Textures.Any() ? 3 : 5)] = saf.X;
|
||||||
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
|
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
|
||||||
temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
|
temp[(!Textures.Any() ? 7 : 11)] = saf.Y;
|
||||||
if (Textures.Count > 0)
|
|
||||||
{
|
|
||||||
Vector2i s = Size;
|
|
||||||
float diff = Window.IntToFloat(s.Y) + 1;
|
|
||||||
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
|
|
||||||
switch (TextureDisplay)
|
|
||||||
{
|
|
||||||
case TextureDisplay.Clamped:
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
break;
|
|
||||||
case TextureDisplay.HorizontalCenter:
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X - diff; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = Textures[0].MaxText.X - per;
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X - diff; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = Textures[0].MaxText.X - per;
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
break;
|
|
||||||
case TextureDisplay.ProgressHorizontalCenter:
|
|
||||||
if (s.X > s.Y)
|
|
||||||
{
|
|
||||||
if (s.X > s.Y + s.Y)
|
|
||||||
{
|
|
||||||
temp[3] = Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = Textures[0].MaxText.X;
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X - diff; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = Textures[0].MaxText.X - per;
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X - diff; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = 1 - per;
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp[3] = (0.666666f + (((s.X - s.Y) / (float)s.Y)* per)) * Textures[0].MaxText.X;
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = temp[3];
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
//start last 33% of texture
|
|
||||||
temp[20] = saf.X; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = temp[3];
|
|
||||||
temp[24] = 1;
|
|
||||||
|
|
||||||
temp[25] = saf.X; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = temp[3];
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = laf.X + diff; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = per;
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = laf.X + diff; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = per;
|
|
||||||
temp[39] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//first 33% of texture
|
|
||||||
temp[3] = ((s.X/(float)s.Y)*per);
|
|
||||||
temp[4] = Textures[0].MaxText.Y;
|
|
||||||
temp[8] = temp[3];
|
|
||||||
temp[19] = Textures[0].MaxText.Y;
|
|
||||||
temp[20] = saf.X; // top r
|
|
||||||
temp[21] = laf.Y;
|
|
||||||
temp[22] = 0;
|
|
||||||
temp[23] = temp[3];
|
|
||||||
temp[24] = Textures[0].MaxText.Y;
|
|
||||||
|
|
||||||
temp[25] = saf.X; // bot r
|
|
||||||
temp[26] = saf.Y;
|
|
||||||
temp[27] = 0;
|
|
||||||
temp[28] = temp[3];
|
|
||||||
temp[29] = 0;
|
|
||||||
|
|
||||||
temp[30] = saf.X; // bot l
|
|
||||||
temp[31] = saf.Y;
|
|
||||||
temp[32] = 0;
|
|
||||||
temp[33] = temp[3];
|
|
||||||
temp[34] = 0;
|
|
||||||
|
|
||||||
temp[35] = saf.X; // top l
|
|
||||||
temp[36] = laf.Y;
|
|
||||||
temp[37] = 0;
|
|
||||||
temp[38] = temp[3];
|
|
||||||
temp[39] = Textures[0].MaxText.Y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Points = temp;
|
Points = temp;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 laf = new(), saf = new();
|
private Vector2 laf = new(), saf = new();
|
||||||
|
|
||||||
public Vector2 LocationAsFloat { get { return laf; } }
|
public Vector2 LocationAsFloat { get { return laf; } }
|
||||||
|
160
GraphicsManager/Objects/RoundedButton.cs
Executable file
160
GraphicsManager/Objects/RoundedButton.cs
Executable file
@ -0,0 +1,160 @@
|
|||||||
|
using GraphicsManager.Enums;
|
||||||
|
using GraphicsManager.Interfaces;
|
||||||
|
using GraphicsManager.Objects.Core;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
using OpenTK.Windowing.Common.Input;
|
||||||
|
|
||||||
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
|
public class RoundedButton : IRenderObject
|
||||||
|
{
|
||||||
|
private RoundedRectangle _bounds, _inside;
|
||||||
|
internal Label _label;
|
||||||
|
public RoundedButton(FontFamily family)
|
||||||
|
{
|
||||||
|
_bounds = new RoundedRectangle();
|
||||||
|
_inside = new RoundedRectangle();
|
||||||
|
_label = new Label(family);
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
|
_bounds.Clicked += BoundsOnClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse
|
||||||
|
{
|
||||||
|
get => _bounds.HoverMouse;
|
||||||
|
set => _bounds.HoverMouse = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoundedButton(FontInteraction family)
|
||||||
|
{
|
||||||
|
_bounds = new RoundedRectangle();
|
||||||
|
_inside = new RoundedRectangle();
|
||||||
|
_label = new Label(family);
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
|
_bounds.Clicked += BoundsOnClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BoundsOnClicked(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (Clicked is not null) _ = Clicked.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BoundsOnMouseLeave(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseLeave is not null) _ = MouseLeave.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BoundsOnMouseEnter(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 int Radius { get => _bounds.Radius; set { _bounds.Radius = value; _inside.Radius = value; } }
|
||||||
|
public int Border { get; set; } = 2;
|
||||||
|
public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
|
||||||
|
public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } }
|
||||||
|
public FontInteraction Font { get => _label.Font; }
|
||||||
|
public string Text { get => _label.Text; set => _label.Text = value; }
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
|
||||||
|
public Vector2i Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _bounds.Size;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Size = value;
|
||||||
|
_inside.Size = new(value.X - (Border * 2), value.Y - (Border * 2));
|
||||||
|
_label.Location = new( Location.X + Border + (((value.X - (Border * 2)) / 2) - (_label.Size.X / 2)), Location.Y + Border + (((value.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
_bounds.ForceDistanceUpdate(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i Location {
|
||||||
|
get => _bounds.Location;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Location = value;
|
||||||
|
_inside.Location = new(value.X + Border, value.Y + Border);
|
||||||
|
_label.Location = new( value.X + Border + (((Size.X - (Border * 2)) / 2) - (_label.Size.X / 2)), value.Y + Border + (((Size.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
|
||||||
|
|
||||||
|
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
|
||||||
|
public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value;}
|
||||||
|
public IParent? Parent { get; private set; } = null;
|
||||||
|
public Window? Window { get; private set; } = null;
|
||||||
|
public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; }
|
||||||
|
public Color4 BorderColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; }
|
||||||
|
public Color4 FontColor { get => _label.Color; set => _label.Color = value; }
|
||||||
|
public bool Visible
|
||||||
|
{
|
||||||
|
get => _bounds.Visible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Visible = value;
|
||||||
|
_inside.Visible = value;
|
||||||
|
_label.Visible = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
_bounds.Clean();
|
||||||
|
_inside.Clean();
|
||||||
|
_label.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (!Visible || !Loaded) return;
|
||||||
|
_bounds.Draw(x,y,w,h);
|
||||||
|
_inside.Draw(x,y,w,h);
|
||||||
|
_label.Draw(x,y,w,h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
|
{
|
||||||
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
|
Loaded = true;
|
||||||
|
_bounds.LoadToParent(Parent, Window);
|
||||||
|
_inside.LoadToParent(Parent, Window);
|
||||||
|
_label.LoadToParent(Parent, Window);
|
||||||
|
Location = Location;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
372
GraphicsManager/Objects/RoundedRectangle.cs
Executable file
372
GraphicsManager/Objects/RoundedRectangle.cs
Executable file
@ -0,0 +1,372 @@
|
|||||||
|
using GraphicsManager.Enums;
|
||||||
|
using GraphicsManager.Interfaces;
|
||||||
|
using GraphicsManager.Objects.Core;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||||
|
using OpenTK.Windowing.Common;
|
||||||
|
using OpenTK.Windowing.Common.Input;
|
||||||
|
|
||||||
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
|
public class RoundedRectangle : IRenderObject
|
||||||
|
{
|
||||||
|
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
|
||||||
|
public ContextMenu? ContextMenu { get; set; } = null;
|
||||||
|
private const int sn = 4, r = 5;
|
||||||
|
private int sn_ = sn, r_ = r;
|
||||||
|
|
||||||
|
public RoundedRectangle()
|
||||||
|
{
|
||||||
|
//Points_ = new float[36 + (((sn - 1) * 4) * 3)];
|
||||||
|
}
|
||||||
|
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 Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255);
|
||||||
|
|
||||||
|
public Color4 BackgroundColor
|
||||||
|
{
|
||||||
|
get => _BackgroundColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_BackgroundColor = value;
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int Radius
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return r_;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
r_ = value;
|
||||||
|
Location = Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Smoothness
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return sn_;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
sn_ = value;
|
||||||
|
List<uint> Indexs = this.Indexs.ToList().GetRange(0, 30);
|
||||||
|
uint wall = 5;
|
||||||
|
uint last = 12;
|
||||||
|
for (uint i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (value == 1)
|
||||||
|
{
|
||||||
|
Indexs.Add(i);
|
||||||
|
Indexs.Add(wall);
|
||||||
|
wall++;
|
||||||
|
if (wall == 12) wall = 4;
|
||||||
|
Indexs.Add(wall);
|
||||||
|
wall++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint j = 0; j < value; j++)
|
||||||
|
{
|
||||||
|
Indexs.Add(i);
|
||||||
|
if (j == 0 || j == value - 1)
|
||||||
|
{
|
||||||
|
if (wall == 12) wall = 4;
|
||||||
|
Indexs.Add(wall);
|
||||||
|
wall++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Indexs.Add(last);
|
||||||
|
last++;
|
||||||
|
}
|
||||||
|
Indexs.Add(last);
|
||||||
|
|
||||||
|
}
|
||||||
|
last++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Indexs = Indexs.ToArray();
|
||||||
|
Location = Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _Visible = true;
|
||||||
|
public bool Visible
|
||||||
|
{
|
||||||
|
get => _Visible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_Visible = value;
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (Visible && Loaded)
|
||||||
|
{
|
||||||
|
GL.Enable(EnableCap.Multisample);
|
||||||
|
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
|
||||||
|
GL.Hint(HintTarget.PolygonSmoothHint, HintMode.Nicest);
|
||||||
|
Shader.Use();
|
||||||
|
GL.Uniform4(0, BackgroundColor);
|
||||||
|
GL.BindVertexArray(ArrayObject);
|
||||||
|
|
||||||
|
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedInt, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||||
|
GL.DeleteBuffer(BufferObject);
|
||||||
|
GL.DeleteBuffer(ElementBufferObject);
|
||||||
|
GL.DeleteVertexArray(ArrayObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
|
{
|
||||||
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
|
if (Shader is null) Shader = Rectangle.DefaultShader[Window.Context];
|
||||||
|
BufferObject = GL.GenBuffer();
|
||||||
|
ArrayObject = GL.GenVertexArray();
|
||||||
|
ElementBufferObject = GL.GenBuffer();
|
||||||
|
Location = Location;
|
||||||
|
Loaded = true;
|
||||||
|
Window.MouseDown += Window_MouseDown;
|
||||||
|
Window.MouseMove += WindowOnMouseMove;
|
||||||
|
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 bool mouseinside = false;
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
private void WindowOnMouseMove(MouseMoveEventArgs obj)
|
||||||
|
{
|
||||||
|
if (Visible &&
|
||||||
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
|
||||||
|
{
|
||||||
|
if (!mouseinside)
|
||||||
|
{
|
||||||
|
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||||
|
{
|
||||||
|
Window!.Cursor = HoverMouse;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
mouseinside = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseinside)
|
||||||
|
{
|
||||||
|
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||||
|
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IParent? Parent { get; private set; }
|
||||||
|
public Window? Window { get; private set; }
|
||||||
|
|
||||||
|
private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (mouseinside && e.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||||
|
if (mouseinside && e.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||||
|
if (!mouseinside && ContextMenu is not null && Window!.ActiveMenu != ContextMenu) ContextMenu.HideContext(Window!);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RoundedRectangle()
|
||||||
|
{
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||||
|
GL.DeleteBuffer(BufferObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shader Shader { get; set; } = null!;
|
||||||
|
public int ElementBufferObject { get; private set; }
|
||||||
|
public int BufferObject { get; private set; }
|
||||||
|
public int ArrayObject { get; private set; }
|
||||||
|
private Vector2i size_ = new(), loc_ = new();
|
||||||
|
|
||||||
|
private float[] Points
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Loaded)
|
||||||
|
{
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||||
|
GL.BindVertexArray(ArrayObject);
|
||||||
|
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
|
||||||
|
GL.EnableVertexAttribArray(0);
|
||||||
|
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||||
|
GL.BufferData(BufferTarget.ArrayBuffer, value.Length * sizeof(float), value, Hint);
|
||||||
|
GL.BindVertexArray(ArrayObject);
|
||||||
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
||||||
|
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
|
||||||
|
if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (AccessViolationException v)
|
||||||
|
{
|
||||||
|
Console.WriteLine(v.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint[] Indexs { get; set; } = new uint[30 + ((sn * 4) * 3)] { 0, 1, 3, 1, 2, 3, 0, 3, 4, 0, 4, 5, 0, 1, 7, 0, 6, 7, 1, 2, 9, 1, 8, 9, 2, 3, 11, 2, 10, 11,
|
||||||
|
0, 5, 12,
|
||||||
|
0, 12, 13,
|
||||||
|
0, 13, 14,
|
||||||
|
0, 6, 14,
|
||||||
|
|
||||||
|
1, 7, 15,
|
||||||
|
1, 15, 16,
|
||||||
|
1, 16, 17,
|
||||||
|
1, 8, 17,
|
||||||
|
|
||||||
|
2, 9, 18,
|
||||||
|
2, 18, 19,
|
||||||
|
2, 19, 20,
|
||||||
|
2, 10, 20,
|
||||||
|
|
||||||
|
3, 11, 21,
|
||||||
|
3, 21, 22,
|
||||||
|
3, 22, 23,
|
||||||
|
3, 4, 23};
|
||||||
|
public BufferUsageHint Hint { get; set; } = BufferUsageHint.StaticDraw;
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
public Vector2i Distance { get; set; }
|
||||||
|
|
||||||
|
public Vector2i Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
size_ = value;
|
||||||
|
if (Window is null || Parent is null) return;
|
||||||
|
Parent.ReportSizeUpdate(this);
|
||||||
|
Location = Location;
|
||||||
|
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
|
||||||
|
//ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i Location
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return loc_;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
loc_ = value;
|
||||||
|
if (Window is null || Parent is null) return;
|
||||||
|
List<float> temp;
|
||||||
|
saf = new Vector2(Parent.IntToFloat(Size.X + loc_.X, false), Parent.IntToFloat(Size.Y + loc_.Y, true));
|
||||||
|
Vector3 _0 = Parent.PointToVector(value.X + Size.X - Radius, value.Y + Radius, 0);
|
||||||
|
Vector3 _1 = Parent.PointToVector(value.X + Size.X - Radius, value.Y + Size.Y - Radius, 0);
|
||||||
|
Vector3 _2 = Parent.PointToVector(value.X + Radius, value.Y + Size.Y - Radius, 0);
|
||||||
|
Vector3 _3 = Parent.PointToVector(value.X + Radius, value.Y + Radius, 0);
|
||||||
|
Vector3 _4 = Parent.PointToVector(value.X + Radius, value.Y, 0);
|
||||||
|
Vector3 _5 = Parent.PointToVector(value.X + Size.X - Radius, value.Y, 0);
|
||||||
|
Vector3 _6 = Parent.PointToVector(value.X + Size.X, value.Y + Radius, 0);
|
||||||
|
Vector3 _7 = Parent.PointToVector(value.X + Size.X, value.Y + Size.Y - Radius, 0);
|
||||||
|
Vector3 _8 = Parent.PointToVector(value.X + Size.X - Radius, value.Y + Size.Y, 0);
|
||||||
|
Vector3 _9 = Parent.PointToVector(value.X + Radius, value.Y + Size.Y, 0);
|
||||||
|
Vector3 _10 = Parent.PointToVector(value.X, value.Y + Size.Y - Radius, 0);
|
||||||
|
Vector3 _11 = Parent.PointToVector(value.X, value.Y + Radius, 0);
|
||||||
|
float[] ff = new float[]
|
||||||
|
{
|
||||||
|
value.X + Size.X - Radius,
|
||||||
|
value.X + Size.X - Radius,
|
||||||
|
value.X + Radius,
|
||||||
|
value.X + Radius,
|
||||||
|
value.Y + Radius,
|
||||||
|
value.Y + Size.Y - Radius,
|
||||||
|
value.Y + Size.Y - Radius,
|
||||||
|
value.Y + Radius
|
||||||
|
};
|
||||||
|
float rotation = 90f / (Smoothness);
|
||||||
|
temp = new()
|
||||||
|
{
|
||||||
|
_0.X, _0.Y, _0.Z, _1.X, _1.Y, _1.Z, _2.X, _2.Y, _2.Z, _3.X, _3.Y, _3.Z, _4.X, _4.Y, _4.Z, _5.X, _5.Y, _5.Z, _6.X, _6.Y, _6.Z, _7.X, _7.Y, _7.Z, _8.X, _8.Y, _8.Z, _9.X, _9.Y, _9.Z, _10.X, _10.Y, _10.Z, _11.X, _11.Y, _11.Z
|
||||||
|
};
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
float start = 90 - (j * 90);
|
||||||
|
for (int i = 0; i < Smoothness - 1; i++)
|
||||||
|
{
|
||||||
|
float degpre = (rotation * (i + 1));
|
||||||
|
float deg = start - degpre;
|
||||||
|
float y = (float)(ff[j + 4] - (Math.Sin(MathHelper.DegreesToRadians(deg)) * Radius));
|
||||||
|
float x = (float)(Math.Cos(MathHelper.DegreesToRadians(deg)) * Radius) + ff[j];
|
||||||
|
Vector3 tri = Parent.PointToVector(x, y, 0f);
|
||||||
|
temp.Add(tri.X);
|
||||||
|
temp.Add(tri.Y);
|
||||||
|
temp.Add(tri.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ScissorLocation = new((int)Window.FloatToInt(Parent.IntToFloat(value.X)),
|
||||||
|
//(int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true)
|
||||||
|
//);
|
||||||
|
//ScissorLocation = Parent.GetParentRelLocPoint() + value;
|
||||||
|
//ScissorLocation = Parent.GetParentRelLocPoint() + value;// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)),
|
||||||
|
//ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y);
|
||||||
|
//ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));
|
||||||
|
Points = temp.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//public Vector2i ScissorLocation { get; private set; }
|
||||||
|
private Vector2 laf = new(), saf = new();
|
||||||
|
|
||||||
|
public Vector2 LocationAsFloat { get { return laf; } }
|
||||||
|
public Vector2 SizeAsFloat { get { return saf; } }
|
||||||
|
}
|
@ -1,28 +1,39 @@
|
|||||||
using GraphicsManager.Enums;
|
using GraphicsManager.Enums;
|
||||||
using GraphicsManager.Interfaces;
|
using GraphicsManager.Interfaces;
|
||||||
using GraphicsManager.Objects.Core;
|
using GraphicsManager.Objects.Core;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
using OpenTK.Mathematics;
|
using OpenTK.Mathematics;
|
||||||
using OpenTK.Windowing.Common;
|
using OpenTK.Windowing.Common;
|
||||||
using OpenTK.Windowing.Common.Input;
|
using OpenTK.Windowing.Common.Input;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
public class TabControl : ParentBase, IParent
|
public class TabControl : IRenderObject, IParent
|
||||||
{
|
{
|
||||||
private Texture t;
|
public Rectangle _bounds;
|
||||||
public TabControl(Texture tex, FontFamily fam)
|
|
||||||
|
public TabControl(FontFamily fam)
|
||||||
{
|
{
|
||||||
t = tex;
|
|
||||||
TitleFont = FontInteraction.Load(fam);
|
TitleFont = FontInteraction.Load(fam);
|
||||||
|
_bounds = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TabControl(Texture tex, FontInteraction fam)
|
public TabControl(FontInteraction fam)
|
||||||
{
|
{
|
||||||
t = tex;
|
|
||||||
TitleFont = fam;
|
TitleFont = fam;
|
||||||
|
_bounds = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse
|
||||||
|
{
|
||||||
|
get => _bounds.HoverMouse;
|
||||||
|
set => _bounds.HoverMouse = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private ControlList Buttonts = new();
|
private ControlList Buttonts = new();
|
||||||
|
public ControlList Controls { get; } = new();
|
||||||
|
|
||||||
public void AddPage(string Title, UserControl page)
|
public void AddPage(string Title, UserControl page)
|
||||||
{
|
{
|
||||||
@ -34,19 +45,21 @@ public class TabControl : ParentBase, IParent
|
|||||||
locc = Buttonts[loc - 1].Location.X;
|
locc = Buttonts[loc - 1].Location.X;
|
||||||
loccc = Buttonts[loc - 1].Size.X;
|
loccc = Buttonts[loc - 1].Size.X;
|
||||||
}
|
}
|
||||||
Buttonts.Add(tmp = new RoundedButton(t, TitleFont.Family)
|
Buttonts.Add(tmp = new RoundedButton(TitleFont.Family)
|
||||||
{
|
{
|
||||||
Location = new(locc+ loccc + (TabSpace * (int)loc) + Border, Border, Location.Z),
|
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
|
||||||
Text = Title,
|
Text = Title,
|
||||||
Tag = loc,
|
Tag = loc,
|
||||||
|
BorderColor = this.BorderColor,
|
||||||
|
InsideColor = this.InsideColor,
|
||||||
FontColor = this.TextColor
|
FontColor = this.TextColor
|
||||||
});
|
});
|
||||||
|
|
||||||
if (loc == PageIndex) tmp.BackgroundColor = this.SelectedColor;
|
if (loc == PageIndex) tmp.BorderColor = this.SelectedColor;
|
||||||
tmp.Clicked += TmpOnClicked;
|
tmp.Clicked += TmpOnClicked;
|
||||||
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
||||||
page.Anchor = ObjectAnchor.All;
|
page.Anchor = ObjectAnchor.All;
|
||||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace, page.Location.Z);
|
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace);
|
||||||
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
||||||
if (PageIndex != loc) page.Visible = false;
|
if (PageIndex != loc) page.Visible = false;
|
||||||
Controls.Add(page);
|
Controls.Add(page);
|
||||||
@ -62,20 +75,22 @@ public class TabControl : ParentBase, IParent
|
|||||||
locc = Buttonts[loc - 1].Location.X;
|
locc = Buttonts[loc - 1].Location.X;
|
||||||
loccc = Buttonts[loc - 1].Size.X;
|
loccc = Buttonts[loc - 1].Size.X;
|
||||||
}
|
}
|
||||||
Buttonts.Add(tmp = new RoundedButton(t, TitleFont)
|
Buttonts.Add(tmp = new RoundedButton(TitleFont)
|
||||||
{
|
{
|
||||||
Location = new(locc+ loccc + (TabSpace * (int)loc) + Border, Border, Location.Z),
|
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
|
||||||
Text = Title,
|
Text = Title,
|
||||||
Tag = loc,
|
Tag = loc,
|
||||||
|
BorderColor = this.BorderColor,
|
||||||
|
InsideColor = this.InsideColor,
|
||||||
FontColor = this.TextColor,
|
FontColor = this.TextColor,
|
||||||
Anchor = ObjectAnchor.Top | ObjectAnchor.Left
|
Anchor = ObjectAnchor.Top | ObjectAnchor.Left
|
||||||
});
|
});
|
||||||
|
|
||||||
if (loc == PageIndex) tmp.BackgroundColor = this.SelectedColor;
|
if (loc == PageIndex) tmp.BorderColor = this.SelectedColor;
|
||||||
tmp.Clicked += TmpOnClicked;
|
tmp.Clicked += TmpOnClicked;
|
||||||
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
||||||
page.Anchor = ObjectAnchor.All;
|
page.Anchor = ObjectAnchor.All;
|
||||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace, page.Location.Z);
|
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace);
|
||||||
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
||||||
if (PageIndex != loc) page.Visible = false;
|
if (PageIndex != loc) page.Visible = false;
|
||||||
Controls.Add(page);
|
Controls.Add(page);
|
||||||
@ -87,22 +102,36 @@ public class TabControl : ParentBase, IParent
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
_bounds.ForceDistanceUpdate(parent);
|
||||||
|
}
|
||||||
|
|
||||||
public Color4 TextColor { get; set; } = new(255, 255, 255, 255);
|
public Color4 TextColor { get; set; } = new(255, 255, 255, 255);
|
||||||
public Color4 BorderColor { get; set; } = new(40, 40, 40, 255);
|
public Color4 BorderColor { get; set; } = new(40, 40, 40, 255);
|
||||||
public Color4 SelectedColor { get; set; } = Color4.DarkCyan;
|
public Color4 SelectedColor { get; set; } = Color4.DarkCyan;
|
||||||
public Color4 InsideColor { get; set; } = new(0, 0, 0, 255);
|
public Color4 InsideColor { get; set; } = new(0, 0, 0, 255);
|
||||||
|
public Color4 BackgroundColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; }
|
||||||
public int TextBorder { get; set; } = 5;
|
public int TextBorder { get; set; } = 5;
|
||||||
public int TabSpace { get; set; } = 5;
|
public int TabSpace { get; set; } = 5;
|
||||||
public int Border { get; set; } = 10;
|
public int Border { get; set; } = 10;
|
||||||
|
public IParent? Parent { get; private set; } = null;
|
||||||
public FontInteraction TitleFont { get; set; } = null!;
|
public FontInteraction TitleFont { get; set; } = null!;
|
||||||
|
public Window? Window { get; private set; } = null;
|
||||||
|
|
||||||
public override bool Visible
|
public bool Visible
|
||||||
{
|
{
|
||||||
get => base.Visible;
|
get => _bounds.Visible;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
base.Visible = value;
|
_bounds.Visible = value;
|
||||||
for (int i = 0; i < Buttonts.Length; i++)
|
for (int i = 0; i < Buttonts.Length; i++)
|
||||||
Buttonts[i].Visible = value;
|
Buttonts[i].Visible = value;
|
||||||
if (value) PageIndex = PageIndex;
|
if (value) PageIndex = PageIndex;
|
||||||
@ -115,6 +144,15 @@ public class TabControl : ParentBase, IParent
|
|||||||
BlockDraw = false;
|
BlockDraw = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; }
|
||||||
|
public object? Tag { get => _bounds.Tag; set => _bounds.Tag = value; }
|
||||||
|
public Vector2i Size { get => _bounds.Size; set => _bounds.Size = value; }
|
||||||
|
public Vector2i Location { get => _bounds.Location; set => _bounds.Location = value; }
|
||||||
|
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
|
||||||
|
public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
|
||||||
|
//public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
|
||||||
|
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
|
||||||
private uint pgi = 0;
|
private uint pgi = 0;
|
||||||
public uint PageIndex
|
public uint PageIndex
|
||||||
{
|
{
|
||||||
@ -126,11 +164,11 @@ public class TabControl : ParentBase, IParent
|
|||||||
{
|
{
|
||||||
pgi = value;
|
pgi = value;
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
if (base.Visible)
|
if (_bounds.Visible)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Buttonts.Length; i++)
|
for (int i = 0; i < Buttonts.Length; i++)
|
||||||
((RoundedButton)Buttonts[i]).BackgroundColor = BorderColor;
|
((RoundedButton)Buttonts[i]).BorderColor = BorderColor;
|
||||||
((RoundedButton)Buttonts[value]).BackgroundColor = SelectedColor;
|
((RoundedButton)Buttonts[value]).BorderColor = SelectedColor;
|
||||||
for (int i = 0; i < Controls.Length; i++)
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
Controls[i].Visible = false;
|
Controls[i].Visible = false;
|
||||||
Controls[value].Visible = true;
|
Controls[value].Visible = true;
|
||||||
@ -140,8 +178,28 @@ public class TabControl : ParentBase, IParent
|
|||||||
BlockDraw = false;
|
BlockDraw = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
|
||||||
public override void ParentResize(ResizeEventArgs e)
|
}
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public Vector2i Position => Location;
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
|
||||||
|
public void TryDraw()
|
||||||
|
{
|
||||||
|
if (!BlockDraw) Parent!.TryDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReportSizeUpdate(IRenderObject Control)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ParentResize(ResizeEventArgs e)
|
||||||
{
|
{
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
if (e.Width == 0 && e.Height == 0) return;
|
if (e.Width == 0 && e.Height == 0) return;
|
||||||
@ -158,7 +216,7 @@ public class TabControl : ParentBase, IParent
|
|||||||
int sy = (bottom ? Size.Y - Controls[PageIndex].Distance.Y - ly : Controls[PageIndex].Size.Y);
|
int sy = (bottom ? Size.Y - Controls[PageIndex].Distance.Y - ly : Controls[PageIndex].Size.Y);
|
||||||
int sx = (right ? Size.X - Controls[PageIndex].Distance.X - lx : Controls[PageIndex].Size.X);
|
int sx = (right ? Size.X - Controls[PageIndex].Distance.X - lx : Controls[PageIndex].Size.X);
|
||||||
Controls[PageIndex].Size = new(sx, sy);
|
Controls[PageIndex].Size = new(sx, sy);
|
||||||
Controls[PageIndex].Location = new(lx, ly, Controls[PageIndex].Location.Z);
|
Controls[PageIndex].Location = new(lx, ly);
|
||||||
if (Controls[PageIndex] is IParent parent)
|
if (Controls[PageIndex] is IParent parent)
|
||||||
{
|
{
|
||||||
parent.ParentResize(e);
|
parent.ParentResize(e);
|
||||||
@ -177,7 +235,7 @@ public class TabControl : ParentBase, IParent
|
|||||||
sy = (bottom ? Size.Y - Buttonts[i].Distance.Y - ly : Buttonts[i].Size.Y);
|
sy = (bottom ? Size.Y - Buttonts[i].Distance.Y - ly : Buttonts[i].Size.Y);
|
||||||
sx = (right ? Size.X - Buttonts[i].Distance.X - lx : Buttonts[i].Size.X);
|
sx = (right ? Size.X - Buttonts[i].Distance.X - lx : Buttonts[i].Size.X);
|
||||||
Buttonts[i].Size = new(sx, sy);
|
Buttonts[i].Size = new(sx, sy);
|
||||||
Buttonts[i].Location = new(lx, ly, Buttonts[i].Location.Z);
|
Buttonts[i].Location = new(lx, ly);
|
||||||
if (Buttonts[i] is IParent parent2)
|
if (Buttonts[i] is IParent parent2)
|
||||||
{
|
{
|
||||||
parent2.ParentResize(e);
|
parent2.ParentResize(e);
|
||||||
@ -187,39 +245,154 @@ public class TabControl : ParentBase, IParent
|
|||||||
BlockDraw = false;
|
BlockDraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
public bool BlockDraw { get; set; } = false;
|
||||||
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
{
|
{
|
||||||
if (Loaded) return;
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
BlockDraw = true;
|
BlockDraw = true;
|
||||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
base.LoadToParent(Parent, Window);
|
Loaded = true;
|
||||||
|
_bounds.LoadToParent(Parent, Window);
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].LoadToParent(this, Window);
|
||||||
|
}
|
||||||
for (int i = 0; i < Buttonts.Length; i++)
|
for (int i = 0; i < Buttonts.Length; i++)
|
||||||
{
|
{
|
||||||
Buttonts[i].LoadToParent(this, Window);
|
Buttonts[i].LoadToParent(this, Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDraw = false;
|
BlockDraw = false;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(int x, int y, int w, int h)
|
public void Draw(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (Loaded && Visible)
|
if (Loaded && Visible)
|
||||||
{
|
{
|
||||||
base.Draw(x,y,w,h);
|
_bounds.Draw(x,y,w,h);
|
||||||
if (!(Controls.Length >= (PageIndex))) return;
|
if (!(Controls.Length >= (PageIndex))) return;
|
||||||
if (!Controls[PageIndex].Loaded) return;
|
if (!Controls[PageIndex].Loaded) return;
|
||||||
|
// GL.Scissor(Controls[PageIndex].ScissorLocation.X, Controls[PageIndex].ScissorLocation.Y, Controls[PageIndex].Size.X, Controls[PageIndex].Size.Y);
|
||||||
Controls[PageIndex].Draw(x,y,w,h);
|
Controls[PageIndex].Draw(x,y,w,h);
|
||||||
|
//GL.Scissor(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
|
||||||
for (int i = 0; i < Buttonts.Length; i++)
|
for (int i = 0; i < Buttonts.Length; i++)
|
||||||
Buttonts[i].Draw(x,y,w,h);
|
Buttonts[i].Draw(x,y,w,h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clean()
|
public void Clean()
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Clean();
|
||||||
|
}
|
||||||
for (int i = 0; i < Buttonts.Length; i++)
|
for (int i = 0; i < Buttonts.Length; i++)
|
||||||
{
|
{
|
||||||
Buttonts[i].Clean();
|
Buttonts[i].Clean();
|
||||||
}
|
}
|
||||||
base.Clean();
|
_bounds.Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
public event Func<IRenderObject, Task>? MouseLeave;
|
||||||
|
public event Func<IRenderObject, Task>? MouseEnter;
|
||||||
|
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||||
|
|
||||||
|
#region Cool Math Things
|
||||||
|
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f)
|
||||||
|
{
|
||||||
|
if (hastexture)
|
||||||
|
{
|
||||||
|
return new float[20] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new float[12] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z,// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 PointToVector(float x, float y, float z = 0.0f)
|
||||||
|
{
|
||||||
|
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float IntToFloat(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? Location.Y : Location.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.Position.Y : tempp.Position.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 1);
|
||||||
|
double Per = Math.Round((double)1 / half, 15);
|
||||||
|
if (p == half) return 0.0f;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p > half) return (float)(((double)(p - half) * Per) * -1);
|
||||||
|
else return (float)(1 - (p * Per));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p > half) return (float)((double)(p - half) * Per);
|
||||||
|
else return (float)((1 - (p * Per)) * -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float FloatToInt(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 15);
|
||||||
|
if (p == 0) return (int)half;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(half * p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(half - (p * half));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(Size - (half * p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(p * half + half);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
335
GraphicsManager/Objects/Textbox.cs
Executable file
335
GraphicsManager/Objects/Textbox.cs
Executable file
@ -0,0 +1,335 @@
|
|||||||
|
using GraphicsManager.Enums;
|
||||||
|
using GraphicsManager.Interfaces;
|
||||||
|
using GraphicsManager.Objects.Core;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
using OpenTK.Windowing.Common;
|
||||||
|
using OpenTK.Windowing.Common.Input;
|
||||||
|
using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||||
|
|
||||||
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
|
public class Textbox : IRenderObject
|
||||||
|
{
|
||||||
|
private RoundedRectangle _bounds, _inside;
|
||||||
|
private Label _label;
|
||||||
|
private Label _watermark;
|
||||||
|
public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
|
||||||
|
|
||||||
|
public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
|
||||||
|
public Textbox(FontFamily LabelFam, FontFamily WaterFam)
|
||||||
|
{
|
||||||
|
_bounds = new RoundedRectangle();
|
||||||
|
_inside = new RoundedRectangle();
|
||||||
|
_label = new Label(LabelFam);
|
||||||
|
_watermark = new(WaterFam)
|
||||||
|
{
|
||||||
|
Color = new(128, 128, 128, 255)
|
||||||
|
};
|
||||||
|
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse
|
||||||
|
{
|
||||||
|
get => _bounds.HoverMouse;
|
||||||
|
set => _bounds.HoverMouse = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Textbox(FontInteraction LabelFam, FontInteraction WaterFam)
|
||||||
|
{
|
||||||
|
_bounds = new RoundedRectangle();
|
||||||
|
_inside = new RoundedRectangle();
|
||||||
|
_label = new Label(LabelFam);
|
||||||
|
_watermark = new(WaterFam)
|
||||||
|
{
|
||||||
|
Color = new(128, 128, 128, 255)
|
||||||
|
};
|
||||||
|
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int currentc = 0;
|
||||||
|
|
||||||
|
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||||
|
public event Func<IRenderObject, Task>? MouseEnter;
|
||||||
|
public event Func<IRenderObject, Task>? MouseLeave;
|
||||||
|
public object? Tag { get; set; } = null;
|
||||||
|
public int Radius { get => _bounds.Radius; set { _bounds.Radius = value; _inside.Radius = value; } }
|
||||||
|
public int Border { get; set; } = 2;
|
||||||
|
public int Smoothness { get => _bounds.Smoothness; set { _bounds.Smoothness = value; _inside.Smoothness = value; } }
|
||||||
|
public ObjectAnchor Anchor { get => _bounds.Anchor; set { _bounds.Anchor = value; _inside.Anchor = value; _label.Anchor = value; } }
|
||||||
|
public FontInteraction Font { get => _label.Font; }
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => _label.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int oldh = _label.TrueHeight;
|
||||||
|
_label.Text = value;
|
||||||
|
if (!string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
bool f = false;
|
||||||
|
if (!_label.Visible)
|
||||||
|
{
|
||||||
|
f = true;
|
||||||
|
_label.Visible = true;
|
||||||
|
_label.Location = TextLocation switch
|
||||||
|
{
|
||||||
|
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||||
|
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
|
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||||
|
TextLocation.TopLeft or _ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||||
|
};
|
||||||
|
_watermark.Location = _label.Location;
|
||||||
|
}
|
||||||
|
if (_watermark.Visible) _watermark.Visible = false;
|
||||||
|
if (!f && TextLocation == TextLocation.TrueCenterLeft && oldh != _label.TrueHeight)
|
||||||
|
{
|
||||||
|
_label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight));
|
||||||
|
_watermark.Location = _label.Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_label.Visible) _label.Visible = false;
|
||||||
|
if (!_watermark.Visible)
|
||||||
|
{
|
||||||
|
_watermark.Visible = true;
|
||||||
|
_watermark.Location = TextLocation switch
|
||||||
|
{
|
||||||
|
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
|
||||||
|
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
|
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2)),
|
||||||
|
TextLocation.TopLeft or _ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||||
|
};
|
||||||
|
_label.Location = _label.Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
_bounds.ForceDistanceUpdate(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontInteraction WatermarkFont { get => _watermark!.Font!; }
|
||||||
|
public string WatermarkText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _watermark.Text;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_watermark.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public char? PasswordChar { get => _label.PasswordChar; set => _label.PasswordChar = value; }
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
public Vector2i Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _bounds.Size;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Size = value;
|
||||||
|
_inside.Size = new(value.X - (Border * 2), value.Y - (Border * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Vector2i Location {
|
||||||
|
get => _bounds.Location;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Location = value;
|
||||||
|
if (_watermark.Visible && !string.IsNullOrEmpty(_watermark.Text))
|
||||||
|
{
|
||||||
|
_watermark.Location = TextLocation switch
|
||||||
|
{
|
||||||
|
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
|
||||||
|
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
|
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2)),
|
||||||
|
TextLocation.TopLeft or _ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||||
|
};
|
||||||
|
_label.Location = _watermark.Location;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_label.Location = TextLocation switch
|
||||||
|
{
|
||||||
|
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||||
|
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
|
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||||
|
TextLocation.TopLeft or _ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||||
|
};
|
||||||
|
_watermark.Location = _label.Location;
|
||||||
|
}
|
||||||
|
_inside.Location = new(value.X + Border, value.Y + Border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
|
||||||
|
public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
|
||||||
|
public IParent? Parent { get; private set; } = null;
|
||||||
|
public Window? Window { get; private set; } = null;
|
||||||
|
public Color4 InsideColor { get => _inside.BackgroundColor; set => _inside.BackgroundColor = value; }
|
||||||
|
public Color4 BorderColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; }
|
||||||
|
public Color4 TextColor { get => _label.Color; set => _label.Color = value; }
|
||||||
|
public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; }
|
||||||
|
|
||||||
|
public bool Visible
|
||||||
|
{
|
||||||
|
get => _bounds.Visible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.Visible = value;
|
||||||
|
_inside.Visible = value;
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_label.Text))
|
||||||
|
{
|
||||||
|
_label.Visible = true;
|
||||||
|
_watermark.Visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_label.Visible = false;
|
||||||
|
_watermark.Visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_label.Visible = value;
|
||||||
|
_watermark.Visible = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
private Task BoundsOnMouseLeave(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseLeave is not null) _ = MouseLeave.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BoundsOnMouseEnter(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
_bounds.Clean();
|
||||||
|
_inside.Clean();
|
||||||
|
_label.Clean();
|
||||||
|
_watermark.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector2i? l = null, s = null;
|
||||||
|
//public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
|
||||||
|
|
||||||
|
public void Draw(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (!Visible || !Loaded) return;
|
||||||
|
_bounds.Draw(x,y,w,h);
|
||||||
|
_inside.Draw(x,y,w,h);
|
||||||
|
if (l is null || s is null)
|
||||||
|
{
|
||||||
|
l = new((int)Window.FloatToInt(Parent.IntToFloat(_inside.Location.X)),
|
||||||
|
(int)Window.FloatToInt(Parent.IntToFloat(_inside.Location.Y, true), true));
|
||||||
|
s = new(_inside.Size.X - _label.Location.X + Location.X,
|
||||||
|
_inside.Size.Y);
|
||||||
|
l = new(l.Value.X, 0);
|
||||||
|
s = new(s.Value.X, Window.Size.Y);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(x,y,w,h);
|
||||||
|
else _watermark.Draw(x,y,w,h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
|
{
|
||||||
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
|
this.Window.MouseDown += Window_MouseDown;
|
||||||
|
this.Window.KeyDown += Window_KeyDown;
|
||||||
|
this.Window.TextInput += WindowOnTextInput;
|
||||||
|
Loaded = true;
|
||||||
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
|
_bounds.LoadToParent(Parent, Window);
|
||||||
|
_inside.LoadToParent(Parent, Window);
|
||||||
|
_label.LoadToParent(Parent, Window);
|
||||||
|
_watermark.LoadToParent(Parent, Window);
|
||||||
|
Location = Location;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowOnTextInput(TextInputEventArgs obj)
|
||||||
|
{
|
||||||
|
if (!use) return;
|
||||||
|
Text += obj.AsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool use = false;
|
||||||
|
public event Func<KeyboardKeyEventArgs, Task>? KeyPress;
|
||||||
|
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
use = false;
|
||||||
|
if (Window is not null && Window.focused == this)
|
||||||
|
Window.focused = null;
|
||||||
|
}
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
if (Window is not null)
|
||||||
|
{
|
||||||
|
if (Window.focused is not null)
|
||||||
|
{
|
||||||
|
Window.focused.UnFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Window.focused = this;
|
||||||
|
use = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void Window_KeyDown(OpenTK.Windowing.Common.KeyboardKeyEventArgs obj)
|
||||||
|
{
|
||||||
|
if (!use) return;
|
||||||
|
if (obj.Key == Keys.CapsLock || obj.Key == Keys.Menu || obj.Key == Keys.LeftSuper || obj.Key == Keys.RightSuper || obj.Key == Keys.End || obj.Key == Keys.Home || obj.Key == Keys.PageDown || obj.Key == Keys.PageUp || obj.Key == Keys.Insert || obj.Key == Keys.Up || obj.Key == Keys.Down || obj.Key == Keys.Left || obj.Key == Keys.Right) return;
|
||||||
|
if (obj.Key == Keys.Backspace || obj.Key == Keys.Delete)
|
||||||
|
{
|
||||||
|
if (!(Text.Length > 0)) return;
|
||||||
|
Text = Text.Remove(Text.Length - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Key == Keys.V && obj.Control && Window is not null) Text += Window.ClipboardString;
|
||||||
|
if (KeyPress is not null) _ = KeyPress.Invoke(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Window_MouseDown(OpenTK.Windowing.Common.MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (Visible &&
|
||||||
|
e.Button == MouseButton.Button1 &&
|
||||||
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((int)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((int)Window?.MousePosition.Y!, true))
|
||||||
|
{
|
||||||
|
use = true;
|
||||||
|
Focus();
|
||||||
|
if (Clicked is not null) Clicked.Invoke(this);
|
||||||
|
}
|
||||||
|
else use = false;
|
||||||
|
}
|
||||||
|
}
|
@ -9,62 +9,94 @@ using OpenTK.Windowing.GraphicsLibraryFramework;
|
|||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
public class TexturedTextBox : Rectangle
|
public class TexturedTextBox : IRenderObject
|
||||||
{
|
{
|
||||||
|
private Rectangle[] _bounds;
|
||||||
private Label _label;
|
private Label _label;
|
||||||
private Label _watermark;
|
private Label _watermark;
|
||||||
|
public ContextMenu? ContextMenu { get; set; }
|
||||||
|
|
||||||
public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
|
public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
|
||||||
|
|
||||||
public TexturedTextBox(Texture texture, FontFamily LabelFam, FontFamily WaterFam)
|
public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontFamily LabelFam, FontFamily WaterFam)
|
||||||
:base(texture)
|
|
||||||
{
|
{
|
||||||
base.HoverMouse = MouseCursor.IBeam;
|
_label = new Label(LabelFam);
|
||||||
_label = new Label(LabelFam)
|
|
||||||
{
|
|
||||||
HoverMouse = MouseCursor.IBeam,
|
|
||||||
IgnoreHover = true
|
|
||||||
};
|
|
||||||
TextureDisplay = TextureDisplay.HorizontalCenter;
|
|
||||||
_watermark = new(WaterFam)
|
_watermark = new(WaterFam)
|
||||||
{
|
{
|
||||||
Color = new(128, 128, 128, 255),
|
Color = new(128, 128, 128, 255)
|
||||||
HoverMouse = MouseCursor.IBeam,
|
|
||||||
IgnoreHover = true
|
|
||||||
};
|
};
|
||||||
|
_bounds = new Rectangle[] {new(Left), new(Middle), new(Right) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MouseCursor HoverMouse
|
public MouseCursor HoverMouse
|
||||||
{
|
{
|
||||||
get => base.HoverMouse;
|
get => _bounds[0].HoverMouse;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].HoverMouse = value;
|
||||||
|
}
|
||||||
|
|
||||||
_watermark.HoverMouse = value;
|
_watermark.HoverMouse = value;
|
||||||
_label.HoverMouse = value;
|
_label.HoverMouse = value;
|
||||||
base.HoverMouse = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Border { get; set; } = 2;
|
public int Border { get; set; } = 2;
|
||||||
|
|
||||||
public TexturedTextBox(Texture texture, FontInteraction LabelFam, FontInteraction WaterFam)
|
public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontInteraction LabelFam, FontInteraction WaterFam)
|
||||||
:base(texture)
|
|
||||||
{
|
{
|
||||||
base.HoverMouse = MouseCursor.IBeam;
|
_label = new Label(LabelFam);
|
||||||
_label = new Label(LabelFam)
|
|
||||||
{
|
|
||||||
HoverMouse = MouseCursor.IBeam,
|
|
||||||
IgnoreHover = true
|
|
||||||
};
|
|
||||||
TextureDisplay = TextureDisplay.HorizontalCenter;
|
|
||||||
_watermark = new(WaterFam)
|
_watermark = new(WaterFam)
|
||||||
{
|
{
|
||||||
Color = new(128, 128, 128, 255),
|
Color = new(128, 128, 128, 255)
|
||||||
HoverMouse = MouseCursor.IBeam,
|
|
||||||
IgnoreHover = true
|
|
||||||
};
|
};
|
||||||
|
_bounds = new Rectangle[] {new(Left), new(Middle), new(Right) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool mouseinside;
|
||||||
|
|
||||||
|
private void WindowOnMouseMove(MouseMoveEventArgs e)
|
||||||
|
{
|
||||||
|
if (Visible &&
|
||||||
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((float)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((float)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((float)Window?.MousePosition.Y!, true))
|
||||||
|
{
|
||||||
|
if (!mouseinside)
|
||||||
|
{
|
||||||
|
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||||
|
{
|
||||||
|
Window!.Cursor = HoverMouse;
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
mouseinside = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseinside)
|
||||||
|
{
|
||||||
|
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||||
|
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||||
|
mouseinside = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private int CurrentIndex = 0;
|
||||||
|
|
||||||
|
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||||
|
public event Func<IRenderObject, Task>? MouseEnter;
|
||||||
|
public event Func<IRenderObject, Task>? MouseLeave;
|
||||||
|
public object? Tag { get; set; } = null;
|
||||||
|
public ObjectAnchor Anchor { get; set; }
|
||||||
public FontInteraction Font { get => _label.Font; }
|
public FontInteraction Font { get => _label.Font; }
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
@ -82,17 +114,17 @@ public class TexturedTextBox : Rectangle
|
|||||||
_label.Visible = true;
|
_label.Visible = true;
|
||||||
_label.Location = TextLocation switch
|
_label.Location = TextLocation switch
|
||||||
{
|
{
|
||||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight), Location.Z),
|
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||||
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2), Location.Z),
|
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5, Location.Z)
|
_ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||||
};
|
};
|
||||||
_watermark.Location = _label.Location;
|
_watermark.Location = _label.Location;
|
||||||
}
|
}
|
||||||
if (_watermark.Visible) _watermark.Visible = false;
|
if (_watermark.Visible) _watermark.Visible = false;
|
||||||
if (!f && TextLocation == TextLocation.TrueCenterLeft && old != _label.TrueHeight)
|
if (!f && TextLocation == TextLocation.TrueCenterLeft && old != _label.TrueHeight)
|
||||||
{
|
{
|
||||||
_label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight), Location.Z);
|
_label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight));
|
||||||
_watermark.Location = _label.Location;
|
_watermark.Location = _label.Location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,10 +136,10 @@ public class TexturedTextBox : Rectangle
|
|||||||
_watermark.Visible = true;
|
_watermark.Visible = true;
|
||||||
_watermark.Location = TextLocation switch
|
_watermark.Location = TextLocation switch
|
||||||
{
|
{
|
||||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight), Location.Z),
|
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
|
||||||
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2), Location.Z),
|
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2)),
|
||||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5, Location.Z)
|
_ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||||
};
|
};
|
||||||
_label.Location = _label.Location;
|
_label.Location = _label.Location;
|
||||||
}
|
}
|
||||||
@ -115,6 +147,17 @@ public class TexturedTextBox : Rectangle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||||
|
}
|
||||||
|
|
||||||
public FontInteraction WatermarkFont { get => _watermark.Font; }
|
public FontInteraction WatermarkFont { get => _watermark.Font; }
|
||||||
public string WatermarkText
|
public string WatermarkText
|
||||||
{
|
{
|
||||||
@ -128,32 +171,45 @@ public class TexturedTextBox : Rectangle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public char? PasswordChar { get => _label.PasswordChar; set => _label.PasswordChar = value; }
|
public char? PasswordChar { get => _label.PasswordChar; set => _label.PasswordChar = value; }
|
||||||
public override Vector2i Size
|
public bool Loaded { get; private set; }
|
||||||
|
private Vector2i _size;
|
||||||
|
public Vector2i Size
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return base.Size;
|
return _size;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (base.Size == value) return;
|
if (_size == value) return;
|
||||||
base.Size = value;
|
_bounds[0].Size = new(value.Y);
|
||||||
|
_bounds[1].Size = new(value.X - (_bounds[0].Size.X * 2), value.Y);
|
||||||
|
_bounds[2].Size = _bounds[0].Size;
|
||||||
|
if (_size.X != value.X)
|
||||||
|
{
|
||||||
|
_bounds[1].Location = new(value.Y, 0);
|
||||||
|
_bounds[2].Location = new(_bounds[1].Size.X + _bounds[1].Location.X, 0);
|
||||||
|
}
|
||||||
|
_size = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override Vector3i Location {
|
public Vector2i Location {
|
||||||
get => base.Location;
|
get => _bounds[0].Location;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Vector3i diff = base.Location - value;
|
Vector2i diff = _bounds[0].Location - value;
|
||||||
base.Location = value;
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].Location -= diff;
|
||||||
|
}
|
||||||
if (_watermark.Visible && !string.IsNullOrEmpty(_watermark.Text))
|
if (_watermark.Visible && !string.IsNullOrEmpty(_watermark.Text))
|
||||||
{
|
{
|
||||||
_watermark.Location = TextLocation switch
|
_watermark.Location = TextLocation switch
|
||||||
{
|
{
|
||||||
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight), Location.Z),
|
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
|
||||||
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2), Location.Z),
|
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2)),
|
||||||
_ => new(value.X + Border + 5, value.Y + Border + 5, Location.Z)
|
_ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||||
};
|
};
|
||||||
_label.Location = _watermark.Location;
|
_label.Location = _watermark.Location;
|
||||||
}
|
}
|
||||||
@ -161,25 +217,34 @@ public class TexturedTextBox : Rectangle
|
|||||||
{
|
{
|
||||||
_label.Location = TextLocation switch
|
_label.Location = TextLocation switch
|
||||||
{
|
{
|
||||||
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight), Location.Z),
|
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||||
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||||
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2), Location.Z),
|
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||||
_ => new(value.X + Border + 5, value.Y + Border + 5, Location.Z)
|
_ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||||
};
|
};
|
||||||
_watermark.Location = _label.Location;
|
_watermark.Location = _label.Location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 SizeAsFloat { get; } = new();
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds[0].LocationAsFloat; }
|
||||||
|
public Vector2i Distance { get; set; }
|
||||||
|
public IParent? Parent { get; private set; }
|
||||||
|
public Window? Window { get; private set; }
|
||||||
public Color4 TextColor { get => _label.Color; set => _label.Color = value; }
|
public Color4 TextColor { get => _label.Color; set => _label.Color = value; }
|
||||||
public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; }
|
public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; }
|
||||||
|
|
||||||
public override bool Visible
|
public bool Visible
|
||||||
{
|
{
|
||||||
get => base.Visible;
|
get => _bounds[0].Visible;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == base.Visible) return;
|
if (value == _bounds[0].Visible) return;
|
||||||
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].Visible = value;
|
||||||
|
}
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_label.Text))
|
if (!string.IsNullOrEmpty(_label.Text))
|
||||||
@ -198,60 +263,74 @@ public class TexturedTextBox : Rectangle
|
|||||||
_label.Visible = value;
|
_label.Visible = value;
|
||||||
_watermark.Visible = value;
|
_watermark.Visible = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Visible = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public event Func<IRenderObject, Task>? Clicked;
|
||||||
|
|
||||||
public override void Clean()
|
public void Clean()
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].Clean();
|
||||||
|
}
|
||||||
_label.Clean();
|
_label.Clean();
|
||||||
_watermark.Clean();
|
_watermark.Clean();
|
||||||
base.Clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//private Vector2i? l, s;
|
||||||
|
|
||||||
public override void Draw(int x, int y, int w, int h)
|
public void Draw(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (!Visible || !Loaded) return;
|
if (!Visible || !Loaded) return;
|
||||||
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].Draw(x,y,w,h);
|
||||||
|
}
|
||||||
int nx = x, ny = y, nw = w, nh = h;
|
int nx = x, ny = y, nw = w, nh = h;
|
||||||
if (Location.X > nw)
|
if (Location.X + Border > nw)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nx += Location.X;
|
nx += (Location.X + Border);
|
||||||
nw -= Location.X;
|
nw -= (Location.X + Border);
|
||||||
if (Size.X < nw)
|
if (Size.X - Border < nw)
|
||||||
nw = Size.X;
|
nw = Size.X - Border;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Location.Y > nh)
|
if (Location.Y + Border > nh)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ny += Location.Y;
|
ny += (Location.Y + Border);
|
||||||
nh -= Location.Y;
|
nh -= (Location.Y + Border);
|
||||||
if (Size.Y < nh)
|
if (Size.Y - Border < nh)
|
||||||
nh = Size.Y;
|
nh = Size.Y - Border;
|
||||||
}
|
}
|
||||||
if (nw == 0 || nh == 0) return;
|
if (nh < 1 || nw < 1) return;
|
||||||
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
GL.Scissor(nx,ny,nw,nh);
|
||||||
base.Draw(nx,ny,nw,nh);
|
|
||||||
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
|
||||||
if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(nx,ny,nw,nh);
|
if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(nx,ny,nw,nh);
|
||||||
else _watermark.Draw(nx,ny,nw,nh);
|
else _watermark.Draw(nx,ny,nw,nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadToParent(IParent parent, IWindow window)
|
public void LoadToParent(IParent parent, Window window)
|
||||||
{
|
{
|
||||||
if (Loaded) return;
|
if (Loaded) return;
|
||||||
window.MouseDown += Window_MouseDown;
|
Parent = parent;
|
||||||
window.KeyDown += Window_KeyDown;
|
Window = window;
|
||||||
window.TextInput += WindowOnTextInput;
|
Window.MouseDown += Window_MouseDown;
|
||||||
if (!window.Context.IsCurrent) window.Context.MakeCurrent();
|
Window.KeyDown += Window_KeyDown;
|
||||||
_label.LoadToParent(parent, window);
|
Window.TextInput += WindowOnTextInput;
|
||||||
_watermark.LoadToParent(parent, window);
|
Loaded = true;
|
||||||
base.LoadToParent(parent, window);
|
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||||
|
for (int i = 0; i < _bounds.Length; i++)
|
||||||
|
{
|
||||||
|
_bounds[i].LoadToParent(Parent, Window);
|
||||||
|
}
|
||||||
|
_label.LoadToParent(Parent, Window);
|
||||||
|
_watermark.LoadToParent(Parent, Window);
|
||||||
|
Window.MouseMove += WindowOnMouseMove;
|
||||||
|
Location = Location;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowOnTextInput(TextInputEventArgs obj)
|
private void WindowOnTextInput(TextInputEventArgs obj)
|
||||||
@ -263,13 +342,13 @@ public class TexturedTextBox : Rectangle
|
|||||||
private bool use;
|
private bool use;
|
||||||
public event Func<KeyboardKeyEventArgs, Task>? KeyPress;
|
public event Func<KeyboardKeyEventArgs, Task>? KeyPress;
|
||||||
|
|
||||||
public override void UnFocus()
|
public void UnFocus()
|
||||||
{
|
{
|
||||||
use = false;
|
use = false;
|
||||||
if (Window is not null && Window.focused == this)
|
if (Window is not null && Window.focused == this)
|
||||||
Window.focused = null;
|
Window.focused = null;
|
||||||
}
|
}
|
||||||
public override void Focus()
|
public void Focus()
|
||||||
{
|
{
|
||||||
if (Window is not null)
|
if (Window is not null)
|
||||||
{
|
{
|
||||||
@ -291,16 +370,23 @@ public class TexturedTextBox : Rectangle
|
|||||||
if (!(Text.Length > 0)) return;
|
if (!(Text.Length > 0)) return;
|
||||||
Text = Text.Remove(Text.Length - 1, 1);
|
Text = Text.Remove(Text.Length - 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.Key == Keys.V && obj.Control && Window is not null) Text += Window.ClipboardString;
|
if (obj.Key == Keys.V && obj.Control && Window is not null) Text += Window.ClipboardString;
|
||||||
if (KeyPress is not null) _ = KeyPress.Invoke(obj);
|
if (KeyPress is not null) _ = KeyPress.Invoke(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_MouseDown(MouseButtonEventArgs e)
|
private void Window_MouseDown(MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
if (MouseInside && e.Button == MouseButton.Button1)
|
if (Visible &&
|
||||||
|
e.Button == MouseButton.Button1 &&
|
||||||
|
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||||
|
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((int)Window?.MousePosition.Y!, true) &&
|
||||||
|
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((int)Window?.MousePosition.Y!, true))
|
||||||
{
|
{
|
||||||
use = true;
|
use = true;
|
||||||
Focus();
|
Focus();
|
||||||
|
if (Clicked is not null) Clicked.Invoke(this);
|
||||||
}
|
}
|
||||||
else use = false;
|
else use = false;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,365 @@
|
|||||||
using GraphicsManager.Objects.Core;
|
using GraphicsManager.Enums;
|
||||||
|
using GraphicsManager.Interfaces;
|
||||||
|
using GraphicsManager.Objects.Core;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
using OpenTK.Windowing.Common;
|
||||||
|
using OpenTK.Windowing.Common.Input;
|
||||||
|
|
||||||
namespace GraphicsManager.Objects;
|
namespace GraphicsManager.Objects;
|
||||||
|
|
||||||
public class UserControl : ParentBase
|
public class UserControl : IRenderObject, IParent
|
||||||
{
|
{
|
||||||
public UserControl(Texture? t)
|
private Rectangle _bounds;
|
||||||
:base(t)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserControl()
|
public UserControl()
|
||||||
{
|
{
|
||||||
|
_bounds = new Rectangle();
|
||||||
|
_bounds.Clicked += _bounds_Clicked;
|
||||||
|
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||||
|
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MouseCursor HoverMouse
|
||||||
|
{
|
||||||
|
get => _bounds.HoverMouse;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bounds.HoverMouse = value;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
if (Controls[i].HoverMouse == MouseCursor.Default) Controls[i].HoverMouse = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TryDraw()
|
||||||
|
{
|
||||||
|
if (!BlockDraw && Parent is not null) Parent.TryDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task _bounds_Clicked(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (Clicked is not null) _ = Clicked.Invoke(arg);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControlList Controls { get; } = new();
|
||||||
|
public ObjectAnchor Anchor { get => _bounds.Anchor; set => _bounds.Anchor = value; }
|
||||||
|
|
||||||
|
public Color4 BackgroundColor { get => _bounds.BackgroundColor; set => _bounds.BackgroundColor = value; }
|
||||||
|
|
||||||
|
public bool Visible { get => _bounds.Visible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
_bounds.Visible = value;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Visible = value;
|
||||||
|
}
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public bool BlockDraw { get; set; } = false;
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void UnFocus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public Vector2i Size
|
||||||
|
{
|
||||||
|
get => _bounds.Size;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
_bounds.Size = value;
|
||||||
|
|
||||||
|
if (Parent is not null)
|
||||||
|
{
|
||||||
|
if (Loaded) ParentResize(new(Parent.Size));
|
||||||
|
Parent.TryDraw();
|
||||||
|
}
|
||||||
|
else ParentResize(new());
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReportSizeUpdate(IRenderObject Control)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
|
||||||
|
public Vector2i Location
|
||||||
|
{
|
||||||
|
get => _bounds.Location;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
_bounds.Location = value;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Location = Controls[i].Location;
|
||||||
|
}
|
||||||
|
ParentResize(new());
|
||||||
|
if (Parent is not null) Parent.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate()
|
||||||
|
{
|
||||||
|
if (Parent is null) return;
|
||||||
|
ForceDistanceUpdate(Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceDistanceUpdate(IParent parent)
|
||||||
|
{
|
||||||
|
_bounds.ForceDistanceUpdate(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
|
||||||
|
|
||||||
|
public Vector2i Position => Location;
|
||||||
|
public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
|
||||||
|
public Vector2i Distance { get => _bounds.Distance; set => _bounds.Distance = value; }
|
||||||
|
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 ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
|
||||||
|
public object? Tag { get; set; } = null;
|
||||||
|
public IParent? Parent { get; private set; }
|
||||||
|
public Window? Window { get; private set; }
|
||||||
|
public bool Loaded { get; private set; } = false;
|
||||||
|
|
||||||
|
public void LoadToParent(IParent Parent, Window Window)
|
||||||
|
{
|
||||||
|
if (Loaded) return;
|
||||||
|
this.Parent = Parent;
|
||||||
|
this.Window = Window;
|
||||||
|
BlockDraw = true;
|
||||||
|
Loaded = true;
|
||||||
|
_bounds.LoadToParent(Parent, Window);
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].LoadToParent(this, Window);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDraw = false;
|
||||||
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool dw;
|
||||||
|
|
||||||
|
public void Draw(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (Loaded)
|
||||||
|
{
|
||||||
|
int nx = x, ny = y, nw = w, nh = h;
|
||||||
|
if (Location.X > nw)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nx += Location.X;
|
||||||
|
nw -= Location.X;
|
||||||
|
if (Size.X < nw)
|
||||||
|
nw = Size.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Location.Y > nh)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ny += Location.Y;
|
||||||
|
nh -= Location.Y;
|
||||||
|
if (Size.Y < nh)
|
||||||
|
nh = Size.Y;
|
||||||
|
}
|
||||||
|
if (dw) Console.WriteLine("UserControl\nLoc: {0}\nSize: {1}\n\nX: {2}\nY: {3}\nW: {4}\nH:{5}\n\nX: {6}\nY: {7}\nW: {8}\nH:{9}",
|
||||||
|
Location,
|
||||||
|
Size,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
nw,
|
||||||
|
nh);
|
||||||
|
if (nw == 0 || nh == 0) return;
|
||||||
|
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
||||||
|
_bounds.Draw(nx,ny,nw,nh);
|
||||||
|
|
||||||
|
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
|
||||||
|
|
||||||
|
if (needload.Any())
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
foreach (IRenderObject Control in needload)
|
||||||
|
{
|
||||||
|
Control.LoadToParent(this, Window!);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
if (Controls[i] is not IParent)
|
||||||
|
{
|
||||||
|
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
|
||||||
|
}
|
||||||
|
Controls[i].Draw(nx, ny, nw, nh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
Controls[i].Clean();
|
||||||
|
}
|
||||||
|
_bounds.Clean();
|
||||||
|
}
|
||||||
|
private Task BoundsOnMouseLeave(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseLeave is not null) _ = MouseLeave.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BoundsOnMouseEnter(IRenderObject arg)
|
||||||
|
{
|
||||||
|
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ParentResize(ResizeEventArgs e)
|
||||||
|
{
|
||||||
|
BlockDraw = true;
|
||||||
|
if (e.Width == 0 && e.Height == 0) return;
|
||||||
|
for (int i = 0; i < Controls.Length; i++)
|
||||||
|
{
|
||||||
|
if (!Controls[i].Loaded) continue;
|
||||||
|
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
|
||||||
|
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
|
||||||
|
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
|
||||||
|
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
|
||||||
|
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
|
||||||
|
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
|
||||||
|
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
|
||||||
|
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
|
||||||
|
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
|
||||||
|
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||||
|
Controls[i].Size = new(sx, sy);
|
||||||
|
Controls[i].Location = new(lx, ly);
|
||||||
|
if (Controls[i] is IParent parent)
|
||||||
|
{
|
||||||
|
parent.ParentResize(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Parent!.TryDraw();
|
||||||
|
BlockDraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Cool Math Things
|
||||||
|
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f)
|
||||||
|
{
|
||||||
|
if (hastexture)
|
||||||
|
{
|
||||||
|
return new float[20] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new float[12] {
|
||||||
|
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
|
||||||
|
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
|
||||||
|
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
|
||||||
|
IntToFloat(x), IntToFloat(y, true), z,// top l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 PointToVector(float x, float y, float z = 0.0f)
|
||||||
|
{
|
||||||
|
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float IntToFloat(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? Location.Y : Location.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.Position.Y : tempp.Position.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 1);
|
||||||
|
double Per = Math.Round((double)1 / half, 15);
|
||||||
|
if (p == half) return 0.0f;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p > half) return (float)(((double)(p - half) * Per) * -1);
|
||||||
|
else return (float)(1 - (p * Per));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p > half) return (float)((double)(p - half) * Per);
|
||||||
|
else return (float)((1 - (p * Per)) * -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float FloatToInt(float p, bool Invert = false)
|
||||||
|
{
|
||||||
|
p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
|
||||||
|
IParent? tempp = Parent;
|
||||||
|
while (tempp is not null)
|
||||||
|
{
|
||||||
|
p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
|
||||||
|
tempp = tempp.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
|
||||||
|
double half = Math.Round((double)Size / (double)2, 15);
|
||||||
|
if (p == 0) return (int)half;
|
||||||
|
if (Invert)
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(half * p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(half - (p * half));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
{
|
||||||
|
p *= -1;
|
||||||
|
p++;
|
||||||
|
return (float)(Size - (half * p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (float)(p * half + half);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,13 @@ using OpenTK.Windowing.GraphicsLibraryFramework;
|
|||||||
|
|
||||||
namespace GraphicsManager;
|
namespace GraphicsManager;
|
||||||
|
|
||||||
public class Window : NativeWindow , IWindow
|
public class Window : NativeWindow , IParent
|
||||||
{
|
{
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
public TextureManager TextureManager { get; private set; }
|
public TextureManager TextureManager { get; private set; }
|
||||||
private TitleBar? _tb = null;
|
private TitleBar? _tb = null;
|
||||||
|
|
||||||
@ -27,7 +32,8 @@ public class Window : NativeWindow , IWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRenderObject? focused { get; set; }
|
internal IRenderObject? focused;
|
||||||
|
public IRenderObject? CurrentTop { get; set;}
|
||||||
public void CenterWindow(int mon)
|
public void CenterWindow(int mon)
|
||||||
{
|
{
|
||||||
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
|
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
|
||||||
@ -46,7 +52,7 @@ public class Window : NativeWindow , IWindow
|
|||||||
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
|
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContextMenu? ActiveMenu { get; set; } = null;
|
internal ContextMenu? ActiveMenu { get; set; } = null;
|
||||||
public IParent? Parent { get; } = null;
|
public IParent? Parent { get; } = null;
|
||||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||||
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);
|
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);
|
||||||
@ -118,14 +124,14 @@ public class Window : NativeWindow , IWindow
|
|||||||
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
|
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
|
||||||
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
|
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
|
||||||
}
|
}
|
||||||
public Vector3i Position { get; } = new(0);
|
public Vector2i Position { get; } = new Vector2i(0, 0);
|
||||||
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
|
public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
|
||||||
|
|
||||||
public ControlList Controls { get; } = new();
|
public ControlList Controls { get; } = new();
|
||||||
#region Cool Math Things
|
#region Cool Math Things
|
||||||
public float[] RctToFloat(int x, int y, int Width, int Height, bool hasTexture = false, float z = 0.0f)
|
public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f)
|
||||||
{
|
{
|
||||||
if (hasTexture)
|
if (hastexture)
|
||||||
{
|
{
|
||||||
return new float[20] {
|
return new float[20] {
|
||||||
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
||||||
@ -219,7 +225,7 @@ public class Window : NativeWindow , IWindow
|
|||||||
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : 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);
|
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
|
||||||
Controls[i].Size = new(sx, sy);
|
Controls[i].Size = new(sx, sy);
|
||||||
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
|
Controls[i].Location = new(lx, ly);
|
||||||
if (Controls[i] is IParent parent)
|
if (Controls[i] is IParent parent)
|
||||||
{
|
{
|
||||||
parent.ParentResize(e);
|
parent.ParentResize(e);
|
||||||
@ -234,7 +240,6 @@ public class Window : NativeWindow , IWindow
|
|||||||
base.OnResize(e);
|
base.OnResize(e);
|
||||||
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
|
||||||
GL.Viewport(0, 0, e.Width, e.Height);
|
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(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +269,7 @@ public class Window : NativeWindow , IWindow
|
|||||||
}
|
}
|
||||||
public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates;
|
public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates;
|
||||||
|
|
||||||
public bool CanControleUpdate { get; private set; } = true;
|
internal bool CanControleUpdate { get; private set; } = true;
|
||||||
|
|
||||||
public int FPS { get; set; } = 0;
|
public int FPS { get; set; } = 0;
|
||||||
public event Func<Window, Task>? WindowLoaded;
|
public event Func<Window, Task>? WindowLoaded;
|
||||||
@ -278,8 +283,6 @@ public class Window : NativeWindow , IWindow
|
|||||||
{
|
{
|
||||||
Context.MakeCurrent();
|
Context.MakeCurrent();
|
||||||
initthread = Thread.CurrentThread.ManagedThreadId;
|
initthread = Thread.CurrentThread.ManagedThreadId;
|
||||||
//GL.Enable(EnableCap.DepthTest);
|
|
||||||
MouseMove += WhenMouseMove;
|
|
||||||
GLFW.PollEvents();
|
GLFW.PollEvents();
|
||||||
DrawFrame();
|
DrawFrame();
|
||||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||||
@ -301,88 +304,20 @@ public class Window : NativeWindow , IWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRenderObject? HoveringControl { get; set; }
|
|
||||||
|
|
||||||
private void WhenMouseMove(MouseMoveEventArgs obj)
|
|
||||||
{
|
|
||||||
IRenderObject? cb = null;
|
|
||||||
IRenderObject? checkcontrol(IRenderObject render, int add_x = 0, int addy = 0, IRenderObject? CurrentBest = null)
|
|
||||||
{
|
|
||||||
void ClearHoverChain(IRenderObject ChainObject)
|
|
||||||
{
|
|
||||||
if (ChainObject is IParent parent)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < parent.Controls.Length; i++)
|
|
||||||
{
|
|
||||||
ClearHoverChain(parent.Controls._internal[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ChainObject.AllowHoverFromBehind) ChainObject.MouseInside = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!render.Visible ||
|
|
||||||
render.IgnoreHover ||
|
|
||||||
render.Location.X + add_x > obj.X ||
|
|
||||||
render.Location.Y + addy > obj.Y ||
|
|
||||||
render.Location.X + render.Size.X + add_x < obj.X ||
|
|
||||||
render.Location.Y + render.Size.Y + addy < obj.Y)
|
|
||||||
{
|
|
||||||
ClearHoverChain(render);
|
|
||||||
return CurrentBest;
|
|
||||||
}
|
|
||||||
if (render.AllowHoverFromBehind) render.MouseInside = true;
|
|
||||||
if (render is IParent p)
|
|
||||||
{
|
|
||||||
for (int i = p.Controls.Length - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
CurrentBest = checkcontrol(p.Controls._internal[i], add_x + render.Location.X, addy + render.Location.Y, CurrentBest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CurrentBest is null)
|
|
||||||
{
|
|
||||||
CurrentBest = render;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (CurrentBest.Location.Z < render.Location.Z) CurrentBest = render;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CurrentBest;
|
|
||||||
}
|
|
||||||
for (int i = Controls.Length - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
cb = checkcontrol(Controls._internal[i],0,0,cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb != HoveringControl)
|
|
||||||
{
|
|
||||||
IRenderObject? old = HoveringControl;
|
|
||||||
HoveringControl = cb;
|
|
||||||
if (cb is not null)
|
|
||||||
{
|
|
||||||
cb.MouseInside = true;
|
|
||||||
Cursor = cb.HoverMouse;
|
|
||||||
}
|
|
||||||
else Cursor = HoverMouse;
|
|
||||||
if (old is not null) old.MouseInside = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartRenderAsync()
|
public void StartRenderAsync()
|
||||||
{
|
{
|
||||||
Thread t = new Thread(_ => StartRender());
|
Thread t = new Thread(_ => StartRender());
|
||||||
t.Start();
|
t.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BlockDraw { get; set; }
|
public bool BlockDraw { get; set; } = false;
|
||||||
|
|
||||||
public void TryDraw()
|
public void TryDraw()
|
||||||
{
|
{
|
||||||
if (!BlockDraw) DrawFrame();
|
if (!BlockDraw) DrawFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int initthread;
|
private int initthread = 0;
|
||||||
|
|
||||||
public bool InvokeRequired
|
public bool InvokeRequired
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user