diff --git a/Flax.sln.DotSettings b/Flax.sln.DotSettings index 96456601b..8ff4f1621 100644 --- a/Flax.sln.DotSettings +++ b/Flax.sln.DotSettings @@ -74,6 +74,7 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> AI + ARGB LO RPC SDK diff --git a/Source/Editor/CustomEditors/Editors/StringEditor.cs b/Source/Editor/CustomEditors/Editors/StringEditor.cs index 9f6b4ce32..d4ed4b3e4 100644 --- a/Source/Editor/CustomEditors/Editors/StringEditor.cs +++ b/Source/Editor/CustomEditors/Editors/StringEditor.cs @@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors if (watermarkAttribute is WatermarkAttribute watermark) { _watermarkText = watermark.WatermarkText; - var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled; + var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGB(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled; _watermarkColor = watermarkColor; _element.TextBox.WatermarkText = watermark.WatermarkText; _element.TextBox.WatermarkTextColor = watermarkColor; diff --git a/Source/Editor/CustomEditors/LayoutElementsContainer.cs b/Source/Editor/CustomEditors/LayoutElementsContainer.cs index 643601b09..d1999bb99 100644 --- a/Source/Editor/CustomEditors/LayoutElementsContainer.cs +++ b/Source/Editor/CustomEditors/LayoutElementsContainer.cs @@ -318,7 +318,7 @@ namespace FlaxEditor.CustomEditors if (header.FontSize > 0) element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize); if (header.Color > 0) - element.Label.TextColor = Color.FromRGBA(header.Color); + element.Label.TextColor = Color.FromRGB(header.Color); return element; } diff --git a/Source/Engine/Core/Math/Color.cpp b/Source/Engine/Core/Math/Color.cpp index 4a551e504..de4425ba3 100644 --- a/Source/Engine/Core/Math/Color.cpp +++ b/Source/Engine/Core/Math/Color.cpp @@ -32,41 +32,39 @@ Color::Color(const Color32& color) { } -Color Color::FromHex(const String& hexString, bool& isValid) +Color Color::FromHex(const String& hex, bool& isValid) { int32 r, g, b, a = 255; isValid = true; - - int32 startIndex = !hexString.IsEmpty() && hexString[0] == Char('#') ? 1 : 0; - if (hexString.Length() == 3 + startIndex) + int32 startIndex = !hex.IsEmpty() && hex[0] == Char('#') ? 1 : 0; + if (hex.Length() == 3 + startIndex) { - r = StringUtils::HexDigit(hexString[startIndex++]); - g = StringUtils::HexDigit(hexString[startIndex++]); - b = StringUtils::HexDigit(hexString[startIndex]); + r = StringUtils::HexDigit(hex[startIndex++]); + g = StringUtils::HexDigit(hex[startIndex++]); + b = StringUtils::HexDigit(hex[startIndex]); r = (r << 4) + r; g = (g << 4) + g; b = (b << 4) + b; } - else if (hexString.Length() == 6 + startIndex) + else if (hex.Length() == 6 + startIndex) { - r = (StringUtils::HexDigit(hexString[startIndex + 0]) << 4) + StringUtils::HexDigit(hexString[startIndex + 1]); - g = (StringUtils::HexDigit(hexString[startIndex + 2]) << 4) + StringUtils::HexDigit(hexString[startIndex + 3]); - b = (StringUtils::HexDigit(hexString[startIndex + 4]) << 4) + StringUtils::HexDigit(hexString[startIndex + 5]); + r = (StringUtils::HexDigit(hex[startIndex + 0]) << 4) + StringUtils::HexDigit(hex[startIndex + 1]); + g = (StringUtils::HexDigit(hex[startIndex + 2]) << 4) + StringUtils::HexDigit(hex[startIndex + 3]); + b = (StringUtils::HexDigit(hex[startIndex + 4]) << 4) + StringUtils::HexDigit(hex[startIndex + 5]); } - else if (hexString.Length() == 8 + startIndex) + else if (hex.Length() == 8 + startIndex) { - r = (StringUtils::HexDigit(hexString[startIndex + 0]) << 4) + StringUtils::HexDigit(hexString[startIndex + 1]); - g = (StringUtils::HexDigit(hexString[startIndex + 2]) << 4) + StringUtils::HexDigit(hexString[startIndex + 3]); - b = (StringUtils::HexDigit(hexString[startIndex + 4]) << 4) + StringUtils::HexDigit(hexString[startIndex + 5]); - a = (StringUtils::HexDigit(hexString[startIndex + 6]) << 4) + StringUtils::HexDigit(hexString[startIndex + 7]); + r = (StringUtils::HexDigit(hex[startIndex + 0]) << 4) + StringUtils::HexDigit(hex[startIndex + 1]); + g = (StringUtils::HexDigit(hex[startIndex + 2]) << 4) + StringUtils::HexDigit(hex[startIndex + 3]); + b = (StringUtils::HexDigit(hex[startIndex + 4]) << 4) + StringUtils::HexDigit(hex[startIndex + 5]); + a = (StringUtils::HexDigit(hex[startIndex + 6]) << 4) + StringUtils::HexDigit(hex[startIndex + 7]); } else { r = g = b = 0; isValid = false; } - return FromBytes(r, g, b, a); } @@ -122,8 +120,9 @@ String Color::ToHexString() const const byte r = static_cast(R * MAX_uint8); const byte g = static_cast(G * MAX_uint8); const byte b = static_cast(B * MAX_uint8); + const byte a = static_cast(A * MAX_uint8); - Char result[6]; + Char result[8]; result[0] = digits[r >> 4 & 0x0f]; result[1] = digits[r & 0x0f]; @@ -134,7 +133,10 @@ String Color::ToHexString() const result[4] = digits[b >> 4 & 0x0f]; result[5] = digits[b & 0x0f]; - return String(result, 6); + result[6] = digits[a >> 4 & 0x0f]; + result[7] = digits[a & 0x0f]; + + return String(result, 8); } bool Color::IsTransparent() const diff --git a/Source/Engine/Core/Math/Color.cs b/Source/Engine/Core/Math/Color.cs index c633c61b9..cb880d66d 100644 --- a/Source/Engine/Core/Math/Color.cs +++ b/Source/Engine/Core/Math/Color.cs @@ -230,36 +230,93 @@ namespace FlaxEngine } /// - /// Creates from the RGB value and separate alpha channel. + /// Creates from the RGB value (bottom bits contain Blue) and separate alpha channel. /// - /// The packed RGB value. + /// The packed RGB value (bottom bits contain Blue). /// The alpha channel value. /// The color. public static Color FromRGB(uint rgb, float a = 1.0f) { - return new Color( - ((rgb >> 16) & 0xff) / 255.0f, - ((rgb >> 8) & 0xff) / 255.0f, - (rgb & 0xff) / 255.0f, - a); + return new Color(((rgb >> 16) & 0xff) / 255.0f, ((rgb >> 8) & 0xff) / 255.0f, (rgb & 0xff) / 255.0f, a); } /// - /// Creates from the RGBA value. + /// Creates from the ARGB value (bottom bits contain Blue). /// - /// The packed RGBA value. + /// The packed ARGB value (bottom bits contain Blue). /// The color. - public static Color FromRGBA(uint rgb) + public static Color FromARGB(uint argb) { - return new Color( - ((rgb >> 16) & 0xff) / 255.0f, - ((rgb >> 8) & 0xff) / 255.0f, - (rgb & 0xff) / 255.0f, - ((rgb >> 24) & 0xff) / 255.0f); + return new Color(((argb >> 16) & 0xff) / 255.0f, ((argb >> 8) & 0xff) / 255.0f, ((argb >> 0) & 0xff) / 255.0f, ((argb >> 24) & 0xff) / 255.0f); } /// - /// Gets the color value as the hexadecimal string. + /// Creates from the RGBA value (bottom bits contain Alpha). + /// + /// The packed RGBA value (bottom bits Alpha Red). + /// The color. + public static Color FromRGBA(uint rgba) + { + return new Color(((rgba >> 24) & 0xff) / 255.0f, ((rgba >> 16) & 0xff) / 255.0f, ((rgba >> 8) & 0xff) / 255.0f, ((rgba >> 0) & 0xff) / 255.0f); + } + + /// + /// Creates from the Hex string. + /// + /// The hexadecimal color string. + /// The output color value. + public static Color FromHex(string hex) + { + FromHex(hex, out var color); + return color; + } + + /// + /// Creates from the Hex string. + /// + /// The hexadecimal color string. + /// The output color value. Valid if method returns true. + /// True if method was able to convert color, otherwise false. + public static bool FromHex(string hex, out Color color) + { + int r, g, b, a = 255; + bool isValid = true; + + int startIndex = hex.Length != 0 && hex[0] == '#' ? 1 : 0; + if (hex.Length == 3 + startIndex) + { + r = StringUtils.HexDigit(hex[startIndex++]); + g = StringUtils.HexDigit(hex[startIndex++]); + b = StringUtils.HexDigit(hex[startIndex]); + r = (r << 4) + r; + g = (g << 4) + g; + b = (b << 4) + b; + } + else if (hex.Length == 6 + startIndex) + { + r = (StringUtils.HexDigit(hex[startIndex + 0]) << 4) + StringUtils.HexDigit(hex[startIndex + 1]); + g = (StringUtils.HexDigit(hex[startIndex + 2]) << 4) + StringUtils.HexDigit(hex[startIndex + 3]); + b = (StringUtils.HexDigit(hex[startIndex + 4]) << 4) + StringUtils.HexDigit(hex[startIndex + 5]); + } + else if (hex.Length == 8 + startIndex) + { + r = (StringUtils.HexDigit(hex[startIndex + 0]) << 4) + StringUtils.HexDigit(hex[startIndex + 1]); + g = (StringUtils.HexDigit(hex[startIndex + 2]) << 4) + StringUtils.HexDigit(hex[startIndex + 3]); + b = (StringUtils.HexDigit(hex[startIndex + 4]) << 4) + StringUtils.HexDigit(hex[startIndex + 5]); + a = (StringUtils.HexDigit(hex[startIndex + 6]) << 4) + StringUtils.HexDigit(hex[startIndex + 7]); + } + else + { + r = g = b = 0; + isValid = false; + } + + color = new Color(r, g, b, a); + return isValid; + } + + /// + /// Gets the color value as the hexadecimal string (in RGBA order). /// /// Hex string. public string ToHexString() @@ -287,7 +344,7 @@ namespace FlaxEngine return new string(result); } - + /// /// Creates from the text string (hex or color name). /// diff --git a/Source/Engine/Core/Math/Color.h b/Source/Engine/Core/Math/Color.h index 49cac28db..955494f8e 100644 --- a/Source/Engine/Core/Math/Color.h +++ b/Source/Engine/Core/Math/Color.h @@ -126,9 +126,9 @@ public: } /// - /// Initializes from packed RGB value of the color and separate alpha channel value. + /// Initializes from packed RGB value (bottom bits contain Blue) of the color and separate alpha channel value. /// - /// The packed RGB value. + /// The packed RGB value (bottom bits contain Blue). /// The alpha channel. /// The color. static Color FromRGB(uint32 rgb, float a = 1.0f) @@ -137,22 +137,32 @@ public: } /// - /// Initializes from packed RGBA value. + /// Initializes from packed ARGB value (bottom bits contain Blue). /// - /// The packed RGBA value. + /// The packed ARGB value (bottom bits contain Blue). + /// The color. + static Color FromARGB(uint32 argb) + { + return Color((float)((argb >> 16) & 0xff) / 255.0f,(float)((argb >> 8) & 0xff) / 255.0f, (float)((argb >> 0) & 0xff) / 255.0f, (float)((argb >> 24) & 0xff) / 255.0f); + } + + /// + /// Initializes from packed RGBA value (bottom bits contain Alpha). + /// + /// The packed RGBA value (bottom bits contain Alpha). /// The color. static Color FromRGBA(uint32 rgba) { - return Color(static_cast(rgba >> 16 & 0xff) / 255.0f, static_cast(rgba >> 8 & 0xff) / 255.0f, static_cast(rgba & 0xff) / 255.0f, static_cast(rgba >> 24 & 0xff) / 255.0f); + return Color((float)((rgba >> 24) & 0xff) / 255.0f,(float)((rgba >> 16) & 0xff) / 255.0f, (float)((rgba >> 8) & 0xff) / 255.0f, (float)((rgba >> 0) & 0xff) / 255.0f); } - static Color FromHex(const String& hexString) + static Color FromHex(const String& hex) { bool isValid; - return FromHex(hexString, isValid); + return FromHex(hex, isValid); } - static Color FromHex(const String& hexString, bool& isValid); + static Color FromHex(const String& hex, bool& isValid); /// /// Creates RGB color from Hue[0-360], Saturation[0-1] and Value[0-1]. diff --git a/Source/Engine/Scripting/Attributes/Editor/HeaderAttribute.cs b/Source/Engine/Scripting/Attributes/Editor/HeaderAttribute.cs index e1ce249da..5d91023af 100644 --- a/Source/Engine/Scripting/Attributes/Editor/HeaderAttribute.cs +++ b/Source/Engine/Scripting/Attributes/Editor/HeaderAttribute.cs @@ -23,11 +23,14 @@ namespace FlaxEngine public int FontSize; /// - /// The custom header color (as 32-bit uint). + /// The custom header color (as 32-bit uint in RGB order, bottom bits contain Blue). /// public uint Color; - private HeaderAttribute() + /// + /// Initializes a new instance of the class. + /// + public HeaderAttribute() { } diff --git a/Source/Engine/Scripting/Attributes/Editor/WatermarkAttribute.cs b/Source/Engine/Scripting/Attributes/Editor/WatermarkAttribute.cs index 73814d11c..456554e44 100644 --- a/Source/Engine/Scripting/Attributes/Editor/WatermarkAttribute.cs +++ b/Source/Engine/Scripting/Attributes/Editor/WatermarkAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace FlaxEngine; @@ -15,7 +15,7 @@ public class WatermarkAttribute : Attribute public string WatermarkText; /// - /// The watermark color. + /// The watermark color (as 32-bit uint in RGB order, bottom bits contain Blue). /// public uint WatermarkColor; @@ -26,7 +26,7 @@ public class WatermarkAttribute : Attribute public WatermarkAttribute(string text) { WatermarkText = text; - WatermarkColor = 0; // default color of watermark in textbox + WatermarkColor = 0; // Default color of watermark in textbox } /// diff --git a/Source/Engine/Tests/TestColor.cs b/Source/Engine/Tests/TestColor.cs index e0aa45539..df1799b5b 100644 --- a/Source/Engine/Tests/TestColor.cs +++ b/Source/Engine/Tests/TestColor.cs @@ -37,6 +37,15 @@ namespace FlaxEngine.Tests Assert.AreEqual(Color.Maroon, ColorHSV.FromColor(Color.Maroon).ToColor()); Assert.AreEqual(new Color(184, 209, 219, 255).ToRgba(), ColorHSV.FromColor(new Color(184, 209, 219, 255)).ToColor().ToRgba()); } + + [Test] + public void TestHexConversion() + { + String hex = Color.Blue.AlphaMultiplied(0.5f).ToHexString(); + Color col1 = Color.FromHex(hex); + Color col2 = Color.FromRGBA(0x0000FF7F); + Assert.AreEqual((Color32)col1, (Color32)col2); + } } } #endif