mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add support for aligning tables
This commit is contained in:

committed by
Patrik Svensson

parent
b52056ee49
commit
9afc1ea721
@ -27,7 +27,7 @@ namespace Spectre.Console
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetHeader(panel, new Title(text, style, alignment));
|
||||
return SetHeader(panel, new PanelHeader(text, style, alignment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -36,7 +36,7 @@ namespace Spectre.Console
|
||||
/// <param name="panel">The panel.</param>
|
||||
/// <param name="header">The header to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Panel SetHeader(this Panel panel, Title header)
|
||||
public static Panel SetHeader(this Panel panel, PanelHeader header)
|
||||
{
|
||||
if (panel is null)
|
||||
{
|
||||
|
@ -183,9 +183,8 @@ namespace Spectre.Console
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="text">The heading.</param>
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetHeading(this Table table, string text, Style? style = null, Justify? alignment = null)
|
||||
public static Table SetHeading(this Table table, string text, Style? style = null)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
@ -197,7 +196,7 @@ namespace Spectre.Console
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetHeading(table, new Title(text, style, alignment));
|
||||
return SetHeading(table, new TableTitle(text, style));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -206,7 +205,7 @@ namespace Spectre.Console
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="heading">The heading.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetHeading(this Table table, Title heading)
|
||||
public static Table SetHeading(this Table table, TableTitle heading)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
@ -223,9 +222,8 @@ namespace Spectre.Console
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="text">The footnote.</param>
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetFootnote(this Table table, string text, Style? style = null, Justify? alignment = null)
|
||||
public static Table SetFootnote(this Table table, string text, Style? style = null)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
@ -237,7 +235,7 @@ namespace Spectre.Console
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetFootnote(table, new Title(text, style, alignment));
|
||||
return SetFootnote(table, new TableTitle(text, style));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -246,7 +244,7 @@ namespace Spectre.Console
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="footnote">The footnote.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetFootnote(this Table table, Title footnote)
|
||||
public static Table SetFootnote(this Table table, TableTitle footnote)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
|
97
src/Spectre.Console/Internal/Aligner.cs
Normal file
97
src/Spectre.Console/Internal/Aligner.cs
Normal file
@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal static class Aligner
|
||||
{
|
||||
public static string Align(RenderContext context, string text, Justify? alignment, int maxWidth)
|
||||
{
|
||||
if (alignment == null || alignment == Justify.Left)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
var width = Cell.GetCellLength(context, text);
|
||||
if (width >= maxWidth)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
switch (alignment)
|
||||
{
|
||||
case Justify.Right:
|
||||
{
|
||||
var diff = maxWidth - width;
|
||||
return new string(' ', diff) + text;
|
||||
}
|
||||
|
||||
case Justify.Center:
|
||||
{
|
||||
var diff = (maxWidth - width) / 2;
|
||||
|
||||
var left = new string(' ', diff);
|
||||
var right = new string(' ', diff);
|
||||
|
||||
// Right side
|
||||
var remainder = (maxWidth - width) % 2;
|
||||
if (remainder != 0)
|
||||
{
|
||||
right += new string(' ', remainder);
|
||||
}
|
||||
|
||||
return left + text + right;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new NotSupportedException("Unknown alignment");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Align<T>(RenderContext context, T segments, Justify? alignment, int maxWidth)
|
||||
where T : List<Segment>
|
||||
{
|
||||
if (alignment == null || alignment == Justify.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var width = Segment.CellLength(context, segments);
|
||||
if (width >= maxWidth)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (alignment)
|
||||
{
|
||||
case Justify.Right:
|
||||
{
|
||||
var diff = maxWidth - width;
|
||||
segments.Insert(0, new Segment(new string(' ', diff)));
|
||||
break;
|
||||
}
|
||||
|
||||
case Justify.Center:
|
||||
{
|
||||
// Left side.
|
||||
var diff = (maxWidth - width) / 2;
|
||||
segments.Insert(0, new Segment(new string(' ', diff)));
|
||||
|
||||
// Right side
|
||||
segments.Add(new Segment(new string(' ', diff)));
|
||||
var remainder = (maxWidth - width) % 2;
|
||||
if (remainder != 0)
|
||||
{
|
||||
segments.Add(new Segment(new string(' ', remainder)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new NotSupportedException("Unknown alignment");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Internal;
|
||||
@ -68,12 +67,7 @@ namespace Spectre.Console.Rendering
|
||||
|
||||
private Segment(string text, Style style, bool lineBreak)
|
||||
{
|
||||
if (text is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
Text = text.NormalizeLineEndings();
|
||||
Text = text?.NormalizeLineEndings() ?? throw new ArgumentNullException(nameof(text));
|
||||
Style = style ?? throw new ArgumentNullException(nameof(style));
|
||||
IsLineBreak = lineBreak;
|
||||
IsWhiteSpace = string.IsNullOrWhiteSpace(text);
|
||||
@ -121,6 +115,15 @@ namespace Spectre.Console.Rendering
|
||||
new Segment(Text.Substring(offset, Text.Length - offset), Style));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the segment.
|
||||
/// </summary>
|
||||
/// <returns>A new segment that's identical to this one.</returns>
|
||||
public Segment Clone()
|
||||
{
|
||||
return new Segment(Text, Style);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of cells that the segments occupies in the console.
|
||||
/// </summary>
|
||||
@ -238,48 +241,6 @@ namespace Spectre.Console.Rendering
|
||||
return lines;
|
||||
}
|
||||
|
||||
internal static IEnumerable<Segment> Merge(IEnumerable<Segment> segments)
|
||||
{
|
||||
var result = new List<Segment>();
|
||||
|
||||
var previous = (Segment?)null;
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
if (previous == null)
|
||||
{
|
||||
previous = segment;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Same style?
|
||||
if (previous.Style.Equals(segment.Style) && !previous.IsLineBreak)
|
||||
{
|
||||
previous = new Segment(previous.Text + segment.Text, previous.Style);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(previous);
|
||||
previous = segment;
|
||||
}
|
||||
}
|
||||
|
||||
if (previous != null)
|
||||
{
|
||||
result.Add(previous);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the segment.
|
||||
/// </summary>
|
||||
/// <returns>A new segment that's identical to this one.</returns>
|
||||
public Segment Clone()
|
||||
{
|
||||
return new Segment(Text, Style);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits an overflowing segment into several new segments.
|
||||
/// </summary>
|
||||
@ -436,6 +397,39 @@ namespace Spectre.Console.Rendering
|
||||
return new Segment(builder.ToString(), segment.Style);
|
||||
}
|
||||
|
||||
internal static IEnumerable<Segment> Merge(IEnumerable<Segment> segments)
|
||||
{
|
||||
var result = new List<Segment>();
|
||||
|
||||
var previous = (Segment?)null;
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
if (previous == null)
|
||||
{
|
||||
previous = segment;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Same style?
|
||||
if (previous.Style.Equals(segment.Style) && !previous.IsLineBreak)
|
||||
{
|
||||
previous = new Segment(previous.Text + segment.Text, previous.Style);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(previous);
|
||||
previous = segment;
|
||||
}
|
||||
}
|
||||
|
||||
if (previous != null)
|
||||
{
|
||||
result.Add(previous);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Segment TruncateWithEllipsis(string text, Style style, RenderContext context, int maxWidth)
|
||||
{
|
||||
return SplitOverflow(
|
||||
|
@ -11,7 +11,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// A renderable calendar.
|
||||
/// </summary>
|
||||
public sealed class Calendar : Renderable, IHasCulture, IHasTableBorder
|
||||
public sealed class Calendar : Renderable, IHasCulture, IHasTableBorder, IAlignable
|
||||
{
|
||||
private const int NumberOfWeekDays = 7;
|
||||
private const int ExpectedRowCount = 6;
|
||||
@ -30,6 +30,7 @@ namespace Spectre.Console
|
||||
private Style _highlightStyle;
|
||||
private bool _showHeader;
|
||||
private Style? _headerStyle;
|
||||
private Justify? _alignment;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the calendar year.
|
||||
@ -115,6 +116,13 @@ namespace Spectre.Console
|
||||
set => MarkAsDirty(() => _headerStyle = value);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Justify? Alignment
|
||||
{
|
||||
get => _alignment;
|
||||
set => MarkAsDirty(() => _alignment = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing all calendar events.
|
||||
/// </summary>
|
||||
@ -195,12 +203,13 @@ namespace Spectre.Console
|
||||
Border = _border,
|
||||
UseSafeBorder = _useSafeBorder,
|
||||
BorderStyle = _borderStyle,
|
||||
Alignment = _alignment,
|
||||
};
|
||||
|
||||
if (ShowHeader)
|
||||
{
|
||||
var heading = new DateTime(Year, Month, Day).ToString("Y", culture).EscapeMarkup();
|
||||
table.Heading = new Title(heading, HeaderStyle);
|
||||
table.Heading = new TableTitle(heading, HeaderStyle);
|
||||
}
|
||||
|
||||
// Add columns
|
||||
|
@ -7,7 +7,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// A renderable grid.
|
||||
/// </summary>
|
||||
public sealed class Grid : Renderable, IExpandable
|
||||
public sealed class Grid : Renderable, IExpandable, IAlignable
|
||||
{
|
||||
private readonly Table _table;
|
||||
|
||||
@ -28,6 +28,13 @@ namespace Spectre.Console
|
||||
set => _table.Expand = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Justify? Alignment
|
||||
{
|
||||
get => _table.Alignment;
|
||||
set => _table.Alignment = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Grid"/> class.
|
||||
/// </summary>
|
||||
|
@ -39,7 +39,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Gets or sets the header.
|
||||
/// </summary>
|
||||
public Title? Header { get; set; }
|
||||
public PanelHeader? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Panel"/> class.
|
||||
|
76
src/Spectre.Console/Widgets/PanelHeader.cs
Normal file
76
src/Spectre.Console/Widgets/PanelHeader.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a panel header.
|
||||
/// </summary>
|
||||
public sealed class PanelHeader : IAlignable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the panel header text.
|
||||
/// </summary>
|
||||
public string Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the panel header style.
|
||||
/// </summary>
|
||||
public Style? Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the panel header alignment.
|
||||
/// </summary>
|
||||
public Justify? Alignment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PanelHeader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The panel header text.</param>
|
||||
/// <param name="style">The panel header style.</param>
|
||||
/// <param name="alignment">The panel header alignment.</param>
|
||||
public PanelHeader(string text, Style? style = null, Justify? alignment = null)
|
||||
{
|
||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
||||
Style = style;
|
||||
Alignment = alignment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the panel header style.
|
||||
/// </summary>
|
||||
/// <param name="style">The panel header style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public PanelHeader SetStyle(Style? style)
|
||||
{
|
||||
Style = style ?? Style.Plain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the panel header style.
|
||||
/// </summary>
|
||||
/// <param name="style">The panel header style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public PanelHeader SetStyle(string style)
|
||||
{
|
||||
if (style is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(style));
|
||||
}
|
||||
|
||||
Style = Style.Parse(style);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the panel header alignment.
|
||||
/// </summary>
|
||||
/// <param name="alignment">The panel header alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public PanelHeader SetAlignment(Justify alignment)
|
||||
{
|
||||
Alignment = alignment;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -144,37 +144,18 @@ namespace Spectre.Console
|
||||
|
||||
// Justify lines
|
||||
var justification = context.Justification ?? Alignment ?? Justify.Left;
|
||||
foreach (var (_, _, last, line) in lines.Enumerate())
|
||||
if (justification != Justify.Left)
|
||||
{
|
||||
var length = line.Sum(l => l.StripLineEndings().CellLength(context));
|
||||
if (length < maxWidth)
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Justify right side
|
||||
if (justification == Justify.Right)
|
||||
{
|
||||
var diff = maxWidth - length;
|
||||
line.Prepend(new Segment(new string(' ', diff)));
|
||||
}
|
||||
else if (justification == Justify.Center)
|
||||
{
|
||||
// Left side.
|
||||
var diff = (maxWidth - length) / 2;
|
||||
line.Prepend(new Segment(new string(' ', diff)));
|
||||
|
||||
// Right side
|
||||
line.Add(new Segment(new string(' ', diff)));
|
||||
var remainder = (maxWidth - length) % 2;
|
||||
if (remainder != 0)
|
||||
{
|
||||
line.Add(new Segment(new string(' ', remainder)));
|
||||
}
|
||||
}
|
||||
Aligner.Align(context, line, justification, maxWidth);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.SingleLine)
|
||||
{
|
||||
return lines.First().Where(segment => !segment.IsLineBreak);
|
||||
// Return the first line
|
||||
return lines[0].Where(segment => !segment.IsLineBreak);
|
||||
}
|
||||
|
||||
return new SegmentLineEnumerator(lines);
|
||||
|
@ -9,7 +9,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// A renderable table.
|
||||
/// </summary>
|
||||
public sealed class Table : Renderable, IHasTableBorder, IExpandable
|
||||
public sealed class Table : Renderable, IHasTableBorder, IExpandable, IAlignable
|
||||
{
|
||||
private const int EdgeCount = 2;
|
||||
|
||||
@ -58,12 +58,15 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Gets or sets the table title.
|
||||
/// </summary>
|
||||
public Title? Heading { get; set; }
|
||||
public TableTitle? Heading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the table footnote.
|
||||
/// </summary>
|
||||
public Title? Footnote { get; set; }
|
||||
public TableTitle? Footnote { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Justify? Alignment { get; set; }
|
||||
|
||||
// Whether this is a grid or not.
|
||||
internal bool IsGrid { get; set; }
|
||||
@ -200,7 +203,7 @@ namespace Spectre.Console
|
||||
rows.AddRange(_rows);
|
||||
|
||||
var result = new List<Segment>();
|
||||
result.AddRange(RenderAnnotation(context, Heading, tableWidth, _defaultHeadingStyle));
|
||||
result.AddRange(RenderAnnotation(context, Heading, actualMaxWidth, tableWidth, _defaultHeadingStyle));
|
||||
|
||||
// Iterate all rows
|
||||
foreach (var (index, firstRow, lastRow, row) in rows.Enumerate())
|
||||
@ -222,7 +225,7 @@ namespace Spectre.Console
|
||||
// Show top of header?
|
||||
if (firstRow && showBorder)
|
||||
{
|
||||
var separator = border.GetColumnRow(TablePart.Top, columnWidths, _columns);
|
||||
var separator = Aligner.Align(context, border.GetColumnRow(TablePart.Top, columnWidths, _columns), Alignment, actualMaxWidth);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
@ -288,6 +291,9 @@ namespace Spectre.Console
|
||||
}
|
||||
}
|
||||
|
||||
// Align the row result.
|
||||
Aligner.Align(context, rowResult, Alignment, actualMaxWidth);
|
||||
|
||||
// Is the row larger than the allowed max width?
|
||||
if (Segment.CellLength(context, rowResult) > actualMaxWidth)
|
||||
{
|
||||
@ -304,7 +310,7 @@ namespace Spectre.Console
|
||||
// Show header separator?
|
||||
if (firstRow && showBorder && ShowHeaders && hasRows)
|
||||
{
|
||||
var separator = border.GetColumnRow(TablePart.Separator, columnWidths, _columns);
|
||||
var separator = Aligner.Align(context, border.GetColumnRow(TablePart.Separator, columnWidths, _columns), Alignment, actualMaxWidth);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
@ -312,13 +318,13 @@ namespace Spectre.Console
|
||||
// Show bottom of footer?
|
||||
if (lastRow && showBorder)
|
||||
{
|
||||
var separator = border.GetColumnRow(TablePart.Bottom, columnWidths, _columns);
|
||||
var separator = Aligner.Align(context, border.GetColumnRow(TablePart.Bottom, columnWidths, _columns), Alignment, actualMaxWidth);
|
||||
result.Add(new Segment(separator, borderStyle));
|
||||
result.Add(Segment.LineBreak);
|
||||
}
|
||||
}
|
||||
|
||||
result.AddRange(RenderAnnotation(context, Footnote, tableWidth, _defaultFootnoteStyle));
|
||||
result.AddRange(RenderAnnotation(context, Footnote, actualMaxWidth, tableWidth, _defaultFootnoteStyle));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -392,25 +398,27 @@ namespace Spectre.Console
|
||||
return widths;
|
||||
}
|
||||
|
||||
private static IEnumerable<Segment> RenderAnnotation(
|
||||
RenderContext context, Title? header,
|
||||
int maxWidth, Style defaultStyle)
|
||||
private IEnumerable<Segment> RenderAnnotation(
|
||||
RenderContext context, TableTitle? header,
|
||||
int maxWidth, int tableWidth, Style defaultStyle)
|
||||
{
|
||||
if (header == null)
|
||||
{
|
||||
yield break;
|
||||
return Array.Empty<Segment>();
|
||||
}
|
||||
|
||||
var paragraph = new Markup(header.Text.Capitalize(), header.Style ?? defaultStyle)
|
||||
.SetAlignment(header.Alignment ?? Justify.Center)
|
||||
.SetAlignment(Justify.Center)
|
||||
.SetOverflow(Overflow.Ellipsis);
|
||||
|
||||
foreach (var segment in ((IRenderable)paragraph).Render(context, maxWidth))
|
||||
{
|
||||
yield return segment;
|
||||
}
|
||||
var items = new List<Segment>();
|
||||
items.AddRange(((IRenderable)paragraph).Render(context, tableWidth));
|
||||
|
||||
yield return Segment.LineBreak;
|
||||
// Align over the whole buffer area
|
||||
Aligner.Align(context, items, Alignment, maxWidth);
|
||||
|
||||
items.Add(Segment.LineBreak);
|
||||
return items;
|
||||
}
|
||||
|
||||
private (int Min, int Max) MeasureColumn(TableColumn column, RenderContext options, int maxWidth)
|
||||
|
@ -3,9 +3,9 @@ using System;
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a title.
|
||||
/// Represents a table title such as a heading or footnote.
|
||||
/// </summary>
|
||||
public sealed class Title : IAlignable
|
||||
public sealed class TableTitle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the title text.
|
||||
@ -18,21 +18,14 @@ namespace Spectre.Console
|
||||
public Style? Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title alignment.
|
||||
/// </summary>
|
||||
public Justify? Alignment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Title"/> class.
|
||||
/// Initializes a new instance of the <see cref="TableTitle"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The title text.</param>
|
||||
/// <param name="style">The title style.</param>
|
||||
/// <param name="alignment">The title alignment.</param>
|
||||
public Title(string text, Style? style = null, Justify? alignment = null)
|
||||
public TableTitle(string text, Style? style = null)
|
||||
{
|
||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
||||
Style = style;
|
||||
Alignment = alignment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -40,20 +33,25 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
/// <param name="style">The title style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public Title SetStyle(Style? style)
|
||||
public TableTitle SetStyle(Style? style)
|
||||
{
|
||||
Style = style ?? Style.Plain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the title alignment.
|
||||
/// Sets the title style.
|
||||
/// </summary>
|
||||
/// <param name="alignment">The title alignment.</param>
|
||||
/// <param name="style">The title style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public Title SetAlignment(Justify alignment)
|
||||
public TableTitle SetStyle(string style)
|
||||
{
|
||||
Alignment = alignment;
|
||||
if (style is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(style));
|
||||
}
|
||||
|
||||
Style = Style.Parse(style);
|
||||
return this;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user