Innovenergy_trunk/csharp/Lib/Utils/TextBlock.cs

77 lines
2.8 KiB
C#

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);
}