mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00

committed by
Patrik Svensson

parent
effdecb1d4
commit
8a01b93aca
@ -1,4 +1,4 @@
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
|
@ -1,27 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="Text"/>.
|
||||
/// </summary>
|
||||
public static class TextExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the text alignment.
|
||||
/// </summary>
|
||||
/// <param name="text">The <see cref="Text"/> instance.</param>
|
||||
/// <param name="alignment">The text alignment.</param>
|
||||
/// <returns>The same <see cref="Text"/> instance.</returns>
|
||||
public static Text WithAlignment(this Text text, Justify alignment)
|
||||
{
|
||||
if (text is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
text.Alignment = alignment;
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
|
61
src/Spectre.Console/Rendering/AlignableExtensions.cs
Normal file
61
src/Spectre.Console/Rendering/AlignableExtensions.cs
Normal file
@ -0,0 +1,61 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="IAlignable"/>.
|
||||
/// </summary>
|
||||
public static class AlignableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the alignment for an <see cref="IAlignable"/> object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The alignable type.</typeparam>
|
||||
/// <param name="alignable">The alignable object.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>The same alignable object.</returns>
|
||||
public static T WithAlignment<T>(this T alignable, Justify alignment)
|
||||
where T : IAlignable
|
||||
{
|
||||
alignable.Alignment = alignment;
|
||||
return alignable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IAlignable"/> object to be left aligned.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The alignable type.</typeparam>
|
||||
/// <param name="alignable">The alignable object.</param>
|
||||
/// <returns>The same alignable object.</returns>
|
||||
public static T LeftAligned<T>(this T alignable)
|
||||
where T : IAlignable
|
||||
{
|
||||
alignable.Alignment = Justify.Left;
|
||||
return alignable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IAlignable"/> object to be centered.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The alignable type.</typeparam>
|
||||
/// <param name="alignable">The alignable object.</param>
|
||||
/// <returns>The same alignable object.</returns>
|
||||
public static T Centered<T>(this T alignable)
|
||||
where T : IAlignable
|
||||
{
|
||||
alignable.Alignment = Justify.Center;
|
||||
return alignable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IAlignable"/> object to be right aligned.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The alignable type.</typeparam>
|
||||
/// <param name="alignable">The alignable object.</param>
|
||||
/// <returns>The same alignable object.</returns>
|
||||
public static T RightAligned<T>(this T alignable)
|
||||
where T : IAlignable
|
||||
{
|
||||
alignable.Alignment = Justify.Right;
|
||||
return alignable;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border used by tables.
|
@ -1,4 +1,4 @@
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the different border parts.
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an old school ASCII border.
|
@ -1,4 +1,4 @@
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an invisible border.
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a rounded border.
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a square border.
|
@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a grid.
|
||||
/// A renderable grid.
|
||||
/// </summary>
|
||||
public sealed class Grid : IRenderable
|
||||
public sealed class Grid : Renderable
|
||||
{
|
||||
private readonly Table _table;
|
||||
|
||||
@ -28,13 +28,13 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Measurement Measure(RenderContext context, int maxWidth)
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return ((IRenderable)_table).Measure(context, maxWidth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<Segment> Render(RenderContext context, int width)
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int width)
|
||||
{
|
||||
return ((IRenderable)_table).Render(context, width);
|
||||
}
|
||||
@ -109,8 +109,8 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public void AddEmptyRow()
|
||||
{
|
||||
var columns = new string[_table.ColumnCount];
|
||||
Enumerable.Range(0, _table.ColumnCount).ForEach(index => columns[index] = string.Empty);
|
||||
var columns = new IRenderable[_table.ColumnCount];
|
||||
Enumerable.Range(0, _table.ColumnCount).ForEach(index => columns[index] = Text.Empty);
|
||||
AddRow(columns);
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ namespace Spectre.Console
|
||||
/// Adds a new row to the grid.
|
||||
/// </summary>
|
||||
/// <param name="columns">The columns to add.</param>
|
||||
public void AddRow(params string[] columns)
|
||||
public void AddRow(params IRenderable[] columns)
|
||||
{
|
||||
if (columns is null)
|
||||
{
|
@ -3,7 +3,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Represents a grid column.
|
||||
/// </summary>
|
||||
public sealed class GridColumn
|
||||
public sealed class GridColumn : IAlignable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the column.
|
31
src/Spectre.Console/Rendering/GridExtensions.cs
Normal file
31
src/Spectre.Console/Rendering/GridExtensions.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="Grid"/>.
|
||||
/// </summary>
|
||||
public static class GridExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new row to the grid.
|
||||
/// </summary>
|
||||
/// <param name="grid">The grid to add the row to.</param>
|
||||
/// <param name="columns">The columns to add.</param>
|
||||
public static void AddRow(this Grid grid, params string[] columns)
|
||||
{
|
||||
if (grid is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(grid));
|
||||
}
|
||||
|
||||
if (columns is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columns));
|
||||
}
|
||||
|
||||
grid.AddRow(columns.Select(column => new Markup(column)).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
13
src/Spectre.Console/Rendering/IAlignable.cs
Normal file
13
src/Spectre.Console/Rendering/IAlignable.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents something that is alignable.
|
||||
/// </summary>
|
||||
public interface IAlignable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the alignment.
|
||||
/// </summary>
|
||||
Justify? Alignment { get; set; }
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents something that can be rendered to the console.
|
43
src/Spectre.Console/Rendering/Markup.cs
Normal file
43
src/Spectre.Console/Rendering/Markup.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// A renderable piece of markup text.
|
||||
/// </summary>
|
||||
public sealed class Markup : Renderable, IAlignable
|
||||
{
|
||||
private readonly Text _text;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Justify? Alignment
|
||||
{
|
||||
get => _text.Alignment;
|
||||
set => _text.Alignment = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Markup"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The markup text.</param>
|
||||
/// <param name="style">The style of the text.</param>
|
||||
public Markup(string text, Style? style = null)
|
||||
{
|
||||
_text = MarkupParser.Parse(text, style);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return ((IRenderable)_text).Measure(context, maxWidth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
return ((IRenderable)_text).Render(context, maxWidth);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a measurement.
|
@ -1,13 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Rendering;
|
||||
using SpectreBorder = Spectre.Console.Rendering.Border;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a panel which contains another renderable item.
|
||||
/// A renderable panel.
|
||||
/// </summary>
|
||||
public sealed class Panel : IRenderable
|
||||
public sealed class Panel : Renderable
|
||||
{
|
||||
private const int EdgeWidth = 2;
|
||||
|
||||
@ -42,6 +43,15 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public Padding Padding { get; set; } = new Padding(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Panel"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The panel content.</param>
|
||||
public Panel(string text)
|
||||
: this(new Markup(text))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Panel"/> class.
|
||||
/// </summary>
|
||||
@ -52,23 +62,25 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
Measurement IRenderable.Measure(RenderContext context, int maxWidth)
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
var childWidth = _child.Measure(context, maxWidth);
|
||||
return new Measurement(childWidth.Min + 2 + Padding.GetHorizontalPadding(), childWidth.Max + 2 + Padding.GetHorizontalPadding());
|
||||
return new Measurement(
|
||||
childWidth.Min + 2 + Padding.GetHorizontalPadding(),
|
||||
childWidth.Max + 2 + Padding.GetHorizontalPadding());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerable<Segment> IRenderable.Render(RenderContext context, int width)
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
var border = Composition.Border.GetBorder(Border, (context.LegacyConsole || !context.Unicode) && SafeBorder);
|
||||
var border = SpectreBorder.GetBorder(Border, (context.LegacyConsole || !context.Unicode) && SafeBorder);
|
||||
|
||||
var paddingWidth = Padding.GetHorizontalPadding();
|
||||
var childWidth = width - EdgeWidth - paddingWidth;
|
||||
var childWidth = maxWidth - EdgeWidth - paddingWidth;
|
||||
|
||||
if (!Expand)
|
||||
{
|
||||
var measurement = _child.Measure(context, width - EdgeWidth - paddingWidth);
|
||||
var measurement = _child.Measure(context, maxWidth - EdgeWidth - paddingWidth);
|
||||
childWidth = measurement.Max;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a render context.
|
41
src/Spectre.Console/Rendering/Renderable.cs
Normal file
41
src/Spectre.Console/Rendering/Renderable.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for a renderable object implementing <see cref="IRenderable"/>.
|
||||
/// </summary>
|
||||
public abstract class Renderable : IRenderable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
Measurement IRenderable.Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return Measure(context, maxWidth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerable<Segment> IRenderable.Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
return Render(context, maxWidth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measures the renderable object.
|
||||
/// </summary>
|
||||
/// <param name="context">The render context.</param>
|
||||
/// <param name="maxWidth">The maximum allowed width.</param>
|
||||
/// <returns>The minimum and maximum width of the object.</returns>
|
||||
protected virtual Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return new Measurement(maxWidth, maxWidth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the object.
|
||||
/// </summary>
|
||||
/// <param name="context">The render context.</param>
|
||||
/// <param name="maxWidth">The maximum allowed width.</param>
|
||||
/// <returns>A collection of segments.</returns>
|
||||
protected abstract IEnumerable<Segment> Render(RenderContext context, int maxWidth);
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a renderable segment.
|
@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of segments.
|
@ -1,7 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
internal sealed class SegmentLineEnumerator : IEnumerable<Segment>
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Composition
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
internal sealed class SegmentLineIterator : IEnumerator<Segment>
|
||||
{
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
@ -100,13 +100,13 @@ namespace Spectre.Console
|
||||
var maxWidths = new List<int>();
|
||||
|
||||
// Include columns in measurement
|
||||
var measure = ((IRenderable)column.Text).Measure(options, maxWidth);
|
||||
var measure = column.Text.Measure(options, maxWidth);
|
||||
minWidths.Add(measure.Min);
|
||||
maxWidths.Add(measure.Max);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
measure = ((IRenderable)row).Measure(options, maxWidth);
|
||||
measure = row.Measure(options, maxWidth);
|
||||
minWidths.Add(measure.Min);
|
||||
maxWidths.Add(measure.Max);
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
using SpectreBorder = Spectre.Console.Rendering.Border;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a table.
|
||||
/// A renderable table.
|
||||
/// </summary>
|
||||
public sealed partial class Table : IRenderable
|
||||
public sealed partial class Table : Renderable
|
||||
{
|
||||
private readonly List<TableColumn> _columns;
|
||||
private readonly List<List<Text>> _rows;
|
||||
private readonly List<List<IRenderable>> _rows;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of columns in the table.
|
||||
@ -67,21 +68,7 @@ namespace Spectre.Console
|
||||
public Table()
|
||||
{
|
||||
_columns = new List<TableColumn>();
|
||||
_rows = new List<List<Text>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a column to the table.
|
||||
/// </summary>
|
||||
/// <param name="column">The column to add.</param>
|
||||
public void AddColumn(string column)
|
||||
{
|
||||
if (column is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(column));
|
||||
}
|
||||
|
||||
AddColumn(new TableColumn(column));
|
||||
_rows = new List<List<IRenderable>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -103,23 +90,6 @@ namespace Spectre.Console
|
||||
_columns.Add(column);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds multiple columns to the table.
|
||||
/// </summary>
|
||||
/// <param name="columns">The columns to add.</param>
|
||||
public void AddColumns(params string[] columns)
|
||||
{
|
||||
if (columns is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columns));
|
||||
}
|
||||
|
||||
foreach (var column in columns)
|
||||
{
|
||||
AddColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds multiple columns to the table.
|
||||
/// </summary>
|
||||
@ -142,8 +112,8 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public void AddEmptyRow()
|
||||
{
|
||||
var columns = new string[ColumnCount];
|
||||
Enumerable.Range(0, ColumnCount).ForEach(index => columns[index] = string.Empty);
|
||||
var columns = new IRenderable[ColumnCount];
|
||||
Enumerable.Range(0, ColumnCount).ForEach(index => columns[index] = Text.Empty);
|
||||
AddRow(columns);
|
||||
}
|
||||
|
||||
@ -151,7 +121,7 @@ namespace Spectre.Console
|
||||
/// Adds a row to the table.
|
||||
/// </summary>
|
||||
/// <param name="columns">The row columns to add.</param>
|
||||
public void AddRow(params string[] columns)
|
||||
public void AddRow(params IRenderable[] columns)
|
||||
{
|
||||
if (columns is null)
|
||||
{
|
||||
@ -168,11 +138,11 @@ namespace Spectre.Console
|
||||
throw new InvalidOperationException("The number of row columns are greater than the number of table columns.");
|
||||
}
|
||||
|
||||
_rows.Add(columns.Select(column => Text.Markup(column)).ToList());
|
||||
_rows.Add(columns.ToList());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
Measurement IRenderable.Measure(RenderContext context, int maxWidth)
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
@ -194,20 +164,20 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerable<Segment> IRenderable.Render(RenderContext context, int width)
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
var border = Composition.Border.GetBorder(Border, (context.LegacyConsole || !context.Unicode) && SafeBorder);
|
||||
var border = SpectreBorder.GetBorder(Border, (context.LegacyConsole || !context.Unicode) && SafeBorder);
|
||||
var tableWidth = maxWidth;
|
||||
|
||||
var showBorder = Border != BorderKind.None;
|
||||
var hideBorder = Border == BorderKind.None;
|
||||
var hasRows = _rows.Count > 0;
|
||||
|
||||
var maxWidth = width;
|
||||
if (Width != null)
|
||||
{
|
||||
maxWidth = Math.Min(Width.Value, maxWidth);
|
||||
@ -219,13 +189,13 @@ namespace Spectre.Console
|
||||
var columnWidths = CalculateColumnWidths(context, maxWidth);
|
||||
|
||||
// Update the table width.
|
||||
width = columnWidths.Sum() + GetExtraWidth(includePadding: true);
|
||||
tableWidth = columnWidths.Sum() + GetExtraWidth(includePadding: true);
|
||||
|
||||
var rows = new List<List<Text>>();
|
||||
var rows = new List<List<IRenderable>>();
|
||||
if (ShowHeaders)
|
||||
{
|
||||
// Add columns to top of rows
|
||||
rows.Add(new List<Text>(_columns.Select(c => c.Text)));
|
||||
rows.Add(new List<IRenderable>(_columns.Select(c => c.Text)));
|
||||
}
|
||||
|
||||
// Add rows.
|
||||
@ -244,7 +214,7 @@ namespace Spectre.Console
|
||||
var justification = _columns[columnIndex].Alignment;
|
||||
var childContext = context.WithJustification(justification);
|
||||
|
||||
var lines = Segment.SplitLines(((IRenderable)cell).Render(childContext, rowWidth));
|
||||
var lines = Segment.SplitLines(cell.Render(childContext, rowWidth));
|
||||
cellHeight = Math.Max(cellHeight, lines.Count);
|
||||
cells.Add(lines);
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a table column.
|
||||
/// </summary>
|
||||
public sealed class TableColumn
|
||||
public sealed class TableColumn : IAlignable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the text associated with the column.
|
||||
/// </summary>
|
||||
public Text Text { get; }
|
||||
public IRenderable Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the column.
|
||||
@ -39,8 +40,17 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
/// <param name="text">The table column text.</param>
|
||||
public TableColumn(string text)
|
||||
: this(new Markup(text))
|
||||
{
|
||||
Text = Text.Markup(text ?? throw new ArgumentNullException(nameof(text)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TableColumn"/> class.
|
||||
/// </summary>
|
||||
/// <param name="renderable">The <see cref="IRenderable"/> instance to use as the table column.</param>
|
||||
public TableColumn(IRenderable renderable)
|
||||
{
|
||||
Text = renderable ?? throw new ArgumentNullException(nameof(renderable));
|
||||
Width = null;
|
||||
Padding = new Padding(1, 1);
|
||||
NoWrap = false;
|
78
src/Spectre.Console/Rendering/TableExtensions.cs
Normal file
78
src/Spectre.Console/Rendering/TableExtensions.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="Table"/>.
|
||||
/// </summary>
|
||||
public static class TableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a column to the table.
|
||||
/// </summary>
|
||||
/// <param name="table">The table to add the column to.</param>
|
||||
/// <param name="column">The column to add.</param>
|
||||
/// <returns>The added <see cref="TableColumn"/> instance.</returns>
|
||||
public static TableColumn AddColumn(this Table table, string column)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
if (column is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(column));
|
||||
}
|
||||
|
||||
var tableColumn = new TableColumn(column);
|
||||
table.AddColumn(tableColumn);
|
||||
|
||||
return tableColumn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds multiple columns to the table.
|
||||
/// </summary>
|
||||
/// <param name="table">The table to add the columns to.</param>
|
||||
/// <param name="columns">The columns to add.</param>
|
||||
public static void AddColumns(this Table table, params string[] columns)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
if (columns is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columns));
|
||||
}
|
||||
|
||||
foreach (var column in columns)
|
||||
{
|
||||
AddColumn(table, column);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a row to the table.
|
||||
/// </summary>
|
||||
/// <param name="table">The table to add the row to.</param>
|
||||
/// <param name="columns">The row columns to add.</param>
|
||||
public static void AddRow(this Table table, params string[] columns)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
if (columns is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columns));
|
||||
}
|
||||
|
||||
table.AddRow(columns.Select(column => new Markup(column)).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
@ -3,24 +3,29 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Composition;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a piece of text.
|
||||
/// A renderable piece of text.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{_text,nq}")]
|
||||
[SuppressMessage("Naming", "CA1724:Type names should not match namespaces")]
|
||||
public sealed class Text : IRenderable
|
||||
public sealed class Text : Renderable, IAlignable
|
||||
{
|
||||
private readonly List<SegmentLine> _lines;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an empty <see cref="Text"/> instance.
|
||||
/// </summary>
|
||||
public static Text Empty { get; } = new Text(string.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text alignment.
|
||||
/// </summary>
|
||||
public Justify Alignment { get; set; } = Justify.Left;
|
||||
public Justify? Alignment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Text"/> class.
|
||||
@ -60,7 +65,7 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Measurement Measure(RenderContext context, int maxWidth)
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (_lines.Count == 0)
|
||||
{
|
||||
@ -74,7 +79,7 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
@ -89,7 +94,7 @@ namespace Spectre.Console
|
||||
var lines = SplitLines(context, maxWidth);
|
||||
|
||||
// Justify lines
|
||||
var justification = context.Justification ?? Alignment;
|
||||
var justification = context.Justification ?? Alignment ?? Justify.Left;
|
||||
foreach (var (_, _, last, line) in lines.Enumerate())
|
||||
{
|
||||
var length = line.Sum(l => l.StripLineEndings().CellLength(context.Encoding));
|
Reference in New Issue
Block a user