feat(D.2b): MarkupDocument (XML -> UiElement tree); vitals panel from vitals.xml
Implements Task 8 of the D.2b retail-UI plan. MarkupDocument.Build() parses
KSML-style panel markup into a live UiNineSlicePanel subtree, resolving
{Binding} attribute expressions against a supplied object via reflection.
Color format is #AARRGGBB (alpha-first, matching controls.ini). Handles
<panel> root (geometry + optional title label) and <meter> children (fill,
label, bar color). Future element kinds (label, button, image) extend the
switch without touching existing code.
vitals.xml encodes the just-approved vitals panel layout (health red #FFC70D0D,
stamina gold #FFD49E1F, mana blue #FF1F33D9); ships next to the binary via
PreserveNewest csproj rule. GameWindow.cs drops the 35-line hand-built panel
block in favour of a 4-line File.ReadAllText + MarkupDocument.Build call —
identical tree, identical render, now data-driven.
2 new tests (Build_CreatesPanelWithMeterFillLabelAndGeometry,
Build_NullBindingValuesYieldNullFillAndLabel) + 11 total targeted green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
97bd1d2f09
commit
07bf6cbf60
5 changed files with 182 additions and 35 deletions
50
tests/AcDream.App.Tests/UI/MarkupDocumentTests.cs
Normal file
50
tests/AcDream.App.Tests/UI/MarkupDocumentTests.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using AcDream.App.UI;
|
||||
|
||||
namespace AcDream.App.Tests.UI;
|
||||
|
||||
public class MarkupDocumentTests
|
||||
{
|
||||
private sealed class FakeBinding
|
||||
{
|
||||
public float HealthPercent => 0.5f;
|
||||
public uint? HealthCurrent => 109;
|
||||
public uint? HealthMax => 218;
|
||||
public float? ManaPercent => null;
|
||||
public uint? ManaCurrent => null;
|
||||
public uint? ManaMax => null;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_CreatesPanelWithMeterFillLabelAndGeometry()
|
||||
{
|
||||
const string xml =
|
||||
"<panel id=\"acdream.vitals\" x=\"10\" y=\"30\" w=\"220\" h=\"96\" title=\"Vitals\">" +
|
||||
" <meter id=\"health\" x=\"8\" y=\"24\" w=\"200\" h=\"14\" fill=\"{HealthPercent}\" cur=\"{HealthCurrent}\" max=\"{HealthMax}\" color=\"#FFFF0000\"/>" +
|
||||
"</panel>";
|
||||
|
||||
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
|
||||
|
||||
Assert.IsType<UiNineSlicePanel>(panel);
|
||||
Assert.Equal(10f, panel.Left);
|
||||
Assert.Equal(220f, panel.Width);
|
||||
Assert.Equal(2, panel.Children.Count); // title UiLabel + 1 meter
|
||||
var meter = Assert.IsType<UiMeter>(panel.Children[1]);
|
||||
Assert.Equal(8f, meter.Left);
|
||||
Assert.Equal(200f, meter.Width);
|
||||
Assert.Equal(0.5f, meter.Fill());
|
||||
Assert.Equal("109/218", meter.Label());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_NullBindingValuesYieldNullFillAndLabel()
|
||||
{
|
||||
const string xml =
|
||||
"<panel id=\"v\" x=\"0\" y=\"0\" w=\"10\" h=\"10\" title=\"V\">" +
|
||||
" <meter id=\"mana\" x=\"0\" y=\"0\" w=\"10\" h=\"2\" fill=\"{ManaPercent}\" cur=\"{ManaCurrent}\" max=\"{ManaMax}\" color=\"#FF0000FF\"/>" +
|
||||
"</panel>";
|
||||
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
|
||||
var meter = Assert.IsType<UiMeter>(panel.Children[1]);
|
||||
Assert.Null(meter.Fill());
|
||||
Assert.Null(meter.Label());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue