2023-09-30 22:50:18 +02:00
using System ;
2020-04-30 21:15:28 +02:00
using System.Globalization ;
2019-08-06 14:20:11 +02:00
using Microsoft.Xna.Framework ;
namespace MLEM.Extensions {
2020-05-21 12:53:42 +02:00
/// <summary>
2021-12-22 14:24:37 +01:00
/// A set of extensions for dealing with <see cref="Color"/> objects.
2020-05-21 12:53:42 +02:00
/// </summary>
2019-08-06 14:20:11 +02:00
public static class ColorExtensions {
2020-05-20 23:59:40 +02:00
/// <summary>
2021-12-22 14:24:37 +01:00
/// Copies the alpha value from another color into this color and returns the result.
2020-05-20 23:59:40 +02:00
/// </summary>
2021-12-22 14:24:37 +01:00
/// <param name="color">The color.</param>
/// <param name="other">The color to copy the alpha from.</param>
/// <returns>The first color with the second color's alpha value.</returns>
2019-08-09 22:04:26 +02:00
public static Color CopyAlpha ( this Color color , Color other ) {
return color * ( other . A / 255F ) ;
}
2021-07-13 22:34:32 +02:00
/// <summary>
/// Returns an inverted version of this color.
/// </summary>
2021-12-22 14:24:37 +01:00
/// <param name="color">The color to invert.</param>
/// <returns>The inverted color.</returns>
2021-07-13 22:34:32 +02:00
public static Color Invert ( this Color color ) {
2021-12-11 00:38:28 +01:00
return new Color ( 255 - color . R , 255 - color . G , 255 - color . B , color . A ) ;
2021-07-13 22:34:32 +02:00
}
2021-12-22 14:24:37 +01:00
/// <summary>
/// Multiplies this color with another color and returns the result.
/// </summary>
/// <param name="color">The first color.</param>
/// <param name="other">The second color.</param>
/// <returns>The two colors multiplied together.</returns>
public static Color Multiply ( this Color color , Color other ) {
return new Color ( color . ToVector4 ( ) * other . ToVector4 ( ) ) ;
}
2024-03-15 20:03:52 +01:00
/// <summary>
/// Returns the hexadecimal representation of this color as a string in the format <c>#AARRGGBB</c>, or optionally <c>AARRGGBB</c>, without the pound symbol.
/// </summary>
/// <param name="color">The color to convert.</param>
/// <param name="hash">Whether a # should prepend the string.</param>
/// <returns>The resulting hex string.</returns>
public static string ToHexStringRgba ( this Color color , bool hash = true ) {
return $"{(hash ? " # " : string.Empty)}{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}" ;
}
/// <summary>
/// Returns the hexadecimal representation of this color as a string in the format <c>#RRGGBB</c>, or optionally <c>RRGGBB</c>, without the pound symbol.
/// The alpha channel is ignored.
/// </summary>
/// <param name="color">The color to convert.</param>
/// <param name="hash">Whether a # should prepend the string.</param>
/// <returns>The resulting hex string.</returns>
public static string ToHexStringRgb ( this Color color , bool hash = true ) {
return $"{(hash ? " # " : string.Empty)}{color.R:X2}{color.G:X2}{color.B:X2}" ;
}
2019-08-06 14:20:11 +02:00
}
2020-11-04 23:44:41 +01:00
/// <summary>
2021-12-22 14:24:37 +01:00
/// A set of utility methods for dealing with <see cref="Color"/> objects.
2020-11-04 23:44:41 +01:00
/// </summary>
public static class ColorHelper {
/// <summary>
/// Parses a hexadecimal number into an rgba color.
/// The number should be in the format <c>0xaarrggbb</c>.
/// </summary>
2021-12-22 14:24:37 +01:00
/// <param name="value">The number to parse.</param>
/// <returns>The resulting color.</returns>
2020-11-04 23:44:41 +01:00
public static Color FromHexRgba ( int value ) {
2022-06-15 11:38:11 +02:00
return new Color ( value > > 16 & 0xFF , value > > 8 & 0xFF , value > > 0 & 0xFF , value > > 24 & 0xFF ) ;
2020-11-04 23:44:41 +01:00
}
/// <summary>
/// Parses a hexadecimal number into an rgb color with 100% alpha.
/// The number should be in the format <c>0xrrggbb</c>.
/// </summary>
2021-12-22 14:24:37 +01:00
/// <param name="value">The number to parse.</param>
/// <returns>The resulting color.</returns>
2020-11-04 23:44:41 +01:00
public static Color FromHexRgb ( int value ) {
2022-06-15 11:38:11 +02:00
return new Color ( value > > 16 & 0xFF , value > > 8 & 0xFF , value > > 0 & 0xFF ) ;
2020-11-04 23:44:41 +01:00
}
/// <summary>
2023-09-30 22:50:18 +02:00
/// Parses a hexadecimal string into a color and throws a <see cref="FormatException"/> if parsing fails.
2024-03-15 20:03:52 +01:00
/// The string can either be formatted as <c>RRGGBB</c> or <c>AARRGGBB</c> and can optionally start with a <c>#</c>.
2020-11-04 23:44:41 +01:00
/// </summary>
2021-12-22 14:24:37 +01:00
/// <param name="value">The string to parse.</param>
/// <returns>The resulting color.</returns>
2023-09-30 22:50:18 +02:00
/// <exception cref="FormatException">Thrown if parsing fails.</exception>
2020-11-04 23:44:41 +01:00
public static Color FromHexString ( string value ) {
2023-09-30 22:50:18 +02:00
if ( ! ColorHelper . TryFromHexString ( value , out var val ) )
throw new FormatException ( $"Cannot parse hex string {value}" ) ;
return val ;
}
/// <summary>
/// Tries to parse a hexadecimal string into a color and returns whether a color was successfully parsed.
2024-03-15 20:03:52 +01:00
/// The string can either be formatted as <c>RRGGBB</c> or <c>AARRGGBB</c> and can optionally start with a <c>#</c>.
2023-09-30 22:50:18 +02:00
/// </summary>
/// <param name="value">The string to parse.</param>
/// <param name="color">The resulting color.</param>
/// <returns>Whether parsing was successful.</returns>
public static bool TryFromHexString ( string value , out Color color ) {
2020-11-04 23:44:41 +01:00
if ( value . StartsWith ( "#" ) )
value = value . Substring ( 1 ) ;
2023-09-30 22:50:18 +02:00
if ( int . TryParse ( value , NumberStyles . HexNumber , CultureInfo . InvariantCulture , out var val ) ) {
color = value . Length > 6 ? ColorHelper . FromHexRgba ( val ) : ColorHelper . FromHexRgb ( val ) ;
return true ;
}
color = default ;
return false ;
2020-11-04 23:44:41 +01:00
}
}
2022-06-17 18:23:47 +02:00
}