Client LuaCsForBarotrauma
UISprite.cs
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3 using System;
4 using System.Xml.Linq;
5 
6 namespace Barotrauma
7 {
8  public class UISprite
9  {
10  public Sprite Sprite
11  {
12  get;
13  private set;
14  }
15 
16  public bool Tile
17  {
18  get;
19  private set;
20  }
21 
22  public bool Slice => Slices != null;
23 
24  public Rectangle[] Slices
25  {
26  get;
27  set;
28  }
29 
33  public Point NonSliceSize { get; set; }
34 
35  public bool MaintainAspectRatio
36  {
37  get;
38  private set;
39  }
40 
42  {
43  get;
44  private set;
45  }
46 
51  private readonly float minBorderScale = 0.1f, maxBorderScale = 10.0f;
52 
53  public bool CrossFadeIn { get; private set; } = true;
54  public bool CrossFadeOut { get; private set; } = true;
55 
56  public TransitionMode TransitionMode { get; private set; }
57 
58  public UISprite(ContentXElement element)
59  {
60  Sprite = new Sprite(element);
61  MaintainAspectRatio = element.GetAttributeBool("maintainaspectratio", false);
62  MaintainBorderAspectRatio = element.GetAttributeBool("maintainborderaspectratio", false);
63  Tile = element.GetAttributeBool("tile", true);
64  CrossFadeIn = element.GetAttributeBool("crossfadein", CrossFadeIn);
65  CrossFadeOut = element.GetAttributeBool("crossfadeout", CrossFadeOut);
66  string transitionMode = element.GetAttributeString("transition", string.Empty);
67  if (Enum.TryParse(transitionMode, ignoreCase: true, out TransitionMode transition))
68  {
69  TransitionMode = transition;
70  }
71 
72  Vector4 sliceVec = element.GetAttributeVector4("slice", Vector4.Zero);
73  Slices = null;
74  if (sliceVec != Vector4.Zero)
75  {
76  minBorderScale = element.GetAttributeFloat("minborderscale", 0.1f);
77  maxBorderScale = element.GetAttributeFloat("minborderscale", 10.0f);
78 
79  Rectangle slice = new Rectangle((int)sliceVec.X, (int)sliceVec.Y, (int)(sliceVec.Z - sliceVec.X), (int)(sliceVec.W - sliceVec.Y));
80  NonSliceSize = new Point(Sprite.SourceRect.Width - slice.Width, Sprite.SourceRect.Height - slice.Height);
81 
82  Slices = new Rectangle[9];
83 
84  //top-left
85  Slices[0] = new Rectangle(Sprite.SourceRect.Location, slice.Location - Sprite.SourceRect.Location);
86  //top-mid
87  Slices[1] = new Rectangle(slice.Location.X, Slices[0].Y, slice.Width, Slices[0].Height);
88  //top-right
89  Slices[2] = new Rectangle(slice.Right, Slices[0].Y, Sprite.SourceRect.Right - slice.Right, Slices[0].Height);
90 
91  //mid-left
92  Slices[3] = new Rectangle(Slices[0].X, slice.Y, Slices[0].Width, slice.Height);
93  //center
94  Slices[4] = slice;
95  //mid-right
96  Slices[5] = new Rectangle(Slices[2].X, slice.Y, Slices[2].Width, slice.Height);
97 
98  //bottom-left
99  Slices[6] = new Rectangle(Slices[0].X, slice.Bottom, Slices[0].Width, Sprite.SourceRect.Bottom - slice.Bottom);
100  //bottom-mid
101  Slices[7] = new Rectangle(Slices[1].X, slice.Bottom, Slices[1].Width, Sprite.SourceRect.Bottom - slice.Bottom);
102  //bottom-right
103  Slices[8] = new Rectangle(Slices[2].X, slice.Bottom, Slices[2].Width, Sprite.SourceRect.Bottom - slice.Bottom);
104  }
105  }
106 
110  public float GetSliceBorderScale(Point drawSize)
111  {
112  if (!Slice) { return 1.0f; }
113 
114  Vector2 scale = new Vector2(
115  MathHelper.Clamp((float)drawSize.X / (Slices[0].Height + Slices[6].Height), 0, 1),
116  MathHelper.Clamp((float)drawSize.Y / (Slices[0].Width + Slices[2].Width), 0, 1));
117  return MathHelper.Clamp(Math.Min(Math.Min(scale.X, scale.Y), GUI.SlicedSpriteScale), minBorderScale, maxBorderScale);
118  }
119 
120  public void Draw(SpriteBatch spriteBatch, RectangleF rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None, Vector2? uvOffset = null)
121  => Draw(spriteBatch, new Rectangle(rect.Location.ToPoint(), rect.Size.ToPoint()), color, spriteEffects, uvOffset);
122 
123  public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None, Vector2? uvOffset = null)
124  {
125  uvOffset ??= Vector2.Zero;
126  if (Sprite.Texture == null)
127  {
128  GUI.DrawRectangle(spriteBatch, rect, Color.Magenta);
129  return;
130  }
131 
132  if (Slice)
133  {
134  Vector2 pos = new Vector2(rect.X, rect.Y);
135 
136  float scale = MaintainBorderAspectRatio ? 1.0f : GetSliceBorderScale(rect.Size);
137  float aspectScale = MaintainBorderAspectRatio ? Math.Min((float)rect.Width / Sprite.SourceRect.Width, (float)rect.Height / Sprite.SourceRect.Height) : 1.0f;
138 
139  int centerHeight = rect.Height - (int)((Slices[0].Height + Slices[6].Height) * scale);
140  int centerWidth = rect.Width - (int)((Slices[0].Width + Slices[2].Width) * scale * aspectScale);
141 
142  for (int x = 0; x < 3; x++)
143  {
144 
145  int width = (int)(x == 1 ? centerWidth : Slices[x].Width * scale * aspectScale);
146  if (width <= 0) { continue; }
147  for (int y = 0; y < 3; y++)
148  {
149  int height = (int)(y == 1 ? centerHeight : Slices[x + y * 3].Height * scale);
150  if (height <= 0) { continue; }
151 
152  spriteBatch.Draw(Sprite.Texture,
153  new Rectangle((int)pos.X, (int)pos.Y, width, height),
154  Slices[x + y * 3],
155  color);
156 
157  pos.Y += height;
158  }
159  pos.X += width;
160  pos.Y = rect.Y;
161  }
162  }
163  else if (Tile)
164  {
165  Vector2 startPos = new Vector2(rect.X, rect.Y);
166  Sprite.DrawTiled(spriteBatch, startPos, new Vector2(rect.Width, rect.Height), color: color, startOffset: uvOffset);
167  }
168  else
169  {
171  {
172  float scale = Math.Min((float)rect.Width / Sprite.SourceRect.Width, (float)rect.Height / Sprite.SourceRect.Height);
173 
174  spriteBatch.Draw(Sprite.Texture, rect.Center.ToVector2(),
176  color,
177  rotation: 0.0f,
178  origin: Sprite.size / 2.0f,
179  scale: scale,
180  effects: spriteEffects, layerDepth: 0.0f);
181  }
182  else
183  {
184  spriteBatch.Draw(Sprite.Texture, rect, Sprite.SourceRect, color, 0, Vector2.Zero, spriteEffects, 0);
185  }
186  }
187  }
188  }
189 }
string? GetAttributeString(string key, string? def)
Vector4 GetAttributeVector4(string key, in Vector4 def)
float GetAttributeFloat(string key, float def)
bool GetAttributeBool(string key, bool def)
void DrawTiled(ISpriteBatch spriteBatch, Vector2 position, Vector2 targetSize, float rotation=0f, Vector2? origin=null, Color? color=null, Vector2? startOffset=null, Vector2? textureScale=null, float? depth=null, SpriteEffects? spriteEffects=null)
Point NonSliceSize
The size of fixed area around the slice area
Definition: UISprite.cs:33
UISprite(ContentXElement element)
Definition: UISprite.cs:58
bool MaintainBorderAspectRatio
Definition: UISprite.cs:42
bool MaintainAspectRatio
Definition: UISprite.cs:36
Rectangle[] Slices
Definition: UISprite.cs:25
float GetSliceBorderScale(Point drawSize)
Get the scale of the sliced sprite's borders when it's draw inside an area of a specific size
Definition: UISprite.cs:110
void Draw(SpriteBatch spriteBatch, RectangleF rect, Color color, SpriteEffects spriteEffects=SpriteEffects.None, Vector2? uvOffset=null)
void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects=SpriteEffects.None, Vector2? uvOffset=null)
Definition: UISprite.cs:123
TransitionMode
Definition: Enums.cs:6