mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-20 18:42:50 +08:00
242 lines
7.2 KiB
C#
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);
|
|
}
|
|
} |