added scrollable basics
This commit is contained in:
parent
d3d9f51012
commit
bcd137f54b
1 changed files with 182 additions and 0 deletions
182
src/Components/ScrollableContainer.bf
Normal file
182
src/Components/ScrollableContainer.bf
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue