using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Barotrauma.Extensions; namespace Barotrauma { public enum WidgetShape { Rectangle, Circle, Cross } internal class Widget { public WidgetShape Shape; public LocalizedString Tooltip; public bool ShowTooltip = true; public Rectangle DrawRect => new Rectangle((int)(DrawPos.X - (float)Size / 2), (int)(DrawPos.Y - (float)Size / 2), Size, Size); public Rectangle InputRect { get { var inputRect = DrawRect; inputRect.Inflate(InputAreaMargin, InputAreaMargin); return inputRect; } } public Vector2 DrawPos { get; set; } public int Size = 10; public float Thickness = 1f; /// /// Used only for circles. /// public int Sides = 40; /// /// Currently used only for rectangles. /// public bool IsFilled; public int InputAreaMargin; public Color Color = GUIStyle.Red; public Color? SecondaryColor; public Color TextColor = Color.White; public Color TextBackgroundColor = Color.Black * 0.5f; public readonly string Id; public event Action Selected; public event Action Deselected; public event Action Hovered; public event Action MouseUp; public event Action MouseDown; public event Action MouseHeld; public event Action PreUpdate; public event Action PostUpdate; public event Action PreDraw; public event Action PostDraw; public bool RequireMouseOn = true; public Action Refresh; public object Data; public bool IsSelected => enabled && SelectedWidgets.Contains(this); public bool IsControlled => IsSelected && PlayerInput.PrimaryMouseButtonHeld(); public bool IsMouseOver => GUI.MouseOn == null && InputRect.Contains(PlayerInput.MousePosition); private bool enabled = true; public bool Enabled { get { return enabled; } set { enabled = value; if (!enabled && SelectedWidgets.Contains(this)) { SelectedWidgets.Remove(this); } } } private static bool multiselect; public static bool EnableMultiSelect { get { return multiselect; } set { multiselect = value; if (!multiselect && SelectedWidgets.Multiple()) { SelectedWidgets = SelectedWidgets.Take(1).ToList(); } } } public Vector2? TooltipOffset; public Widget LinkedWidget; public static List SelectedWidgets = new List(); public Widget(string id, int size, WidgetShape shape) { Id = id; Size = size; Shape = shape; } public virtual void Update(float deltaTime) { PreUpdate?.Invoke(deltaTime); if (!enabled) { return; } if (IsMouseOver || (!RequireMouseOn && SelectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld())) { Hovered?.Invoke(); if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown()) { if ((multiselect && !SelectedWidgets.Contains(this)) || SelectedWidgets.None()) { SelectedWidgets.Add(this); Selected?.Invoke(); } } } else if (SelectedWidgets.Contains(this)) { System.Diagnostics.Debug.WriteLine("selectedWidgets.Contains(this) -> remove"); SelectedWidgets.Remove(this); Deselected?.Invoke(); } if (IsSelected) { if (PlayerInput.PrimaryMouseButtonDown()) { MouseDown?.Invoke(); } if (PlayerInput.PrimaryMouseButtonHeld()) { MouseHeld?.Invoke(deltaTime); } if (PlayerInput.PrimaryMouseButtonClicked()) { MouseUp?.Invoke(); } } PostUpdate?.Invoke(deltaTime); } public virtual void Draw(SpriteBatch spriteBatch, float deltaTime) { PreDraw?.Invoke(spriteBatch, deltaTime); var drawRect = DrawRect; switch (Shape) { case WidgetShape.Rectangle: if (SecondaryColor.HasValue) { GUI.DrawRectangle(spriteBatch, drawRect, SecondaryColor.Value, IsFilled, thickness: 2); } GUI.DrawRectangle(spriteBatch, drawRect, Color, IsFilled, thickness: IsSelected ? (int)(Thickness * 3) : (int)Thickness); break; case WidgetShape.Circle: if (SecondaryColor.HasValue) { ShapeExtensions.DrawCircle(spriteBatch, DrawPos, Size / 2, Sides, SecondaryColor.Value, thickness: 2); } ShapeExtensions.DrawCircle(spriteBatch, DrawPos, Size / 2, Sides, Color, thickness: IsSelected ? 3 : 1); break; case WidgetShape.Cross: float halfSize = Size / 2; if (SecondaryColor.HasValue) { GUI.DrawLine(spriteBatch, DrawPos + Vector2.UnitY * halfSize, DrawPos - Vector2.UnitY * halfSize, SecondaryColor.Value, width: 2); GUI.DrawLine(spriteBatch, DrawPos + Vector2.UnitX * halfSize, DrawPos - Vector2.UnitX * halfSize, SecondaryColor.Value, width: 2); } GUI.DrawLine(spriteBatch, DrawPos + Vector2.UnitY * halfSize, DrawPos - Vector2.UnitY * halfSize, Color, width: IsSelected ? 3 : 1); GUI.DrawLine(spriteBatch, DrawPos + Vector2.UnitX * halfSize, DrawPos - Vector2.UnitX * halfSize, Color, width: IsSelected ? 3 : 1); break; default: throw new NotImplementedException(Shape.ToString()); } if (IsSelected) { if (ShowTooltip && !Tooltip.IsNullOrEmpty()) { var offset = TooltipOffset ?? new Vector2(Size, -Size / 2f); GUIComponent.DrawToolTip(spriteBatch, Tooltip, DrawPos + offset, TextColor, TextBackgroundColor); } } PostDraw?.Invoke(spriteBatch, deltaTime); } } }