From 7f5f368dea92b33f504124fbe7924662aaa75793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 8 May 2026 08:45:57 +0200 Subject: [PATCH] Fix some numeric settings not working correct in some languages when attempting to set negative value (#37667) Closes https://github.com/ppy/osu/issues/37553. You can probably tell by the title that this is going to be a good one. As previously mentioned in https://github.com/ppy/osu/pull/35395, framework-side `TextBox` uses a bunch of `NumberFormat` properties from `CurrentCulture` to contextually allow decimal points or minus signs in a textbox. In some languages, namely (of the ones we support): Finnish, Croatian, Lithuanian, Norsk, Slovenian, and Swedish, `NumberFormat.NegativeSign` is not `U+002D HYPHEN MINUS`, but instead `U+2212 MINUS SIGN`. Therefore, in `FormSliderBar`, when `ToStandardFormattedString()` is attempted to be used to set the textbox value, the hardcoded `U+002D HYPHEN MINUS` is rejected on cultures that expect `U+2212 MINUS SIGN`, and thus due to a feedback loop, all negative values are no longer settable. This applies the obvious fix of applying `NumberFormat.NegativeSign`. --- .../Extensions/NumberFormattingExtensionsTest.cs | 10 +++++++++- osu.Game/Extensions/NumberFormattingExtensions.cs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Extensions/NumberFormattingExtensionsTest.cs b/osu.Game.Tests/Extensions/NumberFormattingExtensionsTest.cs index f60c978788..49655cc1c5 100644 --- a/osu.Game.Tests/Extensions/NumberFormattingExtensionsTest.cs +++ b/osu.Game.Tests/Extensions/NumberFormattingExtensionsTest.cs @@ -51,7 +51,15 @@ namespace osu.Game.Tests.Extensions [TestCase(0.4, true, 2, ExpectedResult = "40%")] [TestCase(1e-6, false, 6, ExpectedResult = "0,000001")] [TestCase(0.48333, true, 4, ExpectedResult = "48,33%")] - public string TestCultureSensitivity(double input, bool percent, int decimalDigits) + public string TestCultureSensitivityDecimalPoint(double input, bool percent, int decimalDigits) + { + return input.ToStandardFormattedString(decimalDigits, percent); + } + + [Test] + [SetCulture("sv-SE")] + [TestCase(-1e-6, false, 6, ExpectedResult = "−0,000001")] + public string TestCultureSensitivityNegativeSign(double input, bool percent, int decimalDigits) { return input.ToStandardFormattedString(decimalDigits, percent); } diff --git a/osu.Game/Extensions/NumberFormattingExtensions.cs b/osu.Game/Extensions/NumberFormattingExtensions.cs index 0c73590808..49f4503362 100644 --- a/osu.Game/Extensions/NumberFormattingExtensions.cs +++ b/osu.Game/Extensions/NumberFormattingExtensions.cs @@ -37,7 +37,7 @@ namespace osu.Game.Extensions return floatValue.ToString($@"0.{new string('0', Math.Max(0, significantDigits - 2))}%", CultureInfo.CurrentCulture); } - string negativeSign = Math.Round(floatValue, significantDigits) < 0 ? "-" : string.Empty; + string negativeSign = Math.Round(floatValue, significantDigits) < 0 ? CultureInfo.CurrentCulture.NumberFormat.NegativeSign : string.Empty; return $"{negativeSign}{Math.Abs(floatValue).ToString($"N{significantDigits}", CultureInfo.CurrentCulture)}"; }