Attribute.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #nullable enable
  2. using System.Text.Json.Serialization;
  3. namespace Terminal.Gui;
  4. /// <summary>Attributes represent how text is styled when displayed in the terminal.</summary>
  5. /// <remarks>
  6. /// <see cref="Attribute"/> provides a platform independent representation of colors (and someday other forms of
  7. /// text styling). They encode both the foreground and the background color and are used in the
  8. /// <see cref="ColorScheme"/> class to define color schemes that can be used in an application.
  9. /// </remarks>
  10. [JsonConverter (typeof (AttributeJsonConverter))]
  11. public readonly struct Attribute : IEquatable<Attribute>
  12. {
  13. /// <summary>Default empty attribute.</summary>
  14. public static readonly Attribute Default = new (Color.White, ColorName.Black);
  15. /// <summary>The <see cref="ConsoleDriver"/>-specific color value.</summary>
  16. [JsonIgnore (Condition = JsonIgnoreCondition.Always)]
  17. internal int PlatformColor { get; }
  18. /// <summary>The foreground color.</summary>
  19. [JsonConverter (typeof (ColorJsonConverter))]
  20. public Color Foreground { get; }
  21. /// <summary>The background color.</summary>
  22. [JsonConverter (typeof (ColorJsonConverter))]
  23. public Color Background { get; }
  24. /// <summary>Initializes a new instance with default values.</summary>
  25. public Attribute ()
  26. {
  27. PlatformColor = -1;
  28. Foreground = Default.Foreground;
  29. Background = Default.Background;
  30. }
  31. /// <summary>Initializes a new instance from an existing instance.</summary>
  32. public Attribute (in Attribute attr)
  33. {
  34. PlatformColor = -1;
  35. Foreground = attr.Foreground;
  36. Background = attr.Background;
  37. }
  38. /// <summary>Initializes a new instance with platform specific color value.</summary>
  39. /// <param name="platformColor">Value.</param>
  40. internal Attribute (int platformColor)
  41. {
  42. PlatformColor = platformColor;
  43. Foreground = Default.Foreground;
  44. Background = Default.Background;
  45. }
  46. /// <summary>Initializes a new instance of the <see cref="Attribute"/> struct.</summary>
  47. /// <param name="platformColor">platform-dependent color value.</param>
  48. /// <param name="foreground">Foreground</param>
  49. /// <param name="background">Background</param>
  50. internal Attribute (int platformColor, in Color foreground, in Color background)
  51. {
  52. Foreground = foreground;
  53. Background = background;
  54. PlatformColor = platformColor;
  55. }
  56. /// <summary>Initializes a new instance of the <see cref="Attribute"/> struct.</summary>
  57. /// <param name="foreground">Foreground</param>
  58. /// <param name="background">Background</param>
  59. public Attribute (Color foreground, Color background)
  60. {
  61. Foreground = foreground;
  62. Background = background;
  63. // TODO: Once CursesDriver supports truecolor all the PlatformColor stuff goes away
  64. if (Application.Driver == null)
  65. {
  66. PlatformColor = -1;
  67. return;
  68. }
  69. Attribute make = Application.Driver.MakeColor (foreground, background);
  70. PlatformColor = make.PlatformColor;
  71. }
  72. /// <summary>
  73. /// Initializes a new instance with a <see cref="ColorName"/> value. Both <see cref="Foreground"/> and
  74. /// <see cref="Background"/> will be set to the specified color.
  75. /// </summary>
  76. /// <param name="colorName">Value.</param>
  77. internal Attribute (ColorName colorName) : this (colorName, colorName) { }
  78. /// <summary>Initializes a new instance of the <see cref="Attribute"/> struct.</summary>
  79. /// <param name="foregroundName">Foreground</param>
  80. /// <param name="backgroundName">Background</param>
  81. public Attribute (in ColorName foregroundName, in ColorName backgroundName) : this (
  82. new Color (foregroundName),
  83. new Color (backgroundName)
  84. )
  85. { }
  86. /// <summary>Initializes a new instance of the <see cref="Attribute"/> struct.</summary>
  87. /// <param name="foregroundName">Foreground</param>
  88. /// <param name="background">Background</param>
  89. public Attribute (ColorName foregroundName, Color background) : this (new Color (foregroundName), background) { }
  90. /// <summary>Initializes a new instance of the <see cref="Attribute"/> struct.</summary>
  91. /// <param name="foreground">Foreground</param>
  92. /// <param name="backgroundName">Background</param>
  93. public Attribute (Color foreground, ColorName backgroundName) : this (foreground, new Color (backgroundName)) { }
  94. /// <summary>
  95. /// Initializes a new instance of the <see cref="Attribute"/> struct with the same colors for the foreground and
  96. /// background.
  97. /// </summary>
  98. /// <param name="color">The color.</param>
  99. public Attribute (Color color) : this (color, color) { }
  100. /// <summary>Compares two attributes for equality.</summary>
  101. /// <param name="left"></param>
  102. /// <param name="right"></param>
  103. /// <returns></returns>
  104. public static bool operator == (Attribute left, Attribute right) { return left.Equals (right); }
  105. /// <summary>Compares two attributes for inequality.</summary>
  106. /// <param name="left"></param>
  107. /// <param name="right"></param>
  108. /// <returns></returns>
  109. public static bool operator != (Attribute left, Attribute right) { return !(left == right); }
  110. /// <inheritdoc/>
  111. public override bool Equals (object? obj) { return obj is Attribute other && Equals (other); }
  112. /// <inheritdoc/>
  113. public bool Equals (Attribute other) { return PlatformColor == other.PlatformColor && Foreground == other.Foreground && Background == other.Background; }
  114. /// <inheritdoc/>
  115. public override int GetHashCode () { return HashCode.Combine (PlatformColor, Foreground, Background); }
  116. /// <inheritdoc/>
  117. public override string ToString ()
  118. {
  119. // Note: Unit tests are dependent on this format
  120. return $"[{Foreground},{Background}]";
  121. }
  122. }