fix(ui): bind visible skills scrollbar

This commit is contained in:
Erik 2026-07-10 18:29:55 +02:00
parent f684f874df
commit 4bb37e302e
2 changed files with 28 additions and 3 deletions

View file

@ -621,8 +621,13 @@ public static class CharacterStatController
if (spriteResolve is null)
return null;
UiElement? source =
(contentPage is not null
// The mounted character sublayout contains duplicated stat-management
// branches with the same element ids. Bind the scrollbar adjacent to the
// active list first; a page-wide DFS can select an inactive duplicate that
// is never drawn while leaving the visible gutter unconfigured.
UiElement? source = statList?.Parent?.Children.FirstOrDefault(
static el => HasDatElementId(el, ListScrollbarId))
?? (contentPage is not null
? FindInSubtree(contentPage, static el => HasDatElementId(el, ListScrollbarId))
: null)
?? layout.FindElement(ListScrollbarId);
@ -1674,7 +1679,17 @@ public static class CharacterStatController
=> DatElementId(element) == id;
private static uint DatElementId(UiElement element)
=> element switch
{
// DatWidgetFactory assigns the canonical id on every imported widget,
// including behavioral types such as UiScrollbar that do not expose a
// type-specific ElementId property. Prefer it so subtree role lookup is
// independent of the concrete widget class. The fallbacks keep the small
// hand-built controller fixtures working when they construct widgets
// directly instead of through the factory.
if (element.DatElementId != 0u)
return element.DatElementId;
return element switch
{
UiDatElement datElement => datElement.ElementId,
UiButton button => button.ElementId,
@ -1682,6 +1697,7 @@ public static class CharacterStatController
UiText text => text.ElementId,
_ => 0u,
};
}
private static UiElement? FindElementByDatId(ImportedLayout layout, UiElement? scope, uint id)
{