fix(studio): Character window — show only the active tab page (clears the dark overlay)
LayoutDesc 0x2100002E is a tabbed window; all three pages (Attributes/Skills/Titles) mount their content as overlapping root children. acdream drew all three, so the inactive pages' backdrops painted over the active content — the dim "almost opaque" cover the user reported, and it displaced the XP meter. The shared gmStatManagement ids are duplicated across pages and _byId keeps the LAST-mounted copy, so every bound widget lives in exactly one page; the controller now keeps that page visible (ContainsWidget reference-walk from the bound name element) and hides the rest. Header/attrs/XP-bar now render clean + correctly placed. Tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0d87e4dc31
commit
27819514af
1 changed files with 26 additions and 0 deletions
|
|
@ -76,6 +76,32 @@ public static class CharacterStatController
|
||||||
rows.LinesProvider = () => AttributeRows(data());
|
rows.LinesProvider = () => AttributeRows(data());
|
||||||
list.AddChild(rows);
|
list.AddChild(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Active-page selection (fixes the "dark overlay") ──────────────────
|
||||||
|
// 0x2100002E is a tabbed window: all three tab pages (Attributes / Skills / Titles) mount
|
||||||
|
// their content as separate root children that OVERLAP in the same content rect. Retail
|
||||||
|
// shows only the active page; acdream draws them all, so the inactive pages' backdrops paint
|
||||||
|
// over the active content (the dim "almost opaque" cover). The shared gmStatManagement ids
|
||||||
|
// are duplicated across pages and acdream's _byId keeps the LAST-mounted copy, so every widget
|
||||||
|
// we just bound lives in exactly ONE page. Keep that page visible; hide the rest.
|
||||||
|
if (layout.FindElement(NameId) is { } anchor && layout.Root is { } root)
|
||||||
|
{
|
||||||
|
foreach (var page in root.Children)
|
||||||
|
{
|
||||||
|
if (page.Children.Count == 0) continue; // tab-bar buttons are leaves — leave them
|
||||||
|
page.Visible = ContainsWidget(page, anchor); // only the bound page stays visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Depth-first reference search: is <paramref name="target"/> somewhere under
|
||||||
|
/// <paramref name="node"/>? Used to find which overlapping tab page owns the bound widgets.</summary>
|
||||||
|
private static bool ContainsWidget(UiElement node, UiElement target)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(node, target)) return true;
|
||||||
|
foreach (var c in node.Children)
|
||||||
|
if (ContainsWidget(c, target)) return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float LineHeight = 18f;
|
private const float LineHeight = 18f;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue