2using System.Collections.Generic;
3using System.Diagnostics;
5using System.Reflection;
6using System.Diagnostics;
7using System.Runtime.CompilerServices;
9using System.Globalization;
11using Microsoft.Xna.Framework;
12using Microsoft.Xna.Framework.Input;
13using Microsoft.Xna.Framework.Graphics;
19 public static partial class CUIExtensions
21 static CUIExtensions()
23 CUI.OnDispose += () =>
26 CustomToString.Clear();
30 public static Dictionary<Type, MethodInfo> Parse =
new()
32 [typeof(
string)] = typeof(CUIExtensions).GetMethod(
"ParseString"),
33 [typeof(Rectangle)] = typeof(CUIExtensions).GetMethod(
"ParseRectangle"),
34 [typeof(GUIFont)] = typeof(CUIExtensions).GetMethod(
"ParseGUIFont"),
35 [typeof(Vector2?)] = typeof(CUIExtensions).GetMethod(
"ParseNullVector2"),
36 [typeof(Vector2)] = typeof(CUIExtensions).GetMethod(
"ParseVector2"),
37 [typeof(SpriteEffects)] = typeof(CUIExtensions).GetMethod(
"ParseSpriteEffects"),
38 [typeof(Color)] = typeof(CUIExtensions).GetMethod(
"ParseColor"),
39 [typeof(
int?)] = typeof(CUIExtensions).GetMethod(
"ParseNullInt"),
40 [typeof(IEnumerable<string>)] = typeof(CUIExtensions).GetMethod(
"ParseIEnumerableString"),
42 public static Dictionary<Type, MethodInfo> CustomToString =
new()
44 [typeof(IEnumerable<string>)] = typeof(CUIExtensions).GetMethod(
"IEnumerableStringToString"),
45 [typeof(
int?)] = typeof(CUIExtensions).GetMethod(
"NullIntToString"),
46 [typeof(Color)] = typeof(CUIExtensions).GetMethod(
"ColorToString"),
47 [typeof(SpriteEffects)] = typeof(CUIExtensions).GetMethod(
"SpriteEffectsToString"),
48 [typeof(Vector2)] = typeof(CUIExtensions).GetMethod(
"Vector2ToString"),
49 [typeof(Vector2?)] = typeof(CUIExtensions).GetMethod(
"NullVector2ToString"),
50 [typeof(GUIFont)] = typeof(CUIExtensions).GetMethod(
"GUIFontToString"),
51 [typeof(Rectangle)] = typeof(CUIExtensions).GetMethod(
"RectangleToString"),
55 public static int Fit(
this int i,
int bottom,
int top) => Math.Max(bottom, Math.Min(i, top));
56 public static Vector2 Rotate(
this Vector2 v,
float angle) => Vector2.Transform(v, Matrix.CreateRotationZ(angle));
57 public static string SubstringSafe(
this string s,
int start)
61 int safeStart = start.Fit(0, s.Length);
62 return s.Substring(safeStart, s.Length - safeStart);
66 CUI.Log($
"SubstringSafe {e}");
70 public static string SubstringSafe(
this string s,
int start,
int length)
72 int end = (start + length).Fit(0, s.Length);
73 int safeStart = start.Fit(0, s.Length);
74 int safeLength = end - safeStart;
77 return s.Substring(safeStart, safeLength);
81 CUI.Log($
"SubstringSafe {e.Message}\ns:\"{s}\" start: {start}->{safeStart} end: {end} length: {length}->{safeLength} ", Color.Orange);
86 public static Dictionary<string, string> ParseKVPairs(
string raw)
88 Dictionary<string, string> props =
new();
90 if (raw ==
null || raw ==
"")
return props;
92 string content = raw.Split(
'{',
'}')[1];
94 List<string> expressions =
new();
98 for (
int i = 0; i < content.Length; i++)
102 if (c ==
'[' || c ==
'{') depth++;
103 if (c ==
']' || c ==
'}') depth--;
105 if (depth <= 0 && c ==
',')
107 expressions.Add(content.Substring(start, end - start));
111 expressions.Add(content.Substring(start, end - start));
113 var pairs = expressions.Select(s => s.Split(
':').Select(sub => sub.Trim()).ToArray());
115 foreach (var pair
in pairs) { props[pair[0].ToLower()] = pair[1]; }
119 public static string ColorToString(Color c) => $
"{c.R},{c.G},{c.B},{c.A}";
120 public static string Vector2ToString(Vector2 v) => $
"[{v.X},{v.Y}]";
121 public static string NullVector2ToString(Vector2? v) => v.HasValue ? $
"[{v.Value.X},{v.Value.Y}]" :
"null";
122 public static string NullIntToString(
int? i) => i.HasValue ? $
"{i}" :
"null";
123 public static string RectangleToString(Rectangle r) => $
"[{r.X},{r.Y},{r.Width},{r.Height}]";
124 public static string GUIFontToString(GUIFont f) => f.Identifier.Value;
125 public static string SpriteEffectsToString(SpriteEffects e)
127 if ((
int)e == 3)
return "FlipBothSides";
128 else return e.ToString();
131 public static string IEnumerableStringToString(IEnumerable<string> e) => $
"[{string.Join(',', e.ToArray())}]";
133 public static IEnumerable<string> ParseIEnumerableString(
string raw)
135 if (raw ==
null || raw ==
"")
return new List<string>();
136 string content = raw.Split(
'[',
']')[1];
137 return content.Split(
',');
140 public static string ParseString(
string s) => s;
143 public static GUIFont ParseGUIFont(
string raw)
145 GUIFont font = GUIStyle.Fonts.GetValueOrDefault(
new Identifier(raw.Trim()));
146 font ??= GUIStyle.Font;
150 public static SpriteEffects ParseSpriteEffects(
string raw)
152 if (raw ==
"FlipBothSides")
return SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically;
153 else return Enum.Parse<SpriteEffects>(raw);
157 public static int? ParseNullInt(
string raw)
159 if (raw ==
"null")
return null;
160 return int.Parse(raw);
162 public static Vector2? ParseNullVector2(
string raw)
164 if (raw ==
"null")
return null;
165 return ParseVector2(raw);
168 public static Vector2 ParseVector2(
string raw)
170 if (raw ==
null || raw ==
"")
return new Vector2(0, 0);
172 string content = raw.Split(
'[',
']')[1];
174 List<string> coords = content.Split(
',').Select(s => s.Trim()).ToList();
179 float.TryParse(coords.ElementAtOrDefault(0), out x);
180 float.TryParse(coords.ElementAtOrDefault(1), out y);
182 return new Vector2(x, y);
185 public static Rectangle ParseRectangle(
string raw)
187 if (raw ==
null || raw ==
"")
return new Rectangle(0, 0, 1, 1);
189 string content = raw.Split(
'[',
']')[1];
191 List<string> coords = content.Split(
',').Select(s => s.Trim()).ToList();
198 int.TryParse(coords.ElementAtOrDefault(0), out x);
199 int.TryParse(coords.ElementAtOrDefault(1), out y);
200 int.TryParse(coords.ElementAtOrDefault(2), out w);
201 int.TryParse(coords.ElementAtOrDefault(3), out h);
203 return new Rectangle(x, y, w, h);
207 public static Color ParseColor(
string s) => XMLExtensions.ParseColor(s,
false);