further changes, lazy loading, new modular backend system
This commit is contained in:
parent
c0e0c30eb8
commit
c0dd04127c
68 changed files with 735 additions and 2865 deletions
|
@ -1,5 +1,5 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {corlib = "*", corlib = "*"}
|
Dependencies = {corlib = "*", corlib = "*", Bofa = "*", raylib-beef = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "TheaterGui"
|
Name = "TheaterGui"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Projects = {TheaterGui = {Path = "."}, examples = {Path = "examples"}}
|
Projects = {TheaterGui = {Path = "."}, examples = {Path = "examples"}, Bofa = {Path = "deps/Bofa"}, raylib-beef = {Path = "deps/Raylib/raylib-beef"}, raylib-backend = {Path = "raylib-backend"}}
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "examples"
|
StartupProject = "examples"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {corlib = "*", TheaterGui = "*"}
|
Dependencies = {corlib = "*", TheaterGui = "*", raylib-backend = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "examples"
|
Name = "examples"
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Box : Container
|
|
||||||
{
|
|
||||||
public this() : base("Box")
|
|
||||||
{
|
|
||||||
//Add ui items here via AddChild() and terminate the row via EndRow()
|
|
||||||
Margin = 5;
|
|
||||||
|
|
||||||
AddChild(new Checkb());
|
|
||||||
AddChild(new Radios());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class StandartButton : Button
|
|
||||||
{
|
|
||||||
public this() : base("Basic Button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LButton : LargeButton
|
|
||||||
{
|
|
||||||
public this() : base("Large Button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CButton : NButton
|
|
||||||
{
|
|
||||||
public this() : base(400, 50, "Custom sized button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Checkb : Checkbox
|
|
||||||
{
|
|
||||||
public this() : base("Check me!")
|
|
||||||
{
|
|
||||||
Checked = true;
|
|
||||||
Description = "Beef is awesome";
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void OnCheck(bool checkValue)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class ExampleToolbar : Toolbar
|
|
||||||
{
|
|
||||||
public this() : base("Toolbar")
|
|
||||||
{
|
|
||||||
AddToolbarCategories(
|
|
||||||
new .("Help",
|
|
||||||
new .("Version", new => PrintVersion)
|
|
||||||
),
|
|
||||||
|
|
||||||
new .("About",
|
|
||||||
new .("TheaterGui", new => PrintAbout),
|
|
||||||
new .("Booklordofthedings", new => PrintAbout)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrintVersion()
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine("1.0");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrintAbout()
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine("""
|
|
||||||
TheaterGui by Booklordofthedings
|
|
||||||
A simple easy to use gui library for tools
|
|
||||||
""");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class HorSlider : HSlider
|
|
||||||
{
|
|
||||||
public this() : base("HorSlider")
|
|
||||||
{
|
|
||||||
//Use the thing above to set the length of the bar
|
|
||||||
Min = 0;
|
|
||||||
Max = 100;
|
|
||||||
Value = 50;
|
|
||||||
ReactToValueChange = true; //This indicates wether OnValueChange gets actually called
|
|
||||||
Description = "A default horizontal slider";
|
|
||||||
|
|
||||||
MarginTop = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnValueChange(float newVal)
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine(Value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class MainScreen : Screen
|
|
||||||
{
|
|
||||||
public this() : base("MainScreen")
|
|
||||||
{
|
|
||||||
//Add ui items here via AddChild() and terminate the row via EndRow()
|
|
||||||
AddChild(new ExampleToolbar());
|
|
||||||
|
|
||||||
AddChild(new Label("Changing the width allows you to see these buttons reordered"));
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new StandartButton());
|
|
||||||
AddChild(new LButton());
|
|
||||||
AddChild(new CButton());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new HorSlider());
|
|
||||||
AddChild(new VertSlider());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
|
|
||||||
AddChild(new Box());
|
|
||||||
AddChild(new Box());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class OpenButton : IconButton
|
|
||||||
{
|
|
||||||
public this() : base("OpenButton")
|
|
||||||
{
|
|
||||||
Icon = .Icon_Folder; //Use this to set the icon sprite
|
|
||||||
Margin = 5;
|
|
||||||
MarginTop = 40;
|
|
||||||
MarginBottom = 40;
|
|
||||||
Description = "Open a file dialogue";
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,34 @@
|
||||||
namespace examples;
|
namespace examples;
|
||||||
|
|
||||||
using TheaterGui;
|
using TheaterGui;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
App.Run<MainScreen>("Example Gui",1920,1080);
|
scope App()
|
||||||
|
..SetName("TheaterGui Application")
|
||||||
|
..SetStartingSize(1280, 720)
|
||||||
|
..SetPlatformLayer(new raylib_backend.PlatformRaylib())
|
||||||
|
.Run(new MainScreen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MainScreen : Container
|
||||||
|
{
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
AddChild("Main Button", new Button());
|
||||||
|
AddChild("Other Button", new Button());
|
||||||
|
|
||||||
|
|
||||||
|
Layout = new (val, width) =>
|
||||||
|
{
|
||||||
|
val.Component("Main Button", 5);
|
||||||
|
val.Component("Other Button", 10);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Radios : RadioButton
|
|
||||||
{
|
|
||||||
public this() : base("Radios")
|
|
||||||
{
|
|
||||||
|
|
||||||
Description = "";
|
|
||||||
//Use SetBoxes(int, params StringView) to set the elements of the radio buttons
|
|
||||||
SetBoxes(3, "Windows", "Linux", "Mac", "Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
//React to the check event, or use the Checked field to get the value directly
|
|
||||||
public override void OnCheck(int32 value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class VertSlider : VSlider
|
|
||||||
{
|
|
||||||
public this() : base("VertSlider")
|
|
||||||
{
|
|
||||||
//Use the thing above to set the length of the bar
|
|
||||||
Min = 0;
|
|
||||||
Max = 100;
|
|
||||||
Value = 50;
|
|
||||||
ReactToValueChange = true; //This indicates wether OnValueChange gets actually called
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnValueChange(float newVal)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
7
raylib-backend/BeefProj.toml
Normal file
7
raylib-backend/BeefProj.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
FileVersion = 1
|
||||||
|
Dependencies = {corlib = "*", raylib-beef = "*", TheaterGui = "*"}
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "raylib-backend"
|
||||||
|
TargetType = "BeefLib"
|
||||||
|
StartupObject = "raylib_backend.Program"
|
45
raylib-backend/src/Platform_Raylib.bf
Normal file
45
raylib-backend/src/Platform_Raylib.bf
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
namespace raylib_backend;
|
||||||
|
|
||||||
|
using TheaterGui;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
class PlatformRaylib : IPlatformLayer
|
||||||
|
{
|
||||||
|
private RenderTexture2D _ScreenTexture;
|
||||||
|
private TextureManager _TextureManager;
|
||||||
|
private Color _BackgroundColor = Raylib.WHITE;
|
||||||
|
private Dictionary<String, Font> _LoadedFonts = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||||
|
private static uint8[?] _Texture_WindowIcon = Compiler.ReadBinary("../assets/64.png");
|
||||||
|
|
||||||
|
|
||||||
|
public void Initialize(StringView pWindowTitle, int32 pWidth, int32 pHeight)
|
||||||
|
{
|
||||||
|
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
||||||
|
String title = scope .(pWindowTitle);
|
||||||
|
Raylib.InitWindow(pWidth, pHeight, title);
|
||||||
|
Raylib.SetExitKey(0);
|
||||||
|
Raylib.SetWindowMinSize(640, 360);
|
||||||
|
Raylib.SetTargetFPS(40);
|
||||||
|
|
||||||
|
var icon = Raylib.LoadImageFromMemory(".png", (.)&_Texture_WindowIcon, _Texture_WindowIcon.Count);
|
||||||
|
Raylib.SetWindowIcon(icon);
|
||||||
|
Raylib.UnloadImage(icon);
|
||||||
|
|
||||||
|
_ScreenTexture = Raylib.LoadRenderTexture(Raylib.GetRenderWidth(), Raylib.GetRenderHeight());
|
||||||
|
_TextureManager = new .();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deinitialize()
|
||||||
|
{
|
||||||
|
for(var i in _LoadedFonts)
|
||||||
|
Raylib.UnloadFont(i.value);
|
||||||
|
Raylib.UnloadRenderTexture(_ScreenTexture);
|
||||||
|
delete _TextureManager;
|
||||||
|
}
|
||||||
|
}
|
31
raylib-backend/src/Platform_Raylib/Conversion.bf
Normal file
31
raylib-backend/src/Platform_Raylib/Conversion.bf
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
namespace raylib_backend;
|
||||||
|
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
extension PlatformRaylib
|
||||||
|
{
|
||||||
|
///Converts a TGColor into a raylib compatible color
|
||||||
|
private Color Convert(color pColor)
|
||||||
|
{
|
||||||
|
return .(pColor.Red, pColor.Green, pColor.Blue, pColor.Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Convert a TGRect into a raylib compatible rectangle
|
||||||
|
private Rectangle Convert(rect pRect)
|
||||||
|
{
|
||||||
|
return .(pRect.x, pRect.y, pRect.width, pRect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float[2] Convert(Vector2 pVector)
|
||||||
|
{
|
||||||
|
return .(pVector.x, pVector.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector2 Convert(int32[2] pValues)
|
||||||
|
{
|
||||||
|
return .(pValues[0], pValues[1]);
|
||||||
|
}
|
||||||
|
}
|
95
raylib-backend/src/Platform_Raylib/Drawing.bf
Normal file
95
raylib-backend/src/Platform_Raylib/Drawing.bf
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
namespace raylib_backend;
|
||||||
|
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
extension PlatformRaylib
|
||||||
|
{
|
||||||
|
public void StartDrawing()
|
||||||
|
{
|
||||||
|
Raylib.BeginDrawing();
|
||||||
|
Raylib.ClearBackground(_BackgroundColor);
|
||||||
|
Raylib.BeginTextureMode(_ScreenTexture);
|
||||||
|
Raylib.ClearBackground(_BackgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopDrawing()
|
||||||
|
{
|
||||||
|
Raylib.EndTextureMode();
|
||||||
|
Raylib.DrawTexturePro(
|
||||||
|
_ScreenTexture.texture,
|
||||||
|
.(0, 0, _ScreenTexture.texture.width, -_ScreenTexture.texture.height),
|
||||||
|
.(0, 0, Raylib.GetScreenWidth(), Raylib.GetScreenHeight()),
|
||||||
|
.(0, 0),
|
||||||
|
0,
|
||||||
|
Raylib.WHITE
|
||||||
|
);
|
||||||
|
Raylib.EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RedrawLastFrame()
|
||||||
|
{
|
||||||
|
Raylib.BeginDrawing();
|
||||||
|
Raylib.ClearBackground(_BackgroundColor);
|
||||||
|
Raylib.DrawTexturePro(
|
||||||
|
_ScreenTexture.texture,
|
||||||
|
.(0, 0, _ScreenTexture.texture.width, -_ScreenTexture.texture.height),
|
||||||
|
.(0, 0, Raylib.GetScreenWidth(), Raylib.GetScreenHeight()),
|
||||||
|
.(0, 0),
|
||||||
|
0,
|
||||||
|
Raylib.WHITE
|
||||||
|
);
|
||||||
|
Raylib.EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeBackgroundColor(color pTint)
|
||||||
|
{
|
||||||
|
_BackgroundColor = Convert(pTint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadTexture(Span<uint8> pData, StringView pName)
|
||||||
|
{
|
||||||
|
_TextureManager.[Friend]LoadAsset(pData, pName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawTexture(StringView pName, rect pTarget, color pTints)
|
||||||
|
{
|
||||||
|
if(_TextureManager.GetAsset(pName) case .Ok(let val))
|
||||||
|
{
|
||||||
|
Raylib.DrawTexturePro(
|
||||||
|
*val.Source,
|
||||||
|
val.SourceRect,
|
||||||
|
Convert(pTarget),
|
||||||
|
.(0,0), 0,
|
||||||
|
Convert(pTints)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Raylib.DrawRectangle(pTarget.x, pTarget.y, pTarget.width, pTarget.height, Raylib.PINK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32[2] MeasureTextureSize(StringView pName)
|
||||||
|
{
|
||||||
|
if(_TextureManager.GetAsset(pName) case .Ok(let val))
|
||||||
|
{
|
||||||
|
return .(val.Width, val.Height);
|
||||||
|
}
|
||||||
|
return .(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawColorRect(rect pTarget, color pTint)
|
||||||
|
{
|
||||||
|
Raylib.DrawRectangleRec(Convert(pTarget), Convert(pTint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawColorRectOutlined(rect pTarget, color pTint, color pOutlineTint)
|
||||||
|
{
|
||||||
|
Raylib.DrawRectangleRec(Convert(pTarget), Convert(pTint));
|
||||||
|
Raylib.DrawRectangleLinesEx(Convert(pTarget), 1, Convert(pOutlineTint));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
raylib-backend/src/Platform_Raylib/Input.bf
Normal file
31
raylib-backend/src/Platform_Raylib/Input.bf
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
namespace raylib_backend;
|
||||||
|
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
extension PlatformRaylib
|
||||||
|
{
|
||||||
|
public bool ShouldClose() => Raylib.WindowShouldClose();
|
||||||
|
public float[2] MousePosition() => Convert(Raylib.GetMousePosition());
|
||||||
|
public float[2] MouseDelta() => Convert(Raylib.GetMouseDelta());
|
||||||
|
public bool MouseLeftClick() => Raylib.IsMouseButtonDown(0);
|
||||||
|
public bool MouseRightClick() => Raylib.IsMouseButtonDown(1);
|
||||||
|
public float MouseWheel() => Raylib.GetMouseWheelMoveV().y;
|
||||||
|
|
||||||
|
public int32[2] ScreenSize()
|
||||||
|
{
|
||||||
|
int32[2] ScreenSize = .();
|
||||||
|
ScreenSize[0] = Raylib.GetScreenWidth();
|
||||||
|
ScreenSize[1] = Raylib.GetScreenHeight();
|
||||||
|
|
||||||
|
//The size of the render texture is also automatically changed to always fit
|
||||||
|
if(ScreenSize[0] != _ScreenTexture.texture.width || ScreenSize[1] != _ScreenTexture.texture.height)
|
||||||
|
{
|
||||||
|
Raylib.UnloadRenderTexture(_ScreenTexture);
|
||||||
|
_ScreenTexture = Raylib.LoadRenderTexture(ScreenSize[0], ScreenSize[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ScreenSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
42
raylib-backend/src/Platform_Raylib/Text.bf
Normal file
42
raylib-backend/src/Platform_Raylib/Text.bf
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
namespace raylib_backend;
|
||||||
|
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
extension PlatformRaylib
|
||||||
|
{
|
||||||
|
|
||||||
|
public void LoadFont(Span<uint8> pData, StringView pName, uint8 pFontSize)
|
||||||
|
{
|
||||||
|
var font = Raylib.LoadFontFromMemory(".ttf", (.)pData.Ptr, (.)pData.Length, pFontSize, null, 256);
|
||||||
|
if(_LoadedFonts.ContainsKeyAlt<StringView>(pName))
|
||||||
|
{
|
||||||
|
Raylib.UnloadFont(_LoadedFonts[scope .(pName)]);
|
||||||
|
_LoadedFonts[scope .(pName)] = font;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_LoadedFonts.Add(new .(pName), font);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawText(StringView pText, StringView pFont, int32[2] pPosition, color pTint)
|
||||||
|
{
|
||||||
|
if(_LoadedFonts.GetValue(scope .(pFont)) case .Ok(let val))
|
||||||
|
Raylib.DrawTextEx(val, scope String(pText), Convert(pPosition), val.baseSize, 1, Convert(pTint));
|
||||||
|
else
|
||||||
|
Raylib.DrawText(scope String(pText), pPosition[0], pPosition[1], 10, Raylib.PINK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32[2] MeasureTextSize(StringView pText, StringView pFont)
|
||||||
|
{
|
||||||
|
if(_LoadedFonts.GetValue(scope .(pFont)) case .Ok(let val))
|
||||||
|
{
|
||||||
|
var res = Raylib.MeasureTextEx(val, scope String(pText), val.baseSize, 1);
|
||||||
|
return .((.)res.x, (.)res.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return .(Raylib.MeasureText(scope String(pText), 10), 10);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,40 +1,14 @@
|
||||||
namespace TheaterGui;
|
namespace raylib_backend;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
|
||||||
class Textures
|
class TextureManager
|
||||||
{
|
{
|
||||||
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
|
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
|
||||||
private List<RenderTexture> _Textures = new .() ~ delete _;
|
private List<RenderTexture> _Textures = new .() ~ delete _;
|
||||||
|
|
||||||
public this()
|
|
||||||
{
|
|
||||||
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSize, null, 256);
|
|
||||||
Theme.FontSmall = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeSmall, null, 256);
|
|
||||||
Theme.FontLarge = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeLarge, null, 256);
|
|
||||||
|
|
||||||
LoadAsset(Theme.Texture_Button, "button");
|
|
||||||
LoadAsset(Theme.Texture_NButton, "n_button");
|
|
||||||
LoadAsset(Theme.Texture_SquareButton, "square_button");
|
|
||||||
LoadAsset(Theme.Texture_LargeButton, "large_button");
|
|
||||||
LoadAsset(Theme.Texture_Checkbox, "checkbox");
|
|
||||||
LoadAsset(Theme.Texture_Checkbox_Checked, "checkbox_checked");
|
|
||||||
LoadAsset(Theme.Horizontal_Patch, "horizontal_patch");
|
|
||||||
LoadAsset(Theme.Dropdown, "dropdown");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LoadAsset(Theme.Texture_TheaterIcon, "theater_icon");
|
|
||||||
LoadAsset(Theme.Texture_FolderIcon, "folder_icon");
|
|
||||||
sprite.Icon_Folder = GetAsset("folder_icon");
|
|
||||||
sprite.Icon_Theater = GetAsset("theater_icon");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
|
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||||
|
|
||||||
///Attempt to get a existing asset by StringView
|
///Attempt to get a existing asset by StringView
|
||||||
|
@ -164,10 +138,6 @@ struct sprite
|
||||||
public int32 Height = 0;
|
public int32 Height = 0;
|
||||||
public float Rotation = 0;
|
public float Rotation = 0;
|
||||||
|
|
||||||
public static sprite Icon_Folder;
|
|
||||||
public static sprite Icon_Theater;
|
|
||||||
|
|
||||||
|
|
||||||
public void Render(float x, float y, Color color = Raylib.WHITE)
|
public void Render(float x, float y, Color color = Raylib.WHITE)
|
||||||
{
|
{
|
||||||
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
|
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
|
294
src/App.bf
294
src/App.bf
|
@ -1,263 +1,53 @@
|
||||||
namespace TheaterGui;
|
namespace TheaterGui;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
using internal TheaterGui;
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
/*
|
private String _Name = new .("TheaterGui Program") ~ delete _;
|
||||||
There are two ways to run TheaterGui.
|
private int32[2] _StartingSize = .(1280, 720);
|
||||||
Either full, by using the Run function or by manually calling the functions in Run.
|
private IPlatformLayer _Platform = null ~ delete _;
|
||||||
This way you can integrate TheaterGui into other raylib applications of your choice.
|
private colorScheme _Scheme = .DefaultScheme;
|
||||||
|
private theme _Theme = .();
|
||||||
|
|
||||||
Components are supposed to be created via inheritance for each individual component, except some very simple exeptions (Labels, Placeholders)
|
public Result<void> Run(Container pScreen)
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
//For hover items
|
|
||||||
private static List<Popup> _Popups = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
private static Vector2 _OldPos = .(0, 0);
|
|
||||||
private static double _MovTime = 0;
|
|
||||||
private static String _HoverText = new .() ~ delete _;
|
|
||||||
private static Vector2 _OldSize = .(0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
public static Textures Textures ~ delete _; //All loaded textures
|
|
||||||
public static Component Selected; //Currently selected component
|
|
||||||
public static bool AllowReorder = true;
|
|
||||||
|
|
||||||
|
|
||||||
private static Screen _CurrentScreen = null ~ delete _;
|
|
||||||
public static Screen CurrentScreen
|
|
||||||
{
|
{
|
||||||
get => _CurrentScreen;
|
if(_Platform == null)
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_CurrentScreen != null)
|
|
||||||
delete _CurrentScreen;
|
|
||||||
_CurrentScreen = value;
|
|
||||||
_CurrentScreen.Reorder(Width);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///Window width
|
|
||||||
public static int32 Width
|
|
||||||
{
|
|
||||||
get => Raylib.GetRenderWidth();
|
|
||||||
set => Raylib.SetWindowSize(value, Raylib.GetRenderHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Window height
|
|
||||||
public static int32 Height
|
|
||||||
{
|
|
||||||
get => Raylib.GetRenderHeight();
|
|
||||||
set => Raylib.SetWindowSize(Raylib.GetRenderWidth(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Mouse position
|
|
||||||
public static Vector2 Mouse
|
|
||||||
{
|
|
||||||
get => Raylib.GetMousePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Mouse wheel offset
|
|
||||||
public static float Wheel
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static bool _ShouldClose;
|
|
||||||
public static bool ShouldClose
|
|
||||||
{
|
|
||||||
public get
|
|
||||||
{
|
|
||||||
return _ShouldClose || Raylib.WindowShouldClose();
|
|
||||||
}
|
|
||||||
public set => _ShouldClose = value;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///Run TheaterGui (Use for fully independent programs)
|
|
||||||
///@param pName Name of the window
|
|
||||||
///@param pWidth Width of the window
|
|
||||||
///@param pHeight Height of the window
|
|
||||||
///@param pStartScreen The starting Screen of the application
|
|
||||||
public static void Run<T>(StringView pName, int32 pWidth, int32 pHeight) where T : Screen
|
|
||||||
{
|
|
||||||
InitializeRaylib(pName, pWidth, pHeight);
|
|
||||||
InitializeGui<T>();
|
|
||||||
|
|
||||||
#if BF_PLATFORM_WASM
|
|
||||||
WebAssembly.emscripten_set_main_loop(=> ProcessDrawFrame, 40, 1);
|
|
||||||
///Afaik the infinite loop means, that the deinitialization functionality will not be called,
|
|
||||||
///but that should be fine for wasm since it fully cleans up when you exit the page.
|
|
||||||
///If we dont do it calls the deinitialization directly afterwards
|
|
||||||
#else
|
|
||||||
while (!App.ShouldClose)
|
|
||||||
ProcessDrawFrame();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DeinitializeGui();
|
|
||||||
DeinitializeRaylib();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Initializes the raylib enviroment
|
|
||||||
///@param pName Name of the window
|
|
||||||
///@param pWidth Width of the window
|
|
||||||
///@param pHeight Height of the window
|
|
||||||
public static void InitializeRaylib(StringView pName, int32 pWidth, int32 pHeight)
|
|
||||||
{
|
|
||||||
//Default raylib settings
|
|
||||||
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
|
||||||
Raylib.InitWindow(pWidth, pHeight, scope String(pName));
|
|
||||||
Raylib.SetExitKey(0);
|
|
||||||
#if !BF_PLATFORM_WASM ///Otherwise raylib sleeps and delays browser responsiveness
|
|
||||||
Raylib.SetTargetFPS(40); //Should be a resonable framerate for gui apps
|
|
||||||
#endif
|
|
||||||
Raylib.SetWindowMinSize(640, 360);
|
|
||||||
|
|
||||||
///Set the default window icon
|
|
||||||
var icon = Raylib.LoadImageFromMemory(".png", (.)&Theme.Texture_WindowIcon, Theme.Texture_WindowIcon.Count);
|
|
||||||
Raylib.SetWindowIcon(icon);
|
|
||||||
Raylib.UnloadImage(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Initialize the gui enviroment
|
|
||||||
public static void InitializeGui<T>() where T : Screen
|
|
||||||
{
|
|
||||||
Textures = new .();
|
|
||||||
CurrentScreen = new T();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Cleanup the gui enviroment
|
|
||||||
public static void DeinitializeGui() => void();
|
|
||||||
|
|
||||||
|
|
||||||
///Cleanup the raylib enviroment
|
|
||||||
public static void DeinitializeRaylib() => void();
|
|
||||||
|
|
||||||
|
|
||||||
///To be called by emscripten
|
|
||||||
private static void ProcessDrawFrame()
|
|
||||||
{
|
|
||||||
ProcessFrame();
|
|
||||||
Raylib.BeginDrawing();
|
|
||||||
Raylib.ClearBackground(Theme.Background);
|
|
||||||
DrawFrame();
|
|
||||||
Raylib.EndDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Process the logic for a single frame of the application
|
|
||||||
public static void ProcessFrame()
|
|
||||||
{
|
|
||||||
|
|
||||||
Vector2 newSize = .(Width, Height);
|
|
||||||
if (_OldSize != newSize)
|
|
||||||
{
|
|
||||||
CurrentScreen.Reorder((.)newSize.x);
|
|
||||||
_OldSize = newSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
Input.HandleScrolling(Raylib.GetMouseWheelMove());
|
|
||||||
|
|
||||||
if (Raylib.IsMouseButtonPressed(0))
|
|
||||||
Input.HandleLeftClick();
|
|
||||||
else if (Raylib.IsMouseButtonDown(0))
|
|
||||||
Input.HandleLeftDown();
|
|
||||||
else if (Raylib.IsMouseButtonPressed(1))
|
|
||||||
Input.HandleRightClick();
|
|
||||||
else
|
|
||||||
Input.HandleHover();
|
|
||||||
|
|
||||||
if(Selected != null)
|
|
||||||
Selected.WhileSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Draw the current state of the application
|
|
||||||
public static void DrawFrame()
|
|
||||||
{
|
|
||||||
//Drawing logic
|
|
||||||
CurrentScreen.Render((.)Wheel);
|
|
||||||
|
|
||||||
for (var i in _Popups)
|
|
||||||
i.Render((.)Wheel);
|
|
||||||
|
|
||||||
if (!_HoverText.IsEmpty)
|
|
||||||
{
|
|
||||||
RenderHoverText();
|
|
||||||
_HoverText.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenderHoverText()
|
|
||||||
{
|
|
||||||
int32 yOffset = 0;
|
|
||||||
int32 xOffset = 0;
|
|
||||||
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.FontSmall, _HoverText, Theme.FontSizeSmall, 0);
|
|
||||||
|
|
||||||
if (Mouse.x < Width / 2) //Render the textbox to the right of the cursor
|
|
||||||
xOffset = 15;
|
|
||||||
else //Render the textbox to the left of the cursor
|
|
||||||
xOffset = (.)(-1 * measure.x) - 15;
|
|
||||||
if (Mouse.y < Height / 2) //Render the textbox at the y location of the cursor
|
|
||||||
yOffset = 0;
|
|
||||||
else //Render the textbox offset so, that the textbox y ends at the y location of the cursor
|
|
||||||
yOffset = (.)(-1 * measure.y);
|
|
||||||
|
|
||||||
//BoxShadow
|
|
||||||
//Box
|
|
||||||
//BoxBorder
|
|
||||||
//BoxContent
|
|
||||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset + 3, (.)Mouse.y - 3 + yOffset + 3, (.)measure.x + 6, (.)measure.y + 3, Color(0, 0, 0, 70));
|
|
||||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Color(218, 211, 176, 255));
|
|
||||||
Raylib.DrawRectangleLines((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Raylib.BLACK);
|
|
||||||
Raylib.DrawTextEx(Theme.FontSmall, _HoverText, Raymath.Vector2Add(Mouse, Vector2(xOffset, yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void ForceReorder()
|
|
||||||
{
|
|
||||||
if (AllowReorder && CurrentScreen != null)
|
|
||||||
CurrentScreen.Reorder(Width);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void OpenPopup(Popup popup)
|
|
||||||
{
|
|
||||||
_Popups.Add(popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Result<Popup> GetTopmostPopup()
|
|
||||||
{
|
|
||||||
if(_Popups.Count < 1)
|
|
||||||
return .Err;
|
return .Err;
|
||||||
return .Ok(_Popups[^1]);
|
|
||||||
}
|
var runtime = new TGRuntime();
|
||||||
}
|
runtime.[Friend]Launch(_Platform, pScreen, _Name, _StartingSize[0], _StartingSize[1], _Scheme, _Theme);
|
||||||
|
delete runtime;
|
||||||
|
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetName(StringView pName)
|
||||||
|
{
|
||||||
|
_Name.Clear();
|
||||||
|
_Name.Append(pName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStartingSize(int32 pWidth, int32 pHeight)
|
||||||
|
{
|
||||||
|
if(pWidth > 0 || pHeight > 0)
|
||||||
|
return;
|
||||||
|
_StartingSize[0] = pWidth;
|
||||||
|
_StartingSize[1] = pHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPlatformLayer(IPlatformLayer pPlatformLayer)
|
||||||
|
{
|
||||||
|
delete _Platform;
|
||||||
|
_Platform = pPlatformLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetColorScheme(colorScheme pScheme) => _Scheme = pScheme;
|
||||||
|
public void SetUITheme(theme pTheme) => _Theme = pTheme;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,55 +1,51 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Button : Component
|
class Button : Component
|
||||||
{
|
{
|
||||||
public this(StringView pLabel, StringView pComponentName = "Button") : base(pComponentName, pLabel)
|
private bool _Hovered = false;
|
||||||
|
private bool _AlreadyHovered = false;
|
||||||
|
|
||||||
|
public String Label ~ delete _;
|
||||||
|
|
||||||
|
public this(StringView pName = "Button")
|
||||||
{
|
{
|
||||||
Sprite = App.Textures.GetAsset("button");
|
Label = new .(pName);
|
||||||
Width = Sprite.Width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ClickAction(); //What happends when its clicked
|
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||||
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
{
|
||||||
_IsHovered = true;
|
if(_Hovered != _AlreadyHovered)
|
||||||
return this;
|
{
|
||||||
|
_Hovered = _AlreadyHovered;
|
||||||
|
rt.Dirty();
|
||||||
|
}
|
||||||
|
_AlreadyHovered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
{
|
{
|
||||||
if(Rectangle(X, Y, Width, Height).Overlaps(x, y))
|
rt.Platform.DrawTexture("Button", rect, rt.Scheme.PrimaryColor);
|
||||||
|
if(_Hovered)
|
||||||
|
rt.Platform.DrawTexture("Button", rect, rt.Scheme.HoverColor);
|
||||||
|
|
||||||
|
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||||
|
rt.Platform.DrawText(Label, "Font_Normal",
|
||||||
|
.((.)(rect.x + 0.5*rect.width - tsize[0]*0.5),
|
||||||
|
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5))
|
||||||
|
,rt.Scheme.TextColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||||
{
|
{
|
||||||
if(Enabled)
|
return rt.Platform.MeasureTextureSize("Button");
|
||||||
|
}
|
||||||
|
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||||
{
|
{
|
||||||
ClickAction();
|
_AlreadyHovered = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(!Enabled)
|
|
||||||
{
|
|
||||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
}
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Checkbox : Component
|
|
||||||
{
|
|
||||||
public sprite SpriteChecked;
|
|
||||||
|
|
||||||
public bool Checked = false;
|
|
||||||
|
|
||||||
public abstract void OnCheck(bool checkValue);
|
|
||||||
|
|
||||||
public this(StringView pName) : base("Checkbox", pName)
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("checkbox");
|
|
||||||
SpriteChecked = App.Textures.GetAsset("checkbox_checked");
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, Theme.FontSize, 0);
|
|
||||||
Width = Sprite.Width + (.)measure.x + 2;
|
|
||||||
Height = measure.y > Sprite.Height ? (.)measure.y : Sprite.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_IsHovered = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
Checked = !Checked;
|
|
||||||
OnCheck(Checked);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
if(!Checked)
|
|
||||||
Sprite.Render(X,Y + soy,Tint);
|
|
||||||
else
|
|
||||||
SpriteChecked.Render(X,Y + soy,Tint);
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(X + Sprite.Width + 2, (.)(Y + Sprite.Height/2 - 0.5*measure.y) + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +1,11 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
using System;
|
using TheaterGui.Core.Structs;
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Component
|
abstract class Component
|
||||||
{
|
{
|
||||||
public this(StringView pComponentName, StringView pLabel)
|
public abstract void Update(TGRuntime rt);
|
||||||
{
|
public abstract void Draw(TGRuntime rt, rect rect);
|
||||||
ComponentType = pComponentName;
|
public abstract int32[2] Resize(TGRuntime rt, int32 width);
|
||||||
Label = pLabel;
|
public abstract bool OnHover(TGRuntime rt, int32[2] mPos);
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Fields
|
|
||||||
///
|
|
||||||
public Container Parent;
|
|
||||||
public bool Enabled = true;
|
|
||||||
|
|
||||||
public Color Tint = Theme.Tint;
|
|
||||||
public Color HoverTint = Theme.HoverTint;
|
|
||||||
public sprite Sprite;
|
|
||||||
|
|
||||||
public int32 MarginTop = 0;
|
|
||||||
public int32 MarginBottom = 0;
|
|
||||||
public int32 MarginLeft = 0;
|
|
||||||
public int32 MarginRight = 0;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Properties
|
|
||||||
///
|
|
||||||
public bool Selected
|
|
||||||
{ //When something is selected its allowed to update every frame
|
|
||||||
get;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Selected = value;
|
|
||||||
App.Selected = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 Margin
|
|
||||||
{
|
|
||||||
//There seems to be no reasonable way to implement a getter here
|
|
||||||
set
|
|
||||||
{
|
|
||||||
MarginTop = value;
|
|
||||||
MarginBottom = value;
|
|
||||||
MarginLeft = value;
|
|
||||||
MarginRight = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int32 _X = 0;
|
|
||||||
public int32 X
|
|
||||||
{
|
|
||||||
get => _X;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_X = value;
|
|
||||||
} //You may set this, but it might fuck up layouting
|
|
||||||
};
|
|
||||||
|
|
||||||
private int32 _Y = 0;
|
|
||||||
public int32 Y
|
|
||||||
{
|
|
||||||
get => _Y;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_Y = value;
|
|
||||||
} //You may set this, but it might fuck up layouting
|
|
||||||
};
|
|
||||||
|
|
||||||
public int32 Width
|
|
||||||
{
|
|
||||||
public get;
|
|
||||||
protected set; //Please do not
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 Height
|
|
||||||
{
|
|
||||||
public get;
|
|
||||||
protected set; //Please do not
|
|
||||||
}
|
|
||||||
|
|
||||||
[DynamicString] //What this type of component is called
|
|
||||||
private String _ComponentType = new .() ~ delete _;
|
|
||||||
[DynamicString] //What the component says on it when rendered
|
|
||||||
private String _Label = null ~ delete _;
|
|
||||||
[DynamicString] //Usually only used by the OnHover tooltip
|
|
||||||
private String _Description = null ~ delete _;
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Functions
|
|
||||||
///
|
|
||||||
public abstract void Render(int32 soy);
|
|
||||||
|
|
||||||
public virtual bool OnClick(int32 x, int32 y) => false;
|
|
||||||
public virtual void OnRightClick(int32 x, int32 y, Toolbar.ToolbarCategory items) {}
|
|
||||||
public virtual bool HandleScrollEvent(float scroll, int32 x, int32 y) {return false;};
|
|
||||||
public virtual bool OnDown(int32 x, int32 y) => false;
|
|
||||||
public abstract Component OnHover(int32 x, int32 y);
|
|
||||||
|
|
||||||
public virtual void WhileSelected() { }
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,195 +1,80 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
class Container : Component
|
abstract class Container : Component
|
||||||
{
|
{
|
||||||
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
|
protected Dictionary<String, Component> _Children = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||||
|
protected List<rect> _Drawings = new .() ~ delete _;
|
||||||
|
|
||||||
|
public delegate void(Layout, int32 width) Layout = null ~ delete _;
|
||||||
|
|
||||||
|
public override void Update(TGRuntime rt)
|
||||||
{
|
{
|
||||||
|
for(var i in _Children)
|
||||||
|
i.value.Update(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Component> _LayoutData = new .() ~ delete _;
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
|
|
||||||
public List<Component> Children = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///Recalculate the layout of all entries
|
|
||||||
public virtual void Reorder(int32 w)
|
|
||||||
{
|
{
|
||||||
/*
|
for(var i in _Drawings)
|
||||||
List<Entries> {Entry, Entry, Entry, RB, Entry, Entry, RB, Entry, RB}
|
|
||||||
null is a rowbreak while non null isnt a rowbreak
|
|
||||||
|
|
||||||
Algorithm
|
|
||||||
if the current entry is a rowbreak, reset the cursor to x = 0, y = y + height
|
|
||||||
|
|
||||||
try to fit the current entry after the cursor
|
|
||||||
if it fits add it,
|
|
||||||
if it doesnt fit break
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 maxWidth = 0; //The highest width line
|
|
||||||
int32 rowHeight = 0; //How high the current row is
|
|
||||||
int32 x = 0;
|
|
||||||
int32 y = 0;
|
|
||||||
|
|
||||||
for(var e in _LayoutData)
|
|
||||||
{
|
{
|
||||||
if(e == null)
|
if(_Children.ContainsKeyAlt<StringView>(i.name))
|
||||||
{ //Manual row break
|
_Children[scope .(i.name)].Draw(rt, i + rect);
|
||||||
x = 0;
|
}
|
||||||
y = y + rowHeight;
|
|
||||||
rowHeight = 0;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e is Container)
|
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||||
{
|
{
|
||||||
((Container)e).Reorder(w);
|
_Drawings.Clear();
|
||||||
if(x+e.Width+e.MarginLeft > w-MarginLeft) //Change both instances of padding to 2*Padding to ensure proper padding on the leftmost side of the screen
|
|
||||||
{ //Automatic row break
|
|
||||||
x = 0;
|
|
||||||
y = y + rowHeight;
|
|
||||||
rowHeight = 0;
|
|
||||||
}
|
|
||||||
MoveChildrenRecursive((Container)e, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Layout l = scope .();
|
||||||
|
l.[Friend]_RT = rt;
|
||||||
|
l.[Friend]_Children = _Children;
|
||||||
|
l.[Friend]_Drawings = _Drawings;
|
||||||
|
l.[Friend]_MaxWidth = width;
|
||||||
|
|
||||||
if(e is Toolbar)
|
Layout.Invoke(l, width);
|
||||||
e.Width = App.Width;
|
|
||||||
|
|
||||||
if(x+e.Width+e.MarginLeft > w-MarginLeft) //Change both instances of padding to 2*Padding to ensure proper padding on the leftmost side of the screen
|
int32[2] max = .(0,0);
|
||||||
{ //Automatic row break
|
for(var i in _Drawings)
|
||||||
x = 0;
|
|
||||||
y = y + rowHeight;
|
|
||||||
rowHeight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.[Friend]X = x + e.MarginLeft;
|
|
||||||
x = x + e.Width + e.MarginLeft + e.MarginRight;
|
|
||||||
e.[Friend]Y = y + e.MarginTop;
|
|
||||||
if(x > maxWidth)
|
|
||||||
maxWidth = x;
|
|
||||||
|
|
||||||
if(rowHeight < e.Height+e.MarginTop+e.MarginBottom)
|
|
||||||
rowHeight = e.Height+e.MarginTop+e.MarginBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
Width = maxWidth + MarginLeft + MarginRight;
|
|
||||||
Height = y + rowHeight + MarginTop + MarginBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MoveChildrenRecursive(Container c, int32 x, int32 y)
|
|
||||||
{
|
{
|
||||||
for(var i in c.Children)
|
if(i.width+i.x > max[0])
|
||||||
|
max[0] = i.width+i.x;
|
||||||
|
if(i.height+i.y > max[1])
|
||||||
|
max[1] = i.height+i.y;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||||
{
|
{
|
||||||
i.[Friend]X += x + MarginLeft + c.MarginLeft;
|
for(var i in _Drawings)
|
||||||
i.[Friend]Y += y + MarginTop + c.MarginTop;
|
{
|
||||||
if(i is Container)
|
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||||
MoveChildrenRecursive((Container)i, x, y);
|
{
|
||||||
|
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||||
|
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||||
|
{
|
||||||
|
if(component.OnHover(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///Add a new item to the list of items
|
|
||||||
public void AddChild(Component pToAdd)
|
|
||||||
{
|
|
||||||
_LayoutData.Add(pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InsertAfter(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
idx++;
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
///Forcefully terminates the current row
|
|
||||||
public void EndRow() => _LayoutData.Add(null);
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
for(var i in Children)
|
|
||||||
i.Render(soy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
|
||||||
return e.OnClick(x, y);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnDown(int32 x, int32 y)
|
public Result<void> AddChild(StringView pName, Component pComponent)
|
||||||
{
|
{
|
||||||
for(var e in Children)
|
if(_Children.ContainsKeyAlt<StringView>(pName))
|
||||||
{
|
return .Err;
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
_Children.Add(new .(pName), pComponent);
|
||||||
return e.OnDown(x, y);
|
return .Ok;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
|
||||||
return e.OnHover(x, y);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HandleScrollEvent(float scroll, int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
|
||||||
return e.HandleScrollEvent(scroll, x, y);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnRightClick(int32 x, int32 y, Toolbar.ToolbarCategory items)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
|
||||||
e.OnRightClick(x, y, items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Dropdown : Component
|
|
||||||
{
|
|
||||||
public List<String> Entries = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
public uint32 SelectedEntry = 0;
|
|
||||||
|
|
||||||
public this() : base("Dropdown", "Label")
|
|
||||||
{
|
|
||||||
Margin = 20;
|
|
||||||
Sprite = App.Textures.GetAsset("dropdown");
|
|
||||||
Width = Sprite.Width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Entries[(.)SelectedEntry], Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Entries[(.)SelectedEntry], Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(!Enabled)
|
|
||||||
{
|
|
||||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
}
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
var list = new List<StringView>(Entries.Count);
|
|
||||||
defer delete list;
|
|
||||||
for(var i in Entries)
|
|
||||||
list.Add(i);
|
|
||||||
var popup = new DropdownPopup(X, Y + Height, Width, list);
|
|
||||||
popup.Owner = this;
|
|
||||||
App.OpenPopup(popup);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void ClickAction(String pNewVal);
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_IsHovered = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class DropdownPopup : Popup
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public int32 SelectedItem = -1;
|
|
||||||
public Dropdown Owner = null;
|
|
||||||
public List<String> Options = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, int32 w, params Span<StringView> options) : base("DropdownPopup", "DropdownPopup")
|
|
||||||
{
|
|
||||||
this.[Friend]X = x;
|
|
||||||
this.[Friend]Y = y-1;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
for(var i in options)
|
|
||||||
Options.Add(new .(i));
|
|
||||||
Width = w;
|
|
||||||
Height = ((.)Options.Count * (Theme.FontSize+10))-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, int32 w, List<StringView> options) : base("DropdownPopup", "DropdownPopup")
|
|
||||||
{
|
|
||||||
this.[Friend]X = x;
|
|
||||||
this.[Friend]Y = y-1;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
for(var i in options)
|
|
||||||
Options.Add(new .(i));
|
|
||||||
Width = w;
|
|
||||||
Height = ((.)Options.Count * (Theme.FontSize+10))-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 y = 5;
|
|
||||||
for(var i in Options)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(i), Vector2(X + 5, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(@i.Index == SelectedItem)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + y - 4 + soy, Width, Theme.FontSize+10),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += (.)Theme.FontSize+5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Options)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)Theme.FontSize+5)
|
|
||||||
{
|
|
||||||
if(Owner != null)
|
|
||||||
{
|
|
||||||
Owner.SelectedEntry = (.)@i.Index;
|
|
||||||
Owner.ClickAction(i);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pos += (.)Theme.FontSize+5;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Options)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)Theme.FontSize+5)
|
|
||||||
{
|
|
||||||
SelectedItem = (.)@i.Index;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
pos += (.)Theme.FontSize+5;
|
|
||||||
}
|
|
||||||
SelectedItem = -1;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnClose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
abstract class HSlider : NHSlider
|
|
||||||
{
|
|
||||||
public this(StringView pLabel) : base(32 * 6, pLabel, "HSlider")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
abstract class IconButton : Button
|
|
||||||
{
|
|
||||||
public sprite Icon = App.Textures.GetAsset("folder_icon");
|
|
||||||
|
|
||||||
|
|
||||||
public this(StringView pName) : base(pName, "SquareButton")
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("square_button");
|
|
||||||
Width = Sprite.Width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
|
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
|
||||||
Icon.Render(X+Width/2-Icon.Width/2+2,Y+Height/2-Icon.Height/2+2 + soy, .(0,0,0,125));
|
|
||||||
Icon.Render(X+Width/2-Icon.Width/2,Y+Height/2-Icon.Height/2 + soy);
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
_IsHovered = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class InputField : Component
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public String InputContent = new .() ~ delete _;
|
|
||||||
|
|
||||||
|
|
||||||
String text = new .() ~ delete _;
|
|
||||||
public this(StringView pLabel) : base("InputField", pLabel)
|
|
||||||
{
|
|
||||||
Label = "Test Data";
|
|
||||||
Sprite = App.Textures.GetAsset("n_button");
|
|
||||||
Width = 128 * 2;
|
|
||||||
Height = 32;
|
|
||||||
Margin = 10;
|
|
||||||
Tint = Theme.Background;
|
|
||||||
PatchInfo = .(Sprite.SourceRect, 7, 7, 7, 7, (.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
}
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0, 0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
|
|
||||||
if (_IsHovered || App.Selected == this)
|
|
||||||
Raylib.DrawTextureNPatch(*Sprite.Source, PatchInfo, Rectangle(X, Y + soy, Width, Height), Vector2(0, 0), 0, Theme.Tint.SetAlpha(120));
|
|
||||||
_IsHovered = false;
|
|
||||||
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, text, Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, text, Vector2(X + 7, Y + Height / 2 - measure.y / 2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_IsHovered = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
App.Selected = this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WhileSelected()
|
|
||||||
{
|
|
||||||
int key = Raylib.GetCharPressed();
|
|
||||||
while (key > 0)
|
|
||||||
{
|
|
||||||
// NOTE: Only allow keys in range [32..125]
|
|
||||||
if ((key >= 32) && (key <= 125) && (text.Length < 100))
|
|
||||||
text.Append((char8)key);
|
|
||||||
|
|
||||||
key = Raylib.GetCharPressed(); // Check next character in the queue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Raylib.IsKeyPressed((.)KeyboardKey.KEY_BACKSPACE))
|
|
||||||
text.RemoveFromEnd(1);
|
|
||||||
if(Raylib.IsKeyPressed((.)KeyboardKey.KEY_ESCAPE))
|
|
||||||
App.Selected = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class Label : Component
|
|
||||||
{
|
|
||||||
private Vector2 _Measure;
|
|
||||||
public this(StringView pName) : base(Label, pName)
|
|
||||||
{
|
|
||||||
Label = pName;
|
|
||||||
Margin = 3;
|
|
||||||
_Measure = Raylib.MeasureTextEx(Theme.FontLarge, Label.Ptr, Theme.FontSizeLarge, 0);
|
|
||||||
Height = (.)_Measure.y;
|
|
||||||
Width = (.)_Measure.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y) => null;
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, Vector2(X,Y + soy), Theme.FontSizeLarge, 0, Theme.Text);
|
|
||||||
Raylib.DrawLine(X,Y + (.)_Measure.y + soy,X + (.)_Measure.x, Y + (.)_Measure.y + soy, Theme.Text);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class LargeButton : Button
|
|
||||||
{
|
|
||||||
public this(StringView pName) : base(pName, "LargeButton")
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("large_button");
|
|
||||||
Width = Sprite.Width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Label.Ptr, Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class NButton : Button
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
|
|
||||||
public this(int32 w, int32 h, StringView pName) : base(pName, "NButton")
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("n_button");
|
|
||||||
Width = w;
|
|
||||||
Height = h;
|
|
||||||
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 7,7,7,7,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
|
|
||||||
if(!Enabled)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Theme.DisabledTint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_IsHovered)
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
//This slider may be any size
|
|
||||||
abstract class NHSlider : Component
|
|
||||||
{
|
|
||||||
private bool _CurrentlyDragged = false; //Used to stop accidental hovers
|
|
||||||
public int32 BarWidth = 0;
|
|
||||||
public float Percentage = 0;
|
|
||||||
public float Min = 0;
|
|
||||||
public float Max = 0;
|
|
||||||
public float Value
|
|
||||||
{
|
|
||||||
get => Min + Percentage * (Max-Min);
|
|
||||||
set => Percentage = (value - Min)/(Max-Min); //This should be mathematically fine, no clue if its actually fine though
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReactToValueChange = false; //Calling on value change too frequently might not be good so we clear here
|
|
||||||
public virtual void OnValueChange(float newVal)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 width, StringView pLabel, StringView pTypename = "NHSlider") : base(pTypename, pLabel)
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("checkbox");
|
|
||||||
Width = width + Sprite.Width;
|
|
||||||
BarWidth = width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawRectangle(X + Sprite.Width/2, Y + Sprite.Height/2 - 4 + soy, BarWidth, 8, Raylib.BLACK);
|
|
||||||
Sprite.Render((.)(X+ Percentage * BarWidth), Y + soy, Tint);
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render((.)(X +Percentage * BarWidth), Y + soy, HoverTint);
|
|
||||||
_IsHovered = false;
|
|
||||||
|
|
||||||
if(!Raylib.IsMouseButtonDown(0))
|
|
||||||
_CurrentlyDragged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_CurrentlyDragged = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnDown(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(_CurrentlyDragged)
|
|
||||||
{
|
|
||||||
float np = 0;
|
|
||||||
np = x - X;
|
|
||||||
np = Math.Clamp(np, Sprite.Width/2, Width - Sprite.Width/2); //Not rly clamp
|
|
||||||
np -= Sprite.Width/2;
|
|
||||||
np = np / (BarWidth); //I fucking hate that this works
|
|
||||||
|
|
||||||
float oldp = Percentage;
|
|
||||||
Percentage = np;
|
|
||||||
if(ReactToValueChange && oldp != Percentage)
|
|
||||||
OnValueChange(Min + np * (Max-Min));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_IsHovered = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
//This slider may be any size
|
|
||||||
abstract class NVSlider : Component
|
|
||||||
{
|
|
||||||
private bool _CurrentlyDragged = false; //Used to stop accidental hovers
|
|
||||||
public int32 BarHeight = 0;
|
|
||||||
public float Percentage = 0;
|
|
||||||
public float Min = 0;
|
|
||||||
public float Max = 0;
|
|
||||||
public float Value
|
|
||||||
{
|
|
||||||
get => Min + Percentage * (Max-Min);
|
|
||||||
set => Percentage = (value - Min)/(Max-Min); //This should be mathematically fine, no clue if its actually fine though
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReactToValueChange = false; //Calling on value change too frequently might not be good so we clear here
|
|
||||||
public virtual void OnValueChange(float newVal)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 height, StringView pLabel, StringView pTypeName = "NVSlider") : base(pTypeName, pLabel)
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("checkbox");
|
|
||||||
Width = Sprite.Width;
|
|
||||||
BarHeight = height;
|
|
||||||
Height = Sprite.Height + height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawRectangle(X + Sprite.Width/2 - 4, Y + Sprite.Height/2 + soy, 8, BarHeight, Raylib.BLACK);
|
|
||||||
Sprite.Render(X, Y + soy + Percentage * BarHeight, Tint);
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X, Y + soy + Percentage * BarHeight, HoverTint);
|
|
||||||
_IsHovered = false;
|
|
||||||
|
|
||||||
if(!Raylib.IsMouseButtonDown(0))
|
|
||||||
_CurrentlyDragged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_CurrentlyDragged = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnDown(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(_CurrentlyDragged)
|
|
||||||
{
|
|
||||||
float np = 0;
|
|
||||||
np = y - Y;
|
|
||||||
np = Math.Clamp(np, Sprite.Height/2, Height - Sprite.Height/2); //Not rly clamp
|
|
||||||
np -= Sprite.Height/2;
|
|
||||||
np = np / (BarHeight); //I fucking hate that this works
|
|
||||||
|
|
||||||
float oldp = Percentage;
|
|
||||||
Percentage = np;
|
|
||||||
if(ReactToValueChange && oldp != Percentage)
|
|
||||||
OnValueChange(Min + np * (Max-Min));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
_IsHovered = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
class Placeholder : Component
|
|
||||||
{
|
|
||||||
public this(int32 w, int32 h) : base("Placeholder", "Placeholder")
|
|
||||||
{
|
|
||||||
Width = w;
|
|
||||||
Height = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y) => null;
|
|
||||||
public override void Render(int32 soy) {}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
abstract class Popup : Component
|
|
||||||
{
|
|
||||||
public this(System.StringView pComponentName, System.StringView pLabel) : base(pComponentName, pLabel)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
///When something force closes the popup
|
|
||||||
public abstract void OnClose();
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
abstract class RadioButton : Container
|
|
||||||
{
|
|
||||||
public int32 Checked = -1;
|
|
||||||
|
|
||||||
public this(StringView pName) : base(pName, "RadioButtons")
|
|
||||||
{
|
|
||||||
Description = pName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnCheck(int32 value)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
///Set all of the fields to be used as checkboxes
|
|
||||||
public void SetBoxes(int32 selectedIndex, params Span<StringView> args)
|
|
||||||
{
|
|
||||||
Checked = selectedIndex;
|
|
||||||
//Clear out old ones
|
|
||||||
this.[Friend]_LayoutData.ClearAndDeleteItems();
|
|
||||||
Children.Clear();
|
|
||||||
|
|
||||||
for(var i in args)
|
|
||||||
{
|
|
||||||
var toAdd = new RadioCheckbox(i);
|
|
||||||
toAdd.Description = Description;
|
|
||||||
if(@i.Index == selectedIndex)
|
|
||||||
toAdd.Checked = true;
|
|
||||||
AddChild(toAdd);
|
|
||||||
EndRow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectButton(RadioCheckbox toSelect)
|
|
||||||
{
|
|
||||||
for(var i in Children)
|
|
||||||
if(i == toSelect)
|
|
||||||
{
|
|
||||||
((RadioCheckbox)i).Checked = true;
|
|
||||||
Checked = (.)@i.Index;
|
|
||||||
OnCheck((.)@i.Index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
((RadioCheckbox)i).Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RadioCheckbox : Checkbox
|
|
||||||
{
|
|
||||||
public this(StringView pName) : base(pName)
|
|
||||||
{
|
|
||||||
Margin = 2;
|
|
||||||
}
|
|
||||||
public override void OnCheck(bool checkValue)
|
|
||||||
{
|
|
||||||
((RadioButton)Parent).SelectButton(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
class RightClickPopup : Popup
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public Toolbar.ToolbarCategory.ToolbarItem SelectedItem = null;
|
|
||||||
|
|
||||||
private Toolbar.ToolbarCategory _Category = null ~ delete _;
|
|
||||||
public Toolbar.ToolbarCategory Category
|
|
||||||
{
|
|
||||||
get => _Category;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_Category = value;
|
|
||||||
int32 maxWidth = 0;
|
|
||||||
for(var i in _Category.Items)
|
|
||||||
if(maxWidth <= i.NameMeasurement.x)
|
|
||||||
maxWidth = (.)i.NameMeasurement.x;
|
|
||||||
|
|
||||||
Width = maxWidth + 10 + 20;
|
|
||||||
Height = (.)(5 +((_Category.NameMeasurement.y + 5) * _Category.Items.Count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, Toolbar.ToolbarCategory category) : base("ToolbarPopup", category.Name)
|
|
||||||
{
|
|
||||||
this.[Friend]X = x;
|
|
||||||
this.[Friend]Y = y-1;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
Category = category;
|
|
||||||
if(x+Width > App.Width)
|
|
||||||
this.[Friend]X -= Width;
|
|
||||||
if(y+Height > App.Height)
|
|
||||||
this.[Friend]Y -= Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 y = 5;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), Vector2(X + 5, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(SelectedItem == i)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
{
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
SelectedItem = i;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
if(i.ClickAction != null)
|
|
||||||
i.ClickAction();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnClose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
using TheaterGui;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
/*
|
|
||||||
While containers are sized depending on their parent, screens are sized depending on the user
|
|
||||||
*/
|
|
||||||
class Screen : Container
|
|
||||||
{
|
|
||||||
public this(StringView pName) : base(pName, "Screen")
|
|
||||||
{
|
|
||||||
this.Width = Raylib.GetRenderWidth();
|
|
||||||
this.Height = Raylib.GetRenderHeight();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class ScrollableContainer : Container
|
|
||||||
{
|
|
||||||
public int32 ContainerHeight = 0;
|
|
||||||
public float Scroll = 0;
|
|
||||||
|
|
||||||
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Component> _LayoutData = new .() ~ delete _;
|
|
||||||
///Recalculate the layout of all entries
|
|
||||||
public override void Reorder(int32 w)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
List<Entries> {Entry, Entry, Entry, RB, Entry, Entry, RB, Entry, RB}
|
|
||||||
null is a rowbreak while non null isnt a rowbreak
|
|
||||||
|
|
||||||
Algorithm
|
|
||||||
if the current entry is a rowbreak, reset the cursor to x = 0, y = y + height
|
|
||||||
|
|
||||||
try to fit the current entry after the cursor
|
|
||||||
if it fits add it,
|
|
||||||
if it doesnt fit break
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 maxWidth = 0; //The highest width line
|
|
||||||
int32 rowHeight = 0; //How high the current row is
|
|
||||||
int32 x = 0;
|
|
||||||
int32 y = 0;
|
|
||||||
|
|
||||||
for(var e in _LayoutData)
|
|
||||||
{
|
|
||||||
if(e == null)
|
|
||||||
{ //Manual row break
|
|
||||||
x = 0;
|
|
||||||
y = y + rowHeight;
|
|
||||||
rowHeight = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e is Container)
|
|
||||||
{
|
|
||||||
((Container)e).Reorder(w);
|
|
||||||
MoveChildrenRecursive((Container)e, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e is Toolbar)
|
|
||||||
e.Width = App.Width;
|
|
||||||
|
|
||||||
if(x+e.Width+e.MarginLeft > w-MarginLeft) //Change both instances of padding to 2*Padding to ensure proper padding on the leftmost side of the screen
|
|
||||||
{ //Automatic row break
|
|
||||||
x = 0;
|
|
||||||
y = y + rowHeight;
|
|
||||||
rowHeight = 0;
|
|
||||||
}
|
|
||||||
e.[Friend]X = x + e.MarginLeft;
|
|
||||||
x = x + e.Width + e.MarginLeft + e.MarginRight;
|
|
||||||
e.[Friend]Y = y + e.MarginTop;
|
|
||||||
if(x > maxWidth)
|
|
||||||
maxWidth = x;
|
|
||||||
|
|
||||||
if(rowHeight < e.Height+e.MarginTop+e.MarginBottom)
|
|
||||||
rowHeight = e.Height+e.MarginTop+e.MarginBottom;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Width = maxWidth + MarginLeft + MarginRight;
|
|
||||||
Height = y + rowHeight + MarginTop + MarginBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MoveChildrenRecursive(Container c, int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var i in c.Children)
|
|
||||||
{
|
|
||||||
i.[Friend]X += x + MarginLeft + c.MarginLeft;
|
|
||||||
i.[Friend]Y += y + MarginTop + c.MarginTop;
|
|
||||||
if(i is Container)
|
|
||||||
MoveChildrenRecursive((Container)i, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Add a new item to the list of items
|
|
||||||
public new void AddChild(Component pToAdd)
|
|
||||||
{
|
|
||||||
_LayoutData.Add(pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InsertAfter(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
idx++;
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
///Forcefully terminates the current row
|
|
||||||
public new void EndRow() => _LayoutData.Add(null);
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.BeginScissorMode(X, Y + soy, Width, Height);
|
|
||||||
for(var i in Children)
|
|
||||||
i.Render((.)(soy + Scroll));
|
|
||||||
Raylib.EndScissorMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
|
||||||
return e.OnClick(x, (.)(y - Scroll));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnDown(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
|
||||||
return e.OnDown(x, (.)(y - Scroll));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
|
||||||
return e.OnHover(x, (.)(y - Scroll));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnRightClick(int32 x, int32 y, Toolbar.ToolbarCategory items)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
|
||||||
e.OnRightClick(x, (.)(y - Scroll), items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HandleScrollEvent(float scroll, int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
|
||||||
if(e.HandleScrollEvent(scroll, x, (.)(y - Scroll)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scroll += scroll;
|
|
||||||
Scroll = Math.Clamp(Scroll,-(Height-ContainerHeight),0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Toolbar : Component
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public List<ToolbarCategory> Categories = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
private ToolbarPopup _CurrentPopup = null;
|
|
||||||
private ToolbarCategory _SelectedPopup = null;
|
|
||||||
|
|
||||||
public this(StringView pLabel) : base("Toolbar", pLabel)
|
|
||||||
{
|
|
||||||
Height = 24;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 x = 5;
|
|
||||||
for(var i in Categories)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), Vector2(X + x, Y + Height/2 - i.NameMeasurement.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(i == _SelectedPopup)
|
|
||||||
{
|
|
||||||
//5 padding in every direction
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X + x-5, Y + soy, i.NameMeasurement.x+10, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
|
|
||||||
x += (.)i.NameMeasurement.x + 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
int32 hor = 10;
|
|
||||||
for(var i in Categories)
|
|
||||||
{
|
|
||||||
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
|
||||||
{
|
|
||||||
var popup = new ToolbarPopup(hor-10,Height + Y, i);
|
|
||||||
popup.Owner = this;
|
|
||||||
App.OpenPopup(popup);
|
|
||||||
_CurrentPopup = popup;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
hor += (.)i.NameMeasurement.x + 10;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
int32 hor = 10;
|
|
||||||
for(var i in Categories)
|
|
||||||
{
|
|
||||||
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
|
||||||
{
|
|
||||||
_SelectedPopup = i;
|
|
||||||
|
|
||||||
if(_CurrentPopup != null && _CurrentPopup.Category != i)
|
|
||||||
{
|
|
||||||
_CurrentPopup.Category = i;
|
|
||||||
_CurrentPopup.[Friend]X = hor-10;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
hor += (.)i.NameMeasurement.x + 10;
|
|
||||||
}
|
|
||||||
_SelectedPopup = null;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddToolbarCategories(params Span<ToolbarCategory> pCategories)
|
|
||||||
{
|
|
||||||
for(var i in pCategories)
|
|
||||||
Categories.Add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
///Toolbar data is stored in here
|
|
||||||
public class ToolbarCategory
|
|
||||||
{
|
|
||||||
private String _Name = null ~ delete _;
|
|
||||||
public Vector2 NameMeasurement = .(0,0);
|
|
||||||
public StringView Name
|
|
||||||
{
|
|
||||||
public get => (_Name != null) ? _Name : default;
|
|
||||||
public set
|
|
||||||
{
|
|
||||||
String.NewOrSet!(_Name, value);
|
|
||||||
NameMeasurement = Raylib.MeasureTextEx(Theme.Font, _Name, Theme.FontSize, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(StringView pName, params Span<ToolbarItem> pItems)
|
|
||||||
{
|
|
||||||
Name = pName;
|
|
||||||
for(var i in pItems)
|
|
||||||
Items.Add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ToolbarItem
|
|
||||||
{
|
|
||||||
private String _Name = null ~ delete _;
|
|
||||||
public Vector2 NameMeasurement = .(0,0);
|
|
||||||
public StringView Name
|
|
||||||
{
|
|
||||||
public get => (_Name != null) ? _Name : default;
|
|
||||||
public set
|
|
||||||
{
|
|
||||||
String.NewOrSet!(_Name, value);
|
|
||||||
NameMeasurement = Raylib.MeasureTextEx(Theme.Font, _Name, Theme.FontSize, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(StringView pName, delegate void() pClickAction)
|
|
||||||
{
|
|
||||||
Name = pName;
|
|
||||||
ClickAction = pClickAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void() ClickAction = null ~ delete _;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ToolbarItem> Items = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class ToolbarPopup : Popup
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public Toolbar Owner = null;
|
|
||||||
public Toolbar.ToolbarCategory.ToolbarItem SelectedItem = null;
|
|
||||||
|
|
||||||
private Toolbar.ToolbarCategory _Category = null;
|
|
||||||
public Toolbar.ToolbarCategory Category
|
|
||||||
{
|
|
||||||
get => _Category;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_Category = value;
|
|
||||||
int32 maxWidth = 0;
|
|
||||||
for(var i in _Category.Items)
|
|
||||||
if(maxWidth <= i.NameMeasurement.x)
|
|
||||||
maxWidth = (.)i.NameMeasurement.x;
|
|
||||||
|
|
||||||
Width = maxWidth + 10 + 32;
|
|
||||||
Height = (.)(5 +((_Category.NameMeasurement.y + 5) * _Category.Items.Count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, Toolbar.ToolbarCategory category) : base("ToolbarPopup", category.Name)
|
|
||||||
{
|
|
||||||
this.[Friend]X = x;
|
|
||||||
this.[Friend]Y = y-1;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
Category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 y = 5;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), Vector2(X + 5 + 32, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(SelectedItem == i)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
{
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
SelectedItem = i;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
if(i.ClickAction != null)
|
|
||||||
i.ClickAction();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnClose()
|
|
||||||
{
|
|
||||||
if(Owner != null)
|
|
||||||
{
|
|
||||||
Owner.[Friend]_CurrentPopup = null;
|
|
||||||
Owner.[Friend]_SelectedPopup = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
abstract class VSlider : NVSlider
|
|
||||||
{
|
|
||||||
public this(StringView pLabel) : base(32 * 6, pLabel, "VSlider")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
64
src/Core/Layout.bf
Normal file
64
src/Core/Layout.bf
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
namespace TheaterGui.Core;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
class Layout
|
||||||
|
{
|
||||||
|
private TGRuntime _RT;
|
||||||
|
private Dictionary<String, Component> _Children;
|
||||||
|
private List<rect> _Drawings;
|
||||||
|
|
||||||
|
private int32 _X = 0;
|
||||||
|
private int32 _Y = 0;
|
||||||
|
private int32 _LineHeight = 0;
|
||||||
|
|
||||||
|
private int32 _MaxWidth = 0;
|
||||||
|
|
||||||
|
public void Linebreak(int32 padding = 0)
|
||||||
|
{
|
||||||
|
_X = 0;
|
||||||
|
_Y += _LineHeight + padding;
|
||||||
|
_LineHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Placeholder(int32 width, int32 height)
|
||||||
|
{
|
||||||
|
if(height > _LineHeight)
|
||||||
|
_LineHeight = height;
|
||||||
|
if(!(_X + width > _MaxWidth))
|
||||||
|
_X += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Component(StringView name, int32 padding) => Component(name, padding, padding, padding, padding);
|
||||||
|
public void Component(StringView name, int32 padding_top = 0, int32 padding_bottom = 0, int32 padding_left = 0, int32 padding_right = 0)
|
||||||
|
{
|
||||||
|
if(_Children.ContainsKeyAlt<StringView>(name))
|
||||||
|
{
|
||||||
|
var item = _Children[scope .(name)];
|
||||||
|
var size = item.Resize(_RT, _MaxWidth);
|
||||||
|
|
||||||
|
if(_X + size[0] + padding_left + padding_right > _MaxWidth)
|
||||||
|
{
|
||||||
|
_X = 0;
|
||||||
|
_Y += _LineHeight;
|
||||||
|
_LineHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect toAdd = .();
|
||||||
|
toAdd.name = name;
|
||||||
|
toAdd.width = size[0];
|
||||||
|
toAdd.height = size[1];
|
||||||
|
toAdd.x = _X + padding_left;
|
||||||
|
toAdd.y = _Y + padding_top;
|
||||||
|
_Drawings.Add(toAdd);
|
||||||
|
|
||||||
|
_X += size[0] + padding_left + padding_right;
|
||||||
|
if(size[1] + padding_top + padding_bottom > _LineHeight)
|
||||||
|
_LineHeight = size[1] + padding_top + padding_bottom;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
src/Core/Structs/color.bf
Normal file
38
src/Core/Structs/color.bf
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
namespace TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
|
||||||
|
struct color
|
||||||
|
{
|
||||||
|
public uint8 Red = 0;
|
||||||
|
public uint8 Green = 0;
|
||||||
|
public uint8 Blue = 0;
|
||||||
|
public uint8 Alpha = 255;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(uint8 red, uint8 green, uint8 blue, uint8 alpha = 255)
|
||||||
|
{
|
||||||
|
Red = red;
|
||||||
|
Green = green;
|
||||||
|
Blue = blue;
|
||||||
|
Alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(uint8[3] data)
|
||||||
|
{
|
||||||
|
Red = data[0];
|
||||||
|
Green = data[1];
|
||||||
|
Blue = data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(uint8[4] data)
|
||||||
|
{
|
||||||
|
Red = data[0];
|
||||||
|
Green = data[1];
|
||||||
|
Blue = data[2];
|
||||||
|
Alpha = data[3];
|
||||||
|
}
|
||||||
|
}
|
16
src/Core/Structs/colorScheme.bf
Normal file
16
src/Core/Structs/colorScheme.bf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
namespace TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
struct colorScheme
|
||||||
|
{
|
||||||
|
public color TextColor = .(216, 197, 215);
|
||||||
|
public color BackgroundColor = .(45, 45, 49);
|
||||||
|
public color PrimaryColor = .(153, 36, 72);
|
||||||
|
public color AcceptColor = .();
|
||||||
|
public color WarningColor = .();
|
||||||
|
public color ErrorColor = .();
|
||||||
|
public color DisabledColor = .(90, 90, 90, 125);
|
||||||
|
public color HoverColor = .(255, 255, 255, 50);
|
||||||
|
|
||||||
|
|
||||||
|
public static colorScheme DefaultScheme = .();
|
||||||
|
}
|
23
src/Core/Structs/rect.bf
Normal file
23
src/Core/Structs/rect.bf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
namespace TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
struct rect
|
||||||
|
{
|
||||||
|
public StringView name;
|
||||||
|
public int32 x = 0;
|
||||||
|
public int32 y = 0;
|
||||||
|
public int32 width;
|
||||||
|
public int32 height;
|
||||||
|
|
||||||
|
public static rect operator+(rect lhs, rect rhs)
|
||||||
|
{
|
||||||
|
rect toReturn = .();
|
||||||
|
toReturn.name = lhs.name;
|
||||||
|
toReturn.x = rhs.x + lhs.x;
|
||||||
|
toReturn.y = rhs.y + lhs.y;
|
||||||
|
toReturn.width = lhs.width;
|
||||||
|
toReturn.height = lhs.height;
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
}
|
25
src/Core/Structs/theme.bf
Normal file
25
src/Core/Structs/theme.bf
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
namespace TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
struct theme
|
||||||
|
{
|
||||||
|
private static uint8[?] _Theme_Font = Compiler.ReadBinary("assets/Din.ttf");
|
||||||
|
private static uint8[?] _Theme_Button = Compiler.ReadBinary("assets/button.png");
|
||||||
|
|
||||||
|
/*
|
||||||
|
private static uint8[?] Texture_SquareButton = Compiler.ReadBinary("assets/square_button.png");
|
||||||
|
private static uint8[?] Texture_LargeButton = Compiler.ReadBinary("assets/large_button.png");
|
||||||
|
private static uint8[?] Texture_NButton = Compiler.ReadBinary("assets/n_button.png");
|
||||||
|
private static uint8[?] Texture_Checkbox = Compiler.ReadBinary("assets/checkbox.png");
|
||||||
|
private static uint8[?] Texture_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png");
|
||||||
|
private static uint8[?] Horizontal_Patch = Compiler.ReadBinary("assets/horizontal_patch.png");
|
||||||
|
private static uint8[?] Dropdown = Compiler.ReadBinary("assets/dropdown.png");
|
||||||
|
*/
|
||||||
|
|
||||||
|
public (Span<uint8>, uint8) Font_Normal = (
|
||||||
|
.(&_Theme_Font, _Theme_Font.Count),
|
||||||
|
16
|
||||||
|
);
|
||||||
|
public Span<uint8> Button = .(&_Theme_Button, _Theme_Button.Count);
|
||||||
|
}
|
40
src/Core/TGRuntime.api.bf
Normal file
40
src/Core/TGRuntime.api.bf
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
namespace TheaterGui.Core;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
extension TGRuntime
|
||||||
|
{
|
||||||
|
public theme Theme;
|
||||||
|
public colorScheme Scheme;;
|
||||||
|
|
||||||
|
private List<Container> _Screens = new .() ~ DeleteContainerAndItems!(_);
|
||||||
|
|
||||||
|
private bool _ShouldClose = false;
|
||||||
|
public bool ShouldClose
|
||||||
|
{
|
||||||
|
get => _ShouldClose;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(value)
|
||||||
|
_ShouldClose = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPlatformLayer Platform
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _Dirty = true;
|
||||||
|
public void Dirty() => _Dirty = true;
|
||||||
|
|
||||||
|
public int32[2] ScreenSize
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
}
|
67
src/Core/TGRuntime.core.bf
Normal file
67
src/Core/TGRuntime.core.bf
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
namespace TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
class TGRuntime
|
||||||
|
{
|
||||||
|
private void Launch(IPlatformLayer platform, Container screen, StringView name, int32 width, int32 height, colorScheme scheme, theme theme)
|
||||||
|
{
|
||||||
|
Platform = platform;
|
||||||
|
Platform.Initialize(name, width, height);
|
||||||
|
LoadTextures(theme, scheme);
|
||||||
|
Theme = theme;
|
||||||
|
Scheme = scheme;
|
||||||
|
|
||||||
|
_Screens.Add(screen);
|
||||||
|
for(var i in _Screens)
|
||||||
|
i.Resize(this, width);
|
||||||
|
#if BF_PLATFORM_WASM
|
||||||
|
WebAssembly.emscripten_set_main_loop(=> ProcessFrame, 60, 1);
|
||||||
|
#else
|
||||||
|
while (!ShouldClose)
|
||||||
|
ProcessFrame();
|
||||||
|
#endif
|
||||||
|
platform.Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessFrame()
|
||||||
|
{
|
||||||
|
//Meta
|
||||||
|
ShouldClose = Platform.ShouldClose();
|
||||||
|
var ss = Platform.ScreenSize();
|
||||||
|
if(ss != ScreenSize)
|
||||||
|
{ //Resultion update
|
||||||
|
Dirty();
|
||||||
|
for(var i in _Screens)
|
||||||
|
i.Resize(this, ss[0]);
|
||||||
|
ScreenSize = ss;
|
||||||
|
}
|
||||||
|
var mPos = Platform.MousePosition();
|
||||||
|
_Screens[0].OnHover(this, .((.)mPos[0], (.)mPos[1]));
|
||||||
|
|
||||||
|
|
||||||
|
//Logic
|
||||||
|
for(var screen in _Screens)
|
||||||
|
screen.Update(this);
|
||||||
|
//Drawing
|
||||||
|
if(_Dirty)
|
||||||
|
{
|
||||||
|
Platform.StartDrawing();
|
||||||
|
for(var screen in _Screens)
|
||||||
|
screen.Draw(this, .() {width = ScreenSize[0], height = ScreenSize[1] });
|
||||||
|
Platform.StopDrawing();
|
||||||
|
_Dirty = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Platform.RedrawLastFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadTextures(theme pStartingTheme, colorScheme pScheme)
|
||||||
|
{
|
||||||
|
Platform.ChangeBackgroundColor(pScheme.BackgroundColor);
|
||||||
|
Platform.LoadFont(pStartingTheme.Font_Normal.0, "Font_Normal", pStartingTheme.Font_Normal.1);
|
||||||
|
Platform.LoadTexture(pStartingTheme.Button, "Button");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
namespace RaylibBeef
|
|
||||||
{
|
|
||||||
extension Rectangle
|
|
||||||
{
|
|
||||||
public bool Overlaps(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if (x >= this.x && x <= this.x + this.width)
|
|
||||||
if (y >= this.y && y <= this.y + this.height)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Color
|
|
||||||
{
|
|
||||||
public Color SetRed(uint8 red) => .(red, g, b, a);
|
|
||||||
public Color SetGreen(uint8 green) => .(r, green, b, a);
|
|
||||||
public Color SetBlue(uint8 blue) => .(r, g, blue, a);
|
|
||||||
public Color SetAlpha(uint8 alpha) => .(r, g, b, alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace System
|
|
||||||
{
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
[AttributeUsage(.Field)]
|
|
||||||
struct DynamicStringAttribute : Attribute, IOnFieldInit
|
|
||||||
{
|
|
||||||
[Comptime]
|
|
||||||
public void OnFieldInit(FieldInfo fieldInfo, Self* prev)
|
|
||||||
{
|
|
||||||
Compiler.EmitTypeBody(fieldInfo.DeclaringType, scope $"""
|
|
||||||
public StringView {fieldInfo.Name.Substring(1)}
|
|
||||||
{{
|
|
||||||
public get => {fieldInfo.Name} == null ? "" : {fieldInfo.Name}..EnsureNullTerminator();
|
|
||||||
public set => String.NewOrSet!({fieldInfo.Name}, value);
|
|
||||||
}};
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace System
|
|
||||||
{
|
|
||||||
#if BF_PLATFORM_WASM
|
|
||||||
extension WebAssembly
|
|
||||||
{
|
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
|
||||||
public static extern void emscripten_set_main_loop(function void() func, int32 fps, int32 simulateInfinteLoop);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class ButtonGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Button"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Button Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : Button
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class CheckboxGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Checkbox"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Checkbox Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : Checkbox
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void OnCheck(bool checkValue)
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class ContainerGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Container"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Container Name", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : Container
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
//Add ui items here via AddChild() and terminate the row via EndRow()
|
|
||||||
Margin = 5;
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class DropdownGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Dropdown"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Button Name", "");
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
AddEdit("content", "Entries", "Seperate entries via ';'");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var description = mParams["description"];
|
|
||||||
var entries = mParams["content"];
|
|
||||||
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class TG{name} : Dropdown
|
|
||||||
{{
|
|
||||||
public this() : base()
|
|
||||||
{{
|
|
||||||
Description = "{description}";
|
|
||||||
""");
|
|
||||||
var split = entries.Split(';');
|
|
||||||
for(var i in split)
|
|
||||||
outText.Append(scope $"\t\tEntries.Add(new .(\"{i}\"));\n");
|
|
||||||
outText.Append(scope $"""
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction(String newValue)
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class IconButtonGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Icon Button"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Button Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : IconButton
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
Icon = .Icon_Folder; //Use this to set the icon sprite
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class LargeButtonGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Large Button"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Button Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : LargeButton
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class NButtonGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> NButton"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Button Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : NButton
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
}}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class RadioButtonGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Radio Button"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Component Name", "");
|
|
||||||
AddCheckbox("enabled", "Enabled", true);
|
|
||||||
AddEdit("description", "Description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var enabled = bool.Parse(mParams["enabled"]);
|
|
||||||
var description = mParams["description"];
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : RadioButton
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
|
||||||
Description = "{description}";
|
|
||||||
//Use SetBoxes(int, params StringView) to set the elements of the radio buttons
|
|
||||||
}}
|
|
||||||
|
|
||||||
//React to the check event, or use the Checked field to get the value directly
|
|
||||||
public override void OnCheck(int32 value)
|
|
||||||
{{
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class ScreenGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Screen"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Screen Name", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : Screen
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
//Add UI items here via AddChild() and terminate the row via EndRow()
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class SliderGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Slider"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Slider Name", "");
|
|
||||||
AddCombo("orientation", "Orientation", "Horizontal", .(scope StringView[]("Horizontal", "Vertical")));
|
|
||||||
AddCheckbox("length", "Fixed Length", true);
|
|
||||||
AddEdit("min", "Minimal Value", "0");
|
|
||||||
AddEdit("max", "Maximal Value", "100");
|
|
||||||
AddEdit("dfault", "Starting Value", "50");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
var orientation = mParams["orientation"];
|
|
||||||
var fixedLength = mParams["length"];
|
|
||||||
var min = mParams["min"];
|
|
||||||
var max = mParams["max"];
|
|
||||||
var dfault = mParams["dfault"];
|
|
||||||
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : {(fixedLength == "True") ? "" : "N" }{(orientation == "Horizontal") ? "H" : "V"}Slider
|
|
||||||
{{
|
|
||||||
public this() : base({(fixedLength == "True") ? "" : "64, "}"{name}")
|
|
||||||
{{
|
|
||||||
//Use the thing above to set the length of the bar
|
|
||||||
Min = {min};
|
|
||||||
Max = {max};
|
|
||||||
Value = {dfault};
|
|
||||||
ReactToValueChange = true; //This indicates wether OnValueChange gets actually called
|
|
||||||
}}
|
|
||||||
|
|
||||||
public override void OnValueChange(float newVal)
|
|
||||||
{{
|
|
||||||
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
namespace TheaterGui.Generators;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class ToolbarGenerator : Compiler.Generator
|
|
||||||
{
|
|
||||||
public override String Name => "TheaterGui -> Toolbar"
|
|
||||||
|
|
||||||
public override void InitUI()
|
|
||||||
{
|
|
||||||
AddEdit("name", "Toolbar Name", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Generate(String outFileName, String outText, ref Flags generateFlags)
|
|
||||||
{
|
|
||||||
var name = mParams["name"];
|
|
||||||
if (name.EndsWith(".bf", .OrdinalIgnoreCase))
|
|
||||||
name.RemoveFromEnd(3);
|
|
||||||
|
|
||||||
|
|
||||||
outFileName.Append(scope $"{name}");
|
|
||||||
|
|
||||||
outText.Append(scope $"""
|
|
||||||
namespace {Namespace};
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class {name} : Toolbar
|
|
||||||
{{
|
|
||||||
public this() : base("{name}")
|
|
||||||
{{
|
|
||||||
|
|
||||||
/*
|
|
||||||
AddToolbarCategories(
|
|
||||||
new .("File",
|
|
||||||
new .("Open Recent", null)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
}
|
|
43
src/IPlatformLayer.bf
Normal file
43
src/IPlatformLayer.bf
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
namespace TheaterGui;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
interface IPlatformLayer
|
||||||
|
{
|
||||||
|
public void Initialize(StringView pWindowTitle, int32 pWidth, int32 pHeight);
|
||||||
|
public void Deinitialize();
|
||||||
|
|
||||||
|
|
||||||
|
//Drawing
|
||||||
|
public void StartDrawing();
|
||||||
|
public void StopDrawing();
|
||||||
|
public void RedrawLastFrame();
|
||||||
|
|
||||||
|
public void ChangeBackgroundColor(color pTint);
|
||||||
|
|
||||||
|
public void LoadTexture(Span<uint8> pData, StringView pName);
|
||||||
|
public void DrawTexture(StringView pName, rect pTarget, color pTint);
|
||||||
|
public int32[2] MeasureTextureSize(StringView pName);
|
||||||
|
|
||||||
|
public void DrawColorRect(rect pTarget, color pTint);
|
||||||
|
public void DrawColorRectOutlined(rect pTarget, color pTint, color pOutlineTint);
|
||||||
|
|
||||||
|
|
||||||
|
///Text
|
||||||
|
public void LoadFont(Span<uint8> pData, StringView pName, uint8 pFontSize);
|
||||||
|
public void DrawText(StringView pText, StringView pFont, int32[2] pPosition, color pTint);
|
||||||
|
public int32[2] MeasureTextSize(StringView pText, StringView pFont);
|
||||||
|
|
||||||
|
|
||||||
|
///Input
|
||||||
|
public bool ShouldClose();
|
||||||
|
|
||||||
|
public int32[2] ScreenSize();
|
||||||
|
|
||||||
|
public float[2] MousePosition();
|
||||||
|
public float[2] MouseDelta();
|
||||||
|
public bool MouseLeftClick();
|
||||||
|
public bool MouseRightClick();
|
||||||
|
public float MouseWheel();
|
||||||
|
}
|
122
src/Input.bf
122
src/Input.bf
|
@ -1,122 +0,0 @@
|
||||||
namespace TheaterGui;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Input
|
|
||||||
{
|
|
||||||
internal static void HandleScrolling(float pWheelMove)
|
|
||||||
{
|
|
||||||
var w = pWheelMove * pWheelMove * pWheelMove;
|
|
||||||
|
|
||||||
if (!App.CurrentScreen.HandleScrollEvent(w, (.)App.Mouse.x, (.)(App.Mouse.y - App.Wheel)) && App.CurrentScreen.Height - App.Height > 0)
|
|
||||||
{
|
|
||||||
App.Wheel += w;
|
|
||||||
App.Wheel = Math.Clamp(App.Wheel, -1 * (App.CurrentScreen.Height - App.Height), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void HandleLeftClick()
|
|
||||||
{
|
|
||||||
var mouse = App.Mouse;
|
|
||||||
|
|
||||||
if (App.GetTopmostPopup() case .Ok(let top))
|
|
||||||
{
|
|
||||||
if (Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps((.)mouse.x, (.)(mouse.y - App.Wheel)))
|
|
||||||
{
|
|
||||||
if (top.OnClick((.)mouse.x, (.)mouse.y))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
App.[Friend]_Popups.Remove(top);
|
|
||||||
top.OnClose(); //Any last words ?
|
|
||||||
delete top;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool a = top is DropdownPopup; //TODO: Make this less horrible
|
|
||||||
|
|
||||||
App.[Friend]_Popups.Remove(top);
|
|
||||||
top.OnClose(); //Any last words ?
|
|
||||||
delete top;
|
|
||||||
if(!a)
|
|
||||||
App.CurrentScreen.OnClick((.)mouse.x, (.)(mouse.y - App.Wheel)); //So that we dont eat any inputs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
App.CurrentScreen.OnClick((.)mouse.x, (.)(mouse.y - App.Wheel));
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void HandleRightClick()
|
|
||||||
{
|
|
||||||
//We dont stack up rightclicks
|
|
||||||
if (App.GetTopmostPopup() case .Ok(let top))
|
|
||||||
if (top is RightClickPopup)
|
|
||||||
delete App.[Friend]_Popups.GetAndRemove(top).Value;
|
|
||||||
|
|
||||||
Toolbar.ToolbarCategory popupCat = new .("Items");
|
|
||||||
App.CurrentScreen.OnRightClick((.)App.Mouse.x, (.)App.Mouse.y, popupCat);
|
|
||||||
if (popupCat.Items.Count > 0)
|
|
||||||
App.[Friend]_Popups.Add(new RightClickPopup((.)App.Mouse.x, (.)App.Mouse.y, popupCat));
|
|
||||||
else
|
|
||||||
delete popupCat;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool HandleLeftDown()
|
|
||||||
{
|
|
||||||
//Topmost first
|
|
||||||
for (var i in App.[Friend]_Popups.Reversed)
|
|
||||||
{
|
|
||||||
var hoverResult = i.OnDown(Raylib.GetMouseX(), Raylib.GetMouseY() - (.)App.Wheel);
|
|
||||||
if (hoverResult == false)
|
|
||||||
continue;
|
|
||||||
return hoverResult;
|
|
||||||
}
|
|
||||||
return App.CurrentScreen.OnDown(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - App.Wheel));
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void HandleHover()
|
|
||||||
{
|
|
||||||
Component hoverRes = HandleHoverPopups();
|
|
||||||
if (hoverRes == null)
|
|
||||||
hoverRes = HandleHoverScreen();
|
|
||||||
|
|
||||||
if (hoverRes == null)
|
|
||||||
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hoverRes.Enabled)
|
|
||||||
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_POINTING_HAND);
|
|
||||||
|
|
||||||
if (App.[Friend]_OldPos != App.Mouse)
|
|
||||||
App.[Friend]_MovTime = Raylib.GetTime();
|
|
||||||
if (Raylib.GetTime() - App.[Friend]_MovTime >= 0.5)
|
|
||||||
App.[Friend]_HoverText.Append(hoverRes.Description);
|
|
||||||
App.[Friend]_OldPos = App.Mouse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Handle the hover effect for all screen objects
|
|
||||||
private static Component HandleHoverScreen()
|
|
||||||
{
|
|
||||||
return App.CurrentScreen.OnHover(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - App.Wheel));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Checks if any popup catches the hover
|
|
||||||
private static Component HandleHoverPopups()
|
|
||||||
{
|
|
||||||
//Topmost first
|
|
||||||
for (var i in App.[Friend]_Popups.Reversed)
|
|
||||||
{
|
|
||||||
var hoverResult = i.OnHover(Raylib.GetMouseX(), Raylib.GetMouseY() - (.)App.Wheel);
|
|
||||||
if (hoverResult == null)
|
|
||||||
continue;
|
|
||||||
return hoverResult;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
namespace TheaterGui;
|
|
||||||
|
|
||||||
//Which backend does theatergui use
|
|
||||||
#define BACKEND_RAYLIB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if BACKEND_RAYLIB
|
|
||||||
using RaylibBeef;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class PlatformLayer
|
|
||||||
{
|
|
||||||
///
|
|
||||||
public static void DrawSprite()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Actually implement this
|
|
41
src/Theme.bf
41
src/Theme.bf
|
@ -1,41 +0,0 @@
|
||||||
namespace TheaterGui;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
public class Theme
|
|
||||||
{
|
|
||||||
public static Font Font ~ Raylib.UnloadFont(_);
|
|
||||||
public static Font FontSmall ~ Raylib.UnloadFont(_);
|
|
||||||
public static Font FontLarge ~ Raylib.UnloadFont(_);
|
|
||||||
|
|
||||||
public static int32 FontSize = 16;
|
|
||||||
public static int32 FontSizeLarge = 20;
|
|
||||||
public static int32 FontSizeSmall = 12;
|
|
||||||
|
|
||||||
public static Color Background = .(45, 45, 49, 255);
|
|
||||||
public static Color Tint = .(153, 36, 72, 255);
|
|
||||||
public static Color HoverTint = .(255,255,255,50); //Color overlay when an object is hovered over
|
|
||||||
public static Color DisabledTint = .(90,90,90,125);
|
|
||||||
public static Color Text = .(216, 197, 215, 255);
|
|
||||||
|
|
||||||
//Font data
|
|
||||||
public static uint8[?] Din = Compiler.ReadBinary("assets/Din.ttf");
|
|
||||||
|
|
||||||
public static uint8[?] Texture_WindowIcon = Compiler.ReadBinary("assets/64.png");
|
|
||||||
//Icons
|
|
||||||
public static uint8[?] Texture_TheaterIcon = Compiler.ReadBinary("assets/icon_theater.png");
|
|
||||||
public static uint8[?] Texture_FolderIcon = Compiler.ReadBinary("assets/icon_folder.png");
|
|
||||||
|
|
||||||
//Controls
|
|
||||||
public static uint8[?] Texture_SquareButton = Compiler.ReadBinary("assets/square_button.png");
|
|
||||||
public static uint8[?] Texture_LargeButton = Compiler.ReadBinary("assets/large_button.png");
|
|
||||||
public static uint8[?] Texture_NButton = Compiler.ReadBinary("assets/n_button.png");
|
|
||||||
public static uint8[?] Texture_Button = Compiler.ReadBinary("assets/button.png");
|
|
||||||
public static uint8[?] Texture_Checkbox = Compiler.ReadBinary("assets/checkbox.png");
|
|
||||||
public static uint8[?] Texture_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png");
|
|
||||||
public static uint8[?] Horizontal_Patch = Compiler.ReadBinary("assets/horizontal_patch.png");
|
|
||||||
public static uint8[?] Dropdown = Compiler.ReadBinary("assets/dropdown.png");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
10
src/WASM.bf
Normal file
10
src/WASM.bf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
#if BF_PLATFORM_WASM
|
||||||
|
extension WebAssembly
|
||||||
|
{
|
||||||
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
|
public static extern void emscripten_set_main_loop(function void() func, int32 fps, int32 simulateInfinteLoop);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue