From b88cea7363f905ff7301a50541f4240e649dcea0 Mon Sep 17 00:00:00 2001
From: JacobTech <jacob@jacobtech.com>
Date: Sun, 29 Jan 2023 21:06:11 -0500
Subject: [PATCH] What am I doing

---
 GraphicsManager/ContextMenu.cs                |   1 +
 GraphicsManager/Globals/EXT.cs                |  63 ++++++++++
 GraphicsManager/GraphicsManager.csproj        |  13 ++-
 GraphicsManager/Interfaces/IParent.cs         |   1 +
 GraphicsManager/Interfaces/IRenderObject.cs   |   3 +-
 GraphicsManager/Objects/Core/Texture.cs       |  70 +++++------
 .../Objects/Core/TextureManager.cs            |   8 +-
 GraphicsManager/Objects/FlowLayout.cs         |  21 +++-
 GraphicsManager/Objects/Label.cs              | 106 +++++++++++++----
 GraphicsManager/Objects/Rectangle.cs          |  26 +++--
 GraphicsManager/Objects/RoundedButton.cs      |  10 +-
 GraphicsManager/Objects/RoundedRectangle.cs   |  43 +++----
 GraphicsManager/Objects/TabControl.cs         |  18 ++-
 GraphicsManager/Objects/Textbox.cs            |  34 +++++-
 GraphicsManager/Objects/TitleBar.cs           |  13 +++
 GraphicsManager/Objects/UserControl.cs        |  23 +++-
 GraphicsManager/Window.cs                     | 110 +++++++++++++++---
 17 files changed, 434 insertions(+), 129 deletions(-)
 create mode 100644 GraphicsManager/Objects/TitleBar.cs

diff --git a/GraphicsManager/ContextMenu.cs b/GraphicsManager/ContextMenu.cs
index bf56208..11d9c28 100644
--- a/GraphicsManager/ContextMenu.cs
+++ b/GraphicsManager/ContextMenu.cs
@@ -19,6 +19,7 @@ public class ContextMenu : Window
         StartFocused = false,
         Size = new OpenTK.Mathematics.Vector2i(400, 5),
         StartVisible = false,
+        SharedContext = null
     };
     
     private FlowLayout fl;
diff --git a/GraphicsManager/Globals/EXT.cs b/GraphicsManager/Globals/EXT.cs
index d3ecebc..5c34a42 100644
--- a/GraphicsManager/Globals/EXT.cs
+++ b/GraphicsManager/Globals/EXT.cs
@@ -1,3 +1,9 @@
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Drawing;
+using SixLabors.ImageSharp.Drawing.Processing;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+
 namespace GraphicsManager.Globals;
 
 public static class EXT
@@ -15,6 +21,63 @@ public static class EXT
         return dest;
     }
     
+    public static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext context, int size, float cornerRadius)
+    {
+        return context.Resize(new ResizeOptions
+        {
+            Size = new Size(size),
+            Mode = ResizeMode.Crop
+        }).ApplyRoundedCorners(cornerRadius);
+    }
+
+
+    // This method can be seen as an inline implementation of an `IImageProcessor`:
+    // (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`)
+    public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext context, float cornerRadius)
+    {
+        Size size = context.GetCurrentSize();
+        IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius);
+
+        context.SetGraphicsOptions(new GraphicsOptions()
+        {
+            Antialias = true,
+
+            // Enforces that any part of this shape that has color is punched out of the background
+            AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
+        });
+
+        // Mutating in here as we already have a cloned original
+        // use any color (not Transparent), so the corners will be clipped
+        foreach (IPath path in corners)
+        {
+            context = context.Fill(Color.Red, path);
+        }
+
+        return context;
+    }
+
+    public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
+    {
+        // First create a square
+        var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
+
+        // Then cut out of the square a circle so we are left with a corner
+        IPath cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
+
+        // Corner is now a corner shape positions top left
+        // let's make 3 more positioned correctly, we can do that by translating the original around the center of the image.
+
+        float rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1;
+        float bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1;
+
+        // Move it across the width of the image - the width of the shape
+        IPath cornerTopRight = cornerTopLeft.RotateDegree(90).Translate(rightPos, 0);
+        IPath cornerBottomLeft = cornerTopLeft.RotateDegree(-90).Translate(0, bottomPos);
+        IPath cornerBottomRight = cornerTopLeft.RotateDegree(180).Translate(rightPos, bottomPos);
+
+        return new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
+    }
+    
     public static T[] Add<T>(this T[] source, T Object)
     {
         T[] dest = new T[source.Length + 1];
diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj
index 881576d..efd6e32 100644
--- a/GraphicsManager/GraphicsManager.csproj
+++ b/GraphicsManager/GraphicsManager.csproj
@@ -10,7 +10,15 @@
         <IncludeSymbols>False</IncludeSymbols>
         <RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
         <RepositoryType>git</RepositoryType>
-        <Version>1.0.4-alpha09</Version>
+        <Version>1.0.5-alpha08</Version>
+    </PropertyGroup>
+
+    <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+      <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    </PropertyGroup>
+
+    <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+      <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     </PropertyGroup>
 
     <ItemGroup>
@@ -26,7 +34,8 @@
 
     <ItemGroup>
         <PackageReference Include="OpenTK" Version="4.7.1" />
-        <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
+        <PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
+        <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta15" />
         <PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" />
     </ItemGroup>
 
diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs
index 1340e61..f447683 100755
--- a/GraphicsManager/Interfaces/IParent.cs
+++ b/GraphicsManager/Interfaces/IParent.cs
@@ -8,6 +8,7 @@ public interface IParent
 	public Vector2 LocationAsFloat { get; }
 	public IParent? Parent { get; }
 	public Vector2i Size { get; }
+	public Vector2i GetParentRelLocPoint();
 	public void ParentResize(ResizeEventArgs e);
 	public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f);
 	public Vector3 PointToVector(float x, float y, float z = 0.0f);
diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs
index 26e9ea1..ab8dfb1 100755
--- a/GraphicsManager/Interfaces/IRenderObject.cs
+++ b/GraphicsManager/Interfaces/IRenderObject.cs
@@ -9,7 +9,7 @@ public interface IRenderObject
 	public ObjectAnchor Anchor { get; set; }
 	public bool Loaded { get; }
 	public void LoadToParent(IParent Parent, Window Window);
-	public void Draw();
+	public void Draw(int x, int y, int w, int h);
 	public void Clean();
 	public void Focus();
 	public void UnFocus();
@@ -17,6 +17,7 @@ public interface IRenderObject
 	public Vector2i Location { get; set; }
 	public Vector2 SizeAsFloat { get; }
 	public Vector2 LocationAsFloat { get; }
+	public Vector2i ScissorLocation { get; }
 	public Vector2i Distance { get; }
 	public IParent? Parent { get; }
 	public Window? Window { get; }
diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs
index 53e212a..4f2fd0f 100755
--- a/GraphicsManager/Objects/Core/Texture.cs
+++ b/GraphicsManager/Objects/Core/Texture.cs
@@ -1,4 +1,5 @@
-using GraphicsManager.Structs;
+using GraphicsManager.Globals;
+using GraphicsManager.Structs;
 using OpenTK.Graphics.ES30;
 using OpenTK.Mathematics;
 using OpenTK.Windowing.Desktop;
@@ -27,31 +28,39 @@ public class Texture
 	public static readonly Dictionary<IGLFWGraphicsContext, Shader> TextureShader = new ();
 
 	public int handel;
-	internal Texture(byte[] File)
+	public int Location { get; set; } = 1;
+	
+	internal Texture(byte[] File, bool Rounded = false)
 	{
 		Image<Rgba32> image = Image.Load<Rgba32>(File);
-		image.Mutate(x => x.Flip(FlipMode.Vertical));
-
-		var pixels = new List<byte>(4 * image.Width * image.Height);
-
-		for (int y = 0; y < image.Height; y++)
+		if (Rounded)
 		{
-			var row = image.GetPixelRowSpan(y);
-
-			for (int x = 0; x < image.Width; x++)
+			image.Mutate(x =>
 			{
-				pixels.Add(row[x].R);
-				pixels.Add(row[x].G);
-				pixels.Add(row[x].B);
-				pixels.Add(row[x].A);
-			}
+				x.Flip(FlipMode.Vertical);
+				if (image.Width <= image.Height) x.ConvertToAvatar(image.Width, image.Width/2);
+				else x.ConvertToAvatar(image.Height, image.Height/2);
+			});
 		}
+		else
+		{
+			image.Mutate(x =>
+			{
+				x.Flip(FlipMode.Vertical);
+			});
+		}
+		
 
+		Span<byte> pixels = new byte[4 * image.Width * image.Height].AsSpan();
+		image.CopyPixelDataTo(pixels);
 		handel = GL.GenTexture();
 		GL.BindTexture(TextureTarget.Texture2D, handel);
 		GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels.ToArray());
 		GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
 		GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+		GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
+		GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
+		GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
 	}
 
 	private Texture()
@@ -224,7 +233,10 @@ public class Texture
 				GL.TexImage2D(TextureTarget.Texture2D, 0,
 					PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0,
 					PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer);
-
+				GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+				GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+				GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
+				GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
 
 				Character cha = new()
 				{
@@ -284,6 +296,10 @@ public class Texture
 					GL.TexImage2D(TextureTarget.Texture2D, 0,
 						PixelInternalFormat.R8, bitmap2.Width, bitmap2.Rows, 0,
 						PixelFormat.Red, PixelType.UnsignedByte, bitmap2.Buffer);
+					GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+					GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+					GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
+					GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
 					Character cha2 = new()
 					{
 						Size = new Vector2(bitmap2.Width, bitmap2.Rows),
@@ -321,7 +337,10 @@ public class Texture
 			GL.TexImage2D(TextureTarget.Texture2D, 0,
 				PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0,
 				PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer);
-
+			GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+			GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+			GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
+			GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
 
 			Character cha = new()
 			{
@@ -344,23 +363,6 @@ public class Texture
 		}
 	}
 
-	public void LoadText()
-	{
-		GL.TextureParameter(handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
-		GL.TextureParameter(handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
-		GL.TextureParameter(handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
-		GL.TextureParameter(handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
-	}
-
-	public void Load(int loc)
-	{
-		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);
-		GL.EnableVertexAttribArray(loc);
-		GL.VertexAttribPointer(loc, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
-	}
-
 	public void Use(TextureUnit unit = TextureUnit.Texture0)
 	{
 		GL.ActiveTexture(unit);
diff --git a/GraphicsManager/Objects/Core/TextureManager.cs b/GraphicsManager/Objects/Core/TextureManager.cs
index 2de58b9..568ecd5 100644
--- a/GraphicsManager/Objects/Core/TextureManager.cs
+++ b/GraphicsManager/Objects/Core/TextureManager.cs
@@ -41,12 +41,14 @@ public class TextureManager
         }
     }
     
-    public Texture AddTexture(byte[] Texture)
+    public Texture AddTexture(byte[] Texture, bool Rounded = false)
     {
-        byte[] hash = SHA256.HashData(Texture);
+        List<byte> hash2 = SHA256.HashData(Texture).ToList();
+        hash2.Insert(0, Convert.ToByte(Rounded));
+        byte[] hash = hash2.ToArray();
         if (TextureHashMap.ContainsKey(hash)) return TextureHashMap[hash];
         Context.MakeCurrent();
-        TextureHashMap.Add(hash, new(Texture));
+        TextureHashMap.Add(hash, new(Texture, Rounded));
         return TextureHashMap[hash];
     }
 }
\ No newline at end of file
diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs
index c1ee967..5ba5f66 100644
--- a/GraphicsManager/Objects/FlowLayout.cs
+++ b/GraphicsManager/Objects/FlowLayout.cs
@@ -217,6 +217,7 @@ public class FlowLayout : IRenderObject, IParent
 			BlockDraw = false;
 		}
 	}
+	public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
 
 	public Vector2i Position => Location;
 	public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
@@ -399,11 +400,11 @@ public class FlowLayout : IRenderObject, IParent
 		}
 	}
 
-	public void Draw()
+	public void Draw(int x, int y, int w, int h)
 	{
 		if (Loaded)
 		{
-			_bounds.Draw();
+			_bounds.Draw(x,y,w,h);
 			IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
 
 			if (needload.Any())
@@ -418,10 +419,24 @@ public class FlowLayout : IRenderObject, IParent
 			}
 			for (int i = 0; i < Controls.Length; i++)
 			{
-				Controls[i].Draw();
+				Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y);
+				Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y);
+				if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y);
+				if (laff.X < x) laff = new(x, laff.Y);
+				if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y);
+				if (laff.Y < y) laff = new(laff.X, y);
+				if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y);
+				if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y);
+				GL.Scissor(laff.X, laff.Y, saff.X, saff.Y);
+				Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
 			}
 		}
 	}
+	
+	public Vector2i GetParentRelLocPoint()
+	{
+		return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
+	}
 
 	public void Clean()
 	{
diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs
index 09b524e..a001f78 100755
--- a/GraphicsManager/Objects/Label.cs
+++ b/GraphicsManager/Objects/Label.cs
@@ -120,8 +120,23 @@ public class Label : IRenderObject
 			Size = new((int)addx, (int)addy);
 			if (Loaded)
 			{
-				GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
-				if (Window is not null && Window.CanControleUpdate) Parent!.TryDraw();
+				
+				if (Window is not null && Window.CanControleUpdate)
+				{
+					if (!Window.Context.IsCurrent)
+					{
+						try
+						{
+							Window.Context.MakeCurrent();
+						}
+						catch (Exception e)
+						{
+							Console.WriteLine(e);
+						}
+					}
+					GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+					Parent!.TryDraw();
+				}
 			}
 		}
 	}
@@ -141,29 +156,56 @@ public class Label : IRenderObject
 		{
 			loc_ = value;
 			if (Window is null || Parent is null) return;
-			if (Window.CanControleUpdate && Loaded) Parent!.TryDraw();
+			if (Window.CanControleUpdate && Loaded)
+			{
+				ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
+				Parent!.TryDraw();
+				if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
+			}
+		}
+	}
+
+	private Vector2i _size;
+	public Vector2i Size { get => _size;
+		set
+		{
+			_size = value;
+			if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y));
 		}
 	}
-	public Vector2i Size { get; set; }
 
 	public void Clean()
 	{
-		GL.DeleteBuffer(VBO);
+		Tuple<int, int, int> tup = GlobalBuffers[Window!.Context];
+		if (tup.Item3 - 1 == 0)
+		{
+			//Broken, I may fix latter
+			
+			//if (!Window.Context.IsCurrent) Window.Context.MakeCurrent();
+			//GL.DeleteBuffer(VBO);
+			//GL.DeleteVertexArray(VAO);
+			//GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+			//GlobalBuffers.Remove(Window!.Context);
+		}
+		else
+		{
+			GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1);
+		}
 		Size = new(0, 0);
-		GL.DeleteVertexArray(VAO);
-		GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 		Loaded = false;
 		Visible = false;
 	}
+	public Vector2i ScissorLocation { get; private set; }
 
-	public void Draw()
+	public void Draw(int x, int y, int ww, int hh)
 	{
 		if (Visible & Loaded)
 		{
+			if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
 			Shader.Use();
 			GL.Enable(EnableCap.Blend);
 			GL.Uniform4(2, Color);
-			Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f);
+			Matrix4 projectionM  = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f);
 			GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
 			GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 			GL.UniformMatrix4(1, false, ref projectionM);
@@ -173,8 +215,7 @@ public class Label : IRenderObject
 			float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X);
 			Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad);
 			Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Window.FloatToInt(Parent!.IntToFloat(0)), loc_.Y + Font.PixelHeight + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
-
-			float char_x = 0.0f;
+			 float char_x = 0.0f;
 			
 			GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
 			GL.ActiveTexture(TextureUnit.Texture0);
@@ -191,7 +232,6 @@ public class Label : IRenderObject
 				if (!_characters[Window!.Context][Font].ContainsKey(c) && !n)
 				{
 					var f = Texture.TextureForChar(Window!.Context, Font, c);
-					f.LoadText();
 				}
 				
                 int maxx = 0;
@@ -226,7 +266,7 @@ public class Label : IRenderObject
 		}
 	}
 	public Window? Window { get; private set; }
-
+	private static Dictionary<IGLFWGraphicsContext, Tuple<int, int, int>> GlobalBuffers = new();
 	public void LoadToParent(IParent window, Window win)
 	{
 		if (Loaded) return;
@@ -237,18 +277,40 @@ public class Label : IRenderObject
 		Window = win;
 		Window.MouseMove += WindowOnMouseMove;
 		Window.MouseDown += WindowOnMouseDown;
+		if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
 		GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
 		GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
-		float[] vquad =
+		if (!GlobalBuffers.ContainsKey(win.Context))
 		{
-			0.0f, -1.0f,   0.0f, 0.0f,
-			0.0f,  0.0f,   0.0f, 1.0f,
-			1.0f,  0.0f,   1.0f, 1.0f,
-			0.0f, -1.0f,   0.0f, 0.0f,
-			1.0f,  0.0f,   1.0f, 1.0f,
-			1.0f, -1.0f,   1.0f, 0.0f
-		};
+			float[] vquad =
+			{
+				0.0f, -1.0f,   0.0f, 0.0f,
+				0.0f,  0.0f,   0.0f, 1.0f,
+				1.0f,  0.0f,   1.0f, 1.0f,
+				0.0f, -1.0f,   0.0f, 0.0f,
+				1.0f,  0.0f,   1.0f, 1.0f,
+				1.0f, -1.0f,   1.0f, 0.0f
+			};
+			int _VBO = GL.GenBuffer();
+			GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO);
+			GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw);
+			int _VAO = GL.GenVertexArray();
+			GL.BindVertexArray(_VAO);
+			GL.EnableVertexAttribArray(0);
+			GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0);
+			GL.EnableVertexAttribArray(1);
+			GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4);
+			GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0));
+		}
 
+		Tuple<int, int, int> tup = GlobalBuffers[win.Context];
+		VBO = tup.Item1;
+		VAO = tup.Item2;
+		GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1);
+		
+		
+		
+/*
 		VBO = GL.GenBuffer();
 		GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
 		GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw);
@@ -259,7 +321,7 @@ public class Label : IRenderObject
 		GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0);
 		GL.EnableVertexAttribArray(1);
 		GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4);
-
+*/
 		GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 		GL.BindVertexArray(0);
 		
diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs
index 880999d..55556f7 100755
--- a/GraphicsManager/Objects/Rectangle.cs
+++ b/GraphicsManager/Objects/Rectangle.cs
@@ -15,7 +15,7 @@ public class Rectangle : ITextureObject
 
 	public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
 
-	public Texture? Texture { get; private set; }
+	public Texture? Texture { get; set; }
 	public ContextMenu? ContextMenu { get; set; } = null;
 	public event Func<string[], Task>? FilesDroped; 
 
@@ -67,13 +67,15 @@ public class Rectangle : ITextureObject
 		}
 	}
 
-	public void Draw()
+	public void Draw(int x, int y, int w, int h)
 	{
 		if (Visible && Loaded)
 		{
+			
+			if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent();
 			if (Texture is not null) Texture.Use();
 			Shader.Use();
-			GL.Uniform4(0, BackgroundColor);
+			if (Texture is null) GL.Uniform4(0, BackgroundColor);
 			if (Texture is not null)
 			{
 				GL.Enable(EnableCap.Blend);
@@ -115,7 +117,6 @@ public class Rectangle : ITextureObject
 		if (Texture is not null)
 		{
 			Shader = Texture.TextureShader[Window.Context];
-			Texture.Load(Shader.GetAttribLocation("aTexCoord"));
 		}
 		GL.EnableVertexAttribArray(0);
 		GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
@@ -197,14 +198,19 @@ public class Rectangle : ITextureObject
 				if (Loaded)
 				{
 					//Distance = new(Parent!.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
-					int add = 3;
-					if (Texture is not null) add = 5;
 					GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
 					GL.BindVertexArray(ArrayObject);
+					int add = 3;
+					if (Texture is not null)
+					{
+						add = 5;
+						GL.VertexAttribPointer(Texture.Location, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
+						GL.EnableVertexAttribArray(Texture.Location);
+					}
 					GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
 					GL.EnableVertexAttribArray(0);
 					GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
-					GL.BufferData(BufferTarget.ArrayBuffer, Points_.Length * sizeof(float), Points_, Hint);
+					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);
@@ -248,6 +254,7 @@ public class Rectangle : ITextureObject
 			temp[(Texture is null ? 3 : 5)] = saf.X;
 			temp[(Texture is null ? 4 : 6)] = saf.Y;
 			temp[(Texture is null ? 7 : 11)] = saf.Y;
+			ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
 			Points = temp;
 		}
 	}
@@ -273,9 +280,14 @@ public class Rectangle : ITextureObject
 			temp[(Texture is null ? 3 : 5)] = saf.X;
 			temp[(Texture is null ? 4 : 6)] = saf.Y;
 			temp[(Texture is null ? 7 : 11)] = saf.Y;
+			ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)),
+			//ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y);
+			//(int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true)
+			//);
 			Points = temp;
 		}
 	}
+	public Vector2i ScissorLocation { get; private set; }
 	private Vector2 laf = new(), saf = new();
 
 	public Vector2 LocationAsFloat { get { return laf; } }
diff --git a/GraphicsManager/Objects/RoundedButton.cs b/GraphicsManager/Objects/RoundedButton.cs
index 219ce77..3929bd8 100755
--- a/GraphicsManager/Objects/RoundedButton.cs
+++ b/GraphicsManager/Objects/RoundedButton.cs
@@ -73,6 +73,8 @@ public class RoundedButton : IRenderObject
 			_label.Location = new( value.X  + Border + (((Size.X - (Border * 2)) / 2) - (_label.Size.X / 2)), value.Y + Border + (((Size.Y - (Border * 2)) / 2) - (_label.Size.Y / 2)));
 		}
 	}
+	public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
+	
 	public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; }
 	public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
 	public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value;}
@@ -108,12 +110,12 @@ public class RoundedButton : IRenderObject
 		_label.Clean();
 	}
 
-	public void Draw()
+	public void Draw(int x, int y, int w, int h)
 	{
 		if (!Visible || !Loaded) return;
-		_bounds.Draw();
-		_inside.Draw();
-		_label.Draw();
+		_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)
diff --git a/GraphicsManager/Objects/RoundedRectangle.cs b/GraphicsManager/Objects/RoundedRectangle.cs
index ecc2c35..0597a9d 100755
--- a/GraphicsManager/Objects/RoundedRectangle.cs
+++ b/GraphicsManager/Objects/RoundedRectangle.cs
@@ -4,7 +4,6 @@ using GraphicsManager.Objects.Core;
 using OpenTK.Graphics.OpenGL4;
 using OpenTK.Mathematics;
 using OpenTK.Windowing.GraphicsLibraryFramework;
-using System.Runtime.Intrinsics.X86;
 using OpenTK.Windowing.Common;
 
 namespace GraphicsManager.Objects;
@@ -18,7 +17,7 @@ public class RoundedRectangle : IRenderObject
 
 	public RoundedRectangle()
 	{
-		Points_ = new float[36 + (((sn - 1) * 4) * 3)];
+		//Points_ = new float[36 + (((sn - 1) * 4) * 3)];
 	}
 	public event Func<IRenderObject, Task>? WindowLoaded;
 	public event Func<IRenderObject, Task>? MouseEnter;
@@ -110,7 +109,7 @@ public class RoundedRectangle : IRenderObject
 		}
 	}
 
-	public void Draw()
+	public void Draw(int x, int y, int w, int h)
 	{
 		if (Visible && Loaded)
 		{
@@ -141,26 +140,13 @@ public class RoundedRectangle : IRenderObject
 		this.Parent = Parent;
 		this.Window = Window;
 		if (Shader is null) Shader = Rectangle.DefaultShader[Window.Context];
-		int pos = Points.Length - 3;
-		pos = 4;
-		
 		BufferObject = GL.GenBuffer();
-		GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
 		ArrayObject = GL.GenVertexArray();
-		GL.BindVertexArray(ArrayObject);
-		int add = 3;
-		GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
-		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);
+		Location = Location;
 		Loaded = true;
 		Window.MouseDown += Window_MouseDown;
 		Window.MouseMove += WindowOnMouseMove;
-		Location = Location;
 		Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y);
 		if (WindowLoaded is not null) WindowLoaded.Invoke(this);
 	}
@@ -212,30 +198,22 @@ public class RoundedRectangle : IRenderObject
 	public int ElementBufferObject { get; private set; }
 	public int BufferObject { get; private set; }
 	public int ArrayObject { get; private set; }
-	private float[] Points_;
 	private Vector2i size_ = new(), loc_ = new();
 
-	public float[] Points
+	private 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);
-					int add = 3;
 					GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
 					GL.BindVertexArray(ArrayObject);
-					GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
+					GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
 					GL.EnableVertexAttribArray(0);
 					GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
-					GL.BufferData(BufferTarget.ArrayBuffer, Points_.Length * sizeof(float), Points_, Hint);
+					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);
@@ -290,6 +268,7 @@ public class RoundedRectangle : IRenderObject
 			Parent.ReportSizeUpdate(this);
 			Location = Location;
 			saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
+			ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y));
 		}
 	}
 
@@ -348,9 +327,17 @@ public class RoundedRectangle : IRenderObject
 					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; } }
diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs
index 55fff57..bf4e469 100644
--- a/GraphicsManager/Objects/TabControl.cs
+++ b/GraphicsManager/Objects/TabControl.cs
@@ -1,6 +1,7 @@
 using GraphicsManager.Enums;
 using GraphicsManager.Interfaces;
 using GraphicsManager.Objects.Core;
+using OpenTK.Graphics.OpenGL4;
 using OpenTK.Mathematics;
 using OpenTK.Windowing.Common;
 using SixLabors.ImageSharp.Processing;
@@ -126,6 +127,7 @@ public class TabControl : IRenderObject, IParent
     public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; }
     public Vector2i Distance { get => _bounds.Distance; internal 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
@@ -226,6 +228,7 @@ public class TabControl : IRenderObject, IParent
     	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++)
@@ -241,18 +244,25 @@ public class TabControl : IRenderObject, IParent
     	if (WindowLoaded is not null) WindowLoaded.Invoke(this);
     }
 
-    public void Draw()
+    public void Draw(int x, int y, int w, int h)
     {
     	if (Loaded && Visible)
     	{
-    		_bounds.Draw();
+    		_bounds.Draw(x,y,w,h);
             if (!(Controls.Length >= (PageIndex))) return;
             if (!Controls[PageIndex].Loaded) return;
-            Controls[PageIndex].Draw();
+            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();
+	            Buttonts[i].Draw(x,y,w,h);
         }
     }
+    
+    public Vector2i GetParentRelLocPoint()
+    {
+	    return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
+    }
 
     public void Clean()
     {
diff --git a/GraphicsManager/Objects/Textbox.cs b/GraphicsManager/Objects/Textbox.cs
index 23002a6..c144216 100755
--- a/GraphicsManager/Objects/Textbox.cs
+++ b/GraphicsManager/Objects/Textbox.cs
@@ -1,8 +1,10 @@
 using System.Timers;
+using System.Timers;
 using GraphicsManager.Enums;
 using GraphicsManager.Interfaces;
 using GraphicsManager.Objects.Core;
 using OpenTK.Graphics.GL;
+using OpenTK.Graphics.OpenGL4;
 using OpenTK.Mathematics;
 using OpenTK.Windowing.Common;
 using OpenTK.Windowing.GraphicsLibraryFramework;
@@ -153,13 +155,34 @@ public class Textbox : IRenderObject
 		_watermark.Clean();
 	}
 
-	public void Draw()
+	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();
-		_inside.Draw();
-		if (!string.IsNullOrEmpty(_label.Text)) _label.Draw();
-		else _watermark.Draw();
+		_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);
+			Console.WriteLine(_inside.Location.Y);
+			Console.WriteLine($"x:{l.Value.X} y:{l.Value.Y} xx:{s.Value.X} yy:{s.Value.Y}");
+			l = new(l.Value.X, 0);
+			s = new(s.Value.X, Window.Size.Y);
+		}
+		GL.Disable(EnableCap.ScissorTest);
+		GL.Enable(EnableCap.ScissorTest);
+		GL.Scissor(l.Value.X,
+			l.Value.Y,
+			s.Value.X,
+			s.Value.Y
+			);
+		if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(x,y,w,h);
+		else _watermark.Draw(x,y,w,h);
 	}
 
 	public void LoadToParent(IParent Parent, Window Window)
@@ -171,6 +194,7 @@ public class Textbox : IRenderObject
 		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);
diff --git a/GraphicsManager/Objects/TitleBar.cs b/GraphicsManager/Objects/TitleBar.cs
new file mode 100644
index 0000000..7f133a7
--- /dev/null
+++ b/GraphicsManager/Objects/TitleBar.cs
@@ -0,0 +1,13 @@
+using GraphicsManager.Interfaces;
+
+namespace GraphicsManager.Objects;
+
+public class TitleBar
+{
+    public bool Loaded { get; private set; } = false;
+
+    public void Draw()
+    {
+        
+    }
+}
\ No newline at end of file
diff --git a/GraphicsManager/Objects/UserControl.cs b/GraphicsManager/Objects/UserControl.cs
index fb129bb..fbcb67f 100755
--- a/GraphicsManager/Objects/UserControl.cs
+++ b/GraphicsManager/Objects/UserControl.cs
@@ -1,6 +1,7 @@
 using GraphicsManager.Enums;
 using GraphicsManager.Interfaces;
 using GraphicsManager.Objects.Core;
+using OpenTK.Graphics.OpenGL4;
 using OpenTK.Mathematics;
 using OpenTK.Windowing.Common;
 
@@ -92,6 +93,7 @@ public class UserControl : IRenderObject, IParent
 			BlockDraw = false;
 		}
 	}
+	public Vector2i ScissorLocation { get => _bounds.ScissorLocation; }
 
 	public Vector2i Position => Location;
 	public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; }
@@ -123,11 +125,12 @@ public class UserControl : IRenderObject, IParent
 		if (WindowLoaded is not null) WindowLoaded.Invoke(this);
 	}
 
-	public void Draw()
+	public void Draw(int x, int y, int w, int h)
 	{
 		if (Loaded)
 		{
-			_bounds.Draw();
+			_bounds.Draw(x,y,w,h);
+			
 			IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
 
 			if (needload.Any())
@@ -142,11 +145,25 @@ public class UserControl : IRenderObject, IParent
 			}
 			for (int i = 0; i < Controls.Length; i++)
 			{
-				Controls[i].Draw();
+				Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y);
+				Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y);
+				if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y);
+				if (laff.X < x) laff = new(x, laff.Y);
+				if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y);
+				if (laff.Y < y) laff = new(laff.X, y);
+				if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y);
+				if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y);
+				GL.Scissor(laff.X, laff.Y, saff.X, saff.Y);
+				Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y);
 			}
 		}
 	}
 
+	public Vector2i GetParentRelLocPoint()
+	{
+		return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y));
+	}
+
 	public void Clean()
 	{
 		for (int i = 0; i < Controls.Length; i++)
diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs
index 4f6cc84..bd12fd1 100755
--- a/GraphicsManager/Window.cs
+++ b/GraphicsManager/Window.cs
@@ -15,15 +15,21 @@ public class Window : NativeWindow , IParent
 {
 	protected override void Dispose(bool disposing)
 	{
-		for (int i = 0; i < Controls.Length; i++)
-		{
-			Controls[i].Clean();
-		}
-		Context.MakeNoneCurrent();
 		base.Dispose(disposing);
 	}
 
 	public TextureManager TextureManager { get; private set; }
+	private TitleBar? _tb = null;
+
+	public TitleBar? CustomeTitleBar
+	{
+		get => _tb;
+		set
+		{
+			_tb = value;
+			//some setting/changeing code
+		}
+	}
 
 	internal IRenderObject? focused;
 	public void CenterWindow(int mon)
@@ -51,15 +57,50 @@ public class Window : NativeWindow , IParent
 	{
 		TextureManager = TextureManager.GetTextureManager(Context);
 		Context.MakeCurrent();
-		Texture.TextureShader.Add(Context, new("RectangleTexture", true));
-		Objects.Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
-		Label.DefaultTextShader.Add(Context, new("Label", true));
-		Label._characters.Add(Context, new());
+		if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
+		if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
+		if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
+		if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());
+		last = WindowState;
+		KeyDown += OnKeyDownn;
 	}
 
-	public Window() : base(new NativeWindowSettings())
+private WindowState last;
+private bool fs = false;
+private Vector2i os, loc;
+private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj)
+{
+	if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return;
+	GLFW.WindowHint(WindowHintBool.AutoIconify, true);
+	if (WindowState != WindowState.Normal) last = WindowState;
+	Console.WriteLine(fs);
+	switch (fs)
 	{
+		case false:
+			loc = Location;
+			os = Size;
+			WindowBorder = WindowBorder.Hidden;
+			Location = new(4090, 0);
+			fs = true;
+			break;
+		case true:
+			WindowBorder = WindowBorder.Resizable;
+			
+			Size = os;
+			Location = loc;
+			fs = false;
+			break;
+	}
+}
+
+	public Window() : this(new NativeWindowSettings())
+	{
+		/*
 		TextureManager = TextureManager.GetTextureManager(Context);
+		if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true));
+		if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true));
+		if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true));
+		if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/
 	}
 	public Vector2i Position { get; } = new Vector2i(0, 0);
 	public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255);
@@ -147,9 +188,10 @@ public class Window : NativeWindow , IParent
 
 	public void ParentResize(ResizeEventArgs e)
 	{
-		if (e.Width == 0 && e.Height == 0) return;
-		BlockDraw = true;
 		base.OnResize(e);
+		if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
+		BlockDraw = true;
+		
 		GL.Viewport(0, 0, e.Width, e.Height);
 		for (int i = 0; i < Controls.Length; i++)
 		{
@@ -189,6 +231,7 @@ public class Window : NativeWindow , IParent
 
 	protected override void OnClosing(CancelEventArgs e)
 	{
+		Context.MakeCurrent();
 		GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 		GL.BindVertexArray(0);
 		GL.UseProgram(0);
@@ -204,6 +247,12 @@ public class Window : NativeWindow , IParent
 
 	public int FPS { get; set; } = 0;
 	public event Func<Window, Task>? WindowLoaded;
+	public List<Window> Windows = new();
+
+	public void ProcessEvent()
+	{
+		ProcessEvents();
+	}
 	public void StartRender()
 	{
 		Context.MakeCurrent();
@@ -214,6 +263,13 @@ public class Window : NativeWindow , IParent
 		while (Exists && IsVisible && !IsExiting)
 		{
 			GLFW.PollEvents();
+			if (Windows.Any())
+			{
+				foreach (var win in Windows)
+				{
+					win.ProcessEvent();
+				}
+			}
 			if (invokes.Any())
 			{
 				for (int i = 0; i < invokes.Count; i++) invokes.Dequeue().Invoke();
@@ -222,6 +278,12 @@ public class Window : NativeWindow , IParent
 		}
 	}
 
+	public void StartRenderAsync()
+	{
+		Thread t = new Thread(_ => StartRender());
+		t.Start();
+	}
+
 	public bool BlockDraw { get; set; } = false;
 
 	public void TryDraw()
@@ -245,12 +307,19 @@ public class Window : NativeWindow , IParent
 	{
 		invokes.Enqueue(A);
 	}
+	
+	public Vector2i GetParentRelLocPoint()
+	{
+		return new(0);
+	}
 
 	public void DrawFrame()
 	{
 		Context.MakeCurrent();
 		frame++;
 		Console.WriteLine($"Drawing Frame: {frame}");
+		GL.Enable(EnableCap.ScissorTest);
+		GL.Scissor(0, 0, Size.X, Size.Y);
 		GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, (BackgroundColor.A * -1) + 1);
 		IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
 		
@@ -263,11 +332,26 @@ public class Window : NativeWindow , IParent
 			}
 			BlockDraw = false;
 		}
+		
 		GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 		for (int i = 0; i < Controls.Length; i++)
 		{
-			if (Controls[i].Loaded) Controls[i].Draw();
+			if (!Controls[i].Loaded) continue;
+			GL.Disable(EnableCap.ScissorTest);
+			if (Controls[i] is not Label)
+			{
+				GL.Enable(EnableCap.ScissorTest);
+				GL.Scissor(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y, Controls[i].Size.X, Controls[i].Size.Y);
+				Controls[i].Draw(0,0,Size.X, Size.Y);
+			}
+			else
+			{
+				GL.Enable(EnableCap.ScissorTest);
+				GL.Scissor(0, 0, Size.X, Size.Y);
+				Controls[i].Draw(0,0,Size.X, Size.Y);
+			}
 		}
+		GL.Disable(EnableCap.ScissorTest);
 		Context.SwapBuffers();
 		
 	}