146 lines
3.7 KiB
C#
146 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
using Barotrauma;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Input;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
namespace QICrabUI
|
|
{
|
|
/// <summary>
|
|
/// Button with multiple options
|
|
/// which are rotating when you click
|
|
/// </summary>
|
|
public class CUIMultiButton : CUIButton
|
|
{
|
|
private List<string> options = new List<string>();
|
|
/// <summary>
|
|
/// Options are just strings
|
|
/// </summary>
|
|
[CUISerializable]
|
|
public IEnumerable<string> Options
|
|
{
|
|
get => options;
|
|
set => options = value.ToList();
|
|
}
|
|
public event Action<string> OnSelect;
|
|
public Action<string> AddOnSelect { set { OnSelect += value; } }
|
|
|
|
public bool CycleOnClick { get; set; } = true;
|
|
public int SelectedIndex
|
|
{
|
|
get => options.IndexOf(Selected);
|
|
set
|
|
{
|
|
if (options.Count == 0)
|
|
{
|
|
Selected = "";
|
|
}
|
|
else
|
|
{
|
|
Selected = options.ElementAtOrDefault(value % options.Count) ?? "";
|
|
}
|
|
}
|
|
}
|
|
[CUISerializable]
|
|
public string Selected
|
|
{
|
|
get => Text;
|
|
set
|
|
{
|
|
Text = value;
|
|
OnSelect?.Invoke(value);
|
|
}
|
|
}
|
|
|
|
public void Add(string option) => options.Add(option);
|
|
public void Remove(string option)
|
|
{
|
|
int i = options.IndexOf(option);
|
|
options.Remove(option);
|
|
if (option == Selected) Select(i);
|
|
}
|
|
public void Select(int i) => SelectedIndex = i;
|
|
public void Select(string option) => Selected = option;
|
|
public void SelectNext() => SelectedIndex++;
|
|
public void SelectPrev() => SelectedIndex--;
|
|
|
|
public CUIMultiButton() : base()
|
|
{
|
|
Text = "MultiButton";
|
|
OnMouseDown += (e) =>
|
|
{
|
|
if (CycleOnClick)
|
|
{
|
|
SelectNext();
|
|
if (Command != null) DispatchUp(new CUICommand(Command, Selected));
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// CUITextBlock DoWrapFor but for all text
|
|
/// </summary>
|
|
/// <param name="size"></param>
|
|
/// <returns></returns>
|
|
protected override Vector2 DoWrapFor(Vector2 size)
|
|
{
|
|
if ((!WrappedForThisSize.HasValue || size == WrappedForThisSize.Value) && !TextPropChanged) return WrappedSize;
|
|
|
|
TextPropChanged = false;
|
|
WrappedForThisSize = size;
|
|
|
|
if (Vertical) size = new Vector2(0, size.Y);
|
|
|
|
|
|
IEnumerable<string> WrappedTexts;
|
|
if (Wrap || Vertical)
|
|
{
|
|
WrappedText = Font.WrapText(Text, size.X / TextScale - Padding.X * 2).Trim('\n');
|
|
WrappedTexts = options.Select(o => Font.WrapText(o, size.X / TextScale - Padding.X * 2).Trim('\n'));
|
|
}
|
|
else
|
|
{
|
|
WrappedText = Text;
|
|
WrappedTexts = options;
|
|
}
|
|
|
|
IEnumerable<Vector2> RealTextSizes = WrappedTexts.Select(t => Font.MeasureString(t) * TextScale);
|
|
|
|
float maxX = 0;
|
|
float maxY = 0;
|
|
foreach (Vector2 s in RealTextSizes)
|
|
{
|
|
if (s.X > maxX) maxX = s.X;
|
|
if (s.Y > maxY) maxY = s.Y;
|
|
}
|
|
|
|
Vector2 MaxTextSize = new Vector2(maxX, maxY);
|
|
|
|
RealTextSize = Font.MeasureString(WrappedText) * TextScale;
|
|
|
|
if (WrappedText == "") RealTextSize = new Vector2(0, 0);
|
|
RealTextSize = new Vector2((float)Math.Round(RealTextSize.X), (float)Math.Round(RealTextSize.Y));
|
|
|
|
Vector2 minSize = MaxTextSize + Padding * 2;
|
|
|
|
if (!Wrap || Vertical)
|
|
{
|
|
SetForcedMinSize(new CUINullVector2(minSize));
|
|
}
|
|
|
|
WrappedSize = new Vector2(Math.Max(size.X, minSize.X), Math.Max(size.Y, minSize.Y));
|
|
|
|
return WrappedSize;
|
|
}
|
|
|
|
internal override Vector2 AmIOkWithThisSize(Vector2 size)
|
|
{
|
|
return DoWrapFor(size);
|
|
}
|
|
}
|
|
} |