added most buttons
BIN
assets/32.png~
Normal file
After Width: | Height: | Size: 559 B |
BIN
assets/button.png
Normal file
After Width: | Height: | Size: 534 B |
BIN
assets/icon_folder.png
Normal file
After Width: | Height: | Size: 349 B |
BIN
assets/icon_theater.png
Normal file
After Width: | Height: | Size: 596 B |
BIN
assets/large_button.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/n_button.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/n_button.png~
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 189 B |
BIN
assets/square_button.png
Normal file
After Width: | Height: | Size: 673 B |
BIN
assets/square_button_hover.png
Normal file
After Width: | Height: | Size: 717 B |
168
src/App.bf
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
30
src/Controls/IconButton.bf
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
24
src/Controls/LargeButton.bf
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
12
src/Controls/Placeholder.bf
Normal 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
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
48
src/Generators/ButtonGenerator.bf
Normal 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()
|
||||
{{
|
||||
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
36
src/Generators/ContainerGenerator.bf
Normal 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()
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
49
src/Generators/IconButtonGenerator.bf
Normal 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()
|
||||
{{
|
||||
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
48
src/Generators/LargeButtonGenerator.bf
Normal 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()
|
||||
{{
|
||||
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
48
src/Generators/NButtonGenerator.bf
Normal 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()
|
||||
{{
|
||||
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
37
src/Generators/ScreenGenerator.bf
Normal 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
|
||||
}}
|
||||
}}
|
||||
""");
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
26
src/Theme.bf
|
@ -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");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|