Files
RobustToolbox/Robust.Client/UserInterface/Controls/Container.cs
T
Pieter-Jan BriersandGitHub cb5f2ffae1 Refactor UI system. (#843)
* Refactor UI system.

Deferred updating is used for styling & layout. This fixes the awful time complexity of containers.
Removed SetDefaults and Initialize. They were a bad idea alright.

* Fix build on .NET Framework.
2019-08-14 22:03:51 +02:00

109 lines
3.1 KiB
C#

using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Robust.Client.UserInterface.Controls
{
/// <summary>
/// A container lays out its children by some implementation-dependent rules.
/// </summary>
public abstract class Container : Control
{
protected internal void QueueSortChildren()
{
UpdateLayout();
}
/// <summary>
/// Called when the container should re-sort its children.
/// </summary>
protected internal virtual void SortChildren()
{
}
protected override void ChildAdded(Control newChild)
{
base.ChildAdded(newChild);
newChild.OnMinimumSizeChanged += _childChanged;
newChild.OnVisibilityChanged += _childChanged;
MinimumSizeChanged();
QueueSortChildren();
}
protected override void ChildRemoved(Control child)
{
base.ChildRemoved(child);
child.OnMinimumSizeChanged -= _childChanged;
child.OnVisibilityChanged -= _childChanged;
MinimumSizeChanged();
QueueSortChildren();
}
protected void FitChildInPixelBox(Control child, UIBox2i pixelBox)
{
var topLeft = pixelBox.TopLeft / UIScale;
var bottomRight = pixelBox.BottomRight / UIScale;
FitChildInBox(child, new UIBox2(topLeft, bottomRight));
}
protected void FitChildInBox(Control child, UIBox2 box)
{
DebugTools.Assert(child.Parent == this);
var (minX, minY) = child.CombinedMinimumSize;
var newPosX = box.Left;
var newSizeX = minX;
if ((child.SizeFlagsHorizontal & SizeFlags.ShrinkEnd) != 0)
{
newPosX += (box.Width - minX);
}
else if ((child.SizeFlagsHorizontal & SizeFlags.ShrinkCenter) != 0)
{
newPosX += (box.Width - minX) / 2;
}
else if ((child.SizeFlagsHorizontal & SizeFlags.Fill) != 0)
{
newSizeX = box.Width;
}
var newPosY = box.Top;
var newSizeY = minY;
if ((child.SizeFlagsVertical & SizeFlags.ShrinkEnd) != 0)
{
newPosY += (box.Height - minY);
}
else if ((child.SizeFlagsVertical & SizeFlags.ShrinkCenter) != 0)
{
newPosY += (box.Height - minY) / 2;
}
else if ((child.SizeFlagsVertical & SizeFlags.Fill) != 0)
{
newSizeY = box.Height;
}
child.SetAnchorPreset(LayoutPreset.TopLeft, true);
child.Position = new Vector2(newPosX, newPosY);
child.Size = new Vector2(newSizeX, newSizeY);
}
private void _childChanged(Control child)
{
MinimumSizeChanged();
QueueSortChildren();
}
protected override void Resized()
{
base.Resized();
QueueSortChildren();
}
}
}