fix(ui): render live component counts

Port retail text-surface clipping so the 15px component count field remains visible under the 16px DAT font. Cover SetStackSize decrements and final component removal while preserving desired restock values.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-15 18:11:02 +02:00
parent a1175e6aac
commit 0527325b25
7 changed files with 217 additions and 36 deletions

View file

@ -323,9 +323,12 @@ public sealed class SpellbookWindowControllerTests
Assert.Equal("Copper Scarab", Assert.Single(
Assert.IsType<UiText>(copper.Content.FindElement(
ComponentBookTemplateFactory.NameId)).LinesProvider()).Text);
Assert.Equal("2", Assert.Single(
Assert.IsType<UiText>(copper.Content.FindElement(
ComponentBookTemplateFactory.OwnedCountId)).LinesProvider()).Text);
UiText ownedCount = Assert.IsType<UiText>(copper.Content.FindElement(
ComponentBookTemplateFactory.OwnedCountId));
Assert.Equal((224f, 0f, 60f, 15f),
(ownedCount.Left, ownedCount.Top, ownedCount.Width, ownedCount.Height));
Assert.False(ownedCount.OneLine);
Assert.Equal("2", Assert.Single(ownedCount.LinesProvider()).Text);
UiField desiredField = Assert.IsType<UiField>(copper.Content.FindElement(
ComponentBookTemplateFactory.DesiredCountId));
Assert.Equal((224f, 15f, 60f, 15f),
@ -361,6 +364,27 @@ public sealed class SpellbookWindowControllerTests
Assert.False(copper.Selected);
selection.Select(0xDEADBEEFu, SelectionChangeSource.World);
Assert.False(amaranth.Selected);
// ACE consumes components through SetStackSize (0x0197). The object table
// publishes ObjectUpdated; the controller rebuilds the tracker total on Tick.
Assert.True(objects.UpdateStackSize(10u, stackSize: 1, value: 0));
controller.Tick();
UiTemplateListSlot updatedCopper = Assert.IsType<UiTemplateListSlot>(list.GetItem(1));
Assert.Equal("1", Assert.Single(
Assert.IsType<UiText>(updatedCopper.Content.FindElement(
ComponentBookTemplateFactory.OwnedCountId)).LinesProvider()).Text);
Assert.Equal("21", Assert.IsType<UiField>(updatedCopper.Content.FindElement(
ComponentBookTemplateFactory.DesiredCountId)).Text);
// Consuming the final item removes its object. The row disappears while the
// category remains because Diamond Scarab is still owned.
Assert.True(objects.Remove(10u));
controller.Tick();
Assert.DoesNotContain(
Enumerable.Range(0, list.GetNumUIItems())
.Select(list.GetItem)
.OfType<UiTemplateListSlot>(),
slot => slot.EntryId == 100u);
}
private static SpellbookWindowController? Bind(