Patrik Svensson 52c1d9122b
Add global usings (#668)
* Use global usings

* Fix namespace declarations for test projects
2021-12-23 16:50:31 +01:00

242 lines
7.2 KiB
C#

namespace Spectre.Console;
/// <summary>
/// Represents color and text decoration.
/// </summary>
public sealed class Style : IEquatable<Style>
{
/// <summary>
/// Gets the foreground color.
/// </summary>
public Color Foreground { get; }
/// <summary>
/// Gets the background color.
/// </summary>
public Color Background { get; }
/// <summary>
/// Gets the text decoration.
/// </summary>
public Decoration Decoration { get; }
/// <summary>
/// Gets the link associated with the style.
/// </summary>
public string? Link { get; }
/// <summary>
/// Gets a <see cref="Style"/> with the
/// default colors and without text decoration.
/// </summary>
public static Style Plain { get; } = new Style();
/// <summary>
/// Initializes a new instance of the <see cref="Style"/> class.
/// </summary>
/// <param name="foreground">The foreground color.</param>
/// <param name="background">The background color.</param>
/// <param name="decoration">The text decoration.</param>
/// <param name="link">The link.</param>
public Style(Color? foreground = null, Color? background = null, Decoration? decoration = null, string? link = null)
{
Foreground = foreground ?? Color.Default;
Background = background ?? Color.Default;
Decoration = decoration ?? Decoration.None;
Link = link;
}
/// <summary>
/// Creates a new style from the specified foreground color.
/// </summary>
/// <param name="color">The foreground color.</param>
/// <returns>A new <see cref="Style"/> with the specified foreground color.</returns>
[Obsolete("Use ctor(..) instead")]
public static Style WithForeground(Color color)
{
return new Style(foreground: color);
}
/// <summary>
/// Creates a new style from the specified background color.
/// </summary>
/// <param name="color">The background color.</param>
/// <returns>A new <see cref="Style"/> with the specified background color.</returns>
[Obsolete("Use ctor(..) instead")]
public static Style WithBackground(Color color)
{
return new Style(background: color);
}
/// <summary>
/// Creates a new style from the specified text decoration.
/// </summary>
/// <param name="decoration">The text decoration.</param>
/// <returns>A new <see cref="Style"/> with the specified text decoration.</returns>
[Obsolete("Use ctor(..) instead")]
public static Style WithDecoration(Decoration decoration)
{
return new Style(decoration: decoration);
}
/// <summary>
/// Creates a new style from the specified link.
/// </summary>
/// <param name="link">The link.</param>
/// <returns>A new <see cref="Style"/> with the specified link.</returns>
[Obsolete("Use ctor(..) instead")]
public static Style WithLink(string link)
{
return new Style(link: link);
}
/// <summary>
/// Combines this style with another one.
/// </summary>
/// <param name="other">The item to combine with this.</param>
/// <returns>A new style representing a combination of this and the other one.</returns>
public Style Combine(Style other)
{
if (other is null)
{
throw new ArgumentNullException(nameof(other));
}
var foreground = Foreground;
if (!other.Foreground.IsDefault)
{
foreground = other.Foreground;
}
var background = Background;
if (!other.Background.IsDefault)
{
background = other.Background;
}
var link = Link;
if (!string.IsNullOrWhiteSpace(other.Link))
{
link = other.Link;
}
return new Style(foreground, background, Decoration | other.Decoration, link);
}
/// <summary>
/// Implicitly converts <see cref="string"/> into a <see cref="Style"/>.
/// </summary>
/// <param name="style">The style string.</param>
public static implicit operator Style(string style)
{
return Parse(style);
}
/// <summary>
/// Converts the string representation of a style to its <see cref="Style"/> equivalent.
/// </summary>
/// <param name="text">A string containing a style to parse.</param>
/// <returns>A <see cref="Style"/> equivalent of the text contained in <paramref name="text"/>.</returns>
public static Style Parse(string text)
{
return StyleParser.Parse(text);
}
/// <summary>
/// Converts the string representation of a style to its <see cref="Style"/> equivalent.
/// A return value indicates whether the operation succeeded.
/// </summary>
/// <param name="text">A string containing a style to parse.</param>
/// <param name="result">
/// When this method returns, contains the <see cref="Style"/> equivalent of the text contained in <paramref name="text"/>,
/// if the conversion succeeded, or <c>null</c> if the conversion failed.
/// </param>
/// <returns><c>true</c> if s was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string text, out Style? result)
{
return StyleParser.TryParse(text, out result);
}
/// <inheritdoc/>
public override int GetHashCode()
{
int? GetLinkHashCode()
{
#if NETSTANDARD2_0
return Link?.GetHashCode();
#else
return Link?.GetHashCode(StringComparison.Ordinal);
#endif
}
unchecked
{
var hash = (int)2166136261;
hash = (hash * 16777619) ^ Foreground.GetHashCode();
hash = (hash * 16777619) ^ Background.GetHashCode();
hash = (hash * 16777619) ^ Decoration.GetHashCode();
if (Link != null)
{
hash = (hash * 16777619) ^ GetLinkHashCode() ?? 0;
}
return hash;
}
}
/// <summary>
/// Returns the markup representation of this style.
/// </summary>
/// <returns>The markup representation of this style.</returns>
public string ToMarkup()
{
var builder = new List<string>();
if (Decoration != Decoration.None)
{
var result = DecorationTable.GetMarkupNames(Decoration);
if (result.Count != 0)
{
builder.AddRange(result);
}
}
if (Foreground != Color.Default)
{
builder.Add(Foreground.ToMarkup());
}
if (Background != Color.Default)
{
if (builder.Count == 0)
{
builder.Add("default");
}
builder.Add("on " + Background.ToMarkup());
}
return string.Join(" ", builder);
}
/// <inheritdoc/>
public override bool Equals(object? obj)
{
return Equals(obj as Style);
}
/// <inheritdoc/>
public bool Equals(Style? other)
{
if (other == null)
{
return false;
}
return Foreground.Equals(other.Foreground) &&
Background.Equals(other.Background) &&
Decoration == other.Decoration &&
string.Equals(Link, other.Link, StringComparison.Ordinal);
}
}