Files
FlaxEngine/Source/Engine/UI/GUI/Panels/TilesPanel.cs

131 lines
3.9 KiB
C#

// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Panel that arranges child controls like tiles.
/// </summary>
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
[ActorToolbox("GUI")]
public class TilesPanel : ContainerControl
{
private Margin _tileMargin;
private Float2 _tileSize = new Float2(64);
private bool _autoResize = false;
/// <summary>
/// Gets or sets the margin applied to each tile.
/// </summary>
[EditorOrder(0), Tooltip("The margin applied to each tile.")]
public Margin TileMargin
{
get => _tileMargin;
set
{
if (_tileMargin != value)
{
_tileMargin = value;
PerformLayout();
}
}
}
/// <summary>
/// Gets or sets the size of the tile.
/// </summary>
[EditorOrder(0), Limit(0.01f), Tooltip("The size of the single tile.")]
public Float2 TileSize
{
get => _tileSize;
set
{
if (value.MinValue <= 0.0f)
throw new ArgumentException("Tiles cannot have negative size.");
if (!Float2.Equals(ref _tileSize, ref value))
{
_tileSize = value;
PerformLayout();
}
}
}
/// <summary>
/// Gets or sets a value indicating whether perform automatic resize after tiles arrange.
/// </summary>
[EditorOrder(10), Tooltip("If checked, the automatic control resize will be performed after tiles arrange,")]
public bool AutoResize
{
get => _autoResize;
set
{
if (_autoResize != value)
{
_autoResize = value;
PerformLayout();
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="TilesPanel"/> class.
/// </summary>
public TilesPanel()
: this(0)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TilesPanel"/> class.
/// </summary>
/// <param name="tileMargin">The tile margin.</param>
public TilesPanel(float tileMargin)
{
TileMargin = new Margin(tileMargin);
AutoFocus = false;
}
/// <inheritdoc />
protected override void PerformLayoutBeforeChildren()
{
base.PerformLayoutBeforeChildren();
// Calculate items size
float width = Width;
/*
maybe use auto fit mode?
float defaultItemsWidth = _tileSize.X;
int itemsToFit = Mathf.FloorToInt(width / defaultItemsWidth);
float itemsWidth = width / Mathf.Max(itemsToFit, 1);
float itemsHeight = itemsWidth / defaultItemsWidth * _tileSize.Y;
*/
float itemsWidth = _tileSize.X;
float itemsHeight = _tileSize.Y;
// Arrange controls
float x = 0, y = 0;
for (int i = 0; i < _children.Count; i++)
{
var c = _children[i];
c.Bounds = new Rectangle(x + TileMargin.Left, y + TileMargin.Top, itemsWidth, itemsHeight);
x += itemsWidth + TileMargin.Width;
if (x + itemsWidth + TileMargin.Width > width)
{
x = 0;
y += itemsHeight + TileMargin.Height;
}
}
if (x > 0)
y += itemsHeight + TileMargin.Height;
if (_autoResize)
{
Height = y;
}
}
}
}