Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
0f12f4359c | |||
f6c0049e78 | |||
9e7330d47c | |||
46ea31a118 | |||
c0dd04127c | |||
c0e0c30eb8 |
74 changed files with 1940 additions and 2707 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
# ---> Beef
|
||||
**/build
|
||||
**/recovery
|
||||
**/deps
|
||||
BeefSpace_User.toml
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
FileVersion = 1
|
||||
Dependencies = {corlib = "*", corlib = "*", raylib-beef = "*"}
|
||||
Dependencies = {corlib = "*", corlib = "*", Bofa = "*", raylib-beef = "*"}
|
||||
|
||||
[Project]
|
||||
Name = "TheaterGui"
|
||||
|
|
8
BeefSpace.toml
Normal file
8
BeefSpace.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
FileVersion = 1
|
||||
Projects = {TheaterGui = {Path = "."}, examples = {Path = "examples"}, Bofa = {Path = "deps/Bofa"}, raylib-beef = {Path = "deps/Raylib/raylib-beef"}, raylib-backend = {Path = "raylib-backend"}}
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "examples"
|
||||
|
||||
[Configs.Debug.Win64]
|
||||
ConfigSelections = {raylib-beef = {Config = "StaticDebug"}}
|
|
@ -1,5 +1,5 @@
|
|||
FileVersion = 1
|
||||
Dependencies = {corlib = "*", TheaterGui = "*"}
|
||||
Dependencies = {corlib = "*", TheaterGui = "*", raylib-backend = "*"}
|
||||
|
||||
[Project]
|
||||
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,74 @@
|
|||
namespace examples;
|
||||
|
||||
using System;
|
||||
|
||||
using TheaterGui;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
|
||||
class Program
|
||||
{
|
||||
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 : Screen
|
||||
{
|
||||
public this()
|
||||
{
|
||||
Toolbar toAdd = new .();
|
||||
toAdd.AddEntry("File", "Open File", new (rt) => {Console.WriteLine("Open file");});
|
||||
toAdd.AddEntry("Edit", "Go back", new (rt) => {Console.WriteLine("Go back");});
|
||||
toAdd.AddEntry("Edit", "Open File", new (rt) => {Console.WriteLine("Open File");});
|
||||
toAdd.AddEntry("Window", "Open File", new (rt) => {Console.WriteLine("Open File");});
|
||||
|
||||
|
||||
|
||||
|
||||
AddChild("Toolbar", toAdd);
|
||||
AddChild("Button", new Button(new (val) => {Console.WriteLine("Hellau :)");}));
|
||||
AddChild("dd", new Dropdown("One", "Two", "Three"));
|
||||
AddChild("Label", new Label("LMAO"));
|
||||
AddChild("CBox", new Checkbox("Box"));
|
||||
|
||||
RadioButton r = new .();
|
||||
r.Label.Add(new .("One"));
|
||||
r.Label.Add(new .("Two"));
|
||||
r.Label.Add(new .("Three"));
|
||||
AddChild("radio", r);
|
||||
AddChild("hslider", new HSlider());
|
||||
AddChild("vslider", new VSlider());
|
||||
AddChild("lb", new Label("""
|
||||
Labels can also be used to
|
||||
contain some larger text since this also
|
||||
works fine
|
||||
and without any
|
||||
issues
|
||||
"""));
|
||||
|
||||
|
||||
Layout = new (val, width) =>
|
||||
{
|
||||
val.Component("Toolbar");
|
||||
val.Component("Label", 10);
|
||||
val.Linebreak();
|
||||
val.Component("Button");
|
||||
val.Component("CBox", 5);
|
||||
val.Linebreak();
|
||||
val.Component("radio", 5);
|
||||
val.Component("hslider");
|
||||
val.Component("vslider");
|
||||
val.Component("lb");
|
||||
val.Linebreak();
|
||||
val.Component("dd", 5);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
20
pkkg
Normal file
20
pkkg
Normal file
|
@ -0,0 +1,20 @@
|
|||
#This is the pkkg template file
|
||||
l Name TheaterGui
|
||||
|
||||
t Desc A simple retained mode gui library
|
||||
|
||||
l Url https://code.booklordofthe.dev/Theater/TheaterGui
|
||||
|
||||
a Authors
|
||||
o Book
|
||||
l Name Booklordofthedings
|
||||
l Url https://Boooklordofthe.dev
|
||||
|
||||
a Dependencies
|
||||
o Bofa
|
||||
l Name Bofa
|
||||
l Url https://code.booklordofthe.dev/Booklordofthedings/Bofa.git
|
||||
l Tag 1.1.0
|
||||
o Raylib
|
||||
l Name Raylib
|
||||
l Url https://code.booklordofthe.dev/Extern/raylib-beef.git
|
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]);
|
||||
}
|
||||
}
|
134
raylib-backend/src/Platform_Raylib/Drawing.bf
Normal file
134
raylib-backend/src/Platform_Raylib/Drawing.bf
Normal file
|
@ -0,0 +1,134 @@
|
|||
namespace raylib_backend;
|
||||
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using RaylibBeef;
|
||||
|
||||
extension PlatformRaylib
|
||||
{
|
||||
public void StartDrawing()
|
||||
{
|
||||
if(Raylib.GetMouseDelta().x + Raylib.GetMouseDelta().y != 0)
|
||||
{
|
||||
if(targetFps != 40)
|
||||
{
|
||||
Raylib.SetTargetFPS(40);
|
||||
targetFps = 40;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(targetFps != 20)
|
||||
{
|
||||
Raylib.SetTargetFPS(20);
|
||||
targetFps = 20;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private int32 targetFps = 40;
|
||||
|
||||
public void RedrawLastFrame()
|
||||
{
|
||||
if(Raylib.GetMouseDelta().x + Raylib.GetMouseDelta().y != 0)
|
||||
{
|
||||
if(targetFps != 40)
|
||||
{
|
||||
Raylib.SetTargetFPS(40);
|
||||
targetFps = 40;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(targetFps != 20)
|
||||
{
|
||||
Raylib.SetTargetFPS(20);
|
||||
targetFps = 20;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
#if DEBUG
|
||||
Raylib.DrawRectangle(0,0,5,5, Raylib.PINK);
|
||||
#endif
|
||||
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.Collections;
|
||||
|
||||
using RaylibBeef;
|
||||
|
||||
class Textures
|
||||
class TextureManager
|
||||
{
|
||||
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
|
||||
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!(_);
|
||||
|
||||
///Attempt to get a existing asset by StringView
|
||||
|
@ -164,10 +138,6 @@ struct sprite
|
|||
public int32 Height = 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)
|
||||
{
|
||||
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;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
using TheaterGui.Components;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using RaylibBeef;
|
||||
|
||||
using internal TheaterGui;
|
||||
using TheaterGui.Components;
|
||||
|
||||
class App
|
||||
{
|
||||
/*
|
||||
There are two ways to run TheaterGui.
|
||||
Either full, by using the Run function or by manually calling the functions in Run.
|
||||
This way you can integrate TheaterGui into other raylib applications of your choice.
|
||||
private String _Name = new .("TheaterGui Program") ~ delete _;
|
||||
private int32[2] _StartingSize = .(1280, 720);
|
||||
private IPlatformLayer _Platform = null ~ delete _;
|
||||
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)
|
||||
*/
|
||||
|
||||
|
||||
#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
|
||||
public Result<void> Run(Screen pScreen)
|
||||
{
|
||||
get => _CurrentScreen;
|
||||
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)
|
||||
if(_Platform == null)
|
||||
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,68 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
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 _;
|
||||
delegate void(TGRuntime rt) Action ~ delete _;
|
||||
|
||||
public this(delegate void(TGRuntime rt) pAction, StringView pLabel = "Button")
|
||||
{
|
||||
Sprite = App.Textures.GetAsset("button");
|
||||
Width = Sprite.Width;
|
||||
Height = Sprite.Height;
|
||||
Label = new .(pLabel);
|
||||
Action = pAction;
|
||||
}
|
||||
|
||||
public abstract void ClickAction(); //What happends when its clicked
|
||||
|
||||
|
||||
protected bool _IsHovered = false;
|
||||
public override Component OnHover(int32 x, int32 y)
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
_IsHovered = true;
|
||||
return this;
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_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 false;
|
||||
}
|
||||
return false;
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
Action.Invoke(rt);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Render(int32 soy)
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList)
|
||||
{
|
||||
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;
|
||||
pList.Add((.)(new String(scope $"Click {Label}"), new (rt) => {this.Action.Invoke(rt);}));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,49 +1,73 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using RaylibBeef;
|
||||
using System.Collections;
|
||||
|
||||
abstract class Checkbox : Component
|
||||
class Checkbox : Component
|
||||
{
|
||||
public sprite SpriteChecked;
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
|
||||
public String Label ~ delete _;
|
||||
public bool Checked = false;
|
||||
|
||||
public abstract void OnCheck(bool checkValue);
|
||||
|
||||
public this(StringView pName) : base("Checkbox", pName)
|
||||
public this(StringView 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;
|
||||
Label = new .(pName);
|
||||
}
|
||||
|
||||
protected bool _IsHovered = false;
|
||||
public override Component OnHover(int32 x, int32 y)
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
_IsHovered = true;
|
||||
return this;
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override bool OnClick(int32 x, int32 y)
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
Checked = !Checked;
|
||||
OnCheck(Checked);
|
||||
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
if(!Checked)
|
||||
rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor);
|
||||
else
|
||||
rt.Platform.DrawTexture("Checkbox_Checked", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor);
|
||||
|
||||
if(_Hovered)
|
||||
rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.HoverColor);
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
rt.Platform.DrawText(Label, "Font_Normal",
|
||||
.(rect.x + textureSize[0] + 5
|
||||
,(.)(rect.y + 0.5*rect.height - tsize[1]*0.5))
|
||||
,rt.Scheme.TextColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
textureSize[0] += 5 + tsize[0];
|
||||
if(tsize[1] > textureSize[1])
|
||||
textureSize[1] = tsize[1];
|
||||
return textureSize;
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Render(int32 soy)
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
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;
|
||||
Checked = !Checked;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false;
|
||||
}
|
|
@ -1,107 +1,17 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using RaylibBeef;
|
||||
using System.Collections;
|
||||
|
||||
abstract class Component
|
||||
{
|
||||
public this(StringView pComponentName, StringView pLabel)
|
||||
{
|
||||
ComponentType = pComponentName;
|
||||
Label = pLabel;
|
||||
}
|
||||
|
||||
///
|
||||
/// 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() { }
|
||||
|
||||
public abstract void Update(TGRuntime rt);
|
||||
public abstract void Draw(TGRuntime rt, rect rect);
|
||||
public abstract int32[2] Resize(TGRuntime rt, int32 width);
|
||||
public abstract bool OnHover(TGRuntime rt, int32[2] mPos);
|
||||
public abstract bool OnLeftClick(TGRuntime rt, int32[2] mPos);
|
||||
public abstract bool OnScroll(TGRuntime rt, float pOffset);
|
||||
public abstract bool OnRightClick(TGRuntime rt, int32[2] mPos, List<(String, delegate void(TGRuntime))> pList);
|
||||
}
|
|
@ -1,195 +1,123 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
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 List<Component> Children = new .() ~ DeleteContainerAndItems!(_);
|
||||
|
||||
|
||||
|
||||
///Recalculate the layout of all entries
|
||||
public virtual void Reorder(int32 w)
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
/*
|
||||
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)
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(e == null)
|
||||
{ //Manual row break
|
||||
x = 0;
|
||||
y = y + rowHeight;
|
||||
rowHeight = 0;
|
||||
continue;
|
||||
if(_Children.ContainsKeyAlt<StringView>(i.name))
|
||||
_Children[scope .(i.name)].Draw(rt, i + rect);
|
||||
}
|
||||
}
|
||||
|
||||
if(e is Container)
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
((Container)e).Reorder(w);
|
||||
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);
|
||||
}
|
||||
_Drawings.Clear();
|
||||
|
||||
Layout l = scope .();
|
||||
l.[Friend]_RT = rt;
|
||||
l.[Friend]_Children = _Children;
|
||||
l.[Friend]_Drawings = _Drawings;
|
||||
l.[Friend]_MaxWidth = width;
|
||||
|
||||
if(e is Toolbar)
|
||||
e.Width = App.Width;
|
||||
Layout.Invoke(l, 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)
|
||||
int32[2] max = .(0,0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
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;
|
||||
i.[Friend]Y += y + MarginTop + c.MarginTop;
|
||||
if(i is Container)
|
||||
MoveChildrenRecursive((Container)i, x, y);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList)
|
||||
{
|
||||
var idx = _LayoutData.IndexOf(Position);
|
||||
if(idx < 0)
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
delete pToAdd; //Avoid memory leaks
|
||||
return;
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||
{
|
||||
component.OnRightClick(rt, .(mPos[0]-i.x, mPos[1]-i.y), pList);
|
||||
return true;
|
||||
}
|
||||
_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;
|
||||
}
|
||||
|
||||
public override bool OnDown(int32 x, int32 y)
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
for(var e in Children)
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
||||
return e.OnDown(x, y);
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||
{
|
||||
if(component.OnLeftClick(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||
return true;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override Component OnHover(int32 x, int32 y)
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset)
|
||||
{
|
||||
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)
|
||||
public Result<void> AddChild(StringView pName, Component pComponent)
|
||||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
||||
e.OnRightClick(x, y, items);
|
||||
}
|
||||
if(_Children.ContainsKeyAlt<StringView>(pName))
|
||||
return .Err;
|
||||
_Children.Add(new .(pName), pComponent);
|
||||
return .Ok;
|
||||
}
|
||||
}
|
|
@ -1,57 +1,71 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using RaylibBeef;
|
||||
|
||||
abstract class Dropdown : Component
|
||||
class Dropdown : Component
|
||||
{
|
||||
public List<String> Entries = new .() ~ DeleteContainerAndItems!(_);
|
||||
public uint32 SelectedEntry = 0;
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
private int32[2] _Pos = .();
|
||||
|
||||
public this() : base("Dropdown", "Label")
|
||||
public List<String> Options = new .() ~ DeleteContainerAndItems!(_);
|
||||
public int32 Selected = 0;
|
||||
|
||||
public this(params Span<StringView> args)
|
||||
{
|
||||
Margin = 20;
|
||||
Sprite = App.Textures.GetAsset("dropdown");
|
||||
Width = Sprite.Width;
|
||||
Height = Sprite.Height;
|
||||
for(var i in args)
|
||||
Options.Add(new .(i));
|
||||
}
|
||||
|
||||
public override void Render(int32 soy)
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
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)
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_IsHovered)
|
||||
Sprite.Render(X,Y + soy, HoverTint);
|
||||
}
|
||||
_IsHovered = false;
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override bool OnClick(int32 x, int32 y)
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
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);
|
||||
_Pos = .(rect.x, rect.y + rect.height);
|
||||
rt.Platform.DrawTexture("Dropdown", rect, rt.Scheme.PrimaryColor);
|
||||
if(_Hovered)
|
||||
rt.Platform.DrawTexture("Dropdown", rect, rt.Scheme.HoverColor);
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(Options[Selected], "Font_Normal");
|
||||
rt.Platform.DrawText(Options[Selected], "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)
|
||||
{
|
||||
return rt.Platform.MeasureTextureSize("Dropdown");
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void ClickAction(String pNewVal);
|
||||
|
||||
protected bool _IsHovered = false;
|
||||
public override Component OnHover(int32 x, int32 y)
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_IsHovered = true;
|
||||
return this;
|
||||
var p = new DropdownPopup(Options) {Position = _Pos};
|
||||
p.[Friend]_Click = new [&] (val) => {
|
||||
this.Selected = val;
|
||||
};
|
||||
rt.OpenPopup(p, "Dropdown");
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false;
|
||||
}
|
|
@ -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 +1,75 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
|
||||
abstract class HSlider : NHSlider
|
||||
class HSlider : Component
|
||||
{
|
||||
public this(StringView pLabel) : base(32 * 6, pLabel, "HSlider")
|
||||
{
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
|
||||
public float Value = 0;
|
||||
|
||||
public this()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
if (_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
|
||||
rt.Platform.DrawColorRect(.() { x = rect.x + ts[0], width = rect.width-2*ts[0], y = rect.y + ts[1] / 2 - 4, height = 8 }, rt.Scheme.AcceptColor);
|
||||
rt.Platform.DrawTexture("Checkbox", .() { x = (.)(rect.x + ts[0] + Value * 10*ts[0]-ts[0]/2), y = rect.y, width = ts[0], height = ts[1] }, rt.Scheme.PrimaryColor);
|
||||
if (_Hovered)
|
||||
rt.Platform.DrawTexture("Checkbox", .() { x = (.)(rect.x + ts[0] + Value * 10*ts[0]-ts[0]/2), y = rect.y, width = ts[0], height = ts[1] }, rt.Scheme.HoverColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
return .(ts[0] * 12, ts[1]);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
if(rt.Platform.MouseLeftClick())
|
||||
{
|
||||
float oldVal = Value;
|
||||
OnLeftClick(rt, mPos);
|
||||
if(Value != oldVal)
|
||||
rt.Dirty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
if(mPos[0] <= ts[0])
|
||||
Value = 0;
|
||||
else if(mPos[0] >= ts[0] * 11)
|
||||
Value = 1;
|
||||
else
|
||||
{
|
||||
float ofst = mPos[0] - ts[0];
|
||||
Value = Math.Clamp(ofst / (ts[0]*10)
|
||||
,0,1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
90
src/Components/Internal/ClickableText.bf
Normal file
90
src/Components/Internal/ClickableText.bf
Normal file
|
@ -0,0 +1,90 @@
|
|||
namespace TheaterGui.Components.Internal;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
|
||||
//The clickable text for things like the right click menu and the top toolbar
|
||||
class ClickableText : Component
|
||||
{
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
|
||||
public String Label ~ delete _;
|
||||
public delegate void(TGRuntime rt) Action ~ delete _;
|
||||
public int32[2] Padding = .(50, 4);
|
||||
public Alignment TextAlign = .LeftAligned;
|
||||
|
||||
public enum Alignment
|
||||
{
|
||||
LeftAligned,
|
||||
Center,
|
||||
RightAligned
|
||||
}
|
||||
|
||||
public this(delegate void(TGRuntime rt) pToCall, StringView pName = "Button")
|
||||
{
|
||||
Action = pToCall;
|
||||
Label = new .(pName);
|
||||
}
|
||||
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
if(_Hovered)
|
||||
rt.Platform.DrawColorRect(rect , rt.Scheme.HoverColor);
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
int32 p = 0;
|
||||
switch(TextAlign)
|
||||
{
|
||||
case .LeftAligned:
|
||||
p = rect.x;
|
||||
p += 2;
|
||||
case .Center:
|
||||
p = (.)(rect.x + 0.5*rect.width - tsize[0]*0.5);
|
||||
case .RightAligned:
|
||||
p = (.)(rect.x + rect.width - tsize[0]);
|
||||
p -= 2;
|
||||
}
|
||||
rt.Platform.DrawText(Label, "Font_Normal",
|
||||
.(p,
|
||||
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5))
|
||||
,rt.Scheme.TextColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
return .(ts[0] + Padding[0], ts[1] + Padding[1]);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
Action.Invoke(rt);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => true;
|
||||
}
|
117
src/Components/Internal/DropdownPopup.bf
Normal file
117
src/Components/Internal/DropdownPopup.bf
Normal file
|
@ -0,0 +1,117 @@
|
|||
namespace TheaterGui.Components.Internal;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class DropdownPopup : Popup
|
||||
{
|
||||
private int32 _Hovered = -1;
|
||||
private int32 _AlreadyHovered = -1;
|
||||
private int32[2] _Size = .();
|
||||
private delegate void(int32) _Click ~ delete _;
|
||||
|
||||
public List<String> Options = new .() ~ DeleteContainerAndItems!(_);
|
||||
public int32 Selected = 0;
|
||||
|
||||
public this(List<String> args) : this()
|
||||
{
|
||||
for(var i in args)
|
||||
Options.Add(new .(i));
|
||||
}
|
||||
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = -1;
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
rt.Platform.DrawColorRectOutlined(
|
||||
.() {x = Position[0], y = Position[1], width = _Size[0], height = _Size[1]}
|
||||
,rt.Scheme.PrimaryColor, rt.Scheme.AcceptColor);
|
||||
int32 offsetY = 2;
|
||||
for(var i in Options)
|
||||
{
|
||||
rt.Platform.DrawText(i, "Font_Normal", .(Position[0] + 2, Position[1] + offsetY), rt.Scheme.TextColor);
|
||||
var size = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
|
||||
if(_Hovered == (.)@i.Index)
|
||||
{
|
||||
rt.Platform.DrawColorRect(
|
||||
.() {x = Position[0], y = Position[1] + offsetY - 2, width = _Size[0], height = 4 + size[1]},
|
||||
rt.Scheme.HoverColor);
|
||||
}
|
||||
|
||||
offsetY += 4 + size[1];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
int32[2] size = .();
|
||||
for(var i in Options)
|
||||
{
|
||||
size[0] = rt.Platform.MeasureTextureSize("Dropdown")[0];
|
||||
var tsize = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
size[1] += tsize[1] + 4; //4 is the padding
|
||||
|
||||
}
|
||||
_Size = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
if(mPos[0] >= Position[0] && mPos[0] < Position[0] + _Size[0])
|
||||
{
|
||||
if(mPos[1] >= Position[1] && mPos[1] < Position[1] + _Size[1])
|
||||
{
|
||||
int32[2] offset = .(mPos[0] - Position[0], mPos[1] - Position[1]);
|
||||
int32 offsetY = 0;
|
||||
for(var i in Options)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
if(offset[1] >= offsetY && offset[1] < offsetY + tsize[1] + 4)
|
||||
{
|
||||
_AlreadyHovered = (.)@i.Index;
|
||||
return true;
|
||||
}
|
||||
offsetY += tsize[1] + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
if(mPos[0] >= Position[0] && mPos[0] < Position[0] + _Size[0])
|
||||
{
|
||||
if(mPos[1] >= Position[1] && mPos[1] < Position[1] + _Size[1])
|
||||
{
|
||||
int32[2] offset = .(mPos[0] - Position[0], mPos[1] - Position[1]);
|
||||
int32 offsetY = 0;
|
||||
for(var i in Options)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
if(offset[1] >= offsetY && offset[1] < offsetY + tsize[1] + 4)
|
||||
{
|
||||
_Click.Invoke((.)@i.Index);
|
||||
return false;
|
||||
}
|
||||
offsetY += tsize[1] + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,25 +1,40 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using RaylibBeef;
|
||||
using System.Collections;
|
||||
|
||||
class Label : Component
|
||||
{
|
||||
private Vector2 _Measure;
|
||||
public this(StringView pName) : base(Label, pName)
|
||||
public String Label = null ~ delete _;
|
||||
|
||||
public this(StringView pLabel)
|
||||
{
|
||||
Label = pName;
|
||||
Margin = 3;
|
||||
_Measure = Raylib.MeasureTextEx(Theme.FontLarge, Label.Ptr, Theme.FontSizeLarge, 0);
|
||||
Height = (.)_Measure.y;
|
||||
Width = (.)_Measure.x;
|
||||
Label = new .(pLabel);
|
||||
}
|
||||
|
||||
public override Component OnHover(int32 x, int32 y) => null;
|
||||
|
||||
public override void Render(int32 soy)
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
rt.Platform.DrawText(Label, "Font_Normal", .(rect.x, rect.y), rt.Scheme.TextColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
var s = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
return .(s[0], s[1]);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos) => false;
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos) => false;
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, List<(String, delegate void(TGRuntime))> pList) => true;
|
||||
}
|
|
@ -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 +1,154 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core.Structs;
|
||||
using TheaterGui.Core;
|
||||
|
||||
abstract class Popup : Component
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
///Unscrollable popup window that has a list of available items, clicking on anything but popup windows with the same tag will close it
|
||||
class Popup : Container
|
||||
{
|
||||
public this(System.StringView pComponentName, System.StringView pLabel) : base(pComponentName, pLabel)
|
||||
{
|
||||
private rect _Container = .();
|
||||
private List<(String, delegate void(TGRuntime))> _ToDelete = null;
|
||||
|
||||
public int32[2] Position = .();
|
||||
public int32 Padding = 0;
|
||||
public bool DoHeightCheck = true;
|
||||
|
||||
public this(int32[2] pPosition)
|
||||
{
|
||||
Position = pPosition;
|
||||
}
|
||||
|
||||
///When something force closes the popup
|
||||
public abstract void OnClose();
|
||||
public ~this()
|
||||
{
|
||||
if(_ToDelete != null)
|
||||
{
|
||||
for(var i in _ToDelete)
|
||||
{
|
||||
delete i.0;
|
||||
delete i.1;
|
||||
}
|
||||
delete _ToDelete;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(TheaterGui.Core.TGRuntime rt, rect rect)
|
||||
{
|
||||
_Container = rect;
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
|
||||
rt.Platform.DrawColorRectOutlined(
|
||||
.() {x = offset.x - Padding, y = offset.y - Padding, width = offset.width + 2*Padding, height = offset.height + 2*Padding}
|
||||
, rt.Scheme.PrimaryColor, rt.Scheme.AcceptColor);
|
||||
rt.Platform.DrawColorRect(
|
||||
.() {x = offset.x - Padding, y = offset.y - Padding, width = offset.width + 2*Padding+4, height = offset.height + 2*Padding+4}
|
||||
, .(0x00, 0x00, 0x00, 40));
|
||||
base.Draw(rt, offset);
|
||||
}
|
||||
|
||||
|
||||
public override bool OnHover(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
|
||||
return base.OnHover(rt, .(mPos[0] - offset.x, mPos[1] - offset.y));
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
return base.OnLeftClick(rt, .(mPos[0] - offset.x, mPos[1] - offset.y));
|
||||
}
|
||||
|
||||
public override bool OnScroll(TheaterGui.Core.TGRuntime rt, float pOffset)
|
||||
{
|
||||
return false; //Popups dont scroll
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
_Drawings.Clear();
|
||||
|
||||
Layout l = scope .();
|
||||
l.[Friend]_RT = rt;
|
||||
l.[Friend]_Children = _Children;
|
||||
l.[Friend]_Drawings = _Drawings;
|
||||
l.[Friend]_MaxWidth = width;
|
||||
|
||||
Layout.Invoke(l, width);
|
||||
|
||||
int32[2] max = .(0,0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
for(var i in ref _Drawings)
|
||||
i.width = max[0];
|
||||
return max;
|
||||
}
|
||||
}
|
|
@ -1,62 +1,103 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
abstract class RadioButton : Container
|
||||
class RadioButton : Component
|
||||
{
|
||||
public int32 Checked = -1;
|
||||
private int32 _Checked = 0;
|
||||
private int32 _Hovered = -1;
|
||||
private int32 _AlreadyHovered = -1;
|
||||
|
||||
public this(StringView pName) : base(pName, "RadioButtons")
|
||||
public List<String> Label = new .() ~ DeleteContainerAndItems!(_);
|
||||
|
||||
public this()
|
||||
{
|
||||
Description = pName;
|
||||
}
|
||||
|
||||
public virtual void OnCheck(int32 value)
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = -1;
|
||||
}
|
||||
|
||||
///Set all of the fields to be used as checkboxes
|
||||
public void SetBoxes(int32 selectedIndex, params Span<StringView> args)
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
Checked = selectedIndex;
|
||||
//Clear out old ones
|
||||
this.[Friend]_LayoutData.ClearAndDeleteItems();
|
||||
Children.Clear();
|
||||
|
||||
for(var i in args)
|
||||
int32 startingY = 0;
|
||||
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
for(var i in Label)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if(!(_Checked == (.)@i.Index))
|
||||
rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor);
|
||||
else
|
||||
((RadioCheckbox)i).Checked = false;
|
||||
rt.Platform.DrawTexture("Checkbox_Checked", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor);
|
||||
|
||||
if(_Hovered == @i.Index)
|
||||
rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.HoverColor);
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
rt.Platform.DrawText(i, "Font_Normal",
|
||||
.(rect.x + textureSize[0] + 5
|
||||
,(.)(rect.y + 0.5*textureSize[1] - tsize[1]*0.5 + startingY))
|
||||
,rt.Scheme.TextColor);
|
||||
|
||||
startingY += textureSize[1];
|
||||
}
|
||||
}
|
||||
|
||||
private class RadioCheckbox : Checkbox
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
public this(StringView pName) : base(pName)
|
||||
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
int32 xAddition = 0;
|
||||
for(var label in Label)
|
||||
{
|
||||
Margin = 2;
|
||||
var tsize = rt.Platform.MeasureTextSize(label, "Font_Normal");
|
||||
if(tsize[0] + 5 > xAddition)
|
||||
xAddition = tsize[0] + 5;
|
||||
}
|
||||
public override void OnCheck(bool checkValue)
|
||||
|
||||
textureSize[0] = textureSize[0] + xAddition;
|
||||
textureSize[1] = (.)(textureSize[1] * Label.Count);
|
||||
return textureSize;
|
||||
}
|
||||
|
||||
private int32 GetSelectedItem(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
((RadioButton)Parent).SelectButton(this);
|
||||
int32 startingY = 0;
|
||||
int32 itemHeight = rt.Platform.MeasureTextureSize("Checkbox")[1];
|
||||
for(var i in Label)
|
||||
{
|
||||
if(mPos[1] >= startingY && mPos[1] < startingY + itemHeight)
|
||||
{
|
||||
var textSize = rt.Platform.MeasureTextSize(i, "Font_Normal");
|
||||
if(mPos[0] <= rt.Platform.MeasureTextureSize("Checkbox")[0] + 5 + textSize[0])
|
||||
return (.)@i.Index;
|
||||
}
|
||||
startingY += itemHeight;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = GetSelectedItem(rt, mPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_Checked = GetSelectedItem(rt, mPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false;
|
||||
}
|
|
@ -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 +1,64 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui;
|
||||
using TheaterGui.Core;
|
||||
|
||||
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")
|
||||
/*
|
||||
Represents a physical view of a screen. It takes up the full window and there can only ever be one screen at a time
|
||||
*/
|
||||
|
||||
private float _ScrollValue = 0;
|
||||
|
||||
public override bool OnHover(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
this.Width = Raylib.GetRenderWidth();
|
||||
this.Height = Raylib.GetRenderHeight();
|
||||
return base.OnHover(rt, .(mPos[0], (.)(mPos[1] + _ScrollValue)));
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y - _ScrollValue && mPos[1] <= i.y + i.height - _ScrollValue)
|
||||
{
|
||||
if(component.OnLeftClick(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Draw(TheaterGui.Core.TGRuntime rt, TheaterGui.Core.Structs.rect rect)
|
||||
{
|
||||
base.Draw(rt, rect + .() {y = -(.)_ScrollValue});
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
return base.Resize(rt, width);
|
||||
}
|
||||
|
||||
public override bool OnScroll(TheaterGui.Core.TGRuntime rt, float pOffset)
|
||||
{
|
||||
int32 lowest = 0;
|
||||
for(var i in _Drawings)
|
||||
if(i.y + i.height > lowest)
|
||||
lowest = i.y + i.height;
|
||||
if(lowest > rt.Platform.ScreenSize()[1])
|
||||
{
|
||||
_ScrollValue += pOffset;
|
||||
_ScrollValue = Math.Clamp(_ScrollValue, 0, lowest - rt.Platform.ScreenSize()[1]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false; //Unable to scroll
|
||||
}
|
||||
}
|
|
@ -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 +1,141 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
using TheaterGui.Core;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using RaylibBeef;
|
||||
|
||||
abstract class Toolbar : Component
|
||||
class Toolbar : Component
|
||||
{
|
||||
public NPatchInfo PatchInfo;
|
||||
public List<ToolbarCategory> Categories = new .() ~ DeleteContainerAndItems!(_);
|
||||
private ToolbarPopup _CurrentPopup = null;
|
||||
private ToolbarCategory _SelectedPopup = null;
|
||||
private Dictionary<String, List<(String, delegate void(TGRuntime))>> _Items = new .() ~ delete _;
|
||||
private StringView _Hovered = "";
|
||||
private StringView _AlreadyHovered = "";
|
||||
private int32 _Offset = 0;
|
||||
|
||||
public this(StringView pLabel) : base("Toolbar", pLabel)
|
||||
public ~this()
|
||||
{
|
||||
Height = 24;
|
||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
||||
for(var i in _Items)
|
||||
{
|
||||
delete i.key;
|
||||
for(var j in i.value)
|
||||
{
|
||||
delete j.0;
|
||||
delete j.1;
|
||||
}
|
||||
|
||||
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;
|
||||
delete i.value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnClick(int32 x, int32 y)
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
int32 hor = 10;
|
||||
for(var i in Categories)
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = "";
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, TheaterGui.Core.Structs.rect rect)
|
||||
{
|
||||
var popup = new ToolbarPopup(hor-10,Height + Y, i);
|
||||
popup.Owner = this;
|
||||
App.OpenPopup(popup);
|
||||
_CurrentPopup = popup;
|
||||
_Offset = rect.x;
|
||||
rt.Platform.DrawColorRectOutlined(rect, rt.Scheme.PrimaryColor, rt.Scheme.AcceptColor);
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
|
||||
|
||||
if(_Hovered == i.key)
|
||||
rt.Platform.DrawColorRect(.() {x = rect.x + xOffset, y = rect.y, width = 10 + tsize[0], height = rect.height}, rt.Scheme.HoverColor);
|
||||
|
||||
xOffset += 5;
|
||||
rt.Platform.DrawText(i.key, "Font_Normal",
|
||||
.(xOffset+(rect.x),
|
||||
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5)+1)
|
||||
,rt.Scheme.TextColor);
|
||||
xOffset += tsize[0];
|
||||
xOffset += 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
return .(width, rt.Platform.MeasureTextSize("I", "Font_Normal")[1] + 6);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
if(mPos[0] > xOffset && mPos[0] <= xOffset + tsize[0] + 10)
|
||||
{
|
||||
_AlreadyHovered = i.key;
|
||||
if(rt.[Friend]_PopupsName == "Toolbar")
|
||||
{
|
||||
rt.ClearPopups();
|
||||
OpenPopup(rt, .(xOffset, rt.Platform.MeasureTextSize("I", "Font_Normal")[1] + 4), i.key);
|
||||
}
|
||||
}
|
||||
xOffset += tsize[0] + 10;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
hor += (.)i.NameMeasurement.x + 10;
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
if(_Hovered == "")
|
||||
return false;
|
||||
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
if(i.key == _Hovered)
|
||||
{
|
||||
OpenPopup(rt, .(xOffset + _Offset,rt.Platform.MeasureTextSize("I", "Font_Normal")[1]+4), i.key);
|
||||
return true;
|
||||
}
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
xOffset += tsize[0] + 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;
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
|
||||
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;
|
||||
private void OpenPopup(TGRuntime rt, int32[2] pos, StringView pName)
|
||||
{
|
||||
Popup toPopup = new .(pos);
|
||||
if(_Items.GetValue(scope String(pName)) case .Ok(let vals))
|
||||
{
|
||||
for(var i in vals)
|
||||
toPopup.AddChild(i.0, new ClickableText(new (rt) => {i.1.Invoke(rt);},i.0));
|
||||
|
||||
toPopup.Layout = new [&] (val, width) => {
|
||||
for(var i in vals)
|
||||
{
|
||||
val.Component(i.0);
|
||||
val.Linebreak();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
rt.OpenPopup(toPopup, "Toolbar");
|
||||
}
|
||||
|
||||
public void AddToolbarCategories(params Span<ToolbarCategory> pCategories)
|
||||
public void AddEntry(StringView pSection, StringView pName, delegate void(TGRuntime) pToRun)
|
||||
{
|
||||
for(var i in pCategories)
|
||||
Categories.Add(i);
|
||||
if(!_Items.ContainsKeyAlt<StringView>(pSection))
|
||||
_Items.Add(new .(pSection), new .());
|
||||
if(_Items.GetValue(scope .(pSection)) case .Ok(let val))
|
||||
val.Add((new .(pName), pToRun));
|
||||
}
|
||||
|
||||
///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 override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => true;
|
||||
|
||||
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 +1,76 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
|
||||
abstract class VSlider : NVSlider
|
||||
class VSlider : Component
|
||||
{
|
||||
public this(StringView pLabel) : base(32 * 6, pLabel, "VSlider")
|
||||
{
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
|
||||
public float Value = 0;
|
||||
|
||||
public this()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
if (_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
|
||||
rt.Platform.DrawColorRect(.() { x = rect.x + ts[0] / 2 - 4, width = 8, y = rect.y + ts[1], height = rect.height-2*ts[1] }, rt.Scheme.AcceptColor);
|
||||
|
||||
rt.Platform.DrawTexture("Checkbox", .() { y = (.)(rect.y + ts[1] + Value * 10*ts[1]-ts[1]/2), x = rect.x, height = ts[1], width = ts[0] }, rt.Scheme.PrimaryColor);
|
||||
if (_Hovered)
|
||||
rt.Platform.DrawTexture("Checkbox", .() { y = (.)(rect.y + ts[1] + Value * 10*ts[1]-ts[1]/2), x = rect.x, height = ts[1], width = ts[0] }, rt.Scheme.HoverColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
return .(ts[0], ts[1] * 12);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
if(rt.Platform.MouseLeftClick())
|
||||
{
|
||||
float oldVal = Value;
|
||||
OnLeftClick(rt, mPos);
|
||||
if(Value != oldVal)
|
||||
rt.Dirty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextureSize("Checkbox");
|
||||
if(mPos[1] <= ts[1])
|
||||
Value = 0;
|
||||
else if(mPos[1] >= ts[1] * 11)
|
||||
Value = 1;
|
||||
else
|
||||
{
|
||||
float ofst = mPos[1] - ts[1];
|
||||
Value = Math.Clamp(ofst / (ts[1]*10)
|
||||
,0,1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false;
|
||||
}
|
59
src/Core/EventSystem.bf
Normal file
59
src/Core/EventSystem.bf
Normal file
|
@ -0,0 +1,59 @@
|
|||
namespace TheaterGui.Core;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class EventSystem
|
||||
{
|
||||
private Dictionary<String, List<(uint64, delegate void(void*))>> _Events = new .() ~ delete _;
|
||||
private uint64 _Id = 0;
|
||||
|
||||
public ~this()
|
||||
{
|
||||
for(var i in _Events)
|
||||
{
|
||||
delete i.key;
|
||||
for(var j in i.value)
|
||||
delete j.1;
|
||||
delete i.value;
|
||||
}
|
||||
}
|
||||
|
||||
///Invoke a event, conditionally pass in a event object, and return the amount of events called
|
||||
public int32 Invoke(StringView name, void* obj)
|
||||
{
|
||||
if(!_Events.ContainsKeyAlt<StringView>(name))
|
||||
return -1;
|
||||
int32 toReturn = 0;
|
||||
for(var i in _Events[scope .(name)])
|
||||
{
|
||||
i.1(obj);
|
||||
toReturn++;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
///Returns the deregistration id to be used when deregistering
|
||||
public uint64 Register(StringView name, delegate void(void*) func)
|
||||
{
|
||||
if(!_Events.ContainsKeyAlt<StringView>(name))
|
||||
_Events.Add(new .(name), new .());
|
||||
_Events[scope .(name)].Add((_Id+1, func));
|
||||
_Id++;
|
||||
return _Id;
|
||||
}
|
||||
|
||||
public void DeRegister(StringView name, uint64 id)
|
||||
{
|
||||
if(!_Events.ContainsKeyAlt<StringView>(name))
|
||||
return;
|
||||
for(var i in _Events[scope .(name)])
|
||||
{
|
||||
if(i.0 == id)
|
||||
{
|
||||
delete i.1;
|
||||
@i.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
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-_X);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
27
src/Core/Structs/theme.bf
Normal file
27
src/Core/Structs/theme.bf
Normal file
|
@ -0,0 +1,27 @@
|
|||
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[?] _Theme_Checkbox = Compiler.ReadBinary("assets/checkbox.png");
|
||||
private static uint8[?] _Theme_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png");
|
||||
private static uint8[?] _Theme_Dropdown = Compiler.ReadBinary("assets/dropdown.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[?] Horizontal_Patch = Compiler.ReadBinary("assets/horizontal_patch.png");
|
||||
*/
|
||||
|
||||
public (Span<uint8>, uint8) Font_Normal = (.(&_Theme_Font, _Theme_Font.Count),16);
|
||||
public Span<uint8> Button = .(&_Theme_Button, _Theme_Button.Count);
|
||||
public Span<uint8> Checkbox = .(&_Theme_Checkbox, _Theme_Checkbox.Count);
|
||||
public Span<uint8> Checkbox_Checked = .(&_Theme_Checkbox_Checked, _Theme_Checkbox_Checked.Count);
|
||||
public Span<uint8> Dropdown = .(&_Theme_Dropdown, _Theme_Dropdown.Count);
|
||||
|
||||
}
|
68
src/Core/TGRuntime.api.bf
Normal file
68
src/Core/TGRuntime.api.bf
Normal file
|
@ -0,0 +1,68 @@
|
|||
namespace TheaterGui.Core;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
extension TGRuntime
|
||||
{
|
||||
public EventSystem Events = new .() ~ delete _;
|
||||
|
||||
public theme Theme;
|
||||
public colorScheme Scheme;;
|
||||
|
||||
private Screen _CurrentScreen ~ delete _;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private List<Popup> _Popups = new .() ~ DeleteContainerAndItems!(_);
|
||||
private String _PopupsName = new .("") ~ delete _;
|
||||
public void OpenPopup(Popup pPopup, StringView pName)
|
||||
{
|
||||
if(pPopup == null)
|
||||
{
|
||||
ClearPopups();
|
||||
return;
|
||||
}
|
||||
else if(pName != _PopupsName)
|
||||
{
|
||||
ClearPopups();
|
||||
_PopupsName.Append(pName);
|
||||
}
|
||||
pPopup.Resize(this, ScreenSize[0]);
|
||||
_Popups.Add(pPopup);
|
||||
}
|
||||
|
||||
public void ClearPopups()
|
||||
{
|
||||
Dirty();
|
||||
_PopupsName..Clear()
|
||||
.Append("");
|
||||
ClearAndDeleteItems(_Popups);
|
||||
}
|
||||
}
|
146
src/Core/TGRuntime.core.bf
Normal file
146
src/Core/TGRuntime.core.bf
Normal file
|
@ -0,0 +1,146 @@
|
|||
namespace TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class TGRuntime
|
||||
{
|
||||
private void Launch(IPlatformLayer platform, Screen 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;
|
||||
|
||||
_CurrentScreen = screen;
|
||||
_CurrentScreen.Resize(this, width);
|
||||
ScreenSize = Platform.ScreenSize();
|
||||
|
||||
#if BF_PLATFORM_WASM
|
||||
WebAssembly.emscripten_set_main_loop(=> ProcessFrame, 60, 1);
|
||||
#else
|
||||
while (!ShouldClose)
|
||||
ProcessFrame();
|
||||
#endif
|
||||
platform.Deinitialize();
|
||||
}
|
||||
|
||||
|
||||
bool _MBDownLastFrame = false;
|
||||
bool _MBRightDownLastFrame = false;
|
||||
private void ProcessFrame()
|
||||
{
|
||||
//Meta
|
||||
ShouldClose = Platform.ShouldClose();
|
||||
var ss = Platform.ScreenSize();
|
||||
if (ss != ScreenSize)
|
||||
{ //Resultion update
|
||||
Dirty();
|
||||
ClearPopups();
|
||||
_CurrentScreen.Resize(this, ss[0]);
|
||||
ScreenSize = ss;
|
||||
}
|
||||
|
||||
if (Platform.MouseWheel() != 0)
|
||||
if (_CurrentScreen.OnScroll(this, -5 * Platform.MouseWheel()))
|
||||
{
|
||||
Dirty();
|
||||
ClearPopups();
|
||||
}
|
||||
|
||||
var mPos = Platform.MousePosition();
|
||||
bool hasHovered = false;
|
||||
for (var i in _Popups)
|
||||
if (i.OnHover(this, .((.)mPos[0], (.)mPos[1])))
|
||||
hasHovered = true;
|
||||
if (!hasHovered)
|
||||
_CurrentScreen.OnHover(this, .((.)mPos[0], (.)mPos[1]));
|
||||
|
||||
if (_MBDownLastFrame && !Platform.MouseLeftClick())
|
||||
{
|
||||
bool hasLClicked = false;
|
||||
for (var i in _Popups)
|
||||
if (i.OnLeftClick(this, .((.)mPos[0], (.)mPos[1])))
|
||||
hasLClicked = true;
|
||||
if (!hasLClicked)
|
||||
{
|
||||
ClearPopups();
|
||||
_CurrentScreen.OnLeftClick(this, .((.)mPos[0], (.)mPos[1]));
|
||||
}
|
||||
}
|
||||
_MBDownLastFrame = Platform.MouseLeftClick();
|
||||
|
||||
if (_MBRightDownLastFrame && !Platform.MouseRightClick())
|
||||
{
|
||||
bool hasLClicked = false;
|
||||
List<(String, delegate void(TGRuntime))> data = new .();
|
||||
for (var i in _Popups)
|
||||
if (i.OnRightClick(this, .((.)mPos[0], (.)mPos[1]), data))
|
||||
{
|
||||
hasLClicked = true;
|
||||
}
|
||||
if (!hasLClicked)
|
||||
{
|
||||
ClearPopups();
|
||||
_CurrentScreen.OnRightClick(this, .((.)mPos[0], (.)mPos[1]), data);
|
||||
}
|
||||
if(data.Count > 0)
|
||||
OpenRightClickPopup(this, .((.)mPos[0], (.)mPos[1]), data);
|
||||
else
|
||||
delete data;
|
||||
}
|
||||
_MBRightDownLastFrame = Platform.MouseRightClick();
|
||||
|
||||
|
||||
//Logic
|
||||
for (var i in _Popups)
|
||||
i.Update(this);
|
||||
_CurrentScreen.Update(this);
|
||||
//Drawing
|
||||
if (_Dirty)
|
||||
{
|
||||
Platform.StartDrawing();
|
||||
_CurrentScreen.Draw(this, .() { width = ScreenSize[0], height = ScreenSize[1] });
|
||||
for (var i in _Popups)
|
||||
i.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");
|
||||
Platform.LoadTexture(pStartingTheme.Checkbox, "Checkbox");
|
||||
Platform.LoadTexture(pStartingTheme.Dropdown, "Dropdown");
|
||||
Platform.LoadTexture(pStartingTheme.Checkbox_Checked, "Checkbox_Checked");
|
||||
|
||||
}
|
||||
|
||||
private void OpenRightClickPopup(TGRuntime rt, int32[2] pos, List<(String, delegate void(TGRuntime))> data)
|
||||
{
|
||||
Popup toPopup = new .(pos);
|
||||
toPopup.Padding = 5;
|
||||
toPopup.[Friend]_ToDelete = data;
|
||||
for (var i in data)
|
||||
toPopup.AddChild(i.0, new ClickableText(new (rt) => { i.1.Invoke(rt); }, i.0));
|
||||
|
||||
toPopup.Layout = new [&] (val, width) =>
|
||||
{
|
||||
for (var i in data)
|
||||
{
|
||||
val.Component(i.0);
|
||||
val.Linebreak();
|
||||
}
|
||||
};
|
||||
OpenPopup(toPopup, "Rightclick");
|
||||
}
|
||||
}
|
|
@ -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
|
17
src/TODO
Normal file
17
src/TODO
Normal file
|
@ -0,0 +1,17 @@
|
|||
TODO:
|
||||
TabbedContainers
|
||||
Fixed size containers
|
||||
Collapseable
|
||||
Code cleanup
|
||||
Dropdowns render offscreen
|
||||
|
||||
|
||||
Being Worked on:
|
||||
Textfields
|
||||
Textboxes
|
||||
|
||||
Done:
|
||||
Radio Buttons
|
||||
Horizontal sliders
|
||||
Vertical sliders
|
||||
Dropdown
|
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
Reference in a new issue