Fixed some stuff, added basic popups and more
This commit is contained in:
parent
c0dd04127c
commit
46ea31a118
14 changed files with 750 additions and 24 deletions
|
@ -3,3 +3,6 @@ Projects = {TheaterGui = {Path = "."}, examples = {Path = "examples"}, Bofa = {P
|
|||
|
||||
[Workspace]
|
||||
StartupProject = "examples"
|
||||
|
||||
[Configs.Debug.Win64]
|
||||
ConfigSelections = {raylib-beef = {Config = "StaticDebug"}}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
namespace examples;
|
||||
|
||||
using System;
|
||||
|
||||
using TheaterGui;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
|
||||
class Program
|
||||
{
|
||||
|
@ -16,18 +19,83 @@ class Program
|
|||
}
|
||||
}
|
||||
|
||||
class MainScreen : Container
|
||||
class MainScreen : Screen
|
||||
{
|
||||
public this()
|
||||
{
|
||||
AddChild("Main Button", new Button());
|
||||
AddChild("Other Button", new Button());
|
||||
Toolbar toAdd = new .();
|
||||
toAdd.AddEntry("File", "Open File", new (rt) => {Console.WriteLine("Open file");});
|
||||
toAdd.AddEntry("Edit", "Go back", new (rt) => {Console.WriteLine("Go back");});
|
||||
toAdd.AddEntry("Edit", "Open File", new (rt) => {Console.WriteLine("Open File");});
|
||||
toAdd.AddEntry("Window", "Open File", new (rt) => {Console.WriteLine("Open File");});
|
||||
|
||||
|
||||
|
||||
|
||||
AddChild("Toolbar", toAdd);
|
||||
AddChild("Button", new Button(new (val) => {Console.WriteLine("Hellau :)");}));
|
||||
|
||||
|
||||
|
||||
Layout = new (val, width) =>
|
||||
{
|
||||
val.Component("Main Button", 5);
|
||||
val.Component("Other Button", 10);
|
||||
val.Component("Toolbar");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
val.Component("Button");
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,23 @@ extension PlatformRaylib
|
|||
{
|
||||
public void StartDrawing()
|
||||
{
|
||||
if(Raylib.GetMouseDelta().x + Raylib.GetMouseDelta().y != 0)
|
||||
{
|
||||
if(targetFps != 40)
|
||||
{
|
||||
Raylib.SetTargetFPS(40);
|
||||
targetFps = 40;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(targetFps != 20)
|
||||
{
|
||||
Raylib.SetTargetFPS(20);
|
||||
targetFps = 20;
|
||||
}
|
||||
}
|
||||
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.ClearBackground(_BackgroundColor);
|
||||
Raylib.BeginTextureMode(_ScreenTexture);
|
||||
|
@ -31,8 +48,27 @@ extension PlatformRaylib
|
|||
Raylib.EndDrawing();
|
||||
}
|
||||
|
||||
private int32 targetFps = 40;
|
||||
|
||||
public void RedrawLastFrame()
|
||||
{
|
||||
if(Raylib.GetMouseDelta().x + Raylib.GetMouseDelta().y != 0)
|
||||
{
|
||||
if(targetFps != 40)
|
||||
{
|
||||
Raylib.SetTargetFPS(40);
|
||||
targetFps = 40;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(targetFps != 20)
|
||||
{
|
||||
Raylib.SetTargetFPS(20);
|
||||
targetFps = 20;
|
||||
}
|
||||
}
|
||||
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.ClearBackground(_BackgroundColor);
|
||||
Raylib.DrawTexturePro(
|
||||
|
@ -43,6 +79,9 @@ extension PlatformRaylib
|
|||
0,
|
||||
Raylib.WHITE
|
||||
);
|
||||
#if DEBUG
|
||||
Raylib.DrawRectangle(0,0,5,5, Raylib.PINK);
|
||||
#endif
|
||||
Raylib.EndDrawing();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class App
|
|||
private colorScheme _Scheme = .DefaultScheme;
|
||||
private theme _Theme = .();
|
||||
|
||||
public Result<void> Run(Container pScreen)
|
||||
public Result<void> Run(Screen pScreen)
|
||||
{
|
||||
if(_Platform == null)
|
||||
return .Err;
|
||||
|
|
|
@ -10,9 +10,11 @@ class Button : Component
|
|||
private bool _AlreadyHovered = false;
|
||||
|
||||
public String Label ~ delete _;
|
||||
delegate void(TGRuntime rt) Action ~ delete _;
|
||||
|
||||
public this(StringView pName = "Button")
|
||||
public this(delegate void(TGRuntime rt) pToCall, StringView pName = "Button")
|
||||
{
|
||||
Action = pToCall;
|
||||
Label = new .(pName);
|
||||
}
|
||||
|
||||
|
@ -43,9 +45,24 @@ class Button : Component
|
|||
{
|
||||
return rt.Platform.MeasureTextureSize("Button");
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
Action.Invoke(rt);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList)
|
||||
{
|
||||
pList.Add((.)(new String(scope $"Click {Label}"), new (rt) => {this.Action.Invoke(rt);}));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -2,10 +2,16 @@ namespace TheaterGui.Components;
|
|||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
abstract class Component
|
||||
{
|
||||
public abstract void Update(TGRuntime rt);
|
||||
public abstract void Draw(TGRuntime rt, rect rect);
|
||||
public abstract int32[2] Resize(TGRuntime rt, int32 width);
|
||||
public abstract bool OnHover(TGRuntime rt, int32[2] mPos);
|
||||
public abstract bool OnLeftClick(TGRuntime rt, int32[2] mPos);
|
||||
public abstract bool OnScroll(TGRuntime rt, float pOffset);
|
||||
public abstract bool OnRightClick(TGRuntime rt, int32[2] mPos, List<(String, delegate void(TGRuntime))> pList);
|
||||
}
|
|
@ -70,6 +70,49 @@ abstract class Container : Component
|
|||
return false;
|
||||
}
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList)
|
||||
{
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||
{
|
||||
component.OnRightClick(rt, .(mPos[0]-i.x, mPos[1]-i.y), pList);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y && mPos[1] <= i.y + i.height)
|
||||
{
|
||||
if(component.OnLeftClick(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||
return true;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Result<void> AddChild(StringView pName, Component pComponent)
|
||||
{
|
||||
if(_Children.ContainsKeyAlt<StringView>(pName))
|
||||
|
|
90
src/Components/Internal/ClickableText.bf
Normal file
90
src/Components/Internal/ClickableText.bf
Normal file
|
@ -0,0 +1,90 @@
|
|||
namespace TheaterGui.Components.Internal;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
|
||||
using System;
|
||||
|
||||
//The clickable text for things like the right click menu and the top toolbar
|
||||
class ClickableText : Component
|
||||
{
|
||||
private bool _Hovered = false;
|
||||
private bool _AlreadyHovered = false;
|
||||
|
||||
public String Label ~ delete _;
|
||||
public delegate void(TGRuntime rt) Action ~ delete _;
|
||||
public int32[2] Padding = .(50, 4);
|
||||
public Alignment TextAlign = .LeftAligned;
|
||||
|
||||
public enum Alignment
|
||||
{
|
||||
LeftAligned,
|
||||
Center,
|
||||
RightAligned
|
||||
}
|
||||
|
||||
public this(delegate void(TGRuntime rt) pToCall, StringView pName = "Button")
|
||||
{
|
||||
Action = pToCall;
|
||||
Label = new .(pName);
|
||||
}
|
||||
|
||||
public override void Update(TheaterGui.Core.TGRuntime rt)
|
||||
{
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = false;
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, rect rect)
|
||||
{
|
||||
if(_Hovered)
|
||||
rt.Platform.DrawColorRect(rect , rt.Scheme.HoverColor);
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
int32 p = 0;
|
||||
switch(TextAlign)
|
||||
{
|
||||
case .LeftAligned:
|
||||
p = rect.x;
|
||||
p += 2;
|
||||
case .Center:
|
||||
p = (.)(rect.x + 0.5*rect.width - tsize[0]*0.5);
|
||||
case .RightAligned:
|
||||
p = (.)(rect.x + rect.width - tsize[0]);
|
||||
p -= 2;
|
||||
}
|
||||
rt.Platform.DrawText(Label, "Font_Normal",
|
||||
.(p,
|
||||
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5))
|
||||
,rt.Scheme.TextColor);
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
var ts = rt.Platform.MeasureTextSize(Label, "Font_Normal");
|
||||
return .(ts[0] + Padding[0], ts[1] + Padding[1]);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
_AlreadyHovered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
Action.Invoke(rt);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => true;
|
||||
}
|
154
src/Components/Popup.bf
Normal file
154
src/Components/Popup.bf
Normal file
|
@ -0,0 +1,154 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core.Structs;
|
||||
using TheaterGui.Core;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
///Unscrollable popup window that has a list of available items, clicking on anything but popup windows with the same tag will close it
|
||||
class Popup : Container
|
||||
{
|
||||
private rect _Container = .();
|
||||
private List<(String, delegate void(TGRuntime))> _ToDelete = null;
|
||||
|
||||
public int32[2] Position = .();
|
||||
public int32 Padding = 0;
|
||||
public bool DoHeightCheck = true;
|
||||
|
||||
public this(int32[2] pPosition)
|
||||
{
|
||||
Position = pPosition;
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
if(_ToDelete != null)
|
||||
{
|
||||
for(var i in _ToDelete)
|
||||
{
|
||||
delete i.0;
|
||||
delete i.1;
|
||||
}
|
||||
delete _ToDelete;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(TheaterGui.Core.TGRuntime rt, rect rect)
|
||||
{
|
||||
_Container = rect;
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
|
||||
rt.Platform.DrawColorRectOutlined(
|
||||
.() {x = offset.x - Padding, y = offset.y - Padding, width = offset.width + 2*Padding, height = offset.height + 2*Padding}
|
||||
, rt.Scheme.PrimaryColor, rt.Scheme.AcceptColor);
|
||||
rt.Platform.DrawColorRect(
|
||||
.() {x = offset.x - Padding, y = offset.y - Padding, width = offset.width + 2*Padding+4, height = offset.height + 2*Padding+4}
|
||||
, .(0x00, 0x00, 0x00, 40));
|
||||
base.Draw(rt, offset);
|
||||
}
|
||||
|
||||
|
||||
public override bool OnHover(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
|
||||
return base.OnHover(rt, .(mPos[0] - offset.x, mPos[1] - offset.y));
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
rect offset = .();
|
||||
int32[2] whLimit = .(0, 0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(whLimit[0] < i.x + i.width)
|
||||
whLimit[0] = i.x + i.width;
|
||||
if(whLimit[1] < i.y + i.height)
|
||||
whLimit[1] = i.y + i.height;
|
||||
}
|
||||
offset.width = whLimit[0];
|
||||
offset.height = whLimit[1];
|
||||
|
||||
if(Position[0] < rt.ScreenSize[0]/2)
|
||||
offset.x = Position[0];
|
||||
else
|
||||
offset.x = Position[0]-offset.width;
|
||||
|
||||
if(Position[1] < rt.ScreenSize[1]/2)
|
||||
offset.y = Position[1];
|
||||
else
|
||||
offset.y = Position[1]-offset.height;
|
||||
return base.OnLeftClick(rt, .(mPos[0] - offset.x, mPos[1] - offset.y));
|
||||
}
|
||||
|
||||
public override bool OnScroll(TheaterGui.Core.TGRuntime rt, float pOffset)
|
||||
{
|
||||
return false; //Popups dont scroll
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
_Drawings.Clear();
|
||||
|
||||
Layout l = scope .();
|
||||
l.[Friend]_RT = rt;
|
||||
l.[Friend]_Children = _Children;
|
||||
l.[Friend]_Drawings = _Drawings;
|
||||
l.[Friend]_MaxWidth = width;
|
||||
|
||||
Layout.Invoke(l, width);
|
||||
|
||||
int32[2] max = .(0,0);
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(i.width+i.x > max[0])
|
||||
max[0] = i.width+i.x;
|
||||
if(i.height+i.y > max[1])
|
||||
max[1] = i.height+i.y;
|
||||
}
|
||||
|
||||
for(var i in ref _Drawings)
|
||||
i.width = max[0];
|
||||
return max;
|
||||
}
|
||||
}
|
64
src/Components/Screen.bf
Normal file
64
src/Components/Screen.bf
Normal file
|
@ -0,0 +1,64 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Core;
|
||||
|
||||
using System;
|
||||
|
||||
class Screen : Container
|
||||
{
|
||||
/*
|
||||
Represents a physical view of a screen. It takes up the full window and there can only ever be one screen at a time
|
||||
*/
|
||||
|
||||
private float _ScrollValue = 0;
|
||||
|
||||
public override bool OnHover(TheaterGui.Core.TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
return base.OnHover(rt, .(mPos[0], (.)(mPos[1] + _ScrollValue)));
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
for(var i in _Drawings)
|
||||
{
|
||||
if(_Children.GetValue(scope .(i.name)) case .Ok(let component))
|
||||
{
|
||||
if(mPos[0] >= i.x && mPos[0] <= i.x + i.width
|
||||
&& mPos[1] >= i.y - _ScrollValue && mPos[1] <= i.y + i.height - _ScrollValue)
|
||||
{
|
||||
if(component.OnLeftClick(rt, .(mPos[0]-i.x, mPos[1]-i.y)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Draw(TheaterGui.Core.TGRuntime rt, TheaterGui.Core.Structs.rect rect)
|
||||
{
|
||||
base.Draw(rt, rect + .() {y = -(.)_ScrollValue});
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TheaterGui.Core.TGRuntime rt, int32 width)
|
||||
{
|
||||
return base.Resize(rt, width);
|
||||
}
|
||||
|
||||
public override bool OnScroll(TheaterGui.Core.TGRuntime rt, float pOffset)
|
||||
{
|
||||
int32 lowest = 0;
|
||||
for(var i in _Drawings)
|
||||
if(i.y + i.height > lowest)
|
||||
lowest = i.y + i.height;
|
||||
if(lowest > rt.Platform.ScreenSize()[1])
|
||||
{
|
||||
_ScrollValue += pOffset;
|
||||
_ScrollValue = Math.Clamp(_ScrollValue, 0, lowest - rt.Platform.ScreenSize()[1]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false; //Unable to scroll
|
||||
}
|
||||
}
|
141
src/Components/Toolbar.bf
Normal file
141
src/Components/Toolbar.bf
Normal file
|
@ -0,0 +1,141 @@
|
|||
namespace TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
using TheaterGui.Core;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class Toolbar : Component
|
||||
{
|
||||
private Dictionary<String, List<(String, delegate void(TGRuntime))>> _Items = new .() ~ delete _;
|
||||
private StringView _Hovered = "";
|
||||
private StringView _AlreadyHovered = "";
|
||||
private int32 _Offset = 0;
|
||||
|
||||
public ~this()
|
||||
{
|
||||
for(var i in _Items)
|
||||
{
|
||||
delete i.key;
|
||||
for(var j in i.value)
|
||||
{
|
||||
delete j.0;
|
||||
delete j.1;
|
||||
}
|
||||
delete i.value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(TGRuntime rt)
|
||||
{
|
||||
if(_Hovered != _AlreadyHovered)
|
||||
{
|
||||
_Hovered = _AlreadyHovered;
|
||||
rt.Dirty();
|
||||
}
|
||||
_AlreadyHovered = "";
|
||||
}
|
||||
|
||||
public override void Draw(TGRuntime rt, TheaterGui.Core.Structs.rect rect)
|
||||
{
|
||||
_Offset = rect.x;
|
||||
rt.Platform.DrawColorRectOutlined(rect, rt.Scheme.PrimaryColor, rt.Scheme.AcceptColor);
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
|
||||
|
||||
if(_Hovered == i.key)
|
||||
rt.Platform.DrawColorRect(.() {x = rect.x + xOffset, y = rect.y, width = 10 + tsize[0], height = rect.height}, rt.Scheme.HoverColor);
|
||||
|
||||
xOffset += 5;
|
||||
rt.Platform.DrawText(i.key, "Font_Normal",
|
||||
.(xOffset+(rect.x),
|
||||
(.)(rect.y + 0.5*rect.height - tsize[1]*0.5)+1)
|
||||
,rt.Scheme.TextColor);
|
||||
xOffset += tsize[0];
|
||||
xOffset += 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override int32[2] Resize(TGRuntime rt, int32 width)
|
||||
{
|
||||
return .(width, rt.Platform.MeasureTextSize("I", "Font_Normal")[1] + 6);
|
||||
}
|
||||
|
||||
public override bool OnHover(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
if(mPos[0] > xOffset && mPos[0] <= xOffset + tsize[0] + 10)
|
||||
{
|
||||
_AlreadyHovered = i.key;
|
||||
if(rt.[Friend]_PopupsName == "Toolbar")
|
||||
{
|
||||
rt.ClearPopups();
|
||||
OpenPopup(rt, .(xOffset, rt.Platform.MeasureTextSize("I", "Font_Normal")[1] + 4), i.key);
|
||||
}
|
||||
}
|
||||
xOffset += tsize[0] + 10;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnLeftClick(TGRuntime rt, int32[2] mPos)
|
||||
{
|
||||
if(_Hovered == "")
|
||||
return false;
|
||||
|
||||
int32 xOffset = 0;
|
||||
for(var i in _Items)
|
||||
{
|
||||
if(i.key == _Hovered)
|
||||
{
|
||||
OpenPopup(rt, .(xOffset + _Offset,rt.Platform.MeasureTextSize("I", "Font_Normal")[1]+4), i.key);
|
||||
return true;
|
||||
}
|
||||
|
||||
var tsize = rt.Platform.MeasureTextSize(i.key, "Font_Normal");
|
||||
xOffset += tsize[0] + 10;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnScroll(TGRuntime rt, float pOffset) => false;
|
||||
|
||||
|
||||
private void OpenPopup(TGRuntime rt, int32[2] pos, StringView pName)
|
||||
{
|
||||
Popup toPopup = new .(pos);
|
||||
if(_Items.GetValue(scope String(pName)) case .Ok(let vals))
|
||||
{
|
||||
for(var i in vals)
|
||||
toPopup.AddChild(i.0, new ClickableText(new (rt) => {i.1.Invoke(rt);},i.0));
|
||||
|
||||
toPopup.Layout = new [&] (val, width) => {
|
||||
for(var i in vals)
|
||||
{
|
||||
val.Component(i.0);
|
||||
val.Linebreak();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
rt.OpenPopup(toPopup, "Toolbar");
|
||||
}
|
||||
|
||||
public void AddEntry(StringView pSection, StringView pName, delegate void(TGRuntime) pToRun)
|
||||
{
|
||||
if(!_Items.ContainsKeyAlt<StringView>(pSection))
|
||||
_Items.Add(new .(pSection), new .());
|
||||
if(_Items.GetValue(scope .(pSection)) case .Ok(let val))
|
||||
val.Add((new .(pName), pToRun));
|
||||
}
|
||||
|
||||
public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => true;
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@ class Layout
|
|||
if(_Children.ContainsKeyAlt<StringView>(name))
|
||||
{
|
||||
var item = _Children[scope .(name)];
|
||||
var size = item.Resize(_RT, _MaxWidth);
|
||||
var size = item.Resize(_RT, _MaxWidth-_X);
|
||||
|
||||
if(_X + size[0] + padding_left + padding_right > _MaxWidth)
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ extension TGRuntime
|
|||
public theme Theme;
|
||||
public colorScheme Scheme;;
|
||||
|
||||
private List<Container> _Screens = new .() ~ DeleteContainerAndItems!(_);
|
||||
private Screen _CurrentScreen ~ delete _;
|
||||
|
||||
private bool _ShouldClose = false;
|
||||
public bool ShouldClose
|
||||
|
@ -37,4 +37,30 @@ extension TGRuntime
|
|||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private List<Popup> _Popups = new .() ~ DeleteContainerAndItems!(_);
|
||||
private String _PopupsName = new .("") ~ delete _;
|
||||
public void OpenPopup(Popup pPopup, StringView pName)
|
||||
{
|
||||
if(pPopup == null)
|
||||
{
|
||||
ClearPopups();
|
||||
return;
|
||||
}
|
||||
else if(pName != _PopupsName)
|
||||
{
|
||||
ClearPopups();
|
||||
_PopupsName.Append(pName);
|
||||
}
|
||||
pPopup.Resize(this, ScreenSize[0]);
|
||||
_Popups.Add(pPopup);
|
||||
}
|
||||
|
||||
public void ClearPopups()
|
||||
{
|
||||
Dirty();
|
||||
_PopupsName..Clear()
|
||||
.Append("");
|
||||
ClearAndDeleteItems(_Popups);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
namespace TheaterGui.Core;
|
||||
using TheaterGui.Core.Structs;
|
||||
using TheaterGui.Components;
|
||||
using TheaterGui.Components.Internal;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class TGRuntime
|
||||
{
|
||||
private void Launch(IPlatformLayer platform, Container screen, StringView name, int32 width, int32 height, colorScheme scheme, theme theme)
|
||||
private void Launch(IPlatformLayer platform, Screen screen, StringView name, int32 width, int32 height, colorScheme scheme, theme theme)
|
||||
{
|
||||
Platform = platform;
|
||||
Platform.Initialize(name, width, height);
|
||||
|
@ -14,9 +16,10 @@ class TGRuntime
|
|||
Theme = theme;
|
||||
Scheme = scheme;
|
||||
|
||||
_Screens.Add(screen);
|
||||
for(var i in _Screens)
|
||||
i.Resize(this, width);
|
||||
_CurrentScreen = screen;
|
||||
_CurrentScreen.Resize(this, width);
|
||||
ScreenSize = Platform.ScreenSize();
|
||||
|
||||
#if BF_PLATFORM_WASM
|
||||
WebAssembly.emscripten_set_main_loop(=> ProcessFrame, 60, 1);
|
||||
#else
|
||||
|
@ -26,31 +29,84 @@ class TGRuntime
|
|||
platform.Deinitialize();
|
||||
}
|
||||
|
||||
|
||||
bool _MBDownLastFrame = false;
|
||||
bool _MBRightDownLastFrame = false;
|
||||
private void ProcessFrame()
|
||||
{
|
||||
//Meta
|
||||
ShouldClose = Platform.ShouldClose();
|
||||
var ss = Platform.ScreenSize();
|
||||
if(ss != ScreenSize)
|
||||
if (ss != ScreenSize)
|
||||
{ //Resultion update
|
||||
Dirty();
|
||||
for(var i in _Screens)
|
||||
i.Resize(this, ss[0]);
|
||||
ClearPopups();
|
||||
_CurrentScreen.Resize(this, ss[0]);
|
||||
ScreenSize = ss;
|
||||
}
|
||||
|
||||
if (Platform.MouseWheel() != 0)
|
||||
if (_CurrentScreen.OnScroll(this, -5 * Platform.MouseWheel()))
|
||||
{
|
||||
Dirty();
|
||||
ClearPopups();
|
||||
}
|
||||
|
||||
var mPos = Platform.MousePosition();
|
||||
_Screens[0].OnHover(this, .((.)mPos[0], (.)mPos[1]));
|
||||
|
||||
bool hasHovered = false;
|
||||
for (var i in _Popups)
|
||||
if (i.OnHover(this, .((.)mPos[0], (.)mPos[1])))
|
||||
hasHovered = true;
|
||||
if (!hasHovered)
|
||||
_CurrentScreen.OnHover(this, .((.)mPos[0], (.)mPos[1]));
|
||||
|
||||
if (_MBDownLastFrame && !Platform.MouseLeftClick())
|
||||
{
|
||||
bool hasLClicked = false;
|
||||
for (var i in _Popups)
|
||||
if (i.OnLeftClick(this, .((.)mPos[0], (.)mPos[1])))
|
||||
hasLClicked = true;
|
||||
if (!hasLClicked)
|
||||
{
|
||||
ClearPopups();
|
||||
_CurrentScreen.OnLeftClick(this, .((.)mPos[0], (.)mPos[1]));
|
||||
}
|
||||
}
|
||||
_MBDownLastFrame = Platform.MouseLeftClick();
|
||||
|
||||
if (_MBRightDownLastFrame && !Platform.MouseRightClick())
|
||||
{
|
||||
bool hasLClicked = false;
|
||||
List<(String, delegate void(TGRuntime))> data = new .();
|
||||
for (var i in _Popups)
|
||||
if (i.OnRightClick(this, .((.)mPos[0], (.)mPos[1]), data))
|
||||
{
|
||||
hasLClicked = true;
|
||||
}
|
||||
if (!hasLClicked)
|
||||
{
|
||||
ClearPopups();
|
||||
_CurrentScreen.OnRightClick(this, .((.)mPos[0], (.)mPos[1]), data);
|
||||
}
|
||||
if(data.Count > 0)
|
||||
OpenRightClickPopup(this, .((.)mPos[0], (.)mPos[1]), data);
|
||||
else
|
||||
delete data;
|
||||
}
|
||||
_MBRightDownLastFrame = Platform.MouseRightClick();
|
||||
|
||||
|
||||
//Logic
|
||||
for(var screen in _Screens)
|
||||
screen.Update(this);
|
||||
for (var i in _Popups)
|
||||
i.Update(this);
|
||||
_CurrentScreen.Update(this);
|
||||
//Drawing
|
||||
if(_Dirty)
|
||||
if (_Dirty)
|
||||
{
|
||||
Platform.StartDrawing();
|
||||
for(var screen in _Screens)
|
||||
screen.Draw(this, .() {width = ScreenSize[0], height = ScreenSize[1] });
|
||||
_CurrentScreen.Draw(this, .() { width = ScreenSize[0], height = ScreenSize[1] });
|
||||
for (var i in _Popups)
|
||||
i.Draw(this, .() { width = ScreenSize[0], height = ScreenSize[1] });
|
||||
Platform.StopDrawing();
|
||||
_Dirty = false;
|
||||
}
|
||||
|
@ -64,4 +120,23 @@ class TGRuntime
|
|||
Platform.LoadFont(pStartingTheme.Font_Normal.0, "Font_Normal", pStartingTheme.Font_Normal.1);
|
||||
Platform.LoadTexture(pStartingTheme.Button, "Button");
|
||||
}
|
||||
|
||||
private void OpenRightClickPopup(TGRuntime rt, int32[2] pos, List<(String, delegate void(TGRuntime))> data)
|
||||
{
|
||||
Popup toPopup = new .(pos);
|
||||
toPopup.Padding = 5;
|
||||
toPopup.[Friend]_ToDelete = data;
|
||||
for (var i in data)
|
||||
toPopup.AddChild(i.0, new ClickableText(new (rt) => { i.1.Invoke(rt); }, i.0));
|
||||
|
||||
toPopup.Layout = new [&] (val, width) =>
|
||||
{
|
||||
for (var i in data)
|
||||
{
|
||||
val.Component(i.0);
|
||||
val.Linebreak();
|
||||
}
|
||||
};
|
||||
OpenPopup(toPopup, "Rightclick");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue