Compare commits
2 Commits
448e0f670f
...
ecf4e808ea
Author | SHA1 | Date | |
---|---|---|---|
ecf4e808ea | |||
f479409fe9 |
@ -36,7 +36,7 @@ public class ContextMenu : Window
|
||||
BackgroundColor = new(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
private Task ItemsOnControlAdded(IRenderObject arg)
|
||||
private Task ItemsOnControlAdded(int index, IRenderObject arg)
|
||||
{
|
||||
arg.Clicked += ArgOnClicked;
|
||||
this.Context.MakeCurrent();
|
||||
@ -57,9 +57,9 @@ public class ContextMenu : Window
|
||||
if (!e.IsFocused && w is not null) HideContext(w,true);
|
||||
}
|
||||
|
||||
private Window? w = null;
|
||||
private IWindow? w = null;
|
||||
|
||||
public void HideContext(Window Parent, bool force = false)
|
||||
public void HideContext(IWindow Parent, bool force = false)
|
||||
{
|
||||
if (Parent.ActiveMenu == this && !false) return;
|
||||
w = null;
|
||||
@ -68,7 +68,7 @@ public class ContextMenu : Window
|
||||
IsVisible = false;
|
||||
}
|
||||
|
||||
public void ShowContext(Window Parent)
|
||||
public void ShowContext(IWindow Parent)
|
||||
{
|
||||
w = Parent;
|
||||
if (Parent.ActiveMenu == this)
|
||||
|
11
GraphicsManager/Enums/TextureDisplay.cs
Normal file
11
GraphicsManager/Enums/TextureDisplay.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace GraphicsManager.Enums;
|
||||
|
||||
public enum TextureDisplay : byte
|
||||
{
|
||||
Clamped,
|
||||
HorizontalCenter,
|
||||
TextureHorizontalCenter,
|
||||
VerticalCenter,
|
||||
Center,
|
||||
ProgressHorizontalCenter,
|
||||
}
|
398
GraphicsManager/FPSWindow.cs
Executable file
398
GraphicsManager/FPSWindow.cs
Executable file
@ -0,0 +1,398 @@
|
||||
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">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
@ -10,7 +10,7 @@
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Version>1.0.6-alpha89</Version>
|
||||
<Version>1.0.7-alpha69</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
@ -12,12 +12,12 @@ public interface IParent
|
||||
public IParent? Parent { get; }
|
||||
public Vector2i Size { get; }
|
||||
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 float IntToFloat(float p, bool Invert = false);
|
||||
public void TryDraw();
|
||||
public void ReportSizeUpdate(IRenderObject Control);
|
||||
public float FloatToInt(float p, bool Invert = false);
|
||||
public Vector2i Position { get; }
|
||||
public Vector3i Position { get; }
|
||||
public MouseCursor HoverMouse { get; set; }
|
||||
}
|
||||
|
@ -10,20 +10,23 @@ public interface IRenderObject
|
||||
public void ForceDistanceUpdate(IParent parent);
|
||||
public ContextMenu? ContextMenu { 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 void LoadToParent(IParent Parent, Window Window);
|
||||
public void LoadToParent(IParent Parent, IWindow Window);
|
||||
public void Draw(int x, int y, int w, int h);
|
||||
public MouseCursor HoverMouse { get; set; }
|
||||
public void Clean();
|
||||
public void Focus();
|
||||
public void UnFocus();
|
||||
public Vector2i Size { get; set; }
|
||||
public Vector2i Location { get; set; }
|
||||
public Vector3i Location { get; set; }
|
||||
public Vector2 SizeAsFloat { get; }
|
||||
public Vector2 LocationAsFloat { get; }
|
||||
public Vector2i Distance { get; set; }
|
||||
public IParent? Parent { get; }
|
||||
public Window? Window { get; }
|
||||
public IWindow? Window { get; }
|
||||
public bool Visible { get; set; }
|
||||
public object? Tag { get; set; }
|
||||
|
||||
|
@ -4,10 +4,14 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GraphicsManager.Enums;
|
||||
|
||||
namespace GraphicsManager.Interfaces;
|
||||
|
||||
public interface ITextureObject : IRenderObject
|
||||
{
|
||||
public List<Texture> Textures { get; }
|
||||
|
||||
public TextureDisplay TextureDisplay { get; set; }
|
||||
|
||||
}
|
||||
|
34
GraphicsManager/Interfaces/IWindow.cs
Normal file
34
GraphicsManager/Interfaces/IWindow.cs
Normal file
@ -0,0 +1,34 @@
|
||||
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;
|
||||
|
||||
internal event Func<IRenderObject, Task>? ControlAdded;
|
||||
internal event Func<int, IRenderObject, Task>? ControlAdded;
|
||||
internal event Func<Task>? ControlRemoved;
|
||||
|
||||
public void Remove(IRenderObject item, bool purge = true)
|
||||
@ -33,12 +33,24 @@ public class ControlList
|
||||
if (ControlRemoved is not null && !Clearing) _ = ControlRemoved.Invoke();
|
||||
}
|
||||
|
||||
public void MoveControlToEnd(IRenderObject item)
|
||||
{
|
||||
_internal.Remove(item);
|
||||
_internal.Add(item);
|
||||
}
|
||||
|
||||
public void Add(IRenderObject item)
|
||||
{
|
||||
if (ControlAdded is not null) ControlAdded.Invoke(item).Wait();
|
||||
if (ControlAdded is not null) ControlAdded.Invoke(_internal.Count, item).Wait();
|
||||
_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)
|
||||
{
|
||||
Clearing = true;
|
||||
|
244
GraphicsManager/Objects/Core/ParentBase.cs
Normal file
244
GraphicsManager/Objects/Core/ParentBase.cs
Normal file
@ -0,0 +1,244 @@
|
||||
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
|
||||
}
|
77
GraphicsManager/Objects/Core/RoundedButton.cs
Normal file
77
GraphicsManager/Objects/Core/RoundedButton.cs
Normal file
@ -0,0 +1,77 @@
|
||||
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,6 +48,7 @@ public class Texture
|
||||
public int handel;
|
||||
public Vector2i? RawSize = null;
|
||||
public int Location { get; set; } = 1;
|
||||
public Vector2 MaxText = new(1f);
|
||||
|
||||
private Texture(byte[] pixels, int Width, int Height)
|
||||
{
|
||||
@ -59,7 +60,6 @@ public class Texture
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
|
||||
}
|
||||
|
||||
private Texture(Image<Rgba32> image, Memory<Rgba32> m)
|
||||
@ -72,7 +72,6 @@ public class Texture
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,27 +5,22 @@ using GraphicsManager.Objects.Core;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Windowing.Common;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace GraphicsManager.Objects;
|
||||
|
||||
public class FlowLayout : IRenderObject, IParent
|
||||
public class FlowLayout : ParentBase
|
||||
{
|
||||
private Rectangle _bounds;
|
||||
|
||||
public FlowLayout()
|
||||
public FlowLayout(Texture? texture = null)
|
||||
:base(texture)
|
||||
{
|
||||
_bounds = new Rectangle();
|
||||
_bounds.Clicked += _bounds_Clicked;
|
||||
AllowHoverFromBehind = true;
|
||||
t = new(33);
|
||||
t.Enabled = true;
|
||||
t.Elapsed += TOnElapsed;
|
||||
t.Start();
|
||||
Controls.ControlAdded += ControlsOnControlAdded;
|
||||
Controls.ControlRemoved += ControlsOnControlRemoved;
|
||||
_bounds.MouseEnter += BoundsOnMouseEnter;
|
||||
_bounds.MouseLeave += BoundsOnMouseLeave;
|
||||
}
|
||||
|
||||
public void ScrollToControl(IRenderObject Control)
|
||||
@ -49,7 +44,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
for (int i = Controls.Length - 1; i >= 0; i--)
|
||||
{
|
||||
start -= Controls[i].Size.Y;
|
||||
Controls[i].Location = new(Controls[i].Location.X, start);
|
||||
Controls[i].Location = new(Controls[i].Location.X, start, Controls[i].Location.Z);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -61,7 +56,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
start += Controls[i].Size.Y;
|
||||
Controls[i].Location = new(Controls[i].Location.X, start);
|
||||
Controls[i].Location = new(Controls[i].Location.X, start, Controls[i].Location.Z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +83,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
ScrollToControl(Controls[Controls.Length - 1]);
|
||||
}
|
||||
|
||||
public void ReportSizeUpdate(IRenderObject Control)
|
||||
public override void ReportSizeUpdate(IRenderObject Control)
|
||||
{
|
||||
if (BlockDraw) return;
|
||||
BlockDraw = true;
|
||||
@ -104,7 +99,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
continue;
|
||||
}
|
||||
|
||||
Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y);
|
||||
Controls[i].Location = new(0, Controls[i - 1].Location.Y + Controls[i - 1].Size.Y, Controls[i].Location.Z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,18 +109,30 @@ public class FlowLayout : IRenderObject, IParent
|
||||
private Task ControlsOnControlRemoved()
|
||||
{
|
||||
if (Controls.Length < 1) return Task.CompletedTask;
|
||||
if (Controls[0].Location.Y > 0) Controls[0].Location = new(0, 0);
|
||||
if (Controls[0].Location.Y > 0) Controls[0].Location = new(0);
|
||||
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 = new(0, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y, Controls[i].Location.Z);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task ControlsOnControlAdded(IRenderObject arg)
|
||||
private Task ControlsOnControlAdded(int index, IRenderObject arg)
|
||||
{
|
||||
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 (Controls.Length > 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)
|
||||
{
|
||||
for (int i = 0; i < par2.Controls.Length; i++)
|
||||
@ -152,71 +159,20 @@ public class FlowLayout : IRenderObject, IParent
|
||||
int sy = (bottom ? Size.Y - par.Controls[i].Distance.Y - ly : par.Controls[i].Size.Y);
|
||||
int sx = (right ? Size.X - par.Controls[i].Distance.X - lx : par.Controls[i].Size.X);
|
||||
par.Controls[i].Size = new(sx, sy);
|
||||
par.Controls[i].Location = new(lx, ly);
|
||||
par.Controls[i].Location = new(lx, ly, par.Controls[i].Location.Z);
|
||||
}
|
||||
}
|
||||
arg.Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task _bounds_Clicked(IRenderObject arg)
|
||||
public override Vector2i 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;
|
||||
get => base.Size;
|
||||
set
|
||||
{
|
||||
BlockDraw = true;
|
||||
_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;
|
||||
base.Size = value;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
Controls[i].Size = new(value.X, Controls[i].Size.Y);
|
||||
@ -227,92 +183,23 @@ public class FlowLayout : IRenderObject, IParent
|
||||
}
|
||||
}
|
||||
|
||||
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 void LoadToParent(IParent Parent, Window Window)
|
||||
public override void LoadToParent(IParent Parent, IWindow 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;
|
||||
base.LoadToParent(Parent,Window);
|
||||
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;
|
||||
private Queue<Action> scrols = new();
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!inside) return;
|
||||
if (!MouseInside) return;
|
||||
BlockDraw = true;
|
||||
dist += (int)obj.OffsetY;
|
||||
if (scrols.Any())
|
||||
@ -373,7 +260,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
if (!lfound)
|
||||
{
|
||||
BlockDraw = true;
|
||||
Controls[i].Location = new(0, found);
|
||||
Controls[i].Location = new(0, found, Controls[i].Location.Z);
|
||||
found += Controls[i].Size.Y;
|
||||
|
||||
if (Controls[i].Location.Y <= Size.Y) Controls[i].Visible = true;
|
||||
@ -415,7 +302,7 @@ public class FlowLayout : IRenderObject, IParent
|
||||
{
|
||||
BlockDraw = true;
|
||||
found -= Controls[i].Size.Y;
|
||||
Controls[i].Location = new(0, found);
|
||||
Controls[i].Location = new(0, found, Controls[i].Location.Z);
|
||||
|
||||
if (Controls[i].Location.Y + Controls[i].Size.Y >= 0) Controls[i].Visible = true;
|
||||
else
|
||||
@ -445,201 +332,4 @@ public class FlowLayout : IRenderObject, IParent
|
||||
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 Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
||||
public Vector2i Distance { get; set; }
|
||||
private Vector2i loc_ = new();
|
||||
private Vector3i loc_ = new();
|
||||
private int maxy = 0, maxx = 0;
|
||||
public Vector2i Location
|
||||
public Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -298,9 +298,11 @@ public class Label : ILabel
|
||||
public void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
}
|
||||
public Window? Window { get; private set; }
|
||||
public IWindow? Window { get; private set; }
|
||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||
public void LoadToParent(IParent window, Window win)
|
||||
public bool IgnoreHover { get; set; }
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public void LoadToParent(IParent window, IWindow win)
|
||||
{
|
||||
if (Loaded) return;
|
||||
if (!_characters.ContainsKey(win!.Context)) _characters.Add(win!.Context, new());
|
||||
@ -308,7 +310,6 @@ public class Label : ILabel
|
||||
if (Shader is null) Shader = DefaultTextShader[win.Context];
|
||||
Parent = window;
|
||||
Window = win;
|
||||
Window.MouseMove += WindowOnMouseMove;
|
||||
Window.MouseDown += WindowOnMouseDown;
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
@ -367,43 +368,31 @@ public class Label : ILabel
|
||||
|
||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||
{
|
||||
if (mouseinside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
if (mouseinside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||
if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||
if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
private bool mouseinside = false;
|
||||
private void WindowOnMouseMove(MouseMoveEventArgs obj)
|
||||
private bool mi = false;
|
||||
|
||||
public bool MouseInside
|
||||
{
|
||||
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))
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (!mouseinside)
|
||||
if (Window is null) return;
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||
{
|
||||
Window!.Cursor = HoverMouse;
|
||||
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||
mouseinside = true;
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
else
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
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;
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
166
GraphicsManager/Objects/ProgressBar.cs
Normal file
166
GraphicsManager/Objects/ProgressBar.cs
Normal file
@ -0,0 +1,166 @@
|
||||
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 Color4 Color { get; set; } = new Color4(255, 255, 255, 255);
|
||||
public Vector2i Distance { get; set; }
|
||||
private Vector2i loc_ = new();
|
||||
private Vector3i loc_ = new();
|
||||
private int maxy = 0, maxx = 0;
|
||||
public Vector2i Location
|
||||
public Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -374,9 +374,9 @@ public class RainbowLabel : ILabel
|
||||
}
|
||||
}
|
||||
}
|
||||
public Window? Window { get; private set; }
|
||||
public IWindow? Window { get; private set; }
|
||||
private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
|
||||
public void LoadToParent(IParent window, Window win)
|
||||
public void LoadToParent(IParent window, IWindow win)
|
||||
{
|
||||
if (Loaded) return;
|
||||
if (!Label._characters.ContainsKey(win!.Context)) Label._characters.Add(win!.Context, new());
|
||||
@ -384,7 +384,6 @@ public class RainbowLabel : ILabel
|
||||
if (Shader is null) Shader = Label.DefaultTextShader[win.Context];
|
||||
Parent = window;
|
||||
Window = win;
|
||||
Window.MouseMove += WindowOnMouseMove;
|
||||
Window.MouseDown += WindowOnMouseDown;
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
|
||||
@ -443,47 +442,35 @@ public class RainbowLabel : ILabel
|
||||
|
||||
private void WindowOnMouseDown(MouseButtonEventArgs obj)
|
||||
{
|
||||
if (mouseinside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
if (mouseinside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||
if (!mouseinside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||
if (MouseInside && obj.Button == MouseButton.Button1 && Clicked is not null) _ = Clicked.Invoke(this);
|
||||
if (MouseInside && obj.Button == MouseButton.Button2 && ContextMenu is not null) ContextMenu.ShowContext(Window!);
|
||||
if (!MouseInside && ContextMenu is not null) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
private bool mouseinside = false;
|
||||
private void WindowOnMouseMove(MouseMoveEventArgs obj)
|
||||
private bool mi = false;
|
||||
public bool MouseInside
|
||||
{
|
||||
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))
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (!mouseinside)
|
||||
if (Window is null) return;
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool AllowHoverFromBehind { get; set; }
|
||||
public bool IgnoreHover { get; set; }
|
||||
public event Func<IRenderObject, Task>? Clicked;
|
||||
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||
public event Func<IRenderObject, Task>? MouseEnter;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using GraphicsManager.Enums;
|
||||
using System.Diagnostics;
|
||||
using GraphicsManager.Enums;
|
||||
using GraphicsManager.Interfaces;
|
||||
using GraphicsManager.Objects.Core;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
@ -18,36 +19,56 @@ public class Rectangle : ITextureObject
|
||||
|
||||
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 ContextMenu? ContextMenu { get; set; } = null;
|
||||
public event Func<string[], Task>? FilesDroped;
|
||||
|
||||
public Rectangle(Texture? texture = null)
|
||||
public Rectangle(Texture? 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 void Focus()
|
||||
|
||||
public virtual void Focus()
|
||||
{
|
||||
|
||||
}
|
||||
public void UnFocus()
|
||||
public virtual void UnFocus()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255);
|
||||
private Color4 _BackgroundColor { get; set; } = new(0, 0, 0, 255);
|
||||
|
||||
public Color4 BackgroundColor
|
||||
{
|
||||
@ -60,7 +81,7 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
|
||||
private bool _Visible = true;
|
||||
public bool Visible
|
||||
public virtual bool Visible
|
||||
{
|
||||
get => _Visible;
|
||||
set
|
||||
@ -71,13 +92,13 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
|
||||
public Action? OnDrawAction;
|
||||
public Action? OnDrawExitAction;
|
||||
//public Action? OnDrawExitAction;
|
||||
|
||||
public void Draw(int x, int y, int w, int h)
|
||||
public virtual void Draw(int x, int y, int w, int h)
|
||||
{
|
||||
if (Visible && Loaded)
|
||||
{
|
||||
|
||||
if (OnDrawAction is not null) OnDrawAction.Invoke();
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
foreach (Texture tex in Textures)
|
||||
{
|
||||
@ -89,11 +110,11 @@ public class Rectangle : ITextureObject
|
||||
GL.Uniform4(0, BackgroundColor);
|
||||
}
|
||||
GL.BindVertexArray(ArrayObject);
|
||||
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedInt, 0);
|
||||
GL.DrawElements(PrimitiveType.Triangles, Indexs.Length, DrawElementsType.UnsignedShort, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
public virtual MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
|
||||
|
||||
public void ForceDistanceUpdate()
|
||||
{
|
||||
@ -106,7 +127,7 @@ public class Rectangle : ITextureObject
|
||||
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
public virtual void Clean()
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
GL.DeleteBuffer(BufferObject);
|
||||
@ -114,7 +135,7 @@ public class Rectangle : ITextureObject
|
||||
GL.DeleteVertexArray(ArrayObject);
|
||||
}
|
||||
|
||||
public void LoadToParent(IParent Parent, Window Window)
|
||||
public virtual void LoadToParent(IParent Parent, IWindow Window)
|
||||
{
|
||||
if (Loaded) return;
|
||||
this.Parent = Parent;
|
||||
@ -124,86 +145,100 @@ public class Rectangle : ITextureObject
|
||||
if (!Textures.Any())Shader = DefaultShader[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();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||
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)
|
||||
{
|
||||
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();
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(ushort), Indexs, Hint);
|
||||
Loaded = true;
|
||||
Window.MouseDown += Window_MouseDown;
|
||||
Window.MouseMove += WindowOnMouseMove;
|
||||
Window.FileDrop += WindowOnFileDrop;
|
||||
Location = Location;
|
||||
if (Distance.X != 0 && Distance.Y != 0) Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!mouseinside) return;
|
||||
if (!MouseInside) return;
|
||||
if (FilesDroped is not null) _ = FilesDroped.Invoke(obj.FileNames);
|
||||
}
|
||||
|
||||
private bool mouseinside = false;
|
||||
private void WindowOnMouseMove(MouseMoveEventArgs e)
|
||||
private bool mi = false;
|
||||
|
||||
public bool MouseInside
|
||||
{
|
||||
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))
|
||||
get => mi;
|
||||
set
|
||||
{
|
||||
if (!mouseinside)
|
||||
if (Window is null) return;
|
||||
if (AllowHoverFromBehind)
|
||||
{
|
||||
if (Window!.CurrentTop is null || Window!.CurrentTop == this)
|
||||
{
|
||||
Window!.Cursor = HoverMouse;
|
||||
if (MouseEnter is not null) _ = MouseEnter.Invoke(this);
|
||||
mouseinside = true;
|
||||
mi = value;
|
||||
if (value && MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
if (!value && MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseinside = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Window.HoveringControl == this && value)
|
||||
{
|
||||
if (mouseinside)
|
||||
mi = value;
|
||||
if (MouseEnter is not null) MouseEnter.Invoke(this);
|
||||
}
|
||||
|
||||
if (Window.HoveringControl != this && !value)
|
||||
{
|
||||
if (mouseinside && Window!.Cursor == HoverMouse) Window!.Cursor = Parent!.HoverMouse;
|
||||
if (MouseLeave is not null && mouseinside) _ = MouseLeave.Invoke(this);
|
||||
mouseinside = false;
|
||||
mi = value;
|
||||
if (MouseLeave is not null) MouseLeave.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IParent? Parent { get; private set; }
|
||||
public Window? Window { get; private set; }
|
||||
public IWindow? 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)
|
||||
{
|
||||
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) ContextMenu.HideContext(Window!);
|
||||
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) ContextMenu.HideContext(Window!);
|
||||
}
|
||||
|
||||
~Rectangle()
|
||||
@ -217,24 +252,19 @@ public class Rectangle : ITextureObject
|
||||
public Shader Shader { get; set; } = null;
|
||||
public int ElementBufferObject { get; private set; }
|
||||
public int BufferObject { get; private set; }
|
||||
public bool IgnoreHover { get; set; }
|
||||
public int ArrayObject { get; private set; }
|
||||
private float[] Points_;
|
||||
private Vector2i size_ = new(), loc_ = new();
|
||||
private Vector2i size_ = new();
|
||||
private Vector3i loc_ = new();
|
||||
|
||||
public float[] Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return Points_;
|
||||
}
|
||||
set
|
||||
{
|
||||
Points_ = value;
|
||||
try
|
||||
{
|
||||
if (Loaded)
|
||||
{
|
||||
//Distance = new(Parent!.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
|
||||
GL.BindVertexArray(ArrayObject);
|
||||
int add = 3;
|
||||
@ -251,7 +281,7 @@ public class Rectangle : ITextureObject
|
||||
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);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(ushort), Indexs, Hint);
|
||||
if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
|
||||
}
|
||||
}
|
||||
@ -262,12 +292,9 @@ public class Rectangle : ITextureObject
|
||||
}
|
||||
}
|
||||
|
||||
public uint[] Indexs { get; set; } = new uint[6] { 0, 1, 3, 1, 2, 3 };
|
||||
public ushort[] Indexs { get; set; } = new ushort[6] { 0, 1, 3, 1, 2, 3 };
|
||||
public BufferUsageHint Hint { get; set; } = BufferUsageHint.StaticDraw;
|
||||
|
||||
|
||||
public event Func<IRenderObject, Task>? Clicked;
|
||||
|
||||
public bool Loaded { get; private set; }
|
||||
public event Func<IRenderObject, Task>? WindowLoaded;
|
||||
public event Func<IRenderObject, Task>? MouseEnter;
|
||||
@ -275,7 +302,73 @@ public class Rectangle : ITextureObject
|
||||
public object? Tag { get; set; }
|
||||
public Vector2i Distance { get; set; }
|
||||
|
||||
public Vector2i Size
|
||||
private TextureDisplay td = TextureDisplay.Clamped;
|
||||
|
||||
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
|
||||
{
|
||||
@ -286,17 +379,180 @@ public class Rectangle : ITextureObject
|
||||
size_ = value;
|
||||
if (Window is null || Parent is null) return;
|
||||
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));
|
||||
temp[0] = saf.X;
|
||||
temp[(!Textures.Any()? 3 : 5)] = saf.X;
|
||||
temp[2] = Location.Z;
|
||||
temp[(!Textures.Any() ? 5 : 7)] = Location.Z;
|
||||
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() ? 6 : 10)] = laf.X;//bot l
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2i Location
|
||||
public virtual Vector3i Location
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -306,8 +562,21 @@ public class Rectangle : ITextureObject
|
||||
{
|
||||
loc_ = value;
|
||||
if (Window is null || Parent is null) return;
|
||||
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 => new float[40],
|
||||
_ => new float[20]
|
||||
};
|
||||
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() ? 9 : 15)] = laf.X;
|
||||
temp[1] = laf.Y;
|
||||
@ -317,9 +586,153 @@ public class Rectangle : ITextureObject
|
||||
temp[(!Textures.Any() ? 3 : 5)] = saf.X;
|
||||
temp[(!Textures.Any() ? 4 : 6)] = 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 laf = new(), saf = new();
|
||||
|
||||
public Vector2 LocationAsFloat { get { return laf; } }
|
||||
|
@ -1,160 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,372 +0,0 @@
|
||||
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,39 +1,28 @@
|
||||
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 SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace GraphicsManager.Objects;
|
||||
|
||||
public class TabControl : IRenderObject, IParent
|
||||
public class TabControl : ParentBase, IParent
|
||||
{
|
||||
public Rectangle _bounds;
|
||||
|
||||
public TabControl(FontFamily fam)
|
||||
private Texture t;
|
||||
public TabControl(Texture tex, FontFamily fam)
|
||||
{
|
||||
t = tex;
|
||||
TitleFont = FontInteraction.Load(fam);
|
||||
_bounds = new();
|
||||
}
|
||||
|
||||
public TabControl(FontInteraction fam)
|
||||
public TabControl(Texture tex, FontInteraction fam)
|
||||
{
|
||||
t = tex;
|
||||
TitleFont = fam;
|
||||
_bounds = new();
|
||||
}
|
||||
|
||||
public MouseCursor HoverMouse
|
||||
{
|
||||
get => _bounds.HoverMouse;
|
||||
set => _bounds.HoverMouse = value;
|
||||
}
|
||||
|
||||
|
||||
private ControlList Buttonts = new();
|
||||
public ControlList Controls { get; } = new();
|
||||
|
||||
public void AddPage(string Title, UserControl page)
|
||||
{
|
||||
@ -45,21 +34,19 @@ public class TabControl : IRenderObject, IParent
|
||||
locc = Buttonts[loc - 1].Location.X;
|
||||
loccc = Buttonts[loc - 1].Size.X;
|
||||
}
|
||||
Buttonts.Add(tmp = new RoundedButton(TitleFont.Family)
|
||||
Buttonts.Add(tmp = new RoundedButton(t, TitleFont.Family)
|
||||
{
|
||||
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
|
||||
Location = new(locc+ loccc + (TabSpace * (int)loc) + Border, Border, Location.Z),
|
||||
Text = Title,
|
||||
Tag = loc,
|
||||
BorderColor = this.BorderColor,
|
||||
InsideColor = this.InsideColor,
|
||||
FontColor = this.TextColor
|
||||
});
|
||||
|
||||
if (loc == PageIndex) tmp.BorderColor = this.SelectedColor;
|
||||
if (loc == PageIndex) tmp.BackgroundColor = this.SelectedColor;
|
||||
tmp.Clicked += TmpOnClicked;
|
||||
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
||||
page.Anchor = ObjectAnchor.All;
|
||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace);
|
||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace, page.Location.Z);
|
||||
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
||||
if (PageIndex != loc) page.Visible = false;
|
||||
Controls.Add(page);
|
||||
@ -75,22 +62,20 @@ public class TabControl : IRenderObject, IParent
|
||||
locc = Buttonts[loc - 1].Location.X;
|
||||
loccc = Buttonts[loc - 1].Size.X;
|
||||
}
|
||||
Buttonts.Add(tmp = new RoundedButton(TitleFont)
|
||||
Buttonts.Add(tmp = new RoundedButton(t, TitleFont)
|
||||
{
|
||||
Location = new( locc+ loccc + (TabSpace * (int)loc) + Border, Border),
|
||||
Location = new(locc+ loccc + (TabSpace * (int)loc) + Border, Border, Location.Z),
|
||||
Text = Title,
|
||||
Tag = loc,
|
||||
BorderColor = this.BorderColor,
|
||||
InsideColor = this.InsideColor,
|
||||
FontColor = this.TextColor,
|
||||
Anchor = ObjectAnchor.Top | ObjectAnchor.Left
|
||||
});
|
||||
|
||||
if (loc == PageIndex) tmp.BorderColor = this.SelectedColor;
|
||||
if (loc == PageIndex) tmp.BackgroundColor = this.SelectedColor;
|
||||
tmp.Clicked += TmpOnClicked;
|
||||
tmp.Size = new(tmp._label.Size.X + ((TextBorder + 4) * 2), tmp._label.Size.Y + ((TextBorder + 4) * 2));
|
||||
page.Anchor = ObjectAnchor.All;
|
||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace);
|
||||
page.Location = new(Border, tmp.Location.Y + tmp.Size.Y + TabSpace, page.Location.Z);
|
||||
page.Size = new(Size.X - Border - Border, Size.Y - page.Location.Y - Border);
|
||||
if (PageIndex != loc) page.Visible = false;
|
||||
Controls.Add(page);
|
||||
@ -102,36 +87,22 @@ public class TabControl : IRenderObject, IParent
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate()
|
||||
{
|
||||
if (Parent is null) return;
|
||||
ForceDistanceUpdate(Parent);
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
_bounds.ForceDistanceUpdate(parent);
|
||||
}
|
||||
|
||||
public Color4 TextColor { get; set; } = new(255, 255, 255, 255);
|
||||
public Color4 BorderColor { get; set; } = new(40, 40, 40, 255);
|
||||
public Color4 SelectedColor { get; set; } = Color4.DarkCyan;
|
||||
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 TabSpace { get; set; } = 5;
|
||||
public int Border { get; set; } = 10;
|
||||
public IParent? Parent { get; private set; } = null;
|
||||
public FontInteraction TitleFont { get; set; } = null!;
|
||||
public Window? Window { get; private set; } = null;
|
||||
|
||||
public bool Visible
|
||||
public override bool Visible
|
||||
{
|
||||
get => _bounds.Visible;
|
||||
get => base.Visible;
|
||||
set
|
||||
{
|
||||
BlockDraw = true;
|
||||
_bounds.Visible = value;
|
||||
base.Visible = value;
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
Buttonts[i].Visible = value;
|
||||
if (value) PageIndex = PageIndex;
|
||||
@ -144,15 +115,6 @@ public class TabControl : IRenderObject, IParent
|
||||
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;
|
||||
public uint PageIndex
|
||||
{
|
||||
@ -164,11 +126,11 @@ public class TabControl : IRenderObject, IParent
|
||||
{
|
||||
pgi = value;
|
||||
BlockDraw = true;
|
||||
if (_bounds.Visible)
|
||||
if (base.Visible)
|
||||
{
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
((RoundedButton)Buttonts[i]).BorderColor = BorderColor;
|
||||
((RoundedButton)Buttonts[value]).BorderColor = SelectedColor;
|
||||
((RoundedButton)Buttonts[i]).BackgroundColor = BorderColor;
|
||||
((RoundedButton)Buttonts[value]).BackgroundColor = SelectedColor;
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
Controls[i].Visible = false;
|
||||
Controls[value].Visible = true;
|
||||
@ -178,28 +140,8 @@ public class TabControl : IRenderObject, IParent
|
||||
BlockDraw = false;
|
||||
}
|
||||
}
|
||||
public void Focus()
|
||||
{
|
||||
|
||||
}
|
||||
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)
|
||||
public override void ParentResize(ResizeEventArgs e)
|
||||
{
|
||||
BlockDraw = true;
|
||||
if (e.Width == 0 && e.Height == 0) return;
|
||||
@ -216,7 +158,7 @@ public class TabControl : IRenderObject, IParent
|
||||
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);
|
||||
Controls[PageIndex].Size = new(sx, sy);
|
||||
Controls[PageIndex].Location = new(lx, ly);
|
||||
Controls[PageIndex].Location = new(lx, ly, Controls[PageIndex].Location.Z);
|
||||
if (Controls[PageIndex] is IParent parent)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
@ -235,7 +177,7 @@ public class TabControl : IRenderObject, IParent
|
||||
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);
|
||||
Buttonts[i].Size = new(sx, sy);
|
||||
Buttonts[i].Location = new(lx, ly);
|
||||
Buttonts[i].Location = new(lx, ly, Buttonts[i].Location.Z);
|
||||
if (Buttonts[i] is IParent parent2)
|
||||
{
|
||||
parent2.ParentResize(e);
|
||||
@ -245,154 +187,39 @@ public class TabControl : IRenderObject, IParent
|
||||
BlockDraw = false;
|
||||
}
|
||||
|
||||
public bool BlockDraw { get; set; } = false;
|
||||
public void LoadToParent(IParent Parent, Window Window)
|
||||
public override void LoadToParent(IParent Parent, IWindow Window)
|
||||
{
|
||||
if (Loaded) return;
|
||||
this.Parent = Parent;
|
||||
this.Window = Window;
|
||||
BlockDraw = true;
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
Loaded = true;
|
||||
_bounds.LoadToParent(Parent, Window);
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
Controls[i].LoadToParent(this, Window);
|
||||
}
|
||||
base.LoadToParent(Parent, Window);
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
{
|
||||
Buttonts[i].LoadToParent(this, Window);
|
||||
}
|
||||
|
||||
BlockDraw = false;
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
}
|
||||
|
||||
public void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
{
|
||||
if (Loaded && Visible)
|
||||
{
|
||||
_bounds.Draw(x,y,w,h);
|
||||
base.Draw(x,y,w,h);
|
||||
if (!(Controls.Length >= (PageIndex))) return;
|
||||
if (!Controls[PageIndex].Loaded) return;
|
||||
// GL.Scissor(Controls[PageIndex].ScissorLocation.X, Controls[PageIndex].ScissorLocation.Y, Controls[PageIndex].Size.X, Controls[PageIndex].Size.Y);
|
||||
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++)
|
||||
Buttonts[i].Draw(x,y,w,h);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
public override void Clean()
|
||||
{
|
||||
for (int i = 0; i < Controls.Length; i++)
|
||||
{
|
||||
Controls[i].Clean();
|
||||
}
|
||||
for (int i = 0; i < Buttonts.Length; i++)
|
||||
{
|
||||
Buttonts[i].Clean();
|
||||
}
|
||||
_bounds.Clean();
|
||||
base.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
|
||||
}
|
@ -1,335 +0,0 @@
|
||||
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,94 +9,62 @@ using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
|
||||
namespace GraphicsManager.Objects;
|
||||
|
||||
public class TexturedTextBox : IRenderObject
|
||||
public class TexturedTextBox : Rectangle
|
||||
{
|
||||
private Rectangle[] _bounds;
|
||||
private Label _label;
|
||||
private Label _watermark;
|
||||
public ContextMenu? ContextMenu { get; set; }
|
||||
|
||||
public TextLocation TextLocation { get; set; } = TextLocation.TopLeft;
|
||||
|
||||
public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontFamily LabelFam, FontFamily WaterFam)
|
||||
public TexturedTextBox(Texture texture, FontFamily LabelFam, FontFamily WaterFam)
|
||||
:base(texture)
|
||||
{
|
||||
_label = new Label(LabelFam);
|
||||
base.HoverMouse = MouseCursor.IBeam;
|
||||
_label = new Label(LabelFam)
|
||||
{
|
||||
HoverMouse = MouseCursor.IBeam,
|
||||
IgnoreHover = true
|
||||
};
|
||||
TextureDisplay = TextureDisplay.HorizontalCenter;
|
||||
_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 MouseCursor HoverMouse
|
||||
public override MouseCursor HoverMouse
|
||||
{
|
||||
get => _bounds[0].HoverMouse;
|
||||
get => base.HoverMouse;
|
||||
set
|
||||
{
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].HoverMouse = value;
|
||||
}
|
||||
|
||||
_watermark.HoverMouse = value;
|
||||
_label.HoverMouse = value;
|
||||
base.HoverMouse = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Border { get; set; } = 2;
|
||||
|
||||
public TexturedTextBox(Texture Left, Texture Middle, Texture Right, FontInteraction LabelFam, FontInteraction WaterFam)
|
||||
public TexturedTextBox(Texture texture, FontInteraction LabelFam, FontInteraction WaterFam)
|
||||
:base(texture)
|
||||
{
|
||||
_label = new Label(LabelFam);
|
||||
base.HoverMouse = MouseCursor.IBeam;
|
||||
_label = new Label(LabelFam)
|
||||
{
|
||||
HoverMouse = MouseCursor.IBeam,
|
||||
IgnoreHover = true
|
||||
};
|
||||
TextureDisplay = TextureDisplay.HorizontalCenter;
|
||||
_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 string Text
|
||||
{
|
||||
@ -114,17 +82,17 @@ public class TexturedTextBox : IRenderObject
|
||||
_label.Visible = true;
|
||||
_label.Location = TextLocation switch
|
||||
{
|
||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 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, Location.Z),
|
||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.Size.Y) / 2), Location.Z),
|
||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5, Location.Z)
|
||||
};
|
||||
_watermark.Location = _label.Location;
|
||||
}
|
||||
if (_watermark.Visible) _watermark.Visible = false;
|
||||
if (!f && TextLocation == TextLocation.TrueCenterLeft && old != _label.TrueHeight)
|
||||
{
|
||||
_label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight));
|
||||
_label.Location = new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight), Location.Z);
|
||||
_watermark.Location = _label.Location;
|
||||
}
|
||||
}
|
||||
@ -136,10 +104,10 @@ public class TexturedTextBox : IRenderObject
|
||||
_watermark.Visible = true;
|
||||
_watermark.Location = TextLocation switch
|
||||
{
|
||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight)),
|
||||
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2)),
|
||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5)
|
||||
TextLocation.TrueCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight), Location.Z),
|
||||
TextLocation.PostiveTureCenterLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
||||
TextLocation.PxLeft => new(Location.X + Border + 5, Location.Y + ((Size.Y - _watermark.Size.Y) / 2), Location.Z),
|
||||
_ => new(Location.X + Border + 5, Location.Y + Border + 5, Location.Z)
|
||||
};
|
||||
_label.Location = _label.Location;
|
||||
}
|
||||
@ -147,17 +115,6 @@ public class TexturedTextBox : IRenderObject
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate()
|
||||
{
|
||||
if (Parent is null) return;
|
||||
ForceDistanceUpdate(Parent);
|
||||
}
|
||||
|
||||
public void ForceDistanceUpdate(IParent parent)
|
||||
{
|
||||
Distance = new(parent.Size.X - Size.X - Location.X, parent.Size.Y - Size.Y - Location.Y);
|
||||
}
|
||||
|
||||
public FontInteraction WatermarkFont { get => _watermark.Font; }
|
||||
public string WatermarkText
|
||||
{
|
||||
@ -171,45 +128,32 @@ public class TexturedTextBox : IRenderObject
|
||||
}
|
||||
}
|
||||
public char? PasswordChar { get => _label.PasswordChar; set => _label.PasswordChar = value; }
|
||||
public bool Loaded { get; private set; }
|
||||
private Vector2i _size;
|
||||
public Vector2i Size
|
||||
public override Vector2i Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return _size;
|
||||
return base.Size;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_size == value) return;
|
||||
_bounds[0].Size = new(value.Y);
|
||||
_bounds[1].Size = new(value.X - (_bounds[0].Size.X * 2), value.Y);
|
||||
_bounds[2].Size = _bounds[0].Size;
|
||||
if (_size.X != value.X)
|
||||
{
|
||||
_bounds[1].Location = new(value.Y, 0);
|
||||
_bounds[2].Location = new(_bounds[1].Size.X + _bounds[1].Location.X, 0);
|
||||
}
|
||||
_size = value;
|
||||
if (base.Size == value) return;
|
||||
base.Size = value;
|
||||
}
|
||||
}
|
||||
public Vector2i Location {
|
||||
get => _bounds[0].Location;
|
||||
public override Vector3i Location {
|
||||
get => base.Location;
|
||||
set
|
||||
{
|
||||
Vector2i diff = _bounds[0].Location - value;
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].Location -= diff;
|
||||
}
|
||||
Vector3i diff = base.Location - value;
|
||||
base.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)),
|
||||
_ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.TrueHeight) / 2) - (_watermark.Size.Y - _watermark.TrueHeight), Location.Z),
|
||||
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight, Location.Z),
|
||||
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _watermark.Size.Y) / 2), Location.Z),
|
||||
_ => new(value.X + Border + 5, value.Y + Border + 5, Location.Z)
|
||||
};
|
||||
_label.Location = _watermark.Location;
|
||||
}
|
||||
@ -217,34 +161,25 @@ public class TexturedTextBox : IRenderObject
|
||||
{
|
||||
_label.Location = TextLocation switch
|
||||
{
|
||||
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 2) - (_label.Size.Y - _label.TrueHeight)),
|
||||
TextLocation.PostiveTureCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.PostiveTrueHeight) / 2) - _label.Size.Y + _label.TrueHeight),
|
||||
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2)),
|
||||
_ => new(value.X + Border + 5, value.Y + Border + 5)
|
||||
TextLocation.TrueCenterLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.TrueHeight) / 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, Location.Z),
|
||||
TextLocation.PxLeft => new(value.X + Border + 5, value.Y + ((Size.Y - _label.Size.Y) / 2), Location.Z),
|
||||
_ => new(value.X + Border + 5, value.Y + Border + 5, Location.Z)
|
||||
};
|
||||
_watermark.Location = _label.Location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 SizeAsFloat { get; } = new();
|
||||
public Vector2 LocationAsFloat { get => _bounds[0].LocationAsFloat; }
|
||||
public Vector2i Distance { get; set; }
|
||||
public IParent? Parent { get; private set; }
|
||||
public Window? Window { get; private set; }
|
||||
public Color4 TextColor { get => _label.Color; set => _label.Color = value; }
|
||||
public Color4 WatermarkColor { get => _watermark.Color; set => _watermark.Color = value; }
|
||||
|
||||
public bool Visible
|
||||
public override bool Visible
|
||||
{
|
||||
get => _bounds[0].Visible;
|
||||
get => base.Visible;
|
||||
set
|
||||
{
|
||||
if (value == _bounds[0].Visible) return;
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].Visible = value;
|
||||
}
|
||||
if (value == base.Visible) return;
|
||||
if (value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_label.Text))
|
||||
@ -263,74 +198,60 @@ public class TexturedTextBox : IRenderObject
|
||||
_label.Visible = value;
|
||||
_watermark.Visible = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public event Func<IRenderObject, Task>? Clicked;
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].Clean();
|
||||
base.Visible = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clean()
|
||||
{
|
||||
_label.Clean();
|
||||
_watermark.Clean();
|
||||
base.Clean();
|
||||
}
|
||||
|
||||
//private Vector2i? l, s;
|
||||
|
||||
public void Draw(int x, int y, int w, int h)
|
||||
public override void Draw(int x, int y, int w, int h)
|
||||
{
|
||||
if (!Visible || !Loaded) return;
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].Draw(x,y,w,h);
|
||||
}
|
||||
int nx = x, ny = y, nw = w, nh = h;
|
||||
if (Location.X + Border > nw)
|
||||
if (Location.X > nw)
|
||||
return;
|
||||
else
|
||||
{
|
||||
nx += (Location.X + Border);
|
||||
nw -= (Location.X + Border);
|
||||
if (Size.X - Border < nw)
|
||||
nw = Size.X - Border;
|
||||
nx += Location.X;
|
||||
nw -= Location.X;
|
||||
if (Size.X < nw)
|
||||
nw = Size.X;
|
||||
}
|
||||
|
||||
if (Location.Y + Border > nh)
|
||||
if (Location.Y > nh)
|
||||
return;
|
||||
else
|
||||
{
|
||||
ny += (Location.Y + Border);
|
||||
nh -= (Location.Y + Border);
|
||||
if (Size.Y - Border < nh)
|
||||
nh = Size.Y - Border;
|
||||
ny += Location.Y;
|
||||
nh -= Location.Y;
|
||||
if (Size.Y < nh)
|
||||
nh = Size.Y;
|
||||
}
|
||||
if (nh < 1 || nw < 1) return;
|
||||
GL.Scissor(nx,ny,nw,nh);
|
||||
if (nw == 0 || nh == 0) return;
|
||||
GL.Scissor(nx, Window!.Size.Y - ny - nh, 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);
|
||||
else _watermark.Draw(nx,ny,nw,nh);
|
||||
}
|
||||
|
||||
public void LoadToParent(IParent parent, Window window)
|
||||
public override void LoadToParent(IParent parent, IWindow window)
|
||||
{
|
||||
if (Loaded) return;
|
||||
Parent = parent;
|
||||
Window = window;
|
||||
Window.MouseDown += Window_MouseDown;
|
||||
Window.KeyDown += Window_KeyDown;
|
||||
Window.TextInput += WindowOnTextInput;
|
||||
Loaded = true;
|
||||
if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
|
||||
for (int i = 0; i < _bounds.Length; i++)
|
||||
{
|
||||
_bounds[i].LoadToParent(Parent, Window);
|
||||
}
|
||||
_label.LoadToParent(Parent, Window);
|
||||
_watermark.LoadToParent(Parent, Window);
|
||||
Window.MouseMove += WindowOnMouseMove;
|
||||
Location = Location;
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
window.MouseDown += Window_MouseDown;
|
||||
window.KeyDown += Window_KeyDown;
|
||||
window.TextInput += WindowOnTextInput;
|
||||
if (!window.Context.IsCurrent) window.Context.MakeCurrent();
|
||||
_label.LoadToParent(parent, window);
|
||||
_watermark.LoadToParent(parent, window);
|
||||
base.LoadToParent(parent, window);
|
||||
}
|
||||
|
||||
private void WindowOnTextInput(TextInputEventArgs obj)
|
||||
@ -342,13 +263,13 @@ public class TexturedTextBox : IRenderObject
|
||||
private bool use;
|
||||
public event Func<KeyboardKeyEventArgs, Task>? KeyPress;
|
||||
|
||||
public void UnFocus()
|
||||
public override void UnFocus()
|
||||
{
|
||||
use = false;
|
||||
if (Window is not null && Window.focused == this)
|
||||
Window.focused = null;
|
||||
}
|
||||
public void Focus()
|
||||
public override void Focus()
|
||||
{
|
||||
if (Window is not null)
|
||||
{
|
||||
@ -370,23 +291,16 @@ public class TexturedTextBox : IRenderObject
|
||||
if (!(Text.Length > 0)) return;
|
||||
Text = Text.Remove(Text.Length - 1, 1);
|
||||
}
|
||||
|
||||
if (obj.Key == Keys.V && obj.Control && Window is not null) Text += Window.ClipboardString;
|
||||
if (KeyPress is not null) _ = KeyPress.Invoke(obj);
|
||||
}
|
||||
|
||||
private void Window_MouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (Visible &&
|
||||
e.Button == MouseButton.Button1 &&
|
||||
Parent?.IntToFloat(Location.X) <= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||
Parent?.IntToFloat(Size.X + Location.X) >= Window?.IntToFloat((int)Window?.MousePosition.X!) &&
|
||||
Parent?.IntToFloat(Location.Y + Size.Y, true) <= Window?.IntToFloat((int)Window?.MousePosition.Y!, true) &&
|
||||
Parent?.IntToFloat(Location.Y, true) >= Window?.IntToFloat((int)Window?.MousePosition.Y!, true))
|
||||
if (MouseInside && e.Button == MouseButton.Button1)
|
||||
{
|
||||
use = true;
|
||||
Focus();
|
||||
if (Clicked is not null) Clicked.Invoke(this);
|
||||
}
|
||||
else use = false;
|
||||
}
|
||||
|
@ -1,365 +1,17 @@
|
||||
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 GraphicsManager.Objects.Core;
|
||||
|
||||
namespace GraphicsManager.Objects;
|
||||
|
||||
public class UserControl : IRenderObject, IParent
|
||||
public class UserControl : ParentBase
|
||||
{
|
||||
private Rectangle _bounds;
|
||||
public UserControl(Texture? t)
|
||||
:base(t)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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,13 +12,8 @@ using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
|
||||
namespace GraphicsManager;
|
||||
|
||||
public class Window : NativeWindow , IParent
|
||||
public class Window : NativeWindow , IWindow
|
||||
{
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public TextureManager TextureManager { get; private set; }
|
||||
private TitleBar? _tb = null;
|
||||
|
||||
@ -32,8 +27,7 @@ public class Window : NativeWindow , IParent
|
||||
}
|
||||
}
|
||||
|
||||
internal IRenderObject? focused;
|
||||
public IRenderObject? CurrentTop { get; set;}
|
||||
public IRenderObject? focused { get; set; }
|
||||
public void CenterWindow(int mon)
|
||||
{
|
||||
Box2i clientArea = Monitors.GetMonitors()[mon].ClientArea;
|
||||
@ -52,7 +46,7 @@ public class Window : NativeWindow , IParent
|
||||
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
|
||||
}
|
||||
|
||||
internal ContextMenu? ActiveMenu { get; set; } = null;
|
||||
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);
|
||||
@ -124,14 +118,14 @@ public class Window : NativeWindow , IParent
|
||||
if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
|
||||
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
|
||||
}
|
||||
public Vector2i Position { get; } = new Vector2i(0, 0);
|
||||
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)
|
||||
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] {
|
||||
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
|
||||
@ -225,7 +219,7 @@ public class Window : NativeWindow , IParent
|
||||
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 = new(lx, ly, Controls[i].Location.Z);
|
||||
if (Controls[i] is IParent parent)
|
||||
{
|
||||
parent.ParentResize(e);
|
||||
@ -240,6 +234,7 @@ public class Window : NativeWindow , IParent
|
||||
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);
|
||||
}
|
||||
|
||||
@ -269,7 +264,7 @@ public class Window : NativeWindow , IParent
|
||||
}
|
||||
public Rendertype Rendertype { get; set; } = Rendertype.ControlUpdates;
|
||||
|
||||
internal bool CanControleUpdate { get; private set; } = true;
|
||||
public bool CanControleUpdate { get; private set; } = true;
|
||||
|
||||
public int FPS { get; set; } = 0;
|
||||
public event Func<Window, Task>? WindowLoaded;
|
||||
@ -283,6 +278,8 @@ public class Window : NativeWindow , IParent
|
||||
{
|
||||
Context.MakeCurrent();
|
||||
initthread = Thread.CurrentThread.ManagedThreadId;
|
||||
//GL.Enable(EnableCap.DepthTest);
|
||||
MouseMove += WhenMouseMove;
|
||||
GLFW.PollEvents();
|
||||
DrawFrame();
|
||||
if (WindowLoaded is not null) WindowLoaded.Invoke(this);
|
||||
@ -304,20 +301,88 @@ public class Window : NativeWindow , IParent
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
Thread t = new Thread(_ => StartRender());
|
||||
t.Start();
|
||||
}
|
||||
|
||||
public bool BlockDraw { get; set; } = false;
|
||||
public bool BlockDraw { get; set; }
|
||||
|
||||
public void TryDraw()
|
||||
{
|
||||
if (!BlockDraw) DrawFrame();
|
||||
}
|
||||
|
||||
private int initthread = 0;
|
||||
private int initthread;
|
||||
|
||||
public bool InvokeRequired
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user