From 112e82d27645531d0ea375bd62149006bb6db2a8 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2026 17:01:00 +0700 Subject: [PATCH] the vendor and gossip windows are the reference's own MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the vendor window is the reference's own `MerchantFrame.xml`, which took three things in order: the vendor cursor, the coin kit's move, and `GameTooltip:SetMerchantCompareItem` — where `offset` is the ordinal among CANDIDATE slots (empty ones skipped without decrementing) and a candidate matches by item CLASS and never by entry (two of four RE workers read it as an entry match, which would have fired the compare tooltip only when you already wear the identical item, i.e. never, with the window looking finished); two visible changes ride with the reference's rows — the coin columns take `SmallMoneyFrameTemplate`'s own geometry, and only the ICON takes the mouse, so hovering a row's name shows nothing, which is the client's behaviour - the gossip window is the reference's own, and its deferral was wrong: the "2px rows" were a harness gap (a bare test VM with no text measurer, while the app always installs one), not an engine one; four things the reference does that ours did not are pinned — a hidden SPACER row between the quest groups, coded options are NOT greyed (a coded row is clickable, and the send path's missing code is named as its own gap), the row label is the Button's own text, and the scroll child is not grown - the CAMP/QUIT dialogs and the PARTY_INVITE dialog move to `StaticPopup`'s home — the fourth such rehome of a dialog that had lived in whichever window first needed it — and moving them found a real bug: `button1 = CANCEL` captured a nil at load because `CANCEL` was declared below the insertion point, so the popup engine fell back and put "Yes" on the camp dialog's cancel button - three instruments: the gap report stops counting commented-out calls (`ShowInventorySellCursor` blocked the character sheet on three commented lines — a whole RE round spent on an over-report), it runs the load itself and answers in ONE table (29 "free" became 24 actually unblocked), and a shadow report predicts which swaps will fail by intersecting the names our files define with the names the chain files in our own manifest define — 38 collisions across 5 files, ours winning every one Co-Authored-By: Claude Fable 5.1 --- .../benilla-app/assets/ui/GameMenuFrame.xml | 89 +- crates/benilla-app/assets/ui/GossipFrame.xml | 568 -------- .../benilla-app/assets/ui/MerchantFrame.xml | 1170 ----------------- crates/benilla-app/assets/ui/PartyFrame.xml | 104 +- crates/benilla-app/assets/ui/UiPanels.xml | 137 +- crates/benilla-app/assets/ui/benilla.toc | 75 +- .../src/ui_script/action_bar_tests.rs | 2 +- crates/benilla-app/src/ui_script/bag_tests.rs | 36 +- .../src/ui_script/delete_item_tests.rs | 2 +- .../src/ui_script/dressup_tests.rs | 2 +- .../benilla-app/src/ui_script/errors_tests.rs | 8 +- .../benilla-app/src/ui_script/escape_tests.rs | 10 +- .../src/ui_script/frame_flag_gate.rs | 73 +- .../src/ui_script/game_menu_tests.rs | 13 +- .../benilla-app/src/ui_script/loot_tests.rs | 2 +- .../src/ui_script/merchant_tests.rs | 308 ++--- .../src/ui_script/options_tests.rs | 2 +- .../benilla-app/src/ui_script/panel_tests.rs | 143 +- .../benilla-app/src/ui_script/quest_tests.rs | 20 +- .../src/ui_script/questlog_tests.rs | 34 +- .../benilla-app/src/ui_script/reference_ui.rs | 268 +++- .../src/ui_script/shipped_xml_tests.rs | 8 + crates/benilla-app/src/ui_script/test_ui.rs | 22 + .../src/ui_script/tooltip_compare_tests.rs | 4 +- .../src/ui_script/trainer_tests.rs | 2 +- .../src/ui_script/unit_frame_tests.rs | 2 +- crates/benilla-app/tests/auction_frame.rs | 8 +- crates/benilla-app/tests/item_text_frame.rs | 20 +- crates/benilla-app/tests/mail_frame.rs | 3 +- crates/benilla-app/tests/trade_frame.rs | 3 +- .../src/script/tests/tooltip_item/bindings.rs | 203 +++ .../benilla-ui/src/script/tooltip_item/mod.rs | 179 ++- 32 files changed, 1139 insertions(+), 2381 deletions(-) delete mode 100644 crates/benilla-app/assets/ui/GossipFrame.xml delete mode 100644 crates/benilla-app/assets/ui/MerchantFrame.xml diff --git a/crates/benilla-app/assets/ui/GameMenuFrame.xml b/crates/benilla-app/assets/ui/GameMenuFrame.xml index d0b5c3b3..11e68d61 100644 --- a/crates/benilla-app/assets/ui/GameMenuFrame.xml +++ b/crates/benilla-app/assets/ui/GameMenuFrame.xml @@ -109,9 +109,6 @@ LOGOUT = LOGOUT or "Logout" EXIT_GAME = EXIT_GAME or "Exit Game" RETURN_TO_GAME = RETURN_TO_GAME or "Return to Game" - CAMP_TIMER = CAMP_TIMER or "%d %s until logout" - QUIT_TIMER = QUIT_TIMER or "%d %s until exit" - QUIT_NOW = QUIT_NOW or "Exit now" CANCEL = CANCEL or "Cancel" -- One label setter for a button with nothing behind it yet (Edit Mode and Support): set @@ -122,74 +119,10 @@ button:Disable() end - -- ── The two logout dialogs (spec: StaticPopup.lua l.564-600) ──────────────────────────── - -- Both are countdown dialogs: their `text` is a format string the popup engine's per-tick - -- branch fills with the remaining time (StaticPopup_OnUpdate's which-list already names CAMP - -- and QUIT), so they open blank and count down. `timeout = 20` matches the server's own - -- logout timer (vmangos `WorldSession::LogoutRequest` → 20 s), which is what the countdown - -- is displaying — the client is not the authority here, it is narrating the server's clock. - -- - -- The asymmetry between them is the spec's: CAMP offers only Cancel (the commented-out - -- CAMP_NOW/ForceLogout button is dead in 1.12 — "uncomment once forced logouts are completely - -- implemented"), while QUIT offers Exit now + Cancel, because a force-quit needs no server - -- round trip. - -- - -- Both entries below are written scalars-first, handlers-last, so the dialog's SHAPE reads - -- before its behaviour does. - - -- Dismissing a running countdown means "I didn't mean it": call the logout off. Only while - -- it is still RUNNING, though — the popup engine zeroes `timeleft` before hiding a dialog - -- that expired, so reaching zero leaves the logout alone. (Backwards, and every logout in - -- the field is cancelled by its own dialog at t=0 and the character never leaves.) One - -- function because both dialogs mean exactly this; `this` is the popup frame, which the - -- engine has bound around the handler. - local function CancelLogoutIfStillCounting() - if this.timeleft > 0 then - CancelLogout() - end - end - - StaticPopupDialogs["CAMP"] = { - text = CAMP_TIMER, - button1 = CANCEL, - timeout = 20, - whileDead = 1, - hideOnEscape = 1, - OnAccept = function() - CancelLogout() - end, - OnHide = CancelLogoutIfStillCounting, - } - - StaticPopupDialogs["QUIT"] = { - text = QUIT_TIMER, - button1 = QUIT_NOW, - button2 = CANCEL, - timeout = 20, - whileDead = 1, - hideOnEscape = 1, - -- A force-quit needs no server round trip, so the countdown it was narrating is over - -- the moment the button is pressed: zero `timeleft` so the OnHide below stands down. - OnAccept = function() - ForceQuit() - this.timeleft = 0 - end, - OnHide = CancelLogoutIfStillCounting, - } - - -- The camp/quit event driver. The ref handles these three in UIParent's own OnEvent - -- (UIParent.lua l.304-315); benilla has no UIParent frame, so this is a dedicated hidden - -- listener — the BenillaDeleteItemConfirmDriver shape. - function BenillaLogoutDriver_OnEvent() - if event == "PLAYER_CAMPING" then - StaticPopup_Show("CAMP") - elseif event == "PLAYER_QUITING" then - StaticPopup_Show("QUIT") - elseif event == "LOGOUT_CANCEL" then - StaticPopup_Hide("CAMP") - StaticPopup_Hide("QUIT") - end - end + -- The CAMP/QUIT dialogs and the three-event driver MOVED OUT, to UiPanels.xml — 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. ]]> - - - - - - self:RegisterEvent("PLAYER_CAMPING") - self:RegisterEvent("PLAYER_QUITING") - self:RegisterEvent("LOGOUT_CANCEL") - - BenillaLogoutDriver_OnEvent() - - diff --git a/crates/benilla-app/assets/ui/GossipFrame.xml b/crates/benilla-app/assets/ui/GossipFrame.xml deleted file mode 100644 index d9c2f592..00000000 --- a/crates/benilla-app/assets/ui/GossipFrame.xml +++ /dev/null @@ -1,568 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GossipFrame_OnLoad() - GossipFrame_OnEvent() - - BenillaGossipFrame_OnUpdate() - - PlaySound("igQuestListOpen") - CloseGossip(); PlaySound("igQuestListClose") - - - diff --git a/crates/benilla-app/assets/ui/MerchantFrame.xml b/crates/benilla-app/assets/ui/MerchantFrame.xml deleted file mode 100644 index 3df57f39..00000000 --- a/crates/benilla-app/assets/ui/MerchantFrame.xml +++ /dev/null @@ -1,1170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MerchantFrame_OnLoad() - MerchantFrame_OnEvent() - - - if MerchantFrame.itemHover then - if IsControlKeyDown() then - ShowInspectCursor() - else - ShowMerchantSellCursor(MerchantFrame.itemHover) - end - end - - - OpenBackpack(); PlaySound("igCharacterInfoOpen") - - CloseMerchant(); CloseBackpack(); HideRepairCursor(); ResetCursor(); MerchantFrame.itemHover = nil; PlaySound("igCharacterInfoClose") - - - diff --git a/crates/benilla-app/assets/ui/PartyFrame.xml b/crates/benilla-app/assets/ui/PartyFrame.xml index 2857e589..56966fe2 100644 --- a/crates/benilla-app/assets/ui/PartyFrame.xml +++ b/crates/benilla-app/assets/ui/PartyFrame.xml @@ -31,87 +31,20 @@ real job is the timeout/override/escape paths. -->