Client LuaCsForBarotrauma
GUIProgressBar.cs
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3 using System;
4 using System.Linq;
5 
6 namespace Barotrauma
7 {
8  public class GUIProgressBar : GUIComponent
9  {
10  private bool isHorizontal;
11  private readonly GUIFrame frame, slider;
12  private float barSize;
13  private readonly bool showFrame;
14 
15  public delegate float ProgressGetterHandler();
17 
18  public bool IsHorizontal
19  {
20  get { return isHorizontal; }
21  set { isHorizontal = value; }
22  }
23 
24  public float BarSize
25  {
26  get { return barSize; }
27  set
28  {
29  if (!MathUtils.IsValid(value))
30  {
31  GameAnalyticsManager.AddErrorEventOnce(
32  "GUIProgressBar.BarSize_setter",
33  GameAnalyticsManager.ErrorSeverity.Error,
34  "Attempted to set the BarSize of a GUIProgressBar to an invalid value (" + value + ")\n" + Environment.StackTrace.CleanupStackTrace());
35  return;
36  }
37  barSize = MathHelper.Clamp(value, 0.0f, 1.0f);
38  //UpdateRect();
39  }
40  }
41 
42  public GUIProgressBar(RectTransform rectT, float barSize, Color? color = null, string style = "", bool showFrame = true) : base(style, rectT)
43  {
44  if (color.HasValue)
45  {
46  this.color = color.Value;
47  }
48  isHorizontal = (Rect.Width > Rect.Height);
49  frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
50  GUIStyle.Apply(frame, "", this);
51  slider = new GUIFrame(new RectTransform(Vector2.One, rectT));
52  GUIStyle.Apply(slider, "Slider", this);
53  this.showFrame = showFrame;
54  this.barSize = barSize;
55  Enabled = true;
56  }
57 
62  public Rectangle GetSliderRect(float fillAmount)
63  {
64  Rectangle sliderArea = new Rectangle(
65  frame.Rect.X + (int)Style.Padding.X,
66  frame.Rect.Y + (int)Style.Padding.Y,
67  (int)(frame.Rect.Width - Style.Padding.X - Style.Padding.Z),
68  (int)(frame.Rect.Height - Style.Padding.Y - Style.Padding.W));
69 
70  Vector4 sliceBorderSizes = Vector4.Zero;
71  if (slider.sprites.ContainsKey(slider.State) && (slider.sprites[slider.State].First()?.Slice ?? false))
72  {
73  var slices = slider.sprites[slider.State].First().Slices;
74  sliceBorderSizes = new Vector4(slices[0].Width, slices[0].Height, slices[8].Width, slices[8].Height);
75  sliceBorderSizes *= slider.sprites[slider.State].First().GetSliceBorderScale(sliderArea.Size);
76  }
77 
78  Rectangle sliderRect = IsHorizontal ?
79  new Rectangle(
80  sliderArea.X + (int)sliceBorderSizes.X,
81  sliderArea.Y,
82  (int)Math.Round((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
83  sliderArea.Height)
84  :
85  new Rectangle(
86  sliderArea.X,
87  (int)Math.Round(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
88  sliderArea.Width,
89  (int)Math.Round((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
90 
91  sliderRect.Width = Math.Max(sliderRect.Width, 1);
92  sliderRect.Height = Math.Max(sliderRect.Height, 1);
93 
94  return sliderRect;
95  }
96 
97  protected override void Draw(SpriteBatch spriteBatch)
98  {
99  if (!Visible) { return; }
100 
101  if (ProgressGetter != null)
102  {
103  float newSize = MathHelper.Clamp(ProgressGetter(), 0.0f, 1.0f);
104  if (!MathUtils.IsValid(newSize))
105  {
106  GameAnalyticsManager.AddErrorEventOnce(
107  "GUIProgressBar.Draw:GetProgress",
108  GameAnalyticsManager.ErrorSeverity.Error,
109  "ProgressGetter of a GUIProgressBar (" + ProgressGetter.Target.ToString() + " - " + ProgressGetter.Method.ToString() + ") returned an invalid value (" + newSize + ")\n" + Environment.StackTrace.CleanupStackTrace());
110  }
111  else
112  {
113  BarSize = newSize;
114  }
115  }
116 
117  var sliderRect = GetSliderRect(barSize);
118 
119  slider.RectTransform.AbsoluteOffset = new Point((int)Style.Padding.X, (int)Style.Padding.Y);
120  slider.RectTransform.MaxSize = new Point(
121  (int)(Rect.Width - Style.Padding.X + Style.Padding.Z),
122  (int)(Rect.Height - Style.Padding.Y + Style.Padding.W));
123  frame.Visible = showFrame;
124  slider.Visible = BarSize > 0.0f;
125 
126  if (showFrame)
127  {
128  if (AutoDraw)
129  {
130  frame.DrawAuto(spriteBatch);
131  }
132  else
133  {
134  frame.DrawManually(spriteBatch);
135  }
136  }
137 
138  Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
139  if (BarSize <= 1.0f)
140  {
141  spriteBatch.End();
142  spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, sliderRect);
143  spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
144  }
145 
146  Color currColor = GetColor(State);
147 
148  slider.Color = currColor;
149  if (AutoDraw)
150  {
151  slider.DrawAuto(spriteBatch);
152  }
153  else
154  {
155  slider.DrawManually(spriteBatch);
156  }
157  //hide the slider, we've already drawn it manually
158  frame.Visible = false;
159  slider.Visible = false;
160  if (BarSize <= 1.0f)
161  {
162  spriteBatch.End();
163  spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
164  spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
165  }
166  }
167  }
168 }
virtual ComponentState State
virtual Color GetColor(ComponentState state)
virtual Rectangle Rect
GUIComponentStyle Style
RectTransform RectTransform
override void Draw(SpriteBatch spriteBatch)
delegate float ProgressGetterHandler()
ProgressGetterHandler ProgressGetter
GUIProgressBar(RectTransform rectT, float barSize, Color? color=null, string style="", bool showFrame=true)
Rectangle GetSliderRect(float fillAmount)
Get the area the slider should be drawn inside
static RasterizerState ScissorTestEnable
Definition: GameMain.cs:195