diff --git a/src/AcDream.App/UI/Layout/DatWidgetFactory.cs b/src/AcDream.App/UI/Layout/DatWidgetFactory.cs index e8791e44..15ba9a85 100644 --- a/src/AcDream.App/UI/Layout/DatWidgetFactory.cs +++ b/src/AcDream.App/UI/Layout/DatWidgetFactory.cs @@ -115,6 +115,9 @@ public static class DatWidgetFactory .OrderBy(c => c.ReadOrder) .ToList(); + if (containers.Count != 2) + Console.WriteLine($"[D.2b] meter 0x{info.Id:X8}: {containers.Count} Type-3 slice containers (expected 2) — bars may render as solid-color fallback."); + if (containers.Count >= 1) { var (l, t, r) = SliceIds(containers[0]); @@ -150,17 +153,17 @@ public static class DatWidgetFactory { // Only children that have a non-zero DirectState image are slice candidates. // The expand-detail overlay has NO DirectState entry, so it's excluded here. + // Project the File during filtering to avoid a second TryGetValue lookup. + // Stable sort: on an X tie, original Children insertion order (dat key-sort order) wins. var slices = container.Children .Where(c => c.StateMedia.TryGetValue("", out var med) && med.File != 0) - .OrderBy(c => c.X) + .Select(c => (c.X, File: c.StateMedia[""].File)) + .OrderBy(t => t.X) .ToList(); - static uint File(ElementInfo e) - => e.StateMedia.TryGetValue("", out var med) ? med.File : 0u; - - uint left = slices.Count > 0 ? File(slices[0]) : 0u; - uint tile = slices.Count > 1 ? File(slices[1]) : 0u; - uint right = slices.Count > 2 ? File(slices[2]) : 0u; + uint left = slices.Count > 0 ? slices[0].File : 0u; + uint tile = slices.Count > 1 ? slices[1].File : 0u; + uint right = slices.Count > 2 ? slices[2].File : 0u; return (left, tile, right); } diff --git a/tests/AcDream.App.Tests/UI/Layout/DatWidgetFactoryTests.cs b/tests/AcDream.App.Tests/UI/Layout/DatWidgetFactoryTests.cs index 6a1ef9c1..4258d0b6 100644 --- a/tests/AcDream.App.Tests/UI/Layout/DatWidgetFactoryTests.cs +++ b/tests/AcDream.App.Tests/UI/Layout/DatWidgetFactoryTests.cs @@ -108,5 +108,8 @@ public class DatWidgetFactoryTests Assert.Equal(FrontL, m.FrontLeft); Assert.Equal(FrontT, m.FrontTile); Assert.Equal(FrontR, m.FrontRight); + // Overlay (ShowDetail-only, no DirectState "") must not leak into any slice slot. + Assert.NotEqual(OverlayFile, m.FrontRight); + Assert.NotEqual(OverlayFile, m.FrontTile); } }