216 lines
6.9 KiB
C#
216 lines
6.9 KiB
C#
namespace InnovEnergy.Lib.Utils;
|
|
|
|
public class TextBlock
|
|
{
|
|
private readonly IReadOnlyList<String> _Lines;
|
|
|
|
private TextBlock(params String[] lines) => _Lines = lines;
|
|
|
|
public override String ToString() => _Lines.JoinLines();
|
|
|
|
public static TextBlock Empty { get; } = new TextBlock();
|
|
|
|
public static TextBlock AlignLeft(IEnumerable<Object> things)
|
|
{
|
|
var lines = things
|
|
.SelectMany(GetLines)
|
|
.Unless(String.IsNullOrEmpty)
|
|
.ToList();
|
|
|
|
if (!lines.Any())
|
|
return Empty;
|
|
|
|
var width = lines.Max(l => l.Length);
|
|
|
|
var alignedLines = lines
|
|
.Select(l => l.PadRight(width))
|
|
.ToArray(lines.Count);
|
|
|
|
return new TextBlock(alignedLines);
|
|
}
|
|
|
|
private static TextBlock AlignRight(IReadOnlyList<Object> things)
|
|
{
|
|
var lines = things
|
|
.SelectMany(GetLines)
|
|
.Unless(String.IsNullOrEmpty)
|
|
.ToList();
|
|
|
|
if (!lines.Any())
|
|
return Empty;
|
|
|
|
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 AlignCenterHorizontal(IReadOnlyList<Object> things)
|
|
{
|
|
var lines = things
|
|
.SelectMany(GetLines)
|
|
.Where(l => !String.IsNullOrEmpty(l))
|
|
.ToList();
|
|
|
|
if (!lines.Any())
|
|
return Empty;
|
|
|
|
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 AlignTop(IReadOnlyList<Object> things)
|
|
{
|
|
var columns = things
|
|
.Select(GetLines)
|
|
.Where(c => c.Count > 0)
|
|
.ToList();
|
|
|
|
if (!columns.Any())
|
|
return Empty;
|
|
|
|
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(IReadOnlyList<Object> things)
|
|
{
|
|
var columns = things
|
|
.Select(GetLines)
|
|
.Where(c => c.Count > 0)
|
|
.ToList();
|
|
|
|
if (!columns.Any())
|
|
return Empty;
|
|
|
|
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 AlignCenterVertical(IReadOnlyList<Object> things)
|
|
{
|
|
var columns = things
|
|
.Select(GetLines)
|
|
.Where(c => c.Count > 0)
|
|
.ToList();
|
|
|
|
if (!columns.Any())
|
|
return Empty;
|
|
|
|
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 static TextBlock AlignLeft (params Object?[] things) => AlignLeft ((IReadOnlyList<Object>) things);
|
|
public static TextBlock AlignRight (params Object?[] things) => AlignRight ((IReadOnlyList<Object>) things);
|
|
public static TextBlock AlignTop (params Object?[] things) => AlignTop ((IReadOnlyList<Object>) things);
|
|
public static TextBlock AlignBottom (params Object?[] things) => AlignBottom ((IReadOnlyList<Object>) things);
|
|
public static TextBlock AlignCenterVertical (params Object?[] things) => AlignCenterVertical ((IReadOnlyList<Object>) things);
|
|
public static TextBlock AlignCenterHorizontal(params Object?[] things) => AlignCenterHorizontal((IReadOnlyList<Object>) things);
|
|
|
|
public static TextBlock FromString(String thing) => AlignLeft(thing);
|
|
|
|
public TextBlock Box()
|
|
{
|
|
var width = _Lines.Any() ? _Lines.Max(l => l.Length) : 0;
|
|
|
|
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.Any() ? _Lines.Max(l => l.Length) : 0;
|
|
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);
|
|
}
|
|
|
|
public static TextBlock Spacer(Int32 n)
|
|
{
|
|
return new TextBlock(Enumerable.Repeat("".PadRight(n), n).ToArray(n));
|
|
}
|
|
|
|
public static TextBlock HorizontalSpace(Int32 n)
|
|
{
|
|
return new TextBlock("".PadRight(n));
|
|
}
|
|
|
|
public static TextBlock VerticalSpace(Int32 n)
|
|
{
|
|
return new TextBlock(Enumerable.Repeat("", n).ToArray(n));
|
|
}
|
|
|
|
|
|
private static IReadOnlyList<String> GetLines(Object? t)
|
|
{
|
|
return t switch
|
|
{
|
|
TextBlock tb => tb._Lines,
|
|
null => Array.Empty<String>(),
|
|
_ => t.ToString()!.SplitLines()
|
|
};
|
|
}
|
|
|
|
private static String Space(Int32 totalWidth)
|
|
{
|
|
return "".PadRight(totalWidth);
|
|
}
|
|
} |