131 lines
3.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|