Client LuaCsForBarotrauma
GUIScrollBar.cs
2 using Microsoft.Xna.Framework;
3 using System;
4 
5 namespace Barotrauma
6 {
7  public class GUIScrollBar : GUIComponent
8  {
9  public static GUIScrollBar DraggingBar
10  {
11  get; private set;
12  }
13 
14  private bool isHorizontal;
15 
16  public GUIFrame Frame { get; private set; }
17  public GUIButton Bar { get; private set; }
18  private float barSize;
19  private float barScroll;
20 
21  private float step;
22 
23  private Vector2? dragStartPos;
24 
25  public delegate bool OnMovedHandler(GUIScrollBar scrollBar, float barScroll);
28 
29  public bool IsBooleanSwitch;
30 
31  public override RichString ToolTip
32  {
33  get { return base.ToolTip; }
34  set
35  {
36  base.ToolTip = value;
37  Frame.ToolTip = value;
38  Bar.ToolTip = value;
39  }
40  }
41 
42  private float minValue;
43  public float MinValue
44  {
45  get { return minValue; }
46  set
47  {
48  minValue = MathHelper.Clamp(value, 0.0f, 1.0f);
49  BarScroll = Math.Max(minValue, barScroll);
50  }
51  }
52 
53  private float maxValue = 1.0f;
54  public float MaxValue
55  {
56  get { return maxValue; }
57  set
58  {
59  maxValue = MathHelper.Clamp(value, 0.0f, 1.0f);
60  BarScroll = Math.Min(maxValue, barScroll);
61  }
62  }
63 
64  public bool IsHorizontal
65  {
66  get { return isHorizontal; }
67  /*set
68  {
69  if (isHorizontal == value) return;
70  isHorizontal = value;
71  UpdateRect();
72  }*/
73  }
74 
75  public override bool Enabled
76  {
77  get { return enabled; }
78  set
79  {
80  enabled = value;
81  Bar.Enabled = value;
82  Children.ForEach(c => c.Enabled = value);
83  if (!enabled)
84  {
85  Bar.Selected = false;
86  }
87  }
88  }
89 
90  public Vector4 Padding
91  {
92  get
93  {
94  if (Frame?.Style == null) return Vector4.Zero;
95  return Frame.Style.Padding;
96  }
97  }
98 
99  private Vector2 range;
100  public Vector2 Range
101  {
102  get
103  {
104  return range;
105  }
106  set
107  {
108  float oldBarScrollValue = BarScrollValue;
109  range = value;
110  BarScrollValue = oldBarScrollValue;
111  }
112  }
113 
114  public delegate float ScrollConversion(GUIScrollBar scrollBar, float f);
117 
118  public float BarScrollValue
119  {
120  get
121  {
122  if (ScrollToValue == null) return (BarScroll * (Range.Y - Range.X)) + Range.X;
123  return ScrollToValue(this, BarScroll);
124  }
125  set
126  {
127  if (ValueToScroll == null) BarScroll = (value - Range.X) / (Range.Y - Range.X);
128  else BarScroll = ValueToScroll(this, value);
129  }
130  }
131 
132  public float BarScroll
133  {
134  get { return step == 0.0f ? barScroll : MathUtils.RoundTowardsClosest(barScroll, step); }
135  set
136  {
137  if (float.IsNaN(value))
138  {
139  return;
140  }
141 
142  barScroll = MathHelper.Clamp(value, minValue, maxValue);
143  int newX = Bar.RectTransform.AbsoluteOffset.X;
144  int newY = Bar.RectTransform.AbsoluteOffset.Y;
145  float newScroll = step == 0.0f ? barScroll : MathUtils.RoundTowardsClosest(barScroll, step);
146  if (isHorizontal)
147  {
148  newX = (int)(Padding.X + newScroll * (Frame.Rect.Width - Bar.Rect.Width - Padding.X - Padding.Z));
149  newX = MathHelper.Clamp(newX, (int)Padding.X, Frame.Rect.Width - Bar.Rect.Width - (int)Padding.Z);
150  }
151  else
152  {
153  newY = (int)(Padding.Y + newScroll * (Frame.Rect.Height - Bar.Rect.Height - Padding.Y - Padding.W));
154  newY = MathHelper.Clamp(newY, (int)Padding.Y, Frame.Rect.Height - Bar.Rect.Height - (int)Padding.W);
155  }
156 
157  Bar.RectTransform.AbsoluteOffset = new Point(newX, newY);
158  }
159  }
160 
161  public float Step
162  {
163  get
164  {
165  return step;
166  }
167  set
168  {
169  step = MathHelper.Clamp(value, 0.0f, 1.0f);
170  }
171  }
172 
173  public float StepValue
174  {
175  get
176  {
177  return step * (Range.Y - Range.X);
178  }
179  set
180  {
181  Step = value / (Range.Y - Range.X);
182  }
183  }
184 
188  public float UnclampedBarSize;
189 
190  public float BarSize
191  {
192  get { return barSize; }
193  set
194  {
195  barSize = Math.Min(Math.Max(value, 0.0f), 1.0f);
196  UpdateRect();
197  }
198  }
199 
200  public GUIScrollBar(RectTransform rectT, float barSize = 1, Color? color = null, string style = "", bool? isHorizontal = null) : base(style, rectT)
201  {
202  CanBeFocused = true;
203  this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
204  Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
205  GUIStyle.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
206  this.barSize = barSize;
207 
208  Bar = new GUIButton(new RectTransform(Vector2.One, rectT, IsHorizontal ? Anchor.CenterLeft : Anchor.TopCenter), color: color, style: null);
209 
210  switch (style)
211  {
212  case "":
213  HoverCursor = CursorState.Default;
214  Bar.HoverCursor = CursorState.Default;
215  break;
216  case "GUISlider":
217  HoverCursor = CursorState.Hand;
218  Bar.HoverCursor = CursorState.Hand;
219  break;
220  default:
221  HoverCursor = CursorState.Hand;
222  Bar.HoverCursor = CursorState.Hand;
223  break;
224  }
225 
226  GUIStyle.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
227  Bar.OnPressed = SelectBar;
228  enabled = true;
229  UpdateRect();
230  BarScroll = 0.0f;
231 
232  rectT.SizeChanged += UpdateRect;
233  rectT.ScaleChanged += UpdateRect;
234  Bar.RectTransform.SizeChanged += () => { BarScroll = barScroll; };
235  }
236 
237  private void UpdateRect()
238  {
239  Vector4 padding = Frame.Style.Padding;
240  var newSize = new Point((int)(Rect.Size.X - padding.X - padding.Z), (int)(Rect.Size.Y - padding.Y - padding.W));
241  newSize = IsHorizontal ? newSize.Multiply(new Vector2(BarSize, 1)) : newSize.Multiply(new Vector2(1, BarSize));
242  Bar.RectTransform.Resize(newSize);
243  BarScroll = barScroll;
244  }
245 
246  protected override void Update(float deltaTime)
247  {
248  if (!Visible) { return; }
249 
250  if (!enabled) { return; }
251 
252  Frame.State = GUI.MouseOn == Frame ? ComponentState.Hover : ComponentState.None;
254  {
255  Frame.State = ComponentState.Pressed;
256  }
257 
258  if (IsBooleanSwitch &&
259  (!PlayerInput.PrimaryMouseButtonHeld() || (GUI.MouseOn != this && !IsParentOf(GUI.MouseOn))))
260  {
261  int dir = Math.Sign(barScroll - (minValue + maxValue) / 2.0f);
262  if (dir == 0) dir = 1;
263  if ((barScroll <= maxValue && dir > 0) ||
264  (barScroll > minValue && dir < 0))
265  {
266  BarScroll += dir * 0.1f;
267  }
268  }
269 
270  if (DraggingBar == this)
271  {
272  GUI.ForceMouseOn(this);
273  if (dragStartPos == null) { dragStartPos = PlayerInput.MousePosition; }
274 
276  {
277  if (IsBooleanSwitch && GUI.MouseOn == Bar && Vector2.Distance(dragStartPos.Value, PlayerInput.MousePosition) < 5)
278  {
279  BarScroll = BarScroll > 0.5f ? 0.0f : 1.0f;
280  OnMoved?.Invoke(this, BarScroll);
281  }
282  OnReleased?.Invoke(this, BarScroll);
283  DraggingBar = null;
284  dragStartPos = null;
285 
286  }
287  if ((isHorizontal && PlayerInput.MousePosition.X > Rect.X && PlayerInput.MousePosition.X < Rect.Right) ||
288  (!isHorizontal && PlayerInput.MousePosition.Y > Rect.Y && PlayerInput.MousePosition.Y < Rect.Bottom))
289  {
291  }
292  }
293  else if (GUI.MouseOn == Frame)
294  {
296  {
298  if (IsBooleanSwitch)
299  {
300  MoveButton(new Vector2(
301  Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Rect.Width,
302  Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Rect.Height));
303  }
304  else
305  {
306  float barScale = 1.0f;
307  if (UnclampedBarSize > 0.0f)
308  {
309  barScale = (UnclampedBarSize / BarSize);
310  }
311 
312  MoveButton(new Vector2(
313  Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width * barScale,
314  Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height * barScale));
315  OnReleased?.Invoke(this, BarScroll);
316  }
317  }
318  }
319  }
320 
321  private bool SelectBar()
322  {
323  if (!enabled || !PlayerInput.PrimaryMouseButtonDown()) { return false; }
324  if (barSize >= 1.0f) { return false; }
325  DraggingBar = this;
326  SoundPlayer.PlayUISound(GUISoundType.Select);
327  return true;
328  }
329 
330  public void MoveButton(Vector2 moveAmount)
331  {
332  float newScroll = barScroll;
333  if (isHorizontal)
334  {
335  moveAmount.Y = 0.0f;
336  newScroll += moveAmount.X / (Frame.Rect.Width - Bar.Rect.Width - Padding.X - Padding.Z);
337  }
338  else
339  {
340  moveAmount.X = 0.0f;
341  newScroll += moveAmount.Y / (Frame.Rect.Height - Bar.Rect.Height - Padding.Y - Padding.W);
342  }
343 
344  BarScroll = newScroll;
345 
346  if (moveAmount != Vector2.Zero && OnMoved != null) { OnMoved(this, BarScroll); }
347  }
348  }
349 }
override bool Enabled
Definition: GUIButton.cs:27
override RichString ToolTip
Definition: GUIButton.cs:150
OnPressedHandler OnPressed
Definition: GUIButton.cs:19
virtual ComponentState State
bool IsParentOf(GUIComponent component, bool recursive=true)
Definition: GUIComponent.cs:75
virtual RichString ToolTip
virtual Rectangle Rect
GUIComponentStyle Style
RectTransform RectTransform
IEnumerable< GUIComponent > Children
Definition: GUIComponent.cs:29
override bool Enabled
Definition: GUIScrollBar.cs:76
delegate float ScrollConversion(GUIScrollBar scrollBar, float f)
GUIScrollBar(RectTransform rectT, float barSize=1, Color? color=null, string style="", bool? isHorizontal=null)
override RichString ToolTip
Definition: GUIScrollBar.cs:32
ScrollConversion ValueToScroll
OnMovedHandler OnMoved
Definition: GUIScrollBar.cs:26
delegate bool OnMovedHandler(GUIScrollBar scrollBar, float barScroll)
ScrollConversion ScrollToValue
static GUIScrollBar DraggingBar
Definition: GUIScrollBar.cs:10
void MoveButton(Vector2 moveAmount)
override void Update(float deltaTime)
OnMovedHandler OnReleased
Definition: GUIScrollBar.cs:27
float UnclampedBarSize
ListBoxes with lots of content in them clamp the size of the scrollbar above a certain minimum size; ...
Point AbsoluteOffset
Absolute in pixels but relative to the anchor point. Calculated away from the anchor point,...
void Resize(Point absoluteSize, bool resizeChildren=true)
GUISoundType
Definition: GUI.cs:21
CursorState
Definition: GUI.cs:40