♻️ Refactoring craftsmans.

This commit is contained in:
Kolosov Alexandr 2024-03-08 14:41:29 +05:00
parent 2eb8fee7d4
commit 074365652d
15 changed files with 78 additions and 67 deletions

View File

@ -23,7 +23,7 @@ public class CellsComponentBase : ComponentBase, IComponent
var content = new StringBuilder();
foreach (var cell in _cells)
{
content.Append(Symbols.Space.Repeat(MaxCellWidth - cell.Width()));
content.Append(Symbols.Space.Repeat(MaxCellWidth - cell.GetWidth()));
content.Append(cell);
}

View File

@ -29,7 +29,7 @@ public class Dashboard : ComponentBase, IComponent
private static void RenderTopLine(StringBuilder dashboardBuilder, Size size, string title)
{
var halfWidth = (size.Width - title.Width() - (int)Indentation.BorderWidth * 2 -
var halfWidth = (size.Width - title.GetWidth() - (int)Indentation.BorderWidth * 2 -
(int)Indentation.Default * 2) / 2;
dashboardBuilder.Append(Symbols.Angles.LeftTop);
dashboardBuilder.Append(Symbols.Lines.Horizontal.Repeat(halfWidth));

View File

@ -1,6 +1,8 @@
namespace TUI.Engine.Nodes.Attributes;
public record Size(int Width, int Height)
public readonly record struct Size(int Width, int Height)
{
public static Size operator -(Size a, Position b) => new(a.Width - b.Left, a.Height - b.Top);
public override string ToString() => $"W[{Width}] H[{Height}]";
}

View File

@ -10,12 +10,12 @@ public sealed class Sketch : IEnumerable<string>
public IEnumerator<string> GetEnumerator() => ContentRows.GetEnumerator();
public IEnumerable<string> Rows(int maxWidth, int maxHeight) =>
ContentRows.Where(row => maxWidth >= row.Width()).Take(maxHeight).ToArray();
public IEnumerable<string> Rows(Size maxSize) =>
ContentRows.Where(row => maxSize.Width >= row.GetWidth()).Take(maxSize.Height).ToArray();
public Size GetSize()
{
var width = ContentRows.Select(row => row.Width()).DefaultIfEmpty(0).Max();
var width = ContentRows.Select(row => row.GetWidth()).DefaultIfEmpty(0).Max();
var height = ContentRows.Count();
return new Size(width, height);
}

View File

@ -2,5 +2,6 @@ namespace TUI.Engine.Nodes;
public record Position(int Left, int Top)
{
public static readonly Position Default = new(0, 0);
public override string ToString() => $"L[{Left}] T[{Top}]";
}

View File

@ -0,0 +1,8 @@
using TUI.Engine.Nodes.Attributes;
namespace TUI.Engine.Rendering;
public static class CanvasExtensions
{
public static Size GetSize(this ICanvas canvas) => new(canvas.Width, canvas.Height);
}

View File

@ -1,4 +1,3 @@
using System.Diagnostics;
using TUI.Engine.Nodes;
using TUI.Engine.Nodes.Attributes;
using TUI.Engine.Nodes.Components;
@ -6,7 +5,7 @@ using TUI.Engine.Nodes.Containers;
namespace TUI.Engine.Rendering;
public sealed class ComponentCraftsman : IDrawable<IComponent>
public sealed class ComponentCraftsman : CraftsmanBase, IDrawable<IComponent>
{
private readonly ICanvas _canvas;
@ -19,16 +18,10 @@ public sealed class ComponentCraftsman : IDrawable<IComponent>
{
var sketch = component.Draw();
var actualSize = sketch.GetSize();
var maxWidth = _canvas.Width - sketchPosition.Left;
var maxHeight = _canvas.Height - sketchPosition.Top;
var maxSize = _canvas.GetSize() - sketchPosition;
var pencilPosition = component.GetPosition(sketchPosition, allowableSize, actualSize);
Debugger.Log(0, "Render", $"{pencilPosition}{component.GetType().Name}.\n");
Helper.ShowBackground(sketchPosition, allowableSize);
foreach (var row in sketch.Rows(maxWidth, maxHeight))
foreach (var row in sketch.Rows(maxSize))
{
_canvas.SetPencil(pencilPosition.Left, pencilPosition.Top);
_canvas.Paint(row);
@ -36,6 +29,8 @@ public sealed class ComponentCraftsman : IDrawable<IComponent>
pencilPosition = pencilPosition with { Top = pencilPosition.Top + 1 };
}
Debug(pencilPosition, sketchPosition, allowableSize);
return actualSize;
}
}

View File

@ -1,9 +1,13 @@
using TUI.Engine.Nodes.Attributes;
namespace TUI.Engine.Rendering;
public class ConsoleCanvas : ICanvas
{
public int Width => Console.WindowWidth;
public int Height => Console.WindowHeight;
public void SetPencil(int left, int top) => Console.SetCursorPosition(left, top);
public void Paint(string value) => Console.Write(value);
public Size GetSize() => new(Width, Height);
}

View File

@ -7,16 +7,12 @@ using TUI.Engine.Nodes.Containers;
namespace TUI.Engine.Rendering;
public sealed class ContainerCraftsman : IDrawable<IContainer>
public sealed class ContainerCraftsman : CraftsmanBase, IDrawable<IContainer>
{
private readonly ICanvas _canvas;
private readonly IDrawable<IComponent> _componentCraftsman;
public ContainerCraftsman(
ICanvas canvas,
IDrawable<IComponent> componentCraftsman)
public ContainerCraftsman(IDrawable<IComponent> componentCraftsman)
{
_canvas = canvas;
_componentCraftsman = componentCraftsman;
}
@ -25,9 +21,6 @@ public sealed class ContainerCraftsman : IDrawable<IContainer>
{
var sketchSize = container.GetSize(allowableSize);
Debugger.Log(0, "Render", $"{sketchPosition} {allowableSize} {container.GetType().Name}\n");
Helper.ShowBackground(sketchPosition, allowableSize);
var controlNumber = 0;
while (controlNumber < container.GetNodes().Count)
@ -38,6 +31,7 @@ public sealed class ContainerCraftsman : IDrawable<IContainer>
controlNumber++;
}
Debug(sketchPosition, sketchPosition, allowableSize);
return sketchSize;
}

View File

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

View File

@ -1,3 +1,5 @@
using TUI.Engine.Nodes.Attributes;
namespace TUI.Engine.Rendering;
public interface ICanvas

View File

@ -5,35 +5,24 @@ using TUI.Engine.Nodes.Containers;
namespace TUI.Engine.Rendering;
public sealed class NodeCraftsman
public sealed class NodeCraftsman : IDrawable<INode>
{
private readonly ICanvas _canvas;
private readonly IDrawable<IComponent> _componentCraftsman;
private readonly IDrawable<IContainer> _containerCraftsman;
public NodeCraftsman(
ICanvas canvas,
IDrawable<IComponent> componentCraftsman,
IDrawable<IContainer> containerCraftsman)
{
_canvas = canvas;
_componentCraftsman = componentCraftsman;
_containerCraftsman = containerCraftsman;
}
public void Draw(INode node)
public Size Draw(INode node, Position sketchPosition, Size allowableSize) =>
node switch
{
var windowSize = new Size(_canvas.Width, _canvas.Height);
var defaultPosition = new Position(0, 0);
switch (node)
{
case IContainer container:
_containerCraftsman.Draw(container, defaultPosition, windowSize);
break;
case IComponent component:
_componentCraftsman.Draw(component, defaultPosition, windowSize);
break;
}
}
IContainer container => _containerCraftsman.Draw(container, sketchPosition, allowableSize),
IComponent component => _componentCraftsman.Draw(component, sketchPosition, allowableSize),
_ => throw new InvalidCastException("Unknown node type.")
};
}

View File

@ -21,7 +21,7 @@ public static class Extensions
return Regex.Replace(text, @"\S\[(\d{0,3}[;m]_?){0,5}", "");
}
public static int Width(this string text)
public static int GetWidth(this string text)
{
if (string.IsNullOrEmpty(text)) return 0;

View File

@ -1,6 +1,7 @@
using System.Diagnostics;
using TUI.Components.Controls;
using TUI.Components.Layouts;
using TUI.Engine.Nodes;
using TUI.Engine.Nodes.Attributes.Alignments;
using TUI.Engine.Rendering;
using TUI.Engine.Theme;
@ -16,8 +17,8 @@ public class DependenciesPage
var canvas = new ConsoleCanvas();
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
var nodeCraftsman = new NodeCraftsman(canvas, componentCraftsman, containerCraftsman);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
var nodeCraftsman = new NodeCraftsman(componentCraftsman, containerCraftsman);
var header = new HeaderContainer();
var copyright = new Copyright()
@ -27,7 +28,8 @@ public class DependenciesPage
var layout = new DashboardLayout().AddHeader(header).AddFooter(copyright);
// CommandLine = new CommandLine();
// DependenciesView = new DependenciesView();
nodeCraftsman.Draw(layout);
nodeCraftsman.Draw(layout, Position.Default, canvas.GetSize());
}
// private bool _commandLineInDisplay;

View File

@ -28,8 +28,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Once());
Mock.Get(canvas).Verify(w => w.Paint("Lorem"), Times.Once());
@ -53,8 +53,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.Paint(content), Times.Once());
Mock.Get(canvas).Verify(w => w.SetPencil(expectedPosition, 0), Times.Once());
@ -84,8 +84,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
foreach (var expectedCursorPosition in expectedPositions)
{
@ -113,8 +113,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(expectedLeft, expectedTop), Times.Once());
}
@ -129,8 +129,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes && r.Orientation == orientation);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Once());
Mock.Get(canvas).Verify(w => w.Paint("Lorem"), Times.Once());
@ -144,8 +144,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes && r.Orientation == Orientation.Vertical);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, 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, 1), Times.Once());
@ -160,8 +160,8 @@ public class NodeCraftsmanTests
var container = Mock.Of<IContainer>(g => g.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(container);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(container, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Exactly(1));
Mock.Get(canvas).Verify(w => w.SetPencil(5, 0), Times.Exactly(1));
@ -176,8 +176,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Exactly(1));
Mock.Get(canvas).Verify(w => w.SetPencil(6, 0), Times.Exactly(1));
@ -195,8 +195,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes && r.Orientation == Orientation.Vertical);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Exactly(1));
Mock.Get(canvas).Verify(w => w.SetPencil(0, 1), Times.Exactly(1));
@ -216,8 +216,8 @@ public class NodeCraftsmanTests
var root = Mock.Of<IContainer>(r => r.GetNodes() == nodes && r.Orientation == Orientation.Horizontal);
var componentCraftsman = new ComponentCraftsman(canvas);
var containerCraftsman = new ContainerCraftsman(canvas, componentCraftsman);
new NodeCraftsman(canvas, componentCraftsman, containerCraftsman).Draw(root);
var containerCraftsman = new ContainerCraftsman(componentCraftsman);
new NodeCraftsman(componentCraftsman, containerCraftsman).Draw(root, Position.Default, canvas.GetSize());
Mock.Get(canvas).Verify(w => w.SetPencil(0, 0), Times.Exactly(1));
Mock.Get(canvas).Verify(w => w.SetPencil(expectedCursorPosition, 0), Times.Exactly(1));