diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0183c8c..bfae87c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,10 @@ Additions
- Added Zero, One, Linear and Clamp to Easings
- Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom
- Added the ability to draw single corners of AutoTiling's extended auto tiles
+- Added ColorHelper.TryFromHexString, a non-throwing version of FromHexString
+
+Improvements
+- Stopped the text formatter throwing if a color can't be parsed
Fixes
- Fixed TextInput not working correctly when using surrogate pairs
diff --git a/MLEM.Extended/Tiled/TiledExtensions.cs b/MLEM.Extended/Tiled/TiledExtensions.cs
index b933636..cb1d575 100644
--- a/MLEM.Extended/Tiled/TiledExtensions.cs
+++ b/MLEM.Extended/Tiled/TiledExtensions.cs
@@ -44,7 +44,8 @@ namespace MLEM.Extended.Tiled {
/// The key by which to get a property
/// The color property
public static Color GetColor(this TiledMapProperties properties, string key) {
- return ColorHelper.FromHexString(properties.Get(key));
+ ColorHelper.TryFromHexString(properties.Get(key), out var val);
+ return val;
}
///
diff --git a/MLEM/Extensions/ColorExtensions.cs b/MLEM/Extensions/ColorExtensions.cs
index 05b66f2..2ac4b9a 100644
--- a/MLEM/Extensions/ColorExtensions.cs
+++ b/MLEM/Extensions/ColorExtensions.cs
@@ -1,3 +1,4 @@
+using System;
using System.Globalization;
using Microsoft.Xna.Framework;
@@ -64,16 +65,34 @@ namespace MLEM.Extensions {
}
///
- /// Parses a hexadecimal string into a color.
+ /// Parses a hexadecimal string into a color and throws a if parsing fails.
/// The string can either be formatted as RRGGBB or AARRGGBB and can optionally start with a #.
///
/// The string to parse.
/// The resulting color.
+ /// Thrown if parsing fails.
public static Color FromHexString(string value) {
+ if (!ColorHelper.TryFromHexString(value, out var val))
+ throw new FormatException($"Cannot parse hex string {value}");
+ return val;
+ }
+
+ ///
+ /// Tries to parse a hexadecimal string into a color and returns whether a color was successfully parsed.
+ /// The string can either be formatted as RRGGBB or AARRGGBB and can optionally start with a #.
+ ///
+ /// The string to parse.
+ /// The resulting color.
+ /// Whether parsing was successful.
+ public static bool TryFromHexString(string value, out Color color) {
if (value.StartsWith("#"))
value = value.Substring(1);
- var val = int.Parse(value, NumberStyles.HexNumber);
- return value.Length > 6 ? ColorHelper.FromHexRgba(val) : ColorHelper.FromHexRgb(val);
+ 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;
}
}
diff --git a/MLEM/Formatting/TextFormatter.cs b/MLEM/Formatting/TextFormatter.cs
index f0789a7..1407572 100644
--- a/MLEM/Formatting/TextFormatter.cs
+++ b/MLEM/Formatting/TextFormatter.cs
@@ -102,7 +102,7 @@ namespace MLEM.Formatting {
this.Codes.Add(new Regex(""), (f, m, r) => new FontCode(m, r, fnt => fnt.Bold));
this.Codes.Add(new Regex(""), (f, m, r) => new FontCode(m, r, fnt => fnt.Italic));
this.Codes.Add(new Regex(@""), (f, m, r) => new ShadowCode(m, r,
- m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultShadowColor,
+ ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultShadowColor,
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var offset) ? new Vector2(offset) : this.DefaultShadowOffset));
this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.UnderlineOffset));
this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.StrikethroughOffset));
@@ -111,7 +111,7 @@ namespace MLEM.Formatting {
this.Codes.Add(new Regex(@""), (f, m, r) => new SubSupCode(m, r,
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var off) ? -off : this.DefaultSupOffset));
this.Codes.Add(new Regex(@""), (f, m, r) => new OutlineCode(m, r,
- m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultOutlineColor,
+ ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultOutlineColor,
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var thickness) ? thickness : this.DefaultOutlineThickness,
this.OutlineDiagonals));
}
@@ -124,12 +124,13 @@ namespace MLEM.Formatting {
this.Codes.Add(new Regex($""), (f, m, r) => new ColorCode(m, r, value));
}
}
- this.Codes.Add(new Regex(@""), (f, m, r) => new ColorCode(m, r, ColorHelper.FromHexString(m.Groups[1].Value)));
+ this.Codes.Add(new Regex(@""), (f, m, r) => new ColorCode(m, r,
+ ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : Color.Red));
}
// animation codes
if (hasAnimations) {
- this.Codes.Add(new Regex(@""), (f, m, r) => new WobblyCode(m, r,
+ this.Codes.Add(new Regex(""), (f, m, r) => new WobblyCode(m, r,
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var mod) ? mod : this.DefaultWobblyModifier,
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var heightMod) ? heightMod : this.DefaultWobblyHeight));
}