Color.ColorExtensions.cs 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System.Collections.Frozen;
  2. using ColorHelper;
  3. namespace Terminal.Gui;
  4. internal static class ColorExtensions
  5. {
  6. // TODO: This should be refactored to support all W3CColors (`ColorStrings` and this should be merged).
  7. // TODO: ColorName and AnsiColorCode are only needed when a driver is in Force16Color mode and we
  8. // TODO: should be able to remove these from any non-Driver-specific usages.
  9. private static FrozenDictionary<Color, ColorName16> colorToNameMap;
  10. static ColorExtensions ()
  11. {
  12. Dictionary<ColorName16, AnsiColorCode> nameToCodeMap = new ()
  13. {
  14. { ColorName16.Black, AnsiColorCode.BLACK },
  15. { ColorName16.Blue, AnsiColorCode.BLUE },
  16. { ColorName16.Green, AnsiColorCode.GREEN },
  17. { ColorName16.Cyan, AnsiColorCode.CYAN },
  18. { ColorName16.Red, AnsiColorCode.RED },
  19. { ColorName16.Magenta, AnsiColorCode.MAGENTA },
  20. { ColorName16.Yellow, AnsiColorCode.YELLOW },
  21. { ColorName16.Gray, AnsiColorCode.WHITE },
  22. { ColorName16.DarkGray, AnsiColorCode.BRIGHT_BLACK },
  23. { ColorName16.BrightBlue, AnsiColorCode.BRIGHT_BLUE },
  24. { ColorName16.BrightGreen, AnsiColorCode.BRIGHT_GREEN },
  25. { ColorName16.BrightCyan, AnsiColorCode.BRIGHT_CYAN },
  26. { ColorName16.BrightRed, AnsiColorCode.BRIGHT_RED },
  27. { ColorName16.BrightMagenta, AnsiColorCode.BRIGHT_MAGENTA },
  28. { ColorName16.BrightYellow, AnsiColorCode.BRIGHT_YELLOW },
  29. { ColorName16.White, AnsiColorCode.BRIGHT_WHITE }
  30. };
  31. ColorName16ToAnsiColorMap = nameToCodeMap.ToFrozenDictionary ();
  32. ColorToName16Map = new Dictionary<Color, ColorName16>
  33. {
  34. // These match the values in Strings.resx, which are the W3C colors.
  35. { new Color(0, 0, 0), ColorName16.Black },
  36. { new Color(0, 0, 255), ColorName16.Blue },
  37. { new Color(0, 128, 0), ColorName16.Green },
  38. { new Color(0, 255, 255), ColorName16.Cyan },
  39. { new Color(255, 0, 0), ColorName16.Red },
  40. { new Color(255, 0, 255), ColorName16.Magenta },
  41. { new Color(255, 255, 0), ColorName16.Yellow },
  42. { new Color(128, 128, 128), ColorName16.Gray },
  43. { new Color(118, 118, 118), ColorName16.DarkGray },
  44. { new Color(59, 120, 255), ColorName16.BrightBlue },
  45. { new Color(22, 198, 12), ColorName16.BrightGreen },
  46. { new Color(97, 214, 214), ColorName16.BrightCyan },
  47. { new Color(231, 72, 86), ColorName16.BrightRed },
  48. { new Color(180, 0, 158), ColorName16.BrightMagenta },
  49. { new Color(249, 241, 165), ColorName16.BrightYellow },
  50. { new Color(255, 255, 255), ColorName16.White }
  51. }.ToFrozenDictionary ();
  52. }
  53. /// <summary>Defines the 16 legacy color names and their corresponding ANSI color codes.</summary>
  54. internal static FrozenDictionary<ColorName16, AnsiColorCode> ColorName16ToAnsiColorMap { get; }
  55. /// <summary>Reverse mapping for <see cref="ColorToName16Map"/>.</summary>
  56. internal static FrozenDictionary<ColorName16, Color> ColorName16ToColorMap { get; private set; }
  57. /// <summary>
  58. /// Gets or sets a <see cref="FrozenDictionary{TKey,TValue}"/> that maps legacy 16-color values to the
  59. /// corresponding <see cref="ColorName16"/>.
  60. /// </summary>
  61. /// <remarks>
  62. /// Setter should be called as infrequently as possible, as <see cref="FrozenDictionary{TKey,TValue}"/> is
  63. /// expensive to create.
  64. /// </remarks>
  65. internal static FrozenDictionary<Color, ColorName16> ColorToName16Map
  66. {
  67. get => colorToNameMap;
  68. set
  69. {
  70. colorToNameMap = value;
  71. //Also be sure to set the reverse mapping
  72. ColorName16ToColorMap = value.ToFrozenDictionary (static kvp => kvp.Value, static kvp => kvp.Key);
  73. }
  74. }
  75. }