Port the retail horizontal ItemList empty-slot padding and share UIItem shortcut-number graphics with the status toolbar. Preserve all authored face children on compound DAT buttons so the three-piece Cast control reflows and renders as one complete button. Co-authored-by: OpenAI Codex <codex@openai.com>
117 lines
3.6 KiB
C#
117 lines
3.6 KiB
C#
using AcDream.App.UI;
|
|
using Xunit;
|
|
|
|
namespace AcDream.App.Tests.UI;
|
|
|
|
public class UiItemListTests
|
|
{
|
|
[Fact]
|
|
public void IsLeafWidget() => Assert.True(new UiItemList().ConsumesDatChildren);
|
|
|
|
[Fact]
|
|
public void StartsWithOneCell_forSingleCellSlot()
|
|
{
|
|
var list = new UiItemList();
|
|
Assert.Equal(1, list.GetNumUIItems());
|
|
Assert.NotNull(list.GetItem(0));
|
|
}
|
|
|
|
[Fact]
|
|
public void Cell_returnsTheFirstSlot()
|
|
{
|
|
var list = new UiItemList();
|
|
Assert.Same(list.GetItem(0), list.Cell);
|
|
}
|
|
|
|
[Fact]
|
|
public void CellEmptySprite_stamps_existing_and_future_cells()
|
|
{
|
|
var list = new UiItemList(); // ctor adds one default cell
|
|
Assert.Equal(0x060074CFu, list.GetItem(0)!.EmptySprite); // UiItemSlot default before set
|
|
|
|
list.CellEmptySprite = 0x06004D20u; // a pack-slot sprite
|
|
Assert.Equal(0x06004D20u, list.GetItem(0)!.EmptySprite); // existing cell re-stamped
|
|
|
|
list.AddItem(new UiItemSlot());
|
|
Assert.Equal(0x06004D20u, list.GetItem(1)!.EmptySprite); // new cell stamped
|
|
}
|
|
|
|
[Fact]
|
|
public void CellEmptySprite_zero_leaves_the_UiItemSlot_default()
|
|
{
|
|
var list = new UiItemList();
|
|
list.CellEmptySprite = 0u;
|
|
Assert.Equal(0x060074CFu, list.GetItem(0)!.EmptySprite); // unchanged default
|
|
}
|
|
|
|
[Fact]
|
|
public void CatalogDrop_routes_payload_and_local_coordinates()
|
|
{
|
|
var list = new UiItemList();
|
|
object payload = new();
|
|
(object Payload, int X, int Y)? received = null;
|
|
list.CatalogDropped = (value, x, y) => received = (value, x, y);
|
|
|
|
bool handled = list.OnEvent(new UiEvent(
|
|
0, list, UiEventType.DropReleased, Data1: 17, Data2: 9, Payload: payload));
|
|
|
|
Assert.True(handled);
|
|
Assert.NotNull(received);
|
|
Assert.Same(payload, received.Value.Payload);
|
|
Assert.Equal((17, 9), (received.Value.X, received.Value.Y));
|
|
}
|
|
|
|
[Fact]
|
|
public void RetailHorizontalEmptySlots_FillViewport_AndShrinkOnlyEmptyTail()
|
|
{
|
|
var list = new UiItemList
|
|
{
|
|
Width = 130f,
|
|
Height = 32f,
|
|
CellWidth = 32f,
|
|
CellHeight = 32f,
|
|
SingleRow = true,
|
|
FillVisibleEmptySlots = true,
|
|
EmptySlotFactory = () => new UiCatalogSlot(),
|
|
};
|
|
list.Flush();
|
|
list.AddItem(new UiCatalogSlot { EntryId = 42u });
|
|
list.LayoutCells();
|
|
|
|
Assert.Equal(4, list.GetNumUIItems());
|
|
Assert.Equal((0f, 32f, 64f, 96f),
|
|
(list.GetItem(0)!.Left, list.GetItem(1)!.Left,
|
|
list.GetItem(2)!.Left, list.GetItem(3)!.Left));
|
|
|
|
list.Width = 65f;
|
|
list.LayoutCells();
|
|
Assert.Equal(2, list.GetNumUIItems());
|
|
Assert.Equal(42u, Assert.IsType<UiCatalogSlot>(list.GetItem(0)).EntryId);
|
|
|
|
list.Width = 16f;
|
|
list.LayoutCells();
|
|
Assert.Single(list.Children); // the occupied cell is never discarded
|
|
}
|
|
|
|
[Fact]
|
|
public void ScrollItemIntoView_moves_only_when_row_is_outside_viewport()
|
|
{
|
|
var list = new UiItemList
|
|
{
|
|
Width = 100f,
|
|
Height = 64f,
|
|
Columns = 1,
|
|
CellWidth = 100f,
|
|
CellHeight = 32f,
|
|
};
|
|
list.Flush();
|
|
for (int i = 0; i < 5; i++) list.AddItem(new UiItemSlot());
|
|
|
|
list.ScrollItemIntoView(3);
|
|
Assert.Equal(64, list.Scroll.ScrollY);
|
|
list.ScrollItemIntoView(2);
|
|
Assert.Equal(64, list.Scroll.ScrollY);
|
|
list.ScrollItemIntoView(0);
|
|
Assert.Equal(0, list.Scroll.ScrollY);
|
|
}
|
|
}
|