added most buttons

This commit is contained in:
Booklordofthedings 2024-06-02 17:57:52 +02:00
parent 9d20ae7cb0
commit 012f86413f
35 changed files with 941 additions and 226 deletions

BIN
assets/32.png~ Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

BIN
assets/button.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

BIN
assets/icon_folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

BIN
assets/icon_theater.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

BIN
assets/large_button.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/n_button.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
assets/n_button.png~ Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

BIN
assets/square_button.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

168
src/App.bf Normal file
View file

@ -0,0 +1,168 @@
namespace TheaterGui;
using TheaterGui.Controls;
using System;
using RaylibBeef;
class App
{
///Initialize the TheaterGui app
public static void Initialize(StringView pAppTitle = "TheaterApp")
{
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
Raylib.InitWindow(1280, 720, scope String(pAppTitle));
Raylib.SetExitKey(0);
Raylib.SetTargetFPS(40);
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);
//Load textures
Textures = new .();
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, 16, null, 256);
}
///Deinitialize the TheaterGui app
public static void Deinitialize()
{
}
///Start the application on the input stream
public static void Start(Screen pScreen)
{
Vector2 oldSize = .(0,0);
//For hover items
Vector2 oldPos = .(0,0);
double movTime = 0;
String hoverText = scope .();
CurrentScreen = pScreen;
while(!Raylib.WindowShouldClose())
{
if(oldSize != .(Width,Height))
{
CurrentScreen.Reorder(Width);
oldSize = .(Width,Height);
}
//This could probably be solved better
if(CurrentScreen.Height - Height > 0)
{
Wheel = -Wheel;
Wheel += 7 * Raylib.GetMouseWheelMove();
Wheel = Math.Clamp(Wheel, -1*(CurrentScreen.Height - Height), 0);
Wheel = -Wheel;
}
if(Raylib.IsMouseButtonPressed(0))
{
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
}
else
{
var hov = CurrentScreen.OnHover(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
if(hov != null)
{
if(hov.Enabled)
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_POINTING_HAND);
//TODO: If we go offscreen with the mouse it doesnt work anymore
if(oldPos != Mouse)
movTime = Raylib.GetTime();
if(Raylib.GetTime() - movTime >= 0.5)
hoverText.Append(hov.Description);
oldPos = Mouse;
}
else
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT);
}
//Drawing logic
Raylib.BeginDrawing();
Raylib.ClearBackground(Theme.Background);
CurrentScreen.Render();
if(hoverText != String.Empty)
{
int32 yOffset = 0;
int32 xOffset = 0;
//TODO: Curently just goes offscreen when it doesnt work
var measure = Raylib.MeasureTextEx(Theme.Font, hoverText, Theme.FontSize, 0);
if(Raylib.GetMouseX() < Width/2)
xOffset = 15;
else
xOffset = (.)(-1 * measure.x)-15;
if(Raylib.GetMouseY() < Height/2)
yOffset = 0;
else
yOffset = (.)(-1 * measure.y);
Raylib.DrawRectangle((.)Mouse.x-3+xOffset+3, (.)Mouse.y-3+yOffset+3, (.)measure.x+6, (.)measure.y+3, .(0, 0, 0, 70));
Raylib.DrawRectangle((.)Mouse.x-3+xOffset, (.)Mouse.y-3+yOffset, (.)measure.x+6, (.)measure.y+3, .(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.Font, hoverText, Raymath.Vector2Add(Mouse, .(xOffset,yOffset)), Theme.FontSize, 0, Raylib.BLACK);
}
Raylib.EndDrawing();
if(hoverText != String.Empty)
hoverText.Clear();
}
}
//
///Platform
//
//All loaded textures
public static Textures Textures ~ delete _;
private static Screen _CurrentScreen = null;
public static Screen CurrentScreen
{
get => _CurrentScreen;
set
{
if(_CurrentScreen != null)
delete _CurrentScreen;
_CurrentScreen = value;
}
};
///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;
}
public static GuiObject Selected
{
get;
set;
}
public static void ForceReorder()
{
CurrentScreen.Reorder(Width);
}
}

View file

@ -1,116 +0,0 @@
namespace TheaterGui;
using System;
using RaylibBeef;
class Application
{
//Letterboxing
private RenderTexture2D _RenderTexture;
private int32[2] _RTPosition = .(0,0);
private int32[2] _RTSize = .(0,0);
private int32[2] _RTOldSize = .(0,0); //How large was the window last time we checked
public this(StringView pAppTitle, int32 pWidth, int32 pHeight)
{
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
Raylib.InitWindow(pWidth, pHeight, scope String(pAppTitle));
Raylib.SetExitKey(0);
Raylib.SetTargetFPS(40);
var icon = Raylib.LoadImageFromMemory(".png", (.)&Assets.WindowIcon, Assets.WindowIcon.Count);
Raylib.SetWindowIcon(icon);
Raylib.UnloadImage(icon);
_RenderTexture = Raylib.LoadRenderTexture(1920, 1080);
Textures = new .();
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Assets.Din, Assets.Din.Count, 16, null, 256);
}
///Window width
public int32 Width
{
get => Raylib.GetRenderWidth();
set => Raylib.SetWindowSize(value, Raylib.GetRenderHeight());
}
///Window height
public int32 Height
{
get => Raylib.GetRenderHeight();
set => Raylib.SetWindowSize(Raylib.GetRenderWidth(), value);
}
public Vector2 MousePosition
{
get
{
var mouse = Raylib.GetMousePosition();
mouse.x -= _RTPosition[0];
mouse.y -= _RTPosition[1];
mouse.x = mouse.x / _RTSize[0] * 1920;
mouse.y = mouse.y / _RTSize[1] * 1080;
return mouse;
}
}
public Textures Textures ~ delete _;
public Screen CurrentScreen;
///Start the application displaying the input screen
public void Start(Screen pScreen)
{
pScreen.Parent = this;
CurrentScreen = pScreen;
while(!Raylib.WindowShouldClose())
{
Raylib.BeginDrawing();
Raylib.ClearBackground(Raylib.BLACK);
Raylib.BeginTextureMode(_RenderTexture); //Our render code goes here
Raylib.ClearBackground(Theme.BackgroundDark);
CurrentScreen.Render();
Raylib.EndTextureMode();
Raylib.DrawTexturePro(
_RenderTexture.texture,
.(0, 0, 1920, -1080),
.(_RTPosition[0], _RTPosition[1], _RTSize[0], _RTSize[1]), //Black bars
.(0,0),
0,
Raylib.WHITE
);
Raylib.EndDrawing();
UpdateLetterboxing();
}
}
///Letterboxing algo from TheaterEngine
private void UpdateLetterboxing()
{
var width = Raylib.GetRenderWidth();
var height = Raylib.GetRenderHeight();
if(!(width == _RTOldSize[0] && height == _RTOldSize[1]))
{ //We dont need to update if the window size hasnt changed
float maxWidth = width/16;
float maxHeight = height/9;
if(maxWidth < maxHeight)
{
_RTPosition[0] = 0;
_RTSize[0] = width;
_RTPosition[1] = (.)((height - maxWidth * 9) / 2);
_RTSize[1] = (.)(height - (height - maxWidth * 9));
}
else
{
_RTPosition[0] = (.)((width - maxHeight * 16) / 2);
_RTSize[0] = (.)(width - (width - maxHeight * 16));
_RTPosition[1] = 0;
_RTSize[1] = height;
}
_RTOldSize[0] = width;
_RTOldSize[1] = height;
}
}
}

View file

@ -1,11 +0,0 @@
namespace TheaterGui;
using System;
class Assets
{
public static uint8[?] WindowIcon = Compiler.ReadBinary("assets/64.png");
public static uint8[?] NPatch = Compiler.ReadBinary("assets/npatch.png");
public static uint8[?] Din = Compiler.ReadBinary("assets/din.ttf");
}

View file

@ -1,19 +1,57 @@
namespace TheaterGui.Controls;
using System;
using RaylibBeef;
class Button : Control
abstract class Button : GuiObject
{
public this()
public sprite Sprite;
public this(StringView pName, StringView pComponentName = "Button") : base(pComponentName, pName)
{
BoundingBox = .(0, 0, 400, 200);
Sprite = App.Textures.GetAsset("button");
Label.Append(pName);
Width = Sprite.Width;
Height = Sprite.Height;
}
protected bool _IsHovered = false;
public override GuiObject OnHover(int32 x, int32 y)
{
_IsHovered = true;
return this;
}
public override bool OnClick(int32 x, int32 y)
{
if(Rectangle(X, Y, Width, Height).Overlaps(x, y))
{
if(Enabled)
{
ClickAction();
return true;
}
return false;
}
return false;
}
public override void Render()
{
var s = Parent.Parent.Textures.GetAsset("npatch").Value;
NPatchInfo patchInfo = .(s.SourceRect,3,3,3,3,(.)NPatchLayout.NPATCH_NINE_PATCH);
Raylib.DrawTextureNPatch(*s.Source, patchInfo,.(BoundingBox.x,BoundingBox.y,400,200),.(0,0),0,Theme.Main);
Raylib.DrawTextEx(Theme.Font, "Button", .(BoundingBox.x + 3, BoundingBox.y + 4), 16, 0, Theme.Text);
Sprite.Render(X,Y, Tint);
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
Raylib.DrawTextEx(Theme.Font, Label, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
if(!Enabled)
{
Sprite.Render(X,Y, Theme.DisabledTint);
}
else
{
if(_IsHovered)
Sprite.Render(X,Y, HoverTint);
}
_IsHovered = false;
}
public abstract void ClickAction();
}

147
src/Controls/Container.bf Normal file
View file

@ -0,0 +1,147 @@
namespace TheaterGui.Controls;
using System;
using System.Collections;
class Container : GuiObject
{
private List<GuiObject> _LayoutData = new .() ~ delete _;
public List<GuiObject> Children = new .() ~ DeleteContainerAndItems!(_); //Entries => LayoutData without nulls
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
{
}
///Reorder all entries
/// @params w The Maximum width that the container should take
public virtual 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);
for(var i in ((Container)e).Children)
{
i.X += x + Padding + e.Padding;
i.Y += y + Padding + e.Padding;
}
}
if(x+e.Width+e.Padding > w-Padding) //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.X = x + e.Padding;
x = x + e.Width + 2*e.Padding;
e.Y = y + e.Padding;
if(x > maxWidth)
maxWidth = x;
if(rowHeight < e.Height+2*e.Padding)
rowHeight = e.Height+2*e.Padding;
}
Width = maxWidth + 2*Padding;
Height = y + rowHeight + 2*Padding;
}
///Add a new item to the list of items
public void AddChild(GuiObject pToAdd)
{
_LayoutData.Add(pToAdd);
Children.Add(pToAdd);
pToAdd.Parent = this;
}
public virtual void InsertBefore(GuiObject pToAdd, GuiObject 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(GuiObject pToAdd, GuiObject 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()
{
for(var i in Children)
i.Render();
}
public override bool OnClick(int32 x, int32 y)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
return e.OnClick(x, y);
}
return false;
}
public override GuiObject OnHover(int32 x, int32 y)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
return e.OnHover(x, y);
}
return null;
}
}

View file

@ -1,18 +0,0 @@
namespace TheaterGui.Controls;
using RaylibBeef;
//The base class for every control object
abstract class Control
{
public Rectangle BoundingBox = .(0,0,0,0);
public Screen Parent;
public abstract void Render();
/*
Reacting to clicks
Reacting to hover
While selected
*/
}

95
src/Controls/GuiObject.bf Normal file
View file

@ -0,0 +1,95 @@
namespace TheaterGui.Controls;
using System;
using System.Collections;
using RaylibBeef;
abstract class GuiObject
{
public String ComponentName = new .() ~ delete _;
public String Name = new .() ~ delete _;
public String Label = new .() ~ delete _;
public String Description = new .() ~ delete _;
public Color Tint = Theme.Tint;
public Color HoverTint = Theme.HoverTint;
public bool Enabled = true;
public this(StringView pComponentName, StringView pName)
{
ComponentName.Append(pComponentName);
Name.Append(pName);
}
private Container _Parent = null;
public Container Parent
{
get => _Parent;
set
{
OnParentChange(value);
_Parent = value;
}
};
public int32 Padding
{
get;
set;
} = 0;
public int32 X
{
get;
set;
} = 0;
public int32 Y
{
get;
set;
} = 0;
public int32 Width
{
public get;
protected set;
};
public int32 Height
{
public get;
protected set;
};
public bool Selected
{
get;
set
{
Selected = value;
App.Selected = this;
}
}
public Vector2 SizeOf()
{
return .(Width + 2*Padding, Height + 2*Padding);
}
///Returns true if the onclick has been handled
public virtual bool OnClick(int32 x, int32 y)
{
return false;
}
public abstract GuiObject OnHover(int32 x, int32 y);
//Called every frame if the object is selected
public virtual void WhileSelected()
{
}
public virtual void OnParentChange(Container pNewParent)
{
}
public virtual void Render()
{
}
}

View file

@ -0,0 +1,30 @@
namespace TheaterGui.Controls;
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()
{
Sprite.Render(X,Y, Tint);
Icon.Render(X+Width/2-Icon.Width/2+2,Y+Height/2-Icon.Height/2+2, .(0,0,0,125));
Icon.Render(X+Width/2-Icon.Width/2,Y+Height/2-Icon.Height/2);
if(_IsHovered)
Sprite.Render(X,Y, HoverTint);
_IsHovered = false;
}
}

17
src/Controls/Label.bf Normal file
View file

@ -0,0 +1,17 @@
namespace TheaterGui.Controls;
using System;
using RaylibBeef;
class Label : GuiObject
{
public this(StringView pName) : base(Label, pName)
{
Label.Append(pName);
}
public override GuiObject OnHover(int32 x, int32 y)
{
return this;
}
}

View file

@ -0,0 +1,24 @@
namespace TheaterGui.Controls;
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()
{
Sprite.Render(X,Y, Tint);
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
Raylib.DrawTextEx(Theme.Font, Label, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
if(_IsHovered)
Sprite.Render(X,Y, HoverTint);
_IsHovered = false;
}
}

56
src/Controls/NButton.bf Normal file
View file

@ -0,0 +1,56 @@
namespace TheaterGui.Controls;
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()
{
Raylib.DrawTextureNPatch(
*Sprite.Source,
PatchInfo,
.(X, Y, Width, Height),
.(0,0),
0,
Tint);
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
Raylib.DrawTextEx(Theme.Font, Label, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
if(!Enabled)
{
Raylib.DrawTextureNPatch(
*Sprite.Source,
PatchInfo,
.(X, Y, Width, Height),
.(0,0),
0,
Theme.DisabledTint);
}
else
{
if(_IsHovered)
Raylib.DrawTextureNPatch(
*Sprite.Source,
PatchInfo,
.(X, Y, Width, Height),
.(0,0),
0,
HoverTint);
}
_IsHovered = false;
}
}

View file

@ -0,0 +1,12 @@
namespace TheaterGui.Controls;
class Placeholder : GuiObject
{
public this(int32 w, int32 h) : base("Placeholder", "Placeholder")
{
Width = w;
Height = h;
}
public override GuiObject OnHover(int32 x, int32 y) => null;
}

18
src/Controls/Screen.bf Normal file
View file

@ -0,0 +1,18 @@
namespace TheaterGui.Controls;
using TheaterGui;
using System;
using System.Collections;
using RaylibBeef;
/*
While containers are sized depending on their parent, screens are sized depending on the user
*/
class Screen : Container
{
public this(StringView pName) : base(pName, "Screen")
{
this.Width = Raylib.GetRenderWidth();
this.Height = Raylib.GetRenderHeight();
}
}

View file

@ -1,19 +0,0 @@
namespace TheaterGui.Controls;
using RaylibBeef;
class Toolbar : Control
{
public this()
{
BoundingBox = .(0,0, 1920, 20);
}
public override void Render()
{
var s = Parent.Parent.Textures.GetAsset("npatch").Value;
NPatchInfo patchInfo = .(s.SourceRect,3,3,3,3,(.)NPatchLayout.NPATCH_NINE_PATCH);
Raylib.DrawTextureNPatch(*s.Source, patchInfo,.(BoundingBox.x,BoundingBox.y,1920,20),.(0,0),0,Theme.Main);
Raylib.DrawTextEx(Theme.Font, "File", .(BoundingBox.x + 3, BoundingBox.y + 4), 16, 0, Theme.Text);
}
}

15
src/Extensions.bf Normal file
View file

@ -0,0 +1,15 @@
namespace TheaterGui;
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;
}
}
}

View file

@ -0,0 +1,48 @@
namespace TheaterGui.Generators;
using System;
class ButtonGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : Button
{{
public this() : base("{name}")
{{
{!enabled ? "Enabled = false;" : ""}
Description.Append("{description}");
}}
//What happens when the button is clicked
public override void ClickAction()
{{
}}
}}
""");
}
}

View file

@ -0,0 +1,36 @@
namespace TheaterGui.Generators;
using System;
class ContainerGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : Screen
{{
public this() : base("{name}")
{{
//Add ui items here via AddChild() and terminate the row via EndRow()
}}
}}
""");
}
}

View file

@ -0,0 +1,49 @@
namespace TheaterGui.Generators;
using System;
class IconButtonGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : IconButton
{{
public this() : base("{name}")
{{
Icon = .Icon_Folder; //Use this to set the icon sprite
{!enabled ? "Enabled = false;" : ""}
Description.Append("{description}");
}}
//What happens when the button is clicked
public override void ClickAction()
{{
}}
}}
""");
}
}

View file

@ -0,0 +1,48 @@
namespace TheaterGui.Generators;
using System;
class LargeButtonGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : LargeButton
{{
public this() : base("{name}")
{{
{!enabled ? "Enabled = false;" : ""}
Description.Append("{description}");
}}
//What happens when the button is clicked
public override void ClickAction()
{{
}}
}}
""");
}
}

View file

@ -0,0 +1,48 @@
namespace TheaterGui.Generators;
using System;
class NButtonGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : NButton
{{
public this() : base("{name}")
{{
{!enabled ? "Enabled = false;" : ""}
Description.Append("{description}");
}}
//What happens when the button is clicked
public override void ClickAction()
{{
}}
}}
""");
}
}

View file

@ -0,0 +1,37 @@
namespace TheaterGui.Generators;
using System;
class ScreenGenerator : Compiler.Generator
{
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
outText.Append(scope $"""
namespace {Namespace};
using TheaterGui.Controls;
class TG{name} : Screen
{{
public this() : base("{name}")
{{
//Add ui items here via AddChild() and terminate the row via EndRow()
//The padding object can be used to add padding to every ui object
}}
}}
""");
}
}

View file

@ -1,44 +0,0 @@
namespace TheaterGui;
using TheaterGui.Controls;
using System;
using System.Collections;
using RaylibBeef;
class Screen
{
private List<Control> _Controls = new .() ~ DeleteContainerAndItems!(_);
//Used for layouting
private int32 _HighestY = 0; //"Highest" y value
private int32 _LowestY = 0; //"Lowest" y value
private int32 _X = 0; //Current X value
public Application Parent = null;
public void Render()
{
for(var i in _Controls)
i.Render();
}
///Add a control to the current screen
public void AddControl(Control pToAdd)
{
if(_X + pToAdd.BoundingBox.width >= 1920)
ForceNewRow();
pToAdd.BoundingBox.x = _X;
pToAdd.BoundingBox.y = _HighestY;
_X = _X + (.)pToAdd.BoundingBox.width; //Update to new x value
if(_HighestY + pToAdd.BoundingBox.height > _LowestY)
_LowestY = _HighestY + (.)pToAdd.BoundingBox.height;
_Controls.Add(pToAdd);
pToAdd.Parent = this;
}
///Force the next controls onto a newline
public void ForceNewRow()
{
_X = 0;
_HighestY = _LowestY;
}
}

View file

@ -8,18 +8,31 @@ class Textures
{
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
private List<RenderTexture> _Textures = new .() ~ delete _;
private Dictionary<String, sprite> _Map = new .() ~ DeleteDictionaryAndKeys!(_); //Mapped Textures
public this()
{
LoadAsset(Assets.NPatch, "npatch");
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_TheaterIcon, "theater_icon");
LoadAsset(Theme.Texture_FolderIcon, "folder_icon");
sprite.Icon_Folder = GetAsset("folder_icon");
sprite.Icon_Theater = GetAsset("theater_icon");
}
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
///Attempt to get a existing asset by StringView
public Result<sprite> GetAsset(StringView acess)
{
if (!_Map.ContainsKeyAlt<StringView>(acess))
if (!_TileMap.ContainsKeyAlt<StringView>(acess))
return .Err;
return .Ok(_Map[scope .(acess)]);
return .Ok(_TileMap[scope .(acess)]);
}
private void LoadAsset(Span<uint8> data, StringView name)
@ -27,7 +40,7 @@ class Textures
var img = Raylib.LoadImageFromMemory(".png", (.)data.Ptr, (.)data.Length);
defer Raylib.UnloadImage(img);
var s = Insert(img);
_Map.Add(new .(name), s);
_TileMap.Add(new .(name), s);
}
private sprite Insert(Image toInsert)
@ -137,8 +150,12 @@ struct sprite
public int32 Height = 0;
public float Rotation = 0;
public void Render(float x, float y)
public static sprite Icon_Folder;
public static sprite Icon_Theater;
public void Render(float x, float y, Color color = Raylib.WHITE)
{
Raylib.DrawTexturePro(*Source, SourceRect, .(x + Width / 2, y + Height / 2, Width, Height), .(Width / 2, Height / 2), Rotation, Raylib.WHITE);
Raylib.DrawTexturePro(*Source, SourceRect, .(x + Width / 2, y + Height / 2, Width, Height), .(Width / 2, Height / 2), Rotation, color);
}
}

View file

@ -1,14 +1,34 @@
namespace TheaterGui;
using System;
using RaylibBeef;
class Theme
public class Theme
{
public static Font Font ~ Raylib.UnloadFont(_);
public static int32 FontSize = 16;
public static Color BackgroundDark = .(45, 45, 49, 255);
public static Color Main = .(153, 36, 72 ,255);
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");
}