diff --git a/ConfigurationManager.Shared/SettingFieldDrawer.cs b/ConfigurationManager.Shared/SettingFieldDrawer.cs index 6697f0c..4dd6855 100644 --- a/ConfigurationManager.Shared/SettingFieldDrawer.cs +++ b/ConfigurationManager.Shared/SettingFieldDrawer.cs @@ -84,6 +84,7 @@ public void DrawSettingValue(SettingEntryBase setting) public static void ClearCache() { _comboBoxCache.Clear(); + _rangeValueWidth = 0; foreach (var tex in _colorCache) UnityEngine.Object.Destroy(tex.Value.Tex); @@ -275,6 +276,39 @@ private static GUIContent ObjectToGuiContent(object x) return new GUIContent(x.ToString()); } + /// + /// Width shared by every value box and percent label next to a slider, so they line up in one column. It only grows: a value + /// that needs more room bumps it for all of them, up to characters. Reset when the window + /// opens or closes (), so a font or skin change is picked up on the next open. + /// + private static float _rangeValueWidth; + + private const float RangeValueMinWidth = 50f; + private const int RangeValueMaxChars = 10; + + /// + /// Fits the longest of the given texts in the current style (so a bigger font or a custom skin does not clip the number) and + /// returns the shared width, never narrower than the old fixed 50. Measured on a sample of zeros of that length, not on the + /// value itself, so the box does not change width while the slider is dragged. + /// + private static float RangeValueWidth(GUIStyle style, params string[] texts) + { + var length = 0; + var negative = false; + foreach (var text in texts) + { + if (text == null) continue; + length = Math.Max(length, text.Length); + negative |= text.StartsWith("-"); + } + length = Math.Min(length, RangeValueMaxChars); + var sample = (negative ? "-" : "") + new string('0', Math.Max(1, length - (negative ? 1 : 0))); + // The style's margin is added too: the percent label sits inside a horizontal group, and without it "100%" wrapped. + var fit = style.CalcSize(ImguiUtils.Content(sample)).x + style.margin.horizontal; + _rangeValueWidth = Mathf.Max(_rangeValueWidth, RangeValueMinWidth, fit); + return _rangeValueWidth; + } + private static void DrawRangeField(SettingEntryBase setting) { var value = setting.Get(); @@ -293,12 +327,14 @@ private static void DrawRangeField(SettingEntryBase setting) { DrawCenteredLabel( Mathf.Round(100 * Mathf.Abs(result - leftValue) / Mathf.Abs(rightValue - leftValue)) + "%", - GUILayout.Width(50)); + GUILayout.Width(RangeValueWidth(GUI.skin.label, "100%"))); } else { var strVal = Convert.ToString(value, CultureInfo.InvariantCulture).AppendZeroIfFloat(setting.SettingType); - var strResult = GUILayout.TextField(strVal, GUILayout.Width(50)); + var strMin = Convert.ToString(setting.AcceptableValueRange.Key, CultureInfo.InvariantCulture).AppendZeroIfFloat(setting.SettingType); + var strMax = Convert.ToString(setting.AcceptableValueRange.Value, CultureInfo.InvariantCulture).AppendZeroIfFloat(setting.SettingType); + var strResult = GUILayout.TextField(strVal, GUILayout.Width(RangeValueWidth(GUI.skin.textField, strVal, strMin, strMax))); if (strResult != strVal) { try