Graphics.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. namespace Terminal.Gui.TextEffects;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. public class Color
  6. {
  7. public string RgbColor { get; }
  8. public int? XtermColor { get; }
  9. public Color (string rgbColor)
  10. {
  11. if (!IsValidHexColor (rgbColor))
  12. throw new ArgumentException ("Invalid RGB hex color format.");
  13. RgbColor = rgbColor.StartsWith ("#") ? rgbColor.Substring (1) : rgbColor;
  14. XtermColor = null; // Convert RGB to XTerm-256 here if necessary
  15. }
  16. public Color (int xtermColor)
  17. {
  18. XtermColor = xtermColor;
  19. RgbColor = ConvertXtermToHex (xtermColor); // Implement conversion logic
  20. }
  21. private bool IsValidHexColor (string color)
  22. {
  23. if (color.StartsWith ("#"))
  24. {
  25. color = color.Substring (1);
  26. }
  27. return color.Length == 6 && int.TryParse (color, System.Globalization.NumberStyles.HexNumber, null, out _);
  28. }
  29. private string ConvertXtermToHex (int xtermColor)
  30. {
  31. // Dummy conversion for the sake of example
  32. return "000000"; // Actual conversion logic needed
  33. }
  34. public (int, int, int) GetRgbInts ()
  35. {
  36. int r = Convert.ToInt32 (RgbColor.Substring (0, 2), 16);
  37. int g = Convert.ToInt32 (RgbColor.Substring (2, 2), 16);
  38. int b = Convert.ToInt32 (RgbColor.Substring (4, 2), 16);
  39. return (r, g, b);
  40. }
  41. public override string ToString ()
  42. {
  43. return $"#{RgbColor.ToUpper ()}";
  44. }
  45. public override bool Equals (object obj)
  46. {
  47. return obj is Color other && RgbColor == other.RgbColor;
  48. }
  49. public override int GetHashCode ()
  50. {
  51. return HashCode.Combine (RgbColor);
  52. }
  53. }
  54. public class Gradient
  55. {
  56. public List<Color> Spectrum { get; private set; }
  57. public Gradient (IEnumerable<Color> stops, IEnumerable<int> steps, bool loop = false)
  58. {
  59. if (stops == null || stops.Count () < 2)
  60. throw new ArgumentException ("At least two color stops are required to create a gradient.");
  61. if (steps == null || !steps.Any ())
  62. throw new ArgumentException ("Steps are required to define the transitions between colors.");
  63. Spectrum = GenerateGradient (stops.ToList (), steps.ToList (), loop);
  64. }
  65. private List<Color> GenerateGradient (List<Color> stops, List<int> steps, bool loop)
  66. {
  67. List<Color> gradient = new List<Color> ();
  68. if (loop)
  69. stops.Add (stops [0]); // Loop the gradient back to the first color.
  70. for (int i = 0; i < stops.Count - 1; i++)
  71. {
  72. gradient.AddRange (InterpolateColors (stops [i], stops [i + 1], i < steps.Count ? steps [i] : steps.Last ()));
  73. }
  74. return gradient;
  75. }
  76. private IEnumerable<Color> InterpolateColors (Color start, Color end, int steps)
  77. {
  78. for (int step = 0; step <= steps; step++)
  79. {
  80. int r = Interpolate (start.GetRgbInts ().Item1, end.GetRgbInts ().Item1, steps, step);
  81. int g = Interpolate (start.GetRgbInts ().Item2, end.GetRgbInts ().Item2, steps, step);
  82. int b = Interpolate (start.GetRgbInts ().Item3, end.GetRgbInts ().Item3, steps, step);
  83. yield return new Color ($"#{r:X2}{g:X2}{b:X2}");
  84. }
  85. }
  86. private int Interpolate (int start, int end, int steps, int currentStep)
  87. {
  88. return start + (end - start) * currentStep / steps;
  89. }
  90. public Color GetColorAtFraction (double fraction)
  91. {
  92. if (fraction < 0 || fraction > 1)
  93. throw new ArgumentOutOfRangeException (nameof (fraction), "Fraction must be between 0 and 1.");
  94. int index = (int)(fraction * (Spectrum.Count - 1));
  95. return Spectrum [index];
  96. }
  97. public IEnumerable<Color> GetRange (int startIndex, int count)
  98. {
  99. return Spectrum.Skip (startIndex).Take (count);
  100. }
  101. public override string ToString ()
  102. {
  103. return $"Gradient with {Spectrum.Count} colors.";
  104. }
  105. }