Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions TUI.Test/UIContainerBaseMeasureTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2023-2026 ktsu-dev contributors

namespace ktsu.TUI.Test;

using ktsu.TUI.Core.Contracts;
using ktsu.TUI.Core.Elements;
using ktsu.TUI.Core.Elements.Primitives;
using ktsu.TUI.Core.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;

/// <summary>
/// Tests for the default measurement a custom container inherits from UIContainerBase
/// </summary>
[TestClass]
public sealed class UIContainerBaseMeasureTests
{
/// <summary>
/// A container that places every child at its content origin and keeps the default measurement
/// </summary>
private sealed class OriginContainer : UIContainerBase
{
protected override void OnRender(IConsoleProvider provider) { }

protected override void OnArrangeChildren()
{
foreach (IUIElement child in GetVisibleChildren())
{
child.Position = GetContentPosition();
}
}
}

private static OriginContainer CreateContainer(Position position)
{
OriginContainer container = new()
{
Position = position,
Padding = Padding.Uniform(1),
};
container.AddChild(new TextElement { Text = "abc" });
container.ArrangeChildren();
return container;
}

/// <summary>
/// The required size is the content plus one padding, not the screen position plus two paddings
/// </summary>
[TestMethod]
public void DefaultMeasurementIsContentPlusPadding()
{
OriginContainer container = CreateContainer(new Position(10, 5));

Assert.AreEqual(new Dimensions(5, 3), container.CalculateRequiredDimensions());
}

/// <summary>
/// Moving the container on screen does not change how large it asks to be
/// </summary>
[TestMethod]
public void DefaultMeasurementDoesNotDependOnPosition()
{
Dimensions atOrigin = CreateContainer(Position.Origin).CalculateRequiredDimensions();
Dimensions elsewhere = CreateContainer(new Position(40, 12)).CalculateRequiredDimensions();

Assert.AreEqual(atOrigin, elsewhere);
}
}
7 changes: 5 additions & 2 deletions TUI/Elements/UIContainerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,17 @@ protected virtual Dimensions OnCalculateRequiredDimensionsForChildren()
return Dimensions.Empty;
}

// Children sit at absolute screen positions, so measure them from the content origin; the
// container's own position and padding are not part of the content's size
Position origin = GetContentPosition();
int maxWidth = 0;
int maxHeight = 0;

foreach (IUIElement child in _children)
{
Dimensions childDimensions = child.CalculateRequiredDimensions();
int childRight = child.Position.X + childDimensions.Width;
int childBottom = child.Position.Y + childDimensions.Height;
int childRight = Math.Max(0, child.Position.X - origin.X + childDimensions.Width);
int childBottom = Math.Max(0, child.Position.Y - origin.Y + childDimensions.Height);

maxWidth = Math.Max(maxWidth, childRight);
maxHeight = Math.Max(maxHeight, childBottom);
Expand Down
Loading