From 7a825111abc8dfda6d86c3854761e91c0d3a453b Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 6 Sep 2026 19:30:54 +0700 Subject: [PATCH] the world map's arrow shows on zone sheets, and UIParent goes stock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the world map's arrow shows on every zone sheet, and alt-clicking a town jumps there: the stock file creates the player arrow as a `Model` child of `WorldMapFrame` and lays a zone sheet's explored-area overlays as ARTWORK textures on `WorldMapDetailFrame` — one `(strata, level)` bucket, where the draw layer outranks the frame — and benilla drew a model's scene at the frame's own layer-0 slot, so every overlay painted over it (the continent sheet has no overlays, which is why it was the only sheet with an arrow); wow-re's carve: a layer batch carries three sub-arrays — quads, the string batch, a render-callback list — that `0x76fb00` drains in that order, and `0x76d160` registers a model's callback only for layer 2 (`0x76d17f cmp ebx,2`), so a model's scene is ARTWORK content, neither a separate pass nor a layer-0 slot; a `ModelPane` quad now keys at the ARTWORK content rank, which re-orders the pet page's happiness icon (a sibling's BACKGROUND quad) under the pane's scene — the reference's own order, harmless because the bake is transparent where the model is not; a model against a LATER-linked ARTWORK font string in the same bucket is still ordered by link stamp, named not built; and the alt-click jump, which required the topmost frame under the cursor to be `WorldMapButton` itself while the stock file parents every POI icon and blip to that button, now walks up from whatever was hit to the button and takes its rect — the map's own chrome still answers nothing (1992) - `UIParent` is the reference's own: `UIParent.xml` loads off the chain at its toc's slot, right after `WorldFrame.xml`, sourcing `UIParent.lua` and `LocaleProperties.lua` itself, and our `UIParent.xml` + `UiPanels.xml` — 3086 lines of transcribed `UIParent.lua` — are deleted; the one unbound verb the stock file ticks, `CheckReadyCheckTime`, was already 1989's; back from the reference: all sixty-six registered events and their arms (`PLAYER_CONTROL_LOST`/`_GAINED`, `RAID_ROSTER_UPDATE`, the trade-request pair, `PLAYER_SKINNED`, `GOSSIP_ENTER_CODE`), the ESC ladder as written — StaticPopup, the options window's Cancel, the game menu, `CloseMenus`, `SpellStopCasting`, `SpellStopTargeting`, `CloseAllWindows`, `ClearTarget`, else open — so ESC no longer clears a held cursor item or cancels the colour picker, two arms ours had grown that the reference does not have; the fade/flash/pulse kits walked from `UIParent`'s own OnUpdate in place of three 1×1 driver frames of ours, so a cinematic's `UIParent:Hide()` stops the walks as it does there; the managed bottom-stack positions without our `UIParent_RegisterManagedPositionListener` extension, which no shipped file registered any more; `LowHealthFrame`/`OutOfControlFrame`; and the `firstTimeLoaded` close on re-show; what stayed ours moved out — the window tab template and its OnUpdate settle (1004's async-measure adapter) and `BENILLA_FALLBACK_ICON` to `ScrollTemplates.xml`, 0561's bag verbs to `ContainerFrameAdapters`, the script log's slot row to its own file, `OptionsFrameCancel = OptionsFrameCloseButton` beside the two options aliases — and the Auction/Inspect/Macro/Talent panel rows, verbatim copies of the LoadOnDemand addons' own registrations, go; the reference also decides that the area spirit healer's dialog accepts on show with one CANCEL button, that losing control closes every window bar the reference's exceptions, and that the bottom-bar clearance reads the saved globals `SHOW_MULTI_ACTIONBAR_1`/`_2` rather than the bars' shown state; three integration binaries that kept private copies of the manifest loader use the shared one now (1988) Co-Authored-By: Claude Fable 5.1 --- .../assets/ui/ContainerFrameAdapters.xml | 79 +- .../benilla-app/assets/ui/GameMenuFrame.xml | 6 +- .../benilla-app/assets/ui/KeyBindingsPage.xml | 2 +- crates/benilla-app/assets/ui/OptionsFrame.xml | 7 +- .../benilla-app/assets/ui/ScriptLogFrame.xml | 7 +- .../benilla-app/assets/ui/ScrollTemplates.xml | 201 +++ crates/benilla-app/assets/ui/UIParent.xml | 1546 ----------------- crates/benilla-app/assets/ui/UiPanels.xml | 1540 ---------------- crates/benilla-app/assets/ui/benilla.toc | 44 +- crates/benilla-app/src/ui_chat/tests.rs | 66 +- crates/benilla-app/src/ui_items/drain.rs | 3 +- .../src/ui_script/action_bar_tests.rs | 17 +- crates/benilla-app/src/ui_script/bag_tests.rs | 18 + .../src/ui_script/battlefield_tests.rs | 3 +- .../benilla-app/src/ui_script/binder_tests.rs | 3 +- .../src/ui_script/bottom_hud_tests.rs | 42 +- .../benilla-app/src/ui_script/buff_tests.rs | 3 +- .../benilla-app/src/ui_script/cast_tests.rs | 17 +- .../src/ui_script/character_tests.rs | 4 +- .../src/ui_script/chat_options_tests.rs | 3 +- .../src/ui_script/chat_resize_tests.rs | 3 +- .../benilla-app/src/ui_script/chat_tests.rs | 5 +- .../src/ui_script/cinematic_tests.rs | 3 +- .../src/ui_script/color_picker_tests.rs | 21 +- .../src/ui_script/combat_text_tests.rs | 2 +- .../src/ui_script/combo_frame_tests.rs | 3 +- .../benilla-app/src/ui_script/death_tests.rs | 3 +- .../src/ui_script/delete_item_tests.rs | 4 +- .../src/ui_script/dressup_tests.rs | 10 +- .../src/ui_script/dropdown_tests.rs | 2 +- .../benilla-app/src/ui_script/duel_tests.rs | 3 +- .../src/ui_script/durability_tests.rs | 6 +- .../src/ui_script/enchant_confirm_tests.rs | 3 +- .../benilla-app/src/ui_script/errors_tests.rs | 6 +- .../benilla-app/src/ui_script/escape_tests.rs | 24 +- .../src/ui_script/exp_bar_tests.rs | 2 +- .../benilla-app/src/ui_script/fade_tests.rs | 101 +- .../src/ui_script/game_menu_tests.rs | 23 +- .../src/ui_script/group_loot_tests.rs | 25 +- .../src/ui_script/help_frame_tests.rs | 3 +- .../src/ui_script/honor_frame_tests.rs | 4 +- .../src/ui_script/inspect_tests.rs | 8 +- .../src/ui_script/instance_tests.rs | 3 +- .../src/ui_script/keybindings_tests.rs | 3 +- .../benilla-app/src/ui_script/loot_tests.rs | 4 +- .../benilla-app/src/ui_script/macro_tests.rs | 3 +- crates/benilla-app/src/ui_script/manifest.rs | 10 +- .../src/ui_script/merchant_tests.rs | 13 +- .../src/ui_script/micro_menu_tests.rs | 2 +- .../src/ui_script/minimap_tests.rs | 3 +- .../src/ui_script/mirror_timer_tests.rs | 3 +- .../src/ui_script/multibar_stance_tests.rs | 49 +- .../src/ui_script/options_tests.rs | 14 +- .../src/ui_script/panel_template_tests.rs | 3 +- .../benilla-app/src/ui_script/panel_tests.rs | 44 +- .../src/ui_script/perf_bar_tests.rs | 4 +- .../src/ui_script/pet_bar_tests.rs | 3 +- .../src/ui_script/pet_frame_tests.rs | 2 +- .../src/ui_script/pet_paperdoll_tests.rs | 13 +- .../src/ui_script/petition_tests.rs | 3 +- .../src/ui_script/quest_share_tests.rs | 3 +- .../benilla-app/src/ui_script/quest_tests.rs | 51 +- .../src/ui_script/quest_timer_tests.rs | 3 +- .../src/ui_script/questlog_tests.rs | 111 +- .../benilla-app/src/ui_script/reference_ui.rs | 68 +- .../src/ui_script/screenshot_tests.rs | 3 +- .../src/ui_script/shipped_xml_tests.rs | 36 +- .../src/ui_script/spellbook_tests.rs | 9 +- .../src/ui_script/static_popup_tests.rs | 19 +- .../benilla-app/src/ui_script/summon_tests.rs | 3 +- .../benilla-app/src/ui_script/tabard_tests.rs | 4 +- .../src/ui_script/talent_wipe_tests.rs | 3 +- .../src/ui_script/target_aura_tests.rs | 2 +- .../benilla-app/src/ui_script/taxi_tests.rs | 2 +- crates/benilla-app/src/ui_script/test_ui.rs | 122 +- .../src/ui_script/tooltip_anchor_tests.rs | 11 +- .../src/ui_script/tooltip_compare_tests.rs | 3 +- .../src/ui_script/tooltip_template_tests.rs | 2 +- .../src/ui_script/tot_frame_tests.rs | 2 +- .../src/ui_script/trainer_tests.rs | 3 +- .../src/ui_script/tutorial_tests.rs | 3 +- .../src/ui_script/uiparent_tests.rs | 5 +- .../src/ui_script/unit_frame_tests.rs | 9 +- .../src/ui_script/unit_popup_tests.rs | 6 +- .../src/ui_script/world_map_tests.rs | 129 +- .../src/ui_script/world_state_tests.rs | 3 +- .../src/ui_script/zone_text_tests.rs | 3 +- crates/benilla-app/src/ui_summon.rs | 2 +- crates/benilla-app/tests/auction_frame.rs | 3 +- crates/benilla-app/tests/character_stats.rs | 3 +- crates/benilla-app/tests/common/mod.rs | 102 +- .../tests/create_frame_template.rs | 52 +- crates/benilla-app/tests/item_text_frame.rs | 3 +- crates/benilla-app/tests/mail_frame.rs | 49 +- crates/benilla-app/tests/talent_frame.rs | 3 +- crates/benilla-app/tests/trade_frame.rs | 48 +- crates/benilla-app/tests/tradeskill_frame.rs | 3 +- crates/benilla-ui/src/script/extract.rs | 16 +- crates/benilla-ui/src/script/worldmap.rs | 14 +- 99 files changed, 1191 insertions(+), 3779 deletions(-) delete mode 100644 crates/benilla-app/assets/ui/UIParent.xml delete mode 100644 crates/benilla-app/assets/ui/UiPanels.xml diff --git a/crates/benilla-app/assets/ui/ContainerFrameAdapters.xml b/crates/benilla-app/assets/ui/ContainerFrameAdapters.xml index bc879b6b..175dbf89 100644 --- a/crates/benilla-app/assets/ui/ContainerFrameAdapters.xml +++ b/crates/benilla-app/assets/ui/ContainerFrameAdapters.xml @@ -96,25 +96,72 @@ refItemButtonOnEnter(button) end - -- ══ Re-publishing the three bag verbs 0561 shadows, and why it is HERE ═════════════ + -- ══ The three bag verbs benilla answers differently (decisions 0561 + 1751) ═════════ -- - -- `OpenBackpack`, `CloseBackpack` and `CloseAllBags` are all defined by the sourced - -- `ContainerFrame.lua` (l.187-217, l.702-707) — and benilla answers all three differently, - -- for one reason: **0561, the director's call that a window opening your bags opens EVERY - -- equipped bag**, not just the backpack. The vendor, bank, mail and trade windows call - -- `OpenBackpack` from their OnShow so your bags come up with them and you can sell or - -- deposit from one. + -- `CloseAllBags`, `OpenBackpack` and `CloseBackpack` all exist in the sourced + -- `ContainerFrame.lua` too, and benilla's differ for one reason, not three: **0561, the + -- director's call that a window which opens your bags opens EVERY equipped bag**, not just + -- the backpack. The vendor/bank/mail/trade windows call `OpenBackpack` from their OnShow so + -- your bags come up with them and you can sell or deposit from one; the reference's own + -- body touches bag 0 alone. `CloseBackpack` is its inverse and has to match it, and + -- `CloseAllBags` is the same family's unconditional form. -- - -- The bodies live in `UiPanels.xml`, because every window that calls them is loaded by - -- harnesses that have no bag stack at all, and a nil `OpenBackpack` in a merchant test is - -- a nil for no reason. But UiPanels is manifest entry 7 and the reference's container file - -- is entry 46, so **its publications lose the collision** — the reference's bodies land on - -- top and the vendor silently stops opening your bags. That is not hypothetical: it is - -- what shipped for the length of one session before a test caught it. + -- **The `Benilla*` names, and the publish under them, are load ORDER** (1751). Order + -- decides every collision and the manifest is the order: this file loads after the + -- reference's `ContainerFrame.xml`, so the three publishes at the foot are the ones that + -- stand. The bodies lived in our UIParent.lua counterpart until 1988 retired it — a + -- harness with no bag stack now meets the loader's stand-ins for the three names + -- (`test_ui::UIPARENT_STAND_INS`), not a nil. -- - -- So the bodies stay where their callers can reach them, under `Benilla*` names that - -- nothing overwrites, and this file — entry 49, after the reference's — puts them back on - -- the reference's names. Three lines, and they are the whole of the fix. + -- What CHANGED with the swap is only the plumbing: these used to walk five benilla windows + -- by name and stash `wasOpen` on each frame. The windows are the reference's recycled + -- `ContainerFrame1..12` now — frame N is a different bag every time it opens — so the + -- was-open memory is keyed by BAG ID, and every open and close goes through the + -- reference's own `OpenBag`/`CloseBag`/`IsBagOpen` rather than a raw Show/Hide. That buys + -- the reference's own guards for free (OpenBag's CanOpenPanels + NotWhileDeadError, + -- ToggleBag's `size > 0`) and means an addon replacing those verbs is honoured here too. + BENILLA_BAG_WAS_OPEN = {} + + -- The UNCONDITIONAL close, called by ShowUIPanel's native-center branch above: a centre + -- frame takes the whole screen, so nothing is being "restored afterwards" the way a vendor + -- window restores the bags it opened, and the was-open memory is deliberately ignored. + -- Range 0..NUM_CONTAINER_FRAMES rather than the old five names — the reference's own + -- CloseAllBags covers the bank bags too (l.702-707), and now so does this. + function BenillaCloseAllBags() + for bagId = 0, (NUM_CONTAINER_FRAMES or -1) do + CloseBag(bagId) + end + end + + -- OpenBackpack — 0561's all-bags form. A bag already open is REMEMBERED and left alone, so + -- the paired CloseBackpack does not close a window the player opened themselves; that + -- memory is the reference's own `backpackWasOpen`, one entry per bag instead of one flag. + function BenillaOpenBackpack() + for bagId = 0, (NUM_BAG_FRAMES or -1) do + -- The backpack always exists; an equipped-bag window only when a bag is in the + -- slot — `OpenBag` makes the same test itself, but the memory has to agree with it. + if bagId == 0 or GetContainerNumSlots(bagId) > 0 then + if IsBagOpen(bagId) then + BENILLA_BAG_WAS_OPEN[bagId] = 1 + else + BENILLA_BAG_WAS_OPEN[bagId] = nil + OpenBag(bagId) + end + end + end + end + + function BenillaCloseBackpack() + for bagId = 0, (NUM_BAG_FRAMES or -1) do + if not BENILLA_BAG_WAS_OPEN[bagId] then + CloseBag(bagId) + end + end + end + + -- The publish — after the reference's container file, so these are the definitions that + -- stand (the stock `ShowUIPanel` calls `CloseAllBags` and the vendor's OnShow + -- `OpenBackpack`, and they reach 0561's bodies). OpenBackpack = BenillaOpenBackpack CloseBackpack = BenillaCloseBackpack CloseAllBags = BenillaCloseAllBags diff --git a/crates/benilla-app/assets/ui/GameMenuFrame.xml b/crates/benilla-app/assets/ui/GameMenuFrame.xml index cd4aebe1..7911677b 100644 --- a/crates/benilla-app/assets/ui/GameMenuFrame.xml +++ b/crates/benilla-app/assets/ui/GameMenuFrame.xml @@ -39,7 +39,7 @@ · **The two logout dialogs** — ref `StaticPopup.lua` l.564-600 (CAMP + QUIT) is the SPECIFICATION for them: the two dialog keys, the field names, the 20 s timeout and the asymmetric button sets are contract, and the entries carrying them are written here in - our own shape on the shared popup engine (UiPanels.xml), whose countdown-text branch + our own shape on the shared popup engine (the stock StaticPopup), whose countdown-text branch already lists both `which` names. Their driver events are the reference's own (`re/events/event-catalog.tsv`: 276 PLAYER_CAMPING, 277 PLAYER_QUITING, 278 LOGOUT_CANCEL), fired by `crate::ui_logout` off `SMSG_LOGOUT_RESPONSE`. @@ -119,7 +119,7 @@ button:Disable() end - -- The CAMP/QUIT dialogs and the three-event driver MOVED OUT, to UiPanels.xml — the + -- The CAMP/QUIT dialogs and the three-event driver MOVED OUT, to our UIParent.lua counterpart (the stock UIParent.lua since 1988) — the -- reference's own homes for both (StaticPopup.lua l.564/586; UIParent.lua l.304-315). -- They were here only because this is where they were first needed, and 1751 moving them -- is one less thing to carry when this window follows them onto the chain. @@ -287,7 +287,7 @@ while the menu is up, and the bag bar greys out under it (you cannot open bags from behind the menu — ShowUIPanel's center gate would refuse the window anyway, so the greying is the visible half of a rule the panel manager already enforces). Guarded, the - UiPanels.xml `CloseMenus and CloseMenus()` posture: a headless test loads this file + the old UiPanels.xml `CloseMenus and CloseMenus()` posture: a headless test loads this file without the action bar behind it. --> GameMenuFrameTitle:SetText(MAIN_MENU) diff --git a/crates/benilla-app/assets/ui/KeyBindingsPage.xml b/crates/benilla-app/assets/ui/KeyBindingsPage.xml index bb5fe601..e2f08cde 100644 --- a/crates/benilla-app/assets/ui/KeyBindingsPage.xml +++ b/crates/benilla-app/assets/ui/KeyBindingsPage.xml @@ -152,7 +152,7 @@ -- ── Key display ── the 1.12 GetBindingText law by hand: modifier prefixes stay the -- canonical uppercase tokens, the base key reads its KEY_* global (Spacebar, Up Arrow, -- Mouse Button 4...) else itself. "CTRL--" renders CTRL + the minus key. (The action - -- bar's ABBREVIATED labels ride our own GetBindingText in UIParent.xml; + -- bar's ABBREVIATED labels ride the stock GetBindingText (UIParent.lua); -- this page and the tooltips show the full form, both references' own split.) function KeyBindings_KeyText(key) if not key then diff --git a/crates/benilla-app/assets/ui/OptionsFrame.xml b/crates/benilla-app/assets/ui/OptionsFrame.xml index 1f45cd98..13f31ab8 100644 --- a/crates/benilla-app/assets/ui/OptionsFrame.xml +++ b/crates/benilla-app/assets/ui/OptionsFrame.xml @@ -4063,9 +4063,14 @@ is down (MainMenuBarMicroButtons.lua l.47-52; decision 1987). These two aliases are the adapter: a stock read of either sibling is answered by this window, which is the honest answer — while ours is up, the reference's question "is an options window open" is yes. - BENILLA_ALLOW_OWN_UI=1 --> + The third alias is the ESC ladder's: the stock `ToggleGameMenu` (UIParent.lua l.1465-1497, + off the chain since 1988) closes an open options window with `OptionsFrameCancel:Click()`, + the reference's Cancel button; ours has a corner X whose click is the same discard-and-hide + (`HideUIPanel(OptionsFrame)`, and OnHide discards the pending page), so that button answers + to the reference's name. BENILLA_ALLOW_OWN_UI=1 --> diff --git a/crates/benilla-app/assets/ui/ScriptLogFrame.xml b/crates/benilla-app/assets/ui/ScriptLogFrame.xml index 89a0cab0..ce16f2da 100644 --- a/crates/benilla-app/assets/ui/ScriptLogFrame.xml +++ b/crates/benilla-app/assets/ui/ScriptLogFrame.xml @@ -26,7 +26,8 @@ attached, so the detail is genuinely variable-height content, which is what the real kit is for; `GossipFrame.xml`'s greeting pane is the same wiring). - The window is registered in `UIPanelWindows` (`UiPanels.xml`), which is what seats it in the + The window registers itself in `UIPanelWindows` (below; the table is the stock UIParent.lua's + since 1988), which is what seats it in the left slot and gets it closed by `CloseAllWindows()` — i.e. by ESC — with no code here. Our own toplevels deliberately stay OUT of `UISpecialFrames`: that table is the addons' (0544's note, 1206). @@ -40,6 +41,10 @@ feed and nothing to keep in step — the window polls the log it is a view of. --> + + + + - - - - this:RegisterEvent("VARIABLES_LOADED") - this:RegisterEvent("TRAINER_SHOW") - this:RegisterEvent("TRAINER_CLOSED") - this:RegisterEvent("AUCTION_HOUSE_SHOW") - this:RegisterEvent("AUCTION_HOUSE_CLOSED") - this:RegisterEvent("TRADE_SKILL_SHOW") - this:RegisterEvent("TRADE_SKILL_CLOSE") - this:RegisterEvent("CRAFT_SHOW") - this:RegisterEvent("CRAFT_CLOSE") - this:RegisterEvent("GUILD_INVITE_REQUEST") - this:RegisterEvent("GUILD_INVITE_CANCEL") - this:RegisterEvent("MIRROR_TIMER_START") - this:RegisterEvent("PLAYER_ENTERING_WORLD") - this:RegisterEvent("READY_CHECK") - this:RegisterEvent("START_LOOT_ROLL") - this:RegisterEvent("CONFIRM_LOOT_ROLL") - -- The dialog-raising events below (ref UIParent.lua l.76-127), registered here - -- since the dialog engine became the reference's file (1960); what the engine does - -- not produce yet is left unregistered and named in that record, never armed blind. - this:RegisterEvent("PLAYER_DEAD") - this:RegisterEvent("PLAYER_ALIVE") - this:RegisterEvent("PLAYER_UNGHOST") - this:RegisterEvent("RESURRECT_REQUEST") - this:RegisterEvent("PARTY_INVITE_REQUEST") - this:RegisterEvent("PARTY_INVITE_CANCEL") - this:RegisterEvent("PLAYER_CAMPING") - this:RegisterEvent("PLAYER_QUITING") - this:RegisterEvent("LOGOUT_CANCEL") - this:RegisterEvent("LOOT_BIND_CONFIRM") - this:RegisterEvent("EQUIP_BIND_CONFIRM") - this:RegisterEvent("AUTOEQUIP_BIND_CONFIRM") - this:RegisterEvent("USE_BIND_CONFIRM") - this:RegisterEvent("DELETE_ITEM_CONFIRM") - this:RegisterEvent("QUEST_ACCEPT_CONFIRM") - this:RegisterEvent("CURSOR_UPDATE") - this:RegisterEvent("DUEL_REQUESTED") - this:RegisterEvent("DUEL_OUTOFBOUNDS") - this:RegisterEvent("DUEL_INBOUNDS") - this:RegisterEvent("DUEL_FINISHED") - this:RegisterEvent("CONFIRM_XP_LOSS") - this:RegisterEvent("CORPSE_IN_RANGE") - this:RegisterEvent("CORPSE_IN_INSTANCE") - this:RegisterEvent("CORPSE_OUT_OF_RANGE") - this:RegisterEvent("BIND_ENCHANT") - this:RegisterEvent("REPLACE_ENCHANT") - this:RegisterEvent("CURRENT_SPELL_CAST_CHANGED") - this:RegisterEvent("CONFIRM_TALENT_WIPE") - this:RegisterEvent("CONFIRM_BINDER") - this:RegisterEvent("CONFIRM_SUMMON") - -- The dialog engine's verbs (1963): the feeds behind these exist now. - this:RegisterEvent("INSTANCE_BOOT_START") - this:RegisterEvent("INSTANCE_BOOT_STOP") - this:RegisterEvent("CONFIRM_PET_UNLEARN") - this:RegisterEvent("AREA_SPIRIT_HEALER_IN_RANGE") - this:RegisterEvent("AREA_SPIRIT_HEALER_OUT_OF_RANGE") - - UIParent_OnEvent(event) - - if FCF_OnUpdate then FCF_OnUpdate(arg1) end if ButtonPulse_OnUpdate then ButtonPulse_OnUpdate(arg1) end if UnitPopup_OnUpdate then UnitPopup_OnUpdate(arg1) end - - - - - - - - diff --git a/crates/benilla-app/assets/ui/UiPanels.xml b/crates/benilla-app/assets/ui/UiPanels.xml deleted file mode 100644 index 0279eece..00000000 --- a/crates/benilla-app/assets/ui/UiPanels.xml +++ /dev/null @@ -1,1540 +0,0 @@ - - - - - - - - - - if not FLASHFRAMES[1] then this:Hide() return end UIFrameFlashUpdate(arg1) - - - - - - if not FADEFRAMES[1] then this:Hide() return end UIFrameFadeUpdate(arg1) - - - - - - - if not PULSEBUTTONS[1] then this:Hide() return end ButtonPulse_OnUpdate(arg1) - - - - - - - - diff --git a/crates/benilla-app/assets/ui/benilla.toc b/crates/benilla-app/assets/ui/benilla.toc index 76a012bd..7239435f 100644 --- a/crates/benilla-app/assets/ui/benilla.toc +++ b/crates/benilla-app/assets/ui/benilla.toc @@ -124,7 +124,21 @@ Interface\FrameXML\BasicControls.xml # the reference's toc has it (l.7-8). Needs Fonts.xml's SystemFont above; everything else it # names is call-time. Interface\FrameXML\WorldFrame.xml -UIParent.xml +# UIParent itself and its Lua — the reference's own file (1751; decision 1988), at the slot its +# toc gives it (l.8, right after BasicControls). UIParent.lua is the whole of the glue this +# engine used to carry as UIParent.xml + UiPanels.xml: the UIPanelWindows table and the slot +# manager (Show/HideUIPanel, CloseAllWindows, ToggleGameMenu's ESC ladder), the fade/flash/pulse +# kits (ticked from UIParent's own OnUpdate, so the three driver frames of ours retired with +# it), the managed bottom-stack positions, the model turntable, the LoadOnDemand shims, and the +# sixty-six globally-routed events and their arms. It sources LocaleProperties.lua itself. Its +# OnUpdate also ticks FCF_OnUpdate, UnitPopup_OnUpdate, BattlefieldFrame_OnUpdate, the +# battlefield-position ask (1980) and the ready-check timeout (1989) — call-time names, all of +# them below. LowHealthFrame (parent WorldFrame, above) and OutOfControlFrame ride along. +# What stayed ours moved out: the window tab template and its settle + the placeholder icon +# (ScrollTemplates.xml), 0561's bag verbs (ContainerFrameAdapters.xml), the script log's row +# (ScriptLogFrame.xml), and three aliases in OptionsFrame.xml that answer the reference's three +# options windows and its Cancel button. +Interface\FrameXML\UIParent.xml # ══ THE ITEM-SLOT BASE — the reference's own, off the player's chain (1751, window 24) ══ # `ItemButtonTemplate` and the eight `SetItemButton*` verbs out of `ItemButtonTemplate.lua`. It # sits as early as it can be read: no frames, no dependencies of its own, and every window that @@ -169,12 +183,6 @@ Interface\FrameXML\MoneyFrame.xml # `every_chain_xml_brings_its_own_lua` is now a gate so neither can recur. Interface\FrameXML\MoneyInputFrame.lua Interface\FrameXML\MoneyInputFrame.xml -# The UIPanel slot manager (decision 0084 §2) and the fade/flash/pulse kits — the UIParent.lua -# halves this engine still carries itself: script-only but for the kits' tick drivers, loaded -# before any panel frame so ShowUIPanel/HideUIPanel already exist when those frames' OnLoad/OnEvent -# reference them. The StaticPopup engine and every dialog it used to carry are the reference's -# own file now, far below at the reference's own slot after UIPanelTemplates (decision 1960). -UiPanels.xml # ══ THE TOOLTIP — the reference's own, off the player's chain (1751; decision 1968) ══ # GameTooltip.xml sources HealthBar.lua and GameTooltip.lua and s GameTooltipTemplate.xml: # the two virtual templates (GameTooltipTemplate, ShoppingTooltipTemplate — thirty declared line @@ -592,14 +600,6 @@ Interface\FrameXML\CastingBarFrame.xml # 1.12 never reaches it — vmangos refuses to send that packet and substitutes a full START, # saying so in `Player::SendMirrorTimers` — and `ui_mirror.rs`'s Pause edge carries the note. Interface\FrameXML\MirrorTimer.xml -# ══ THE WORLD-STATE FRAMES — the reference's own, off the player's chain (1751; decision 1972) ══ -# WorldStateFrame.xml + WorldStateFrame.lua: the always-up readout 1586 built (the tower/flag/base -# counters at top-centre, `UPDATE_WORLD_STATES` from `crate::world_state_ui`), the capture bars, -# and the battleground SCOREBOARD ours never had — `WorldStateScoreFrame`, over the score family -# 1972 built (`MSG_PVP_LOG_DATA`, the eleven verbs, `UPDATE_BATTLEFIELD_SCORE`) and UIParent.xml's -# `BattlefieldMinimap_LoadUI`. Needs Fonts, GameTooltip, the panel kit (its close button, tabs, -# faux scroll frame) — all above; sits beside the mirror timers, which share its top-centre lane. -Interface\FrameXML\WorldStateFrame.xml # ══ THE DURABILITY ALERT — the reference's own, off the player's chain (1751, window 4) ══ # The "armor guy" under the minimap: `DurabilityFrame`, its eleven glyph textures, and # `DurabilityFrame_SetAlerts` / `_OnUpdate` with `INVENTORY_ALERT_STATUS_SLOTS` and @@ -1053,6 +1053,20 @@ Interface\FrameXML\QuestTimerFrame.xml # CHAT_MSG_* events the reference's ChatFrame_OnEvent prints from — it no longer prints them itself. Interface\FrameXML\ChatFrame.xml Interface\FrameXML\FloatingChatFrame.xml + +# ══ THE WORLD-STATE FRAMES — the reference's own, off the player's chain (1751; decision 1972) ══ +# WorldStateFrame.xml + WorldStateFrame.lua: the always-up readout 1586 built (the tower/flag/base +# counters at top-centre, `UPDATE_WORLD_STATES` from `crate::world_state_ui`), the capture bars, +# and the battleground SCOREBOARD ours never had — `WorldStateScoreFrame`, over the score family +# 1972 built (`MSG_PVP_LOG_DATA`, the eleven verbs, `UPDATE_BATTLEFIELD_SCORE`) and UIParent.xml's +# `BattlefieldMinimap_LoadUI`. Needs Fonts, GameTooltip, the panel kit (its close button, tabs, +# faux scroll frame) — all above. It sat beside the mirror timers until 1988: the always-up +# frame's OnLoad runs the stock UIParent_ManageFramePositions, and that pass indexes half the +# HUD unguarded — ReputationWatchBar, QuestTimerFrame, QuestWatchFrame (QuestLogFrame.xml), +# MinimapCluster, DurabilityFrame, the bars and their sliding textures — and ends by calling +# FCF_DockUpdate and re-anchoring the container frames. So this file sits after all of them, +# which is why the reference's own toc has it at l.89, near the end (1988). +Interface\FrameXML\WorldStateFrame.xml # ══ THE MACRO WINDOW — the reference's own, off the player's chain (1751, window 32) ══ # A LoadOnDemand addon with no row here since 1967 (the addons header far above); what stays in # this slot is the FrameXML file it needs loaded first. diff --git a/crates/benilla-app/src/ui_chat/tests.rs b/crates/benilla-app/src/ui_chat/tests.rs index 371a59e9..e920bc4b 100644 --- a/crates/benilla-app/src/ui_chat/tests.rs +++ b/crates/benilla-app/src/ui_chat/tests.rs @@ -451,7 +451,7 @@ fn chat_vm() -> benilla_ui::script::UiScript { "Interface\\FrameXML\\ChatFrame.xml", "Interface\\FrameXML\\UIPanelTemplates.lua", "Interface\\FrameXML\\UIPanelTemplates.xml", - "UiPanels.xml", + r"Interface\FrameXML\UIParent.xml", "Interface\\FrameXML\\LocaleProperties.lua", "Interface\\FrameXML\\StaticPopup.xml", "Interface\\FrameXML\\FloatingChatFrame.xml", @@ -2039,37 +2039,47 @@ fn both_dock_windows_carry_the_same_chrome() { } } -/// **No docked chat window may appear in `UIParent.xml`'s managed-position table.** +/// **A docked chat window survives the managed-position pass.** /// -/// The structural guard on the root cause. That pass owns a frame's whole seat — it -/// `ClearAllPoints()` first, by design (decision 1499) — so a row naming a *docked* window wipes -/// the anchors that tie it to the dock and re-seats it with a single point and no size: an -/// unresolvable rect. The reference's own ChatFrame2 row is for an UNDOCKED window, which is chat -/// settings and not built (0288 §2); carrying it here cost B297 a visible fix. -/// -/// A string check because that is the level the bug lives at — the row's mere presence is the -/// defect, whatever it contains. +/// The pass owns a frame's whole seat — it `ClearAllPoints()` first, by design (decision 1499) — +/// and the reference's own table carries a `ChatFrame2` row. That row cost B297 a visible fix +/// while the pass was ours, and our answer then was to drop the row from our copy. The stock pass +/// is the one that runs now (1988), row and all, and it ends by calling `FCF_DockUpdate()` — +/// which re-anchors every docked window onto `DEFAULT_CHAT_FRAME` in the same breath. That is the +/// reference's answer to its own row, and this is the behavioural check that it holds: after the +/// pass, the docked window is still exactly on the dock. #[test] -fn no_docked_chat_window_is_managed_by_uiparent() { +fn a_docked_chat_window_survives_the_managed_position_pass() { let _data = benilla_formats::wow_data_or_skip!(); - let xml = std::fs::read_to_string( - std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("assets/ui/UIParent.xml"), - ) - .expect("UIParent.xml"); - for line in xml.lines() { - let code = line.trim_start(); - if code.starts_with("--") { - continue; // the comment explaining why the row is gone names it, deliberately - } - assert!( - !code.starts_with("ChatFrame2 ="), - "ChatFrame2 is DOCKED — a managed row clears its dock anchors: {code}" - ); - } - assert!( - xml.contains("ChatFrame1 = {baseY = 85"), - "ChatFrame1 IS managed (it is the dock's own seat) — this test must not pass vacuously" + let mut s = benilla_ui::script::UiScript::new().expect("VM"); + s.set_screen_size(1024.0, 768.0); + s.set_unit( + "player", + Some(benilla_ui::script::UnitState { + exists: true, + name: Some("Probefour".into()), + level: 60, + ..Default::default() + }), ); + assert!(crate::ui_script::load_default_ui(&s).is_empty()); + s.resolve(); + // Dock the combat log the way the reference's own default layout does, then run the pass. + s.run("FCF_DockFrame(ChatFrame2, 2, nil) UIParent_ManageFramePositions()") + .unwrap(); + s.resolve(); + let rect = |name: &str| { + s.eval::<(f64, f64, f64, f64)>(&format!( + "return {name}:GetLeft(), {name}:GetBottom(), {name}:GetRight(), {name}:GetTop()" + )) + .unwrap_or_else(|e| panic!("{name}: {e}")) + }; + assert_eq!( + rect("ChatFrame2"), + rect("ChatFrame1"), + "the docked window still sits exactly on the dock" + ); + assert!(s.errors().is_empty(), "script errors: {:?}", s.errors()); } /// **What does NOT gate a `/sit` underwater** — the negative that sends B155's refusal to the diff --git a/crates/benilla-app/src/ui_items/drain.rs b/crates/benilla-app/src/ui_items/drain.rs index 233648bf..56da9012 100644 --- a/crates/benilla-app/src/ui_items/drain.rs +++ b/crates/benilla-app/src/ui_items/drain.rs @@ -1176,12 +1176,11 @@ mod bind_confirm_tests { "Interface\\FrameXML\\Fonts.xml", r"Interface\FrameXML\MoneyFrame.lua", r"Interface\FrameXML\MoneyFrame.xml", - "UiPanels.xml", + r"Interface\FrameXML\UIParent.xml", "Interface\\FrameXML\\GlobalStrings.lua", "Interface\\FrameXML\\BasicControls.xml", "Interface\\FrameXML\\LocaleProperties.lua", "Interface\\FrameXML\\StaticPopup.xml", - "UIParent.xml", ] { crate::ui_script::load_ui_for_test(s, file); } diff --git a/crates/benilla-app/src/ui_script/action_bar_tests.rs b/crates/benilla-app/src/ui_script/action_bar_tests.rs index fa2dba8c..a6ead5d0 100644 --- a/crates/benilla-app/src/ui_script/action_bar_tests.rs +++ b/crates/benilla-app/src/ui_script/action_bar_tests.rs @@ -21,7 +21,7 @@ fn shipped_action_bar_drives_end_to_end() { super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\Fonts.xml"); - super::test_ui::load_ui(&s, "UIParent.xml"); + super::test_ui::load_ui(&s, r"Interface\FrameXML\UIParent.xml"); super::test_ui::load_ui(&s, r"Interface\FrameXML\MoneyFrame.lua"); super::test_ui::load_ui(&s, r"Interface\FrameXML\MoneyFrame.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\GameTooltip.xml"); @@ -185,7 +185,7 @@ fn load_action_bar(s: &UiScript) { super::test_ui::load_ui(s, "Interface\\FrameXML\\TextStatusBar.lua"); super::test_ui::load_ui(s, "Interface\\FrameXML\\TextStatusBar.xml"); super::test_ui::load_ui(s, "Interface\\FrameXML\\Fonts.xml"); - super::test_ui::load_ui(s, "UIParent.xml"); + super::test_ui::load_ui(s, r"Interface\FrameXML\UIParent.xml"); super::test_ui::load_ui(s, "Interface\\FrameXML\\GlobalStrings.lua"); super::test_ui::load_ui(s, "Interface\\FrameXML\\MainMenuBar.xml"); super::test_ui::load_ui(s, r"Interface\FrameXML\MoneyFrame.lua"); @@ -208,7 +208,6 @@ fn load_action_bar(s: &UiScript) { // The options window: `LOCK_ACTIONBAR` and `ALWAYS_SHOW_MULTIBARS` are declared there, as the // reference declares them in UIOptionsFrame_Init (1938) — and the manifest loads it before // the bars. - super::test_ui::load_ui(s, "UiPanels.xml"); // The dialog engine — the keybindings page registers its two confirms into its table (1960). super::test_ui::load_ui(s, r"Interface\FrameXML\BasicControls.xml"); // `TEXT` super::test_ui::load_ui(s, r"Interface\FrameXML\LocaleProperties.lua"); // `GetText` @@ -835,7 +834,8 @@ fn shipped_bag_frame_drives_end_to_end() { load_ui(&s, "Interface\\FrameXML\\TextStatusBar.lua"); load_ui(&s, "Interface\\FrameXML\\TextStatusBar.xml"); load_ui(&s, "Interface\\FrameXML\\Fonts.xml"); - load_ui(&s, "UIParent.xml"); + load_ui(&s, r"Interface\FrameXML\UIParent.xml"); + load_ui(&s, "ScrollTemplates.xml"); // the window tab template, ours (1004/1988) load_ui(&s, "Interface\\FrameXML\\GlobalStrings.lua"); load_ui(&s, "Interface\\FrameXML\\MainMenuBar.xml"); load_ui(&s, "Interface\\FrameXML\\ActionBarFrame.xml"); @@ -1350,7 +1350,7 @@ fn the_main_bar_pages_and_a_bonus_page_still_outranks_it() { for file in [ // Fonts first: the pane's check-box labels colour from `RED_FONT_COLOR` in their own OnLoad. "Interface\\FrameXML\\Fonts.xml", - "UIParent.xml", + r"Interface\FrameXML\UIParent.xml", "Cooldown.xml", "Interface\\FrameXML\\ActionButtonTemplate.xml", "Interface\\FrameXML\\TextStatusBar.lua", @@ -1371,7 +1371,6 @@ fn the_main_bar_pages_and_a_bonus_page_still_outranks_it() { r"Interface\FrameXML\OptionsFrameTemplates.xml", r"Interface\FrameXML\ReputationFrame.xml", "Interface\\FrameXML\\ActionBarFrame.xml", - "UiPanels.xml", "Interface\\FrameXML\\UIDropDownMenu.xml", "ScrollTemplates.xml", r"Interface\FrameXML\UIPanelTemplates.lua", @@ -1523,7 +1522,7 @@ fn bonus_bar_slides_up_with_sound_and_down_without() { super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\Fonts.xml"); - super::test_ui::load_ui(&s, "UIParent.xml"); + super::test_ui::load_ui(&s, r"Interface\FrameXML\UIParent.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\GlobalStrings.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\MainMenuBar.xml"); super::test_ui::load_ui(&s, r"Interface\FrameXML\MoneyFrame.lua"); @@ -1745,7 +1744,7 @@ fn bonus_bar_turnaround_continues_from_position() { super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\Fonts.xml"); - super::test_ui::load_ui(&s, "UIParent.xml"); + super::test_ui::load_ui(&s, r"Interface\FrameXML\UIParent.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\GlobalStrings.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\MainMenuBar.xml"); super::test_ui::load_ui(&s, r"Interface\FrameXML\MoneyFrame.lua"); @@ -1827,7 +1826,7 @@ fn the_page_arrows_do_not_steal_each_other_s_clicks() { super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\TextStatusBar.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\Fonts.xml"); - super::test_ui::load_ui(&s, "UIParent.xml"); + super::test_ui::load_ui(&s, r"Interface\FrameXML\UIParent.xml"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\GlobalStrings.lua"); super::test_ui::load_ui(&s, "Interface\\FrameXML\\MainMenuBar.xml"); super::test_ui::load_ui(&s, r"Interface\FrameXML\MoneyFrame.lua"); diff --git a/crates/benilla-app/src/ui_script/bag_tests.rs b/crates/benilla-app/src/ui_script/bag_tests.rs index e1a4198a..bed12058 100644 --- a/crates/benilla-app/src/ui_script/bag_tests.rs +++ b/crates/benilla-app/src/ui_script/bag_tests.rs @@ -133,6 +133,7 @@ fn b_opens_the_backpack_alone_and_closes_every_bag() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -214,6 +215,7 @@ fn shift_b_toggles_every_bag_at_once() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); s.set_container( @@ -295,6 +297,7 @@ fn bag_bar_buttons_light_while_their_bag_is_open() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); s.set_container( @@ -412,6 +415,7 @@ fn bag_tooltip_hangs_left_when_the_slot_sits_in_the_right_half() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -489,6 +493,7 @@ fn hovered_bag_tooltip_fills_itself_when_the_stats_land() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -593,6 +598,7 @@ fn vendor_bag_hover_shows_sell_price_and_arms_the_pouch_cursor() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -729,6 +735,7 @@ fn readable_letter_hover_shows_the_inspect_magnifier() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -799,6 +806,7 @@ fn drag_across_two_slots_queues_the_same_move_a_click_pickup_would() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -883,6 +891,7 @@ fn a_second_bag_window_feeds_and_paints_via_the_bag_bar() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -956,6 +965,7 @@ fn equipped_bag_window_snug_fits_its_row_count() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -1015,6 +1025,7 @@ fn open_backpack_with_a_five_stack(s: &mut UiScript) -> (f32, f32) { for file in BAG_UI { load_xml(s, file); } + load_xml(s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(s, "Interface\\FrameXML\\MerchantFrame.xml"); load_xml(s, "Interface\\FrameXML\\StackSplitFrame.xml"); s.set_money(0); @@ -1356,6 +1367,7 @@ fn bag_slot_cooldown_sweeps_through_the_xml() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); s.tick(100.0); // a nonzero clock epoch, like the engine cooldown tests @@ -1429,6 +1441,7 @@ fn the_bar_bag_buttons_name_themselves_on_hover() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.resolve(); @@ -1563,6 +1576,7 @@ fn keyring_surface(s: &UiScript) { for file in BAG_UI { load_xml(s, file); } + load_xml(s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(s, "Interface\\FrameXML\\MerchantFrame.xml"); load_xml(s, "Interface\\FrameXML\\UIErrorsFrame.xml"); } @@ -1837,6 +1851,7 @@ fn an_item_push_drops_its_icon_into_the_bag_that_took_it() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.resolve(); @@ -2093,6 +2108,7 @@ fn an_addon_that_hooks_toggle_backpack_receives_the_click() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); @@ -2149,6 +2165,7 @@ fn the_bag_slots_carry_the_references_names_and_icon_names() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); for i in 0..4 { @@ -2209,6 +2226,7 @@ fn the_backpack_buttons_ring_follows_its_own_window_through_real_clicks() { for file in BAG_UI { load_xml(&s, file); } + load_xml(&s, "ScrollTemplates.xml"); // our window tab template, before the window that inherits it (1988) load_xml(&s, "Interface\\FrameXML\\MerchantFrame.xml"); s.set_money(0); // The reference's `ToggleBag` opens nothing for a container of size 0, so the backpack has to diff --git a/crates/benilla-app/src/ui_script/battlefield_tests.rs b/crates/benilla-app/src/ui_script/battlefield_tests.rs index bb29292a..e9d9cf2f 100644 --- a/crates/benilla-app/src/ui_script/battlefield_tests.rs +++ b/crates/benilla-app/src/ui_script/battlefield_tests.rs @@ -34,10 +34,9 @@ fn session() -> UiScript { "Interface\\FrameXML\\Localization.xml", "Interface\\FrameXML\\LocaleProperties.lua", "Interface\\FrameXML\\BasicControls.xml", - "UIParent.xml", + r"Interface\FrameXML\UIParent.xml", r"Interface\FrameXML\MoneyFrame.lua", r"Interface\FrameXML\MoneyFrame.xml", - "UiPanels.xml", "Interface\\FrameXML\\GameTooltip.xml", "Interface\\FrameXML\\UIDropDownMenu.xml", r"Interface\FrameXML\UIPanelTemplates.lua", diff --git a/crates/benilla-app/src/ui_script/binder_tests.rs b/crates/benilla-app/src/ui_script/binder_tests.rs index 66a603ec..26cbaa4a 100644 --- a/crates/benilla-app/src/ui_script/binder_tests.rs +++ b/crates/benilla-app/src/ui_script/binder_tests.rs @@ -14,14 +14,13 @@ fn setup() -> UiScript { load_xml(&s, "Interface\\FrameXML\\Fonts.xml"); load_xml(&s, r"Interface\FrameXML\MoneyFrame.lua"); load_xml(&s, r"Interface\FrameXML\MoneyFrame.xml"); - load_xml(&s, "UiPanels.xml"); + load_xml(&s, r"Interface\FrameXML\UIParent.xml"); load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.lua"); load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.xml"); load_xml(&s, r"Interface\FrameXML\GlobalStrings.lua"); load_xml(&s, r"Interface\FrameXML\BasicControls.xml"); load_xml(&s, r"Interface\FrameXML\LocaleProperties.lua"); load_xml(&s, r"Interface\FrameXML\StaticPopup.xml"); - load_xml(&s, "UIParent.xml"); s.set_binder_pending(true); s } diff --git a/crates/benilla-app/src/ui_script/bottom_hud_tests.rs b/crates/benilla-app/src/ui_script/bottom_hud_tests.rs index 8e6c790f..9fec8868 100644 --- a/crates/benilla-app/src/ui_script/bottom_hud_tests.rs +++ b/crates/benilla-app/src/ui_script/bottom_hud_tests.rs @@ -100,7 +100,7 @@ fn shipped_xml() -> Vec<(String, String)> { fn no_shipped_file_declares_its_own_copy_of_a_managed_offset() { let mut offences = Vec::new(); for (name, text) in shipped_xml() { - if name == "UIParent.xml" { + if name == r"Interface\FrameXML\UIParent.xml" { continue; // the owner: its var rows are where these numbers are defined } for (n, line) in without_xml_comments(&text).lines().enumerate() { @@ -208,11 +208,17 @@ const BOTTOM_EXEMPT: &[(&str, &str)] = &[ /// not need to. Failing here is not a bug report; it is a prompt to pick one. #[test] fn every_bottom_anchored_top_level_frame_is_accounted_for() { - let pass = std::fs::read_to_string(ui_dir().join("UIParent.xml")).expect("UIParent.xml"); + // The pass is the stock `UIParent.lua`'s since 1988 — read off the player's chain. + let _data = benilla_formats::wow_data_or_skip!(); + let pass = String::from_utf8_lossy( + &super::reference_ui::read(r"Interface\FrameXML\UIParent.lua") + .expect("the stock UIParent.lua off the chain"), + ) + .into_owned(); for f in MANAGED_FRAMES { assert!( pass.contains(f), - "{f} is listed here as managed but does not appear in UIParent.xml's pass — this \ + "{f} is listed here as managed but does not appear in UIParent.lua's pass — this \ list has drifted from the file it mirrors" ); } @@ -222,8 +228,7 @@ fn every_bottom_anchored_top_level_frame_is_accounted_for() { let doc = benilla_ui::framexml::parse(&text).unwrap_or_else(|e| panic!("{file}: {e}")); for (name, anchors) in bottom_anchored_top_level(&doc) { let known = MANAGED_FRAMES.contains(&name.as_str()) - || BOTTOM_EXEMPT.iter().any(|(n, _)| *n == name) - || registers_a_listener(&text, &name); + || BOTTOM_EXEMPT.iter().any(|(n, _)| *n == name); if !known { unaccounted.push(format!("{file}: {name} ({anchors})")); } @@ -233,21 +238,12 @@ fn every_bottom_anchored_top_level_frame_is_accounted_for() { unaccounted.is_empty(), "these top-level frames anchor to the screen's bottom edge but nothing decides their \ clearance over the action bars. Give each one a row in \ - UIPARENT_MANAGED_FRAME_POSITIONS (UIParent.xml), or seat it from a managed global and \ - register UIParent_RegisterManagedPositionListener, or add it to BOTTOM_EXEMPT here with \ - the reason it needs neither (decision 1499):\n{}", + UIPARENT_MANAGED_FRAME_POSITIONS (the stock UIParent.lua's table, since 1988), or add \ + it to BOTTOM_EXEMPT here with the reason it needs no row (decision 1499):\n{}", unaccounted.join("\n") ); } -/// A file that registers a managed-position listener is seating something itself; the frames it -/// declares are covered by that registration. Coarse on purpose — the listener seats a whole -/// family (the bag stack is five windows), and naming each one here would be the same drift trap -/// `MANAGED_FRAMES` guards against. -fn registers_a_listener(text: &str, _frame: &str) -> bool { - text.contains("UIParent_RegisterManagedPositionListener") -} - /// Every top-level INSTANCE (a ``/`