diff --git a/src/AcDream.App/UI/Layout/InventoryController.cs b/src/AcDream.App/UI/Layout/InventoryController.cs index 41fd325a..9aa6ac45 100644 --- a/src/AcDream.App/UI/Layout/InventoryController.cs +++ b/src/AcDream.App/UI/Layout/InventoryController.cs @@ -20,6 +20,16 @@ public sealed class InventoryController public const uint BurdenTextId = 0x100001D8u; // gmBackpackUI m_burdenText ("%d%%") public const uint BurdenCaptionId = 0x100001D7u; // "Burden" public const uint ContentsCaptionId = 0x100001C5u; // "Contents of Backpack" + public const uint ContentsScrollbarId = 0x100001C7u; // gm3DItemsUI gutter scrollbar (right of the grid) + + // Scrollbar chrome from base layout 0x2100003E (shared with the chat scrollbar; see + // ChatWindowController). Both inventory + chat scrollbars inherit this base. + private const uint ScrollTrackSprite = 0x06004C5Fu; + private const uint ScrollThumbSprite = 0x06004C63u; // 3-slice middle tile + private const uint ScrollThumbTop = 0x06004C60u; // 3-slice top cap + private const uint ScrollThumbBot = 0x06004C66u; // 3-slice bottom cap + private const uint ScrollUpSprite = 0x06004C6Cu; // up arrow (top button) + private const uint ScrollDownSprite = 0x06004C69u; // down arrow (bottom button) // 3D-items grid: 192x96 → 6 cols x 3 rows of the 32x32 UIItem cell (template 0x21000037). private const int ContentsColumns = 6; @@ -66,6 +76,21 @@ public sealed class InventoryController _contentsGrid.CellWidth = CellPx; _contentsGrid.CellHeight = CellPx; } + + // Bind the gutter scrollbar to the contents grid's scroll model (the factory built + // 0x100001C7 as a bare Type-11 UiScrollbar; wire it like ChatWindowController does). + if (_contentsGrid is not null + && layout.FindElement(ContentsScrollbarId) is UiScrollbar bar) + { + bar.Model = _contentsGrid.Scroll; + bar.SpriteResolve = _contentsGrid.SpriteResolve; // chrome resolve from the factory ctor + bar.TrackSprite = ScrollTrackSprite; + bar.ThumbSprite = ScrollThumbSprite; + bar.ThumbTopSprite = ScrollThumbTop; + bar.ThumbBotSprite = ScrollThumbBot; + bar.UpSprite = ScrollUpSprite; + bar.DownSprite = ScrollDownSprite; + } if (_containerList is not null) { _containerList.Columns = 1; diff --git a/tests/AcDream.App.Tests/UI/Layout/InventoryControllerTests.cs b/tests/AcDream.App.Tests/UI/Layout/InventoryControllerTests.cs index d1fb4746..53844cd5 100644 --- a/tests/AcDream.App.Tests/UI/Layout/InventoryControllerTests.cs +++ b/tests/AcDream.App.Tests/UI/Layout/InventoryControllerTests.cs @@ -22,6 +22,7 @@ public class InventoryControllerTests private const uint BurdenText = 0x100001D8u; private const uint BurdenCaption = 0x100001D7u; private const uint ContentsCaption = 0x100001C5u; + private const uint ContentsScrollbar = 0x100001C7u; private static (ImportedLayout layout, UiItemList grid, UiItemList containers, UiItemList top, UiMeter meter, UiElement burdenText, @@ -34,15 +35,16 @@ public class InventoryControllerTests var burdenText = new TestElement { Width = 36, Height = 15 }; var burdenCap = new TestElement { Width = 36, Height = 15 }; var contentsCap = new TestElement { Width = 192, Height = 15 }; + var scrollbar = new UiScrollbar { Width = 16, Height = 96 }; var root = new TestElement { Width = 300, Height = 362 }; root.AddChild(grid); root.AddChild(containers); root.AddChild(top); root.AddChild(meter); root.AddChild(burdenText); root.AddChild(burdenCap); - root.AddChild(contentsCap); + root.AddChild(contentsCap); root.AddChild(scrollbar); var byId = new Dictionary { [ContentsGrid] = grid, [ContainerList] = containers, [TopContainer] = top, [BurdenMeter] = meter, [BurdenText] = burdenText, [BurdenCaption] = burdenCap, - [ContentsCaption] = contentsCap, + [ContentsCaption] = contentsCap, [ContentsScrollbar] = scrollbar, }; return (new ImportedLayout(root, byId), grid, containers, top, meter, burdenText, burdenCap, contentsCap); @@ -192,6 +194,15 @@ public class InventoryControllerTests Assert.Equal(0.2f, meter.Fill() ?? -1f, 3); // 9000/15000/3 } + [Fact] + public void Contents_grid_scrollbar_binds_to_the_grid_scroll_model() + { + var (layout, grid, _, _, _, _, _, _) = BuildLayout(); + Bind(layout, new ClientObjectTable()); + var bar = (UiScrollbar)layout.FindElement(ContentsScrollbar)!; + Assert.Same(grid.Scroll, bar.Model); // the bar drives the grid's scroll + } + // Reads the text of the UiText caption child attached by the controller. private static string CaptionText(UiElement host) {