Editor/Common/WrapPanel.cs
using System;
using System.Linq;
using Editor;
using Sandbox;
namespace Grains.RazorDesigner.Common;
public sealed class WrapPanel : Widget
{
public int HSpacing { get; set; } = 4;
public int VSpacing { get; set; } = 4;
public int PaddingLeft { get; set; } = 4;
public int PaddingTop { get; set; } = 4;
public int PaddingRight { get; set; } = 4;
public int PaddingBottom { get; set; } = 4;
public int MinItemWidth { get; set; } = 96;
public int ItemHeight { get; set; } = 26;
// Convenience setter — applies the value to all four sides.
public int Padding
{
set { PaddingLeft = PaddingTop = PaddingRight = PaddingBottom = value; }
}
public WrapPanel( Widget parent ) : base( parent )
{
}
public void Relayout()
{
DoLayout();
}
protected override void DoLayout()
{
base.DoLayout();
var children = Children.Where( c => c.IsValid ).ToList();
if ( children.Count == 0 )
{
FixedHeight = PaddingTop + PaddingBottom;
return;
}
float availW = Math.Max( 0, Size.x - PaddingLeft - PaddingRight );
int cols = Math.Max( 1, (int)Math.Floor( (availW + HSpacing) / (float)(MinItemWidth + HSpacing) ) );
float itemW = cols == 1 ? availW : (availW - (cols - 1) * HSpacing) / cols;
int col = 0, row = 0;
foreach ( var child in children )
{
float x = PaddingLeft + col * (itemW + HSpacing);
float y = PaddingTop + row * (ItemHeight + VSpacing);
child.Position = new Vector2( x, y );
child.Size = new Vector2( itemW, ItemHeight );
col++;
if ( col >= cols )
{
col = 0;
row++;
}
}
int rows = (children.Count + cols - 1) / cols;
float totalH = PaddingTop + PaddingBottom + rows * ItemHeight + Math.Max( 0, rows - 1 ) * VSpacing;
FixedHeight = totalH;
}
}