CrabUI
Loading...
Searching...
No Matches
CUIExtensions.cs
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Linq;
5using System.Reflection;
6using System.Diagnostics;
7using System.Runtime.CompilerServices;
8using System.IO;
9using System.Globalization;
10using Barotrauma;
11using Microsoft.Xna.Framework;
12using Microsoft.Xna.Framework.Input;
13using Microsoft.Xna.Framework.Graphics;
14using HarmonyLib;
15
16namespace CrabUI
17{
18 [CUIInternal]
19 public static partial class CUIExtensions
20 {
21 static CUIExtensions()
22 {
23 CUI.OnDispose += () =>
24 {
25 Parse.Clear();
26 CustomToString.Clear();
27 };
28 }
29
30 public static Dictionary<Type, MethodInfo> Parse = new()
31 {
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"),
41 };
42 public static Dictionary<Type, MethodInfo> CustomToString = new()
43 {
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"),
52 };
53
54
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)
58 {
59 try
60 {
61 int safeStart = start.Fit(0, s.Length);
62 return s.Substring(safeStart, s.Length - safeStart);
63 }
64 catch (Exception e)
65 {
66 CUI.Log($"SubstringSafe {e}");
67 return "";
68 }
69 }
70 public static string SubstringSafe(this string s, int start, int length)
71 {
72 int end = (start + length).Fit(0, s.Length);
73 int safeStart = start.Fit(0, s.Length);
74 int safeLength = end - safeStart;
75 try
76 {
77 return s.Substring(safeStart, safeLength);
78 }
79 catch (Exception e)
80 {
81 CUI.Log($"SubstringSafe {e.Message}\ns:\"{s}\" start: {start}->{safeStart} end: {end} length: {length}->{safeLength} ", Color.Orange);
82 return "";
83 }
84 }
85
86 public static Dictionary<string, string> ParseKVPairs(string raw)
87 {
88 Dictionary<string, string> props = new();
89
90 if (raw == null || raw == "") return props;
91
92 string content = raw.Split('{', '}')[1];
93
94 List<string> expressions = new();
95 int start = 0;
96 int end = 0;
97 int depth = 0;
98 for (int i = 0; i < content.Length; i++)
99 {
100 char c = content[i];
101 end = i;
102 if (c == '[' || c == '{') depth++;
103 if (c == ']' || c == '}') depth--;
104
105 if (depth <= 0 && c == ',')
106 {
107 expressions.Add(content.Substring(start, end - start));
108 start = end + 1;
109 }
110 }
111 expressions.Add(content.Substring(start, end - start));
112
113 var pairs = expressions.Select(s => s.Split(':').Select(sub => sub.Trim()).ToArray());
114
115 foreach (var pair in pairs) { props[pair[0].ToLower()] = pair[1]; }
116 return props;
117 }
118
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)
126 {
127 if ((int)e == 3) return "FlipBothSides";
128 else return e.ToString();
129 }
130
131 public static string IEnumerableStringToString(IEnumerable<string> e) => $"[{string.Join(',', e.ToArray())}]";
132
133 public static IEnumerable<string> ParseIEnumerableString(string raw)
134 {
135 if (raw == null || raw == "") return new List<string>();
136 string content = raw.Split('[', ']')[1];
137 return content.Split(',');
138 }
139
140 public static string ParseString(string s) => s; // BaroDev (wide)
141 //public static GUISoundType ParseGUISoundType(string s) => Enum.Parse<GUISoundType>(s);
142
143 public static GUIFont ParseGUIFont(string raw)
144 {
145 GUIFont font = GUIStyle.Fonts.GetValueOrDefault(new Identifier(raw.Trim()));
146 font ??= GUIStyle.Font;
147 return font;
148 }
149
150 public static SpriteEffects ParseSpriteEffects(string raw)
151 {
152 if (raw == "FlipBothSides") return SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically;
153 else return Enum.Parse<SpriteEffects>(raw);
154 }
155
156
157 public static int? ParseNullInt(string raw)
158 {
159 if (raw == "null") return null;
160 return int.Parse(raw);
161 }
162 public static Vector2? ParseNullVector2(string raw)
163 {
164 if (raw == "null") return null;
165 return ParseVector2(raw);
166 }
167
168 public static Vector2 ParseVector2(string raw)
169 {
170 if (raw == null || raw == "") return new Vector2(0, 0);
171
172 string content = raw.Split('[', ']')[1];
173
174 List<string> coords = content.Split(',').Select(s => s.Trim()).ToList();
175
176 float x = 0;
177 float y = 0;
178
179 float.TryParse(coords.ElementAtOrDefault(0), out x);
180 float.TryParse(coords.ElementAtOrDefault(1), out y);
181
182 return new Vector2(x, y);
183 }
184
185 public static Rectangle ParseRectangle(string raw)
186 {
187 if (raw == null || raw == "") return new Rectangle(0, 0, 1, 1);
188
189 string content = raw.Split('[', ']')[1];
190
191 List<string> coords = content.Split(',').Select(s => s.Trim()).ToList();
192
193 int x = 0;
194 int y = 0;
195 int w = 0;
196 int h = 0;
197
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);
202
203 return new Rectangle(x, y, w, h);
204 }
205
206
207 public static Color ParseColor(string s) => XMLExtensions.ParseColor(s, false);
208 }
209}