Fix multiple issues with textbox content display

- Sometimes would display too many decimal digits due to floating point
  representation errors.

- Placeholder would also look wrong if text was removed during a
  multiple (but determinate) selection.
This commit is contained in:
Bartłomiej Dach 2021-11-12 23:07:24 +01:00
parent e55e2a1697
commit d567d2be97
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
3 changed files with 28 additions and 21 deletions

View File

@ -19,6 +19,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Utils;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
@ -219,7 +220,7 @@ namespace osu.Game.Graphics.UserInterface
decimal decimalPrecision = normalise(CurrentNumber.Precision.ToDecimal(NumberFormatInfo.InvariantInfo), max_decimal_digits); decimal decimalPrecision = normalise(CurrentNumber.Precision.ToDecimal(NumberFormatInfo.InvariantInfo), max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize()) // Find the number of significant digits (we could have less than 5 after normalize())
int significantDigits = findPrecision(decimalPrecision); int significantDigits = FormatUtils.FindPrecision(decimalPrecision);
TooltipText = floatValue.ToString($"N{significantDigits}"); TooltipText = floatValue.ToString($"N{significantDigits}");
} }
@ -248,23 +249,5 @@ namespace osu.Game.Graphics.UserInterface
/// <returns>The normalised decimal.</returns> /// <returns>The normalised decimal.</returns>
private decimal normalise(decimal d, int sd) private decimal normalise(decimal d, int sd)
=> decimal.Parse(Math.Round(d, sd).ToString(string.Concat("0.", new string('#', sd)), CultureInfo.InvariantCulture), CultureInfo.InvariantCulture); => decimal.Parse(Math.Round(d, sd).ToString(string.Concat("0.", new string('#', sd)), CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
/// <summary>
/// Finds the number of digits after the decimal.
/// </summary>
/// <param name="d">The value to find the number of decimal digits for.</param>
/// <returns>The number decimal digits.</returns>
private int findPrecision(decimal d)
{
int precision = 0;
while (d != Math.Round(d))
{
d *= 10;
precision++;
}
return precision;
}
} }
} }

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Globalization;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -9,6 +10,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Utils;
namespace osu.Game.Screens.Edit.Timing namespace osu.Game.Screens.Edit.Timing
{ {
@ -65,7 +67,6 @@ namespace osu.Game.Screens.Edit.Timing
textbox = new LabelledTextBox textbox = new LabelledTextBox
{ {
Label = labelText, Label = labelText,
PlaceholderText = "(multiple)"
}, },
slider = new SettingsSlider<T> slider = new SettingsSlider<T>
{ {
@ -104,11 +105,16 @@ namespace osu.Game.Screens.Edit.Timing
if (Current.Value is T nonNullValue) if (Current.Value is T nonNullValue)
{ {
slider.Current.Value = nonNullValue; slider.Current.Value = nonNullValue;
textbox.Text = slider.Current.ToString();
// use the value from the slider to ensure that any precision/min/max set on it via the initial indeterminate value have been applied correctly.
decimal decimalValue = slider.Current.Value.ToDecimal(NumberFormatInfo.InvariantInfo);
textbox.Text = decimalValue.ToString($@"N{FormatUtils.FindPrecision(decimalValue)}");
textbox.PlaceholderText = string.Empty;
} }
else else
{ {
textbox.Text = null; textbox.Text = null;
textbox.PlaceholderText = "(multiple)";
} }
} }
} }

View File

@ -31,5 +31,23 @@ namespace osu.Game.Utils
/// </summary> /// </summary>
/// <param name="rank">The rank/position to be formatted.</param> /// <param name="rank">The rank/position to be formatted.</param>
public static string FormatRank(this int rank) => rank.ToMetric(decimals: rank < 100_000 ? 1 : 0); public static string FormatRank(this int rank) => rank.ToMetric(decimals: rank < 100_000 ? 1 : 0);
/// <summary>
/// Finds the number of digits after the decimal.
/// </summary>
/// <param name="d">The value to find the number of decimal digits for.</param>
/// <returns>The number decimal digits.</returns>
public static int FindPrecision(decimal d)
{
int precision = 0;
while (d != Math.Round(d))
{
d *= 10;
precision++;
}
return precision;
}
} }
} }