From a0fce18079347c42771f730bad4384dccf2a8797 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 14 Aug 2026 18:54:39 +0700 Subject: [PATCH] the main action bar pages, and runs Lua like the client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the main bar's page arrows page for real, with the reference's own rule that a page a shown multibar displays is not also reachable by paging - `` executes the file the way the client does — dispatch on the extension — so an addon pulling its libraries through XML stops losing them - UIParentLoadAddOn lands, the on-demand loader behind every "open the panel" path - nine constants take the reference's names back (NUM_GROUP_LOOT_FRAMES and friends — an addon reads the real name, not our prefix), and UnitCreatureType answers through the client's own three-stage resolver Co-Authored-By: Claude Fable 5 --- crates/benilla-app/assets/ui/ActionBar.xml | 97 +++++++++++++-- crates/benilla-app/assets/ui/BankFrame.xml | 10 +- .../benilla-app/assets/ui/BasicControls.xml | 33 +++++ .../benilla-app/assets/ui/CharacterFrame.xml | 6 +- .../benilla-app/assets/ui/GroupLootFrame.xml | 15 ++- crates/benilla-app/assets/ui/PetActionBar.xml | 6 +- .../assets/ui/PetPaperDollFrame.xml | 4 +- .../benilla-app/assets/ui/QuestLogFrame.xml | 20 ++-- .../src/ui_script/action_bar_tests.rs | 113 +++++++++++++++++- .../src/ui_script/addon_list_tests.rs | 63 ++++++++++ crates/benilla-app/src/ui_unit.rs | 10 +- crates/benilla-ui/src/loader/mod.rs | 61 ++++++++++ crates/benilla-ui/src/loader/tests.rs | 80 +++++++++++++ .../src/script/tests/reference_surface.rs | 54 +++++++++ crates/benilla-ui/src/script/unit/bindings.rs | 59 +++++++++ 15 files changed, 592 insertions(+), 39 deletions(-) diff --git a/crates/benilla-app/assets/ui/ActionBar.xml b/crates/benilla-app/assets/ui/ActionBar.xml index 0e2e3e32..95544f42 100644 --- a/crates/benilla-app/assets/ui/ActionBar.xml +++ b/crates/benilla-app/assets/ui/ActionBar.xml @@ -67,12 +67,12 @@ -- -- Found by the use-probe, which is the only column that touches anything. -- - -- `CURRENT_ACTIONBAR_PAGE` is deliberately NOT among them. It is the reference's mutable - -- page cursor (ActionButton.lua:64/74 walk it), and benilla does not page the main bar that - -- way — the bonus offset re-pages it instead. Defining it as a frozen 1 would hand every - -- addon a number that is silently wrong forever; absent, a reader fails loudly and we find - -- out. That is this arc's own rule (1203/1205/1230: a silent wrong answer costs more than - -- a missing one), applied to ourselves. + -- `CURRENT_ACTIONBAR_PAGE` used to be withheld from this list on the grounds that it is the + -- reference's MUTABLE page cursor and we did not page the main bar — "defining it as a + -- frozen 1 would hand every addon a number that is silently wrong forever". That reasoning + -- was right and is now discharged rather than overruled: the bar pages, the global is live + -- state the paged-id formula reads, and it is declared with the paging verbs below rather + -- than here among the true constants. A frozen 1 would still be a lie; this one moves. NUM_ACTIONBAR_PAGES = 6 NUM_ACTIONBAR_BUTTONS = 12 BOTTOMLEFT_ACTIONBAR_PAGE = 6 @@ -134,6 +134,80 @@ -- feedback events per-button; our bar-level fan needs the full set in one place. BENILLA_ACTION_BUTTONS = {} + -- ── Main-bar paging (ref ActionButton.lua l.1-12 and l.63-101) ─────────────────────── + -- The main bar has six pages, and we already hold every slot they address: the app owns + -- the authoritative 1..120 action table, so the DATA for pages 2-6 was always there and + -- only the page SELECTOR was missing. Its absence was on screen, not just in the API — + -- the page arrows below shipped as art with no OnClick, which this file's own comment + -- admitted ("ART ONLY - we have no bar paging, so the clicks are no-ops"). + -- + -- `Bartender2.lua:686` is the corpus tell: three bare `ChangeActionBarPage()` calls, and + -- the addon died on the nil global at session start. + CURRENT_ACTIONBAR_PAGE = 1 + -- "Table of actionbar pages and whether they're viewable or not" (the reference's own + -- comment). The page walk below honours it rather than counting, which is what makes the + -- next two lines work at all. + -- + -- **Pages 5 and 6 are deliberately NOT viewable, and that is the reference's own rule + -- applied to our configuration rather than a deviation from it.** + -- `MultiActionBar_Update` (ref MultiActionBars.lua l.49-60) blanks + -- `VIEWABLE_ACTION_BAR_PAGES[BOTTOMLEFT_ACTIONBAR_PAGE]` whenever MultiBarBottomLeft is + -- SHOWN — a page a multibar already displays must not also be reachable on the main bar, + -- or paging up shows you the twelve actions already on screen below. benilla's two bottom + -- bars are always-on with no `SHOW_MULTI_ACTIONBAR_*` state (0270, the director's call), + -- and they own pages 6 and 5 (MultiBars.xml: BottomLeft = actions 61..72, BottomRight = + -- 49..60), so the two rows are blanked at declaration instead of by a toggle. + -- + -- MultiBarLeft/Right (pages 4 and 3) stay viewable because ours ship HIDDEN (1219), which + -- is the same state the reference is in with SHOW_MULTI_ACTIONBAR_3/4 unset. + VIEWABLE_ACTION_BAR_PAGES = {1, 1, 1, 1} + VIEWABLE_ACTION_BAR_PAGES[BOTTOMRIGHT_ACTIONBAR_PAGE] = nil + VIEWABLE_ACTION_BAR_PAGES[BOTTOMLEFT_ACTIONBAR_PAGE] = nil + + -- `ChangeActionBarPage()` takes NO arguments — every reference caller sets + -- CURRENT_ACTIONBAR_PAGE first and then calls this to apply it (l.79, l.100), and + -- Bartender2 calls it bare. + -- + -- Upstream it is a client binding; here it is FrameXML, deliberately. Our paged action id + -- is computed in Lua by `BenillaActionBar_ActionFor`, so the page IS this global and the + -- only work left for the verb is the repaint the reference gets by firing + -- ACTIONBAR_PAGE_CHANGED. Addons CALL this, they never replace it, so the divergence is + -- unobservable from Lua — unlike a name we shadow, which is 1222's class. + function ChangeActionBarPage() + for i = 1, table.getn(BENILLA_ACTION_BUTTONS) do + BenillaActionButton_Update(BENILLA_ACTION_BUTTONS[i]) + end + end + + function ActionBar_PageUp() + local page = CURRENT_ACTIONBAR_PAGE + 1 + local nextPage + for i = page, NUM_ACTIONBAR_PAGES do + if VIEWABLE_ACTION_BAR_PAGES[i] then nextPage = i break end + end + -- Past the last viewable page, wrap to 1 — the reference wraps to the LITERAL 1 here + -- rather than to the first viewable page, which is its own asymmetry with PageDown + -- (which rescans). Kept, because it is observable: with page 1 blanked, paging up off + -- the end lands on a page the down-walk would have skipped. + CURRENT_ACTIONBAR_PAGE = nextPage or 1 + ChangeActionBarPage() + end + + function ActionBar_PageDown() + local page = CURRENT_ACTIONBAR_PAGE - 1 + local prevPage + for i = page, 1, -1 do + if VIEWABLE_ACTION_BAR_PAGES[i] then prevPage = i break end + end + if not prevPage then + for i = NUM_ACTIONBAR_PAGES, 1, -1 do + if VIEWABLE_ACTION_BAR_PAGES[i] then prevPage = i break end + end + end + CURRENT_ACTIONBAR_PAGE = prevPage + ChangeActionBarPage() + end + -- Seat a TOP-LEVEL frame that anchors INTO the bar art (the bag bar + backpack toggle, -- BagFrame.xml; the micro-button row, MicroMenu.xml) one frame level above the art, so its -- icons draw over the bar plate instead of under it. @@ -224,6 +298,11 @@ local base = 0 if offset > 0 then base = (6 + offset - 1) * 12 + else + -- The paged main bar. A bonus page (stance/form/stealth) OUTRANKS it, which is + -- why this is the else arm and not an addition: the reference's own + -- `ActionButton_GetPagedID` takes the bonus branch first. + base = (CURRENT_ACTIONBAR_PAGE - 1) * 12 end return base + index end @@ -1485,8 +1564,8 @@ + (ref-ActionBarFrame.xml l.159-217). Live now that the bar pages — they were + art with no OnClick for as long as `CURRENT_ACTIONBAR_PAGE` did not exist. --> diff --git a/crates/benilla-app/assets/ui/BankFrame.xml b/crates/benilla-app/assets/ui/BankFrame.xml index b54750eb..32de67f7 100644 --- a/crates/benilla-app/assets/ui/BankFrame.xml +++ b/crates/benilla-app/assets/ui/BankFrame.xml @@ -56,8 +56,8 @@ established cross-window reuse `TrainerFrame.xml`/`BagFrame.xml` already lean on). -->