Client LuaCsForBarotrauma
GUIPrefab.cs
1 #nullable enable
3 using Microsoft.Xna.Framework;
4 using Microsoft.Xna.Framework.Graphics;
5 using System;
6 using System.Collections.Generic;
7 using System.Collections.Immutable;
8 using System.Globalization;
9 using System.Linq;
10 using System.Xml.Linq;
11 
12 namespace Barotrauma
13 {
14  public abstract class GUIPrefab : Prefab
15  {
16  public GUIPrefab(ContentXElement element, UIStyleFile file) : base(file, element) { }
17 
18  protected override Identifier DetermineIdentifier(XElement element)
19  {
20  return element.NameAsIdentifier();
21  }
22 
23  protected int ParseSize(XElement element, string attributeName)
24  {
25  string valueStr = element.GetAttributeString(attributeName, string.Empty);
26  bool relativeToWidth = valueStr.EndsWith("vw");
27  bool relativeToHeight = valueStr.EndsWith("vh");
28  if (relativeToWidth || relativeToHeight)
29  {
30  string floatStr = valueStr.Substring(0, valueStr.Length - 2);
31  if (!float.TryParse(floatStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float relativeHeight))
32  {
33  DebugConsole.ThrowError($"Error while parsing a {nameof(GUIComponentStyle)}: {valueStr} is not a valid size.");
34  }
35  return (int)(relativeHeight / 100.0f * (relativeToWidth ? GameMain.GraphicsWidth : GameMain.GraphicsHeight));
36  }
37  else
38  {
39  return element.GetAttributeInt(attributeName, 0);
40  }
41  }
42  }
43 
44  public abstract class GUISelector<T> where T : GUIPrefab
45  {
46  public readonly PrefabSelector<T> Prefabs = new PrefabSelector<T>();
47  public readonly Identifier Identifier;
48 
49  public GUISelector(string identifier)
50  {
51  Identifier = identifier.ToIdentifier();
52  }
53  }
54 
55  public class GUIFontPrefab : GUIPrefab
56  {
57  private readonly ContentXElement element;
58  private ScalableFont? font;
60  {
61  get
62  {
63  if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
64  return font;
65  }
66  }
67 
68  private ImmutableDictionary<TextManager.SpeciallyHandledCharCategory, ScalableFont>? specialHandlingFonts;
69 
70  public ScalableFont? GetFontForCategory(TextManager.SpeciallyHandledCharCategory category)
71  {
72  if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
73  if (font is null) { return null; }
74  if (specialHandlingFonts is null) { return font; }
75  if (font.SpeciallyHandledCharCategory.HasFlag(category)) { return font; }
76  return specialHandlingFonts.TryGetValue(category, out var resultFont)
77  ? resultFont
78  : specialHandlingFonts.TryGetValue(TextManager.SpeciallyHandledCharCategory.CJK, out resultFont)
79  ? resultFont
80  : font;
81  }
82 
83  public LanguageIdentifier Language { get; private set; }
84 
85  public GUIFontPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
86  {
87  this.element = element;
88  LoadFont();
89  }
90 
91  public void LoadFont()
92  {
93  string? fontPath = GetFontFilePath(element);
94  uint size = GetFontSize(element);
95  bool dynamicLoading = GetFontDynamicLoading(element);
96  var shcc = GetShcc(element);
97  font?.Dispose();
98  specialHandlingFonts?.Values.ForEach(f => f.Dispose());
99  font = new ScalableFont(
100  fontPath,
101  size,
102  GameMain.Instance.GraphicsDevice,
103  dynamicLoading,
104  shcc)
105  {
106  ForceUpperCase = element.GetAttributeBool("forceuppercase", false)
107  };
108 
109  var fallbackFonts = new Dictionary<TextManager.SpeciallyHandledCharCategory, ScalableFont>();
110  foreach (var flag in TextManager.SpeciallyHandledCharCategories)
111  {
112  if (shcc.HasFlag(flag)) { continue; }
113 
114  var extractedFont = ExtractFont(flag, element);
115  if (extractedFont is null) { continue; }
116  fallbackFonts.Add(flag, extractedFont);
117  }
118  fallbackFonts.Values.ForEach(ff => ff.ForceUpperCase = font.ForceUpperCase);
119  specialHandlingFonts = fallbackFonts.ToImmutableDictionary();
120  Language = GameSettings.CurrentConfig.Language;
121  }
122 
123  public override void Dispose()
124  {
125  font?.Dispose();
126  font = null;
127  specialHandlingFonts?.Values.ForEach(f => f.Dispose());
128  specialHandlingFonts = null;
129  }
130 
131  private ScalableFont? ExtractFont(TextManager.SpeciallyHandledCharCategory flag, ContentXElement element)
132  {
133  foreach (var subElement in element.Elements().Reverse())
134  {
135  if (subElement.NameAsIdentifier() != "override") { continue; }
136  if (ScalableFont.ExtractShccFromXElement(subElement).HasFlag(flag))
137  {
138  uint overrideFontSize = GetFontSize(subElement, defaultSize: font?.Size ?? 14);
139  return new ScalableFont(subElement, overrideFontSize, GameMain.Instance.GraphicsDevice);
140  }
141  }
142 
143  ScalableFont hardcodedFallback(string path)
144  => new ScalableFont(
145  path,
146  font?.Size ?? 0,
147  GameMain.Instance.GraphicsDevice,
148  dynamicLoading: true,
149  speciallyHandledCharCategory: flag);
150 
151  return flag switch
152  {
153  TextManager.SpeciallyHandledCharCategory.CJK
154  => hardcodedFallback("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf"),
155  TextManager.SpeciallyHandledCharCategory.Cyrillic
156  => hardcodedFallback("Content/Fonts/Oswald-Bold.ttf"),
157  _ => null
158  };
159  }
160 
161  private string? GetFontFilePath(ContentXElement element)
162  {
163  foreach (var subElement in element.Elements())
164  {
165  if (IsValidOverride(subElement))
166  {
167  return subElement.GetAttributeContentPath("file")?.Value;
168  }
169  }
170  return element.GetAttributeContentPath("file")?.Value;
171  }
172 
173  private uint GetFontSize(XElement element, uint defaultSize = 14)
174  {
175  //check if any of the language override fonts want to override the font size as well
176  foreach (var subElement in element.Elements())
177  {
178  if (IsValidOverride(subElement))
179  {
180  uint overrideFontSize = GetFontSize(subElement, 0);
181  if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.CurrentConfig.Graphics.TextScale); }
182  }
183  }
184 
185  foreach (var subElement in element.Elements())
186  {
187  if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
188  Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
189  if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
190  {
191  int rawSize = ParseSize(subElement, "size");
192  return (uint)Math.Round(rawSize * GameSettings.CurrentConfig.Graphics.TextScale);
193  }
194  }
195  return (uint)Math.Round(defaultSize * GameSettings.CurrentConfig.Graphics.TextScale);
196  }
197 
198  private bool GetFontDynamicLoading(XElement element)
199  {
200  foreach (var subElement in element.Elements())
201  {
202  if (IsValidOverride(subElement))
203  {
204  return subElement.GetAttributeBool("dynamicloading", false);
205  }
206  }
207  return element.GetAttributeBool("dynamicloading", false);
208  }
209 
210  private TextManager.SpeciallyHandledCharCategory GetShcc(XElement element)
211  {
212  foreach (var subElement in element.Elements())
213  {
214  if (IsValidOverride(subElement))
215  {
216  return ScalableFont.ExtractShccFromXElement(subElement);
217  }
218  }
219  return ScalableFont.ExtractShccFromXElement(element);
220  }
221 
222  private bool IsValidOverride(XElement element)
223  {
224  if (!element.IsOverride()) { return false; }
225  var languages = element.GetAttributeIdentifierArray("language", Array.Empty<Identifier>());
226  return languages.Any(l => l.ToLanguageIdentifier() == GameSettings.CurrentConfig.Language);
227  }
228  }
229 
230  public class GUIFont : GUISelector<GUIFontPrefab>
231  {
232  public GUIFont(string identifier) : base(identifier) { }
233 
234  public bool HasValue => Value is not null;
235 
236  public ScalableFont? Value => Prefabs.ActivePrefab?.Font;
237 
238  public static implicit operator ScalableFont?(GUIFont reference) => reference.Value;
239 
240  public bool ForceUpperCase => Prefabs.ActivePrefab?.Font is { ForceUpperCase: true };
241 
242  public uint Size => Value?.Size ?? 0;
243 
244  private ScalableFont? GetFontForStr(LocalizedString str) => GetFontForStr(str.Value);
245 
246  public ScalableFont? GetFontForStr(string str) =>
247  Prefabs.ActivePrefab?.GetFontForCategory(TextManager.GetSpeciallyHandledCategories(str));
248 
249  public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
250  {
251  DrawString(sb, text.Value, position, color, rotation, origin, scale, spriteEffects, layerDepth);
252  }
253 
254  public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
255  {
256  GetFontForStr(text)?.DrawString(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth);
257  }
258 
259  public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment = Alignment.TopLeft)
260  {
261  DrawString(sb, text.Value, position, color, rotation, origin, scale, spriteEffects, layerDepth, alignment);
262  }
263 
264  public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
265  {
266  GetFontForStr(text)?.DrawString(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth, alignment, forceUpperCase);
267  }
268 
269  public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
270  {
271  DrawString(sb, text.Value, position, color, forceUpperCase, italics);
272  }
273 
274  public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
275  {
276  GetFontForStr(text)?.DrawString(sb, text, position, color, forceUpperCase, italics);
277  }
278 
279  public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
280  {
281  GetFontForStr(text)?.DrawStringWithColors(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
282  }
283 
284  public Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing = false)
285  {
286  return GetFontForStr(str)?.MeasureString(str, removeExtraSpacing) ?? Vector2.Zero;
287  }
288 
289  public Vector2 MeasureChar(char c)
290  {
291  return GetFontForStr($"{c}")?.MeasureChar(c) ?? Vector2.Zero;
292  }
293 
294  public string WrapText(string text, float width)
295  => GetFontForStr(text)?.WrapText(text, width) ?? text;
296 
297  public string WrapText(string text, float width, int requestCharPos, out Vector2 requestedCharPos)
298  {
299  requestedCharPos = default;
300  return GetFontForStr(text)?.WrapText(text, width, requestCharPos, out requestedCharPos) ?? text;
301  }
302 
303  public string WrapText(string text, float width, out Vector2[] allCharPositions)
304  {
305  var scalableFont = GetFontForStr(text);
306  if (scalableFont != null)
307  {
308  return scalableFont.WrapText(text, width, out allCharPositions);
309  }
310 
311  allCharPositions = Enumerable.Range(0, text.Length + 1).Select(_ => Vector2.Zero).ToArray();
312  return text;
313  }
314 
315  public float LineHeight => Value?.LineHeight ?? 0;
316  }
317 
318  public class GUIColorPrefab : GUIPrefab
319  {
320  public readonly Color Color;
321 
322  public GUIColorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
323  {
324  Color = element.GetAttributeColor("color", Color.White);
325  }
326 
327  public override void Dispose() { }
328  }
329 
330  public class GUIColor : GUISelector<GUIColorPrefab>
331  {
332  private readonly Color fallbackColor;
333 
334  public GUIColor(string identifier, Color fallbackColor) : base(identifier)
335  {
336  this.fallbackColor = fallbackColor;
337  }
338 
339  public Color Value
340  {
341  get
342  {
343  return Prefabs?.ActivePrefab?.Color ?? fallbackColor;
344  }
345  }
346 
347  public static implicit operator Color(GUIColor reference) => reference.Value;
348 
349  public static Color operator*(GUIColor value, float scale)
350  {
351  return value.Value * scale;
352  }
353  }
354 
355  public class GUISpritePrefab : GUIPrefab
356  {
357  public readonly UISprite Sprite;
358 
359  public GUISpritePrefab(ContentXElement element, UIStyleFile file) : base(element, file)
360  {
361  Sprite = new UISprite(element);
362  }
363 
364  public override void Dispose()
365  {
366  Sprite.Sprite.Remove();
367  }
368  }
369 
370  public class GUISprite : GUISelector<GUISpritePrefab>
371  {
372  public GUISprite(string identifier) : base(identifier) { }
373 
374  public UISprite? Value
375  {
376  get
377  {
378  return Prefabs.ActivePrefab?.Sprite;
379  }
380  }
381 
382  public static implicit operator UISprite?(GUISprite reference) => reference.Value;
383 
384  public void Draw(SpriteBatch spriteBatch, RectangleF rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None)
385  {
386  Value?.Draw(spriteBatch, rect, color, spriteEffects);
387  }
388 
389  public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None)
390  {
391  Value?.Draw(spriteBatch, rect, color, spriteEffects);
392  }
393  }
394 
396  {
397  public readonly SpriteSheet SpriteSheet;
398 
399  public GUISpriteSheetPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
400  {
401  SpriteSheet = new SpriteSheet(element);
402  }
403 
404  public override void Dispose()
405  {
407  }
408  }
409 
410  public class GUISpriteSheet : GUISelector<GUISpriteSheetPrefab>
411  {
412  public GUISpriteSheet(string identifier) : base(identifier) { }
413 
414  public SpriteSheet? Value
415  {
416  get
417  {
418  return Prefabs.ActivePrefab?.SpriteSheet;
419  }
420  }
421 
422  public int FrameCount => Value?.FrameCount ?? 1;
423  public Point FrameSize => Value?.FrameSize ?? Point.Zero;
424 
425  public void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None)
426  {
427  Value?.Draw(spriteBatch, pos, rotate, scale, spriteEffects);
428  }
429 
430  public void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
431  {
432  Value?.Draw(spriteBatch, pos, color, origin, rotate, scale, spriteEffects, depth);
433  }
434 
435  public void Draw(ISpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
436  {
437  Value?.Draw(spriteBatch, spriteIndex, pos, color, origin, rotate, scale, spriteEffects, depth);
438  }
439 
440  public static implicit operator SpriteSheet?(GUISpriteSheet reference) => reference.Value;
441  }
442 
443  public class GUICursorPrefab : GUIPrefab
444  {
445  public readonly Sprite[] Sprites;
446 
447  public GUICursorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
448  {
449  Sprites = new Sprite[Enum.GetValues(typeof(CursorState)).Length];
450  foreach (var subElement in element.Elements())
451  {
452  CursorState state = subElement.GetAttributeEnum("state", CursorState.Default);
453  Sprites[(int)state] = new Sprite(subElement);
454  }
455  }
456 
457  public override void Dispose()
458  {
459  foreach (var sprite in Sprites)
460  {
461  sprite?.Remove();
462  }
463  }
464  }
465 
466  public class GUICursor : GUISelector<GUICursorPrefab>
467  {
468  public GUICursor(string identifier) : base(identifier) { }
469 
470  public Sprite? this[CursorState k] => Prefabs.ActivePrefab?.Sprites[(int)k];
471  }
472 }
Color GetAttributeColor(string key, in Color def)
IEnumerable< ContentXElement > Elements()
GUIColor(string identifier, Color fallbackColor)
Definition: GUIPrefab.cs:334
static Color operator*(GUIColor value, float scale)
Definition: GUIPrefab.cs:349
readonly Color Color
Definition: GUIPrefab.cs:320
GUIColorPrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:322
override void Dispose()
Definition: GUIPrefab.cs:327
GUICursor(string identifier)
Definition: GUIPrefab.cs:468
readonly Sprite[] Sprites
Definition: GUIPrefab.cs:445
override void Dispose()
Definition: GUIPrefab.cs:457
GUICursorPrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:447
void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
Definition: GUIPrefab.cs:254
Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing=false)
Definition: GUIPrefab.cs:284
void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, ForceUpperCase forceUpperCase=Barotrauma.ForceUpperCase.Inherit, bool italics=false)
Definition: GUIPrefab.cs:274
ScalableFont? GetFontForStr(string str)
ScalableFont? Value
Definition: GUIPrefab.cs:236
string WrapText(string text, float width)
string WrapText(string text, float width, out Vector2[] allCharPositions)
Definition: GUIPrefab.cs:303
void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, ForceUpperCase forceUpperCase=Barotrauma.ForceUpperCase.Inherit, bool italics=false)
Definition: GUIPrefab.cs:269
string WrapText(string text, float width, int requestCharPos, out Vector2 requestedCharPos)
Definition: GUIPrefab.cs:297
Vector2 MeasureChar(char c)
Definition: GUIPrefab.cs:289
void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment=Alignment.TopLeft)
Definition: GUIPrefab.cs:259
GUIFont(string identifier)
Definition: GUIPrefab.cs:232
void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, in ImmutableArray< RichTextData >? richTextData, int rtdOffset=0, Alignment alignment=Alignment.TopLeft, ForceUpperCase forceUpperCase=Barotrauma.ForceUpperCase.Inherit)
Definition: GUIPrefab.cs:279
void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment=Alignment.TopLeft, ForceUpperCase forceUpperCase=Barotrauma.ForceUpperCase.Inherit)
Definition: GUIPrefab.cs:264
void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
Definition: GUIPrefab.cs:249
GUIFontPrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:85
ScalableFont? GetFontForCategory(TextManager.SpeciallyHandledCharCategory category)
Definition: GUIPrefab.cs:70
ScalableFont? Font
Definition: GUIPrefab.cs:60
LanguageIdentifier Language
Definition: GUIPrefab.cs:83
override void Dispose()
Definition: GUIPrefab.cs:123
override Identifier DetermineIdentifier(XElement element)
Definition: GUIPrefab.cs:18
GUIPrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:16
int ParseSize(XElement element, string attributeName)
Definition: GUIPrefab.cs:23
readonly Identifier Identifier
Definition: GUIPrefab.cs:47
readonly PrefabSelector< T > Prefabs
Definition: GUIPrefab.cs:46
GUISelector(string identifier)
Definition: GUIPrefab.cs:49
void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects=SpriteEffects.None)
Definition: GUIPrefab.cs:389
GUISprite(string identifier)
Definition: GUIPrefab.cs:372
GUISpritePrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:359
override void Dispose()
Definition: GUIPrefab.cs:364
readonly UISprite Sprite
Definition: GUIPrefab.cs:357
void Draw(ISpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffects=SpriteEffects.None, float? depth=null)
Definition: GUIPrefab.cs:435
void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate=0, float scale=1, SpriteEffects spriteEffects=SpriteEffects.None)
Definition: GUIPrefab.cs:425
GUISpriteSheet(string identifier)
Definition: GUIPrefab.cs:412
void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate=0, float scale=1, SpriteEffects spriteEffects=SpriteEffects.None, float? depth=null)
Definition: GUIPrefab.cs:430
readonly SpriteSheet SpriteSheet
Definition: GUIPrefab.cs:397
GUISpriteSheetPrefab(ContentXElement element, UIStyleFile file)
Definition: GUIPrefab.cs:399
static int GraphicsWidth
Definition: GameMain.cs:162
static int GraphicsHeight
Definition: GameMain.cs:168
static GameMain Instance
Definition: GameMain.cs:144
readonly Identifier Identifier
Definition: Prefab.cs:34
TextManager.SpeciallyHandledCharCategory SpeciallyHandledCharCategory
Definition: ScalableFont.cs:42
Sprite(ContentXElement element, string path="", string file="", bool lazyLoad=false, float sourceRectScale=1)
SpriteSheet(ContentXElement element, string path="", string file="")
void Draw(SpriteBatch spriteBatch, RectangleF rect, Color color, SpriteEffects spriteEffects=SpriteEffects.None, Vector2? uvOffset=null)
CursorState
Definition: GUI.cs:40