mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-01 09:37:03 +02:00
235 lines
6.8 KiB
C#
235 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
|
|
namespace Robust.Client.UserInterface.Controls
|
|
{
|
|
/// <summary>
|
|
/// Number input LineEdit with increment buttons.
|
|
/// </summary>
|
|
[Virtual]
|
|
public class SpinBox : BoxContainer
|
|
{
|
|
public const string LeftButtonStyle = "spinbox-left";
|
|
public const string RightButtonStyle = "spinbox-right";
|
|
public const string MiddleButtonStyle = "spinbox-middle";
|
|
public LineEdit LineEditControl { get; }
|
|
private List<SpinBoxButton> _leftButtons = new();
|
|
private List<SpinBoxButton> _rightButtons = new();
|
|
private int _stepSize = 1;
|
|
private bool _buttonsDisabled;
|
|
|
|
/// <summary>
|
|
/// Determines whether the SpinBox value gets changed by the input text.
|
|
/// </summary>
|
|
public Func<int, bool>? IsValid { get; set; }
|
|
|
|
private int _value;
|
|
public int Value
|
|
{
|
|
get => _value;
|
|
set
|
|
{
|
|
OverrideValue(value);
|
|
ValueChanged?.Invoke(new ValueChangedEventArgs(value));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overrides the value of the spinbox without calling the event.
|
|
/// Still applies validity-checks
|
|
/// </summary>
|
|
/// <param name="value">the new value</param>
|
|
public void OverrideValue(int value)
|
|
{
|
|
if (IsValid != null && !IsValid(value))
|
|
{
|
|
return;
|
|
}
|
|
_value = value;
|
|
UpdateButtonCanPress();
|
|
LineEditControl.Text = value.ToString();
|
|
}
|
|
|
|
public event Action<ValueChangedEventArgs>? ValueChanged;
|
|
|
|
public SpinBox()
|
|
{
|
|
Orientation = LayoutOrientation.Horizontal;
|
|
MouseFilter = MouseFilterMode.Pass;
|
|
|
|
LineEditControl = new LineEdit
|
|
{
|
|
MinSize = new Vector2(40, 0),
|
|
HorizontalExpand = true
|
|
};
|
|
AddChild(LineEditControl);
|
|
|
|
Value = 0;
|
|
|
|
LineEditControl.IsValid = (str) => int.TryParse(str, out var i) && (IsValid == null || IsValid(i));
|
|
LineEditControl.OnTextChanged += (args) =>
|
|
{
|
|
if (int.TryParse(args.Text, out int i))
|
|
Value = i;
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and sets buttons to - and +.
|
|
/// </summary>
|
|
public void InitDefaultButtons()
|
|
{
|
|
ClearButtons();
|
|
AddLeftButton(-1, "-");
|
|
AddRightButton(1, "+");
|
|
UpdateButtonCanPress();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a button to the right of the SpinBox LineEdit.
|
|
/// </summary>
|
|
public void AddRightButton(int num, string text)
|
|
{
|
|
var button = new SpinBoxButton(num) { Text = text };
|
|
button.OnPressed += _ => Value += num;
|
|
AddChild(button);
|
|
button.AddStyleClass(RightButtonStyle);
|
|
if (_rightButtons.Count > 0)
|
|
{
|
|
_rightButtons[^1].RemoveStyleClass(RightButtonStyle);
|
|
_rightButtons[^1].AddStyleClass(MiddleButtonStyle);
|
|
}
|
|
_rightButtons.Add(button);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a button to the left of the SpinBox LineEdit.
|
|
/// </summary>
|
|
public void AddLeftButton(int num, string text)
|
|
{
|
|
var button = new SpinBoxButton(num) { Text = text };
|
|
button.OnPressed += _ => Value += num;
|
|
AddChild(button);
|
|
button.SetPositionInParent(_leftButtons.Count);
|
|
button.AddStyleClass(_leftButtons.Count == 0 ? LeftButtonStyle : MiddleButtonStyle);
|
|
if (_leftButtons.Count == 0)
|
|
{
|
|
}
|
|
_leftButtons.Add(button);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and sets buttons for each int in leftButtons and rightButtons.
|
|
/// </summary>
|
|
public void SetButtons(List<int> leftButtons, List<int> rightButtons)
|
|
{
|
|
ClearButtons();
|
|
foreach (var num in leftButtons)
|
|
{
|
|
AddLeftButton(num, num.ToString("+#;-#;0"));
|
|
}
|
|
foreach (var num in rightButtons)
|
|
{
|
|
AddRightButton(num, num.ToString("+#;-#;0"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the editability of the lineedit-field
|
|
/// </summary>
|
|
public bool LineEditDisabled
|
|
{
|
|
get => !LineEditControl.Editable;
|
|
set => LineEditControl.Editable = !value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the editability of the buttons
|
|
/// </summary>
|
|
/// <param name="disabled"></param>
|
|
public void SetButtonDisabled(bool disabled)
|
|
{
|
|
foreach (var leftButton in _leftButtons)
|
|
{
|
|
leftButton.Disabled = disabled;
|
|
}
|
|
|
|
foreach (var rightButton in _rightButtons)
|
|
{
|
|
rightButton.Disabled = disabled;
|
|
}
|
|
|
|
_buttonsDisabled = disabled;
|
|
}
|
|
|
|
private void UpdateButtonCanPress()
|
|
{
|
|
if (IsValid == null)
|
|
return;
|
|
|
|
foreach (var button in _leftButtons)
|
|
{
|
|
button.Disabled = !IsValid(_value + button.Value) || _buttonsDisabled;
|
|
}
|
|
|
|
foreach (var button in _rightButtons)
|
|
{
|
|
button.Disabled = !IsValid(_value + button.Value) || _buttonsDisabled;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all buttons inside the SpinBox.
|
|
/// </summary>
|
|
public void ClearButtons()
|
|
{
|
|
foreach (var button in _leftButtons)
|
|
{
|
|
button.Orphan();
|
|
}
|
|
_leftButtons.Clear();
|
|
foreach (var button in _rightButtons)
|
|
{
|
|
button.Orphan();
|
|
}
|
|
_rightButtons.Clear();
|
|
}
|
|
|
|
protected internal override void MouseWheel(GUIMouseWheelEventArgs args)
|
|
{
|
|
base.MouseWheel(args);
|
|
|
|
if (!LineEditControl.HasKeyboardFocus())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (args.Delta.Y > 0)
|
|
Value += _stepSize;
|
|
else if (args.Delta.Y < 0)
|
|
Value -= _stepSize;
|
|
}
|
|
|
|
private sealed class SpinBoxButton : Button
|
|
{
|
|
public readonly int Value;
|
|
|
|
public SpinBoxButton(int value)
|
|
{
|
|
Value = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public sealed class ValueChangedEventArgs : EventArgs
|
|
{
|
|
public readonly int Value;
|
|
|
|
public ValueChangedEventArgs(int value)
|
|
{
|
|
Value = value;
|
|
}
|
|
}
|
|
}
|