mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add support for markdown tables
Closes #85 * Split Border into BoxBorder and TableBorder * Change how different table parts are composed * Add markdown table border
This commit is contained in:

committed by
Patrik Svensson

parent
697273917e
commit
93ec7401c8
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents another old school ASCII border.
|
||||
/// </summary>
|
||||
public sealed class Ascii2Border : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "+",
|
||||
BorderPart.HeaderTop => "-",
|
||||
BorderPart.HeaderTopSeparator => "+",
|
||||
BorderPart.HeaderTopRight => "+",
|
||||
BorderPart.HeaderLeft => "|",
|
||||
BorderPart.HeaderSeparator => "|",
|
||||
BorderPart.HeaderRight => "|",
|
||||
BorderPart.HeaderBottomLeft => "|",
|
||||
BorderPart.HeaderBottom => "-",
|
||||
BorderPart.HeaderBottomSeparator => "+",
|
||||
BorderPart.HeaderBottomRight => "|",
|
||||
BorderPart.CellLeft => "|",
|
||||
BorderPart.CellSeparator => "|",
|
||||
BorderPart.CellRight => "|",
|
||||
BorderPart.FooterBottomLeft => "+",
|
||||
BorderPart.FooterBottom => "-",
|
||||
BorderPart.FooterBottomSeparator => "+",
|
||||
BorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border.
|
||||
/// </summary>
|
||||
public sealed class AsciiBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "+",
|
||||
BorderPart.HeaderTop => "-",
|
||||
BorderPart.HeaderTopSeparator => "-",
|
||||
BorderPart.HeaderTopRight => "+",
|
||||
BorderPart.HeaderLeft => "|",
|
||||
BorderPart.HeaderSeparator => "|",
|
||||
BorderPart.HeaderRight => "|",
|
||||
BorderPart.HeaderBottomLeft => "|",
|
||||
BorderPart.HeaderBottom => "-",
|
||||
BorderPart.HeaderBottomSeparator => "+",
|
||||
BorderPart.HeaderBottomRight => "|",
|
||||
BorderPart.CellLeft => "|",
|
||||
BorderPart.CellSeparator => "|",
|
||||
BorderPart.CellRight => "|",
|
||||
BorderPart.FooterBottomLeft => "+",
|
||||
BorderPart.FooterBottom => "-",
|
||||
BorderPart.FooterBottomSeparator => "-",
|
||||
BorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border with a double header border.
|
||||
/// </summary>
|
||||
public sealed class AsciiDoubleHeadBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "+",
|
||||
BorderPart.HeaderTop => "-",
|
||||
BorderPart.HeaderTopSeparator => "+",
|
||||
BorderPart.HeaderTopRight => "+",
|
||||
BorderPart.HeaderLeft => "|",
|
||||
BorderPart.HeaderSeparator => "|",
|
||||
BorderPart.HeaderRight => "|",
|
||||
BorderPart.HeaderBottomLeft => "|",
|
||||
BorderPart.HeaderBottom => "=",
|
||||
BorderPart.HeaderBottomSeparator => "+",
|
||||
BorderPart.HeaderBottomRight => "|",
|
||||
BorderPart.CellLeft => "|",
|
||||
BorderPart.CellSeparator => "|",
|
||||
BorderPart.CellRight => "|",
|
||||
BorderPart.FooterBottomLeft => "+",
|
||||
BorderPart.FooterBottom => "-",
|
||||
BorderPart.FooterBottomSeparator => "+",
|
||||
BorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a double border.
|
||||
/// </summary>
|
||||
public sealed class DoubleBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "╔",
|
||||
BorderPart.HeaderTop => "═",
|
||||
BorderPart.HeaderTopSeparator => "╦",
|
||||
BorderPart.HeaderTopRight => "╗",
|
||||
BorderPart.HeaderLeft => "║",
|
||||
BorderPart.HeaderSeparator => "║",
|
||||
BorderPart.HeaderRight => "║",
|
||||
BorderPart.HeaderBottomLeft => "╠",
|
||||
BorderPart.HeaderBottom => "═",
|
||||
BorderPart.HeaderBottomSeparator => "╬",
|
||||
BorderPart.HeaderBottomRight => "╣",
|
||||
BorderPart.CellLeft => "║",
|
||||
BorderPart.CellSeparator => "║",
|
||||
BorderPart.CellRight => "║",
|
||||
BorderPart.FooterBottomLeft => "╚",
|
||||
BorderPart.FooterBottom => "═",
|
||||
BorderPart.FooterBottomSeparator => "╩",
|
||||
BorderPart.FooterBottomRight => "╝",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a double edge.
|
||||
/// </summary>
|
||||
public sealed class DoubleEdgeBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "╔",
|
||||
BorderPart.HeaderTop => "═",
|
||||
BorderPart.HeaderTopSeparator => "╤",
|
||||
BorderPart.HeaderTopRight => "╗",
|
||||
BorderPart.HeaderLeft => "║",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => "║",
|
||||
BorderPart.HeaderBottomLeft => "╟",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "┼",
|
||||
BorderPart.HeaderBottomRight => "╢",
|
||||
BorderPart.CellLeft => "║",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => "║",
|
||||
BorderPart.FooterBottomLeft => "╚",
|
||||
BorderPart.FooterBottom => "═",
|
||||
BorderPart.FooterBottomSeparator => "╧",
|
||||
BorderPart.FooterBottomRight => "╝",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a heavy border.
|
||||
/// </summary>
|
||||
public sealed class HeavyBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder => Border.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "┏",
|
||||
BorderPart.HeaderTop => "━",
|
||||
BorderPart.HeaderTopSeparator => "┳",
|
||||
BorderPart.HeaderTopRight => "┓",
|
||||
BorderPart.HeaderLeft => "┃",
|
||||
BorderPart.HeaderSeparator => "┃",
|
||||
BorderPart.HeaderRight => "┃",
|
||||
BorderPart.HeaderBottomLeft => "┣",
|
||||
BorderPart.HeaderBottom => "━",
|
||||
BorderPart.HeaderBottomSeparator => "╋",
|
||||
BorderPart.HeaderBottomRight => "┫",
|
||||
BorderPart.CellLeft => "┃",
|
||||
BorderPart.CellSeparator => "┃",
|
||||
BorderPart.CellRight => "┃",
|
||||
BorderPart.FooterBottomLeft => "┗",
|
||||
BorderPart.FooterBottom => "━",
|
||||
BorderPart.FooterBottomSeparator => "┻",
|
||||
BorderPart.FooterBottomRight => "┛",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a heavy edge.
|
||||
/// </summary>
|
||||
public sealed class HeavyEdgeBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder => Border.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "┏",
|
||||
BorderPart.HeaderTop => "━",
|
||||
BorderPart.HeaderTopSeparator => "┯",
|
||||
BorderPart.HeaderTopRight => "┓",
|
||||
BorderPart.HeaderLeft => "┃",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => "┃",
|
||||
BorderPart.HeaderBottomLeft => "┠",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "┼",
|
||||
BorderPart.HeaderBottomRight => "┨",
|
||||
BorderPart.CellLeft => "┃",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => "┃",
|
||||
BorderPart.FooterBottomLeft => "┗",
|
||||
BorderPart.FooterBottom => "━",
|
||||
BorderPart.FooterBottomSeparator => "┷",
|
||||
BorderPart.FooterBottomRight => "┛",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a heavy header.
|
||||
/// </summary>
|
||||
public sealed class HeavyHeadBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder => Border.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "┏",
|
||||
BorderPart.HeaderTop => "━",
|
||||
BorderPart.HeaderTopSeparator => "┳",
|
||||
BorderPart.HeaderTopRight => "┓",
|
||||
BorderPart.HeaderLeft => "┃",
|
||||
BorderPart.HeaderSeparator => "┃",
|
||||
BorderPart.HeaderRight => "┃",
|
||||
BorderPart.HeaderBottomLeft => "┡",
|
||||
BorderPart.HeaderBottom => "━",
|
||||
BorderPart.HeaderBottomSeparator => "╇",
|
||||
BorderPart.HeaderBottomRight => "┩",
|
||||
BorderPart.CellLeft => "│",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => "│",
|
||||
BorderPart.FooterBottomLeft => "└",
|
||||
BorderPart.FooterBottom => "─",
|
||||
BorderPart.FooterBottomSeparator => "┴",
|
||||
BorderPart.FooterBottomRight => "┘",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a horizontal border.
|
||||
/// </summary>
|
||||
public sealed class HorizontalBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "─",
|
||||
BorderPart.HeaderTop => "─",
|
||||
BorderPart.HeaderTopSeparator => "─",
|
||||
BorderPart.HeaderTopRight => "─",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => " ",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => "─",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "─",
|
||||
BorderPart.HeaderBottomRight => "─",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => " ",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => "─",
|
||||
BorderPart.FooterBottom => "─",
|
||||
BorderPart.FooterBottomSeparator => "─",
|
||||
BorderPart.FooterBottomRight => "─",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border.
|
||||
/// </summary>
|
||||
public sealed class MinimalBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => " ",
|
||||
BorderPart.HeaderTop => " ",
|
||||
BorderPart.HeaderTopSeparator => " ",
|
||||
BorderPart.HeaderTopRight => " ",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => " ",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "┼",
|
||||
BorderPart.HeaderBottomRight => " ",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => " ",
|
||||
BorderPart.FooterBottom => " ",
|
||||
BorderPart.FooterBottomSeparator => " ",
|
||||
BorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border with a double header border.
|
||||
/// </summary>
|
||||
public sealed class MinimalDoubleHeadBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => " ",
|
||||
BorderPart.HeaderTop => " ",
|
||||
BorderPart.HeaderTopSeparator => " ",
|
||||
BorderPart.HeaderTopRight => " ",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => " ",
|
||||
BorderPart.HeaderBottom => "═",
|
||||
BorderPart.HeaderBottomSeparator => "╪",
|
||||
BorderPart.HeaderBottomRight => " ",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => " ",
|
||||
BorderPart.FooterBottom => " ",
|
||||
BorderPart.FooterBottomSeparator => " ",
|
||||
BorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border with a heavy header.
|
||||
/// </summary>
|
||||
public sealed class MinimalHeavyHeadBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder => Border.Minimal;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => " ",
|
||||
BorderPart.HeaderTop => " ",
|
||||
BorderPart.HeaderTopSeparator => " ",
|
||||
BorderPart.HeaderTopRight => " ",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => " ",
|
||||
BorderPart.HeaderBottom => "━",
|
||||
BorderPart.HeaderBottomSeparator => "┿",
|
||||
BorderPart.HeaderBottomRight => " ",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => " ",
|
||||
BorderPart.FooterBottom => " ",
|
||||
BorderPart.FooterBottomSeparator => " ",
|
||||
BorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a rounded border.
|
||||
/// </summary>
|
||||
public sealed class RoundedBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder { get; } = Border.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "╭",
|
||||
BorderPart.HeaderTop => "─",
|
||||
BorderPart.HeaderTopSeparator => "┬",
|
||||
BorderPart.HeaderTopRight => "╮",
|
||||
BorderPart.HeaderLeft => "│",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => "│",
|
||||
BorderPart.HeaderBottomLeft => "├",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "┼",
|
||||
BorderPart.HeaderBottomRight => "┤",
|
||||
BorderPart.CellLeft => "│",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => "│",
|
||||
BorderPart.FooterBottomLeft => "╰",
|
||||
BorderPart.FooterBottom => "─",
|
||||
BorderPart.FooterBottomSeparator => "┴",
|
||||
BorderPart.FooterBottomRight => "╯",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple border.
|
||||
/// </summary>
|
||||
public sealed class SimpleBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => " ",
|
||||
BorderPart.HeaderTop => " ",
|
||||
BorderPart.HeaderTopSeparator => " ",
|
||||
BorderPart.HeaderTopRight => " ",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => " ",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => "─",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "─",
|
||||
BorderPart.HeaderBottomRight => "─",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => " ",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => " ",
|
||||
BorderPart.FooterBottom => " ",
|
||||
BorderPart.FooterBottomSeparator => " ",
|
||||
BorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple border with heavy lines.
|
||||
/// </summary>
|
||||
public sealed class SimpleHeavyBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Border? SafeBorder => Border.Simple;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => " ",
|
||||
BorderPart.HeaderTop => " ",
|
||||
BorderPart.HeaderTopSeparator => " ",
|
||||
BorderPart.HeaderTopRight => " ",
|
||||
BorderPart.HeaderLeft => " ",
|
||||
BorderPart.HeaderSeparator => " ",
|
||||
BorderPart.HeaderRight => " ",
|
||||
BorderPart.HeaderBottomLeft => "━",
|
||||
BorderPart.HeaderBottom => "━",
|
||||
BorderPart.HeaderBottomSeparator => "━",
|
||||
BorderPart.HeaderBottomRight => "━",
|
||||
BorderPart.CellLeft => " ",
|
||||
BorderPart.CellSeparator => " ",
|
||||
BorderPart.CellRight => " ",
|
||||
BorderPart.FooterBottomLeft => " ",
|
||||
BorderPart.FooterBottom => " ",
|
||||
BorderPart.FooterBottomSeparator => " ",
|
||||
BorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a square border.
|
||||
/// </summary>
|
||||
public sealed class SquareBorder : Border
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BorderPart.HeaderTopLeft => "┌",
|
||||
BorderPart.HeaderTop => "─",
|
||||
BorderPart.HeaderTopSeparator => "┬",
|
||||
BorderPart.HeaderTopRight => "┐",
|
||||
BorderPart.HeaderLeft => "│",
|
||||
BorderPart.HeaderSeparator => "│",
|
||||
BorderPart.HeaderRight => "│",
|
||||
BorderPart.HeaderBottomLeft => "├",
|
||||
BorderPart.HeaderBottom => "─",
|
||||
BorderPart.HeaderBottomSeparator => "┼",
|
||||
BorderPart.HeaderBottomRight => "┤",
|
||||
BorderPart.CellLeft => "│",
|
||||
BorderPart.CellSeparator => "│",
|
||||
BorderPart.CellRight => "│",
|
||||
BorderPart.FooterBottomLeft => "└",
|
||||
BorderPart.FooterBottom => "─",
|
||||
BorderPart.FooterBottomSeparator => "┴",
|
||||
BorderPart.FooterBottomRight => "┘",
|
||||
_ => throw new InvalidOperationException("Unknown box part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
42
src/Spectre.Console/BoxBorder.Known.cs
Normal file
42
src/Spectre.Console/BoxBorder.Known.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// </summary>
|
||||
public abstract partial class BoxBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an invisible border.
|
||||
/// </summary>
|
||||
public static BoxBorder None { get; } = new NoBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ASCII border.
|
||||
/// </summary>
|
||||
public static BoxBorder Ascii { get; } = new AsciiBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a double border.
|
||||
/// </summary>
|
||||
[SuppressMessage("Naming", "CA1720:Identifier contains type name")]
|
||||
public static BoxBorder Double { get; } = new DoubleBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a heavy border.
|
||||
/// </summary>
|
||||
public static BoxBorder Heavy { get; } = new HeavyBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a rounded border.
|
||||
/// </summary>
|
||||
public static BoxBorder Rounded { get; } = new RoundedBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a square border.
|
||||
/// </summary>
|
||||
public static BoxBorder Square { get; } = new SquareBoxBorder();
|
||||
}
|
||||
}
|
@ -9,45 +9,40 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// </summary>
|
||||
public abstract partial class Border
|
||||
public abstract partial class BoxBorder
|
||||
{
|
||||
private readonly Dictionary<BorderPart, string> _lookup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the border is visible.
|
||||
/// </summary>
|
||||
public virtual bool Visible { get; } = true;
|
||||
private readonly Dictionary<BoxBorderPart, string> _lookup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the safe border for this border or <c>null</c> if none exist.
|
||||
/// </summary>
|
||||
public virtual Border? SafeBorder { get; }
|
||||
public virtual BoxBorder? SafeBorder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Border"/> class.
|
||||
/// Initializes a new instance of the <see cref="BoxBorder"/> class.
|
||||
/// </summary>
|
||||
protected Border()
|
||||
protected BoxBorder()
|
||||
{
|
||||
_lookup = Initialize();
|
||||
}
|
||||
|
||||
private Dictionary<BorderPart, string> Initialize()
|
||||
private Dictionary<BoxBorderPart, string> Initialize()
|
||||
{
|
||||
var lookup = new Dictionary<BorderPart, string>();
|
||||
foreach (BorderPart? part in Enum.GetValues(typeof(BorderPart)))
|
||||
var lookup = new Dictionary<BoxBorderPart, string>();
|
||||
foreach (BoxBorderPart? part in Enum.GetValues(typeof(BoxBorderPart)))
|
||||
{
|
||||
if (part == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var text = GetBoxPart(part.Value);
|
||||
var text = GetBorderPart(part.Value);
|
||||
if (text.Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException("A box part cannot contain more than one character.");
|
||||
}
|
||||
|
||||
lookup.Add(part.Value, GetBoxPart(part.Value));
|
||||
lookup.Add(part.Value, GetBorderPart(part.Value));
|
||||
}
|
||||
|
||||
return lookup;
|
||||
@ -59,10 +54,10 @@ namespace Spectre.Console
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <param name="count">The number of repetitions.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(BorderPart part, int count)
|
||||
public string GetPart(BoxBorderPart part, int count)
|
||||
{
|
||||
// TODO: This need some optimization...
|
||||
return string.Join(string.Empty, Enumerable.Repeat(GetBoxPart(part)[0], count));
|
||||
return string.Join(string.Empty, Enumerable.Repeat(GetBorderPart(part)[0], count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -70,7 +65,7 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(BorderPart part)
|
||||
public string GetPart(BoxBorderPart part)
|
||||
{
|
||||
return _lookup[part].ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
@ -80,6 +75,6 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get the character representation for.</param>
|
||||
/// <returns>A character representation of the specified border part.</returns>
|
||||
protected abstract string GetBoxPart(BorderPart part);
|
||||
protected abstract string GetBorderPart(BoxBorderPart part);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console
|
||||
|
@ -3,7 +3,7 @@ using System;
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="Border"/>.
|
||||
/// Contains extension methods for <see cref="TableBorder"/>.
|
||||
/// </summary>
|
||||
public static class BorderExtensions
|
||||
{
|
||||
@ -13,7 +13,7 @@ namespace Spectre.Console.Rendering
|
||||
/// <param name="border">The border to get the safe border for.</param>
|
||||
/// <param name="safe">Whether or not to return the safe border.</param>
|
||||
/// <returns>The safe border if one exist, otherwise the original border.</returns>
|
||||
public static Border GetSafeBorder(this Border border, bool safe)
|
||||
public static TableBorder GetSafeBorder(this TableBorder border, bool safe)
|
||||
{
|
||||
if (border is null)
|
||||
{
|
||||
|
31
src/Spectre.Console/Extensions/BoxExtensions.cs
Normal file
31
src/Spectre.Console/Extensions/BoxExtensions.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="BoxBorder"/>.
|
||||
/// </summary>
|
||||
public static class BoxExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the safe border for a border.
|
||||
/// </summary>
|
||||
/// <param name="border">The border to get the safe border for.</param>
|
||||
/// <param name="safe">Whether or not to return the safe border.</param>
|
||||
/// <returns>The safe border if one exist, otherwise the original border.</returns>
|
||||
public static BoxBorder GetSafeBorder(this BoxBorder border, bool safe)
|
||||
{
|
||||
if (border is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(border));
|
||||
}
|
||||
|
||||
if (safe && border.SafeBorder != null)
|
||||
{
|
||||
border = border.SafeBorder;
|
||||
}
|
||||
|
||||
return border;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,229 +7,6 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static class HasBorderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not display a border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T NoBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a square border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SquareBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Square);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display an ASCII border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T AsciiBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Ascii);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display another ASCII border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T Ascii2Border<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Ascii2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display an ASCII border with a double header border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T AsciiDoubleHeadBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.AsciiDoubleHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a rounded border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T RoundedBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Rounded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Minimal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border with a heavy head.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalHeavyHeadBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.MinimalHeavyHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border with a double header border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalDoubleHeadBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.MinimalDoubleHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SimpleBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Simple);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border with heavy lines.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SimpleHeavyBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.SimpleHeavy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HorizontalBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Horizontal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a heavy border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Heavy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a heavy edge.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyEdgeBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.HeavyEdge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a heavy header.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyHeadBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.HeavyHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a double border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T DoubleBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.Double);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a double edge.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T DoubleEdgeBorder<T>(this T obj)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
return SetBorder(obj, Border.DoubleEdge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <param name="border">The border to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SetBorder<T>(this T obj, Border border)
|
||||
where T : class, IHasBorder
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
}
|
||||
|
||||
obj.Border = border;
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the safe border.
|
||||
/// </summary>
|
||||
|
101
src/Spectre.Console/Extensions/HasBoxBorderExtensions.cs
Normal file
101
src/Spectre.Console/Extensions/HasBoxBorderExtensions.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="IHasBoxBorder"/>.
|
||||
/// </summary>
|
||||
public static class HasBoxBorderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not display a border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T NoBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a square border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SquareBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.Square);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display an ASCII border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T AsciiBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.Ascii);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a rounded border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T RoundedBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.Rounded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a heavy border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.Heavy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a double border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T DoubleBorder<T>(this T obj)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
return SetBorder(obj, BoxBorder.Double);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <param name="border">The border to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SetBorder<T>(this T obj, BoxBorder border)
|
||||
where T : class, IHasBoxBorder
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
}
|
||||
|
||||
obj.Border = border;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
245
src/Spectre.Console/Extensions/HasTableBorderExtensions.cs
Normal file
245
src/Spectre.Console/Extensions/HasTableBorderExtensions.cs
Normal file
@ -0,0 +1,245 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="IHasTableBorder"/>.
|
||||
/// </summary>
|
||||
public static class HasTableBorderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not display a border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T NoBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a square border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SquareBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Square);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display an ASCII border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T AsciiBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Ascii);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display another ASCII border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T Ascii2Border<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Ascii2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display an ASCII border with a double header border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T AsciiDoubleHeadBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.AsciiDoubleHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a rounded border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T RoundedBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Rounded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Minimal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border with a heavy head.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalHeavyHeadBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.MinimalHeavyHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a minimal border with a double header border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MinimalDoubleHeadBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.MinimalDoubleHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SimpleBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Simple);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border with heavy lines.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SimpleHeavyBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.SimpleHeavy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a simple border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HorizontalBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Horizontal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a heavy border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Heavy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a heavy edge.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyEdgeBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.HeavyEdge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a heavy header.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T HeavyHeadBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.HeavyHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a double border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T DoubleBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Double);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a border with a double edge.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T DoubleEdgeBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.DoubleEdge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a markdown border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T MarkdownBorder<T>(this T obj)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
return SetBorder(obj, TableBorder.Markdown);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the border.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">An object type with a border.</typeparam>
|
||||
/// <param name="obj">The object to set the border for.</param>
|
||||
/// <param name="border">The border to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static T SetBorder<T>(this T obj, TableBorder border)
|
||||
where T : class, IHasTableBorder
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
}
|
||||
|
||||
obj.Border = border;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,12 +13,7 @@ namespace Spectre.Console
|
||||
bool UseSafeBorder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the border.
|
||||
/// </summary>
|
||||
public Border Border { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the border style.
|
||||
/// Gets or sets the box style.
|
||||
/// </summary>
|
||||
public Style? BorderStyle { get; set; }
|
||||
}
|
||||
|
13
src/Spectre.Console/IHasBoxBorder.cs
Normal file
13
src/Spectre.Console/IHasBoxBorder.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents something that has a box border.
|
||||
/// </summary>
|
||||
public interface IHasBoxBorder : IHasBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the box.
|
||||
/// </summary>
|
||||
public BoxBorder Border { get; set; }
|
||||
}
|
||||
}
|
13
src/Spectre.Console/IHasTableBorder.cs
Normal file
13
src/Spectre.Console/IHasTableBorder.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents something that has a border.
|
||||
/// </summary>
|
||||
public interface IHasTableBorder : IHasBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the border.
|
||||
/// </summary>
|
||||
public TableBorder Border { get; set; }
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
@ -80,27 +81,24 @@ namespace Spectre.Console.Internal
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
// https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
|
||||
public static int GetDeterministicHashCode(this string str)
|
||||
public static string Multiply(this string text, int count)
|
||||
{
|
||||
unchecked
|
||||
if (text is null)
|
||||
{
|
||||
var hash1 = (5381 << 16) + 5381;
|
||||
var hash2 = hash1;
|
||||
|
||||
for (var i = 0; i < str.Length; i += 2)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ str[i];
|
||||
if (i == str.Length - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
|
||||
}
|
||||
|
||||
return hash1 + (hash2 * 1566083941);
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
return string.Concat(Enumerable.Repeat(text, count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
src/Spectre.Console/Rendering/Borders/BoxBorderPart.cs
Normal file
48
src/Spectre.Console/Rendering/Borders/BoxBorderPart.cs
Normal file
@ -0,0 +1,48 @@
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the different parts of a box border.
|
||||
/// </summary>
|
||||
public enum BoxBorderPart
|
||||
{
|
||||
/// <summary>
|
||||
/// The top left part of a box.
|
||||
/// </summary>
|
||||
TopLeft,
|
||||
|
||||
/// <summary>
|
||||
/// The top part of a box.
|
||||
/// </summary>
|
||||
Top,
|
||||
|
||||
/// <summary>
|
||||
/// The top right part of a box.
|
||||
/// </summary>
|
||||
TopRight,
|
||||
|
||||
/// <summary>
|
||||
/// The left part of a box.
|
||||
/// </summary>
|
||||
Left,
|
||||
|
||||
/// <summary>
|
||||
/// The right part of a box.
|
||||
/// </summary>
|
||||
Right,
|
||||
|
||||
/// <summary>
|
||||
/// The bottom left part of a box.
|
||||
/// </summary>
|
||||
BottomLeft,
|
||||
|
||||
/// <summary>
|
||||
/// The bottom part of a box.
|
||||
/// </summary>
|
||||
Bottom,
|
||||
|
||||
/// <summary>
|
||||
/// The bottom right part of a box.
|
||||
/// </summary>
|
||||
BottomRight,
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border.
|
||||
/// </summary>
|
||||
public sealed class AsciiBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BoxBorderPart.TopLeft => "+",
|
||||
BoxBorderPart.Top => "-",
|
||||
BoxBorderPart.TopRight => "+",
|
||||
BoxBorderPart.Left => "|",
|
||||
BoxBorderPart.Right => "|",
|
||||
BoxBorderPart.BottomLeft => "+",
|
||||
BoxBorderPart.Bottom => "-",
|
||||
BoxBorderPart.BottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a double border.
|
||||
/// </summary>
|
||||
public sealed class DoubleBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BoxBorderPart.TopLeft => "╔",
|
||||
BoxBorderPart.Top => "═",
|
||||
BoxBorderPart.TopRight => "╗",
|
||||
BoxBorderPart.Left => "║",
|
||||
BoxBorderPart.Right => "║",
|
||||
BoxBorderPart.BottomLeft => "╚",
|
||||
BoxBorderPart.Bottom => "═",
|
||||
BoxBorderPart.BottomRight => "╝",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a heavy border.
|
||||
/// </summary>
|
||||
public sealed class HeavyBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override BoxBorder? SafeBorder => BoxBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BoxBorderPart.TopLeft => "┏",
|
||||
BoxBorderPart.Top => "━",
|
||||
BoxBorderPart.TopRight => "┓",
|
||||
BoxBorderPart.Left => "┃",
|
||||
BoxBorderPart.Right => "┃",
|
||||
BoxBorderPart.BottomLeft => "┗",
|
||||
BoxBorderPart.Bottom => "━",
|
||||
BoxBorderPart.BottomRight => "┛",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
14
src/Spectre.Console/Rendering/Borders/Boxes/NoBoxBorder.cs
Normal file
14
src/Spectre.Console/Rendering/Borders/Boxes/NoBoxBorder.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an invisible border.
|
||||
/// </summary>
|
||||
public sealed class NoBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a rounded border.
|
||||
/// </summary>
|
||||
public sealed class RoundedBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override BoxBorder? SafeBorder => BoxBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BoxBorderPart.TopLeft => "╭",
|
||||
BoxBorderPart.Top => "─",
|
||||
BoxBorderPart.TopRight => "╮",
|
||||
BoxBorderPart.Left => "│",
|
||||
BoxBorderPart.Right => "│",
|
||||
BoxBorderPart.BottomLeft => "╰",
|
||||
BoxBorderPart.Bottom => "─",
|
||||
BoxBorderPart.BottomRight => "╯",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a square border.
|
||||
/// </summary>
|
||||
public sealed class SquareBoxBorder : BoxBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(BoxBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
BoxBorderPart.TopLeft => "┌",
|
||||
BoxBorderPart.Top => "─",
|
||||
BoxBorderPart.TopRight => "┐",
|
||||
BoxBorderPart.Left => "│",
|
||||
BoxBorderPart.Right => "│",
|
||||
BoxBorderPart.BottomLeft => "└",
|
||||
BoxBorderPart.Bottom => "─",
|
||||
BoxBorderPart.BottomRight => "┘",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the different border parts.
|
||||
/// Represents the different parts of a table border.
|
||||
/// </summary>
|
||||
public enum BorderPart
|
||||
public enum TableBorderPart
|
||||
{
|
||||
/// <summary>
|
||||
/// The top left part of a header.
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents another old school ASCII border.
|
||||
/// </summary>
|
||||
public sealed class Ascii2TableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "+",
|
||||
TableBorderPart.HeaderTop => "-",
|
||||
TableBorderPart.HeaderTopSeparator => "+",
|
||||
TableBorderPart.HeaderTopRight => "+",
|
||||
TableBorderPart.HeaderLeft => "|",
|
||||
TableBorderPart.HeaderSeparator => "|",
|
||||
TableBorderPart.HeaderRight => "|",
|
||||
TableBorderPart.HeaderBottomLeft => "|",
|
||||
TableBorderPart.HeaderBottom => "-",
|
||||
TableBorderPart.HeaderBottomSeparator => "+",
|
||||
TableBorderPart.HeaderBottomRight => "|",
|
||||
TableBorderPart.CellLeft => "|",
|
||||
TableBorderPart.CellSeparator => "|",
|
||||
TableBorderPart.CellRight => "|",
|
||||
TableBorderPart.FooterBottomLeft => "+",
|
||||
TableBorderPart.FooterBottom => "-",
|
||||
TableBorderPart.FooterBottomSeparator => "+",
|
||||
TableBorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border with a double header border.
|
||||
/// </summary>
|
||||
public sealed class AsciiDoubleHeadTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "+",
|
||||
TableBorderPart.HeaderTop => "-",
|
||||
TableBorderPart.HeaderTopSeparator => "+",
|
||||
TableBorderPart.HeaderTopRight => "+",
|
||||
TableBorderPart.HeaderLeft => "|",
|
||||
TableBorderPart.HeaderSeparator => "|",
|
||||
TableBorderPart.HeaderRight => "|",
|
||||
TableBorderPart.HeaderBottomLeft => "|",
|
||||
TableBorderPart.HeaderBottom => "=",
|
||||
TableBorderPart.HeaderBottomSeparator => "+",
|
||||
TableBorderPart.HeaderBottomRight => "|",
|
||||
TableBorderPart.CellLeft => "|",
|
||||
TableBorderPart.CellSeparator => "|",
|
||||
TableBorderPart.CellRight => "|",
|
||||
TableBorderPart.FooterBottomLeft => "+",
|
||||
TableBorderPart.FooterBottom => "-",
|
||||
TableBorderPart.FooterBottomSeparator => "+",
|
||||
TableBorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border.
|
||||
/// </summary>
|
||||
public sealed class AsciiTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "+",
|
||||
TableBorderPart.HeaderTop => "-",
|
||||
TableBorderPart.HeaderTopSeparator => "-",
|
||||
TableBorderPart.HeaderTopRight => "+",
|
||||
TableBorderPart.HeaderLeft => "|",
|
||||
TableBorderPart.HeaderSeparator => "|",
|
||||
TableBorderPart.HeaderRight => "|",
|
||||
TableBorderPart.HeaderBottomLeft => "|",
|
||||
TableBorderPart.HeaderBottom => "-",
|
||||
TableBorderPart.HeaderBottomSeparator => "+",
|
||||
TableBorderPart.HeaderBottomRight => "|",
|
||||
TableBorderPart.CellLeft => "|",
|
||||
TableBorderPart.CellSeparator => "|",
|
||||
TableBorderPart.CellRight => "|",
|
||||
TableBorderPart.FooterBottomLeft => "+",
|
||||
TableBorderPart.FooterBottom => "-",
|
||||
TableBorderPart.FooterBottomSeparator => "-",
|
||||
TableBorderPart.FooterBottomRight => "+",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a double edge.
|
||||
/// </summary>
|
||||
public sealed class DoubleEdgeTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "╔",
|
||||
TableBorderPart.HeaderTop => "═",
|
||||
TableBorderPart.HeaderTopSeparator => "╤",
|
||||
TableBorderPart.HeaderTopRight => "╗",
|
||||
TableBorderPart.HeaderLeft => "║",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => "║",
|
||||
TableBorderPart.HeaderBottomLeft => "╟",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "┼",
|
||||
TableBorderPart.HeaderBottomRight => "╢",
|
||||
TableBorderPart.CellLeft => "║",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => "║",
|
||||
TableBorderPart.FooterBottomLeft => "╚",
|
||||
TableBorderPart.FooterBottom => "═",
|
||||
TableBorderPart.FooterBottomSeparator => "╧",
|
||||
TableBorderPart.FooterBottomRight => "╝",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a double border.
|
||||
/// </summary>
|
||||
public sealed class DoubleTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "╔",
|
||||
TableBorderPart.HeaderTop => "═",
|
||||
TableBorderPart.HeaderTopSeparator => "╦",
|
||||
TableBorderPart.HeaderTopRight => "╗",
|
||||
TableBorderPart.HeaderLeft => "║",
|
||||
TableBorderPart.HeaderSeparator => "║",
|
||||
TableBorderPart.HeaderRight => "║",
|
||||
TableBorderPart.HeaderBottomLeft => "╠",
|
||||
TableBorderPart.HeaderBottom => "═",
|
||||
TableBorderPart.HeaderBottomSeparator => "╬",
|
||||
TableBorderPart.HeaderBottomRight => "╣",
|
||||
TableBorderPart.CellLeft => "║",
|
||||
TableBorderPart.CellSeparator => "║",
|
||||
TableBorderPart.CellRight => "║",
|
||||
TableBorderPart.FooterBottomLeft => "╚",
|
||||
TableBorderPart.FooterBottom => "═",
|
||||
TableBorderPart.FooterBottomSeparator => "╩",
|
||||
TableBorderPart.FooterBottomRight => "╝",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a heavy edge.
|
||||
/// </summary>
|
||||
public sealed class HeavyEdgeTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "┏",
|
||||
TableBorderPart.HeaderTop => "━",
|
||||
TableBorderPart.HeaderTopSeparator => "┯",
|
||||
TableBorderPart.HeaderTopRight => "┓",
|
||||
TableBorderPart.HeaderLeft => "┃",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => "┃",
|
||||
TableBorderPart.HeaderBottomLeft => "┠",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "┼",
|
||||
TableBorderPart.HeaderBottomRight => "┨",
|
||||
TableBorderPart.CellLeft => "┃",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => "┃",
|
||||
TableBorderPart.FooterBottomLeft => "┗",
|
||||
TableBorderPart.FooterBottom => "━",
|
||||
TableBorderPart.FooterBottomSeparator => "┷",
|
||||
TableBorderPart.FooterBottomRight => "┛",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border with a heavy header.
|
||||
/// </summary>
|
||||
public sealed class HeavyHeadTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "┏",
|
||||
TableBorderPart.HeaderTop => "━",
|
||||
TableBorderPart.HeaderTopSeparator => "┳",
|
||||
TableBorderPart.HeaderTopRight => "┓",
|
||||
TableBorderPart.HeaderLeft => "┃",
|
||||
TableBorderPart.HeaderSeparator => "┃",
|
||||
TableBorderPart.HeaderRight => "┃",
|
||||
TableBorderPart.HeaderBottomLeft => "┡",
|
||||
TableBorderPart.HeaderBottom => "━",
|
||||
TableBorderPart.HeaderBottomSeparator => "╇",
|
||||
TableBorderPart.HeaderBottomRight => "┩",
|
||||
TableBorderPart.CellLeft => "│",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => "│",
|
||||
TableBorderPart.FooterBottomLeft => "└",
|
||||
TableBorderPart.FooterBottom => "─",
|
||||
TableBorderPart.FooterBottomSeparator => "┴",
|
||||
TableBorderPart.FooterBottomRight => "┘",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a heavy border.
|
||||
/// </summary>
|
||||
public sealed class HeavyTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "┏",
|
||||
TableBorderPart.HeaderTop => "━",
|
||||
TableBorderPart.HeaderTopSeparator => "┳",
|
||||
TableBorderPart.HeaderTopRight => "┓",
|
||||
TableBorderPart.HeaderLeft => "┃",
|
||||
TableBorderPart.HeaderSeparator => "┃",
|
||||
TableBorderPart.HeaderRight => "┃",
|
||||
TableBorderPart.HeaderBottomLeft => "┣",
|
||||
TableBorderPart.HeaderBottom => "━",
|
||||
TableBorderPart.HeaderBottomSeparator => "╋",
|
||||
TableBorderPart.HeaderBottomRight => "┫",
|
||||
TableBorderPart.CellLeft => "┃",
|
||||
TableBorderPart.CellSeparator => "┃",
|
||||
TableBorderPart.CellRight => "┃",
|
||||
TableBorderPart.FooterBottomLeft => "┗",
|
||||
TableBorderPart.FooterBottom => "━",
|
||||
TableBorderPart.FooterBottomSeparator => "┻",
|
||||
TableBorderPart.FooterBottomRight => "┛",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a horizontal border.
|
||||
/// </summary>
|
||||
public sealed class HorizontalTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "─",
|
||||
TableBorderPart.HeaderTop => "─",
|
||||
TableBorderPart.HeaderTopSeparator => "─",
|
||||
TableBorderPart.HeaderTopRight => "─",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => " ",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => "─",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "─",
|
||||
TableBorderPart.HeaderBottomRight => "─",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => " ",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => "─",
|
||||
TableBorderPart.FooterBottom => "─",
|
||||
TableBorderPart.FooterBottomSeparator => "─",
|
||||
TableBorderPart.FooterBottomRight => "─",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Markdown border.
|
||||
/// </summary>
|
||||
public sealed class MarkdownTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => "|",
|
||||
TableBorderPart.HeaderSeparator => "|",
|
||||
TableBorderPart.HeaderRight => "|",
|
||||
TableBorderPart.HeaderBottomLeft => "|",
|
||||
TableBorderPart.HeaderBottom => "-",
|
||||
TableBorderPart.HeaderBottomSeparator => "|",
|
||||
TableBorderPart.HeaderBottomRight => "|",
|
||||
TableBorderPart.CellLeft => "|",
|
||||
TableBorderPart.CellSeparator => "|",
|
||||
TableBorderPart.CellRight => "|",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetColumnRow(TablePart part, IReadOnlyList<int> widths, IReadOnlyList<IColumn> columns)
|
||||
{
|
||||
if (part != TablePart.Separator)
|
||||
{
|
||||
return base.GetColumnRow(part, widths, columns);
|
||||
}
|
||||
|
||||
var (left, center, separator, right) = GetTableParts(part);
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.Append(left);
|
||||
|
||||
foreach (var (columnIndex, _, lastColumn, columnWidth) in widths.Enumerate())
|
||||
{
|
||||
var padding = columns[columnIndex].Padding;
|
||||
|
||||
if (padding.Left > 0)
|
||||
{
|
||||
// Left padding
|
||||
builder.Append(" ".Multiply(padding.Left));
|
||||
}
|
||||
|
||||
var justification = columns[columnIndex].Alignment;
|
||||
if (justification == null)
|
||||
{
|
||||
// No alignment
|
||||
builder.Append(center.Multiply(columnWidth));
|
||||
}
|
||||
else if (justification.Value == Justify.Left)
|
||||
{
|
||||
// Left
|
||||
builder.Append(':');
|
||||
builder.Append(center.Multiply(columnWidth - 1));
|
||||
}
|
||||
else if (justification.Value == Justify.Center)
|
||||
{
|
||||
// Centered
|
||||
builder.Append(':');
|
||||
builder.Append(center.Multiply(columnWidth - 2));
|
||||
builder.Append(':');
|
||||
}
|
||||
else if (justification.Value == Justify.Right)
|
||||
{
|
||||
// Right
|
||||
builder.Append(center.Multiply(columnWidth - 1));
|
||||
builder.Append(':');
|
||||
}
|
||||
|
||||
// Right padding
|
||||
if (padding.Right > 0)
|
||||
{
|
||||
builder.Append(" ".Multiply(padding.Right));
|
||||
}
|
||||
|
||||
if (!lastColumn)
|
||||
{
|
||||
builder.Append(separator);
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(right);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border with a double header border.
|
||||
/// </summary>
|
||||
public sealed class MinimalDoubleHeadTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => " ",
|
||||
TableBorderPart.HeaderBottom => "═",
|
||||
TableBorderPart.HeaderBottomSeparator => "╪",
|
||||
TableBorderPart.HeaderBottomRight => " ",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border with a heavy header.
|
||||
/// </summary>
|
||||
public sealed class MinimalHeavyHeadTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Minimal;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => " ",
|
||||
TableBorderPart.HeaderBottom => "━",
|
||||
TableBorderPart.HeaderBottomSeparator => "┿",
|
||||
TableBorderPart.HeaderBottomRight => " ",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a minimal border.
|
||||
/// </summary>
|
||||
public sealed class MinimalTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => " ",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "┼",
|
||||
TableBorderPart.HeaderBottomRight => " ",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -3,13 +3,13 @@ namespace Spectre.Console.Rendering
|
||||
/// <summary>
|
||||
/// Represents an invisible border.
|
||||
/// </summary>
|
||||
public sealed class NoBorder : Border
|
||||
public sealed class NoTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool Visible => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBoxPart(BorderPart part)
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return " ";
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a rounded border.
|
||||
/// </summary>
|
||||
public sealed class RoundedTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "╭",
|
||||
TableBorderPart.HeaderTop => "─",
|
||||
TableBorderPart.HeaderTopSeparator => "┬",
|
||||
TableBorderPart.HeaderTopRight => "╮",
|
||||
TableBorderPart.HeaderLeft => "│",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => "│",
|
||||
TableBorderPart.HeaderBottomLeft => "├",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "┼",
|
||||
TableBorderPart.HeaderBottomRight => "┤",
|
||||
TableBorderPart.CellLeft => "│",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => "│",
|
||||
TableBorderPart.FooterBottomLeft => "╰",
|
||||
TableBorderPart.FooterBottom => "─",
|
||||
TableBorderPart.FooterBottomSeparator => "┴",
|
||||
TableBorderPart.FooterBottomRight => "╯",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple border with heavy lines.
|
||||
/// </summary>
|
||||
public sealed class SimpleHeavyTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TableBorder? SafeBorder => TableBorder.Simple;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => " ",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => "━",
|
||||
TableBorderPart.HeaderBottom => "━",
|
||||
TableBorderPart.HeaderBottomSeparator => "━",
|
||||
TableBorderPart.HeaderBottomRight => "━",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => " ",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple border.
|
||||
/// </summary>
|
||||
public sealed class SimpleTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => " ",
|
||||
TableBorderPart.HeaderTop => " ",
|
||||
TableBorderPart.HeaderTopSeparator => " ",
|
||||
TableBorderPart.HeaderTopRight => " ",
|
||||
TableBorderPart.HeaderLeft => " ",
|
||||
TableBorderPart.HeaderSeparator => " ",
|
||||
TableBorderPart.HeaderRight => " ",
|
||||
TableBorderPart.HeaderBottomLeft => "─",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "─",
|
||||
TableBorderPart.HeaderBottomRight => "─",
|
||||
TableBorderPart.CellLeft => " ",
|
||||
TableBorderPart.CellSeparator => " ",
|
||||
TableBorderPart.CellRight => " ",
|
||||
TableBorderPart.FooterBottomLeft => " ",
|
||||
TableBorderPart.FooterBottom => " ",
|
||||
TableBorderPart.FooterBottomSeparator => " ",
|
||||
TableBorderPart.FooterBottomRight => " ",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a square border.
|
||||
/// </summary>
|
||||
public sealed class SquareTableBorder : TableBorder
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override string GetBorderPart(TableBorderPart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
TableBorderPart.HeaderTopLeft => "┌",
|
||||
TableBorderPart.HeaderTop => "─",
|
||||
TableBorderPart.HeaderTopSeparator => "┬",
|
||||
TableBorderPart.HeaderTopRight => "┐",
|
||||
TableBorderPart.HeaderLeft => "│",
|
||||
TableBorderPart.HeaderSeparator => "│",
|
||||
TableBorderPart.HeaderRight => "│",
|
||||
TableBorderPart.HeaderBottomLeft => "├",
|
||||
TableBorderPart.HeaderBottom => "─",
|
||||
TableBorderPart.HeaderBottomSeparator => "┼",
|
||||
TableBorderPart.HeaderBottomRight => "┤",
|
||||
TableBorderPart.CellLeft => "│",
|
||||
TableBorderPart.CellSeparator => "│",
|
||||
TableBorderPart.CellRight => "│",
|
||||
TableBorderPart.FooterBottomLeft => "└",
|
||||
TableBorderPart.FooterBottom => "─",
|
||||
TableBorderPart.FooterBottomSeparator => "┴",
|
||||
TableBorderPart.FooterBottomRight => "┘",
|
||||
_ => throw new InvalidOperationException("Unknown border part."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
23
src/Spectre.Console/Rendering/TablePart.cs
Normal file
23
src/Spectre.Console/Rendering/TablePart.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents different parts of a table.
|
||||
/// </summary>
|
||||
public enum TablePart
|
||||
{
|
||||
/// <summary>
|
||||
/// The top of a table.
|
||||
/// </summary>
|
||||
Top,
|
||||
|
||||
/// <summary>
|
||||
/// The separator between the header and the cells.
|
||||
/// </summary>
|
||||
Separator,
|
||||
|
||||
/// <summary>
|
||||
/// The bottom of a table.
|
||||
/// </summary>
|
||||
Bottom,
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
@ -14,12 +14,15 @@
|
||||
<Compile Update="AnsiConsole.*.cs">
|
||||
<DependentUpon>AnsiConsole.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Color.*.cs">
|
||||
<DependentUpon>Color.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Border.*.cs">
|
||||
<DependentUpon>Border.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="BoxBorder.*.cs">
|
||||
<DependentUpon>BoxBorder.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Color.*.cs">
|
||||
<DependentUpon>Color.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Emoji.*.cs">
|
||||
<DependentUpon>Emoji.cs</DependentUpon>
|
||||
</Compile>
|
||||
@ -39,6 +42,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="BoxBorder.Known.cs">
|
||||
<DependentUpon>BoxBorder.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="TableBorder.Known.cs">
|
||||
<DependentUpon>TableBorder.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Extensions\AnsiConsoleExtensions.Markup.cs">
|
||||
<DependentUpon>AnsiConsoleExtensions.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -6,92 +6,97 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// </summary>
|
||||
public abstract partial class Border
|
||||
public abstract partial class TableBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an invisible border.
|
||||
/// </summary>
|
||||
public static Border None { get; } = new NoBorder();
|
||||
public static TableBorder None { get; } = new NoTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ASCII border.
|
||||
/// </summary>
|
||||
public static Border Ascii { get; } = new AsciiBorder();
|
||||
public static TableBorder Ascii { get; } = new AsciiTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets another ASCII border.
|
||||
/// Gets an ASCII border.
|
||||
/// </summary>
|
||||
public static Border Ascii2 { get; } = new Ascii2Border();
|
||||
public static TableBorder Ascii2 { get; } = new Ascii2TableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ASCII border with a double header border.
|
||||
/// </summary>
|
||||
public static Border AsciiDoubleHead { get; } = new AsciiDoubleHeadBorder();
|
||||
public static TableBorder AsciiDoubleHead { get; } = new AsciiDoubleHeadTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a square border.
|
||||
/// </summary>
|
||||
public static Border Square { get; } = new SquareBorder();
|
||||
public static TableBorder Square { get; } = new SquareTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a rounded border.
|
||||
/// </summary>
|
||||
public static Border Rounded { get; } = new RoundedBorder();
|
||||
public static TableBorder Rounded { get; } = new RoundedTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a minimal border.
|
||||
/// </summary>
|
||||
public static Border Minimal { get; } = new MinimalBorder();
|
||||
public static TableBorder Minimal { get; } = new MinimalTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a minimal border with a heavy head.
|
||||
/// </summary>
|
||||
public static Border MinimalHeavyHead { get; } = new MinimalHeavyHeadBorder();
|
||||
public static TableBorder MinimalHeavyHead { get; } = new MinimalHeavyHeadTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a minimal border with a double header border.
|
||||
/// </summary>
|
||||
public static Border MinimalDoubleHead { get; } = new MinimalDoubleHeadBorder();
|
||||
public static TableBorder MinimalDoubleHead { get; } = new MinimalDoubleHeadTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a simple border.
|
||||
/// </summary>
|
||||
public static Border Simple { get; } = new SimpleBorder();
|
||||
public static TableBorder Simple { get; } = new SimpleTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a simple border with heavy lines.
|
||||
/// </summary>
|
||||
public static Border SimpleHeavy { get; } = new SimpleHeavyBorder();
|
||||
public static TableBorder SimpleHeavy { get; } = new SimpleHeavyTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a horizontal border.
|
||||
/// </summary>
|
||||
public static Border Horizontal { get; } = new HorizontalBorder();
|
||||
public static TableBorder Horizontal { get; } = new HorizontalTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a heavy border.
|
||||
/// </summary>
|
||||
public static Border Heavy { get; } = new HeavyBorder();
|
||||
public static TableBorder Heavy { get; } = new HeavyTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a border with a heavy edge.
|
||||
/// </summary>
|
||||
public static Border HeavyEdge { get; } = new HeavyEdgeBorder();
|
||||
public static TableBorder HeavyEdge { get; } = new HeavyEdgeTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a border with a heavy header.
|
||||
/// </summary>
|
||||
public static Border HeavyHead { get; } = new HeavyHeadBorder();
|
||||
public static TableBorder HeavyHead { get; } = new HeavyHeadTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a double border.
|
||||
/// </summary>
|
||||
[SuppressMessage("Naming", "CA1720:Identifier contains type name")]
|
||||
public static Border Double { get; } = new DoubleBorder();
|
||||
public static TableBorder Double { get; } = new DoubleTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a border with a double edge.
|
||||
/// </summary>
|
||||
public static Border DoubleEdge { get; } = new DoubleEdgeBorder();
|
||||
public static TableBorder DoubleEdge { get; } = new DoubleEdgeTableBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a markdown border.
|
||||
/// </summary>
|
||||
public static TableBorder Markdown { get; } = new MarkdownTableBorder();
|
||||
}
|
||||
}
|
157
src/Spectre.Console/TableBorder.cs
Normal file
157
src/Spectre.Console/TableBorder.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// </summary>
|
||||
public abstract partial class TableBorder
|
||||
{
|
||||
private readonly Dictionary<TableBorderPart, string> _lookup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the border is visible.
|
||||
/// </summary>
|
||||
public virtual bool Visible { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the safe border for this border or <c>null</c> if none exist.
|
||||
/// </summary>
|
||||
public virtual TableBorder? SafeBorder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TableBorder"/> class.
|
||||
/// </summary>
|
||||
protected TableBorder()
|
||||
{
|
||||
_lookup = Initialize();
|
||||
}
|
||||
|
||||
private Dictionary<TableBorderPart, string> Initialize()
|
||||
{
|
||||
var lookup = new Dictionary<TableBorderPart, string>();
|
||||
foreach (TableBorderPart? part in Enum.GetValues(typeof(TableBorderPart)))
|
||||
{
|
||||
if (part == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var text = GetBorderPart(part.Value);
|
||||
if (text.Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException("A box part cannot contain more than one character.");
|
||||
}
|
||||
|
||||
lookup.Add(part.Value, GetBorderPart(part.Value));
|
||||
}
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representation of a specific border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <param name="count">The number of repetitions.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(TableBorderPart part, int count)
|
||||
{
|
||||
// TODO: This need some optimization...
|
||||
return string.Join(string.Empty, Enumerable.Repeat(GetBorderPart(part)[0], count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a whole column row for the specific column row part.
|
||||
/// </summary>
|
||||
/// <param name="part">The column row part.</param>
|
||||
/// <param name="widths">The column widths.</param>
|
||||
/// <param name="columns">The columns.</param>
|
||||
/// <returns>A string representing the column row.</returns>
|
||||
public virtual string GetColumnRow(TablePart part, IReadOnlyList<int> widths, IReadOnlyList<IColumn> columns)
|
||||
{
|
||||
if (widths is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(widths));
|
||||
}
|
||||
|
||||
if (columns is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columns));
|
||||
}
|
||||
|
||||
var (left, center, separator, right) = GetTableParts(part);
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.Append(left);
|
||||
|
||||
foreach (var (columnIndex, _, lastColumn, columnWidth) in widths.Enumerate())
|
||||
{
|
||||
var padding = columns[columnIndex].Padding;
|
||||
var centerWidth = padding.Left + columnWidth + padding.Right;
|
||||
builder.Append(center.Multiply(centerWidth));
|
||||
|
||||
if (!lastColumn)
|
||||
{
|
||||
builder.Append(separator);
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(right);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representation of a specific border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(TableBorderPart part)
|
||||
{
|
||||
return _lookup[part].ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the character representing the specified border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get the character representation for.</param>
|
||||
/// <returns>A character representation of the specified border part.</returns>
|
||||
protected abstract string GetBorderPart(TableBorderPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the table parts used to render a specific table row.
|
||||
/// </summary>
|
||||
/// <param name="part">The table part.</param>
|
||||
/// <returns>The table parts used to render the specific table row.</returns>
|
||||
protected (string Left, string Center, string Separator, string Right)
|
||||
GetTableParts(TablePart part)
|
||||
{
|
||||
return part switch
|
||||
{
|
||||
// Top part
|
||||
TablePart.Top =>
|
||||
(GetPart(TableBorderPart.HeaderTopLeft), GetPart(TableBorderPart.HeaderTop),
|
||||
GetPart(TableBorderPart.HeaderTopSeparator), GetPart(TableBorderPart.HeaderTopRight)),
|
||||
|
||||
// Separator between header and cells
|
||||
TablePart.Separator =>
|
||||
(GetPart(TableBorderPart.HeaderBottomLeft), GetPart(TableBorderPart.HeaderBottom),
|
||||
GetPart(TableBorderPart.HeaderBottomSeparator), GetPart(TableBorderPart.HeaderBottomRight)),
|
||||
|
||||
// Bottom part
|
||||
TablePart.Bottom =>
|
||||
(GetPart(TableBorderPart.FooterBottomLeft), GetPart(TableBorderPart.FooterBottom),
|
||||
GetPart(TableBorderPart.FooterBottomSeparator), GetPart(TableBorderPart.FooterBottomRight)),
|
||||
|
||||
// Unknown
|
||||
_ => throw new NotSupportedException("Unknown column row part"),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ namespace Spectre.Console
|
||||
{
|
||||
_table = new Table
|
||||
{
|
||||
Border = Border.None,
|
||||
Border = TableBorder.None,
|
||||
ShowHeaders = false,
|
||||
IsGrid = true,
|
||||
PadRightCell = false,
|
||||
|
@ -8,14 +8,14 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// A renderable panel.
|
||||
/// </summary>
|
||||
public sealed class Panel : Renderable, IHasBorder, IExpandable, IPaddable
|
||||
public sealed class Panel : Renderable, IHasBoxBorder, IExpandable, IPaddable
|
||||
{
|
||||
private const int EdgeWidth = 2;
|
||||
|
||||
private readonly IRenderable _child;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Border Border { get; set; } = Border.Square;
|
||||
public BoxBorder Border { get; set; } = BoxBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool UseSafeBorder { get; set; } = true;
|
||||
@ -95,7 +95,7 @@ namespace Spectre.Console
|
||||
var childSegments = ((IRenderable)child).Render(context, childWidth);
|
||||
foreach (var line in Segment.SplitLines(childSegments, panelWidth))
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BoxBorderPart.Left), borderStyle));
|
||||
|
||||
var content = new List<Segment>();
|
||||
content.AddRange(line);
|
||||
@ -110,7 +110,7 @@ namespace Spectre.Console
|
||||
|
||||
result.AddRange(content);
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BoxBorderPart.Right), borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
|
||||
@ -120,17 +120,17 @@ namespace Spectre.Console
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void AddBottomBorder(List<Segment> result, Border border, Style borderStyle, int panelWidth)
|
||||
private static void AddBottomBorder(List<Segment> result, BoxBorder border, Style borderStyle, int panelWidth)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottomLeft), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, panelWidth - EdgeWidth), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottomRight), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BoxBorderPart.BottomLeft), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BoxBorderPart.Bottom, panelWidth - EdgeWidth), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BoxBorderPart.BottomRight), borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
|
||||
private void AddTopBorder(List<Segment> segments, RenderContext context, Border border, Style borderStyle, int panelWidth)
|
||||
private void AddTopBorder(List<Segment> segments, RenderContext context, BoxBorder border, Style borderStyle, int panelWidth)
|
||||
{
|
||||
segments.Add(new Segment(border.GetPart(BorderPart.HeaderTopLeft), borderStyle));
|
||||
segments.Add(new Segment(border.GetPart(BoxBorderPart.TopLeft), borderStyle));
|
||||
|
||||
if (Header != null)
|
||||
{
|
||||
@ -160,16 +160,16 @@ namespace Spectre.Console
|
||||
}
|
||||
}
|
||||
|
||||
segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, leftSpacing + 1), borderStyle));
|
||||
segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, leftSpacing + 1), borderStyle));
|
||||
segments.Add(header);
|
||||
segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, rightSpacing + 1), borderStyle));
|
||||
segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, rightSpacing + 1), borderStyle));
|
||||
}
|
||||
else
|
||||
{
|
||||
segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, panelWidth - EdgeWidth), borderStyle));
|
||||
segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, panelWidth - EdgeWidth), borderStyle));
|
||||
}
|
||||
|
||||
segments.Add(new Segment(border.GetPart(BorderPart.HeaderTopRight), borderStyle));
|
||||
segments.Add(new Segment(border.GetPart(BoxBorderPart.TopRight), borderStyle));
|
||||
segments.Add(Segment.LineBreak);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// A renderable table.
|
||||
/// </summary>
|
||||
public sealed class Table : Renderable, IHasBorder, IExpandable
|
||||
public sealed class Table : Renderable, IHasTableBorder, IExpandable
|
||||
{
|
||||
private const int EdgeCount = 2;
|
||||
|
||||
@ -27,7 +27,7 @@ namespace Spectre.Console
|
||||
public int RowCount => _rows.Count;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Border Border { get; set; } = Border.Square;
|
||||
public TableBorder Border { get; set; } = TableBorder.Square;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Style? BorderStyle { get; set; }
|
||||
@ -202,22 +202,8 @@ namespace Spectre.Console
|
||||
// Show top of header?
|
||||
if (firstRow && showBorder)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTopLeft), borderStyle));
|
||||
foreach (var (columnIndex, _, lastColumn, columnWidth) in columnWidths.Enumerate())
|
||||
{
|
||||
var padding = _columns[columnIndex].Padding;
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, padding.Left), borderStyle)); // Left padding
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, columnWidth), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, padding.Right), borderStyle)); // Right padding
|
||||
|
||||
if (!lastColumn)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTopSeparator), borderStyle));
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderTopRight), borderStyle));
|
||||
var separator = border.GetColumnRow(TablePart.Top, columnWidths, _columns);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
|
||||
@ -232,7 +218,7 @@ namespace Spectre.Console
|
||||
if (firstCell && showBorder)
|
||||
{
|
||||
// Show left column edge
|
||||
var part = firstRow && ShowHeaders ? BorderPart.HeaderLeft : BorderPart.CellLeft;
|
||||
var part = firstRow && ShowHeaders ? TableBorderPart.HeaderLeft : TableBorderPart.CellLeft;
|
||||
result.Add(new Segment(border.GetPart(part), borderStyle));
|
||||
}
|
||||
|
||||
@ -269,13 +255,13 @@ namespace Spectre.Console
|
||||
if (lastCell && showBorder)
|
||||
{
|
||||
// Add right column edge
|
||||
var part = firstRow && ShowHeaders ? BorderPart.HeaderRight : BorderPart.CellRight;
|
||||
var part = firstRow && ShowHeaders ? TableBorderPart.HeaderRight : TableBorderPart.CellRight;
|
||||
result.Add(new Segment(border.GetPart(part), borderStyle));
|
||||
}
|
||||
else if (showBorder)
|
||||
{
|
||||
// Add column separator
|
||||
var part = firstRow && ShowHeaders ? BorderPart.HeaderSeparator : BorderPart.CellSeparator;
|
||||
var part = firstRow && ShowHeaders ? TableBorderPart.HeaderSeparator : TableBorderPart.CellSeparator;
|
||||
result.Add(new Segment(border.GetPart(part), borderStyle));
|
||||
}
|
||||
}
|
||||
@ -286,44 +272,16 @@ namespace Spectre.Console
|
||||
// Show header separator?
|
||||
if (firstRow && showBorder && ShowHeaders && hasRows)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomLeft), borderStyle));
|
||||
foreach (var (columnIndex, first, lastColumn, columnWidth) in columnWidths.Enumerate())
|
||||
{
|
||||
var padding = _columns[columnIndex].Padding;
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, padding.Left), borderStyle)); // Left padding
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, columnWidth), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, padding.Right), borderStyle)); // Right padding
|
||||
|
||||
if (!lastColumn)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomSeparator), borderStyle));
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomRight), borderStyle));
|
||||
var separator = border.GetColumnRow(TablePart.Separator, columnWidths, _columns);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
|
||||
// Show bottom of footer?
|
||||
if (lastRow && showBorder)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottomLeft), borderStyle));
|
||||
foreach (var (columnIndex, first, lastColumn, columnWidth) in columnWidths.Enumerate())
|
||||
{
|
||||
var padding = _columns[columnIndex].Padding;
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, padding.Left), borderStyle)); // Left padding
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, columnWidth), borderStyle));
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, padding.Right), borderStyle)); // Right padding
|
||||
|
||||
if (!lastColumn)
|
||||
{
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottomSeparator), borderStyle));
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(new Segment(border.GetPart(BorderPart.FooterBottomRight), borderStyle));
|
||||
var separator = border.GetColumnRow(TablePart.Bottom, columnWidths, _columns);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user