checkbox, radio button, and parts of the toolbar work now
This commit is contained in:
parent
d9b116f389
commit
70ea6d0555
32 changed files with 788 additions and 282 deletions
24
README.md
24
README.md
|
@ -1,3 +1,23 @@
|
||||||
# TheaterGui
|
# TheaterGui *A simple ui library*
|
||||||
|
*Tg* is inspired by Winforms, so most components require their own new classes, generated by the "New File" functionality of BeefIDE
|
||||||
|
|
||||||
Simple library to create graphical user interfaces
|
### Components
|
||||||
|
- Container
|
||||||
|
- Screen
|
||||||
|
- Button
|
||||||
|
|
||||||
|
### Layouting
|
||||||
|
*Tg* uses a layouting system thats partially inspired by HTML, though its significantly less powerfull but easier to implement and to grasp.
|
||||||
|
All components are put next to their immidiate left neighbor.
|
||||||
|
If an object would overflow outside of the view width, it will instead be forced down onto the next row.
|
||||||
|
Calling *EndRow()* manually will also force components into the next row.
|
||||||
|
The vertical position of the next row is determined by the height of the largest component in the row above, so that they never overlap.
|
||||||
|
If the screen height is larger than the view it will scroll.
|
||||||
|
Containers are a component, that can be used for more complicated layouts.
|
||||||
|
A container grows to fits its children but is still treated like a normal components.
|
||||||
|
So if part of your layout needs to be vertical you would put it inside of a container and then add the container normally
|
||||||
|
Every component also has a Margin property, to make things look better.
|
||||||
|
|
||||||
|
Whenever a component changes its size, the app will need to reorder its layout to fit everything.
|
||||||
|
*App.ForceReorder()* Is used for that. Most components will call it themselves if their size changes
|
||||||
|
If you want to change alot of sizes at once consider turning of *App.AllowReorder* and then manually calling it after you are done to increase the total speed.
|
BIN
assets/32.png~
BIN
assets/32.png~
Binary file not shown.
Before Width: | Height: | Size: 559 B |
BIN
assets/horizontal_patch.png
Normal file
BIN
assets/horizontal_patch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 207 B |
0
docs/Button.md
Normal file
0
docs/Button.md
Normal file
177
src/App.bf
177
src/App.bf
|
@ -1,14 +1,75 @@
|
||||||
namespace TheaterGui;
|
namespace TheaterGui;
|
||||||
using TheaterGui.Controls;
|
using TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//All loaded textures
|
||||||
|
private static List<Component> Popups = new .() ~ DeleteContainerAndItems!(_);
|
||||||
|
public static Textures Textures ~ delete _;
|
||||||
|
public static Component Selected; //Currently selected component
|
||||||
|
public static bool AllowReorder = true;
|
||||||
|
|
||||||
|
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 void ForceReorder()
|
||||||
|
{
|
||||||
|
if(AllowReorder && CurrentScreen != null)
|
||||||
|
CurrentScreen.Reorder(Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OpenPopup(Component popup)
|
||||||
|
{
|
||||||
|
Popups.Add(popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///Initialize the TheaterGui app
|
///Initialize the TheaterGui app
|
||||||
public static void Initialize(StringView pAppTitle = "TheaterApp")
|
public static void Initialize(StringView pAppTitle = "TheaterApp")
|
||||||
{
|
{
|
||||||
|
//Default raylib settings
|
||||||
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
||||||
Raylib.InitWindow(1280, 720, scope String(pAppTitle));
|
Raylib.InitWindow(1280, 720, scope String(pAppTitle));
|
||||||
Raylib.SetExitKey(0);
|
Raylib.SetExitKey(0);
|
||||||
|
@ -22,7 +83,10 @@ class App
|
||||||
|
|
||||||
//Load textures
|
//Load textures
|
||||||
Textures = new .();
|
Textures = new .();
|
||||||
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, 16, null, 256);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Deinitialize the TheaterGui app
|
///Deinitialize the TheaterGui app
|
||||||
|
@ -61,38 +125,64 @@ class App
|
||||||
|
|
||||||
if(Raylib.IsMouseButtonPressed(0))
|
if(Raylib.IsMouseButtonPressed(0))
|
||||||
{
|
{
|
||||||
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
|
if(Popups.Count > 0)
|
||||||
|
{
|
||||||
|
var top = Popups[Popups.Count-1];
|
||||||
|
if(Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), Raylib.GetMouseY()))
|
||||||
|
top.OnClick(Raylib.GetMouseX(), Raylib.GetMouseY());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Popups.Remove(top);
|
||||||
|
delete top;
|
||||||
|
|
||||||
|
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var hov = CurrentScreen.OnHover(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel));
|
if(Popups.Count > 0)
|
||||||
if(hov != null)
|
|
||||||
{
|
{
|
||||||
if(hov.Enabled)
|
var top = Popups[Popups.Count-1];
|
||||||
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_POINTING_HAND);
|
if(Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), Raylib.GetMouseY()))
|
||||||
//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
|
else
|
||||||
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT);
|
{
|
||||||
|
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
|
//Drawing logic
|
||||||
Raylib.BeginDrawing();
|
Raylib.BeginDrawing();
|
||||||
Raylib.ClearBackground(Theme.Background);
|
Raylib.ClearBackground(Theme.Background);
|
||||||
CurrentScreen.Render();
|
CurrentScreen.Render();
|
||||||
|
for(var i in Popups)
|
||||||
|
i.Render();
|
||||||
|
|
||||||
if(hoverText != String.Empty)
|
if(hoverText != String.Empty)
|
||||||
{
|
{ //TODO: When you move outside of the window, the hover fucks up
|
||||||
int32 yOffset = 0;
|
int32 yOffset = 0;
|
||||||
int32 xOffset = 0;
|
int32 xOffset = 0;
|
||||||
//TODO: Curently just goes offscreen when it doesnt work
|
var measure = Raylib.MeasureTextEx(Theme.FontSmall, hoverText, Theme.FontSizeSmall, 0);
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, hoverText, Theme.FontSize, 0);
|
|
||||||
if(Raylib.GetMouseX() < Width/2)
|
if(Raylib.GetMouseX() < Width/2)
|
||||||
xOffset = 15;
|
xOffset = 15;
|
||||||
else
|
else
|
||||||
|
@ -104,7 +194,7 @@ class App
|
||||||
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+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.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.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.DrawTextEx(Theme.FontSmall, hoverText, Raymath.Vector2Add(Mouse, .(xOffset,yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
Raylib.EndDrawing();
|
Raylib.EndDrawing();
|
||||||
|
@ -114,55 +204,14 @@ class App
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
///Checks wether any popup catches the hover, returns wether it has been caught
|
||||||
///Platform
|
public bool HandleHoverPopups()
|
||||||
//
|
|
||||||
|
|
||||||
//All loaded textures
|
|
||||||
public static Textures Textures ~ delete _;
|
|
||||||
|
|
||||||
private static Screen _CurrentScreen = null;
|
|
||||||
public static Screen CurrentScreen
|
|
||||||
{
|
{
|
||||||
get => _CurrentScreen;
|
//Topmost first
|
||||||
set
|
for(var i in Popups.Reversed)
|
||||||
{
|
{
|
||||||
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,22 +1,22 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
|
||||||
abstract class Button : GuiObject
|
abstract class Button : Component
|
||||||
{
|
{
|
||||||
public sprite Sprite;
|
public this(StringView pLabel, StringView pComponentName = "Button") : base(pComponentName, pLabel)
|
||||||
|
|
||||||
public this(StringView pName, StringView pComponentName = "Button") : base(pComponentName, pName)
|
|
||||||
{
|
{
|
||||||
Sprite = App.Textures.GetAsset("button");
|
Sprite = App.Textures.GetAsset("button");
|
||||||
Label.Append(pName);
|
|
||||||
Width = Sprite.Width;
|
Width = Sprite.Width;
|
||||||
Height = Sprite.Height;
|
Height = Sprite.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void ClickAction(); //What happends when its clicked
|
||||||
|
|
||||||
|
|
||||||
protected bool _IsHovered = false;
|
protected bool _IsHovered = false;
|
||||||
public override GuiObject OnHover(int32 x, int32 y)
|
public override Component OnHover(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
_IsHovered = true;
|
_IsHovered = true;
|
||||||
return this;
|
return this;
|
||||||
|
@ -39,8 +39,8 @@ abstract class Button : GuiObject
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y, Tint);
|
Sprite.Render(X,Y, Tint);
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
|
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), 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);
|
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
|
||||||
if(!Enabled)
|
if(!Enabled)
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y, Theme.DisabledTint);
|
Sprite.Render(X,Y, Theme.DisabledTint);
|
||||||
|
@ -52,6 +52,4 @@ abstract class Button : GuiObject
|
||||||
}
|
}
|
||||||
_IsHovered = false;
|
_IsHovered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ClickAction();
|
|
||||||
}
|
}
|
49
src/Components/Checkbox.bf
Normal file
49
src/Components/Checkbox.bf
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
abstract class Checkbox : Component
|
||||||
|
{
|
||||||
|
public sprite SpriteChecked;
|
||||||
|
|
||||||
|
public bool Checked = false;
|
||||||
|
|
||||||
|
public abstract void OnCheck(bool checkValue);
|
||||||
|
|
||||||
|
public this(StringView pName) : base("Checkbox", pName)
|
||||||
|
{
|
||||||
|
Sprite = App.Textures.GetAsset("checkbox");
|
||||||
|
SpriteChecked = App.Textures.GetAsset("checkbox_checked");
|
||||||
|
var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, Theme.FontSize, 0);
|
||||||
|
Width = Sprite.Width + (.)measure.x + 2;
|
||||||
|
Height = measure.y > Sprite.Height ? (.)measure.y : Sprite.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool _IsHovered = false;
|
||||||
|
public override Component OnHover(int32 x, int32 y)
|
||||||
|
{
|
||||||
|
_IsHovered = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnClick(int32 x, int32 y)
|
||||||
|
{
|
||||||
|
Checked = !Checked;
|
||||||
|
OnCheck(Checked);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
if(!Checked)
|
||||||
|
Sprite.Render(X,Y,Tint);
|
||||||
|
else
|
||||||
|
SpriteChecked.Render(X,Y,Tint);
|
||||||
|
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0);
|
||||||
|
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X + Sprite.Width + 2, (.)(Y + Sprite.Height/2 - 0.5*measure.y)), Theme.FontSize, 0, Theme.Text);
|
||||||
|
if(_IsHovered)
|
||||||
|
Sprite.Render(X,Y, HoverTint);
|
||||||
|
_IsHovered = false;
|
||||||
|
}
|
||||||
|
}
|
103
src/Components/Component.bf
Normal file
103
src/Components/Component.bf
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
abstract class Component
|
||||||
|
{
|
||||||
|
public this(StringView pComponentName, StringView pLabel)
|
||||||
|
{
|
||||||
|
_ComponentType.Append(pComponentName);
|
||||||
|
Label = pLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Fields
|
||||||
|
///
|
||||||
|
public Container Parent;
|
||||||
|
public bool Enabled = true;
|
||||||
|
|
||||||
|
public Color Tint = Theme.Tint;
|
||||||
|
public Color HoverTint = Theme.HoverTint;
|
||||||
|
public sprite Sprite;
|
||||||
|
|
||||||
|
public int32 MarginTop = 0;
|
||||||
|
public int32 MarginBottom = 0;
|
||||||
|
public int32 MarginLeft = 0;
|
||||||
|
public int32 MarginRight = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Properties
|
||||||
|
///
|
||||||
|
public bool Selected
|
||||||
|
{ //When something is selected its allowed to update every frame
|
||||||
|
get;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Selected = value;
|
||||||
|
App.Selected = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32 Margin
|
||||||
|
{
|
||||||
|
//There seems to be no reasonable way to implement a getter here
|
||||||
|
set
|
||||||
|
{
|
||||||
|
MarginTop = value;
|
||||||
|
MarginBottom = value;
|
||||||
|
MarginLeft = value;
|
||||||
|
MarginRight = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int32 _X = 0;
|
||||||
|
public int32 X
|
||||||
|
{
|
||||||
|
get => _X;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_X = value;
|
||||||
|
} //You may set this, but it might fuck up layouting
|
||||||
|
};
|
||||||
|
|
||||||
|
private int32 _Y = 0;
|
||||||
|
public int32 Y
|
||||||
|
{
|
||||||
|
get => _Y;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_Y = value;
|
||||||
|
} //You may set this, but it might fuck up layouting
|
||||||
|
};
|
||||||
|
|
||||||
|
public int32 Width
|
||||||
|
{
|
||||||
|
public get;
|
||||||
|
protected set; //Please do not
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32 Height
|
||||||
|
{
|
||||||
|
public get;
|
||||||
|
protected set; //Please do not
|
||||||
|
}
|
||||||
|
|
||||||
|
[DynamicString] //What this type of component is called
|
||||||
|
private String _ComponentType = new .() ~ delete _;
|
||||||
|
[DynamicString] //What the component says on it when rendered
|
||||||
|
private String _Label = null ~ delete _;
|
||||||
|
[DynamicString] //Usually only used by the OnHover tooltip
|
||||||
|
private String _Description = null ~ delete _;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Functions
|
||||||
|
///
|
||||||
|
public abstract void Render();
|
||||||
|
|
||||||
|
public virtual bool OnClick(int32 x, int32 y) => false;
|
||||||
|
public abstract Component OnHover(int32 x, int32 y);
|
||||||
|
|
||||||
|
public virtual void WhileSelected() { }
|
||||||
|
}
|
|
@ -1,20 +1,21 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
class Container : GuiObject
|
class Container : Component
|
||||||
{
|
{
|
||||||
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)
|
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Reorder all entries
|
private List<Component> _LayoutData = new .() ~ delete _;
|
||||||
/// @params w The Maximum width that the container should take
|
public List<Component> Children = new .() ~ DeleteContainerAndItems!(_);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///Recalculate the layout of all entries
|
||||||
public virtual void Reorder(int32 w)
|
public virtual void Reorder(int32 w)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -47,13 +48,12 @@ class Container : GuiObject
|
||||||
if(e is Container)
|
if(e is Container)
|
||||||
{
|
{
|
||||||
((Container)e).Reorder(w);
|
((Container)e).Reorder(w);
|
||||||
for(var i in ((Container)e).Children)
|
MoveChildrenRecursive((Container)e, x, y);
|
||||||
{
|
|
||||||
i.X += x + MarginLeft + e.MarginLeft;
|
|
||||||
i.Y += y + MarginTop + e.MarginTop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
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
|
{ //Automatic row break
|
||||||
x = 0;
|
x = 0;
|
||||||
|
@ -61,9 +61,9 @@ class Container : GuiObject
|
||||||
rowHeight = 0;
|
rowHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.X = x + e.MarginLeft;
|
e.[Friend]X = x + e.MarginLeft;
|
||||||
x = x + e.Width + e.MarginLeft + e.MarginRight;
|
x = x + e.Width + e.MarginLeft + e.MarginRight;
|
||||||
e.Y = y + e.MarginTop;
|
e.[Friend]Y = y + e.MarginTop;
|
||||||
if(x > maxWidth)
|
if(x > maxWidth)
|
||||||
maxWidth = x;
|
maxWidth = x;
|
||||||
|
|
||||||
|
@ -75,15 +75,26 @@ class Container : GuiObject
|
||||||
Height = y + rowHeight + MarginTop + MarginBottom;
|
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
|
///Add a new item to the list of items
|
||||||
public void AddChild(GuiObject pToAdd)
|
public void AddChild(Component pToAdd)
|
||||||
{
|
{
|
||||||
_LayoutData.Add(pToAdd);
|
_LayoutData.Add(pToAdd);
|
||||||
Children.Add(pToAdd);
|
Children.Add(pToAdd);
|
||||||
pToAdd.Parent = this;
|
pToAdd.Parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void InsertBefore(GuiObject pToAdd, GuiObject Position, bool pReorder = true)
|
public virtual void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
|
||||||
{
|
{
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
var idx = _LayoutData.IndexOf(Position);
|
||||||
if(idx < 0)
|
if(idx < 0)
|
||||||
|
@ -99,7 +110,7 @@ class Container : GuiObject
|
||||||
App.ForceReorder();
|
App.ForceReorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void InsertAfter(GuiObject pToAdd, GuiObject Position, bool pReorder = true)
|
public virtual void InsertAfter(Component pToAdd, Component Position, bool pReorder = true)
|
||||||
{
|
{
|
||||||
var idx = _LayoutData.IndexOf(Position);
|
var idx = _LayoutData.IndexOf(Position);
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -122,7 +133,9 @@ class Container : GuiObject
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
for(var i in Children)
|
for(var i in Children)
|
||||||
i.Render();
|
{
|
||||||
|
i.Render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnClick(int32 x, int32 y)
|
public override bool OnClick(int32 x, int32 y)
|
||||||
|
@ -135,7 +148,7 @@ class Container : GuiObject
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override GuiObject OnHover(int32 x, int32 y)
|
public override Component OnHover(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
for(var e in Children)
|
for(var e in Children)
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
25
src/Components/Label.bf
Normal file
25
src/Components/Label.bf
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
class Label : Component
|
||||||
|
{
|
||||||
|
private Vector2 _Measure;
|
||||||
|
public this(StringView pName) : base(Label, pName)
|
||||||
|
{
|
||||||
|
Label = pName;
|
||||||
|
Margin = 3;
|
||||||
|
_Measure = Raylib.MeasureTextEx(Theme.FontLarge, Label.Ptr, Theme.FontSizeLarge, 0);
|
||||||
|
Height = (.)_Measure.y;
|
||||||
|
Width = (.)_Measure.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Component OnHover(int32 x, int32 y) => null;
|
||||||
|
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, .(X,Y), Theme.FontSizeLarge, 0, Theme.Text);
|
||||||
|
Raylib.DrawLine(X,Y + (.)_Measure.y,X + (.)_Measure.x, Y + (.)_Measure.y, Theme.Text);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
@ -15,8 +15,8 @@ abstract class LargeButton : Button
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
Sprite.Render(X,Y, Tint);
|
Sprite.Render(X,Y, Tint);
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
|
var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, 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);
|
Raylib.DrawTextEx(Theme.Font, Label.Ptr, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
|
||||||
if(_IsHovered)
|
if(_IsHovered)
|
||||||
Sprite.Render(X,Y, HoverTint);
|
Sprite.Render(X,Y, HoverTint);
|
||||||
_IsHovered = false;
|
_IsHovered = false;
|
|
@ -1,4 +1,4 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using RaylibBeef;
|
using RaylibBeef;
|
||||||
|
@ -27,8 +27,8 @@ abstract class NButton : Button
|
||||||
0,
|
0,
|
||||||
Tint);
|
Tint);
|
||||||
|
|
||||||
var measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
|
var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), 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);
|
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text);
|
||||||
|
|
||||||
if(!Enabled)
|
if(!Enabled)
|
||||||
{
|
{
|
13
src/Components/Placeholder.bf
Normal file
13
src/Components/Placeholder.bf
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
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() {}
|
||||||
|
}
|
62
src/Components/RadioButton.bf
Normal file
62
src/Components/RadioButton.bf
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
abstract class RadioButton : Container
|
||||||
|
{
|
||||||
|
public int32 Checked = -1;
|
||||||
|
|
||||||
|
public this(StringView pName) : base(pName, "RadioButtons")
|
||||||
|
{
|
||||||
|
Description = pName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnCheck(int32 value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///Set all of the fields to be used as checkboxes
|
||||||
|
public void SetBoxes(int32 selectedIndex, params Span<StringView> args)
|
||||||
|
{
|
||||||
|
Checked = selectedIndex;
|
||||||
|
//Clear out old ones
|
||||||
|
this.[Friend]_LayoutData.ClearAndDeleteItems();
|
||||||
|
Children.Clear();
|
||||||
|
|
||||||
|
for(var i in args)
|
||||||
|
{
|
||||||
|
var toAdd = new RadioCheckbox(i);
|
||||||
|
toAdd.Description = Description;
|
||||||
|
if(@i.Index == selectedIndex)
|
||||||
|
toAdd.Checked = true;
|
||||||
|
AddChild(toAdd);
|
||||||
|
EndRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectButton(RadioCheckbox toSelect)
|
||||||
|
{
|
||||||
|
for(var i in Children)
|
||||||
|
if(i == toSelect)
|
||||||
|
{
|
||||||
|
((RadioCheckbox)i).Checked = true;
|
||||||
|
Checked = (.)@i.Index;
|
||||||
|
OnCheck((.)@i.Index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
((RadioCheckbox)i).Checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RadioCheckbox : Checkbox
|
||||||
|
{
|
||||||
|
public this(StringView pName) : base(pName)
|
||||||
|
{
|
||||||
|
Margin = 2;
|
||||||
|
}
|
||||||
|
public override void OnCheck(bool checkValue)
|
||||||
|
{
|
||||||
|
((RadioButton)Parent).SelectButton(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace TheaterGui.Controls;
|
namespace TheaterGui.Components;
|
||||||
using TheaterGui;
|
using TheaterGui;
|
||||||
|
|
||||||
using System;
|
using System;
|
142
src/Components/Toolbar.bf
Normal file
142
src/Components/Toolbar.bf
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
class Toolbar : Component
|
||||||
|
{
|
||||||
|
public NPatchInfo PatchInfo;
|
||||||
|
public List<ToolbarCategory> Categories = new .() ~ DeleteContainerAndItems!(_);
|
||||||
|
private ToolbarPopup _CurrentPopup = null;
|
||||||
|
private ToolbarCategory _HoveredPopup = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public this(StringView pLabel) : base("Toolbar", pLabel)
|
||||||
|
{
|
||||||
|
Height = 24;
|
||||||
|
Sprite = App.Textures.GetAsset("horizontal_patch");
|
||||||
|
PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH);
|
||||||
|
|
||||||
|
Categories.Add(new .("File", new .("Load file",null), new .("Save file",null), new .("Recent Files",null)));
|
||||||
|
Categories.Add(new .("Edit", new .("Revert",null), new .("Really long thing goes here",null)));
|
||||||
|
Categories.Add(new .("Secret third thing", new .("Load file",null), new .("Save file",null), new .("Recent Files",null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
Raylib.DrawTextureNPatch(
|
||||||
|
*Sprite.Source,
|
||||||
|
PatchInfo,
|
||||||
|
.(X, Y, Width, Height),
|
||||||
|
.(0,0),
|
||||||
|
0,
|
||||||
|
Tint);
|
||||||
|
int32 x = 5;
|
||||||
|
for(var i in Categories)
|
||||||
|
{
|
||||||
|
Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), .(X + x, Y + Height/2 - i.NameMeasurement.y/2), Theme.FontSize, 0, Theme.Text);
|
||||||
|
if(i == _HoveredPopup)
|
||||||
|
{
|
||||||
|
//5 padding in every direction
|
||||||
|
Raylib.DrawTextureNPatch(
|
||||||
|
*Sprite.Source,
|
||||||
|
PatchInfo,
|
||||||
|
.(X + x-5, Y, i.NameMeasurement.x+10, Height),
|
||||||
|
.(0,0),
|
||||||
|
0,
|
||||||
|
HoverTint);
|
||||||
|
}
|
||||||
|
|
||||||
|
x += (.)i.NameMeasurement.x + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnClick(int32 x, int32 y)
|
||||||
|
{
|
||||||
|
int32 hor = 10;
|
||||||
|
for(var i in Categories)
|
||||||
|
{
|
||||||
|
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
||||||
|
{
|
||||||
|
var popup = new ToolbarPopup(hor-10,Height, i);
|
||||||
|
App.OpenPopup(popup);
|
||||||
|
_CurrentPopup = popup;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
hor += (.)i.NameMeasurement.x + 10;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Component OnHover(int32 x, int32 y)
|
||||||
|
{
|
||||||
|
int32 hor = 10;
|
||||||
|
for(var i in Categories)
|
||||||
|
{
|
||||||
|
if(x >= hor && x <= hor + i.NameMeasurement.x)
|
||||||
|
{
|
||||||
|
_HoveredPopup = i;
|
||||||
|
|
||||||
|
if(_CurrentPopup != null && _CurrentPopup.Category != i)
|
||||||
|
{
|
||||||
|
_CurrentPopup.Category = i;
|
||||||
|
_CurrentPopup.[Friend]X = hor-10;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
hor += (.)i.NameMeasurement.x + 10;
|
||||||
|
}
|
||||||
|
_HoveredPopup = null;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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!(_);
|
||||||
|
}
|
||||||
|
}
|
57
src/Components/ToolbarPopup.bf
Normal file
57
src/Components/ToolbarPopup.bf
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
namespace TheaterGui.Components;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using RaylibBeef;
|
||||||
|
|
||||||
|
class ToolbarPopup : Component
|
||||||
|
{
|
||||||
|
public NPatchInfo PatchInfo;
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
Raylib.DrawTextureNPatch(
|
||||||
|
*Sprite.Source,
|
||||||
|
PatchInfo,
|
||||||
|
.(X, Y, Width, Height),
|
||||||
|
.(0,0),
|
||||||
|
0,
|
||||||
|
Tint);
|
||||||
|
int32 y = 5;
|
||||||
|
for(var i in Category.Items)
|
||||||
|
{
|
||||||
|
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), .(X + 5 + 32, Y + y), Theme.FontSize, 0, Theme.Text);
|
||||||
|
y += (.)i.NameMeasurement.y+5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Component OnHover(int32 x, int32 y)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
namespace TheaterGui.Controls;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
class Checkbox : GuiObject
|
|
||||||
{
|
|
||||||
public sprite Sprite;
|
|
||||||
public sprite SpriteChecked;
|
|
||||||
|
|
||||||
public override GuiObject OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(StringView pName) : base("Checkbox", pName)
|
|
||||||
{
|
|
||||||
Sprite = App.Textures.GetAsset("checkbox");
|
|
||||||
SpriteChecked = App.Textures.GetAsset("checkbox_checked");
|
|
||||||
Label.Append(pName);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///Margin stuff
|
|
||||||
public int32 MarginTop = 0;
|
|
||||||
public int32 MarginBottom = 0;
|
|
||||||
public int32 MarginLeft = 0;
|
|
||||||
public int32 MarginRight = 0;
|
|
||||||
public int32 Margin
|
|
||||||
{
|
|
||||||
//There seems to be no reasonable way to implement a getter here
|
|
||||||
set
|
|
||||||
{
|
|
||||||
MarginTop = value;
|
|
||||||
MarginBottom = value;
|
|
||||||
MarginLeft = value;
|
|
||||||
MarginRight = value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
get => .(Width + MarginLeft + MarginRight, Height + MarginTop + MarginBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
///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()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
namespace TheaterGui.Controls;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using RaylibBeef;
|
|
||||||
|
|
||||||
class Label : GuiObject
|
|
||||||
{
|
|
||||||
private Vector2 _Measure;
|
|
||||||
public this(StringView pName) : base(Label, pName)
|
|
||||||
{
|
|
||||||
Label.Append(pName);
|
|
||||||
Margin = 3;
|
|
||||||
_Measure = Raylib.MeasureTextEx(Theme.Font, Label, Theme.FontSize, 0);
|
|
||||||
Height = (.)_Measure.y;
|
|
||||||
Width = (.)_Measure.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override GuiObject OnHover(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Render()
|
|
||||||
{
|
|
||||||
Raylib.DrawTextEx(Theme.Font, Label, .(X,Y), Theme.FontSize, 0, Theme.Text);
|
|
||||||
Raylib.DrawLine(X,Y + (.)_Measure.y,X + (.)_Measure.x, Y + (.)_Measure.y, Theme.Text);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,15 +1,34 @@
|
||||||
namespace TheaterGui;
|
|
||||||
|
|
||||||
namespace RaylibBeef
|
namespace RaylibBeef
|
||||||
{
|
{
|
||||||
extension Rectangle
|
extension Rectangle
|
||||||
{
|
{
|
||||||
public bool Overlaps(int32 x, int32 y)
|
public bool Overlaps(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
if(x >= this.x && x <= this.x + this.width)
|
if (x >= this.x && x <= this.x + this.width)
|
||||||
if(y >= this.y && y <= this.y + this.height)
|
if (y >= this.y && y <= this.y + this.height)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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};
|
||||||
|
public set => String.NewOrSet!({fieldInfo.Name}, value);
|
||||||
|
}};
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -34,7 +34,7 @@ class ButtonGenerator : Compiler.Generator
|
||||||
public this() : base("{name}")
|
public this() : base("{name}")
|
||||||
{{
|
{{
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
{!enabled ? "Enabled = false;" : ""}
|
||||||
Description.Append("{description}");
|
Description = "{description}";
|
||||||
}}
|
}}
|
||||||
|
|
||||||
//What happens when the button is clicked
|
//What happens when the button is clicked
|
||||||
|
|
48
src/Generators/CheckboxGenerator.bf
Normal file
48
src/Generators/CheckboxGenerator.bf
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
namespace TheaterGui.Generators;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
class CheckboxGenerator : Compiler.Generator
|
||||||
|
{
|
||||||
|
public override String Name => "TheaterGui -> Generate 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 $"TG{name}");
|
||||||
|
|
||||||
|
outText.Append(scope $"""
|
||||||
|
namespace {Namespace};
|
||||||
|
|
||||||
|
using TheaterGui.Controls;
|
||||||
|
|
||||||
|
class TG{name} : Checkbox
|
||||||
|
{{
|
||||||
|
public this() : base("{name}")
|
||||||
|
{{
|
||||||
|
{!enabled ? "Enabled = false;" : ""}
|
||||||
|
Description = "{description}";
|
||||||
|
}}
|
||||||
|
|
||||||
|
//What happens when the button is clicked
|
||||||
|
public override void OnCheck(bool checkValue)
|
||||||
|
{{
|
||||||
|
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ class IconButtonGenerator : Compiler.Generator
|
||||||
{{
|
{{
|
||||||
Icon = .Icon_Folder; //Use this to set the icon sprite
|
Icon = .Icon_Folder; //Use this to set the icon sprite
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
{!enabled ? "Enabled = false;" : ""}
|
||||||
Description.Append("{description}");
|
Description = "{description}";
|
||||||
}}
|
}}
|
||||||
|
|
||||||
//What happens when the button is clicked
|
//What happens when the button is clicked
|
||||||
|
|
|
@ -34,7 +34,7 @@ class LargeButtonGenerator : Compiler.Generator
|
||||||
public this() : base("{name}")
|
public this() : base("{name}")
|
||||||
{{
|
{{
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
{!enabled ? "Enabled = false;" : ""}
|
||||||
Description.Append("{description}");
|
Description = "{description}";
|
||||||
}}
|
}}
|
||||||
|
|
||||||
//What happens when the button is clicked
|
//What happens when the button is clicked
|
||||||
|
|
|
@ -34,7 +34,7 @@ class NButtonGenerator : Compiler.Generator
|
||||||
public this() : base("{name}")
|
public this() : base("{name}")
|
||||||
{{
|
{{
|
||||||
{!enabled ? "Enabled = false;" : ""}
|
{!enabled ? "Enabled = false;" : ""}
|
||||||
Description.Append("{description}");
|
Description = "{description}";
|
||||||
}}
|
}}
|
||||||
|
|
||||||
//What happens when the button is clicked
|
//What happens when the button is clicked
|
||||||
|
|
48
src/Generators/RadioButtonGenerator.bf
Normal file
48
src/Generators/RadioButtonGenerator.bf
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
namespace TheaterGui.Generators;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
class RadioButtonGenerator : Compiler.Generator
|
||||||
|
{
|
||||||
|
public override String Name => "TheaterGui -> Generate Radio Button"
|
||||||
|
|
||||||
|
public override void InitUI()
|
||||||
|
{
|
||||||
|
AddEdit("name", "ComponentName 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} : 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)
|
||||||
|
{{
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
21
src/PlatformLayer.bf
Normal file
21
src/PlatformLayer.bf
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
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,6 +17,8 @@ class Textures
|
||||||
LoadAsset(Theme.Texture_LargeButton, "large_button");
|
LoadAsset(Theme.Texture_LargeButton, "large_button");
|
||||||
LoadAsset(Theme.Texture_Checkbox, "checkbox");
|
LoadAsset(Theme.Texture_Checkbox, "checkbox");
|
||||||
LoadAsset(Theme.Texture_Checkbox_Checked, "checkbox_checked");
|
LoadAsset(Theme.Texture_Checkbox_Checked, "checkbox_checked");
|
||||||
|
LoadAsset(Theme.Horizontal_Patch, "horizontal_patch");
|
||||||
|
|
||||||
|
|
||||||
LoadAsset(Theme.Texture_TheaterIcon, "theater_icon");
|
LoadAsset(Theme.Texture_TheaterIcon, "theater_icon");
|
||||||
LoadAsset(Theme.Texture_FolderIcon, "folder_icon");
|
LoadAsset(Theme.Texture_FolderIcon, "folder_icon");
|
||||||
|
|
|
@ -6,7 +6,12 @@ using RaylibBeef;
|
||||||
public class Theme
|
public class Theme
|
||||||
{
|
{
|
||||||
public static Font Font ~ Raylib.UnloadFont(_);
|
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 FontSize = 16;
|
||||||
|
public static int32 FontSizeLarge = 20;
|
||||||
|
public static int32 FontSizeSmall = 12;
|
||||||
|
|
||||||
public static Color Background = .(45, 45, 49, 255);
|
public static Color Background = .(45, 45, 49, 255);
|
||||||
public static Color Tint = .(153, 36, 72, 255);
|
public static Color Tint = .(153, 36, 72, 255);
|
||||||
|
@ -29,5 +34,7 @@ public class Theme
|
||||||
public static uint8[?] Texture_Button = Compiler.ReadBinary("assets/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 = Compiler.ReadBinary("assets/checkbox.png");
|
||||||
public static uint8[?] Texture_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png");
|
public static uint8[?] Texture_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png");
|
||||||
|
public static uint8[?] Horizontal_Patch = Compiler.ReadBinary("assets/horizontal_patch.png");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue