mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 09:47:58 +01:00
Refactored argb->rgba to match ARGB32 standards
This commit is contained in:
@@ -10,7 +10,8 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// 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"/>.
|
||||
/// 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>
|
||||
/// <remarks>
|
||||
///
|
||||
@@ -91,39 +92,25 @@ namespace Terminal.Gui {
|
||||
/// <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)
|
||||
/// <param name="red">The red 8-bits.</param>
|
||||
/// <param name="green">The green 8-bits.</param>
|
||||
/// <param name="blue">The blue 8-bits.</param>
|
||||
/// <param name="alpha">Optional; defaults to 0xFF. The Alpha channel is not supported by Terminal.Gui.</param>
|
||||
public Color (int red, int green, int blue, int alpha = 0xFF)
|
||||
{
|
||||
A = 0xFF;
|
||||
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)
|
||||
/// <param name="rgba">The encoded 24-bit color value (see <see cref="Rgba"/>).</param>
|
||||
public Color (int rgba)
|
||||
{
|
||||
Value = argb;
|
||||
Rgba = rgba;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -133,10 +120,26 @@ namespace Terminal.Gui {
|
||||
public Color (ColorNames colorName)
|
||||
{
|
||||
var c = Color.FromColorName (colorName);
|
||||
A = c.A;
|
||||
R = c.R;
|
||||
G = c.G;
|
||||
B = c.B;
|
||||
A = c.A;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color"/> color from string. See <see cref="TryParse(string, out Color)"/> for details.
|
||||
/// </summary>
|
||||
/// <param name="colorString"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public Color (string colorString)
|
||||
{
|
||||
if (!TryParse (colorString, out var c)) {
|
||||
throw new ArgumentOutOfRangeException (nameof (colorString));
|
||||
}
|
||||
R = c.R;
|
||||
G = c.G;
|
||||
B = c.B;
|
||||
A = c.A;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -144,10 +147,10 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
public Color ()
|
||||
{
|
||||
A = 0xFF;
|
||||
R = 0;
|
||||
G = 0;
|
||||
B = 0;
|
||||
A = 0xFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -167,17 +170,17 @@ namespace Terminal.Gui {
|
||||
/// Alpha color component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not currently supported; here for completeness.
|
||||
/// The Alpha channel is not supported by Terminal.Gui.
|
||||
/// </remarks>
|
||||
public int A { get; set; }
|
||||
public int A { get; set; } = 0xFF; // Not currently supported; here for completeness.
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color value encoded using the following code:
|
||||
/// Gets or sets the color value encoded as ARGB32.
|
||||
/// <code>
|
||||
/// (<see cref="A"/> << 24) | (<see cref="R"/> << 16) | (<see cref="G"/> << 8) | <see cref="B"/>
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public int Value {
|
||||
public int Rgba {
|
||||
get => (A << 24) | (R << 16) | (G << 8) | B;
|
||||
set {
|
||||
A = (byte)((value >> 24) & 0xFF);
|
||||
@@ -194,6 +197,7 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
internal static readonly ImmutableDictionary<Color, ColorNames> _colorNames = new Dictionary<Color, ColorNames> () {
|
||||
// using "Windows 10 Console/PowerShell 6" here: https://i.stack.imgur.com/9UVnC.png
|
||||
// See also: https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
{ new Color (12, 12, 12),ColorNames.Black },
|
||||
{ new Color (0, 55, 218),ColorNames.Blue },
|
||||
{ new Color (19, 161, 14),ColorNames.Green},
|
||||
@@ -260,10 +264,10 @@ namespace Terminal.Gui {
|
||||
set {
|
||||
|
||||
var c = FromColorName (value);
|
||||
A = c.A;
|
||||
R = c.R;
|
||||
G = c.G;
|
||||
B = c.B;
|
||||
A = c.A;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,11 +341,16 @@ namespace Terminal.Gui {
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Converts the provided text to a new <see cref="Color"/> instance.
|
||||
/// Converts the provided string to a new <see cref="Color"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to analyze.</param>
|
||||
/// <param name="text">The text to analyze. Formats supported are
|
||||
/// "#RGB", "#RRGGBB", "#RGBA", "#RRGGBBAA", "rgb(r,g,b)", "rgb(r,g,b,a)", and any of the
|
||||
/// <see cref="ColorNames"/>.</param>
|
||||
/// <param name="color">The parsed value.</param>
|
||||
/// <returns>A boolean value indicating whether it was successful.</returns>
|
||||
/// <returns>A boolean value indicating whether parsing was successful.</returns>
|
||||
/// <remarks>
|
||||
/// While <see cref="Color"/> supports the alpha channel <see cref="A"/>, Terminal.Gui does not.
|
||||
/// </remarks>
|
||||
public static bool TryParse (string text, [NotNullWhen (true)] out Color color)
|
||||
{
|
||||
// empty color
|
||||
@@ -370,25 +379,25 @@ namespace Terminal.Gui {
|
||||
return true;
|
||||
}
|
||||
|
||||
// #AARRGGBB, #ARGB
|
||||
// #RRGGBB, #RGBA
|
||||
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);
|
||||
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);
|
||||
var a = 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 rText = char.ToString (text [1]);
|
||||
var gText = char.ToString (text [2]);
|
||||
var bText = char.ToString (text [3]);
|
||||
var aText = 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);
|
||||
var r = Convert.ToInt32 (aText + aText, 16);
|
||||
var g = Convert.ToInt32 (rText + rText, 16);
|
||||
var b = Convert.ToInt32 (gText + gText, 16);
|
||||
var a = Convert.ToInt32 (bText + bText, 16);
|
||||
color = new Color (r, g, b, a);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -403,14 +412,14 @@ namespace Terminal.Gui {
|
||||
return true;
|
||||
}
|
||||
|
||||
// rgb(a,r,g,b)
|
||||
// rgb(r,g,b,a)
|
||||
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);
|
||||
var r = int.Parse (match.Groups [1].Value);
|
||||
var g = int.Parse (match.Groups [2].Value);
|
||||
var b = int.Parse (match.Groups [3].Value);
|
||||
var a = int.Parse (match.Groups [4].Value);
|
||||
color = new Color (r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -422,10 +431,10 @@ namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// Cast from int.
|
||||
/// </summary>
|
||||
/// <param name="argb"></param>
|
||||
public static implicit operator Color (int argb)
|
||||
/// <param name="rgba"></param>
|
||||
public static implicit operator Color (int rgba)
|
||||
{
|
||||
return new Color (argb);
|
||||
return new Color (rgba);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -434,7 +443,7 @@ namespace Terminal.Gui {
|
||||
/// <param name="color"></param>
|
||||
public static explicit operator int (Color color)
|
||||
{
|
||||
return color.Value;
|
||||
return color.Rgba;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -546,16 +555,16 @@ namespace Terminal.Gui {
|
||||
public bool Equals (Color other)
|
||||
{
|
||||
return
|
||||
A == other.A &&
|
||||
R == other.R &&
|
||||
G == other.G &&
|
||||
B == other.B;
|
||||
B == other.B &&
|
||||
A == other.A;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return HashCode.Combine (A, R, G, B);
|
||||
return HashCode.Combine (R, G, B, A);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -563,7 +572,12 @@ namespace Terminal.Gui {
|
||||
/// Converts the color to a string representation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// If the color is a named color, the name is returned. Otherwise, the color is returned as a hex string.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <see cref="A"/> (Alpha channel) is ignored and the returned string will not include it.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public override string ToString ()
|
||||
|
||||
@@ -108,29 +108,29 @@ public class ColorTests {
|
||||
int expectedB = 128;
|
||||
|
||||
// Act
|
||||
var color = new Color (expectedA, expectedR, expectedG, expectedB);
|
||||
var color = new Color (expectedR, expectedG, expectedB, expectedA);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedA, color.A);
|
||||
Assert.Equal (expectedR, color.R);
|
||||
Assert.Equal (expectedG, color.G);
|
||||
Assert.Equal (expectedB, color.B);
|
||||
Assert.Equal (expectedA, color.A);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Color_Constructor_WithArgbValue ()
|
||||
public void Color_Constructor_WithRgbaValue ()
|
||||
{
|
||||
// Arrange
|
||||
int expectedArgb = unchecked((int)0xFF804040); // Alpha: 255, R: 128, G: 64, B: 64
|
||||
int expectedRgba = unchecked((int)0xFF804040); // R: 128, G: 64, B: 64, Alpha: 255
|
||||
|
||||
// Act
|
||||
var color = new Color (expectedArgb);
|
||||
var color = new Color (expectedRgba);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (255, color.A);
|
||||
Assert.Equal (128, color.R);
|
||||
Assert.Equal (64, color.G);
|
||||
Assert.Equal (64, color.B);
|
||||
Assert.Equal (255, color.A);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -177,11 +177,11 @@ public class ColorTests {
|
||||
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);
|
||||
int Rgba = unchecked((int)0xFF804020); // R: 128, G: 64, B: 32, Alpha: 255
|
||||
var expectedColor = new Color (128, 64, 32);
|
||||
|
||||
// Act
|
||||
Color color = argb;
|
||||
Color color = Rgba;
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColor, color);
|
||||
@@ -191,14 +191,14 @@ public class ColorTests {
|
||||
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
|
||||
var color = new Color (128, 64, 32);
|
||||
int expectedRgba = unchecked((int)0xFF804020); // R: 128, G: 64, B: 32, Alpha: 255
|
||||
|
||||
// Act
|
||||
int argb = (int)color;
|
||||
int Rgba = (int)color;
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedArgb, argb);
|
||||
Assert.Equal (expectedRgba, Rgba);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user