// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. namespace FlaxEngine.GUI { /// /// A panel that evenly divides up available space between all of its children. /// /// public class UniformGridPanel : ContainerControl { private Margin _slotPadding; private int _slotsV, _slotsH; /// /// Gets or sets the padding given to each slot. /// [EditorOrder(0), Tooltip("The padding margin appied to each item slot.")] public Margin SlotPadding { get => _slotPadding; set { _slotPadding = value; PerformLayout(); } } /// /// Gets or sets the amount of slots horizontally. Use 0 to don't limit it. /// [EditorOrder(10), Limit(0, 100000, 0.1f), Tooltip("The amount of slots horizontally. Use 0 to don't limit it.")] public int SlotsHorizontally { get => _slotsH; set { value = Mathf.Clamp(value, 0, 1000000); if (value != _slotsH) { _slotsH = value; PerformLayout(); } } } /// /// Gets or sets the amount of slots vertically. Use 0 to don't limit it. /// [EditorOrder(20), Limit(0, 100000, 0.1f), Tooltip("The amount of slots vertically. Use 0 to don't limit it.")] public int SlotsVertically { get => _slotsV; set { value = Mathf.Clamp(value, 0, 1000000); if (value != _slotsV) { _slotsV = value; PerformLayout(); } } } /// /// Initializes a new instance of the class. /// public UniformGridPanel() : this(2) { } /// /// Initializes a new instance of the class. /// /// The slot padding. public UniformGridPanel(float slotPadding = 2) { SlotPadding = new Margin(slotPadding); _slotsH = _slotsV = 5; } /// protected override void PerformLayoutBeforeChildren() { base.PerformLayoutBeforeChildren(); int slotsV = _slotsV; int slotsH = _slotsH; Vector2 slotSize; if (_slotsV + _slotsH == 0) { slotSize = HasChildren ? Children[0].Size : new Vector2(32); slotsH = Mathf.CeilToInt(Width / slotSize.X); slotsV = Mathf.CeilToInt(Height / slotSize.Y); } else if (slotsH == 0) { float size = Height / slotsV; slotSize = new Vector2(size); } else if (slotsV == 0) { float size = Width / slotsH; slotSize = new Vector2(size); } else { slotSize = new Vector2(Width / slotsH, Height / slotsV); } int i = 0; for (int y = 0; y < slotsV; y++) { int end = Mathf.Min(i + slotsH, _children.Count) - i; if (end <= 0) break; for (int x = 0; x < end; x++) { var slotBounds = new Rectangle(slotSize.X * x, slotSize.Y * y, slotSize.X, slotSize.Y); _slotPadding.ShrinkRectangle(ref slotBounds); var c = _children[i++]; c.Bounds = slotBounds; } } } } }