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
|
# ---> Beef
|
||||||
**/build
|
**/build
|
||||||
**/recovery
|
**/recovery
|
||||||
|
**/deps
|
||||||
BeefSpace_User.toml
|
BeefSpace_User.toml
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {corlib = "*", corlib = "*", raylib-beef = "*"}
|
Dependencies = {corlib = "*", corlib = "*", Bofa = "*", raylib-beef = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "TheaterGui"
|
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
|
FileVersion = 1
|
||||||
Dependencies = {corlib = "*", TheaterGui = "*"}
|
Dependencies = {corlib = "*", TheaterGui = "*", raylib-backend = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "examples"
|
Name = "examples"
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Box : Container
|
|
||||||
{
|
|
||||||
public this() : base("Box")
|
|
||||||
{
|
|
||||||
//Add ui items here via AddChild() and terminate the row via EndRow()
|
|
||||||
Margin = 5;
|
|
||||||
|
|
||||||
AddChild(new Checkb());
|
|
||||||
AddChild(new Radios());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class StandartButton : Button
|
|
||||||
{
|
|
||||||
public this() : base("Basic Button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LButton : LargeButton
|
|
||||||
{
|
|
||||||
public this() : base("Large Button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CButton : NButton
|
|
||||||
{
|
|
||||||
public this() : base(400, 50, "Custom sized button")
|
|
||||||
{
|
|
||||||
Margin = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class Checkb : Checkbox
|
|
||||||
{
|
|
||||||
public this() : base("Check me!")
|
|
||||||
{
|
|
||||||
Checked = true;
|
|
||||||
Description = "Beef is awesome";
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void OnCheck(bool checkValue)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class ExampleToolbar : Toolbar
|
|
||||||
{
|
|
||||||
public this() : base("Toolbar")
|
|
||||||
{
|
|
||||||
AddToolbarCategories(
|
|
||||||
new .("Help",
|
|
||||||
new .("Version", new => PrintVersion)
|
|
||||||
),
|
|
||||||
|
|
||||||
new .("About",
|
|
||||||
new .("TheaterGui", new => PrintAbout),
|
|
||||||
new .("Booklordofthedings", new => PrintAbout)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrintVersion()
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine("1.0");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrintAbout()
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine("""
|
|
||||||
TheaterGui by Booklordofthedings
|
|
||||||
A simple easy to use gui library for tools
|
|
||||||
""");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class HorSlider : HSlider
|
|
||||||
{
|
|
||||||
public this() : base("HorSlider")
|
|
||||||
{
|
|
||||||
//Use the thing above to set the length of the bar
|
|
||||||
Min = 0;
|
|
||||||
Max = 100;
|
|
||||||
Value = 50;
|
|
||||||
ReactToValueChange = true; //This indicates wether OnValueChange gets actually called
|
|
||||||
Description = "A default horizontal slider";
|
|
||||||
|
|
||||||
MarginTop = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnValueChange(float newVal)
|
|
||||||
{
|
|
||||||
#if !BF_PLATFORM_WASM
|
|
||||||
System.Console.WriteLine(Value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class MainScreen : Screen
|
|
||||||
{
|
|
||||||
public this() : base("MainScreen")
|
|
||||||
{
|
|
||||||
//Add ui items here via AddChild() and terminate the row via EndRow()
|
|
||||||
AddChild(new ExampleToolbar());
|
|
||||||
|
|
||||||
AddChild(new Label("Changing the width allows you to see these buttons reordered"));
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
AddChild(new OpenButton());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new StandartButton());
|
|
||||||
AddChild(new LButton());
|
|
||||||
AddChild(new CButton());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
AddChild(new HorSlider());
|
|
||||||
AddChild(new VertSlider());
|
|
||||||
EndRow();
|
|
||||||
|
|
||||||
|
|
||||||
AddChild(new Box());
|
|
||||||
AddChild(new Box());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
namespace examples;
|
|
||||||
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class OpenButton : IconButton
|
|
||||||
{
|
|
||||||
public this() : base("OpenButton")
|
|
||||||
{
|
|
||||||
Icon = .Icon_Folder; //Use this to set the icon sprite
|
|
||||||
Margin = 5;
|
|
||||||
MarginTop = 40;
|
|
||||||
MarginBottom = 40;
|
|
||||||
Description = "Open a file dialogue";
|
|
||||||
}
|
|
||||||
|
|
||||||
//What happens when the button is clicked
|
|
||||||
public override void ClickAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,74 @@
|
||||||
namespace examples;
|
namespace examples;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
using TheaterGui;
|
using TheaterGui;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
using TheaterGui.Components.Internal;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
App.Run<MainScreen>("Example Gui",1920,1080);
|
scope App()
|
||||||
|
..SetName("TheaterGui Application")
|
||||||
|
..SetStartingSize(1280, 720)
|
||||||
|
..SetPlatformLayer(new raylib_backend.PlatformRaylib())
|
||||||
|
.Run(new MainScreen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MainScreen : 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;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
|
||||||
class Textures
|
class TextureManager
|
||||||
{
|
{
|
||||||
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
|
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
|
||||||
private List<RenderTexture> _Textures = new .() ~ delete _;
|
private List<RenderTexture> _Textures = new .() ~ delete _;
|
||||||
|
|
||||||
public this()
|
|
||||||
{
|
|
||||||
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSize, null, 256);
|
|
||||||
Theme.FontSmall = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeSmall, null, 256);
|
|
||||||
Theme.FontLarge = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeLarge, null, 256);
|
|
||||||
|
|
||||||
LoadAsset(Theme.Texture_Button, "button");
|
|
||||||
LoadAsset(Theme.Texture_NButton, "n_button");
|
|
||||||
LoadAsset(Theme.Texture_SquareButton, "square_button");
|
|
||||||
LoadAsset(Theme.Texture_LargeButton, "large_button");
|
|
||||||
LoadAsset(Theme.Texture_Checkbox, "checkbox");
|
|
||||||
LoadAsset(Theme.Texture_Checkbox_Checked, "checkbox_checked");
|
|
||||||
LoadAsset(Theme.Horizontal_Patch, "horizontal_patch");
|
|
||||||
LoadAsset(Theme.Dropdown, "dropdown");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LoadAsset(Theme.Texture_TheaterIcon, "theater_icon");
|
|
||||||
LoadAsset(Theme.Texture_FolderIcon, "folder_icon");
|
|
||||||
sprite.Icon_Folder = GetAsset("folder_icon");
|
|
||||||
sprite.Icon_Theater = GetAsset("theater_icon");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
|
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||||
|
|
||||||
///Attempt to get a existing asset by StringView
|
///Attempt to get a existing asset by StringView
|
||||||
|
@ -164,10 +138,6 @@ struct sprite
|
||||||
public int32 Height = 0;
|
public int32 Height = 0;
|
||||||
public float Rotation = 0;
|
public float Rotation = 0;
|
||||||
|
|
||||||
public static sprite Icon_Folder;
|
|
||||||
public static sprite Icon_Theater;
|
|
||||||
|
|
||||||
|
|
||||||
public void Render(float x, float y, Color color = Raylib.WHITE)
|
public void Render(float x, float y, Color color = Raylib.WHITE)
|
||||||
{
|
{
|
||||||
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
|
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
|
294
src/App.bf
294
src/App.bf
|
@ -1,263 +1,53 @@
|
||||||
namespace TheaterGui;
|
namespace TheaterGui;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
using TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
using internal TheaterGui;
|
|
||||||
using TheaterGui.Components;
|
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
/*
|
private String _Name = new .("TheaterGui Program") ~ delete _;
|
||||||
There are two ways to run TheaterGui.
|
private int32[2] _StartingSize = .(1280, 720);
|
||||||
Either full, by using the Run function or by manually calling the functions in Run.
|
private IPlatformLayer _Platform = null ~ delete _;
|
||||||
This way you can integrate TheaterGui into other raylib applications of your choice.
|
private colorScheme _Scheme = .DefaultScheme;
|
||||||
|
private theme _Theme = .();
|
||||||
|
|
||||||
Components are supposed to be created via inheritance for each individual component, except some very simple exeptions (Labels, Placeholders)
|
public Result<void> Run(Screen pScreen)
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
//For hover items
|
|
||||||
private static List<Popup> _Popups = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
private static Vector2 _OldPos = .(0, 0);
|
|
||||||
private static double _MovTime = 0;
|
|
||||||
private static String _HoverText = new .() ~ delete _;
|
|
||||||
private static Vector2 _OldSize = .(0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
public static Textures Textures ~ delete _; //All loaded textures
|
|
||||||
public static Component Selected; //Currently selected component
|
|
||||||
public static bool AllowReorder = true;
|
|
||||||
|
|
||||||
|
|
||||||
private static Screen _CurrentScreen = null ~ delete _;
|
|
||||||
public static Screen CurrentScreen
|
|
||||||
{
|
{
|
||||||
get => _CurrentScreen;
|
if(_Platform == null)
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_CurrentScreen != null)
|
|
||||||
delete _CurrentScreen;
|
|
||||||
_CurrentScreen = value;
|
|
||||||
_CurrentScreen.Reorder(Width);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///Window width
|
|
||||||
public static int32 Width
|
|
||||||
{
|
|
||||||
get => Raylib.GetRenderWidth();
|
|
||||||
set => Raylib.SetWindowSize(value, Raylib.GetRenderHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Window height
|
|
||||||
public static int32 Height
|
|
||||||
{
|
|
||||||
get => Raylib.GetRenderHeight();
|
|
||||||
set => Raylib.SetWindowSize(Raylib.GetRenderWidth(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Mouse position
|
|
||||||
public static Vector2 Mouse
|
|
||||||
{
|
|
||||||
get => Raylib.GetMousePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Mouse wheel offset
|
|
||||||
public static float Wheel
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static bool _ShouldClose;
|
|
||||||
public static bool ShouldClose
|
|
||||||
{
|
|
||||||
public get
|
|
||||||
{
|
|
||||||
return _ShouldClose || Raylib.WindowShouldClose();
|
|
||||||
}
|
|
||||||
public set => _ShouldClose = value;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///Run TheaterGui (Use for fully independent programs)
|
|
||||||
///@param pName Name of the window
|
|
||||||
///@param pWidth Width of the window
|
|
||||||
///@param pHeight Height of the window
|
|
||||||
///@param pStartScreen The starting Screen of the application
|
|
||||||
public static void Run<T>(StringView pName, int32 pWidth, int32 pHeight) where T : Screen
|
|
||||||
{
|
|
||||||
InitializeRaylib(pName, pWidth, pHeight);
|
|
||||||
InitializeGui<T>();
|
|
||||||
|
|
||||||
#if BF_PLATFORM_WASM
|
|
||||||
WebAssembly.emscripten_set_main_loop(=> ProcessDrawFrame, 40, 1);
|
|
||||||
///Afaik the infinite loop means, that the deinitialization functionality will not be called,
|
|
||||||
///but that should be fine for wasm since it fully cleans up when you exit the page.
|
|
||||||
///If we dont do it calls the deinitialization directly afterwards
|
|
||||||
#else
|
|
||||||
while (!App.ShouldClose)
|
|
||||||
ProcessDrawFrame();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DeinitializeGui();
|
|
||||||
DeinitializeRaylib();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Initializes the raylib enviroment
|
|
||||||
///@param pName Name of the window
|
|
||||||
///@param pWidth Width of the window
|
|
||||||
///@param pHeight Height of the window
|
|
||||||
public static void InitializeRaylib(StringView pName, int32 pWidth, int32 pHeight)
|
|
||||||
{
|
|
||||||
//Default raylib settings
|
|
||||||
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
|
||||||
Raylib.InitWindow(pWidth, pHeight, scope String(pName));
|
|
||||||
Raylib.SetExitKey(0);
|
|
||||||
#if !BF_PLATFORM_WASM ///Otherwise raylib sleeps and delays browser responsiveness
|
|
||||||
Raylib.SetTargetFPS(40); //Should be a resonable framerate for gui apps
|
|
||||||
#endif
|
|
||||||
Raylib.SetWindowMinSize(640, 360);
|
|
||||||
|
|
||||||
///Set the default window icon
|
|
||||||
var icon = Raylib.LoadImageFromMemory(".png", (.)&Theme.Texture_WindowIcon, Theme.Texture_WindowIcon.Count);
|
|
||||||
Raylib.SetWindowIcon(icon);
|
|
||||||
Raylib.UnloadImage(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Initialize the gui enviroment
|
|
||||||
public static void InitializeGui<T>() where T : Screen
|
|
||||||
{
|
|
||||||
Textures = new .();
|
|
||||||
CurrentScreen = new T();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Cleanup the gui enviroment
|
|
||||||
public static void DeinitializeGui() => void();
|
|
||||||
|
|
||||||
|
|
||||||
///Cleanup the raylib enviroment
|
|
||||||
public static void DeinitializeRaylib() => void();
|
|
||||||
|
|
||||||
|
|
||||||
///To be called by emscripten
|
|
||||||
private static void ProcessDrawFrame()
|
|
||||||
{
|
|
||||||
ProcessFrame();
|
|
||||||
Raylib.BeginDrawing();
|
|
||||||
Raylib.ClearBackground(Theme.Background);
|
|
||||||
DrawFrame();
|
|
||||||
Raylib.EndDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Process the logic for a single frame of the application
|
|
||||||
public static void ProcessFrame()
|
|
||||||
{
|
|
||||||
|
|
||||||
Vector2 newSize = .(Width, Height);
|
|
||||||
if (_OldSize != newSize)
|
|
||||||
{
|
|
||||||
CurrentScreen.Reorder((.)newSize.x);
|
|
||||||
_OldSize = newSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
Input.HandleScrolling(Raylib.GetMouseWheelMove());
|
|
||||||
|
|
||||||
if (Raylib.IsMouseButtonPressed(0))
|
|
||||||
Input.HandleLeftClick();
|
|
||||||
else if (Raylib.IsMouseButtonDown(0))
|
|
||||||
Input.HandleLeftDown();
|
|
||||||
else if (Raylib.IsMouseButtonPressed(1))
|
|
||||||
Input.HandleRightClick();
|
|
||||||
else
|
|
||||||
Input.HandleHover();
|
|
||||||
|
|
||||||
if(Selected != null)
|
|
||||||
Selected.WhileSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///Draw the current state of the application
|
|
||||||
public static void DrawFrame()
|
|
||||||
{
|
|
||||||
//Drawing logic
|
|
||||||
CurrentScreen.Render((.)Wheel);
|
|
||||||
|
|
||||||
for (var i in _Popups)
|
|
||||||
i.Render((.)Wheel);
|
|
||||||
|
|
||||||
if (!_HoverText.IsEmpty)
|
|
||||||
{
|
|
||||||
RenderHoverText();
|
|
||||||
_HoverText.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenderHoverText()
|
|
||||||
{
|
|
||||||
int32 yOffset = 0;
|
|
||||||
int32 xOffset = 0;
|
|
||||||
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.FontSmall, _HoverText, Theme.FontSizeSmall, 0);
|
|
||||||
|
|
||||||
if (Mouse.x < Width / 2) //Render the textbox to the right of the cursor
|
|
||||||
xOffset = 15;
|
|
||||||
else //Render the textbox to the left of the cursor
|
|
||||||
xOffset = (.)(-1 * measure.x) - 15;
|
|
||||||
if (Mouse.y < Height / 2) //Render the textbox at the y location of the cursor
|
|
||||||
yOffset = 0;
|
|
||||||
else //Render the textbox offset so, that the textbox y ends at the y location of the cursor
|
|
||||||
yOffset = (.)(-1 * measure.y);
|
|
||||||
|
|
||||||
//BoxShadow
|
|
||||||
//Box
|
|
||||||
//BoxBorder
|
|
||||||
//BoxContent
|
|
||||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset + 3, (.)Mouse.y - 3 + yOffset + 3, (.)measure.x + 6, (.)measure.y + 3, Color(0, 0, 0, 70));
|
|
||||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Color(218, 211, 176, 255));
|
|
||||||
Raylib.DrawRectangleLines((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Raylib.BLACK);
|
|
||||||
Raylib.DrawTextEx(Theme.FontSmall, _HoverText, Raymath.Vector2Add(Mouse, Vector2(xOffset, yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void ForceReorder()
|
|
||||||
{
|
|
||||||
if (AllowReorder && CurrentScreen != null)
|
|
||||||
CurrentScreen.Reorder(Width);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void OpenPopup(Popup popup)
|
|
||||||
{
|
|
||||||
_Popups.Add(popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Result<Popup> GetTopmostPopup()
|
|
||||||
{
|
|
||||||
if(_Popups.Count < 1)
|
|
||||||
return .Err;
|
return .Err;
|
||||||
return .Ok(_Popups[^1]);
|
|
||||||
|
var runtime = new TGRuntime();
|
||||||
|
runtime.[Friend]Launch(_Platform, pScreen, _Name, _StartingSize[0], _StartingSize[1], _Scheme, _Theme);
|
||||||
|
delete runtime;
|
||||||
|
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetName(StringView pName)
|
||||||
|
{
|
||||||
|
_Name.Clear();
|
||||||
|
_Name.Append(pName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStartingSize(int32 pWidth, int32 pHeight)
|
||||||
|
{
|
||||||
|
if(pWidth > 0 || pHeight > 0)
|
||||||
|
return;
|
||||||
|
_StartingSize[0] = pWidth;
|
||||||
|
_StartingSize[1] = pHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPlatformLayer(IPlatformLayer pPlatformLayer)
|
||||||
|
{
|
||||||
|
delete _Platform;
|
||||||
|
_Platform = pPlatformLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetColorScheme(colorScheme pScheme) => _Scheme = pScheme;
|
||||||
|
public void SetUITheme(theme pTheme) => _Theme = pTheme;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,55 +1,68 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Button : Component
|
class Button : Component
|
||||||
{
|
{
|
||||||
public this(StringView pLabel, StringView pComponentName = "Button") : base(pComponentName, pLabel)
|
private bool _Hovered = false;
|
||||||
|
private bool _AlreadyHovered = false;
|
||||||
|
|
||||||
|
public String Label ~ delete _;
|
||||||
|
delegate void(TGRuntime rt) Action ~ delete _;
|
||||||
|
|
||||||
|
public this(delegate void(TGRuntime rt) pAction, StringView pLabel = "Button")
|
||||||
{
|
{
|
||||||
Sprite = App.Textures.GetAsset("button");
|
Label = new .(pLabel);
|
||||||
Width = Sprite.Width;
|
Action = pAction;
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ClickAction(); //What happends when its clicked
|
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||||
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
{
|
||||||
_IsHovered = true;
|
if(_Hovered != _AlreadyHovered)
|
||||||
return this;
|
{
|
||||||
|
_Hovered = _AlreadyHovered;
|
||||||
|
rt.Dirty();
|
||||||
|
}
|
||||||
|
_AlreadyHovered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
{
|
{
|
||||||
if(Rectangle(X, Y, Width, Height).Overlaps(x, y))
|
rt.Platform.DrawTexture("Button", rect, rt.Scheme.PrimaryColor);
|
||||||
{
|
if(_Hovered)
|
||||||
if(Enabled)
|
rt.Platform.DrawTexture("Button", rect, rt.Scheme.HoverColor);
|
||||||
{
|
|
||||||
ClickAction();
|
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||||
return true;
|
rt.Platform.DrawText(Label, "Font_Normal",
|
||||||
}
|
.((.)(rect.x + 0.5*rect.width - tsize[0]*0.5),
|
||||||
return false;
|
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5))
|
||||||
}
|
,rt.Scheme.TextColor);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
return rt.Platform.MeasureTextureSize("Button");
|
||||||
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)
|
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
_AlreadyHovered = true;
|
||||||
}
|
return true;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
if(_IsHovered)
|
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
{
|
||||||
}
|
Action.Invoke(rt);
|
||||||
_IsHovered = false;
|
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)
|
||||||
|
{
|
||||||
|
pList.Add((.)(new String(scope $"Click {Label}"), new (rt) => {this.Action.Invoke(rt);}));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,49 +1,73 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
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 bool Checked = false;
|
||||||
|
|
||||||
public abstract void OnCheck(bool checkValue);
|
public this(StringView pName)
|
||||||
|
|
||||||
public this(StringView pName) : base("Checkbox", pName)
|
|
||||||
{
|
{
|
||||||
Sprite = App.Textures.GetAsset("checkbox");
|
Label = new .(pName);
|
||||||
SpriteChecked = App.Textures.GetAsset("checkbox_checked");
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, Theme.FontSize, 0);
|
|
||||||
Width = Sprite.Width + (.)measure.x + 2;
|
|
||||||
Height = measure.y > Sprite.Height ? (.)measure.y : Sprite.Height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
public override void Update(TGRuntime rt)
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
{
|
||||||
_IsHovered = true;
|
if(_Hovered != _AlreadyHovered)
|
||||||
return this;
|
{
|
||||||
|
_Hovered = _AlreadyHovered;
|
||||||
|
rt.Dirty();
|
||||||
|
}
|
||||||
|
_AlreadyHovered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
{
|
{
|
||||||
Checked = !Checked;
|
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||||
OnCheck(Checked);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||||
{
|
{
|
||||||
if(!Checked)
|
Checked = !Checked;
|
||||||
Sprite.Render(X,Y + soy,Tint);
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
using System.Collections;
|
||||||
|
|
||||||
abstract class Component
|
abstract class Component
|
||||||
{
|
{
|
||||||
public this(StringView pComponentName, StringView pLabel)
|
public abstract void Update(TGRuntime rt);
|
||||||
{
|
public abstract void Draw(TGRuntime rt, rect rect);
|
||||||
ComponentType = pComponentName;
|
public abstract int32[2] Resize(TGRuntime rt, int32 width);
|
||||||
Label = pLabel;
|
public abstract bool OnHover(TGRuntime rt, int32[2] mPos);
|
||||||
}
|
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);
|
||||||
/// Fields
|
|
||||||
///
|
|
||||||
public Container Parent;
|
|
||||||
public bool Enabled = true;
|
|
||||||
|
|
||||||
public Color Tint = Theme.Tint;
|
|
||||||
public Color HoverTint = Theme.HoverTint;
|
|
||||||
public sprite Sprite;
|
|
||||||
|
|
||||||
public int32 MarginTop = 0;
|
|
||||||
public int32 MarginBottom = 0;
|
|
||||||
public int32 MarginLeft = 0;
|
|
||||||
public int32 MarginRight = 0;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Properties
|
|
||||||
///
|
|
||||||
public bool Selected
|
|
||||||
{ //When something is selected its allowed to update every frame
|
|
||||||
get;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Selected = value;
|
|
||||||
App.Selected = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 Margin
|
|
||||||
{
|
|
||||||
//There seems to be no reasonable way to implement a getter here
|
|
||||||
set
|
|
||||||
{
|
|
||||||
MarginTop = value;
|
|
||||||
MarginBottom = value;
|
|
||||||
MarginLeft = value;
|
|
||||||
MarginRight = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int32 _X = 0;
|
|
||||||
public int32 X
|
|
||||||
{
|
|
||||||
get => _X;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_X = value;
|
|
||||||
} //You may set this, but it might fuck up layouting
|
|
||||||
};
|
|
||||||
|
|
||||||
private int32 _Y = 0;
|
|
||||||
public int32 Y
|
|
||||||
{
|
|
||||||
get => _Y;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_Y = value;
|
|
||||||
} //You may set this, but it might fuck up layouting
|
|
||||||
};
|
|
||||||
|
|
||||||
public int32 Width
|
|
||||||
{
|
|
||||||
public get;
|
|
||||||
protected set; //Please do not
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 Height
|
|
||||||
{
|
|
||||||
public get;
|
|
||||||
protected set; //Please do not
|
|
||||||
}
|
|
||||||
|
|
||||||
[DynamicString] //What this type of component is called
|
|
||||||
private String _ComponentType = new .() ~ delete _;
|
|
||||||
[DynamicString] //What the component says on it when rendered
|
|
||||||
private String _Label = null ~ delete _;
|
|
||||||
[DynamicString] //Usually only used by the OnHover tooltip
|
|
||||||
private String _Description = null ~ delete _;
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Functions
|
|
||||||
///
|
|
||||||
public abstract void Render(int32 soy);
|
|
||||||
|
|
||||||
public virtual bool OnClick(int32 x, int32 y) => false;
|
|
||||||
public virtual void OnRightClick(int32 x, int32 y, Toolbar.ToolbarCategory items) {}
|
|
||||||
public virtual bool HandleScrollEvent(float scroll, int32 x, int32 y) {return false;};
|
|
||||||
public virtual bool OnDown(int32 x, int32 y) => false;
|
|
||||||
public abstract Component OnHover(int32 x, int32 y);
|
|
||||||
|
|
||||||
public virtual void WhileSelected() { }
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,195 +1,123 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
class Container : Component
|
abstract class Container : Component
|
||||||
{
|
{
|
||||||
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
|
protected Dictionary<String, Component> _Children = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||||
{
|
protected List<rect> _Drawings = new .() ~ delete _;
|
||||||
|
|
||||||
|
public delegate void(Layout, int32 width) Layout = null ~ delete _;
|
||||||
|
|
||||||
|
public override void Update(TGRuntime rt)
|
||||||
|
{
|
||||||
|
for(var i in _Children)
|
||||||
|
i.value.Update(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Component> _LayoutData = new .() ~ delete _;
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
|
|
||||||
public List<Component> Children = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///Recalculate the layout of all entries
|
|
||||||
public virtual void Reorder(int32 w)
|
|
||||||
{
|
{
|
||||||
/*
|
for(var i in _Drawings)
|
||||||
List<Entries> {Entry, Entry, Entry, RB, Entry, Entry, RB, Entry, RB}
|
|
||||||
null is a rowbreak while non null isnt a rowbreak
|
|
||||||
|
|
||||||
Algorithm
|
|
||||||
if the current entry is a rowbreak, reset the cursor to x = 0, y = y + height
|
|
||||||
|
|
||||||
try to fit the current entry after the cursor
|
|
||||||
if it fits add it,
|
|
||||||
if it doesnt fit break
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 maxWidth = 0; //The highest width line
|
|
||||||
int32 rowHeight = 0; //How high the current row is
|
|
||||||
int32 x = 0;
|
|
||||||
int32 y = 0;
|
|
||||||
|
|
||||||
for(var e in _LayoutData)
|
|
||||||
{
|
{
|
||||||
if(e == null)
|
if(_Children.ContainsKeyAlt<StringView>(i.name))
|
||||||
{ //Manual row break
|
_Children[scope .(i.name)].Draw(rt, i + rect);
|
||||||
x = 0;
|
}
|
||||||
y = y + rowHeight;
|
}
|
||||||
rowHeight = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e is Container)
|
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||||
|
{
|
||||||
|
_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;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||||
|
{
|
||||||
|
for(var i in _Drawings)
|
||||||
|
{
|
||||||
|
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||||
{
|
{
|
||||||
((Container)e).Reorder(w);
|
if(mPos[0] >= i.x && mPos[0] <= i.x + i.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
|
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||||
{ //Automatic row break
|
{
|
||||||
x = 0;
|
if(component.OnHover(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||||
y = y + rowHeight;
|
return true;
|
||||||
rowHeight = 0;
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
MoveChildrenRecursive((Container)e, x, y);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(e is Toolbar)
|
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList)
|
||||||
e.Width = App.Width;
|
{
|
||||||
|
for(var i in _Drawings)
|
||||||
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
|
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||||
x = 0;
|
{
|
||||||
y = y + rowHeight;
|
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||||
rowHeight = 0;
|
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||||
|
{
|
||||||
|
component.OnRightClick(rt, .(mPos[0]-i.x, mPos[1]-i.y), pList);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 void AddChild(Component pToAdd)
|
|
||||||
{
|
|
||||||
_LayoutData.Add(pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InsertAfter(Component pToAdd, Component Position, bool pReorder = true)
|
|
||||||
{
|
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
|
||||||
idx++;
|
|
||||||
if(idx < 0)
|
|
||||||
{
|
|
||||||
delete pToAdd; //Avoid memory leaks
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_LayoutData.Insert(idx, pToAdd);
|
|
||||||
Children.Add(pToAdd);
|
|
||||||
pToAdd.Parent = this;
|
|
||||||
|
|
||||||
if(pReorder)
|
|
||||||
App.ForceReorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
///Forcefully terminates the current row
|
|
||||||
public void EndRow() => _LayoutData.Add(null);
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
for(var i in Children)
|
|
||||||
i.Render(soy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
for(var e in Children)
|
|
||||||
{
|
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
|
||||||
return e.OnClick(x, y);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnDown(int32 x, int32 y)
|
|
||||||
|
public 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))
|
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||||
return e.OnDown(x, y);
|
{
|
||||||
|
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||||
|
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||||
|
{
|
||||||
|
if(component.OnLeftClick(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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;
|
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(_Children.ContainsKeyAlt<StringView>(pName))
|
||||||
{
|
return .Err;
|
||||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
_Children.Add(new .(pName), pComponent);
|
||||||
e.OnRightClick(x, y, items);
|
return .Ok;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,57 +1,71 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Components.Internal;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Dropdown : Component
|
class Dropdown : Component
|
||||||
{
|
{
|
||||||
public List<String> Entries = new .() ~ DeleteContainerAndItems!(_);
|
private bool _Hovered = false;
|
||||||
public uint32 SelectedEntry = 0;
|
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;
|
for(var i in args)
|
||||||
Sprite = App.Textures.GetAsset("dropdown");
|
Options.Add(new .(i));
|
||||||
Width = Sprite.Width;
|
|
||||||
Height = Sprite.Height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y + soy, Tint);
|
if(_Hovered != _AlreadyHovered)
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Entries[(.)SelectedEntry], Theme.FontSize, 0);
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Entries[(.)SelectedEntry], Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(!Enabled)
|
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
_Hovered = _AlreadyHovered;
|
||||||
|
rt.Dirty();
|
||||||
}
|
}
|
||||||
else
|
_AlreadyHovered = false;
|
||||||
{
|
|
||||||
if(_IsHovered)
|
|
||||||
Sprite.Render(X,Y + soy, HoverTint);
|
|
||||||
}
|
|
||||||
_IsHovered = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
{
|
{
|
||||||
var list = new List<StringView>(Entries.Count);
|
_Pos = .(rect.x, rect.y + rect.height);
|
||||||
defer delete list;
|
rt.Platform.DrawTexture("Dropdown", rect, rt.Scheme.PrimaryColor);
|
||||||
for(var i in Entries)
|
if(_Hovered)
|
||||||
list.Add(i);
|
rt.Platform.DrawTexture("Dropdown", rect, rt.Scheme.HoverColor);
|
||||||
var popup = new DropdownPopup(X, Y + Height, Width, list);
|
|
||||||
popup.Owner = this;
|
var tsize = rt.Platform.MeasureTextSize(Options[Selected], "Font_Normal");
|
||||||
App.OpenPopup(popup);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ClickAction(String pNewVal);
|
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
{
|
||||||
_IsHovered = true;
|
var p = new DropdownPopup(Options) {Position = _Pos};
|
||||||
return this;
|
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;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
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;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
using System.Collections;
|
||||||
|
|
||||||
class Label : Component
|
class Label : Component
|
||||||
{
|
{
|
||||||
private Vector2 _Measure;
|
public String Label = null ~ delete _;
|
||||||
public this(StringView pName) : base(Label, pName)
|
|
||||||
|
public this(StringView pLabel)
|
||||||
{
|
{
|
||||||
Label = pName;
|
Label = new .(pLabel);
|
||||||
Margin = 3;
|
|
||||||
_Measure = Raylib.MeasureTextEx(Theme.FontLarge, Label.Ptr, Theme.FontSizeLarge, 0);
|
|
||||||
Height = (.)_Measure.y;
|
|
||||||
Width = (.)_Measure.x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y) => null;
|
public override void Update(TGRuntime rt)
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
{
|
||||||
Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, Vector2(X,Y + soy), Theme.FontSizeLarge, 0, Theme.Text);
|
|
||||||
Raylib.DrawLine(X,Y + (.)_Measure.y + soy,X + (.)_Measure.x, Y + (.)_Measure.y + soy, Theme.Text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
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 ~this()
|
||||||
public abstract void OnClose();
|
{
|
||||||
|
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;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
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)
|
||||||
}
|
|
||||||
|
|
||||||
///Set all of the fields to be used as checkboxes
|
|
||||||
public void SetBoxes(int32 selectedIndex, params Span<StringView> args)
|
|
||||||
{
|
|
||||||
Checked = selectedIndex;
|
|
||||||
//Clear out old ones
|
|
||||||
this.[Friend]_LayoutData.ClearAndDeleteItems();
|
|
||||||
Children.Clear();
|
|
||||||
|
|
||||||
for(var i in args)
|
|
||||||
{
|
{
|
||||||
var toAdd = new RadioCheckbox(i);
|
_Hovered = _AlreadyHovered;
|
||||||
toAdd.Description = Description;
|
rt.Dirty();
|
||||||
if(@i.Index == selectedIndex)
|
|
||||||
toAdd.Checked = true;
|
|
||||||
AddChild(toAdd);
|
|
||||||
EndRow();
|
|
||||||
}
|
}
|
||||||
|
_AlreadyHovered = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectButton(RadioCheckbox toSelect)
|
public override void Draw(TGRuntime rt, rect rect)
|
||||||
{
|
{
|
||||||
for(var i in Children)
|
int32 startingY = 0;
|
||||||
if(i == toSelect)
|
var textureSize = rt.Platform.MeasureTextureSize("Checkbox");
|
||||||
{
|
for(var i in Label)
|
||||||
((RadioCheckbox)i).Checked = true;
|
{
|
||||||
Checked = (.)@i.Index;
|
if(!(_Checked == (.)@i.Index))
|
||||||
OnCheck((.)@i.Index);
|
rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor);
|
||||||
}
|
|
||||||
else
|
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)
|
||||||
public override void OnCheck(bool checkValue)
|
xAddition = tsize[0] + 5;
|
||||||
{
|
|
||||||
((RadioButton)Parent).SelectButton(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textureSize[0] = textureSize[0] + xAddition;
|
||||||
|
textureSize[1] = (.)(textureSize[1] * Label.Count);
|
||||||
|
return textureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int32 GetSelectedItem(TGRuntime rt, int32[2] mPos)
|
||||||
|
{
|
||||||
|
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;
|
namespace TheaterGui.Components;
|
||||||
using TheaterGui;
|
using TheaterGui.Core;
|
||||||
|
|
||||||
using System;
|
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
|
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();
|
return base.OnHover(rt, .(mPos[0], (.)(mPos[1] + _ScrollValue)));
|
||||||
this.Height = Raylib.GetRenderHeight();
|
}
|
||||||
|
|
||||||
|
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;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Components.Internal;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
abstract class Toolbar : Component
|
class Toolbar : Component
|
||||||
{
|
{
|
||||||
public NPatchInfo PatchInfo;
|
private Dictionary<String, List<(String, delegate void(TGRuntime))>> _Items = new .() ~ delete _;
|
||||||
public List<ToolbarCategory> Categories = new .() ~ DeleteContainerAndItems!(_);
|
private StringView _Hovered = "";
|
||||||
private ToolbarPopup _CurrentPopup = null;
|
private StringView _AlreadyHovered = "";
|
||||||
private ToolbarCategory _SelectedPopup = null;
|
private int32 _Offset = 0;
|
||||||
|
|
||||||
public this(StringView pLabel) : base("Toolbar", pLabel)
|
public ~this()
|
||||||
{
|
{
|
||||||
Height = 24;
|
for(var i in _Items)
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 x = 5;
|
|
||||||
for(var i in Categories)
|
|
||||||
{
|
{
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), Vector2(X + x, Y + Height/2 - i.NameMeasurement.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
delete i.key;
|
||||||
if(i == _SelectedPopup)
|
for(var j in i.value)
|
||||||
{
|
{
|
||||||
//5 padding in every direction
|
delete j.0;
|
||||||
Raylib.DrawTextureNPatch(
|
delete j.1;
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X + x-5, Y + soy, i.NameMeasurement.x+10, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
}
|
||||||
|
delete i.value;
|
||||||
x += (.)i.NameMeasurement.x + 10;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override void Update(TGRuntime rt)
|
||||||
{
|
{
|
||||||
int32 hor = 10;
|
if(_Hovered != _AlreadyHovered)
|
||||||
for(var i in Categories)
|
|
||||||
{
|
{
|
||||||
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
_Hovered = _AlreadyHovered;
|
||||||
|
rt.Dirty();
|
||||||
|
}
|
||||||
|
_AlreadyHovered = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(TGRuntime rt, TheaterGui.Core.Structs.rect rect)
|
||||||
|
{
|
||||||
|
_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)
|
||||||
{
|
{
|
||||||
var popup = new ToolbarPopup(hor-10,Height + Y, i);
|
_AlreadyHovered = i.key;
|
||||||
popup.Owner = this;
|
if(rt.[Friend]_PopupsName == "Toolbar")
|
||||||
App.OpenPopup(popup);
|
{
|
||||||
_CurrentPopup = popup;
|
rt.ClearPopups();
|
||||||
|
OpenPopup(rt, .(xOffset, rt.Platform.MeasureTextSize("I", "Font_Normal")[1] + 4), i.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xOffset += tsize[0] + 10;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
hor += (.)i.NameMeasurement.x + 10;
|
|
||||||
|
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||||
|
xOffset += tsize[0] + 10;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||||
{
|
|
||||||
int32 hor = 10;
|
|
||||||
for(var i in Categories)
|
|
||||||
{
|
|
||||||
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
|
||||||
{
|
|
||||||
_SelectedPopup = i;
|
|
||||||
|
|
||||||
if(_CurrentPopup != null && _CurrentPopup.Category != i)
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
_CurrentPopup.Category = i;
|
val.Component(i.0);
|
||||||
_CurrentPopup.[Friend]X = hor-10;
|
val.Linebreak();
|
||||||
}
|
}
|
||||||
return this;
|
};
|
||||||
}
|
|
||||||
hor += (.)i.NameMeasurement.x + 10;
|
|
||||||
}
|
|
||||||
_SelectedPopup = null;
|
|
||||||
|
|
||||||
return null;
|
}
|
||||||
|
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)
|
if(!_Items.ContainsKeyAlt<StringView>(pSection))
|
||||||
Categories.Add(i);
|
_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 override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => true;
|
||||||
public class ToolbarCategory
|
|
||||||
{
|
|
||||||
private String _Name = null ~ delete _;
|
|
||||||
public Vector2 NameMeasurement = .(0,0);
|
|
||||||
public StringView Name
|
|
||||||
{
|
|
||||||
public get => (_Name != null) ? _Name : default;
|
|
||||||
public set
|
|
||||||
{
|
|
||||||
String.NewOrSet!(_Name, value);
|
|
||||||
NameMeasurement = Raylib.MeasureTextEx(Theme.Font, _Name, Theme.FontSize, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(StringView pName, params Span<ToolbarItem> pItems)
|
|
||||||
{
|
|
||||||
Name = pName;
|
|
||||||
for(var i in pItems)
|
|
||||||
Items.Add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ToolbarItem
|
|
||||||
{
|
|
||||||
private String _Name = null ~ delete _;
|
|
||||||
public Vector2 NameMeasurement = .(0,0);
|
|
||||||
public StringView Name
|
|
||||||
{
|
|
||||||
public get => (_Name != null) ? _Name : default;
|
|
||||||
public set
|
|
||||||
{
|
|
||||||
String.NewOrSet!(_Name, value);
|
|
||||||
NameMeasurement = Raylib.MeasureTextEx(Theme.Font, _Name, Theme.FontSize, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(StringView pName, delegate void() pClickAction)
|
|
||||||
{
|
|
||||||
Name = pName;
|
|
||||||
ClickAction = pClickAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void() ClickAction = null ~ delete _;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ToolbarItem> Items = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,116 +0,0 @@
|
||||||
namespace TheaterGui.Components;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class ToolbarPopup : Popup
|
|
||||||
{
|
|
||||||
public NPatchInfo PatchInfo;
|
|
||||||
public Toolbar Owner = null;
|
|
||||||
public Toolbar.ToolbarCategory.ToolbarItem SelectedItem = null;
|
|
||||||
|
|
||||||
private Toolbar.ToolbarCategory _Category = null;
|
|
||||||
public Toolbar.ToolbarCategory Category
|
|
||||||
{
|
|
||||||
get => _Category;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_Category = value;
|
|
||||||
int32 maxWidth = 0;
|
|
||||||
for(var i in _Category.Items)
|
|
||||||
if(maxWidth <= i.NameMeasurement.x)
|
|
||||||
maxWidth = (.)i.NameMeasurement.x;
|
|
||||||
|
|
||||||
Width = maxWidth + 10 + 32;
|
|
||||||
Height = (.)(5 +((_Category.NameMeasurement.y + 5) * _Category.Items.Count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, Toolbar.ToolbarCategory category) : base("ToolbarPopup", category.Name)
|
|
||||||
{
|
|
||||||
this.[Friend]X = x;
|
|
||||||
this.[Friend]Y = y-1;
|
|
||||||
Sprite = App.Textures.GetAsset("horizontal_patch");
|
|
||||||
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
|
||||||
Category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render(int32 soy)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + soy, Width, Height),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
Tint);
|
|
||||||
int32 y = 5;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), Vector2(X + 5 + 32, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
|
||||||
if(SelectedItem == i)
|
|
||||||
{
|
|
||||||
Raylib.DrawTextureNPatch(
|
|
||||||
*Sprite.Source,
|
|
||||||
PatchInfo,
|
|
||||||
Rectangle(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10),
|
|
||||||
Vector2(0,0),
|
|
||||||
0,
|
|
||||||
HoverTint);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Component OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
{
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
SelectedItem = i;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
SelectedItem = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
if(!(x >= X && x <= X + Width))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int32 pos = 5 + Y;
|
|
||||||
for(var i in Category.Items)
|
|
||||||
{
|
|
||||||
if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5)
|
|
||||||
{
|
|
||||||
if(i.ClickAction != null)
|
|
||||||
i.ClickAction();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pos += (.)i.NameMeasurement.y+5;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnClose()
|
|
||||||
{
|
|
||||||
if(Owner != null)
|
|
||||||
{
|
|
||||||
Owner.[Friend]_CurrentPopup = null;
|
|
||||||
Owner.[Friend]_SelectedPopup = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,76 @@
|
||||||
namespace TheaterGui.Components;
|
namespace TheaterGui.Components;
|
||||||
|
using TheaterGui.Core;
|
||||||
|
using TheaterGui.Core.Structs;
|
||||||
|
|
||||||
using System;
|
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