added scrollable basics

This commit is contained in:
Booklordofthedings 2024-06-20 23:08:21 +02:00
parent d3d9f51012
commit bcd137f54b

View file

@ -0,0 +1,182 @@
namespace TheaterGui.Components;
using System;
using System.Collections;
using RaylibBeef;
class ScrollableContainer : Container
{
public int32 ContainerHeight = 0;
public float Scroll = 0;
public this(StringView pName, StringView pComponentName = "Container") : base(pName, pComponentName)
{
}
private List<Component> _LayoutData = new .() ~ delete _;
///Recalculate the layout of all entries
public override void Reorder(int32 w)
{
/*
List<Entries> {Entry, Entry, Entry, RB, Entry, Entry, RB, Entry, RB}
null is a rowbreak while non null isnt a rowbreak
Algorithm
if the current entry is a rowbreak, reset the cursor to x = 0, y = y + height
try to fit the current entry after the cursor
if it fits add it,
if it doesnt fit break
*/
int32 maxWidth = 0; //The highest width line
int32 rowHeight = 0; //How high the current row is
int32 x = 0;
int32 y = 0;
for(var e in _LayoutData)
{
if(e == null)
{ //Manual row break
x = 0;
y = y + rowHeight;
rowHeight = 0;
continue;
}
if(e is Container)
{
((Container)e).Reorder(w);
MoveChildrenRecursive((Container)e, x, y);
}
if(e is Toolbar)
e.Width = App.Width;
if(x+e.Width+e.MarginLeft > w-MarginLeft) //Change both instances of padding to 2*Padding to ensure proper padding on the leftmost side of the screen
{ //Automatic row break
x = 0;
y = y + rowHeight;
rowHeight = 0;
}
e.[Friend]X = x + e.MarginLeft;
x = x + e.Width + e.MarginLeft + e.MarginRight;
e.[Friend]Y = y + e.MarginTop;
if(x > maxWidth)
maxWidth = x;
if(rowHeight < e.Height+e.MarginTop+e.MarginBottom)
rowHeight = e.Height+e.MarginTop+e.MarginBottom;
}
Width = maxWidth + MarginLeft + MarginRight;
Height = y + rowHeight + MarginTop + MarginBottom;
}
private void MoveChildrenRecursive(Container c, int32 x, int32 y)
{
for(var i in c.Children)
{
i.[Friend]X += x + MarginLeft + c.MarginLeft;
i.[Friend]Y += y + MarginTop + c.MarginTop;
if(i is Container)
MoveChildrenRecursive((Container)i, x, y);
}
}
///Add a new item to the list of items
public new void AddChild(Component pToAdd)
{
_LayoutData.Add(pToAdd);
Children.Add(pToAdd);
pToAdd.Parent = this;
}
public override void InsertBefore(Component pToAdd, Component Position, bool pReorder = true)
{
var idx = _LayoutData.IndexOf(Position);
if(idx < 0)
{
delete pToAdd; //Avoid memory leaks
return;
}
_LayoutData.Insert(idx, pToAdd);
Children.Add(pToAdd);
pToAdd.Parent = this;
if(pReorder)
App.ForceReorder();
}
public override void InsertAfter(Component pToAdd, Component Position, bool pReorder = true)
{
var idx = _LayoutData.IndexOf(Position);
idx++;
if(idx < 0)
{
delete pToAdd; //Avoid memory leaks
return;
}
_LayoutData.Insert(idx, pToAdd);
Children.Add(pToAdd);
pToAdd.Parent = this;
if(pReorder)
App.ForceReorder();
}
///Forcefully terminates the current row
public new void EndRow() => _LayoutData.Add(null);
public override void Render(int32 soy)
{
Raylib.BeginScissorMode(X, Y + soy, Width, ContainerHeight);
for(var i in Children)
i.Render(soy);
Raylib.EndScissorMode();
}
public override bool OnClick(int32 x, int32 y)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
return e.OnClick(x, y);
}
return false;
}
public override bool OnDown(int32 x, int32 y)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
return e.OnDown(x, y);
}
return false;
}
public override Component OnHover(int32 x, int32 y)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
return e.OnHover(x, y);
}
return null;
}
public override void OnRightClick(int32 x, int32 y, Toolbar.ToolbarCategory items)
{
for(var e in Children)
{
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
e.OnRightClick(x, y, items);
}
}
}