new implementation of TextBlock
This commit is contained in:
parent
dcc4bfa78a
commit
c78451d4cf
|
@ -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;
|
||||||
//
|
//
|
|
@ -75,7 +75,6 @@ internal static class Program
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task Run()
|
private static async Task Run()
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextBlock TitleBox(String title)
|
||||||
|
{
|
||||||
|
var linesWidth = _Lines.Max(l => l.Length);
|
||||||
|
var titleWidth = title.Length;
|
||||||
|
|
||||||
|
var width = Math.Max(linesWidth, titleWidth);
|
||||||
|
|
||||||
|
var hLine = "".PadRight(width + 2, '─');
|
||||||
|
var top = "┌" + hLine + "┐";
|
||||||
|
var between = "├" + hLine + "┤";
|
||||||
|
var bottom = "└" + hLine + "┘";
|
||||||
|
|
||||||
|
var centeredTitle = "│ " + title.PadLeft((width + title.Length) / 2).PadRight(width) + " │";
|
||||||
|
|
||||||
|
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);
|
return new TextBlock(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextBlock AlignHorizontal(Func<String, Int32, String> alignLine, Int32 width = -1)
|
|
||||||
|
|
||||||
|
|
||||||
|
public static TextBlock Spacer(Int32 n)
|
||||||
{
|
{
|
||||||
if (!Lines.Any())
|
return new TextBlock(Enumerable.Repeat("".PadRight(n), n).ToArray(n));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TextBlock HorizontalSpace(Int32 n)
|
||||||
private static IReadOnlyList<String> GetLines(Object l)
|
|
||||||
{
|
{
|
||||||
return l is TextBlock tb
|
return new TextBlock("".PadRight(n));
|
||||||
? tb.Lines
|
}
|
||||||
: l.ToString()?.SplitLines() ?? new[] { "<null>" };
|
|
||||||
|
public static TextBlock VerticalSpace(Int32 n)
|
||||||
|
{
|
||||||
|
return new TextBlock(Enumerable.Repeat("", n).ToArray(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override String ToString() => String.Join(Environment.NewLine, Lines);
|
|
||||||
|
|
||||||
public static implicit operator TextBlock(String[] lines) => new TextBlock(lines);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue