fix(vt): plugin <list> draws no selection band by default in either mode
Slice-7 resemblance re-check found UiMarkupList's column-less items= mode and its <column> mode disagreed on whether a selected row gets a persistent SelectedColor fill, so a plugin's Buffs lists highlighted a row while the Monsters/Meta grids looked different for the same widget. Real VVS lists (VTank's HudList) draw no such fill at all. UiMarkupList.SelectionBandEnabled (default false) now gates the fill in both OnDraw's legacy branch and DrawColumns; MarkupDocument parses <list selectionband="true"> (same literal-bool convention as openupward/clearonsubmit) to opt a single list back in. selected/onchange semantics and scroll-into-view of the selected row are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
69638584e8
commit
3cec9df4ab
4 changed files with 158 additions and 3 deletions
|
|
@ -1126,6 +1126,18 @@ public sealed class MarkupListColumnsTests
|
|||
/// entirely — i.e. against the widget's own unmodified
|
||||
/// <c>OnDraw</c>/legacy branch, not a snapshot captured from a different
|
||||
/// commit. Every vertex float must match exactly.
|
||||
///
|
||||
/// <para>
|
||||
/// Deliberately updated for the slice-7 resemblance re-check's
|
||||
/// <see cref="UiMarkupList.SelectionBandEnabled"/> fix: <c>SelectedIndex
|
||||
/// = 1</c> (a real selected row) previously meant this byte-for-byte
|
||||
/// comparison implicitly included the <see cref="UiMarkupList.SelectedColor"/>
|
||||
/// fill quad on BOTH sides. Neither the markup XML nor the hand-built
|
||||
/// widget below sets <c>selectionband</c>/<see cref="UiMarkupList.SelectionBandEnabled"/>,
|
||||
/// so that fill is now absent from both — the explicit assertion at the
|
||||
/// end locks in that the new no-band default applies here too, rather
|
||||
/// than leaving it to accidentally fall out of the byte-for-byte diff.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void ColumnLessList_ProducesTheIdenticalDrawRecordToTheHandBuiltWidget()
|
||||
|
|
@ -1181,6 +1193,119 @@ public sealed class MarkupListColumnsTests
|
|||
}
|
||||
|
||||
Assert.Null(viaMarkup.Columns);
|
||||
|
||||
// Neither side opted into selectionband="true" — row 1 IS selected
|
||||
// (LegacyBinding.SelectedIndex = 1) but the new default draws no
|
||||
// SelectedColor fill for it, on either the markup or the hand-built
|
||||
// path.
|
||||
Assert.False(viaMarkup.SelectionBandEnabled);
|
||||
Assert.False(handBuilt.SelectionBandEnabled);
|
||||
Assert.DoesNotContain(markupVerts, s => s.Texture == 0u
|
||||
&& Chunk(s.Verts).Any(v => ColorMatches(v, viaMarkup.SelectedColor)));
|
||||
}
|
||||
|
||||
// ── Slice 7 resemblance re-check: selectionband default + opt-in ────────
|
||||
|
||||
private sealed class SelectionBandBinding
|
||||
{
|
||||
public IReadOnlyList<string> Choices => new[] { "First", "Second" };
|
||||
public int Selected { get; set; } = 1;
|
||||
public Action<int> SelectIndex => _ => { };
|
||||
}
|
||||
|
||||
/// <summary>Any untextured (fill) quad in <paramref name="segs"/> whose vertex
|
||||
/// color matches <paramref name="color"/> — used to detect the selection-band
|
||||
/// fill regardless of its exact geometry.</summary>
|
||||
private static bool HasFillOfColor(
|
||||
IEnumerable<(uint Texture, IReadOnlyList<float> Verts)> segs, Vector4 color)
|
||||
=> segs.Where(s => s.Texture == 0u)
|
||||
.SelectMany(s => Chunk(s.Verts))
|
||||
.Any(v => ColorMatches(v, color));
|
||||
|
||||
/// <summary>
|
||||
/// Slice-7 resemblance re-check finding: VVS lists (VTank's real
|
||||
/// <c>HudList</c>) draw no persistent row-selection fill, so a
|
||||
/// column-less <c><list items="..."></c> must match that by
|
||||
/// default — <see cref="UiMarkupList.SelectionBandEnabled"/> defaults
|
||||
/// false. <c>selectionband="true"</c> opts a single list back into the
|
||||
/// visible <see cref="UiMarkupList.SelectedColor"/> band.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void SingleColumnList_SelectionBand_DefaultsOffAndAttributeOptsIn(bool enabled)
|
||||
{
|
||||
var binding = new SelectionBandBinding();
|
||||
string attr = enabled ? " selectionband=\"true\"" : "";
|
||||
string xml =
|
||||
"<panel x=\"0\" y=\"0\" w=\"200\" h=\"100\">" +
|
||||
"<list x=\"0\" y=\"0\" w=\"180\" h=\"60\" rowheight=\"18\" " +
|
||||
$"items=\"{{Choices}}\" selected=\"{{Selected}}\" onchange=\"{{SelectIndex}}\"{attr}/>" +
|
||||
"</panel>";
|
||||
|
||||
var panel = MarkupDocument.Build(xml, binding, Sprite);
|
||||
var list = Assert.IsType<UiMarkupList>(panel.Children[0]);
|
||||
Assert.Equal(enabled, list.SelectionBandEnabled);
|
||||
|
||||
var (renderer, ctx) = MakeContext(200f, 200f);
|
||||
list.DrawSelfAndChildren(ctx);
|
||||
|
||||
Assert.Equal(enabled, HasFillOfColor(renderer.DebugSpriteSegmentVerts, list.SelectedColor));
|
||||
}
|
||||
|
||||
/// <summary>Same fix, exercised through <c><column></c> mode
|
||||
/// (<see cref="UiMarkupList.DrawColumns"/>) — the gate applies to both
|
||||
/// draw branches of the shared widget, not just the legacy one.</summary>
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void ColumnModeList_SelectionBand_DefaultsOffAndAttributeOptsIn(bool enabled)
|
||||
{
|
||||
var binding = new SelectionBandBinding();
|
||||
string attr = enabled ? " selectionband=\"true\"" : "";
|
||||
string xml =
|
||||
"<panel x=\"0\" y=\"0\" w=\"200\" h=\"100\">" +
|
||||
$"<list x=\"0\" y=\"0\" w=\"180\" h=\"60\" rowheight=\"18\" selected=\"{{Selected}}\" onchange=\"{{SelectIndex}}\"{attr}>" +
|
||||
" <column type=\"text\" width=\"*\" items=\"{Choices}\"/>" +
|
||||
"</list></panel>";
|
||||
|
||||
var panel = MarkupDocument.Build(xml, binding, Sprite);
|
||||
var list = Assert.IsType<UiMarkupList>(panel.Children[0]);
|
||||
Assert.Equal(enabled, list.SelectionBandEnabled);
|
||||
|
||||
var (renderer, ctx) = MakeContext(200f, 200f);
|
||||
list.DrawSelfAndChildren(ctx);
|
||||
|
||||
Assert.Equal(enabled, HasFillOfColor(renderer.DebugSpriteSegmentVerts, list.SelectedColor));
|
||||
}
|
||||
|
||||
/// <summary>Parse-only pin: <c>selectionband</c> follows the same silent
|
||||
/// literal-bool convention as <c>openupward</c>/<c>clearonsubmit</c>
|
||||
/// (<see cref="MarkupDocument"/>'s private <c>B</c> helper) — omitted
|
||||
/// defaults false, and <c>"true"</c> sets the property, with no draw
|
||||
/// involved at all.</summary>
|
||||
[Fact]
|
||||
public void ListSelectionBandAttribute_ParsesToProperty()
|
||||
{
|
||||
var binding = new SelectionBandBinding();
|
||||
const string xmlDefault =
|
||||
"<panel x=\"0\" y=\"0\" w=\"200\" h=\"100\">" +
|
||||
"<list x=\"0\" y=\"0\" w=\"180\" h=\"60\" items=\"{Choices}\" " +
|
||||
"selected=\"{Selected}\" onchange=\"{SelectIndex}\"/>" +
|
||||
"</panel>";
|
||||
const string xmlEnabled =
|
||||
"<panel x=\"0\" y=\"0\" w=\"200\" h=\"100\">" +
|
||||
"<list x=\"0\" y=\"0\" w=\"180\" h=\"60\" items=\"{Choices}\" " +
|
||||
"selected=\"{Selected}\" onchange=\"{SelectIndex}\" selectionband=\"true\"/>" +
|
||||
"</panel>";
|
||||
|
||||
var defaultList = Assert.IsType<UiMarkupList>(
|
||||
MarkupDocument.Build(xmlDefault, binding, Sprite).Children[0]);
|
||||
var enabledList = Assert.IsType<UiMarkupList>(
|
||||
MarkupDocument.Build(xmlEnabled, binding, Sprite).Children[0]);
|
||||
|
||||
Assert.False(defaultList.SelectionBandEnabled);
|
||||
Assert.True(enabledList.SelectionBandEnabled);
|
||||
}
|
||||
|
||||
// ── Fix round: end-to-end MarkupDocument builds (fix item 10) ───────────
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue