mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-02 18:17:09 +02:00
146 lines
4.1 KiB
C#
146 lines
4.1 KiB
C#
using Robust.Shared.Maths;
|
|
using System;
|
|
using System.Globalization;
|
|
|
|
namespace Robust.Client.UserInterface.Controls
|
|
{
|
|
/// <summary>
|
|
/// Number input LineEdit with increment buttons.
|
|
/// </summary>
|
|
public class FloatSpinBox : BoxContainer
|
|
{
|
|
private readonly float _stepSize;
|
|
private readonly byte _precision;
|
|
private readonly LineEdit _lineEdit;
|
|
private float _value;
|
|
private Button _btnLeft;
|
|
private Button _btnRight;
|
|
|
|
/// <summary>
|
|
/// Determines whether the SpinBox value gets changed by the input text.
|
|
/// </summary>
|
|
public Func<float, bool>? IsValid { get; set; }
|
|
|
|
public event Action<FloatSpinBoxEventArgs>? OnValueChanged;
|
|
|
|
|
|
public float Value
|
|
{
|
|
get => _value;
|
|
set
|
|
{
|
|
if (IsValid != null && !IsValid(value))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_value = value;
|
|
UpdateTextValue();
|
|
}
|
|
}
|
|
|
|
public FloatSpinBox(): this(.1f, 1)
|
|
{
|
|
}
|
|
|
|
public FloatSpinBox(float stepSize, byte precision)
|
|
{
|
|
Orientation = LayoutOrientation.Horizontal;
|
|
MouseFilter = MouseFilterMode.Pass;
|
|
|
|
_lineEdit = new LineEdit
|
|
{
|
|
MinSize = new Vector2(40, 0),
|
|
HorizontalExpand = true,
|
|
};
|
|
AddChild(_lineEdit);
|
|
|
|
Value = 0;
|
|
|
|
_lineEdit.OnFocusExit += TextChanged;
|
|
_lineEdit.OnTextEntered += TextChanged;
|
|
// step size can not be lesser than precision
|
|
_stepSize = Math.Max(stepSize, MathF.Pow(10, -precision));
|
|
_precision = precision;
|
|
_btnLeft = AddButton(-_stepSize, "-", 0, SpinBox.LeftButtonStyle);
|
|
_btnRight = AddButton(_stepSize, "+", ChildCount, SpinBox.RightButtonStyle);
|
|
}
|
|
|
|
public override bool HasKeyboardFocus()
|
|
{
|
|
return _lineEdit.HasKeyboardFocus();
|
|
}
|
|
|
|
private Button AddButton(float change, string text, int pos, string style)
|
|
{
|
|
var btn = new Button
|
|
{
|
|
Text = text,
|
|
StyleClasses = { style }
|
|
};
|
|
btn.OnPressed += args =>
|
|
{
|
|
Value += change;
|
|
OnValueChanged?.Invoke(new FloatSpinBoxEventArgs(this, _value));
|
|
};
|
|
AddChild(btn);
|
|
btn.SetPositionInParent(pos);
|
|
return btn;
|
|
}
|
|
|
|
private void TextChanged(LineEdit.LineEditEventArgs args)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(args.Text))
|
|
{
|
|
Value = 0;
|
|
OnValueChanged?.Invoke(new FloatSpinBoxEventArgs(this, _value));
|
|
return;
|
|
}
|
|
|
|
if (float.TryParse(args.Text, NumberStyles.Float, CultureInfo.InvariantCulture, out var res))
|
|
{
|
|
if (IsValid == null || IsValid(res))
|
|
{
|
|
Value = MathF.Round(res, _precision);
|
|
OnValueChanged?.Invoke(new FloatSpinBoxEventArgs(this, _value));
|
|
return;
|
|
}
|
|
}
|
|
|
|
UpdateTextValue();
|
|
}
|
|
|
|
private void UpdateTextValue()
|
|
{
|
|
var cursorPos = _lineEdit.CursorPosition;
|
|
_lineEdit.Text = _value.ToString("F"+_precision, CultureInfo.InvariantCulture);
|
|
_lineEdit.CursorPosition = cursorPos;
|
|
}
|
|
|
|
protected internal override void MouseWheel(GUIMouseWheelEventArgs args)
|
|
{
|
|
base.MouseWheel(args);
|
|
|
|
if (!_lineEdit.HasKeyboardFocus())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Value += _stepSize * (args.Delta.Y > 0 ? 1 : -1);
|
|
}
|
|
|
|
public class FloatSpinBoxEventArgs : EventArgs
|
|
{
|
|
public FloatSpinBox Control { get; }
|
|
public float Value { get; }
|
|
|
|
public FloatSpinBoxEventArgs(FloatSpinBox control, float value)
|
|
{
|
|
Control = control;
|
|
Value = value;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|