diff --git a/src/AcDream.App/UI/UiItemList.cs b/src/AcDream.App/UI/UiItemList.cs index 8cfef904..b25e45cb 100644 --- a/src/AcDream.App/UI/UiItemList.cs +++ b/src/AcDream.App/UI/UiItemList.cs @@ -129,6 +129,17 @@ public sealed class UiItemList : UiElement _cells.Clear(); } + public override bool OnEvent(in UiEvent e) + { + if (e.Type == UiEventType.Scroll && CellWidth > 0f) + { + // Mirror UiText: Silk +Y wheel = up/older = decrease ScrollY; negate Data0. + Scroll.ScrollByLines(-e.Data0); + return true; + } + return base.OnEvent(e); + } + protected override void OnDraw(UiRenderContext ctx) { // The factory sets Width/Height AFTER construction, so re-layout each frame: diff --git a/tests/AcDream.App.Tests/UI/UiItemListScrollTests.cs b/tests/AcDream.App.Tests/UI/UiItemListScrollTests.cs index 48af8e79..d89c8be7 100644 --- a/tests/AcDream.App.Tests/UI/UiItemListScrollTests.cs +++ b/tests/AcDream.App.Tests/UI/UiItemListScrollTests.cs @@ -51,4 +51,15 @@ public sealed class UiItemListScrollTests Assert.Equal(0f, list.GetItem(6)!.Top); // row 1 now at the view top Assert.True(list.GetItem(18)!.Visible); // row 3 now visible } + + [Fact] + public void Wheel_down_scrolls_toward_the_bottom() + { + var list = Grid(30); // max scroll 64, LineHeight 32 + // Silk wheel +Y = up/older; UiText negates Data0. Wheel DOWN (Data0 < 0) → +ScrollY. + var e = new UiEvent(0u, null, UiEventType.Scroll, Data0: -1); + bool handled = list.OnEvent(e); + Assert.True(handled); + Assert.Equal(32, list.Scroll.ScrollY); // one line (32px) down + } }