fix(settings): stop enum combos listing blank rows
The shared label buffer was handed to ImGui.Combo whole, with the value count as the fourth argument. That argument is not the item count -- it is popupMaxHeightInItems. The count comes from the span's own length, which was always 8. So every enum combo listed eight rows. A three-value setting showed five blank ones below its real entries, and the popup was capped at three rows high, so it scrolled. Clicking a blank row hit the range guard and silently did nothing. Five combos were affected: world suffix, name form, command help side, preview position and tell auto-open mode. The per-tab code this replaced sized its array to the value count, so the count happened to be right; sharing one buffer is what exposed the misread parameter. Slicing the buffer fixes both halves at once: the span carries the real count and popupMaxHeightInItems falls back to its -1 default. Also moves Lerp below LerpTowardWhite. It was inserted directly under that method's comment block, TEST-MIRROR line included, so the documentation sat on the wrong method.
This commit is contained in:
@@ -24,6 +24,7 @@ internal sealed class SettingsWidgets
|
|||||||
|
|
||||||
// Shared across every combo. ImGui.Combo copies the strings it needs before
|
// Shared across every combo. ImGui.Combo copies the strings it needs before
|
||||||
// returning, so the buffer is free again by the time the next call runs.
|
// returning, so the buffer is free again by the time the next call runs.
|
||||||
|
// Always sliced to the value count when passed on -- see EnumCombo.
|
||||||
private string[] _labelScratch = new string[8];
|
private string[] _labelScratch = new string[8];
|
||||||
|
|
||||||
internal SettingsWidgets(Plugin plugin)
|
internal SettingsWidgets(Plugin plugin)
|
||||||
@@ -105,12 +106,14 @@ internal sealed class SettingsWidgets
|
|||||||
selected = i;
|
selected = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sliced, not passed whole with a count. The binding's fourth parameter
|
||||||
|
// is popupMaxHeightInItems, not the item count -- that comes from the
|
||||||
|
// span's own length. Handing over the full buffer would list all eight
|
||||||
|
// slots, so a three-value enum would show five blank rows.
|
||||||
ImGui.SetNextItemWidth(width);
|
ImGui.SetNextItemWidth(width);
|
||||||
if (!ImGui.Combo(label, ref selected, _labelScratch, values.Length))
|
if (!ImGui.Combo(label, ref selected, _labelScratch.AsSpan(0, values.Length)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// The scratch buffer can be longer than the value set, so a stale index
|
|
||||||
// from a previous, larger combo must not reach the setter.
|
|
||||||
if (selected < 0 || selected >= values.Length)
|
if (selected < 0 || selected >= values.Length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -108,21 +108,6 @@ internal static class ColourUtil
|
|||||||
// going fully saturated (effect level stays "subtle"). RGB-only on
|
// going fully saturated (effect level stays "subtle"). RGB-only on
|
||||||
// purpose -- DrawHoverSheen owns the alpha falloff.
|
// purpose -- DrawHoverSheen owns the alpha falloff.
|
||||||
// TEST-MIRROR: ../../../Hellion Build test/Util/ColourUtilTintTests.cs
|
// TEST-MIRROR: ../../../Hellion Build test/Util/ColourUtilTintTests.cs
|
||||||
// Mixes two ABGR colours channel by channel, alpha included. Used where a
|
|
||||||
// widget crossfades between two theme slots rather than toward a constant.
|
|
||||||
internal static uint Lerp(uint fromAbgr, uint toAbgr, float t)
|
|
||||||
{
|
|
||||||
t = Math.Clamp(t, 0f, 1f);
|
|
||||||
uint Mix(int shift)
|
|
||||||
{
|
|
||||||
var a = (byte)((fromAbgr >> shift) & 0xFFu);
|
|
||||||
var b = (byte)((toAbgr >> shift) & 0xFFu);
|
|
||||||
return (uint)Math.Round(a + (b - a) * t) & 0xFFu;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Mix(24) << 24) | (Mix(16) << 16) | (Mix(8) << 8) | Mix(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static uint LerpTowardWhite(uint abgr, float t)
|
internal static uint LerpTowardWhite(uint abgr, float t)
|
||||||
{
|
{
|
||||||
t = Math.Clamp(t, 0f, 1f);
|
t = Math.Clamp(t, 0f, 1f);
|
||||||
@@ -138,6 +123,21 @@ internal static class ColourUtil
|
|||||||
return ((uint)a << 24) | ((uint)nb << 16) | ((uint)ng << 8) | nr;
|
return ((uint)a << 24) | ((uint)nb << 16) | ((uint)ng << 8) | nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mixes two ABGR colours channel by channel, alpha included. Used where a
|
||||||
|
// widget crossfades between two theme slots rather than toward a constant.
|
||||||
|
internal static uint Lerp(uint fromAbgr, uint toAbgr, float t)
|
||||||
|
{
|
||||||
|
t = Math.Clamp(t, 0f, 1f);
|
||||||
|
uint Mix(int shift)
|
||||||
|
{
|
||||||
|
var a = (byte)((fromAbgr >> shift) & 0xFFu);
|
||||||
|
var b = (byte)((toAbgr >> shift) & 0xFFu);
|
||||||
|
return (uint)Math.Round(a + (b - a) * t) & 0xFFu;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Mix(24) << 24) | (Mix(16) << 16) | (Mix(8) << 8) | Mix(0);
|
||||||
|
}
|
||||||
|
|
||||||
public static uint HexToRgba(string hex)
|
public static uint HexToRgba(string hex)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(hex);
|
ArgumentNullException.ThrowIfNull(hex);
|
||||||
|
|||||||
Reference in New Issue
Block a user