new implementation of TextBlock

This commit is contained in:
ig 2023-06-20 14:26:48 +02:00
parent dcc4bfa78a
commit c78451d4cf
3 changed files with 275 additions and 53 deletions

View File

@ -1,4 +1,45 @@
// using InnovEnergy.Lib.Utils; using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.App.SaliMax;
public static class Flow
{
private static readonly String RightArrowChar = ">";
private static readonly String LeftArrowChar = "<";
private static readonly String DownArrowChar = "V";
private static readonly String UpArrowChar = "^";
public static TextBlock Horizontal(Unit amount, Int32 width = 10)
{
var label = amount.ToString();
var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar;
var arrow = Enumerable.Repeat(arrowChar, width).Join();
// note : appending "fake label" below to make it vertically symmetric
return TextBlock.CenterHorizontal(label, arrow, "");
}
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
public static TextBlock Vertical(Unit amount, Int32 height = 8)
{
var label = amount.ToString();
var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar;
var halfArrow = Enumerable.Repeat(arrowChar, height/2);
var lines = halfArrow
.Append(label)
.Concat(halfArrow)
.ToArray(height / 2 * 2 + 1);
return TextBlock.CenterHorizontal(lines);
}
}
// //
// namespace InnovEnergy.App.SaliMax; // namespace InnovEnergy.App.SaliMax;
// //

View File

@ -75,7 +75,6 @@ internal static class Program
Console.WriteLine(e); Console.WriteLine(e);
} }
} }
} }
private static async Task Run() private static async Task Run()

View File

@ -1,76 +1,258 @@
namespace InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Utils;
// public class TextBlock
// {
// public static TextBlock Empty { get; } = new TextBlock(Array.Empty<String>());
//
// public IReadOnlyList<String> Lines { get; }
//
// public Int32 Width => Lines.Count == 0
// ? 0
// : Lines.Max(l=>l.Length);
//
// public Int32 Height => Lines.Count;
//
// public TextBlock(IReadOnlyList<String> lines) => Lines = lines;
//
// public TextBlock AlignLeft (Int32 width = -1) => AlignHorizontal((l, w) => l.PadRight(w), width);
// public TextBlock AlignRight (Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft(w), width);
// public TextBlock AlignHCenter(Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width);
//
// public TextBlock AlignTop (Int32 height) => Lines.Concat(EmptyLines(height)).Take(height).ToArray(height);
// public TextBlock AlignBottom (Int32 height) => EmptyLines(Lines.Count - height).Concat(Lines).Take(height).ToArray(height);
// //public TextBlock AlignVCenter(Int32 height) => EmptyLines(height/2).Concat(Lines).Take(height).ToArray(height);
// //public TextBlock AlignVCenter(Int32 height) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width);
//
// private static IEnumerable<String> EmptyLines(Int32 height)
// {
// return height > 0
// ? Enumerable.Repeat("", height)
// : Enumerable.Empty<String>();
// }
//
//
// public static TextBlock HSpace(Int32 width ) => new TextBlock(new []{"".PadRight(width)});
// public static TextBlock VSpace(Int32 height) => new TextBlock(Enumerable.Repeat("", height).ToArray(height));
//
// public static TextBlock Space(Int32 width, Int32 height)
// {
// var lines = Enumerable
// .Repeat("".PadRight(width), height)
// .ToArray(height);
//
// return new TextBlock(lines);
// }
//
// private TextBlock AlignHorizontal(Func<String, Int32, String> alignLine, Int32 width = -1)
// {
// if (!Lines.Any())
// return Empty;
//
// var strings = Lines
// .SelectMany(GetLines)
// .ToList();
//
// width = width < 0 ? strings.Max(l => l.Length) : width;
//
// var aligned = strings
// .Select(l => l.Length > width ? l.Substring(0, width) : l)
// .Select(l => alignLine(l, width))
// .ToArray(strings.Count);
//
// return new TextBlock(aligned);
// }
//
//
// private static IReadOnlyList<String> GetLines(Object l)
// {
// return l is TextBlock tb
// ? tb.Lines
// : l.ToString()?.SplitLines() ?? new[] { "<null>" };
// }
//
// public override String ToString() => String.Join(Environment.NewLine, Lines);
//
// public static implicit operator TextBlock(String[] lines) => new TextBlock(lines);
// }
public class TextBlock public class TextBlock
{ {
public static TextBlock Empty { get; } = new TextBlock(Array.Empty<String>()); private readonly IReadOnlyList<String> _Lines;
public IReadOnlyList<String> Lines { get; } private TextBlock(params String[] lines) => _Lines = lines;
public Int32 Width => Lines.Count == 0 public override String ToString() => _Lines.JoinLines();
? 0
: Lines.Max(l=>l.Length);
public Int32 Height => Lines.Count;
public TextBlock(IReadOnlyList<String> lines) => Lines = lines; public static TextBlock AlignLeft(params Object[] things)
public TextBlock AlignLeft (Int32 width = -1) => AlignHorizontal((l, w) => l.PadRight(w), width);
public TextBlock AlignRight (Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft(w), width);
public TextBlock AlignHCenter(Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width);
public TextBlock AlignTop (Int32 height) => Lines.Concat(EmptyLines(height)).Take(height).ToArray(height);
public TextBlock AlignBottom (Int32 height) => EmptyLines(Lines.Count - height).Concat(Lines).Take(height).ToArray(height);
//public TextBlock AlignVCenter(Int32 height) => EmptyLines(height/2).Concat(Lines).Take(height).ToArray(height);
//public TextBlock AlignVCenter(Int32 height) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width);
private static IEnumerable<String> EmptyLines(Int32 height)
{ {
return height > 0 var lines = things
? Enumerable.Repeat("", height) .SelectMany(GetLines)
: Enumerable.Empty<String>(); .ToList();
var width = lines.Max(l => l.Length);
var alignedLines = lines.Select(l => l.PadRight(width)).ToArray(lines.Count);
return new TextBlock(alignedLines);
}
public static TextBlock AlignRight(params Object[] things)
{
var lines = things
.SelectMany(GetLines)
.ToList();
var width = lines.Max(l => l.Length);
var alignedLines = lines.Select(l => l.PadLeft(width)).ToArray(lines.Count);
return new TextBlock(alignedLines);
}
public static TextBlock CenterHorizontal(params Object[] things)
{
var lines = things
.SelectMany(GetLines)
.ToList();
var width = lines.Max(l => l.Length);
var alignedLines = lines
.Select(l => l.PadLeft((width + l.Length) / 2).PadRight(width))
.ToArray(lines.Count);
return new TextBlock(alignedLines);
} }
public static TextBlock HSpace(Int32 width ) => new TextBlock(new []{"".PadRight(width)}); public static TextBlock AlignTop(params Object[] things)
public static TextBlock VSpace(Int32 height) => new TextBlock(Enumerable.Repeat("", height).ToArray(height));
public static TextBlock Space(Int32 width, Int32 height)
{ {
var lines = Enumerable var columns = things
.Repeat("".PadRight(width), height) .Select(GetLines)
.ToArray(height); .ToList();
var height = columns.Max(l => l.Count);
var alignedLines = Enumerable
.Range(0, height)
.Select(l => columns.Select(c => c.ElementAtOr(l, Space(c[0].Length))).Join())
.ToArray(height);
return new TextBlock(alignedLines);
}
public static TextBlock AlignBottom(params Object[] things)
{
var columns = things
.Select(GetLines)
.ToList();
var height = columns.Max(l => l.Count);
var alignedLines = Enumerable
.Range(0, height)
.Select(l => columns.Select(c => c.ElementAtOr(c.Count - height + l, Space(c[0].Length))).Join())
.ToArray(height);
return new TextBlock(alignedLines);
}
public static TextBlock CenterVertical(params Object[] things)
{
var columns = things
.Select(GetLines)
.ToList();
var height = columns.Max(l => l.Count);
var alignedLines = Enumerable
.Range(0, height)
.Select(l => columns.Select(c => c.ElementAtOr((c.Count - height) / 2 + l, Space(c[0].Length))).Join())
.ToArray(height);
return new TextBlock(alignedLines);
}
public TextBlock Box()
{
var width = _Lines.Max(l => l.Length);
var hLine = "".PadRight(width + 2, '─');
var top = "┌" + hLine + "┐";
var bottom = "└" + hLine + "┘";
var lines = _Lines
.Select(l => l.SurroundWith(" "))
.Select(l => l.SurroundWith("│"))
.Prepend(top)
.Append(bottom)
.ToArray(_Lines.Count + 2);
return new TextBlock(lines); return new TextBlock(lines);
} }
private TextBlock AlignHorizontal(Func<String, Int32, String> alignLine, Int32 width = -1) public TextBlock TitleBox(String title)
{ {
if (!Lines.Any()) var linesWidth = _Lines.Max(l => l.Length);
return Empty; var titleWidth = title.Length;
var strings = Lines var width = Math.Max(linesWidth, titleWidth);
.SelectMany(GetLines)
.ToList();
width = width < 0 ? strings.Max(l => l.Length) : width; var hLine = "".PadRight(width + 2, '─');
var top = "┌" + hLine + "┐";
var between = "├" + hLine + "┤";
var bottom = "└" + hLine + "┘";
var aligned = strings var centeredTitle = "│ " + title.PadLeft((width + title.Length) / 2).PadRight(width) + " │";
.Select(l => l.Length > width ? l.Substring(0, width) : l)
.Select(l => alignLine(l, width))
.ToArray(strings.Count);
return new TextBlock(aligned); var lines = _Lines
.Select(l => l.PadRight(width))
.Select(l => l.SurroundWith(" "))
.Select(l => l.SurroundWith("│"))
.Prepend(between)
.Prepend(centeredTitle)
.Prepend(top)
.Append(bottom)
.ToArray();
return new TextBlock(lines);
} }
private static IReadOnlyList<String> GetLines(Object l)
public static TextBlock Spacer(Int32 n)
{ {
return l is TextBlock tb return new TextBlock(Enumerable.Repeat("".PadRight(n), n).ToArray(n));
? tb.Lines
: l.ToString()?.SplitLines() ?? new[] { "<null>" };
} }
public override String ToString() => String.Join(Environment.NewLine, Lines); public static TextBlock HorizontalSpace(Int32 n)
{
return new TextBlock("".PadRight(n));
}
public static implicit operator TextBlock(String[] lines) => new TextBlock(lines); public static TextBlock VerticalSpace(Int32 n)
{
return new TextBlock(Enumerable.Repeat("", n).ToArray(n));
}
private static IReadOnlyList<String> GetLines(Object t)
{
return t is TextBlock tb
? tb._Lines
: t.ToString()!.SplitLines();
}
private static String Space(Int32 totalWidth)
{
return "".PadRight(totalWidth);
}
} }