Clean up public API

* Make things a bit more consistent
* Add extension methods to configure things like tables, panels and grids.
This commit is contained in:
Patrik Svensson
2020-08-26 15:03:49 +02:00
committed by Patrik Svensson
parent c111c7d463
commit 31f117aed0
24 changed files with 569 additions and 266 deletions

View File

@ -0,0 +1,81 @@
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 object type.</typeparam>
/// <param name="obj">The alignable object.</param>
/// <param name="alignment">The alignment.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T SetAlignment<T>(this T obj, Justify alignment)
where T : class, IAlignable
{
if (obj is null)
{
throw new System.ArgumentNullException(nameof(obj));
}
obj.Alignment = alignment;
return obj;
}
/// <summary>
/// Sets the <see cref="IAlignable"/> object to be left aligned.
/// </summary>
/// <typeparam name="T">The alignable type.</typeparam>
/// <param name="obj">The alignable object.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T LeftAligned<T>(this T obj)
where T : class, IAlignable
{
if (obj is null)
{
throw new System.ArgumentNullException(nameof(obj));
}
obj.Alignment = Justify.Left;
return obj;
}
/// <summary>
/// Sets the <see cref="IAlignable"/> object to be centered.
/// </summary>
/// <typeparam name="T">The alignable type.</typeparam>
/// <param name="obj">The alignable object.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T Centered<T>(this T obj)
where T : class, IAlignable
{
if (obj is null)
{
throw new System.ArgumentNullException(nameof(obj));
}
obj.Alignment = Justify.Center;
return obj;
}
/// <summary>
/// Sets the <see cref="IAlignable"/> object to be right aligned.
/// </summary>
/// <typeparam name="T">The alignable type.</typeparam>
/// <param name="obj">The alignable object.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T RightAligned<T>(this T obj)
where T : class, IAlignable
{
if (obj is null)
{
throw new System.ArgumentNullException(nameof(obj));
}
obj.Alignment = Justify.Right;
return obj;
}
}
}

View File

@ -0,0 +1,66 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// Contains extension methods for <see cref="IHasBorder"/>.
/// </summary>
public static class BorderExtensions
{
/// <summary>
/// Sets the border.
/// </summary>
/// <typeparam name="T">The object that has 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, BorderKind 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>
/// <typeparam name="T">The object that has 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 NoSafeBorder<T>(this T obj)
where T : class, IHasBorder
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
obj.SafeBorder = false;
return obj;
}
/// <summary>
/// Sets the border color.
/// </summary>
/// <typeparam name="T">The object that has a border.</typeparam>
/// <param name="obj">The object to set the border color for.</param>
/// <param name="color">The color to set.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T SetBorderColor<T>(this T obj, Color color)
where T : class, IHasBorder
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
obj.BorderColor = color;
return obj;
}
}
}

View File

@ -0,0 +1,28 @@
using System;
namespace Spectre.Console
{
/// <summary>
/// Contains extension methods for <see cref="IColumn"/>.
/// </summary>
public static class ColumnExtensions
{
/// <summary>
/// Prevents a column from wrapping.
/// </summary>
/// <typeparam name="T">An object implementing <see cref="IColumn"/>.</typeparam>
/// <param name="obj">The column.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T NoWrap<T>(this T obj)
where T : class, IColumn
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
obj.NoWrap = true;
return obj;
}
}
}

View File

@ -0,0 +1,48 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// Contains extension methods for <see cref="IExpandable"/>.
/// </summary>
public static class ExpandableExtensions
{
/// <summary>
/// Tells the specified object to not expand to the available area
/// but take as little space as possible.
/// </summary>
/// <typeparam name="T">The expandable object.</typeparam>
/// <param name="obj">The object to collapse.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T Collapse<T>(this T obj)
where T : class, IExpandable
{
SetExpand<T>(obj, false);
return obj;
}
/// <summary>
/// Tells the specified object to expand to the available area.
/// </summary>
/// <typeparam name="T">The expandable object.</typeparam>
/// <param name="obj">The object to expand.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T Expand<T>(this T obj)
where T : class, IExpandable
{
SetExpand<T>(obj, true);
return obj;
}
private static void SetExpand<T>(T obj, bool value)
where T : class, IExpandable
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
obj.Expand = value;
}
}
}

View File

@ -0,0 +1,79 @@
using System;
namespace Spectre.Console
{
/// <summary>
/// Contains extension methods for <see cref="IPaddable"/>.
/// </summary>
public static class PaddableExtensions
{
/// <summary>
/// Sets the left padding.
/// </summary>
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
/// <param name="obj">The paddable object instance.</param>
/// <param name="padding">The left padding to apply.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T PadLeft<T>(this T obj, int padding)
where T : class, IPaddable
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
return SetPadding(obj, new Padding(padding, obj.Padding.Right));
}
/// <summary>
/// Sets the right padding.
/// </summary>
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
/// <param name="obj">The paddable object instance.</param>
/// <param name="padding">The right padding to apply.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T PadRight<T>(this T obj, int padding)
where T : class, IPaddable
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
return SetPadding(obj, new Padding(obj.Padding.Left, padding));
}
/// <summary>
/// Sets the left and right padding.
/// </summary>
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
/// <param name="obj">The paddable object instance.</param>
/// <param name="left">The left padding to apply.</param>
/// <param name="right">The right padding to apply.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T SetPadding<T>(this T obj, int left, int right)
where T : class, IPaddable
{
return SetPadding(obj, new Padding(left, right));
}
/// <summary>
/// Sets the padding.
/// </summary>
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
/// <param name="obj">The paddable object instance.</param>
/// <param name="padding">The padding to apply.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static T SetPadding<T>(this T obj, Padding padding)
where T : class, IPaddable
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
obj.Padding = padding;
return obj;
}
}
}

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

View File

@ -0,0 +1,14 @@
namespace Spectre.Console
{
/// <summary>
/// Represents a column.
/// </summary>
public interface IColumn : IAlignable, IPaddable
{
/// <summary>
/// Gets or sets a value indicating whether
/// or not wrapping should be prevented.
/// </summary>
bool NoWrap { get; set; }
}
}

View File

@ -0,0 +1,15 @@
namespace Spectre.Console
{
/// <summary>
/// Represents something that is expandable.
/// </summary>
public interface IExpandable
{
/// <summary>
/// Gets or sets a value indicating whether or not the object should
/// expand to the available space. If <c>false</c>, the object's
/// width will be auto calculated.
/// </summary>
bool Expand { get; set; }
}
}

View File

@ -0,0 +1,25 @@
namespace Spectre.Console
{
/// <summary>
/// Represents something that has a border.
/// </summary>
public interface IHasBorder
{
/// <summary>
/// Gets or sets a value indicating whether or not to use
/// a "safe" border on legacy consoles that might not be able
/// to render non-ASCII characters.
/// </summary>
bool SafeBorder { get; set; }
/// <summary>
/// Gets or sets the kind of border to use.
/// </summary>
public BorderKind Border { get; set; }
/// <summary>
/// Gets or sets the border color.
/// </summary>
public Color? BorderColor { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace Spectre.Console
{
/// <summary>
/// Represents something that is paddable.
/// </summary>
public interface IPaddable
{
/// <summary>
/// Gets or sets the padding.
/// </summary>
public Padding Padding { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Spectre.Console.Rendering
{
/// <summary>
/// Represents something that can be rendered to the console.
/// </summary>
public interface IRenderable
{
/// <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>
Measurement Measure(RenderContext context, int 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>
IEnumerable<Segment> Render(RenderContext context, int maxWidth);
}
}