Finish overload by vertical.

This commit is contained in:
Kolosov Alexandr 2024-03-14 00:09:18 +05:00
parent e15e42dbe8
commit 3c2f945480
9 changed files with 124 additions and 34 deletions

View File

@ -8,7 +8,7 @@ public static class Helper
{ {
private static readonly Queue<ConsoleColor> Colors = new(); private static readonly Queue<ConsoleColor> Colors = new();
static Helper() private static void Init()
{ {
Colors.Enqueue(ConsoleColor.DarkYellow); Colors.Enqueue(ConsoleColor.DarkYellow);
Colors.Enqueue(ConsoleColor.DarkMagenta); Colors.Enqueue(ConsoleColor.DarkMagenta);
@ -22,7 +22,12 @@ public static class Helper
public static void ShowBackground(Position position, Size size) public static void ShowBackground(Position position, Size size)
{ {
return; // return;
if (!Colors.Any())
{
Init();
}
var color = Colors.Dequeue(); var color = Colors.Dequeue();
var top = position.Top; var top = position.Top;

View File

@ -10,8 +10,10 @@ public sealed class Sketch : IEnumerable<string>
public IEnumerator<string> GetEnumerator() => ContentRows.GetEnumerator(); public IEnumerator<string> GetEnumerator() => ContentRows.GetEnumerator();
public IEnumerable<string> Crop(Size maxSize) => public IEnumerable<string> Crop(Size maxSize) => ContentRows
ContentRows.Where(row => maxSize.Width >= row.GetWidth()).Take(maxSize.Height).ToArray(); .Select(row => maxSize.Width < row.GetWidth() ? row[..maxSize.Width] : row)
.Take(maxSize.Height)
.ToArray();
public Size GetSize() public Size GetSize()
{ {

View File

@ -3,28 +3,84 @@ using TUI.Engine.Nodes.Attributes.Alignments;
using TUI.Engine.Nodes.Attributes.Orientations; using TUI.Engine.Nodes.Attributes.Orientations;
using TUI.Engine.Nodes.Attributes.Resizing; using TUI.Engine.Nodes.Attributes.Resizing;
using TUI.Engine.Nodes.Components; using TUI.Engine.Nodes.Components;
using TUI.Engine.Rendering;
namespace TUI.Engine.Nodes.Containers; namespace TUI.Engine.Nodes.Containers;
public static class ContainerExtension public static class ContainerExtension
{ {
public static Size GetSize(this IContainer container, Size allowableSize) public static Size GetSize(this INode node, IContainer parentContainer, int nodeNumber, Size allowableSize)
{ {
var nodeCount = container.GetNodes().Count; var width = GetWidth(node, parentContainer, allowableSize.Width);
var width = container.ResizingHorizontal switch var height = GetHeight(node, parentContainer, allowableSize.Height, nodeNumber);
{
Resizing.Adaptive => container.Orientation == Orientation.Horizontal
? allowableSize.Width / nodeCount
: allowableSize.Width,
Resizing.Fixed => container.GetFixedSize().Width,
_ => throw new ArgumentOutOfRangeException()
};
var height = container.Orientation == Orientation.Vertical
? allowableSize.Height / nodeCount
: allowableSize.Height;
return new Size(width, height); return new Size(width, height);
} }
private static IEnumerable<INode> GetFixedNodes(this IContainer container, int? takeNodeNumber = null)
{
if (takeNodeNumber is not null)
{
return container
.GetNodes()
.Take(takeNodeNumber.Value + 1)
.Where(n => n.ResizingVertical == Resizing.Fixed);
}
return container
.GetNodes()
.Where(n => n.ResizingVertical == Resizing.Fixed);
}
private static int GetHeight(IResizable node, IContainer container, int maxHeight, int nodeIndex)
{
if (node.ResizingVertical == Resizing.Fixed)
{
return node.GetFixedSize().Height;
}
if (container.Orientation == Orientation.Horizontal)
{
return maxHeight;
}
var fixedNodes = container.GetFixedNodes().ToArray();
var fixedHeight = fixedNodes.Sum(s => s.GetFixedSize().Height);
var allowableHeight = maxHeight - fixedHeight;
var allowableCount = container.GetNodes().Count - fixedNodes.Length;
var nodeHeight = (allowableHeight / allowableCount).Min(1);
var nodeNumber = nodeIndex + 1 - container.GetFixedNodes(nodeIndex).Sum(c => c.GetFixedSize().Height);
if (allowableHeight - nodeNumber * nodeHeight < nodeHeight)
{
return allowableHeight + nodeHeight - nodeNumber * nodeHeight;
}
return nodeHeight;
}
private static int GetWidth(IResizable node, IContainer container, int maxWidth)
{
if (node.ResizingHorizontal == Resizing.Fixed)
{
return node.GetFixedSize().Width;
}
if (container.Orientation == Orientation.Vertical)
{
return maxWidth;
}
var fixedNodes = container
.GetNodes()
.Where(n => n.ResizingHorizontal == Resizing.Fixed).ToArray();
var allowableWidth = maxWidth - fixedNodes.Sum(s => s.GetFixedSize().Width);
var allowableCount = container.GetNodes().Count - fixedNodes.Length;
return allowableWidth / allowableCount;
}
} }
public static class ComponentExtensions public static class ComponentExtensions

View File

@ -21,7 +21,7 @@ public sealed class ComponentCraftsman : CraftsmanBase, IDrawable<IComponent>
var correctedPencil = component.CorrectPosition(pencil, maxSize, sketchSize); var correctedPencil = component.CorrectPosition(pencil, maxSize, sketchSize);
Debug(correctedPencil, pencil, maxSize); Debug(pencil, maxSize);
foreach (var line in sketch.Crop(maxSize)) foreach (var line in sketch.Crop(maxSize))
{ {

View File

@ -18,20 +18,22 @@ public sealed class ContainerCraftsman : CraftsmanBase, IDrawable<IContainer>
public Size Draw(IContainer container, Position pencil, Size maxSize) public Size Draw(IContainer container, Position pencil, Size maxSize)
{ {
var controlNumber = 0; var nodeNumber = 0;
var nextNodePosition = pencil; var nextNodePosition = pencil;
var nodes = container.GetNodes(); var nodes = container.GetNodes();
var sketchSize = container.GetSize(maxSize);
Debug(nextNodePosition, nextNodePosition, maxSize);
while (controlNumber < nodes.Count) Debug(nextNodePosition, maxSize);
while (nodeNumber < nodes.Count)
{ {
var node = nodes[controlNumber]; var node = nodes[nodeNumber];
nextNodePosition = DrawNode(node, container, nextNodePosition, sketchSize); var nodeSize = node.GetSize(container, nodeNumber, maxSize);
controlNumber++;
nextNodePosition = DrawNode(node, container, nextNodePosition, nodeSize);
nodeNumber++;
} }
return sketchSize; return maxSize;
} }
private Position DrawNode(INode node, IContainer container, Position nodePosition, Size maxSize) private Position DrawNode(INode node, IContainer container, Position nodePosition, Size maxSize)

View File

@ -6,9 +6,9 @@ namespace TUI.Engine.Rendering;
public abstract class CraftsmanBase public abstract class CraftsmanBase
{ {
protected void Debug(Position pencilPosition, Position sketchPosition, Size allowableSize) protected void Debug(Position pencilPosition, Size allowableSize)
{ {
Debugger.Log(0, "Draw", $"{pencilPosition}{GetType().Name}.\n"); Debugger.Log(0, "Draw", $"{pencilPosition}{GetType().Name}.\n");
Helper.ShowBackground(sketchPosition, allowableSize); Helper.ShowBackground(pencilPosition, allowableSize);
} }
} }

View File

@ -3,4 +3,5 @@ namespace TUI.Engine.Rendering;
public static class IntegerExtension public static class IntegerExtension
{ {
public static int Max(this int value, int maxValue) => value <= maxValue ? value : maxValue; public static int Max(this int value, int maxValue) => value <= maxValue ? value : maxValue;
public static int Min(this int value, int minValue) => value > minValue ? value : minValue;
} }

View File

@ -3,6 +3,7 @@ using TUI.Components.Controls;
using TUI.Components.Layouts; using TUI.Components.Layouts;
using TUI.Engine.Nodes; using TUI.Engine.Nodes;
using TUI.Engine.Nodes.Attributes.Alignments; using TUI.Engine.Nodes.Attributes.Alignments;
using TUI.Engine.Nodes.Attributes.Orientations;
using TUI.Engine.Rendering; using TUI.Engine.Rendering;
using TUI.Engine.Theme; using TUI.Engine.Theme;
@ -21,6 +22,8 @@ public class DependenciesPage
var nodeCraftsman = new NodeCraftsman(componentCraftsman, containerCraftsman); var nodeCraftsman = new NodeCraftsman(componentCraftsman, containerCraftsman);
var header = new HeaderContainer(); var header = new HeaderContainer();
header.SetFixed(Orientation.Vertical, 6);
var copyright = new Copyright(); var copyright = new Copyright();
copyright.SetPaddingRight(Level.Normal); copyright.SetPaddingRight(Level.Normal);
copyright.SetAlignment(Horizontal.Right); copyright.SetAlignment(Horizontal.Right);

View File

@ -112,8 +112,7 @@ public class NodeCraftsmanTests
[Theory] [Theory]
[InlineData(Orientation.Horizontal, 9, 1)] [InlineData(Orientation.Horizontal, 9, 1)]
[InlineData(Orientation.Vertical, 5, 1)] public void DrawWithOverloadHorizontal(Orientation orientation, int rootWidth, int rootHeight)
public void DrawWithOverload(Orientation orientation, int rootWidth, int rootHeight)
{ {
var canvas = Mock.Of<ICanvas>(w => w.Width == rootWidth && w.Height == rootHeight); var canvas = Mock.Of<ICanvas>(w => w.Width == rootWidth && w.Height == rootHeight);
var nodes = new Nodes { _component, _component }; var nodes = new Nodes { _component, _component };
@ -124,7 +123,30 @@ public class NodeCraftsmanTests
containerCraftsman.Draw(root, Position.Default, canvas.GetSize()); containerCraftsman.Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Once()); Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Once());
Mock.Get(canvas).Verify(w => w.Paint("Lorem"), Times.Once()); Mock.Get(canvas).Verify(w => w.SetPencil(4, 0), Times.Once());
Mock.Get(canvas).Verify(w => w.Paint("Lore"), Times.Exactly(2));
}
[Theory]
[InlineData(4, 4, new[] { 0, 1, 2, 3 })]
public void DrawWithOverloadVertical(int rootWidth, int rootHeight, int[] expectedTopPositions)
{
var canvas = Mock.Of<ICanvas>(w => w.Width == rootWidth && w.Height == rootHeight);
_component.SetContent("Lorem\nLorem\nLorem");
var nodes = new Nodes { _component, _component };
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes && r.Orientation == Orientation.Vertical);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
containerCraftsman.Draw(root, Position.Default, canvas.GetSize());
foreach (var expectedTopPosition in expectedTopPositions)
{
Mock.Get(canvas).Verify(w => w.SetPencil(0, expectedTopPosition), Times.Once());
}
Mock.Get(canvas).Verify(w => w.Paint("Lorem"), Times.Exactly(rootHeight));
} }
[Fact] [Fact]
@ -196,7 +218,6 @@ public class NodeCraftsmanTests
[Theory] [Theory]
[InlineData(Resizing.Fixed, 6)] [InlineData(Resizing.Fixed, 6)]
[InlineData(Resizing.Fixed, 3)]
[InlineData(Resizing.Adaptive, 10)] [InlineData(Resizing.Adaptive, 10)]
public void DrawResizingContainer(Resizing resizing, int expectedCursorPosition) public void DrawResizingContainer(Resizing resizing, int expectedCursorPosition)
{ {