using Content.Client.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Trinary.Components;
+using Content.Shared.Localizations;
using JetBrains.Annotations;
-using Robust.Client.GameObjects;
namespace Content.Client.Atmos.UI
{
private void OnFilterTransferRatePressed(string value)
{
- float rate = float.TryParse(value, out var parsed) ? parsed : 0f;
+ var rate = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
SendMessage(new GasFilterChangeRateMessage(rate));
}
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-filter-ui-filter-transfer-rate}"/>
- <LineEdit Name="FilterTransferRateInput" MinSize="60 0" />
+ <LineEdit Name="FilterTransferRateInput" MinSize="70 0" />
<Button Name="SetFilterRate" Text="{Loc comp-gas-filter-ui-filter-set-rate}" Disabled="True"/>
</BoxContainer>
public void SetTransferRate(float rate)
{
- FilterTransferRateInput.Text = rate.ToString(CultureInfo.InvariantCulture);
+ FilterTransferRateInput.Text = rate.ToString(CultureInfo.CurrentCulture);
}
public void SetFilterStatus(bool enabled)
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Trinary.Components;
+using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
private void OnMixerOutputPressurePressed(string value)
{
- var pressure = float.TryParse(value, out var parsed) ? parsed : 0f;
+ var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
if (pressure > MaxPressure)
pressure = MaxPressure;
private void OnMixerSetPercentagePressed(string value)
{
// We don't need to send both nodes because it's just 100.0f - node
- var node = float.TryParse(value, out var parsed) ? parsed : 1.0f;
+ var node = UserInputParser.TryFloat(value, out var parsed) ? parsed : 1.0f;
node = Math.Clamp(node, 0f, 100.0f);
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-mixer-ui-mixer-output-pressure}"/>
<Control MinSize="5 0" />
- <LineEdit Name="MixerPressureOutputInput" MinSize="60 0" />
+ <LineEdit Name="MixerPressureOutputInput" MinSize="70 0" />
<Control MinSize="5 0" />
<Button Name="SetMaxPressureButton" Text="{Loc comp-gas-mixer-ui-mixer-max}" />
<Control MinSize="5 0" />
SetMaxPressureButton.OnPressed += _ =>
{
- MixerPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.InvariantCulture);
+ MixerPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture);
SetOutputPressureButton.Disabled = false;
};
public void SetOutputPressure(float pressure)
{
- MixerPressureOutputInput.Text = pressure.ToString(CultureInfo.InvariantCulture);
+ MixerPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture);
}
public void SetNodePercentages(float nodeOne)
{
nodeOne *= 100.0f;
- MixerNodeOneInput.Text = nodeOne.ToString("0.##", CultureInfo.InvariantCulture);
+ MixerNodeOneInput.Text = nodeOne.ToString("0.##", CultureInfo.CurrentCulture);
float nodeTwo = 100.0f - nodeOne;
- MixerNodeTwoInput.Text = nodeTwo.ToString("0.##", CultureInfo.InvariantCulture);
+ MixerNodeTwoInput.Text = nodeTwo.ToString("0.##", CultureInfo.CurrentCulture);
}
public void SetMixerStatus(bool enabled)
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
private void OnPumpOutputPressurePressed(string value)
{
- float pressure = float.TryParse(value, out var parsed) ? parsed : 0f;
+ var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
if (pressure > MaxPressure) pressure = MaxPressure;
SendMessage(new GasPressurePumpChangeOutputPressureMessage(pressure));
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-pump-ui-pump-output-pressure}"/>
<Control MinSize="5 0" />
- <LineEdit Name="PumpPressureOutputInput" MinSize="60 0" />
+ <LineEdit Name="PumpPressureOutputInput" MinSize="70 0" />
<Control MinSize="5 0" />
<Button Name="SetMaxPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
<Control MinSize="5 0" />
SetMaxPressureButton.OnPressed += _ =>
{
- PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.InvariantCulture);
+ PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture);
SetOutputPressureButton.Disabled = false;
};
}
public void SetOutputPressure(float pressure)
{
- PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.InvariantCulture);
+ PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture);
}
public void SetPumpStatus(bool enabled)
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
private void OnPumpTransferRatePressed(string value)
{
- var rate = float.TryParse(value, out var parsed) ? parsed : 0f;
+ var rate = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
if (rate > MaxTransferRate)
rate = MaxTransferRate;
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-pump-ui-pump-transfer-rate}"/>
<Control MinSize="5 0" />
- <LineEdit Name="PumpTransferRateInput" MinSize="60 0" />
+ <LineEdit Name="PumpTransferRateInput" MinSize="70 0" />
<Control MinSize="5 0" />
<Button Name="SetMaxRateButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
<Control MinSize="5 0" />
SetMaxRateButton.OnPressed += _ =>
{
- PumpTransferRateInput.Text = Atmospherics.MaxTransferRate.ToString(CultureInfo.InvariantCulture);
+ PumpTransferRateInput.Text = Atmospherics.MaxTransferRate.ToString(CultureInfo.CurrentCulture);
SetTransferRateButton.Disabled = false;
};
}
public void SetTransferRate(float rate)
{
- PumpTransferRateInput.Text = rate.ToString(CultureInfo.InvariantCulture);
+ PumpTransferRateInput.Text = rate.ToString(CultureInfo.CurrentCulture);
}
public void SetPumpStatus(bool enabled)
--- /dev/null
+using System.Globalization;
+
+namespace Content.Shared.Localizations;
+
+/// <summary>
+/// Helpers for user input parsing.
+/// </summary>
+/// <remarks>
+/// A wrapper around the <see cref="System.Single.TryParse(string, out float)"/> API,
+/// with the goal of trying more options to make the user input parsing less restrictive.
+/// For culture-invariant parsing use <see cref="Robust.Shared.Utility.Parse"/>.
+/// </remarks>
+public static class UserInputParser
+{
+ private static readonly NumberFormatInfo[] StandardDecimalNumberFormats = new[]
+ {
+ new NumberFormatInfo()
+ {
+ NumberDecimalSeparator = "."
+ },
+ new NumberFormatInfo()
+ {
+ NumberDecimalSeparator = ","
+ }
+ };
+
+ public static bool TryFloat(ReadOnlySpan<char> text, out float result)
+ {
+ foreach (var format in StandardDecimalNumberFormats)
+ {
+ if (float.TryParse(text, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, format, out result))
+ {
+ return true;
+ }
+ }
+
+ result = 0f;
+ return false;
+ }
+
+ public static bool TryDouble(ReadOnlySpan<char> text, out double result)
+ {
+ foreach (var format in StandardDecimalNumberFormats)
+ {
+ if (double.TryParse(text, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, format, out result))
+ {
+ return true;
+ }
+ }
+
+ result = 0d;
+ return false;
+ }
+}
--- /dev/null
+using Content.Shared.Localizations;
+using NUnit.Framework;
+
+namespace Content.Tests.Shared.Localizations
+{
+ [TestFixture]
+ public sealed class UserInputParserTest
+ {
+ [Test]
+ [TestCase("1234.56", 1234.56f, true)]
+ [TestCase("1234,56", 1234.56f, true)]
+ [TestCase(" +1234.56 ", 1234.56f, true)]
+ [TestCase(" -1234.56 ", -1234.56f, true)]
+ [TestCase("1234.56e7", 0f, false)]
+ [TestCase("1,234.56", 0f, false)]
+ [TestCase("1 234,56", 0f, false)]
+ public void TryFloatTest(string input, float expectedOutput, bool expectedResult)
+ {
+ var result = UserInputParser.TryFloat(input, out var output);
+
+ Assert.That(result, Is.EqualTo(expectedResult));
+ Assert.That(output, Is.EqualTo(expectedOutput).Within(float.Epsilon));
+ }
+
+ [Test]
+ [TestCase("1234.56", 1234.56d, true)]
+ [TestCase("1234,56", 1234.56d, true)]
+ [TestCase(" +1234.56 ", 1234.56d, true)]
+ [TestCase(" -1234.56 ", -1234.56d, true)]
+ [TestCase("1234.56e7", 0d, false)]
+ [TestCase("1,234.56", 0d, false)]
+ [TestCase("1 234,56", 0d, false)]
+ public void TryDoubleTest(string input, double expectedOutput, bool expectedResult)
+ {
+ var result = UserInputParser.TryDouble(input, out var output);
+
+ Assert.That(result, Is.EqualTo(expectedResult));
+ Assert.That(output, Is.EqualTo(expectedOutput).Within(double.Epsilon));
+ }
+ }
+}