namespace AcDream.App.UI; /// /// Retail gmPanelUI panel ids carried by DAT property 0x10000029. /// The toolbar exposes only a subset of these ids; Helpful/Harmful effects use /// the authored gmUIElement_EffectsIndicator buttons instead. /// public static class RetailPanelCatalog { public const uint CharacterInformation = 3u; public const uint PositiveEffects = 4u; public const uint NegativeEffects = 5u; public const uint Inventory = 7u; public const uint LinkStatus = 8u; public const uint MiniGame = 9u; public const uint Character = 11u; public const uint Magic = 13u; public const uint Vitae = 15u; /// /// The retail Options panel's gmPanelUI slot key — byte-verified /// from the toolbar options button's OWN authored property /// 0x10000029 = 10 (fixture toolbar_21000016.json, /// element 0x1000019B) and independently corroborated by /// docs/research/2026-08-10-options-panel-structure.md §1.4's /// decompiled slot-key table (host 0x2100006E, slot /// 0x1000018D → key 10). Campaign OP slice OP3. /// public const uint Options = 10u; /// /// Campaign FA slice FA3: the four-tab Friends/Allegiance/Fellowship/ /// Squelch panel's gmPanelUI slot key — byte-verified from the /// live installed DATs (host 0x2100006E slot 0x1000018F's /// own authored 0x10000029 = 12, FaPanelSlotProbeTests). /// No toolbar button authors this id (lane A §6.1: the open path is /// keyboard-only, F3/F4) — is therefore in /// only, not , the same /// convention // /// // /// already use for their own non-toolbar open paths. /// public const uint SocialPanel = 12u; private static readonly (uint PanelId, string WindowName)[] Mounted = { (CharacterInformation, WindowNames.CharacterInformation), (PositiveEffects, WindowNames.PositiveEffects), (NegativeEffects, WindowNames.NegativeEffects), (Inventory, WindowNames.Inventory), (LinkStatus, WindowNames.LinkStatus), (MiniGame, WindowNames.MiniGame), (Character, WindowNames.Character), (Magic, WindowNames.Spellbook), (Vitae, WindowNames.Vitae), (Options, WindowNames.Options), (SocialPanel, WindowNames.SocialPanel), }; private static readonly (uint PanelId, string WindowName)[] Toolbar = { (Inventory, WindowNames.Inventory), (Character, WindowNames.Character), (Magic, WindowNames.Spellbook), (Options, WindowNames.Options), }; public static IReadOnlyList<(uint PanelId, string WindowName)> MountedPanels => Mounted; public static IReadOnlyList<(uint PanelId, string WindowName)> ToolbarPanels => Toolbar; public static bool TryGetWindowName(uint panelId, out string windowName) { foreach (var entry in Mounted) { if (entry.PanelId != panelId) continue; windowName = entry.WindowName; return true; } windowName = string.Empty; return false; } public static bool TryGetPanelId(string windowName, out uint panelId) { foreach (var entry in Mounted) { if (!string.Equals(entry.WindowName, windowName, StringComparison.Ordinal)) continue; panelId = entry.PanelId; return true; } panelId = 0; return false; } }