Răsfoiți Sursa

WIP - Revamped Color

Tigger Kindel 1 an în urmă
părinte
comite
1fa6267895
30 a modificat fișierele cu 1030 adăugiri și 231 ștergeri
  1. 16 3
      Terminal.Gui/Configuration/AttributeJsonConverter.cs
  2. 9 31
      Terminal.Gui/Configuration/ColorJsonConverter.cs
  3. 1 1
      Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
  4. 17 17
      Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
  5. 545 54
      Terminal.Gui/Drawing/Color.cs
  6. 5 5
      Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs
  7. 2 2
      Terminal.Gui/Views/FileDialog.cs
  8. 1 1
      Terminal.Gui/Views/ProgressBar.cs
  9. 1 1
      Terminal.Gui/Views/TextField.cs
  10. 1 1
      Terminal.Gui/Views/TextValidateField.cs
  11. 0 1
      UICatalog/Scenarios/Animation.cs
  12. 0 2
      UICatalog/Scenarios/ConfigurationEditor.cs
  13. 14 15
      UICatalog/Scenarios/GraphViewExample.cs
  14. 0 3
      UICatalog/Scenarios/Images.cs
  15. 2 2
      UICatalog/Scenarios/InvertColors.cs
  16. 1 2
      UICatalog/Scenarios/LineDrawing.cs
  17. 1 1
      UICatalog/Scenarios/ListColumns.cs
  18. 0 3
      UICatalog/Scenarios/ListViewWithSelection.cs
  19. 10 10
      UICatalog/Scenarios/MultiColouredTable.cs
  20. 0 1
      UICatalog/Scenarios/Snake.cs
  21. 1 3
      UICatalog/Scenarios/SyntaxHighlighting.cs
  22. 3 5
      UICatalog/Scenarios/TableEditor.cs
  23. 2 2
      UICatalog/Scenarios/TextAlignmentsAndDirection.cs
  24. 1 0
      UICatalog/UICatalog.cs
  25. 8 8
      UnitTests/Configuration/ConfigurationMangerTests.cs
  26. 27 29
      UnitTests/Configuration/JsonConverterTests.cs
  27. 8 8
      UnitTests/Configuration/ThemeTests.cs
  28. 14 14
      UnitTests/ConsoleDrivers/AttributeTests.cs
  29. 334 0
      UnitTests/Drawing/ColorTests.cs
  30. 6 6
      UnitTests/Text/AutocompleteTests.cs

+ 16 - 3
Terminal.Gui/Configuration/AttributeJsonConverter.cs

@@ -63,15 +63,28 @@ namespace Terminal.Gui {
 				case "truecolorbackground":
 				case "truecolorbackground":
 					trueColorBackground = JsonSerializer.Deserialize<TrueColor> (color, options);
 					trueColorBackground = JsonSerializer.Deserialize<TrueColor> (color, options);
 					break;
 					break;
-				//case "Bright":
+				//case "bright":
+				//case "bold":
 				//	attribute.Bright = reader.GetBoolean ();
 				//	attribute.Bright = reader.GetBoolean ();
 				//	break;
 				//	break;
-				//case "Underline":
+				//case "dim":
+				//	attribute.Dim = reader.GetBoolean ();
+				//	break;
+				//case "underline":
 				//	attribute.Underline = reader.GetBoolean ();
 				//	attribute.Underline = reader.GetBoolean ();
 				//	break;
 				//	break;
-				//case "Reverse":
+				//case "blink":
+				//	attribute.Blink = reader.GetBoolean ();
+				//	break;
+				//case "reverse":
 				//	attribute.Reverse = reader.GetBoolean ();
 				//	attribute.Reverse = reader.GetBoolean ();
 				//	break;
 				//	break;
+				//case "hidden":
+				//	attribute.Hidden = reader.GetBoolean ();
+				//	break;
+				//case "strike-through":
+				//	attribute.StrikeThrough = reader.GetBoolean ();
+				//	break;				
 				default:
 				default:
 					throw new JsonException ($"Unknown Attribute property {propertyName}.");
 					throw new JsonException ($"Unknown Attribute property {propertyName}.");
 				}
 				}

+ 9 - 31
Terminal.Gui/Configuration/ColorJsonConverter.cs

@@ -8,18 +8,18 @@ namespace Terminal.Gui {
 	/// Json converter for the <see cref="Color"/> class.
 	/// Json converter for the <see cref="Color"/> class.
 	/// </summary>
 	/// </summary>
 	internal class ColorJsonConverter : JsonConverter<Color> {
 	internal class ColorJsonConverter : JsonConverter<Color> {
-		private static ColorJsonConverter instance;
+		private static ColorJsonConverter _instance;
 
 
 		/// <summary>
 		/// <summary>
 		/// Singleton
 		/// Singleton
 		/// </summary>
 		/// </summary>
 		public static ColorJsonConverter Instance {
 		public static ColorJsonConverter Instance {
 			get {
 			get {
-				if (instance == null) {
-					instance = new ColorJsonConverter ();
+				if (_instance == null) {
+					_instance = new ColorJsonConverter ();
 				}
 				}
 
 
-				return instance;
+				return _instance;
 			}
 			}
 		}
 		}
 
 
@@ -34,18 +34,11 @@ namespace Terminal.Gui {
 				if (Enum.TryParse (colorString, ignoreCase: true, out ColorNames color)) {
 				if (Enum.TryParse (colorString, ignoreCase: true, out ColorNames color)) {
 					// Return the parsed color
 					// Return the parsed color
 					return new Color(color);
 					return new Color(color);
-				} else {
-					// Parse the color string as an RGB value
-					var match = Regex.Match (colorString, @"rgb\((\d+),(\d+),(\d+)\)");
-					if (match.Success) {
-						var r = int.Parse (match.Groups [1].Value);
-						var g = int.Parse (match.Groups [2].Value);
-						var b = int.Parse (match.Groups [3].Value);
-						return TrueColor.ToConsoleColor(new TrueColor (r, g, b));
-					} else {
-						throw new JsonException ($"Invalid Color: '{colorString}'");
-					}
 				}
 				}
+				if (Color.TryParse (colorString, out Color parsedColor)) {
+					return parsedColor;
+				}
+				throw new JsonException ($"Unexpected color name: {colorString}.");
 			} else {
 			} else {
 				throw new JsonException ($"Unexpected token when parsing Color: {reader.TokenType}");
 				throw new JsonException ($"Unexpected token when parsing Color: {reader.TokenType}");
 			}
 			}
@@ -53,22 +46,7 @@ namespace Terminal.Gui {
 
 
 		public override void Write (Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
 		public override void Write (Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
 		{
 		{
-			// Try to get the human readable color name from the map
-			var name = Enum.GetName (typeof (Color), value);
-			if (name != null) {
-				// Write the color name to the JSON
-				writer.WriteStringValue (name);
-			} else {
-				//// If the color is not in the map, look up its RGB values in the consoleDriver.colors array
-				//ConsoleColor consoleColor = (ConsoleDriver [(int)value]);
-				//int r = consoleColor.R;
-				//int g = consoleColor.G;
-				//int b = consoleColor.B;
-
-				//// Write the RGB values as a string to the JSON
-				//writer.WriteStringValue ($"rgb({r},{g},{b})");
-				throw new JsonException ($"Unknown Color value. Cannot serialize to JSON: {value}");
-			}
+			writer.WriteStringValue (value.ToString());
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs

@@ -391,7 +391,7 @@ public abstract class ConsoleDriver {
 		get => _currentAttribute;
 		get => _currentAttribute;
 		set {
 		set {
 			if (value is { Initialized: false, HasValidColors: true } && Application.Driver != null) {
 			if (value is { Initialized: false, HasValidColors: true } && Application.Driver != null) {
-				_currentAttribute = Application.Driver.MakeAttribute (value.Foreground, value.Background);
+				_currentAttribute = new Attribute (value.Foreground, value.Background);
 				return;
 				return;
 			}
 			}
 			if (!value.Initialized) Debug.WriteLine ("ConsoleDriver.CurrentAttribute: Attributes must be initialized before use.");
 			if (!value.Initialized) Debug.WriteLine ("ConsoleDriver.CurrentAttribute: Attributes must be initialized before use.");

+ 17 - 17
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -155,37 +155,37 @@ internal class CursesDriver : ConsoleDriver {
 	{
 	{
 		switch (color) {
 		switch (color) {
 		case Curses.COLOR_BLACK:
 		case Curses.COLOR_BLACK:
-			return Color.Black;
+			return new Color (Color.Black);
 		case Curses.COLOR_BLUE:
 		case Curses.COLOR_BLUE:
-			return Color.Blue;
+			return new Color (Color.Blue);
 		case Curses.COLOR_GREEN:
 		case Curses.COLOR_GREEN:
-			return Color.Green;
+			return (Color)Color.Green;
 		case Curses.COLOR_CYAN:
 		case Curses.COLOR_CYAN:
-			return Color.Cyan;
+			return (Color)Color.Cyan;
 		case Curses.COLOR_RED:
 		case Curses.COLOR_RED:
-			return Color.Red;
+			return (Color)Color.Red;
 		case Curses.COLOR_MAGENTA:
 		case Curses.COLOR_MAGENTA:
-			return Color.Magenta;
+			return (Color)Color.Magenta;
 		case Curses.COLOR_YELLOW:
 		case Curses.COLOR_YELLOW:
-			return Color.Brown;
+			return (Color)Color.Brown;
 		case Curses.COLOR_WHITE:
 		case Curses.COLOR_WHITE:
-			return Color.Gray;
+			return (Color)Color.Gray;
 		case Curses.COLOR_GRAY:
 		case Curses.COLOR_GRAY:
-			return Color.DarkGray;
+			return (Color)Color.DarkGray;
 		case Curses.COLOR_BLUE | Curses.COLOR_GRAY:
 		case Curses.COLOR_BLUE | Curses.COLOR_GRAY:
-			return Color.BrightBlue;
+			return (Color)Color.BrightBlue;
 		case Curses.COLOR_GREEN | Curses.COLOR_GRAY:
 		case Curses.COLOR_GREEN | Curses.COLOR_GRAY:
-			return Color.BrightGreen;
+			return (Color)Color.BrightGreen;
 		case Curses.COLOR_CYAN | Curses.COLOR_GRAY:
 		case Curses.COLOR_CYAN | Curses.COLOR_GRAY:
-			return Color.BrightCyan;
+			return (Color)Color.BrightCyan;
 		case Curses.COLOR_RED | Curses.COLOR_GRAY:
 		case Curses.COLOR_RED | Curses.COLOR_GRAY:
-			return Color.BrightRed;
+			return (Color)Color.BrightRed;
 		case Curses.COLOR_MAGENTA | Curses.COLOR_GRAY:
 		case Curses.COLOR_MAGENTA | Curses.COLOR_GRAY:
-			return Color.BrightMagenta;
+			return (Color)Color.BrightMagenta;
 		case Curses.COLOR_YELLOW | Curses.COLOR_GRAY:
 		case Curses.COLOR_YELLOW | Curses.COLOR_GRAY:
-			return Color.BrightYellow;
+			return (Color)Color.BrightYellow;
 		case Curses.COLOR_WHITE | Curses.COLOR_GRAY:
 		case Curses.COLOR_WHITE | Curses.COLOR_GRAY:
-			return Color.White;
+			return (Color)Color.White;
 		}
 		}
 		throw new ArgumentException ("Invalid curses color code");
 		throw new ArgumentException ("Invalid curses color code");
 	}
 	}
@@ -614,7 +614,7 @@ internal class CursesDriver : ConsoleDriver {
 
 
 	UnixMainLoop _mainLoop;
 	UnixMainLoop _mainLoop;
 	object _processInputToken;
 	object _processInputToken;
-	
+
 	public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
 	public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
 	{
 	{
 		if (!RunningUnitTests) {
 		if (!RunningUnitTests) {

+ 545 - 54
Terminal.Gui/Drawing/Color.cs

@@ -1,4 +1,5 @@
-using System;
+global using Attribute = Terminal.Gui.Attribute;
+using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Collections.Immutable;
@@ -7,13 +8,14 @@ using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
+using System.Xml.Linq;
 
 
 namespace Terminal.Gui {
 namespace Terminal.Gui {
 	/// <summary>
 	/// <summary>
-	/// Colors that can be used to set the foreground and background colors in console applications.
+	/// Defines the 16 legacy color names and values that can be used to set the foreground and background colors in Terminal.Gui apps. Used with <see cref="Color"/>.
 	/// </summary>
 	/// </summary>
 	/// <remarks>
 	/// <remarks>
-	/// The <see cref="Attribute.HasValidColors"/> value indicates either no-color has been set or the color is invalid.
+	/// 
 	/// </remarks>
 	/// </remarks>
 	public enum ColorNames {
 	public enum ColorNames {
 		/// <summary>
 		/// <summary>
@@ -83,100 +85,377 @@ namespace Terminal.Gui {
 	}
 	}
 
 
 	[JsonConverter (typeof (ColorJsonConverter))]
 	[JsonConverter (typeof (ColorJsonConverter))]
-	public class Color {
+	public class Color : IEquatable<Color> {
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Color"/> class.
+		/// </summary>
+		/// <param name="red"></param>
+		/// <param name="green"></param>
+		/// <param name="blue"></param>
+		public Color (int red, int green, int blue)
+		{
+			A = 0;
+			R = red;
+			G = green;
+			B = blue;
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Color"/> class.
+		/// </summary>
+		/// <param name="alpha"></param>
+		/// <param name="red"></param>
+		/// <param name="green"></param>
+		/// <param name="blue"></param>
+		public Color (int alpha, int red, int green, int blue)
+		{
+			A = alpha;
+			R = red;
+			G = green;
+			B = blue;
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Color"/> class with an encoded 24-bit color value.
+		/// </summary>
+		/// <param name="argb">The encoded 24-bit color value.</param>
+		public Color (int argb)
+		{
+			Value = argb;
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Color"/> color from a legacy 16-color value.
+		/// </summary>
+		/// <param name="colorName">The 16-color value.</param>
 		public Color (ColorNames colorName)
 		public Color (ColorNames colorName)
 		{
 		{
-			var tc = TrueColor.FromColorName (colorName).GetValueOrDefault ();
-			Value = (tc.Alpha << 24) | (tc.Red << 16) | (tc.Green << 8) | tc.Blue;
+			var c = Color.FromColorName (colorName);
+			A = c.A;
+			R = c.R;
+			G = c.G;
+			B = c.B;
 		}
 		}
 
 
 		public Color ()
 		public Color ()
 		{
 		{
-			Value = -1;
+			A = 0;
+			R = 0;
+			G = 0;
+			B = 0;
+		}
+
+		/// <summary>
+		/// Red color component.
+		/// </summary>
+		public int R { get; set; }
+		/// <summary>
+		/// Green color component.
+		/// </summary>
+		public int G { get; set; }
+		/// <summary>
+		/// Blue color component.
+		/// </summary>
+		public int B { get; set; }
+
+		/// <summary>
+		/// Alpha color component.
+		/// </summary>
+		/// <remarks>
+		/// Not currently supported; here for completeness. 
+		/// </remarks>
+		public int A { get; set; }
+
+		/// <summary>
+		/// Gets or sets the color value encoded using the following code:
+		/// <code>
+		/// (&lt;see cref="A"/&gt; &lt;&lt; 24) | (&lt;see cref="R"/&gt; &lt;&lt; 16) | (&lt;see cref="G"/&gt; &lt;&lt; 8) | &lt;see cref="B"/&gt;
+		/// </code>
+		/// </summary>
+		public int Value {
+			get => (A << 24) | (R << 16) | (G << 8) | B;
+			set {
+				A = (byte)((value >> 24) & 0xFF);
+				R = (byte)((value >> 16) & 0xFF);
+				G = (byte)((value >> 8) & 0xFF);
+				B = (byte)(value & 0xFF);
+			}
+		}
+
+		// TODO: Make this map configurable via ConfigurationManager
+		/// <summary>
+		/// Maps legacy 16-color values to the corresponding 24-bit RGB value.
+		/// </summary>
+		private static readonly ImmutableDictionary<Color, ColorNames> _colorNames = new Dictionary<Color, ColorNames> () {
+			{ new Color (0,0,0),ColorNames.Black },
+			{ new Color (0, 0, 0x80),ColorNames.Blue },
+			{ new Color (0, 0x80, 0),ColorNames.Green},
+			{ new Color (0, 0x80, 0x80),ColorNames.Cyan},
+			{ new Color (0x80, 0, 0),ColorNames.Red},
+			{ new Color (0x80, 0, 0x80),ColorNames.Magenta},
+			{ new Color (0xC1, 0x9C, 0x00),ColorNames.Brown},
+			{ new Color (0xC0, 0xC0, 0xC0),ColorNames.Gray},
+			{ new Color (0x80, 0x80, 0x80),ColorNames.DarkGray},
+			{ new Color (0, 0, 0xFF),ColorNames.BrightBlue},
+			{ new Color (0, 0xFF, 0),ColorNames.BrightGreen},
+			{ new Color (0, 0xFF, 0xFF),ColorNames.BrightCyan},
+			{ new Color (0xFF, 0, 0),ColorNames.BrightRed},
+			{ new Color (0xFF, 0, 0xFF),ColorNames.BrightMagenta },
+			{ new Color (0xFF, 0xFF, 0),ColorNames.BrightYellow},
+			{ new Color (0xFF, 0xFF, 0xFF),ColorNames.White},
+		}.ToImmutableDictionary ();
+
+		/// <summary>
+		/// Converts a legacy <see cref="ColorNames"/> to a 24-bit <see cref="Color"/>.
+		/// </summary>
+		/// <param name="consoleColor">The <see cref="Color"/> to convert.</param>
+		/// <returns></returns>
+		public static Color FromColorName (ColorNames consoleColor) => _colorNames.FirstOrDefault (x => x.Value == consoleColor).Key;
+
+		/// <summary>
+		/// Converts a legacy <see cref="ColorNames"/> index to a 24-bit <see cref="Color"/>.
+		/// </summary>
+		/// <param name="colorNameId">The index into the <see cref="ColorNames"/> enum to convert.</param>
+		/// <returns></returns>
+		public static Color FromColorName (int colorNameId)
+		{
+			return FromColorName ((ColorNames)colorNameId);
+		}
+
+		// This function iterates through the entries in the _colorNames dictionary, calculates the
+		// Euclidean distance between the input color and each dictionary color in RGB space,
+		// and keeps track of the closest entry found so far. The function returns a KeyValuePair
+		// representing the closest color entry and its associated color name.
+		public static ColorNames FindClosestColor (Color inputColor)
+		{
+			ColorNames closestColor = ColorNames.Black; // Default to Black
+			double closestDistance = double.MaxValue;
+
+			foreach (var colorEntry in _colorNames) {
+				var distance = CalculateColorDistance (inputColor, colorEntry.Key);
+				if (distance < closestDistance) {
+					closestDistance = distance;
+					closestColor = colorEntry.Value;
+				}
+			}
+
+			return closestColor;
+		}
+
+		private static double CalculateColorDistance (Color color1, Color color2)
+		{
+			// Calculate the Euclidean distance between two colors
+			var deltaR = (double)color1.R - (double)color2.R;
+			var deltaG = (double)color1.G - (double)color2.G;
+			var deltaB = (double)color1.B - (double)color2.B;
+
+			return Math.Sqrt (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB);
+		}
+
+		//private static KeyValuePair<Color, ColorNames> FindClosestColor (Color inputColor)
+		//{
+		//	KeyValuePair<Color, ColorNames> closestEntry = default;
+		//	double closestDistance = double.MaxValue;
+
+		//	foreach (var entry in _colorNames) {
+		//		Color dictionaryColor = entry.Key;
+		//		double distance = Math.Sqrt (
+		//			Math.Pow (inputColor.R - dictionaryColor.R, 2) +
+		//			Math.Pow (inputColor.G - dictionaryColor.G, 2) +
+		//			Math.Pow (inputColor.B - dictionaryColor.B, 2)
+		//		);
+
+		//		if (distance < closestDistance) {
+		//			closestDistance = distance;
+		//			closestEntry = entry;
+		//		}
+		//	}
+
+		//	return closestEntry;
+		//}
+
+		/// <summary>
+		/// Gets or sets the <see cref="Color"/> using a legacy 16-color <see cref="ColorNames"/> value.
+		/// </summary>
+		/// <remarks>
+		/// Get returns the closest 24-bit color value. Set sets the RGB value using a hard-coded map.
+		/// </remarks>
+		public ColorNames ColorName {
+			get {
+				return FindClosestColor (this.Value);
+			}
+			set {
+
+				var c = FromColorName (value);
+				A = c.A;
+				R = c.R;
+				G = c.G;
+				B = c.B;
+			}
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>
+		/// 
 		/// The black color.
 		/// The black color.
 		/// </summary>
 		/// </summary>
-		public const int Black = (int)ColorNames.Black;
+		public const ColorNames Black = ColorNames.Black;
 
 
 		/// <summary>
 		/// <summary>
 		/// The blue color.
 		/// The blue color.
 		/// </summary>
 		/// </summary>
-		public const int Blue = (int)ColorNames.Blue;
+		public const ColorNames Blue = ColorNames.Blue;
 		/// <summary>
 		/// <summary>
 		/// The green color.
 		/// The green color.
 		/// </summary>
 		/// </summary>
-		public const int Green = (int)ColorNames.Green;
+		public const ColorNames Green = ColorNames.Green;
 		/// <summary>
 		/// <summary>
 		/// The cyan color.
 		/// The cyan color.
 		/// </summary>
 		/// </summary>
-		public const int Cyan = (int)ColorNames.Cyan;
+		public const ColorNames Cyan = ColorNames.Cyan;
 		/// <summary>
 		/// <summary>
 		/// The red color.
 		/// The red color.
 		/// </summary>
 		/// </summary>
-		public const int Red = (int)ColorNames.Red;
+		public const ColorNames Red = ColorNames.Red;
 		/// <summary>
 		/// <summary>
 		/// The magenta color.
 		/// The magenta color.
 		/// </summary>
 		/// </summary>
-		public const int Magenta = (int)ColorNames.Magenta;
+		public const ColorNames Magenta = ColorNames.Magenta;
 		/// <summary>
 		/// <summary>
 		/// The brown color.
 		/// The brown color.
 		/// </summary>
 		/// </summary>
-		public const int Brown = (int)ColorNames.Brown;
+		public const ColorNames Brown = ColorNames.Brown;
 		/// <summary>
 		/// <summary>
 		/// The gray color.
 		/// The gray color.
 		/// </summary>
 		/// </summary>
-		public const int Gray = (int)ColorNames.Gray;
+		public const ColorNames Gray = ColorNames.Gray;
 		/// <summary>
 		/// <summary>
 		/// The dark gray color.
 		/// The dark gray color.
 		/// </summary>
 		/// </summary>
-		public const int DarkGray = (int)ColorNames.DarkGray;
+		public const ColorNames DarkGray = ColorNames.DarkGray;
 		/// <summary>
 		/// <summary>
 		/// The bright bBlue color.
 		/// The bright bBlue color.
 		/// </summary>
 		/// </summary>
-		public const int BrightBlue = (int)ColorNames.BrightBlue;
+		public const ColorNames BrightBlue = ColorNames.BrightBlue;
 		/// <summary>
 		/// <summary>
 		/// The bright green color.
 		/// The bright green color.
 		/// </summary>
 		/// </summary>
-		public const int BrightGreen = (int)ColorNames.BrightGreen;
+		public const ColorNames BrightGreen = ColorNames.BrightGreen;
 		/// <summary>
 		/// <summary>
 		/// The bright cyan color.
 		/// The bright cyan color.
 		/// </summary>
 		/// </summary>
-		public const int BrightCyan = (int)ColorNames.BrightCyan;
+		public const ColorNames BrightCyan = ColorNames.BrightCyan;
 		/// <summary>
 		/// <summary>
 		/// The bright red color.
 		/// The bright red color.
 		/// </summary>
 		/// </summary>
-		public const int BrightRed = (int)ColorNames.BrightRed;
+		public const ColorNames BrightRed = ColorNames.BrightRed;
 		/// <summary>
 		/// <summary>
 		/// The bright magenta color.
 		/// The bright magenta color.
 		/// </summary>
 		/// </summary>
-		public const int BrightMagenta = (int)ColorNames.BrightMagenta;
+		public const ColorNames BrightMagenta = ColorNames.BrightMagenta;
 		/// <summary>
 		/// <summary>
 		/// The bright yellow color.
 		/// The bright yellow color.
 		/// </summary>
 		/// </summary>
-		public const int BrightYellow = (int)ColorNames.BrightYellow;
+		public const ColorNames BrightYellow = ColorNames.BrightYellow;
 		/// <summary>
 		/// <summary>
 		/// The White color.
 		/// The White color.
 		/// </summary>
 		/// </summary>
-		public const int White = (int)ColorNames.White;
+		public const ColorNames White = ColorNames.White;
 
 
 		/// <summary>
 		/// <summary>
-		/// The truecolor value. -1 if not valid. 
+		/// Converts the provided text to a new <see cref="Color"/> instance.
 		/// </summary>
 		/// </summary>
-		public int Value { get; set; }
+		/// <param name="text">The text to analyze.</param>
+		/// <param name="color">The parsed value.</param>
+		/// <returns>A boolean value indicating whether it was successful.</returns>
+		public static bool TryParse (string text, [NotNullWhen (true)] out Color color)
+		{
+			// empty color
+			if ((text == null) || (text.Length == 0)) {
+				color = null;
+				return false;
+			}
+
+			// #RRGGBB, #RGB
+			if ((text [0] == '#') && text.Length is 7 or 4) {
+				if (text.Length == 7) {
+					var r = Convert.ToInt32 (text.Substring (1, 2), 16);
+					var g = Convert.ToInt32 (text.Substring (3, 2), 16);
+					var b = Convert.ToInt32 (text.Substring (5, 2), 16);
+					color = new Color (r, g, b);
+				} else {
+					var rText = char.ToString (text [1]);
+					var gText = char.ToString (text [2]);
+					var bText = char.ToString (text [3]);
+
+					var r = Convert.ToInt32 (rText + rText, 16);
+					var g = Convert.ToInt32 (gText + gText, 16);
+					var b = Convert.ToInt32 (bText + bText, 16);
+					color = new Color (r, g, b);
+				}
+				return true;
+			}
+
+			// #AARRGGBB, #ARGB
+			if ((text [0] == '#') && text.Length is 8 or 5) {
+				if (text.Length == 7) {
+					var a = Convert.ToInt32 (text.Substring (1, 2), 16);
+					var r = Convert.ToInt32 (text.Substring (3, 2), 16);
+					var g = Convert.ToInt32 (text.Substring (5, 2), 16);
+					var b = Convert.ToInt32 (text.Substring (7, 2), 16);
+					color = new Color (a, r, g, b);
+				} else {
+					var aText = char.ToString (text [1]);
+					var rText = char.ToString (text [2]);
+					var gText = char.ToString (text [3]);
+					var bText = char.ToString (text [4]);
+
+					var a = Convert.ToInt32 (aText + aText, 16);
+					var r = Convert.ToInt32 (rText + rText, 16);
+					var g = Convert.ToInt32 (gText + gText, 16);
+					var b = Convert.ToInt32 (bText + bText, 16);
+					color = new Color (a, r, g, b);
+				}
+				return true;
+			}
+
+			// rgb(XX,YY,ZZ)
+			var match = Regex.Match (text, @"rgb\((\d+),(\d+),(\d+)\)");
+			if (match.Success) {
+				var r = int.Parse (match.Groups [1].Value);
+				var g = int.Parse (match.Groups [2].Value);
+				var b = int.Parse (match.Groups [3].Value);
+				color = new Color (r, g, b);
+				return true;
+			}
+
+			// rgb(AA,XX,YY,ZZ)
+			match = Regex.Match (text, @"rgb\((\d+),(\d+),(\d+),(\d+)\)");
+			if (match.Success) {
+				var a = int.Parse (match.Groups [1].Value);
+				var r = int.Parse (match.Groups [2].Value);
+				var g = int.Parse (match.Groups [3].Value);
+				var b = int.Parse (match.Groups [4].Value);
+				color = new Color (a, r, g, b);
+				return true;
+			}
+
+			color = null;
+			return false;
+		}
+
 
 
 		/// <summary>
 		/// <summary>
-		/// 
+		/// Cast from int.
 		/// </summary>
 		/// </summary>
-		/// <param name="value"></param>
-		public static implicit operator Color (int value)
+		/// <param name="argb"></param>
+		public static implicit operator Color (int argb)
 		{
 		{
-			return new Color { Value = value };
+			return new Color (argb);
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>
-		/// 
+		/// Cast to int.
 		/// </summary>
 		/// </summary>
 		/// <param name="color"></param>
 		/// <param name="color"></param>
 		public static explicit operator int (Color color)
 		public static explicit operator int (Color color)
@@ -184,6 +463,99 @@ namespace Terminal.Gui {
 			return color.Value;
 			return color.Value;
 		}
 		}
 
 
+		/// <summary>
+		/// Cast from <see cref="ColorNames"/>.
+		/// </summary>
+		/// <param name="colorName"></param>
+		public static explicit operator Color (ColorNames colorName)
+		{
+			return new Color (colorName);
+		}
+
+		/// <summary>
+		/// Cast to <see cref="ColorNames"/>.
+		/// </summary>
+		/// <param name="color"></param>
+		public static explicit operator ColorNames (Color color)
+		{
+			return color.ColorName;
+		}
+
+
+		/// <inheritdoc/>
+		public static bool operator == (Color left, Color right)
+		{
+			return left.Equals (right);
+		}
+
+		/// <inheritdoc/>
+		public static bool operator != (Color left, Color right)
+		{
+			return !left.Equals (right);
+		}
+
+		/// <inheritdoc/>
+		public static bool operator == (ColorNames left, Color right)
+		{
+			return left == right.ColorName;
+		}
+
+		/// <inheritdoc/>
+		public static bool operator != (ColorNames left, Color right)
+		{
+			return left != right.ColorName;
+		}
+
+		/// <inheritdoc/>
+		public static bool operator == (Color left, ColorNames right)
+		{
+			return left.ColorName == right;
+		}
+
+		/// <inheritdoc/>
+		public static bool operator != (Color left, ColorNames right)
+		{
+			return left.ColorName != right;
+		}
+
+
+		/// <inheritdoc/>
+		public override bool Equals (object obj)
+		{
+			return obj is Color other && Equals (other);
+		}
+
+		/// <inheritdoc/>
+		public bool Equals (Color other)
+		{
+			return
+				A == other.A &&
+				R == other.R &&
+				G == other.G &&
+				B == other.B;
+		}
+
+		/// <inheritdoc/>
+		public override int GetHashCode ()
+		{
+			return HashCode.Combine (A, R, G, B);
+		}
+
+		/// <summary>
+		/// Converts the color to a string representation.
+		/// </summary>
+		/// <remarks>
+		/// </remarks>
+		/// <returns></returns>
+		public override string ToString ()
+		{
+			// If Values has an exact match with a named color (in _colorNames), use that.
+			if (_colorNames.TryGetValue (this, out ColorNames colorName)) {
+				return Enum.GetName (typeof (ColorNames), colorName);
+			}
+			// Otherwise return as an RGB hex value.
+			return $"#{R:X2}{G:X2}{B:X2}";
+		}
 	}
 	}
 
 
 	/// <summary>
 	/// <summary>
@@ -191,7 +563,7 @@ namespace Terminal.Gui {
 	/// </summary>
 	/// </summary>
 	[JsonConverter (typeof (TrueColorJsonConverter))]
 	[JsonConverter (typeof (TrueColorJsonConverter))]
 	public readonly struct TrueColor : IEquatable<TrueColor> {
 	public readonly struct TrueColor : IEquatable<TrueColor> {
-		private static readonly ImmutableDictionary<TrueColor, Color> TrueColorToConsoleColorMap = new Dictionary<TrueColor, Color> () {
+		private static readonly ImmutableDictionary<TrueColor, ColorNames> TrueColorToConsoleColorMap = new Dictionary<TrueColor, ColorNames> () {
 			{ new TrueColor (0,0,0),Color.Black },
 			{ new TrueColor (0,0,0),Color.Black },
 			{ new TrueColor (0, 0, 0x80),Color.Blue },
 			{ new TrueColor (0, 0, 0x80),Color.Blue },
 			{ new TrueColor (0, 0x80, 0),Color.Green},
 			{ new TrueColor (0, 0x80, 0),Color.Green},
@@ -232,7 +604,7 @@ namespace Terminal.Gui {
 		public int Alpha { get; }
 		public int Alpha { get; }
 
 
 		/// <summary>
 		/// <summary>
-		/// Initializes a new instance of the <see cref="TrueColor"/> struct.
+		/// Initializes a new instance of the <see cref="Color"/> class.
 		/// </summary>
 		/// </summary>
 		/// <param name="red"></param>
 		/// <param name="red"></param>
 		/// <param name="green"></param>
 		/// <param name="green"></param>
@@ -245,27 +617,26 @@ namespace Terminal.Gui {
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>
-		/// Converts the provided text to a <see cref="TrueColor"/>.
+		/// Converts the provided text to a new <see cref="Color"/> instance.
 		/// </summary>
 		/// </summary>
 		/// <param name="text">The text to analyze.</param>
 		/// <param name="text">The text to analyze.</param>
-		/// <param name="trueColor">The parsed value.</param>
-		/// <returns>A boolean value indcating whether it was successful.</returns>
-		public static bool TryParse (string text, [NotNullWhen (true)] out TrueColor? trueColor)
+		/// <param name="color">The parsed value.</param>
+		/// <returns>A boolean value indicating whether it was successful.</returns>
+		public static bool TryParse (string text, [NotNullWhen (true)] out TrueColor? color)
 		{
 		{
 			// empty color
 			// empty color
 			if ((text == null) || (text.Length == 0)) {
 			if ((text == null) || (text.Length == 0)) {
-				trueColor = null;
+				color = null;
 				return false;
 				return false;
 			}
 			}
 
 
-			// #RRGGBB or #RGB
-			if ((text [0] == '#') &&
-			    ((text.Length == 7) || (text.Length == 4))) {
+			// #RRGGBB, #RGB
+			if ((text [0] == '#') && text.Length is 7 or 4) {
 				if (text.Length == 7) {
 				if (text.Length == 7) {
 					var r = Convert.ToInt32 (text.Substring (1, 2), 16);
 					var r = Convert.ToInt32 (text.Substring (1, 2), 16);
 					var g = Convert.ToInt32 (text.Substring (3, 2), 16);
 					var g = Convert.ToInt32 (text.Substring (3, 2), 16);
 					var b = Convert.ToInt32 (text.Substring (5, 2), 16);
 					var b = Convert.ToInt32 (text.Substring (5, 2), 16);
-					trueColor = new TrueColor (r, g, b);
+					color = new TrueColor (r, g, b);
 				} else {
 				} else {
 					var rText = char.ToString (text [1]);
 					var rText = char.ToString (text [1]);
 					var gText = char.ToString (text [2]);
 					var gText = char.ToString (text [2]);
@@ -274,22 +645,23 @@ namespace Terminal.Gui {
 					var r = Convert.ToInt32 (rText + rText, 16);
 					var r = Convert.ToInt32 (rText + rText, 16);
 					var g = Convert.ToInt32 (gText + gText, 16);
 					var g = Convert.ToInt32 (gText + gText, 16);
 					var b = Convert.ToInt32 (bText + bText, 16);
 					var b = Convert.ToInt32 (bText + bText, 16);
-					trueColor = new TrueColor (r, g, b);
+					color = new TrueColor (r, g, b);
 				}
 				}
 				return true;
 				return true;
 			}
 			}
 
 
+
 			// rgb(XX,YY,ZZ)
 			// rgb(XX,YY,ZZ)
 			var match = Regex.Match (text, @"rgb\((\d+),(\d+),(\d+)\)");
 			var match = Regex.Match (text, @"rgb\((\d+),(\d+),(\d+)\)");
 			if (match.Success) {
 			if (match.Success) {
 				var r = int.Parse (match.Groups [1].Value);
 				var r = int.Parse (match.Groups [1].Value);
 				var g = int.Parse (match.Groups [2].Value);
 				var g = int.Parse (match.Groups [2].Value);
 				var b = int.Parse (match.Groups [3].Value);
 				var b = int.Parse (match.Groups [3].Value);
-				trueColor = new TrueColor (r, g, b);
+				color = new TrueColor (r, g, b);
 				return true;
 				return true;
 			}
 			}
 
 
-			trueColor = null;
+			color = null;
 			return false;
 			return false;
 		}
 		}
 
 
@@ -340,7 +712,7 @@ namespace Terminal.Gui {
 		public static Color ToConsoleColor (TrueColor? trueColor)
 		public static Color ToConsoleColor (TrueColor? trueColor)
 		{
 		{
 			if (trueColor.HasValue) {
 			if (trueColor.HasValue) {
-				return TrueColorToConsoleColorMap.MinBy (kv => CalculateDistance (kv.Key, trueColor.Value)).Value;
+				return new Color (TrueColorToConsoleColorMap.MinBy (kv => CalculateDistance (kv.Key, trueColor.Value)).Value);
 			} else {
 			} else {
 				return (Color)(-1);
 				return (Color)(-1);
 			}
 			}
@@ -444,20 +816,41 @@ namespace Terminal.Gui {
 		public TrueColor? TrueColorBackground { get; private init; }
 		public TrueColor? TrueColorBackground { get; private init; }
 
 
 		/// <summary>
 		/// <summary>
-		/// Initializes a new instance with a platform-specific color value.
+		/// Initializes a new instance with a 24-bit rgb value.
 		/// </summary>
 		/// </summary>
 		/// <param name="value">Value.</param>
 		/// <param name="value">Value.</param>
-		internal Attribute (int value)
+		internal Attribute (int argb)
 		{
 		{
 			Color foreground = default;
 			Color foreground = default;
 			Color background = default;
 			Color background = default;
 
 
 			Initialized = false;
 			Initialized = false;
 			if (Application.Driver != null) {
 			if (Application.Driver != null) {
-				Application.Driver.GetColors (value, out foreground, out background);
+				Application.Driver.GetColors (argb, out foreground, out background);
 				Initialized = true;
 				Initialized = true;
 			}
 			}
-			Value = value;
+			Value = argb;
+			Foreground = foreground;
+			Background = background;
+			//TrueColorForeground = TrueColor.FromColorName (foreground);
+			//TrueColorBackground = TrueColor.FromColorName (background);
+		}
+
+		/// <summary>
+		/// Initializes a new instance with <see cref="ColorNames" value./>
+		/// </summary>
+		/// <param name="value">Value.</param>
+		internal Attribute (ColorNames colorName)
+		{
+			Color foreground = default;
+			Color background = default;
+
+			Initialized = false;
+			if (Application.Driver != null) {
+				Application.Driver.GetColors (((Color)colorName).Value, out foreground, out background);
+				Initialized = true;
+			}
+			Value = ((Color)colorName).Value;
 			Foreground = foreground;
 			Foreground = foreground;
 			Background = background;
 			Background = background;
 			//TrueColorForeground = TrueColor.FromColorName (foreground);
 			//TrueColorForeground = TrueColor.FromColorName (foreground);
@@ -497,6 +890,58 @@ namespace Terminal.Gui {
 			Value = make.Value;
 			Value = make.Value;
 		}
 		}
 
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Attribute"/> struct.
+		/// </summary>
+		/// <param name="foreground">Foreground</param>
+		/// <param name="background">Background</param>
+		public Attribute (ColorNames foreground, ColorNames background)
+		{
+			Foreground = new Color (foreground);
+			Background = new Color (background);
+			TrueColorForeground = TrueColor.FromColorName (foreground);
+			TrueColorBackground = TrueColor.FromColorName (background);
+
+			var make = Make (foreground, background);
+			Initialized = make.Initialized;
+			Value = make.Value;
+		}
+
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Attribute"/> struct.
+		/// </summary>
+		/// <param name="foreground">Foreground</param>
+		/// <param name="background">Background</param>
+		public Attribute (ColorNames foreground, Color background)
+		{
+			Foreground = new Color (foreground);
+			Background = background;
+			TrueColorForeground = TrueColor.FromColorName (foreground);
+			TrueColorBackground = TrueColor.FromColorName (background.ColorName);
+
+			var make = Make (foreground, background);
+			Initialized = make.Initialized;
+			Value = make.Value;
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Attribute"/> struct.
+		/// </summary>
+		/// <param name="foreground">Foreground</param>
+		/// <param name="background">Background</param>
+		public Attribute (Color foreground, ColorNames background)
+		{
+			Foreground = foreground;
+			Background = new Color (background);
+			TrueColorForeground = TrueColor.FromColorName (foreground.ColorName);
+			TrueColorBackground = TrueColor.FromColorName (background);
+
+			var make = Make (foreground, background);
+			Initialized = make.Initialized;
+			Value = make.Value;
+		}
+
 		/// <summary>
 		/// <summary>
 		/// Initializes a new instance of the <see cref="Attribute"/> class.  Populates
 		/// Initializes a new instance of the <see cref="Attribute"/> class.  Populates
 		/// <see cref="TrueColorBackground"/> and <see cref="TrueColorForeground"/>. Also computes
 		/// <see cref="TrueColorBackground"/> and <see cref="TrueColorForeground"/>. Also computes
@@ -575,7 +1020,7 @@ namespace Terminal.Gui {
 		public bool Equals (Attribute other)
 		public bool Equals (Attribute other)
 		{
 		{
 			if (TrueColorForeground.HasValue || TrueColorBackground.HasValue) {
 			if (TrueColorForeground.HasValue || TrueColorBackground.HasValue) {
-				return 
+				return
 					TrueColorForeground == other.TrueColorForeground &&
 					TrueColorForeground == other.TrueColorForeground &&
 					TrueColorBackground == other.TrueColorBackground;
 					TrueColorBackground == other.TrueColorBackground;
 			}
 			}
@@ -608,7 +1053,7 @@ namespace Terminal.Gui {
 					Background = background
 					Background = background
 				};
 				};
 			}
 			}
-			return Application.Driver.MakeAttribute (foreground, background);
+			return new Attribute (foreground, background);
 		}
 		}
 
 
 
 
@@ -628,11 +1073,57 @@ namespace Terminal.Gui {
 				// Create the attribute, but show it's not been initialized
 				// Create the attribute, but show it's not been initialized
 				return new Attribute () {
 				return new Attribute () {
 					Initialized = false,
 					Initialized = false,
-					Foreground = new Color(foreground),
-					Background = new Color(background)
+					Foreground = new Color (foreground),
+					Background = new Color (background)
+				};
+			}
+			return new Attribute (foreground, background);
+		}
+
+		/// <summary>
+		/// Creates an <see cref="Attribute"/> from the specified foreground and background colors.
+		/// </summary>
+		/// <remarks>
+		/// If a <see cref="ConsoleDriver"/> has not been loaded (<c>Application.Driver == null</c>) this
+		/// method will return an attribute with <see cref="Initialized"/> set to  <see langword="false"/>.
+		/// </remarks>
+		/// <returns>The new attribute.</returns>
+		/// <param name="foreground">Foreground color to use.</param>
+		/// <param name="background">Background color to use.</param>
+		public static Attribute Make (ColorNames foreground, Color background)
+		{
+			if (Application.Driver == null) {
+				// Create the attribute, but show it's not been initialized
+				return new Attribute () {
+					Initialized = false,
+					Foreground = new Color (foreground),
+					Background = background
+				};
+			}
+			return new Attribute (new Color (foreground), background);
+		}
+
+		/// <summary>
+		/// Creates an <see cref="Attribute"/> from the specified foreground and background colors.
+		/// </summary>
+		/// <remarks>
+		/// If a <see cref="ConsoleDriver"/> has not been loaded (<c>Application.Driver == null</c>) this
+		/// method will return an attribute with <see cref="Initialized"/> set to  <see langword="false"/>.
+		/// </remarks>
+		/// <returns>The new attribute.</returns>
+		/// <param name="foreground">Foreground color to use.</param>
+		/// <param name="background">Background color to use.</param>
+		public static Attribute Make (Color foreground, ColorNames background)
+		{
+			if (Application.Driver == null) {
+				// Create the attribute, but show it's not been initialized
+				return new Attribute () {
+					Initialized = false,
+					Foreground = foreground,
+					Background = new Color (background)
 				};
 				};
 			}
 			}
-			return Application.Driver.MakeAttribute (foreground, background);
+			return new Attribute (foreground, new Color (background));
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>

+ 5 - 5
Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs

@@ -32,11 +32,11 @@ namespace Terminal.Gui {
 			SelectionKey = Key.Tab;
 			SelectionKey = Key.Tab;
 
 
 			ColorScheme = new ColorScheme {
 			ColorScheme = new ColorScheme {
-				Normal = new Attribute (Color.DarkGray, 0),
-				Focus = new Attribute (Color.DarkGray, 0),
-				HotNormal = new Attribute (Color.DarkGray, 0),
-				HotFocus = new Attribute (Color.DarkGray, 0),
-				Disabled = new Attribute (Color.DarkGray, 0),
+				Normal = new Attribute (Color.DarkGray, Color.Black),
+				Focus = new Attribute (Color.DarkGray, Color.Black),
+				HotNormal = new Attribute (Color.DarkGray, Color.Black),
+				HotFocus = new Attribute (Color.DarkGray, Color.Black),
+				Disabled = new Attribute (Color.DarkGray, Color.Black),
 			};
 			};
 		}
 		}
 
 

+ 2 - 2
Terminal.Gui/Views/FileDialog.cs

@@ -177,7 +177,7 @@ namespace Terminal.Gui {
 
 
 			this.tbPath = new TextField {
 			this.tbPath = new TextField {
 				Width = Dim.Fill (0),
 				Width = Dim.Fill (0),
-				CaptionColor = Color.Black
+				CaptionColor = (Color)Color.Black
 			};
 			};
 			this.tbPath.KeyPress += (s, k) => {
 			this.tbPath.KeyPress += (s, k) => {
 
 
@@ -273,7 +273,7 @@ namespace Terminal.Gui {
 
 
 			tbFind = new TextField {
 			tbFind = new TextField {
 				X = Pos.Right (this.btnToggleSplitterCollapse) + 1,
 				X = Pos.Right (this.btnToggleSplitterCollapse) + 1,
-				CaptionColor = Color.Black,
+				CaptionColor = (Color)Color.Black,
 				Width = 30,
 				Width = 30,
 				Y = Pos.AnchorEnd (1),
 				Y = Pos.AnchorEnd (1),
 			};
 			};

+ 1 - 1
Terminal.Gui/Views/ProgressBar.cs

@@ -90,7 +90,7 @@ namespace Terminal.Gui {
 			CanFocus = false;
 			CanFocus = false;
 			fraction = 0;
 			fraction = 0;
 			ColorScheme = new ColorScheme () {
 			ColorScheme = new ColorScheme () {
-				Normal = Application.Driver.MakeAttribute (Color.BrightGreen, Color.Gray),
+				Normal = new Attribute (Color.BrightGreen, Color.Gray),
 				HotNormal = Colors.Base.Normal
 				HotNormal = Colors.Base.Normal
 			};
 			};
 			if (rect.IsEmpty) {
 			if (rect.IsEmpty) {

+ 1 - 1
Terminal.Gui/Views/TextField.cs

@@ -40,7 +40,7 @@ namespace Terminal.Gui {
 		/// Gets or sets the foreground <see cref="Color"/> to use when 
 		/// Gets or sets the foreground <see cref="Color"/> to use when 
 		/// rendering <see cref="Caption"/>.
 		/// rendering <see cref="Caption"/>.
 		/// </summary>
 		/// </summary>
-		public Color CaptionColor { get; set; } = Color.DarkGray;
+		public Color CaptionColor { get; set; } = (Color)Color.DarkGray;
 
 
 		/// <summary>
 		/// <summary>
 		/// Tracks whether the text field should be considered "used", that is, that the user has moved in the entry, so new input should be appended at the cursor position, rather than clearing the entry
 		/// Tracks whether the text field should be considered "used", that is, that the user has moved in the entry, so new input should be appended at the cursor position, rather than clearing the entry

+ 1 - 1
Terminal.Gui/Views/TextValidateField.cs

@@ -509,7 +509,7 @@ namespace Terminal.Gui {
 				return;
 				return;
 			}
 			}
 
 
-			var bgcolor = !IsValid ? Color.BrightRed : ColorScheme.Focus.Background;
+			var bgcolor = !IsValid ? (Color)Color.BrightRed : ColorScheme.Focus.Background;
 			var textColor = new Attribute (ColorScheme.Focus.Foreground, bgcolor);
 			var textColor = new Attribute (ColorScheme.Focus.Foreground, bgcolor);
 
 
 			var (margin_left, margin_right) = GetMargins (Bounds.Width);
 			var (margin_left, margin_right) = GetMargins (Bounds.Width);

+ 0 - 1
UICatalog/Scenarios/Animation.cs

@@ -10,7 +10,6 @@ using System.Reflection;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Animation", Description: "Demonstration of how to render animated images with threading.")]
 	[ScenarioMetadata (Name: "Animation", Description: "Demonstration of how to render animated images with threading.")]

+ 0 - 2
UICatalog/Scenarios/ConfigurationEditor.cs

@@ -3,8 +3,6 @@ using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
 using Terminal.Gui;
 using Terminal.Gui;
-using static Terminal.Gui.ConfigurationManager;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Configuration Editor", Description: "Edits Terminal.Gui Config Files.")]
 	[ScenarioMetadata (Name: "Configuration Editor", Description: "Edits Terminal.Gui Config Files.")]

+ 14 - 15
UICatalog/Scenarios/GraphViewExample.cs

@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
 using Terminal.Gui;
 using Terminal.Gui;
-
 using Color = Terminal.Gui.Color;
 using Color = Terminal.Gui.Color;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
@@ -98,10 +97,10 @@ namespace UICatalog.Scenarios {
 
 
 			// BUGBUG: (v2 truecolor) This code depends on 8-bit color names; refactor
 			// BUGBUG: (v2 truecolor) This code depends on 8-bit color names; refactor
 			var fore = graphView.ColorScheme.Normal.Foreground == new Color(ColorNames.Black) ? new Color(ColorNames.White) : graphView.ColorScheme.Normal.Foreground;
 			var fore = graphView.ColorScheme.Normal.Foreground == new Color(ColorNames.Black) ? new Color(ColorNames.White) : graphView.ColorScheme.Normal.Foreground;
-			var black = Application.Driver.MakeAttribute (fore, Color.Black);
-			var cyan = Application.Driver.MakeAttribute (Color.BrightCyan, Color.Black);
-			var magenta = Application.Driver.MakeAttribute (Color.BrightMagenta, Color.Black);
-			var red = Application.Driver.MakeAttribute (Color.BrightRed, Color.Black);
+			var black = new Attribute (fore, Color.Black);
+			var cyan = new Attribute (Color.BrightCyan, Color.Black);
+			var magenta = new Attribute (Color.BrightMagenta, Color.Black);
+			var red = new Attribute (Color.BrightRed, Color.Black);
 
 
 			graphView.GraphColor = black;
 			graphView.GraphColor = black;
 
 
@@ -147,10 +146,10 @@ namespace UICatalog.Scenarios {
 
 
 			about.Text = "This graph shows random points";
 			about.Text = "This graph shows random points";
 
 
-			var black = Application.Driver.MakeAttribute (graphView.ColorScheme.Normal.Foreground, Color.Black);
-			var cyan = Application.Driver.MakeAttribute (Color.BrightCyan, Color.Black);
-			var magenta = Application.Driver.MakeAttribute (Color.BrightMagenta, Color.Black);
-			var red = Application.Driver.MakeAttribute (Color.BrightRed, Color.Black);
+			var black = new Attribute (graphView.ColorScheme.Normal.Foreground, Color.Black);
+			var cyan = new Attribute (Color.BrightCyan, Color.Black);
+			var magenta = new Attribute (Color.BrightMagenta, Color.Black);
+			var red = new Attribute (Color.BrightRed, Color.Black);
 
 
 			graphView.GraphColor = black;
 			graphView.GraphColor = black;
 
 
@@ -521,11 +520,11 @@ namespace UICatalog.Scenarios {
 			public DiscoBarSeries ()
 			public DiscoBarSeries ()
 			{
 			{
 
 
-				green = Application.Driver.MakeAttribute (Color.BrightGreen, Color.Black);
-				brightgreen = Application.Driver.MakeAttribute (Color.Green, Color.Black);
-				brightyellow = Application.Driver.MakeAttribute (Color.BrightYellow, Color.Black);
-				red = Application.Driver.MakeAttribute (Color.Red, Color.Black);
-				brightred = Application.Driver.MakeAttribute (Color.BrightRed, Color.Black);
+				green = new Attribute (Color.BrightGreen, Color.Black);
+				brightgreen = new Attribute (Color.Green, Color.Black);
+				brightyellow = new Attribute (Color.BrightYellow, Color.Black);
+				red = new Attribute (Color.Red, Color.Black);
+				brightred = new Attribute (Color.BrightRed, Color.Black);
 			}
 			}
 			protected override void DrawBarLine (GraphView graph, Terminal.Gui.Point start, Terminal.Gui.Point end, BarSeriesBar beingDrawn)
 			protected override void DrawBarLine (GraphView graph, Terminal.Gui.Point start, Terminal.Gui.Point end, BarSeriesBar beingDrawn)
 			{
 			{
@@ -559,7 +558,7 @@ namespace UICatalog.Scenarios {
 
 
 			about.Text = "This graph shows a graphic equaliser for an imaginary song";
 			about.Text = "This graph shows a graphic equaliser for an imaginary song";
 
 
-			graphView.GraphColor = Application.Driver.MakeAttribute (Color.White, Color.Black);
+			graphView.GraphColor = new Attribute (Color.White, Color.Black);
 
 
 			var stiple = new GraphCellToRender ((Rune)'\u2593');
 			var stiple = new GraphCellToRender ((Rune)'\u2593');
 
 

+ 0 - 3
UICatalog/Scenarios/Images.cs

@@ -5,9 +5,6 @@ using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.IO;
 using System.IO;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
-
-
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Images", Description: "Demonstration of how to render an image with/without true color support.")]
 	[ScenarioMetadata (Name: "Images", Description: "Demonstration of how to render an image with/without true color support.")]

+ 2 - 2
UICatalog/Scenarios/InvertColors.cs

@@ -18,7 +18,7 @@ namespace UICatalog.Scenarios {
 
 
 				var fore = foreColors [y];
 				var fore = foreColors [y];
 				var back = foreColors [(y + 1) % foreColors.Length];
 				var back = foreColors [(y + 1) % foreColors.Length];
-				var color = Application.Driver.MakeAttribute (fore, back);
+				var color = new Attribute (fore, back);
 
 
 				var label = new Label ($"{fore} on {back}") {
 				var label = new Label ($"{fore} on {back}") {
 					ColorScheme = new ColorScheme (),
 					ColorScheme = new ColorScheme (),
@@ -37,7 +37,7 @@ namespace UICatalog.Scenarios {
 
 
 				foreach (var label in labels) {
 				foreach (var label in labels) {
 					var color = label.ColorScheme.Normal;
 					var color = label.ColorScheme.Normal;
-					color = Application.Driver.MakeAttribute (color.Background, color.Foreground);
+					color = new Attribute (color.Background, color.Foreground);
 
 
 					label.ColorScheme.Normal = color;
 					label.ColorScheme.Normal = color;
 					label.Text = $"{color.Foreground} on {color.Background}";
 					label.Text = $"{color.Foreground} on {color.Background}";

+ 1 - 2
UICatalog/Scenarios/LineDrawing.cs

@@ -2,7 +2,6 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 
 
@@ -96,7 +95,7 @@ namespace UICatalog.Scenarios {
 		class DrawingArea : View {
 		class DrawingArea : View {
 			List<LineCanvas> _layers = new List<LineCanvas> ();
 			List<LineCanvas> _layers = new List<LineCanvas> ();
 			LineCanvas _currentLayer;
 			LineCanvas _currentLayer;
-			Color _currentColor = Color.White;
+			Color _currentColor = (Color)Color.White;
 			StraightLine _currentLine = null;
 			StraightLine _currentLine = null;
 
 
 			public LineStyle LineStyle { get; set; }
 			public LineStyle LineStyle { get; set; }

+ 1 - 1
UICatalog/Scenarios/ListColumns.cs

@@ -110,7 +110,7 @@ namespace UICatalog.Scenarios {
 				Disabled = Win.ColorScheme.Disabled,
 				Disabled = Win.ColorScheme.Disabled,
 				HotFocus = Win.ColorScheme.HotFocus,
 				HotFocus = Win.ColorScheme.HotFocus,
 				Focus = Win.ColorScheme.Focus,
 				Focus = Win.ColorScheme.Focus,
-				Normal = Application.Driver.MakeAttribute (Color.White, Color.BrightBlue)
+				Normal = new Attribute (Color.White, Color.BrightBlue)
 			};
 			};
 
 
 			// if user clicks the mouse in TableView
 			// if user clicks the mouse in TableView

+ 0 - 3
UICatalog/Scenarios/ListViewWithSelection.cs

@@ -2,10 +2,7 @@
 using System;
 using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json.Nodes;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "List View With Selection", Description: "ListView with columns and selection")]
 	[ScenarioMetadata (Name: "List View With Selection", Description: "ListView with columns and selection")]

+ 10 - 10
UICatalog/Scenarios/MultiColouredTable.cs

@@ -59,7 +59,7 @@ namespace UICatalog.Scenarios {
 				Disabled = Win.ColorScheme.Disabled,
 				Disabled = Win.ColorScheme.Disabled,
 				HotFocus = Win.ColorScheme.HotFocus,
 				HotFocus = Win.ColorScheme.HotFocus,
 				Focus = Win.ColorScheme.Focus,
 				Focus = Win.ColorScheme.Focus,
-				Normal = Application.Driver.MakeAttribute (Color.DarkGray, Color.Black)
+				Normal = new Attribute (Color.DarkGray, Color.Black)
 			};
 			};
 
 
 			tableView.Table = new DataTableSource (this.table = dt);
 			tableView.Table = new DataTableSource (this.table = dt);
@@ -127,7 +127,7 @@ namespace UICatalog.Scenarios {
 				for (int i = 0; i < render.Length; i++) {
 				for (int i = 0; i < render.Length; i++) {
 
 
 					if (unicorns != -1 && i >= unicorns && i <= unicorns + 8) {
 					if (unicorns != -1 && i >= unicorns && i <= unicorns + 8) {
-						Driver.SetAttribute (Driver.MakeAttribute (Color.White, cellColor.Background));
+						Driver.SetAttribute (new Attribute (Color.White, cellColor.Background));
 					}
 					}
 
 
 					if (rainbows != -1 && i >= rainbows && i <= rainbows + 8) {
 					if (rainbows != -1 && i >= rainbows && i <= rainbows + 8) {
@@ -135,28 +135,28 @@ namespace UICatalog.Scenarios {
 						var letterOfWord = i - rainbows;
 						var letterOfWord = i - rainbows;
 						switch (letterOfWord) {
 						switch (letterOfWord) {
 						case 0:
 						case 0:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.Red, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.Red, cellColor.Background));
 							break;
 							break;
 						case 1:
 						case 1:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.BrightRed, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.BrightRed, cellColor.Background));
 							break;
 							break;
 						case 2:
 						case 2:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.BrightYellow, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.BrightYellow, cellColor.Background));
 							break;
 							break;
 						case 3:
 						case 3:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.Green, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.Green, cellColor.Background));
 							break;
 							break;
 						case 4:
 						case 4:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.BrightGreen, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.BrightGreen, cellColor.Background));
 							break;
 							break;
 						case 5:
 						case 5:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.BrightBlue, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.BrightBlue, cellColor.Background));
 							break;
 							break;
 						case 6:
 						case 6:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.BrightCyan, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.BrightCyan, cellColor.Background));
 							break;
 							break;
 						case 7:
 						case 7:
-							Driver.SetAttribute (Driver.MakeAttribute (Color.Cyan, cellColor.Background));
+							Driver.SetAttribute (new Attribute (Color.Cyan, cellColor.Background));
 							break;
 							break;
 						}
 						}
 					}
 					}

+ 0 - 1
UICatalog/Scenarios/Snake.cs

@@ -5,7 +5,6 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Snake", Description: "The game of apple eating.")]
 	[ScenarioMetadata (Name: "Snake", Description: "The game of apple eating.")]

+ 1 - 3
UICatalog/Scenarios/SyntaxHighlighting.cs

@@ -1,5 +1,4 @@
-
-using System;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.ComponentModel;
 using System.IO;
 using System.IO;
@@ -9,7 +8,6 @@ using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using Terminal.Gui;
 using Terminal.Gui;
-using Attribute = Terminal.Gui.Attribute;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Syntax Highlighting", Description: "Text editor with keyword highlighting using the TextView control.")]
 	[ScenarioMetadata (Name: "Syntax Highlighting", Description: "Text editor with keyword highlighting using the TextView control.")]

+ 3 - 5
UICatalog/Scenarios/TableEditor.cs

@@ -4,10 +4,8 @@ using System.Data;
 using Terminal.Gui;
 using Terminal.Gui;
 using System.Linq;
 using System.Linq;
 using System.Globalization;
 using System.Globalization;
-using static Terminal.Gui.TableView;
 using System.Text;
 using System.Text;
 using System.IO;
 using System.IO;
-using System.Text.RegularExpressions;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 
 
@@ -132,7 +130,7 @@ namespace UICatalog.Scenarios {
 				Disabled = Win.ColorScheme.Disabled,
 				Disabled = Win.ColorScheme.Disabled,
 				HotFocus = Win.ColorScheme.HotFocus,
 				HotFocus = Win.ColorScheme.HotFocus,
 				Focus = Win.ColorScheme.Focus,
 				Focus = Win.ColorScheme.Focus,
-				Normal = Application.Driver.MakeAttribute (Color.Red, Win.ColorScheme.Normal.Background)
+				Normal = new Attribute (Color.Red, Win.ColorScheme.Normal.Background)
 			};
 			};
 
 
 			alternatingColorScheme = new ColorScheme () {
 			alternatingColorScheme = new ColorScheme () {
@@ -140,14 +138,14 @@ namespace UICatalog.Scenarios {
 				Disabled = Win.ColorScheme.Disabled,
 				Disabled = Win.ColorScheme.Disabled,
 				HotFocus = Win.ColorScheme.HotFocus,
 				HotFocus = Win.ColorScheme.HotFocus,
 				Focus = Win.ColorScheme.Focus,
 				Focus = Win.ColorScheme.Focus,
-				Normal = Application.Driver.MakeAttribute (Color.White, Color.BrightBlue)
+				Normal = new Attribute (Color.White, Color.BrightBlue)
 			};
 			};
 			redColorSchemeAlt = new ColorScheme () {
 			redColorSchemeAlt = new ColorScheme () {
 
 
 				Disabled = Win.ColorScheme.Disabled,
 				Disabled = Win.ColorScheme.Disabled,
 				HotFocus = Win.ColorScheme.HotFocus,
 				HotFocus = Win.ColorScheme.HotFocus,
 				Focus = Win.ColorScheme.Focus,
 				Focus = Win.ColorScheme.Focus,
-				Normal = Application.Driver.MakeAttribute (Color.Red, Color.BrightBlue)
+				Normal = new Attribute (Color.Red, Color.BrightBlue)
 			};
 			};
 
 
 			// if user clicks the mouse in TableView
 			// if user clicks the mouse in TableView

+ 2 - 2
UICatalog/Scenarios/TextAlignmentsAndDirection.cs

@@ -15,8 +15,8 @@ namespace UICatalog.Scenarios {
 			// string txt = "┌──┴──┐\n┤HELLO├\n└──┬──┘";
 			// string txt = "┌──┴──┐\n┤HELLO├\n└──┬──┘";
 			string txt = "HELLO WORLD";
 			string txt = "HELLO WORLD";
 
 
-			var color1 = new ColorScheme { Normal = Application.Driver.MakeAttribute (Color.Black, Color.Gray) };
-			var color2 = new ColorScheme { Normal = Application.Driver.MakeAttribute (Color.Black, Color.DarkGray) };
+			var color1 = new ColorScheme { Normal = new Attribute (Color.Black, Color.Gray) };
+			var color2 = new ColorScheme { Normal = new Attribute (Color.Black, Color.DarkGray) };
 
 
 			var txts = new List<Label> (); // single line
 			var txts = new List<Label> (); // single line
 			var mtxts = new List<Label> (); // multi line
 			var mtxts = new List<Label> (); // multi line

+ 1 - 0
UICatalog/UICatalog.cs

@@ -1,4 +1,5 @@
 global using CM = Terminal.Gui.ConfigurationManager;
 global using CM = Terminal.Gui.ConfigurationManager;
+global using Attribute = Terminal.Gui.Attribute;
 
 
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;

+ 8 - 8
UnitTests/Configuration/ConfigurationMangerTests.cs

@@ -325,8 +325,8 @@ namespace Terminal.Gui.ConfigurationTests {
 
 
 			Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey);
 			Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey);
 
 
-			Assert.Equal (Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
-			Assert.Equal (Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
+			Assert.Equal ((Color)Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
+			Assert.Equal ((Color)Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
 
 
 			// Change Base
 			// Change Base
 			var json = ConfigurationManager.ToStream ();
 			var json = ConfigurationManager.ToStream ();
@@ -509,12 +509,12 @@ namespace Terminal.Gui.ConfigurationTests {
 
 
 			Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
 			Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
 
 
-			Assert.Equal (Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
-			Assert.Equal (Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
+			Assert.Equal ((Color)Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
+			Assert.Equal ((Color)Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
 
 
 			var colorSchemes = (Dictionary<string, ColorScheme>)Themes.First ().Value ["ColorSchemes"].PropertyValue;
 			var colorSchemes = (Dictionary<string, ColorScheme>)Themes.First ().Value ["ColorSchemes"].PropertyValue;
-			Assert.Equal (Color.White, colorSchemes ["Base"].Normal.Foreground);
-			Assert.Equal (Color.Blue, colorSchemes ["Base"].Normal.Background);
+			Assert.Equal ((Color)Color.White, colorSchemes ["Base"].Normal.Foreground);
+			Assert.Equal ((Color)Color.Blue, colorSchemes ["Base"].Normal.Background);
 
 
 			// Now re-apply
 			// Now re-apply
 			ConfigurationManager.Apply ();
 			ConfigurationManager.Apply ();
@@ -522,8 +522,8 @@ namespace Terminal.Gui.ConfigurationTests {
 			Assert.Equal (Key.Z | Key.AltMask, Application.QuitKey);
 			Assert.Equal (Key.Z | Key.AltMask, Application.QuitKey);
 			Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
 			Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
 
 
-			Assert.Equal (Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
-			Assert.Equal (Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
+			Assert.Equal ((Color)Color.White, Colors.ColorSchemes ["Base"].Normal.Foreground);
+			Assert.Equal ((Color)Color.Blue, Colors.ColorSchemes ["Base"].Normal.Background);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]

+ 27 - 29
UnitTests/Configuration/JsonConverterTests.cs

@@ -34,28 +34,28 @@ namespace Terminal.Gui.ConfigurationTests {
 		}
 		}
 
 
 		[Theory]
 		[Theory]
-		[InlineData (Color.Black, "Black")]
-		[InlineData (Color.Blue, "Blue")]
-		[InlineData (Color.Green, "Green")]
-		[InlineData (Color.Cyan, "Cyan")]
-		[InlineData (Color.Gray, "Gray")]
-		[InlineData (Color.Red, "Red")]
-		[InlineData (Color.Magenta, "Magenta")]
-		[InlineData (Color.Brown, "Brown")]
-		[InlineData (Color.DarkGray, "DarkGray")]
-		[InlineData (Color.BrightBlue, "BrightBlue")]
-		[InlineData (Color.BrightGreen, "BrightGreen")]
-		[InlineData (Color.BrightCyan, "BrightCyan")]
-		[InlineData (Color.BrightRed, "BrightRed")]
-		[InlineData (Color.BrightMagenta, "BrightMagenta")]
-		[InlineData (Color.BrightYellow, "BrightYellow")]
-		[InlineData (Color.White, "White")]
-		public void SerializesEnumValuesAsStrings (Color color, string expectedJson)
+		[InlineData (ColorNames.Black, "Black")]
+		[InlineData (ColorNames.Blue, "Blue")]
+		[InlineData (ColorNames.Green, "Green")]
+		[InlineData (ColorNames.Cyan, "Cyan")]
+		[InlineData (ColorNames.Gray, "Gray")]
+		[InlineData (ColorNames.Red, "Red")]
+		[InlineData (ColorNames.Magenta, "Magenta")]
+		[InlineData (ColorNames.Brown, "Brown")]
+		[InlineData (ColorNames.DarkGray, "DarkGray")]
+		[InlineData (ColorNames.BrightBlue, "BrightBlue")]
+		[InlineData (ColorNames.BrightGreen, "BrightGreen")]
+		[InlineData (ColorNames.BrightCyan, "BrightCyan")]
+		[InlineData (ColorNames.BrightRed, "BrightRed")]
+		[InlineData (ColorNames.BrightMagenta, "BrightMagenta")]
+		[InlineData (ColorNames.BrightYellow, "BrightYellow")]
+		[InlineData (ColorNames.White, "White")]
+		public void SerializesEnumValuesAsStrings (ColorNames color, string expectedJson)
 		{
 		{
 			var converter = new ColorJsonConverter ();
 			var converter = new ColorJsonConverter ();
 			var options = new JsonSerializerOptions { Converters = { converter } };
 			var options = new JsonSerializerOptions { Converters = { converter } };
 
 
-			var serialized = JsonSerializer.Serialize (color, options);
+			var serialized = JsonSerializer.Serialize<Color> (Color.FromColorName (color), options);
 
 
 			Assert.Equal ($"\"{expectedJson}\"", serialized);
 			Assert.Equal ($"\"{expectedJson}\"", serialized);
 		}
 		}
@@ -64,11 +64,10 @@ namespace Terminal.Gui.ConfigurationTests {
 		public void TestSerializeColor_Black ()
 		public void TestSerializeColor_Black ()
 		{
 		{
 			// Arrange
 			// Arrange
-			var color = Color.Black;
 			var expectedJson = "\"Black\"";
 			var expectedJson = "\"Black\"";
 
 
 			// Act
 			// Act
-			var json = JsonSerializer.Serialize (color, new JsonSerializerOptions {
+			var json = JsonSerializer.Serialize<Color> (Color.FromColorName (Color.Black), new JsonSerializerOptions {
 				Converters = { new ColorJsonConverter () }
 				Converters = { new ColorJsonConverter () }
 			});
 			});
 
 
@@ -80,11 +79,10 @@ namespace Terminal.Gui.ConfigurationTests {
 		public void TestSerializeColor_BrightRed ()
 		public void TestSerializeColor_BrightRed ()
 		{
 		{
 			// Arrange
 			// Arrange
-			var color = Color.BrightRed;
 			var expectedJson = "\"BrightRed\"";
 			var expectedJson = "\"BrightRed\"";
 
 
 			// Act
 			// Act
-			var json = JsonSerializer.Serialize (color, new JsonSerializerOptions {
+			var json = JsonSerializer.Serialize<Color> (Color.FromColorName (Color.BrightRed), new JsonSerializerOptions {
 				Converters = { new ColorJsonConverter () }
 				Converters = { new ColorJsonConverter () }
 			});
 			});
 
 
@@ -97,7 +95,7 @@ namespace Terminal.Gui.ConfigurationTests {
 		{
 		{
 			// Arrange
 			// Arrange
 			var json = "\"Black\"";
 			var json = "\"Black\"";
-			var expectedColor = Color.Black;
+			var expectedColor = new Color (ColorNames.Black);
 
 
 			// Act
 			// Act
 			var color = JsonSerializer.Deserialize<Color> (json, new JsonSerializerOptions {
 			var color = JsonSerializer.Deserialize<Color> (json, new JsonSerializerOptions {
@@ -113,7 +111,7 @@ namespace Terminal.Gui.ConfigurationTests {
 		{
 		{
 			// Arrange
 			// Arrange
 			var json = "\"BrightRed\"";
 			var json = "\"BrightRed\"";
-			var expectedColor = Color.BrightRed;
+			var expectedColor = new Color (ColorNames.BrightRed);
 
 
 			// Act
 			// Act
 			var color = JsonSerializer.Deserialize<Color> (json, new JsonSerializerOptions {
 			var color = JsonSerializer.Deserialize<Color> (json, new JsonSerializerOptions {
@@ -127,7 +125,7 @@ namespace Terminal.Gui.ConfigurationTests {
 
 
 	public class TrueColorJsonConverterTests {
 	public class TrueColorJsonConverterTests {
 		[Theory]
 		[Theory]
-		[InlineData (0,0,0, "\"#000000\"")]
+		[InlineData (0, 0, 0, "\"#000000\"")]
 		public void SerializesToHexCode (int r, int g, int b, string expected)
 		public void SerializesToHexCode (int r, int g, int b, string expected)
 		{
 		{
 			// Arrange
 			// Arrange
@@ -182,14 +180,14 @@ namespace Terminal.Gui.ConfigurationTests {
 			// Test deserializing from human-readable color names
 			// Test deserializing from human-readable color names
 			var json = "{\"Foreground\":\"Blue\",\"Background\":\"Green\"}";
 			var json = "{\"Foreground\":\"Blue\",\"Background\":\"Green\"}";
 			var attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
 			var attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
-			Assert.Equal (Color.Blue, attribute.Foreground);
-			Assert.Equal (Color.Green, attribute.Background);
+			Assert.Equal (Color.Blue, attribute.Foreground.ColorName);
+			Assert.Equal (Color.Green, attribute.Background.ColorName);
 
 
 			// Test deserializing from RGB values
 			// Test deserializing from RGB values
 			json = "{\"Foreground\":\"rgb(255,0,0)\",\"Background\":\"rgb(0,255,0)\"}";
 			json = "{\"Foreground\":\"rgb(255,0,0)\",\"Background\":\"rgb(0,255,0)\"}";
 			attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
 			attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
-			Assert.Equal (Color.BrightRed, attribute.Foreground);
-			Assert.Equal (Color.BrightGreen, attribute.Background);
+			Assert.Equal (Color.BrightRed, attribute.Foreground.ColorName);
+			Assert.Equal (Color.BrightGreen, attribute.Background.ColorName);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]

+ 8 - 8
UnitTests/Configuration/ThemeTests.cs

@@ -38,8 +38,8 @@ namespace Terminal.Gui.ConfigurationTests {
 				{ "test",  colorScheme }
 				{ "test",  colorScheme }
 			};
 			};
 
 
-			Assert.Equal (Color.Red, ((Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue) ["test"].Normal.Foreground);
-			Assert.Equal (Color.Green, ((Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue) ["test"].Normal.Background);
+			Assert.Equal ((Color)Color.Red, ((Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue) ["test"].Normal.Foreground);
+			Assert.Equal ((Color)Color.Green, ((Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue) ["test"].Normal.Background);
 
 
 			// Act
 			// Act
 			Themes.Theme = "testTheme";
 			Themes.Theme = "testTheme";
@@ -47,8 +47,8 @@ namespace Terminal.Gui.ConfigurationTests {
 
 
 			// Assert
 			// Assert
 			var updatedScheme = Colors.ColorSchemes ["test"];
 			var updatedScheme = Colors.ColorSchemes ["test"];
-			Assert.Equal (Color.Red, updatedScheme.Normal.Foreground);
-			Assert.Equal (Color.Green, updatedScheme.Normal.Background);
+			Assert.Equal ((Color)Color.Red, updatedScheme.Normal.Foreground);
+			Assert.Equal ((Color)Color.Green, updatedScheme.Normal.Background);
 
 
 			// remove test ColorScheme from Colors to avoid failures on others unit tests with ColorScheme
 			// remove test ColorScheme from Colors to avoid failures on others unit tests with ColorScheme
 			Colors.ColorSchemes.Remove ("test");
 			Colors.ColorSchemes.Remove ("test");
@@ -118,10 +118,10 @@ namespace Terminal.Gui.ConfigurationTests {
 			// Assert
 			// Assert
 			colorSchemes = (Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue;
 			colorSchemes = (Dictionary<string, ColorScheme>)theme ["ColorSchemes"].PropertyValue;
 			// Normal should have changed
 			// Normal should have changed
-			Assert.Equal (Color.Blue, colorSchemes ["Test"].Normal.Foreground);
-			Assert.Equal (Color.BrightBlue, colorSchemes ["Test"].Normal.Background);
-			Assert.Equal (Color.Cyan, colorSchemes ["Test"].Focus.Foreground);
-			Assert.Equal (Color.BrightCyan, colorSchemes ["Test"].Focus.Background);
+			Assert.Equal ((Color)Color.Blue, colorSchemes ["Test"].Normal.Foreground);
+			Assert.Equal ((Color)Color.BrightBlue, colorSchemes ["Test"].Normal.Background);
+			Assert.Equal ((Color)Color.Cyan, colorSchemes ["Test"].Focus.Foreground);
+			Assert.Equal ((Color)Color.BrightCyan, colorSchemes ["Test"].Focus.Background);
 		}
 		}
 
 
 		[Fact]
 		[Fact]

+ 14 - 14
UnitTests/ConsoleDrivers/AttributeTests.cs

@@ -25,10 +25,10 @@ namespace Terminal.Gui.DriverTests {
 
 
 			// Test foreground, background
 			// Test foreground, background
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			attr = new Attribute (fg, bg);
 			attr = new Attribute (fg, bg);
 
 
@@ -64,10 +64,10 @@ namespace Terminal.Gui.DriverTests {
 
 
 			var value = 42;
 			var value = 42;
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			// Test conversion to int
 			// Test conversion to int
 			attr = new Attribute (value, fg, bg);
 			attr = new Attribute (value, fg, bg);
@@ -84,10 +84,10 @@ namespace Terminal.Gui.DriverTests {
 		public void Make_SetsNotInitialized_NoDriver ()
 		public void Make_SetsNotInitialized_NoDriver ()
 		{
 		{
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			var a = Attribute.Make (fg, bg);
 			var a = Attribute.Make (fg, bg);
 
 
@@ -102,10 +102,10 @@ namespace Terminal.Gui.DriverTests {
 			driver.Init (() => { });
 			driver.Init (() => { });
 
 
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			var attr = Attribute.Make (fg, bg);
 			var attr = Attribute.Make (fg, bg);
 			Assert.True (attr.Initialized);
 			Assert.True (attr.Initialized);
@@ -121,10 +121,10 @@ namespace Terminal.Gui.DriverTests {
 		{
 		{
 
 
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			var attr = Attribute.Make (fg, bg);
 			var attr = Attribute.Make (fg, bg);
 			Assert.False (attr.Initialized);
 			Assert.False (attr.Initialized);
@@ -147,10 +147,10 @@ namespace Terminal.Gui.DriverTests {
 
 
 			var value = 42;
 			var value = 42;
 			var fg = new Color ();
 			var fg = new Color ();
-			fg = Color.Red;
+			fg = (Color)Color.Red;
 
 
 			var bg = new Color ();
 			var bg = new Color ();
-			bg = Color.Blue;
+			bg = (Color)Color.Blue;
 
 
 			var attr = new Attribute (value, fg, bg);
 			var attr = new Attribute (value, fg, bg);
 
 
@@ -174,8 +174,8 @@ namespace Terminal.Gui.DriverTests {
 			var attrValue = new Attribute (Color.Red, Color.Green).Value;
 			var attrValue = new Attribute (Color.Red, Color.Green).Value;
 			driver.GetColors (attrValue, out Color fg, out Color bg);
 			driver.GetColors (attrValue, out Color fg, out Color bg);
 
 
-			Assert.Equal (Color.Red, fg);
-			Assert.Equal (Color.Green, bg);
+			Assert.Equal ((Color)Color.Red, fg);
+			Assert.Equal ((Color)Color.Green, bg);
 		}
 		}
 
 
 		[Fact]
 		[Fact]

+ 334 - 0
UnitTests/Drawing/ColorTests.cs

@@ -0,0 +1,334 @@
+using Terminal.Gui;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using Xunit;
+using static Unix.Terminal.Curses;
+namespace Terminal.Gui.DrawingTests;
+
+public class ColorTests {
+	[Fact]
+	public void ColorNames_Has16Elements ()
+	{
+		Assert.Equal (16, Enum.GetValues (typeof (ColorNames)).Length);
+	}
+
+	[Fact]
+	public void ColorNames_HaveCorrectOrdinals ()
+	{
+		Assert.Equal (0, (int)ColorNames.Black);
+		Assert.Equal (1, (int)ColorNames.Blue);
+		Assert.Equal (2, (int)ColorNames.Green);
+		Assert.Equal (3, (int)ColorNames.Cyan);
+		Assert.Equal (4, (int)ColorNames.Red);
+		Assert.Equal (5, (int)ColorNames.Magenta);
+		Assert.Equal (6, (int)ColorNames.Brown);
+		Assert.Equal (7, (int)ColorNames.Gray);
+		Assert.Equal (8, (int)ColorNames.DarkGray);
+		Assert.Equal (9, (int)ColorNames.BrightBlue);
+		Assert.Equal (10, (int)ColorNames.BrightGreen);
+		Assert.Equal (11, (int)ColorNames.BrightCyan);
+		Assert.Equal (12, (int)ColorNames.BrightRed);
+		Assert.Equal (13, (int)ColorNames.BrightMagenta);
+		Assert.Equal (14, (int)ColorNames.BrightYellow);
+		Assert.Equal (15, (int)ColorNames.White);
+	}
+
+	[Fact]
+	public void Color_Constructor_WithRGBValues ()
+	{
+		// Arrange
+		int expectedR = 255;
+		int expectedG = 0;
+		int expectedB = 128;
+
+		// Act
+		var color = new Color (expectedR, expectedG, expectedB);
+
+		// Assert
+		Assert.Equal (expectedR, color.R);
+		Assert.Equal (expectedG, color.G);
+		Assert.Equal (expectedB, color.B);
+		Assert.Equal (0, color.A); // Alpha should be 0 by default
+	}
+
+	[Fact]
+	public void Color_Constructor_WithAlphaAndRGBValues ()
+	{
+		// Arrange
+		int expectedA = 128;
+		int expectedR = 255;
+		int expectedG = 0;
+		int expectedB = 128;
+
+		// Act
+		var color = new Color (expectedA, expectedR, expectedG, expectedB);
+
+		// Assert
+		Assert.Equal (expectedA, color.A);
+		Assert.Equal (expectedR, color.R);
+		Assert.Equal (expectedG, color.G);
+		Assert.Equal (expectedB, color.B);
+	}
+
+	[Fact]
+	public void Color_Constructor_WithArgbValue ()
+	{
+		// Arrange
+		int expectedArgb = unchecked((int)0xFF804040); // Alpha: 255, R: 128, G: 64, B: 64
+
+		// Act
+		var color = new Color (expectedArgb);
+
+		// Assert
+		Assert.Equal (255, color.A);
+		Assert.Equal (128, color.R);
+		Assert.Equal (64, color.G);
+		Assert.Equal (64, color.B);
+	}
+
+	[Fact]
+	public void Color_Constructor_WithColorName ()
+	{
+		// Arrange
+		ColorNames colorName = ColorNames.Blue;
+		var expectedColor = new Color (0, 0, 0x80); // Blue
+
+		// Act
+		var color = new Color (colorName);
+
+		// Assert
+		Assert.Equal (expectedColor, color);
+	}
+
+	[Fact]
+	public void Color_ToString_WithNamedColor ()
+	{
+		// Arrange
+		Color color = new Color (0, 0, 0x80); // Blue
+
+		// Act
+		string colorString = color.ToString ();
+
+		// Assert
+		Assert.Equal ("Blue", colorString);
+	}
+
+	[Fact]
+	public void Color_ToString_WithRGBColor ()
+	{
+		// Arrange
+		Color color = new Color (128, 64, 32); // Custom RGB color
+
+		// Act
+		string colorString = color.ToString ();
+
+		// Assert
+		Assert.Equal ("#804020", colorString);
+	}
+
+	[Fact]
+	public void Color_ImplicitOperator_FromInt ()
+	{
+		// Arrange
+		int argb = unchecked((int)0xFF804020); // Alpha: 255, R: 128, G: 64, B: 32
+		var expectedColor = new Color (255, 128, 64, 32);
+
+		// Act
+		Color color = argb;
+
+		// Assert
+		Assert.Equal (expectedColor, color);
+	}
+
+	[Fact]
+	public void Color_ExplicitOperator_ToInt ()
+	{
+		// Arrange
+		var color = new Color (255, 128, 64, 32);
+		int expectedArgb = unchecked((int)0xFF804020); // Alpha: 255, R: 128, G: 64, B: 32
+
+		// Act
+		int argb = (int)color;
+
+		// Assert
+		Assert.Equal (expectedArgb, argb);
+	}
+
+
+	[Fact]
+	public void Color_ImplicitOperator_FromColorNames ()
+	{
+		// Arrange
+		ColorNames colorName = ColorNames.Blue;
+		var expectedColor = new Color (0, 0, 0x80); // Blue
+
+		// Act
+		Color color = (Color)colorName;
+
+		// Assert
+		Assert.Equal (expectedColor, color);
+	}
+
+	[Fact]
+	public void Color_ExplicitOperator_ToColorNames ()
+	{
+		// Arrange
+		var color = new Color (0, 0, 0x80); // Blue
+		ColorNames expectedColorName = ColorNames.Blue;
+
+		// Act
+		ColorNames colorName = (ColorNames)color;
+
+		// Assert
+		Assert.Equal (expectedColorName, colorName);
+	}
+
+
+
+	[Fact]
+	public void Color_EqualityOperator_WithColorAndColor ()
+	{
+		// Arrange
+		var color1 = new Color (255, 128, 64, 32);
+		var color2 = new Color (255, 128, 64, 32);
+
+		// Act & Assert
+		Assert.True (color1 == color2);
+		Assert.False (color1 != color2);
+	}
+
+	[Fact]
+	public void Color_InequalityOperator_WithColorAndColor ()
+	{
+		// Arrange
+		var color1 = new Color (255, 128, 64, 32);
+		var color2 = new Color (128, 64, 32, 16);
+
+		// Act & Assert
+		Assert.False (color1 == color2);
+		Assert.True (color1 != color2);
+	}
+
+	[Fact]
+	public void Color_EqualityOperator_WithColorNamesAndColor ()
+	{
+		// Arrange
+		var color1 = new Color (ColorNames.Red);
+		var color2 = new Color (0x80, 0, 0); // Red in RGB
+
+		// Act & Assert
+		Assert.True (ColorNames.Red == color1);
+		Assert.False (ColorNames.Red != color1);
+
+		Assert.True (color1 == ColorNames.Red);
+		Assert.False (color1 != ColorNames.Red);
+
+		Assert.True (color2 == ColorNames.Red);
+		Assert.False (color2 != ColorNames.Red);
+	}
+
+	[Fact]
+	public void Color_InequalityOperator_WithColorNamesAndColor ()
+	{
+		// Arrange
+		var color1 = new Color (ColorNames.Red);
+		var color2 = new Color (0, 255, 255); // Cyan in RGB
+
+		// Act & Assert
+		Assert.False (ColorNames.Red == color2);
+		Assert.True (ColorNames.Red != color2);
+
+		Assert.False (color2 == ColorNames.Red);
+		Assert.True (color2 != ColorNames.Red);
+	}
+
+	[Fact]
+	public void Color_FromColorName_ConvertsColorNamesToColor ()
+	{
+		// Arrange
+		var colorName = ColorNames.Red;
+		var expectedColor = new Color (255, 0, 0); // Red in RGB
+
+		// Act
+		var convertedColor = Color.FromColorName (colorName);
+
+		// Assert
+		Assert.Equal (expectedColor, convertedColor);
+	}
+
+	[Fact]
+	public void Color_FromColorName_ConvertsColorNameIdToColor ()
+	{
+		// Arrange
+		int colorNameId = (int)ColorNames.Green;
+		var expectedColor = new Color (0, 255, 0); // Green in RGB
+
+		// Act
+		var convertedColor = Color.FromColorName (colorNameId);
+
+		// Assert
+		Assert.Equal (expectedColor, convertedColor);
+	}
+
+	[Fact]
+	public void Color_ColorName_Get_ReturnsClosestColorName ()
+	{
+		// Arrange
+		var color = new Color (128, 64, 32); // Custom RGB color, closest to Brown (0xC1, 0x9C, 0x00)
+		var expectedColorName = ColorNames.Brown;
+
+		// Act
+		var colorName = color.ColorName;
+
+		// Assert
+		Assert.Equal (expectedColorName, colorName);
+	}
+
+	[Fact]
+	public void FindClosestColor_ReturnsClosestColor ()
+	{
+		// Test cases with RGB values and expected closest color names
+		var testCases = new []
+		{
+			(new Color(0, 0, 0), ColorNames.Black),
+			(new Color(255, 255, 255), ColorNames.White),
+			(new Color(0, 0, 255), ColorNames.BrightBlue),
+			(new Color(0, 255, 0), ColorNames.BrightGreen),
+			(new Color(255, 0, 0), ColorNames.BrightRed),
+			(new Color(0, 128, 128), ColorNames.Cyan),
+			(new Color(128, 64, 32), ColorNames.Brown),
+		};
+
+		foreach (var testCase in testCases) {
+			var inputColor = testCase.Item1;
+			var expectedColorName = testCase.Item2;
+
+			var actualColorName = Color.FindClosestColor (inputColor);
+
+			Assert.Equal (expectedColorName, actualColorName);
+		}
+	}
+
+	[Fact]
+	public void Color_ColorName_Set_SetsColorBasedOnColorName ()
+	{
+		// Arrange
+		var color = new Color (0, 0, 0); // Black
+		var expectedColor = new Color (ColorNames.Magenta);
+
+		// Act
+		color.ColorName = ColorNames.Magenta;
+
+		// Assert
+		Assert.Equal (expectedColor, color);
+	}
+}
+
+

+ 6 - 6
UnitTests/Text/AutocompleteTests.cs

@@ -50,19 +50,19 @@ namespace Terminal.Gui.TextTests {
 
 
 			// allocate a new custom scheme
 			// allocate a new custom scheme
 			tv.Autocomplete.ColorScheme = new ColorScheme () {
 			tv.Autocomplete.ColorScheme = new ColorScheme () {
-				Normal = Application.Driver.MakeAttribute (Color.Black, Color.Blue),
-				Focus = Application.Driver.MakeAttribute (Color.Black, Color.Cyan),
+				Normal = new Attribute (Color.Black, Color.Blue),
+				Focus = new Attribute (Color.Black, Color.Cyan),
 			};
 			};
 
 
 			// should be separate instance
 			// should be separate instance
 			Assert.NotSame (Colors.Menu, tv.Autocomplete.ColorScheme);
 			Assert.NotSame (Colors.Menu, tv.Autocomplete.ColorScheme);
 
 
 			// with the values we set on it
 			// with the values we set on it
-			Assert.Equal (Color.Black, tv.Autocomplete.ColorScheme.Normal.Foreground);
-			Assert.Equal (Color.Blue, tv.Autocomplete.ColorScheme.Normal.Background);
+			Assert.Equal ((Color)Color.Black, tv.Autocomplete.ColorScheme.Normal.Foreground);
+			Assert.Equal ((Color)Color.Blue, tv.Autocomplete.ColorScheme.Normal.Background);
 
 
-			Assert.Equal (Color.Black, tv.Autocomplete.ColorScheme.Focus.Foreground);
-			Assert.Equal (Color.Cyan, tv.Autocomplete.ColorScheme.Focus.Background);
+			Assert.Equal ((Color)Color.Black, tv.Autocomplete.ColorScheme.Focus.Foreground);
+			Assert.Equal ((Color)Color.Cyan, tv.Autocomplete.ColorScheme.Focus.Background);
 		}
 		}
 
 
 		[Fact]
 		[Fact]