- the bag windows are the reference's own `ContainerFrame.xml` running off the player's patch chain — decision 1751 makes the stock 1.12 UI off the install the end state and `assets/ui` scaffolding that retires file-by-file (86 files against the 99-file stock corpus, 72% of the 1128-function global surface already built) — via one ordered manifest, `benilla.toc`, where a bare name is a file we ship and an `Interface\FrameXML\` path is the player's own file; the windows on screen are `ContainerFrame1..12`, the bank's six copy-pasted popouts fold into them at ids 5..10, net −750 lines, and the swap forced real engine verbs into being rather than stubs (`SetBagPortaitTexture` with its id-0 no-texture arm, `GameTooltip:AppendText`, `SetButtonPulse`, and a `<Model>` whose file is the cooldown indicator materializing as the native sweep, which three corpus addons inherit) - the 1.12 walk toggle lands: `TOGGLERUN` latches one bit with `ToggleRun`'s own silent refusal chain (dead, rooted, on a live server spline), and the walk animation was never missing at all — the flag reaches it through exactly one channel, the speed (`0x5fd100` picks Walk over Run on `speed > 2 × walkSpeed`); pinning it caught our remote extrapolator with the two min rungs backwards — `min(walk, run)` runs BEFORE the backward min, so a walking backpedaller moves at 2.5 yd/s where we would have played them the Run clip at 4.5 — and one shared `current_speed` now keeps the local controller and the extrapolator from ever disagreeing about it - the instance and raid lockout messages exist — six packets that were dropped as unknown opcodes now land, four of them as the CHAT_MSG_SYSTEM lines the client composes itself, which is why no Lua handler ever surfaced them — plus `IsInInstance`, `ResetInstances`, and the unit popup's "Reset all instances" row behind the reference's own predicate; where the binary contradicts vmangos: the ownership flag means "any instance bind" but vmangos only ever names raid binds, so the row was dead for every character without a raid lockout — term 1 is now also satisfied by our own eyes, walking out of a party dungeon the server itself bound us to - opening the world map showed 3D world at the sheet's margins: `BlackoutWorld` was parented to the very `UIParent` a fullscreen panel hides, and three more frames had crossed the same boundary — the shared dropdown lists (so the map's continent and zone pickers answered a click with nothing at all), the master-looter menu, and the screenshot confirmation, which could never appear during a cinematic; `frame_flag_gate` now checks the parent seat against the reference both ways a frame acquires one (the attribute, template-inherited included, and `<Frames>` nesting), and its first harvest took 30 divergences down to three accepted ones Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
995 lines
64 KiB
XML
995 lines
64 KiB
XML
<Ui>
|
||
<!--
|
||
**benilla's bag BAR** — the five buttons on the right of the main action bar, and nothing
|
||
else. The bag WINDOWS this file used to hold are gone: they are the reference's own
|
||
`ContainerFrame1..12`, executed off the player's installed patch chain (decision 1751,
|
||
`Interface\FrameXML\ContainerFrame.xml` in benilla.toc, three lines above this one).
|
||
|
||
So what remains is this client's stand-in for the reference's `MainMenuBarBagButtons.xml` /
|
||
`.lua` — the backpack button, `CharacterBag0Slot`..`CharacterBag3Slot`, `KeyRingButton`, and
|
||
the item-push card that flies into whichever of them took an item. It keeps the reference's
|
||
names because those are what addons reach for, and it will be replaced by the reference's
|
||
own file the day `PutItemInBag` / `PickupBagFromSlot` are bound (see the note at
|
||
`BagSlotButton_OnClick`, which is the migration ticket).
|
||
|
||
THE VERBS ARE THE REFERENCE'S NOW, and every button below calls them through the global:
|
||
`ToggleBackpack`, `ToggleBag`, `OpenAllBags`, `ToggleKeyRing`, `PutKeyInKeyRing`,
|
||
`IsBagOpen` — all from the sourced `ContainerFrame.lua`. That is not incidental: those
|
||
names are precisely what a bag addon replaces, so a button that called a private body
|
||
instead would make the addon silently inert (the lesson this file's own history carries —
|
||
four of the five buttons did exactly that once).
|
||
|
||
WHAT LIGHTS A BUTTON. The reference's `ContainerFrame_OnShow`/`_OnHide` write
|
||
`MainMenuBarBackpackButton:SetChecked` / `CharacterBag<N>Slot:SetChecked` directly, so with
|
||
stock windows the flag is already correct by the time a click handler's tail runs; each
|
||
tail below re-derives it with `IsBagOpen`, which is the reference's own scan under the name
|
||
it publishes for it. `KeyRingButton` is the same at `KEYRING_CONTAINER`.
|
||
|
||
KEYRING. `KEYRING_CONTAINER = -2` lives here because it lives in
|
||
`MainMenuBarBagButtons.lua:1` in the reference — and the sourced `ContainerFrame.lua` reads
|
||
it, so this file is load-bearing for a file above it in the manifest. Decision 0765's
|
||
keyring-as-container stands: the app feeds it like any other bag, so the reference's own
|
||
window, verbs and sounds take it unchanged. The one place the reference detours out of the
|
||
container API for a keyring slot is its tooltip, and that detour is adapted — with its
|
||
reasons — in `ContainerFrameAdapters.xml`.
|
||
|
||
ITEM PUSH (decision 0887): `BENILLA_ITEM_PUSH_*` + `BenillaItemPushAnim_*` are ours, and
|
||
deliberately not the reference's `ItemAnimTemplate` — that is a `<Model>` playing an .mdx
|
||
sequence, and this engine renders no FrameXML models (see `Cooldown.xml`'s own note). The
|
||
card below is the same animation sampled from the model's tracks and drawn as a quad.
|
||
|
||
The counts are NumberFontNormal and the labels GameFontHighlight — both from the shipped
|
||
Fonts.xml, so they render in the real fonts.
|
||
-->
|
||
<Script><![CDATA[
|
||
|
||
-- The keyring's container id (ref MainMenuBarBagButtons.lua:1) — decision 0765. It is an
|
||
-- ordinary container in every respect the seam cares about: the app feeds it like any other
|
||
-- bag (its slots are the player descriptor's own 81.., no container object), and every
|
||
-- container verb, the cursor, the pending-op lock and the wire drains take it unchanged.
|
||
-- What makes it special is only what the reference makes special: the window's art, its
|
||
-- open/close sound, and the fact that its capacity is not a wire field.
|
||
KEYRING_CONTAINER = -2
|
||
|
||
-- The backpack button (MainMenuBarBackpackButton): if any bag window is open, close them
|
||
-- all; otherwise open every existing bag (ref ToggleBackpack — "if numOpen > 0 then
|
||
-- CloseAllBags() else OpenAllBags()").
|
||
--
|
||
-- ONE STATED DIVERGENCE from ref BackpackButton_OnClick (MainMenuBarBagButtons.lua
|
||
-- l.55-69). The ref's tail re-derives the checked state from a scan of its NATIVE
|
||
-- ContainerFrames — and OnShow/OnHide dispatch is SYNCHRONOUS in the reference (wow-re
|
||
-- `onshow-onhide-dispatch-order.md`: Show binder 0x775750 → transition 0x76ae10 → notify
|
||
-- 0x76b260 → lua_pcall, every hop a direct call), so when an addon owns the bags its
|
||
-- OnShow's `SetChecked(1)` (Bagnon.lua l.33) lands FIRST and the ref tail stomps it: on
|
||
-- the real client the backpack button ends UNLIT after clicking it with Bagnon, and
|
||
-- lights only via the key binding (whose body is the bare `ToggleBackpack()`, no tail).
|
||
-- That click-path outcome contradicts the addon's evident intent and the director's call,
|
||
-- so ours swaps the scan for the auto-toggle UNDO below: checked belongs to the WINDOWS'
|
||
-- OnShow/OnHide writes — ours (BenillaBagFrame_OnShow/_OnHide) and any addon's alike —
|
||
-- and this handler only repairs what the CheckButton widget flipped before it ran. Every
|
||
-- stock outcome is identical to the ref's (the transition writes land inside
|
||
-- ToggleBackpack and are the last word); the addon case ends lit instead of stomped.
|
||
-- The widget-flip UNDO itself lives in the button's XML <OnClick> wrapper — the one seat
|
||
-- where the CheckButton auto-toggle has just happened — so every DIRECT caller of this
|
||
-- function (the tests, a macro) gets pure toggle semantics with no checked bookkeeping
|
||
-- to corrupt.
|
||
function BenillaBagToggle_OnClick()
|
||
-- Through the GLOBAL, so an addon that replaced `ToggleBackpack` gets the click.
|
||
ToggleBackpack()
|
||
end
|
||
|
||
-- ── The bag bar (decision 0216 slice 2) — four 30×30 buttons left of MainMenuBarBackpackButton,
|
||
-- mirroring the reference main-bar bag buttons (CharacterBag0..3Slot). No exact reference
|
||
-- XML was available to transcribe (not in the session's extracted set) — size (30×30) and
|
||
-- placement (left of the backpack button) are per the brief; inter-button spacing is an
|
||
-- authored assumption (2px), FLAGGED for the director's look. Each button shows the
|
||
-- equipped bag's own icon (GetInventoryItemTexture, inv slots 20..23 — Bag0Slot..Bag3Slot,
|
||
-- PaperDollItemFrame.dbc-verified, decision 0216 slice 2's char-feed extension) or the
|
||
-- empty-slot art when no bag is equipped there. Click toggles that bag's window — NAMED
|
||
-- DEFERRAL: no drag-to-equip a bag onto the bar yet (that's the paper-doll drag arc, slice
|
||
-- 3's scope, not this one).
|
||
-- The bag bar (and the backpack toggle) are RELOCATED onto the action bar — anchored into
|
||
-- MainMenuBarArtFrame's bottom-right — which means they need seating one frame level
|
||
-- above the bar art or it paints over their icons. That lever lives with the frame it's
|
||
-- about: BenillaActionBarArt_SeatAbove (ActionBar.xml, loaded before this file), which
|
||
-- carries the full explanation; the micro-button row is its second caller. Called
|
||
-- nil-GUARDED here: the shipped load order always has the bar first, but ~25 bag/bank/
|
||
-- escape/merchant test harnesses load THIS file alone — and with no bar loaded there is by
|
||
-- definition no bar art to seat above, so the guard's no-op is the right answer, not a
|
||
-- swallowed failure.
|
||
|
||
-- Bag0Slot..Bag3Slot = live inv ids 20..23 (char_stats.rs SLOT_INFO, DBC-verified); OUR bag
|
||
-- ids 1..4 map the same way (bagId N ⇒ inv slot 19+N), the id PickupInventoryItem/
|
||
-- GetInventoryItemTexture speak.
|
||
function BenillaBagBarSlot_InvSlot(button) return 19 + button.bagId end
|
||
|
||
function BenillaBagBarSlot_OnLoad(button, bagId)
|
||
button.bagId = bagId
|
||
-- The button's ID is the REFERENCE's: its 1-based inventory slot, 20..23 (the real
|
||
-- client gets there through PaperDollItemSlotButton_OnLoad, which resolves
|
||
-- "CharacterBag0Slot" → "Bag0Slot" → GetInventorySlotInfo → 20). Nothing of ours reads
|
||
-- it — every body here goes through `button.bagId` — but every ADDON does:
|
||
-- `Bagnon.lua:104` computes its highlight target as `this:GetID() - 19`, and against
|
||
-- an unset id that is -19, so Bagnon highlighted the wrong bag (silently, with no
|
||
-- raise) on every bag-slot hover. `isBag` is the same story from the same template
|
||
-- (ref BagSlotButtonTemplate OnLoad l.33), read by KeyRingItemButton_OnClick.
|
||
button:SetID(19 + bagId)
|
||
button.isBag = 1
|
||
button.icon = getglobal(button:GetName() .. "IconTexture")
|
||
if BenillaActionBarArt_SeatAbove then BenillaActionBarArt_SeatAbove(button) end
|
||
-- Both buttons (ref BagSlotButtonTemplate inherits PaperDollItemSlotButtonTemplate, and
|
||
-- its OnLoad calls PaperDollItemSlotButton_OnLoad — PaperDollFrame.lua:86 — so a bag-bar
|
||
-- slot registers the pair like every doll slot; MainMenuBarBagButtons.xml:78 does the
|
||
-- same for the backpack). BagSlotButton_OnClick reads no button: right-click opens the
|
||
-- bag, exactly as left does.
|
||
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||
-- Drag-to-equip (decision 0208 phase 1b's deferred bag-icon arm, now landed): the bar
|
||
-- slot is a paper-doll equipment slot for bags. LEFT drag picks the equipped bag up;
|
||
-- a drag/receive drops a carried bag in to equip it (PickupInventoryItem — the exact
|
||
-- doll-slot transition, the app maps id 20..23 onto wire bag slots 19..22).
|
||
button:RegisterForDrag("LeftButton")
|
||
button:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||
button:RegisterEvent("BAG_UPDATE")
|
||
button:RegisterEvent("ITEM_LOCK_CHANGED")
|
||
BenillaBagBarSlot_Update(button)
|
||
end
|
||
|
||
-- Placing/equipping a carried bag (or picking the equipped one up) rides PickupInventoryItem,
|
||
-- exactly like a paper-doll slot; the empty-cursor plain click just toggles the bag's window.
|
||
function BenillaBagBarSlot_Place(button)
|
||
PickupInventoryItem(BenillaBagBarSlot_InvSlot(button))
|
||
BenillaBagBarSlot_Update(button)
|
||
end
|
||
|
||
-- ref BagSlotButton_OnClick (MainMenuBarBagButtons.lua l.3-21): the cursor arm first (the
|
||
-- ref's PutItemInBag; ours is the equip/swap PickupInventoryItem arm, decision 0208 1b),
|
||
-- otherwise the toggle goes THROUGH THE GLOBAL `ToggleBag` — the exact name
|
||
-- Bagnon_Core/Overrides.lua replaces — with the ref's own button sound on that arm only.
|
||
-- Toggling the window directly here (what this did before) made every bag addon's override
|
||
-- silently inert for the four slot buttons while the backpack button honoured it: the
|
||
-- 517-line rule above ("the reference's names are the real entry points") applied to only
|
||
-- one of the five buttons, and the director met the other four.
|
||
function BenillaBagBarSlot_OnClick(button)
|
||
if CursorHasItem() then
|
||
BenillaBagBarSlot_Place(button) -- drop/equip the carried bag onto this slot
|
||
else
|
||
ToggleBag(button.bagId)
|
||
PlaySound("BAGMENUBUTTONPRESS")
|
||
end
|
||
-- The click's own CheckButton auto-toggle is provisional — re-derive from the NATIVE
|
||
-- window on every branch, the ref's exact tail (BagSlotButton_OnClick l.12-20 scans
|
||
-- ContainerFrame1..N: SetChecked(isVisible) whether the click toggled, placed a bag,
|
||
-- or did nothing). `IsBagOpen` IS that scan, under the name the reference publishes
|
||
-- for it. Reading the WINDOW rather than what ToggleBag did is load-bearing both ways:
|
||
-- stock, the flag is already set when the tail runs (ContainerFrame_OnShow wrote it);
|
||
-- with an addon holding the bags, no ContainerFrame is shown and the slot button stays
|
||
-- unlit — the reference's own behaviour, its scan being equally blind to addon frames.
|
||
button:SetChecked(IsBagOpen(button.bagId) and 1 or nil)
|
||
end
|
||
|
||
function BenillaBagBarSlot_OnEvent(button)
|
||
if event == "UNIT_INVENTORY_CHANGED" and arg1 ~= "player" then return end
|
||
-- ITEM_LOCK_CHANGED names its slot in arg1/arg2; the bar's slots are the EQUIPMENT_BAG
|
||
-- space, so a bag-window lock event (a real bag id in arg1) never concerns the icon —
|
||
-- repainting anyway is idempotent (the lock read below is slot-specific). BAG_UPDATE
|
||
-- fires per-bag-CONTENTS change, not per-icon change (the icon is the bag ITEM's own
|
||
-- texture) — repainting on it too covers the freshly-equipped-bag-template-in-flight frame.
|
||
BenillaBagBarSlot_Update(button)
|
||
end
|
||
|
||
-- ── The bar buttons' hovers ───────────────────────────────────────────────────────────
|
||
-- ref GlobalStrings.lua l.132 / l.1458 (enUS), fallback form: the real localized
|
||
-- GlobalStrings.lua runs before this file at runtime (ui_script/mod.rs), so these only
|
||
-- fill in for the harnesses that load no patch chain.
|
||
BACKPACK_TOOLTIP = BACKPACK_TOOLTIP or "Backpack"
|
||
EQUIP_CONTAINER = EQUIP_CONTAINER or "Equip Container"
|
||
-- ref GlobalStrings.lua l.2472 / l.2810 — the keyring's window title + button tooltip, and
|
||
-- the full-keyring refusal.
|
||
KEYRING = KEYRING or "Keyring"
|
||
NO_EMPTY_KEYRING_SLOTS_ERROR = NO_EMPTY_KEYRING_SLOTS_ERROR or "Your keyring is full."
|
||
-- **A REFERENCE TYPO, repaired here rather than lived with** (decision 1751: a divergence
|
||
-- becomes faithful or becomes a record, never silent — this is the record).
|
||
--
|
||
-- `PutKeyInKeyRing`'s full-ring arm reads `NO_EMPTY_KEYRING_SLOTS`
|
||
-- (ContainerFrame.lua l.753), and 1.12 ships **only** `NO_EMPTY_KEYRING_SLOTS_ERROR`
|
||
-- (GlobalStrings.lua l.2810 — checked, the shorter name appears nowhere in the file). So
|
||
-- in the real client the text is nil, `UIErrorsFrame:AddMessage` refuses it, and dropping
|
||
-- a key onto a full keyring reports nothing at all.
|
||
--
|
||
-- benilla ran its own `PutKeyInKeyRing` before 1751 and simply used the right name; now
|
||
-- the reference's own file runs, so the choice is explicit. **Supplying the name the
|
||
-- reference meant is the call**: the mechanism is not in dispute (its own line says which
|
||
-- string it wants), nothing of Blizzard's is edited, and the alternative is a player
|
||
-- gesture that silently does nothing while an error scrolls past. If fidelity to the bug
|
||
-- is ever wanted instead, deleting this line is the whole change.
|
||
NO_EMPTY_KEYRING_SLOTS = NO_EMPTY_KEYRING_SLOTS or NO_EMPTY_KEYRING_SLOTS_ERROR
|
||
|
||
-- Both are PLAIN tooltips — the reference calls GameTooltip:SetText here, not
|
||
-- GameTooltip_AddNewbieTip, so unlike the micro buttons next door (0661) there is no second
|
||
-- explanation line to be missing. They also anchor beside the button (ANCHOR_LEFT, so the
|
||
-- plate opens toward screen center off a bottom-right button), NOT at the default corner.
|
||
--
|
||
-- ref MainMenuBarBackpackButton OnEnter (ref-MainMenuBarBagButtons.xml l.91-99). The ref
|
||
-- appends the live binding key with GameTooltip:AppendText; ours concatenates the same
|
||
-- suffix from a LIVE GetBindingKey read since 0997, rendered through the Key Bindings
|
||
-- window's display law when it is loaded. Unbound: the bare label, the ref's own read.
|
||
-- The command is TOGGLEBACKPACK — the ref's own read here, and since 1494 ours too: it is
|
||
-- the key that runs what a plain click on this button runs.
|
||
function BenillaBagToggle_OnEnter(button)
|
||
if not GameTooltip then return end -- engine tests load file subsets
|
||
GameTooltip:SetOwner(button, "ANCHOR_LEFT")
|
||
local text = BACKPACK_TOOLTIP
|
||
local key = GetBindingKey("TOGGLEBACKPACK")
|
||
if key then
|
||
if KeyBindings_KeyText then key = KeyBindings_KeyText(key) end
|
||
text = text .. " " .. NORMAL_FONT_COLOR_CODE .. "(" .. key .. ")" .. FONT_COLOR_CODE_CLOSE
|
||
end
|
||
GameTooltip:SetText(text, 1.0, 1.0, 1.0)
|
||
end
|
||
|
||
-- ref BagSlotButton_OnEnter (ref-MainMenuBarBagButtons.lua l.86-96): the equipped bag's own
|
||
-- item tooltip, or "Equip Container" for an empty slot. The ref's "(F8)".."(F11)" suffix
|
||
-- needed GetBindingKey AND the TOGGLEBAG1..4 bindings; those bind as of 1494, so the ONE
|
||
-- thing still missing is `GameTooltip:AppendText` — our tooltip has SetText/AddLine and no
|
||
-- append verb, and the ref's suffix lands on a plate SetInventoryItem already wrote. That
|
||
-- verb's byte semantics (which line does it extend?) are unverified, so the suffix waits
|
||
-- rather than guessing; this is where it goes, over `GetBindingKey("TOGGLEBAG"..(5 -
|
||
-- button.bagId))` — the ref's index is REVERSED against the bar, so the slot nearest the
|
||
-- backpack (bagId 1) is TOGGLEBAG4/F11 and the farthest (bagId 4) is TOGGLEBAG1/F8.
|
||
function BenillaBagBarSlot_OnEnter(button)
|
||
if not GameTooltip then return end
|
||
GameTooltip:SetOwner(button, "ANCHOR_LEFT")
|
||
if not GameTooltip:SetInventoryItem("player", BenillaBagBarSlot_InvSlot(button)) then
|
||
GameTooltip:SetText(EQUIP_CONTAINER, 1.0, 1.0, 1.0)
|
||
end
|
||
end
|
||
|
||
-- `BagSlotButton_OnEnter()` — THE REFERENCE'S NAME for the hover above, and the entry point
|
||
-- the four `CharacterBag<N>Slot` buttons actually call (their XML below). Published for the
|
||
-- same standing reason `ToggleBackpack` is: an addon replaces the client's global and
|
||
-- expects the client to call the replacement.
|
||
--
|
||
-- `Bagnon.lua:67` is the exact shape, and it is a hover-frequency call, not a rare one:
|
||
-- bBagSlotButton_OnEnter = BagSlotButton_OnEnter -- capture ours
|
||
-- BagSlotButton_OnEnter = BagnonBlizBag_OnEnter -- replace the global
|
||
-- Bagnon's replacement highlights the matching slots in its own window and then calls the
|
||
-- capture. With the global absent that capture was nil, and — because nothing here ever
|
||
-- looked the global up — the replacement was never reached to raise on it: Bagnon's
|
||
-- highlight was simply, silently inert. Corpus demand is exactly one addon (this one) at
|
||
-- two sites; its siblings `BagSlotButton_OnClick`/`_OnDrag`/`_OnShiftClick`/
|
||
-- `BackpackButton_OnClick` score ZERO and are deliberately not published (1210).
|
||
--
|
||
-- The reference's body takes no argument and reads `this`; so does this one.
|
||
function BagSlotButton_OnEnter()
|
||
BenillaBagBarSlot_OnEnter(this)
|
||
end
|
||
|
||
-- ref BagSlotButton_OnClick / _OnDrag / _OnShiftClick (MainMenuBarBagButtons.lua l.3-53),
|
||
-- published beside _OnEnter above for the same reason it was: they are the names
|
||
-- BagSlotButtonTemplate binds, and an addon that builds its bag bar from that template
|
||
-- reaches them and nothing else. pfUI is the measured caller (modules/bags.lua l.537), and
|
||
-- it CHAINS them — `GetScript("OnEnter")` then calling what it got — so a missing one is
|
||
-- not a dead button, it is a nil call inside the addon's own wrapper.
|
||
--
|
||
-- **Our four bar slots do not come through here** and are untouched: they carry an explicit
|
||
-- bagId from BenillaBagBarSlot_OnLoad and wire the Benilla bodies directly. These three
|
||
-- exist so a TEMPLATE-built button reaches the same bodies — one implementation, two entry
|
||
-- points, which is the whole point of publishing the reference's name over ours.
|
||
--
|
||
-- NOT the reference's bodies, and ONE of the two reasons for that expired with decision
|
||
-- 1751's bag swap. The reference's versions do two things: scan
|
||
-- ContainerFrame1..NUM_CONTAINER_FRAMES to re-derive the checked state — which now works
|
||
-- here, and the tails below do exactly it through `IsBagOpen` — and reach for
|
||
-- `PutItemInBag` / `PickupBagFromSlot`, which this client still does not bind (our
|
||
-- equip/swap arm is the paper doll's `PickupInventoryItem`, 0208 1b). That second half is
|
||
-- what still keeps `Interface\FrameXML\MainMenuBarBagButtons.xml` out of the manifest:
|
||
-- sourcing it today hands every caller a body that raises on a verb we have not built.
|
||
-- Those two verbs are the bag BAR's migration ticket, and this file is what it replaces.
|
||
function BagSlotButton_OnClick()
|
||
BenillaBagBarSlot_OnClick(this)
|
||
end
|
||
|
||
-- The drag arm: ref picks the equipped bag up with PickupBagFromSlot; ours is the same
|
||
-- PickupInventoryItem transition the bar slots already use, so an empty cursor picks the
|
||
-- bag up and a held bag places it.
|
||
function BagSlotButton_OnDrag()
|
||
BenillaBagBarSlot_Place(this)
|
||
end
|
||
|
||
-- Shift-click opens every bag if this slot HOLDS one (ref l.38-41 verbatim), then re-reads
|
||
-- the checked state off our own window the way BenillaBagBarSlot_OnClick's tail does.
|
||
function BagSlotButton_OnShiftClick()
|
||
if GetInventoryItemTexture("player", this:GetID()) then
|
||
OpenAllBags()
|
||
end
|
||
this:SetChecked(this.bagId and IsBagOpen(this.bagId) and 1 or nil)
|
||
end
|
||
|
||
-- ref OnLeave for both (l.100-102 / the template's own): a plain Hide, no fade — the item
|
||
-- half of the split BenillaUnitFrame_OnLeave's comment describes.
|
||
function BenillaBagBarButton_OnLeave()
|
||
if GameTooltip then GameTooltip:Hide() end
|
||
end
|
||
|
||
-- ref KeyRingButton's OnLoad/OnClick/OnReceiveDrag (MainMenuBarBagButtons.xml l.142-199).
|
||
-- The button is authored HIDDEN and only ever revealed by MainMenuBar_UpdateKeyRing
|
||
-- (ActionBar.xml), which is where the whole show/hide law and its divergence note live.
|
||
function BenillaKeyRingButton_OnLoad(button)
|
||
button:SetID(KEYRING_CONTAINER)
|
||
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||
button:RegisterForDrag("LeftButton")
|
||
-- The ref watches PLAYER_ENTERING_WORLD / VARIABLES_LOADED / BAG_UPDATE on the bar's art
|
||
-- frame; with no saved variable there is nothing for VARIABLES_LOADED to restore, and
|
||
-- BAG_UPDATE is what actually carries "a key just arrived".
|
||
button:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||
button:RegisterEvent("BAG_UPDATE")
|
||
if BenillaActionBarArt_SeatAbove then BenillaActionBarArt_SeatAbove(button) end
|
||
BenillaKeyRingButton_OnEvent()
|
||
end
|
||
|
||
function BenillaKeyRingButton_OnEvent()
|
||
if MainMenuBar_UpdateKeyRing then MainMenuBar_UpdateKeyRing() end
|
||
end
|
||
|
||
function BenillaKeyRingButton_OnClick(button)
|
||
-- Holding something ⇒ file it; empty-handed ⇒ open/close the keyring (ref l.166-173).
|
||
if CursorHasItem() then
|
||
PutKeyInKeyRing()
|
||
else
|
||
ToggleKeyRing()
|
||
end
|
||
-- Re-derive the lit ring from the window, the same provisional-toggle tail every other
|
||
-- bag-bar button uses. The keyring's window is an ordinary ContainerFrame now, so this
|
||
-- is the same `IsBagOpen` scan as the four bag slots', at KEYRING_CONTAINER.
|
||
button:SetChecked(IsBagOpen(KEYRING_CONTAINER) and 1 or nil)
|
||
end
|
||
|
||
-- ref l.180-184: the plain KEYRING title plus the ref's own empty AddLine (which reserves
|
||
-- the second row the binding key would print into — we ship no TOGGLEKEYRING binding, the
|
||
-- same gap the bag slots' "(F1)".."(F4)" suffixes have).
|
||
function BenillaKeyRingButton_OnEnter(button)
|
||
if not GameTooltip then return end
|
||
GameTooltip:SetOwner(button, "ANCHOR_LEFT")
|
||
GameTooltip:SetText(KEYRING, 1.0, 1.0, 1.0)
|
||
end
|
||
|
||
function BenillaBagBarSlot_Update(button)
|
||
local invSlot = BenillaBagBarSlot_InvSlot(button)
|
||
local texture = GetInventoryItemTexture("player", invSlot)
|
||
button.icon:SetTexture(texture or "Interface\\PaperDoll\\UI-PaperDoll-Slot-Bag")
|
||
-- Dim while the bag is up on the cursor or a pending equip is in flight (the doll's own
|
||
-- drag feedback, IsInventoryItemLocked — the bag-slot twin of BenillaBagSlot_Update).
|
||
if IsInventoryItemLocked(invSlot) then
|
||
button.icon:SetVertexColor(0.4, 0.4, 0.4)
|
||
elseif button:IsEnabled() ~= 0 then
|
||
button.icon:SetVertexColor(1, 1, 1)
|
||
else
|
||
-- Disabled by Disable_BagButtons below: keep the grey. The reference needs no such
|
||
-- arm — its desaturation is a shader flag on the texture, untouched by an Update
|
||
-- that only re-sets the image — but ours IS a vertex colour (UiPanels.xml
|
||
-- SetDesaturation), so a bag update behind the open game menu would otherwise
|
||
-- repaint the icon bright under a button that stayed dead.
|
||
button.icon:SetVertexColor(0.5, 0.5, 0.5)
|
||
end
|
||
end
|
||
|
||
-- ── The item-push drop animation (decision 0887) ─────────────────────────────────────────
|
||
-- An item lands in a bag: its icon pops in above the bag bar, hangs there, then falls into
|
||
-- the button that took it and shrinks away. ref ItemAnim (MainMenuBarBagButtons.xml l.4-16 +
|
||
-- .lua l.68-80, .lua l.92-94): each bag button owns a hidden child that, on ITEM_PUSH
|
||
-- naming its own container, swaps in the pushed item's icon, rewinds to sequence time 0 and
|
||
-- shows itself; OnAnimFinished hides it again. A second push on the same button RESTARTS it
|
||
-- (SetSequenceTime(0,0)); pushes into different bags run independently. That is exactly the
|
||
-- machine below, with the reference's ITEM_PUSH `arg1` translated from its inventory-slot
|
||
-- vocabulary (20..23) into ours (bagId 1..4) app-side — ui_loot.rs `push_container` carries
|
||
-- the byte-verified selector.
|
||
--
|
||
-- The reference's is a <Model> playing Interface\ItemAnimations\ForcedBackpackItem.mdx — a
|
||
-- single 4-vertex quad on one animated bone, i.e. a 2D icon card with keyframed scale, alpha
|
||
-- and offset. benilla has no Model widget (decision 0137's Cooldown took the same posture:
|
||
-- model the mechanism, let our own renderer draw it), so it is a Texture driven by the
|
||
-- model's OWN tracks, read out of the shipped .m2 with `benilla-extract m2anim`/`m2bones`:
|
||
--
|
||
-- sequence 0, CLAMP (plays once), duration 1.000 s
|
||
-- texture-weight (alpha) 0.000→0.0 0.133→1.0 0.267→1.0 1.000→0.0 linear
|
||
-- bone 0 scale 0.000→1.0 0.133→1.2 0.267→1.0 1.000→0.014 linear
|
||
-- bone 0 translation 0.000→(0,0) 0.500→(0,0) 1.000→(+0.010,-0.040)
|
||
-- the quad itself: 0.03 x 0.03 model units, blend Alpha, unlit, no depth write
|
||
--
|
||
-- So: fade in over the first 133 ms while swelling to 1.2x; settle back to full size by
|
||
-- 267 ms; from there dwindle and fade continuously for the remaining 733 ms — while the
|
||
-- POSITION holds until the half-second and only then falls. The three tracks deliberately
|
||
-- do not share a schedule: the card is already down to ~0.69 size and ~0.68 alpha when it
|
||
-- starts moving, so the drop reads as the icon being drawn into the bag rather than as a
|
||
-- solid tile sliding. Those numbers are the file's, not ours.
|
||
--
|
||
-- THE MODEL-UNIT → PIXEL SCALE is no longer ours to calibrate: the <Model> widget's
|
||
-- projection is RE-recorded now (wow-re `system/ui/scratch/modelframe-animation-clock.md`,
|
||
-- dispatched over the pet bar's B228 and folded back with it). The ortho leg gives
|
||
--
|
||
-- px per model unit = (5/3) * modelScale * layoutScale * screenHeightPx
|
||
--
|
||
-- which in FrameXML units is **1280 * modelScale * layoutScale**, aspect- and
|
||
-- resolution-independent, with the model ORIGIN at the frame rect's bottom-left. The ref's
|
||
-- `ItemAnimTemplate` (MainMenuBarBagButtons.xml:4) carries **no `scale` attribute**, so
|
||
-- modelScale is 1 and the constant is a flat 1280. Decision 0887's named gap is closed.
|
||
--
|
||
-- This REPLACES a back-fit, and the back-fit is worth naming because it looked like
|
||
-- evidence. The old 1200 came from assuming CooldownFrameTemplate's 0.04-unit sweep
|
||
-- *exactly* covers a 36 px action button at its scale="0.75" (⇒ K = 1200). The assumption
|
||
-- is the error: at the real projection that sweep is 0.04 · 1280 · 0.75 = **38.4 px**, so
|
||
-- it overhangs its button by 6.7% rather than fitting it — exactly as the autocast shine's
|
||
-- 30.72 px square overhangs its 30 px button. Solving against a wrong premise produced a
|
||
-- number that then "cross-checked" against a second model derived the same wrong way, and
|
||
-- both files cited the agreement as the reason to trust it.
|
||
--
|
||
-- Everything below is the model's own ratios times this constant, so the correction lands
|
||
-- in one place and the animation stays in proportion.
|
||
BENILLA_ITEM_PUSH_PX_PER_UNIT = 1280
|
||
BENILLA_ITEM_PUSH_DURATION = 1.0
|
||
|
||
-- ── The widget rect, and why the card is not placed against the button ─────────────────
|
||
-- A `<Model>` with no `<Size>` and no `setAllPoints` takes its rect from the **M2 header
|
||
-- bounding box** (`MD20+0xB4`, max−min per axis), consumed RAW as layout units — unlike
|
||
-- CSimpleTexture's texel fallback, there is no AbsDimension conversion. So the ref's
|
||
-- ItemAnim widget is **42.41 x 124.72**, nothing like the 36-square everyone assumes from
|
||
-- looking at the XML, and **model-space (0,0,0) lands on that rect's BOTTOM-LEFT corner**.
|
||
-- (wow-re `system/ui/scratch/modelframe-implicit-size-law.md`, §5-cross-checked: vtable
|
||
-- 0x81c5d8 +0x1c/+0x20 -> 0x76d080/0x76d0d0, bbox source 0x713640 at `713661 add esi,0xb4`.
|
||
-- The one worker who read `MD20+0xD0` — the VertexBox — got an all-zero box and concluded
|
||
-- the widget was degenerate; that wrong premise is exactly what the pair round exists to
|
||
-- catch, and it is why this looked unresolvable in 0887.)
|
||
--
|
||
-- That rect is the whole reason this animation reads the way it does: it stands 124.72 tall
|
||
-- off the button's own bottom edge, so the card's travel band reaches **54 px above the
|
||
-- button's top**. Decision 0887 could not know that and placed the card against the
|
||
-- button's CENTER instead, which is what put it in the wrong place in x and gave it no
|
||
-- horizontal drift at all.
|
||
BENILLA_ITEM_PUSH_FRAME_W = 42.41
|
||
BENILLA_ITEM_PUSH_FRAME_H = 124.72
|
||
-- Where that rect hangs off the button: the ref anchors the widget's BOTTOMRIGHT to the
|
||
-- button's, 10 in from the right for the five bag buttons and flush (0) for the keyring —
|
||
-- MainMenuBarBagButtons.xml l.19-27 (BagSlotButtonTemplate) and l.152-160 (KeyRingButton).
|
||
-- Per-button, so it is an OnLoad argument, not a constant.
|
||
BENILLA_ITEM_PUSH_ANCHOR_X = -10
|
||
|
||
-- ── The model's own numbers, unrounded ────────────────────────────────────────────────
|
||
-- Every one of these was rounded in 0887 and every rounding moved the card. The quad span
|
||
-- read as 0.03 (it is 0.0288 — a 4% size error), and the translation as (0.010, -0.040)
|
||
-- (which alone accounts for half a pixel of the landing point).
|
||
--
|
||
-- The bone transform is `v' = pivot + T(t) + S(t) * (v - pivot)` — three wow-re workers
|
||
-- derived that independently in three matrix conventions and agreed. The pivot
|
||
-- (M2CompBone+0x60) is NOT the quad's centre: it sits 0.23 px right and 0.07 px above it,
|
||
-- so the card shrinks *almost* in place and drifts a fifth of a pixel doing it. Keeping
|
||
-- the pivot as its own term rather than folding it into the centre is what makes this
|
||
-- reproduce the reference exactly at all three sampled times instead of nearly.
|
||
-- Bone 0's ROTATION track is empty (nKeys = 0), so there is no roll to model.
|
||
BENILLA_ITEM_PUSH_PIVOT_X = 0.017580900341272354
|
||
BENILLA_ITEM_PUSH_PIVOT_Y = 0.053958501666784286
|
||
BENILLA_ITEM_PUSH_QUAD_X = 0.017400000942870975
|
||
BENILLA_ITEM_PUSH_QUAD_Y = 0.053900001570582390
|
||
BENILLA_ITEM_PUSH_QUAD_SPAN = 0.028800001833587885
|
||
|
||
-- {time, value} keyframes, linear between (M2 track interpolation 1) — the file's own keys,
|
||
-- at full precision. The three tracks keep DIFFERENT schedules and that is the whole feel:
|
||
-- the card fades up while swelling to 1.2x over 133 ms, settles back to full size at
|
||
-- 267 ms, then dwindles and fades *continuously* for the remaining 733 ms — while its
|
||
-- position holds until the half second and only then falls. So it is already at ~0.69 size
|
||
-- and ~0.68 alpha when it starts to move, and it is invisible by the time it lands.
|
||
BENILLA_ITEM_PUSH_ALPHA = { {0.000, 0.0}, {0.133, 1.0}, {0.267, 1.0}, {1.000, 0.0} }
|
||
BENILLA_ITEM_PUSH_SCALE = { {0.000, 1.0}, {0.133, 1.2000000476837158}, {0.267, 1.0}, {1.000, 0.01441549975425005} }
|
||
-- Translation is per-AXIS: the card falls 51.4 px and drifts 13.3 px RIGHT, so one shared
|
||
-- 0..1 "drop" curve (0887's shape) cannot express it — the old code had no horizontal term
|
||
-- at all and moved the card the wrong way in x when it inferred one.
|
||
BENILLA_ITEM_PUSH_TRANS_X = { {0.000, 0.0}, {0.500, 0.0}, {1.000, 0.010394600220024586} }
|
||
BENILLA_ITEM_PUSH_TRANS_Y = { {0.000, 0.0}, {0.500, 0.0}, {1.000, -0.040167398750782013} }
|
||
|
||
-- Sample a {time, value} keyframe list at `t`, linear between keys, clamped at both ends
|
||
-- (the M2 sampler's own shape for a CLAMP sequence).
|
||
function BenillaItemPushAnim_Sample(track, t)
|
||
local last = table.getn(track)
|
||
if t <= track[1][1] then return track[1][2] end
|
||
for i = 2, last do
|
||
local key = track[i]
|
||
if t <= key[1] then
|
||
local prev = track[i - 1]
|
||
local span = key[1] - prev[1]
|
||
if span <= 0 then return key[2] end
|
||
return prev[2] + (key[2] - prev[2]) * (t - prev[1]) / span
|
||
end
|
||
end
|
||
return track[last][2]
|
||
end
|
||
|
||
-- Place/size/fade the card for the current clock, from the model's own transform.
|
||
--
|
||
-- The card's centre in MODEL space is `pivot + T(t) + S(t)*(quadCentre - pivot)`; times the
|
||
-- projection constant that is its offset in layout units from the model origin, which is
|
||
-- the widget rect's bottom-left corner. The rect's own BOTTOMRIGHT hangs off the button's,
|
||
-- so the card is placed against the BUTTON'S BOTTOMRIGHT — never its centre — and the
|
||
-- frame width is what converts between the two.
|
||
--
|
||
-- On screen: a button-sized card appears with its bottom edge ~13.6 px ABOVE the button's
|
||
-- top, pops to 1.2x and back while fading in, hangs there through the first half second,
|
||
-- then falls down-and-right INTO the button, shrinking to a half-pixel point at its centre
|
||
-- as it fades out. Reproduces the reference at t = 0, 0.133 and 1.0 to the hundredth of a
|
||
-- pixel (`modelframe-implicit-size-law.md` §3's table).
|
||
--
|
||
-- NOT modelled, deliberately, and both are named in the record: the reference's widget
|
||
-- CLIPS the card to its own rect, which shaves 1.94 px off the right edge at the 1.2x peak
|
||
-- **at 4:3 only** (16:10 and 16:9 clear it); and the widget clears the depth buffer inside
|
||
-- that 124.72-tall rect every paint. benilla draws this as a Texture, not a Model, so it
|
||
-- inherits neither — reproducing an aspect-conditional sliver would be hard-coding a
|
||
-- rendering artefact rather than modelling the mechanism that causes it.
|
||
function BenillaItemPushAnim_Paint(anim)
|
||
local t = anim.elapsed
|
||
local k = BENILLA_ITEM_PUSH_PX_PER_UNIT
|
||
local scale = BenillaItemPushAnim_Sample(BENILLA_ITEM_PUSH_SCALE, t)
|
||
local size = BENILLA_ITEM_PUSH_QUAD_SPAN * scale * k
|
||
local cx = (BENILLA_ITEM_PUSH_PIVOT_X
|
||
+ BenillaItemPushAnim_Sample(BENILLA_ITEM_PUSH_TRANS_X, t)
|
||
+ scale * (BENILLA_ITEM_PUSH_QUAD_X - BENILLA_ITEM_PUSH_PIVOT_X)) * k
|
||
local cy = (BENILLA_ITEM_PUSH_PIVOT_Y
|
||
+ BenillaItemPushAnim_Sample(BENILLA_ITEM_PUSH_TRANS_Y, t)
|
||
+ scale * (BENILLA_ITEM_PUSH_QUAD_Y - BENILLA_ITEM_PUSH_PIVOT_Y)) * k
|
||
anim:SetWidth(size)
|
||
anim:SetHeight(size)
|
||
anim:SetPoint("CENTER", anim:GetParent(), "BOTTOMRIGHT",
|
||
anim.anchorX - BENILLA_ITEM_PUSH_FRAME_W + cx, cy)
|
||
anim:SetAlpha(BenillaItemPushAnim_Sample(BENILLA_ITEM_PUSH_ALPHA, t))
|
||
end
|
||
|
||
-- ref ItemAnim_OnLoad (l.68-70): the card listens for ITEM_PUSH and nothing else. It is
|
||
-- authored hidden, so it costs no OnUpdate until a push shows it (events reach hidden
|
||
-- frames; OnUpdate does not — the reference's own split).
|
||
function BenillaItemPushAnim_OnLoad(anim, containerId, anchorX)
|
||
anim.containerId = containerId
|
||
-- The widget's own offset from the button's BOTTOMRIGHT: -10 for the five bag buttons,
|
||
-- flush 0 for the keyring (the ref's two different anchors — see the constant block).
|
||
anim.anchorX = anchorX or BENILLA_ITEM_PUSH_ANCHOR_X
|
||
anim.icon = getglobal(anim:GetName() .. "Icon")
|
||
anim.elapsed = 0
|
||
anim:RegisterEvent("ITEM_PUSH")
|
||
end
|
||
|
||
-- ref ItemAnim_OnEvent (l.72-80): `if this:GetParent():GetID() == arg1`, then
|
||
-- ReplaceIconTexture(arg2) / SetSequence(0) / SetSequenceTime(0,0) / Show. A push into a bag
|
||
-- with no button (a bank bag) matches nothing and animates nowhere, there and here.
|
||
function BenillaItemPushAnim_OnEvent(anim)
|
||
if arg1 ~= anim.containerId then return end
|
||
anim.icon:SetTexture(arg2)
|
||
anim.elapsed = 0
|
||
-- Seat the card above its button rather than at load: the bag bar's own level is set in
|
||
-- the BUTTON's OnLoad (BenillaActionBarArt_SeatAbove), which the loader may run after
|
||
-- this child exists. Re-deriving it per push is one call and can never read it stale.
|
||
anim:SetFrameLevel(anim:GetParent():GetFrameLevel() + 1)
|
||
BenillaItemPushAnim_Paint(anim)
|
||
anim:Show()
|
||
end
|
||
|
||
-- The CLAMP sequence's end is the ref's OnAnimFinished → this:Hide() (l.92-94).
|
||
function BenillaItemPushAnim_OnUpdate(anim, elapsed)
|
||
anim.elapsed = anim.elapsed + (elapsed or 0)
|
||
if anim.elapsed >= BENILLA_ITEM_PUSH_DURATION then
|
||
anim:Hide()
|
||
return
|
||
end
|
||
BenillaItemPushAnim_Paint(anim)
|
||
end
|
||
|
||
-- The bag BAR's five buttons (the backpack toggle + the four equipped-bag slots) — the row
|
||
-- Disable_/Enable_BagButtons greys as a unit. Distinct from UiPanels.xml's BAG_WINDOWS,
|
||
-- which is the five bag *windows* those buttons open.
|
||
BENILLA_BAG_BUTTONS = { "MainMenuBarBackpackButton", "CharacterBag0Slot", "CharacterBag1Slot",
|
||
"CharacterBag2Slot", "CharacterBag3Slot" }
|
||
|
||
-- Disable_BagButtons / Enable_BagButtons — ref MainMenuBarBagButtons.lua l.102-128, called
|
||
-- by GameMenuFrame's OnShow/OnHide (decision 0674) and by nothing else: while the game menu
|
||
-- holds the screen, the whole bag row greys out. That is the *visible* half of a rule the
|
||
-- panel manager already enforces (ShowUIPanel's native-center gate refuses every window
|
||
-- while the menu is up — UiPanels.xml `CanOpenPanels`); without it the bags would look
|
||
-- clickable and simply do nothing.
|
||
--
|
||
-- Mapping onto benilla's row: the ref's MainMenuBarBackpackButton is MainMenuBarBackpackButton and
|
||
-- CharacterBag0..3Slot are CharacterBag0Slot..4 — and in BOTH cases the greying goes onto
|
||
-- the button's `$parentIcon` LAYER texture, never onto a state texture. That is the
|
||
-- reference's own structure and it is load-bearing here: a disabled button draws its
|
||
-- DisabledTexture, and with none set it draws no state texture at all
|
||
-- (`ButtonState::region_visible`), so greying a NormalTexture would grey something already
|
||
-- gone. The four slots' UI-Quickslot2 rings ARE state textures and do vanish while
|
||
-- disabled unless the slot states one explicitly — so what you should see is the
|
||
-- ring stay put and the bag icon grey — which is why each slot repeats its ring as
|
||
-- DisabledTexture (see the slot instances below).
|
||
function Disable_BagButtons()
|
||
for _, button in ipairs(BENILLA_BAG_BUTTONS) do
|
||
local b = getglobal(button)
|
||
b:Disable()
|
||
SetDesaturation(b.icon, 1)
|
||
end
|
||
end
|
||
|
||
function Enable_BagButtons()
|
||
for _, button in ipairs(BENILLA_BAG_BUTTONS) do
|
||
local b = getglobal(button)
|
||
b:Enable()
|
||
SetDesaturation(b.icon, nil)
|
||
end
|
||
-- The four slots' own paint decides their restored colour: an item locked on the cursor
|
||
-- wants its 0.4 grey back, which the un-desaturate above does not restore (it clears
|
||
-- the greyscale flag, not the tint).
|
||
for i = 1, 4 do
|
||
BenillaBagBarSlot_Update(getglobal("CharacterBag" .. (i - 1) .. "Slot"))
|
||
end
|
||
end
|
||
]]></Script>
|
||
|
||
<!--
|
||
The backpack toggle, RELOCATED onto the main action bar's right side so the bar reads whole
|
||
(the real client's MainMenuBarBackpackButton, ref-MainMenuBarBagButtons.xml l.54-64): a 37x37
|
||
button parented/anchored to the bar art frame at BOTTOMRIGHT (-6,2). Its behavior (toggle the
|
||
backpack window) is unchanged; only its seat moved from the free-floating screen corner onto
|
||
the bar. (MainMenuBarArtFrame is defined in ActionBar.xml, which the loader loads before
|
||
this file; the anchor resolves by name.)
|
||
-->
|
||
<CheckButton name="MainMenuBarBackpackButton" id="0" parent="MainMenuBarArtFrame">
|
||
<Size><AbsDimension x="37" y="37"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOMRIGHT" relativeTo="MainMenuBarArtFrame" relativePoint="BOTTOMRIGHT">
|
||
<Offset><AbsDimension x="-6" y="2"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<!-- The backpack art is a LAYER texture, not the NormalTexture — the reference's own
|
||
structure (MainMenuBarBackpackButton inherits ItemButtonTemplate and sets
|
||
`MainMenuBarBackpackButtonIconTexture` in its OnLoad; the state textures are the
|
||
template's ring). It matters because `Disable_BagButtons` (decision 0674) disables this
|
||
button while the game menu is up, and a *state* texture with no DisabledTexture beside
|
||
it is not drawn in the disabled state (`ButtonState::region_visible` — the byte rule at
|
||
`SetState 0x779790`), so the backpack icon vanished outright instead of greying
|
||
(director-reported). As a layer it is untouched by button state, exactly like the four
|
||
bag-bar slots' own `$parentIcon`, and the greying is the vertex tint on it. -->
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentIconTexture" file="Interface\Buttons\Button-Backpack-Up"/>
|
||
</Layer>
|
||
</Layers>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button, container id 0 = the backpack. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, 0)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
||
<!-- The lit ring while the backpack window is open (ref MainMenuBarBackpackButton
|
||
l.104) — a CheckButton like the ref's; OnShow/OnHide of the window drive it. -->
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<!-- Seat the backpack icon above the bar art too (same reason as the bag-bar slots —
|
||
BenillaActionBarArt_SeatAbove's comment). -->
|
||
<OnLoad>
|
||
self.icon = getglobal("MainMenuBarBackpackButtonIconTexture")
|
||
if BenillaActionBarArt_SeatAbove then BenillaActionBarArt_SeatAbove(self) end
|
||
</OnLoad>
|
||
<!-- The undo repairs the CheckButton widget's own pre-handler flip; from there the
|
||
checked state belongs to the windows' OnShow/OnHide writes (ours and any
|
||
addon's) — the stated divergence at BenillaBagToggle_OnClick's comment.
|
||
The shift fork is the ref's own (MainMenuBarBagButtons.xml l.81-87): the button
|
||
carries the SAME pair of knobs the B / SHIFT-B keys do (1494), so a shift-click
|
||
opens all bags and a plain one toggles the backpack. -->
|
||
<OnClick>
|
||
self:SetChecked(not self:GetChecked())
|
||
if IsShiftKeyDown() then
|
||
OpenAllBags()
|
||
else
|
||
BenillaBagToggle_OnClick()
|
||
end
|
||
</OnClick>
|
||
<OnEnter>BenillaBagToggle_OnEnter(self)</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
</Scripts>
|
||
</CheckButton>
|
||
|
||
<!--
|
||
The bag bar (decision 0216 slice 2, BenillaBagBarSlot_* above): four 36×36 buttons to the
|
||
LEFT of MainMenuBarBackpackButton, mirroring the reference CharacterBag0..3Slot row. Bar slot N (1..4)
|
||
sits at chain position N counting away from the backpack button — CharacterBag0Slot (bagId
|
||
1, Bag0Slot) is CLOSEST to the backpack, CharacterBag3Slot (bagId 4, Bag3Slot) FARTHEST —
|
||
the real bar's own left-to-right order. Sized to MATCH the action buttons (36×36 icon in a
|
||
66×66 UI-Quickslot2 ring, 6px chain gap = the 42px stride), so the bag icons fill their slots
|
||
exactly like the spell icons instead of floating undersized (the earlier 30×30 guess).
|
||
-->
|
||
<CheckButton name="CharacterBag0Slot" parent="MainMenuBarArtFrame">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors>
|
||
<Anchor point="RIGHT" relativeTo="MainMenuBarBackpackButton" relativePoint="LEFT"><Offset><AbsDimension x="-6" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers><Layer level="BACKGROUND"><Texture name="$parentIconTexture"/></Layer></Layers>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button; container id 1. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, 1)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<NormalTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</NormalTexture>
|
||
<!-- The same ring again as the DISABLED art, so the slot keeps its frame while
|
||
Disable_BagButtons has the row greyed under the game menu (decision 0674). A button
|
||
with no DisabledTexture draws NO state texture when disabled
|
||
(`ButtonState::region_visible`) — the ring would blink out of the bar entirely. The
|
||
reference needs no such line because its widget keeps the previously shown texture up
|
||
when the new state's slot is empty (`SetState 0x779790`'s gated hide); ours states it
|
||
instead of relying on that. -->
|
||
<DisabledTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</DisabledTexture>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
||
<!-- The lit ring while this bag's window is open (ref BagSlotButtonTemplate l.52). -->
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>BenillaBagBarSlot_OnLoad(self, 1)</OnLoad>
|
||
<OnClick>BenillaBagBarSlot_OnClick(self)</OnClick>
|
||
<OnEvent>BenillaBagBarSlot_OnEvent(self)</OnEvent>
|
||
<OnEnter>BagSlotButton_OnEnter()</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
<!-- The drag trio: OnDragStart picks the equipped bag up, OnReceiveDrag drops a carried
|
||
bag in — both the same PickupInventoryItem transition (empty cursor picks up, a held
|
||
bag places), mirroring the paper-doll/bag-slot drag routing. -->
|
||
<OnDragStart>BenillaBagBarSlot_Place(self)</OnDragStart>
|
||
<OnReceiveDrag>BenillaBagBarSlot_Place(self)</OnReceiveDrag>
|
||
</Scripts>
|
||
</CheckButton>
|
||
<CheckButton name="CharacterBag1Slot" parent="MainMenuBarArtFrame">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors>
|
||
<Anchor point="RIGHT" relativeTo="CharacterBag0Slot" relativePoint="LEFT"><Offset><AbsDimension x="-6" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers><Layer level="BACKGROUND"><Texture name="$parentIconTexture"/></Layer></Layers>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button; container id 2. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, 2)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<NormalTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</NormalTexture>
|
||
<!-- The same ring again as the DISABLED art, so the slot keeps its frame while
|
||
Disable_BagButtons has the row greyed under the game menu (decision 0674). A button
|
||
with no DisabledTexture draws NO state texture when disabled
|
||
(`ButtonState::region_visible`) — the ring would blink out of the bar entirely. The
|
||
reference needs no such line because its widget keeps the previously shown texture up
|
||
when the new state's slot is empty (`SetState 0x779790`'s gated hide); ours states it
|
||
instead of relying on that. -->
|
||
<DisabledTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</DisabledTexture>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>BenillaBagBarSlot_OnLoad(self, 2)</OnLoad>
|
||
<OnClick>BenillaBagBarSlot_OnClick(self)</OnClick>
|
||
<OnEvent>BenillaBagBarSlot_OnEvent(self)</OnEvent>
|
||
<OnEnter>BagSlotButton_OnEnter()</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
<!-- The drag trio: OnDragStart picks the equipped bag up, OnReceiveDrag drops a carried
|
||
bag in — both the same PickupInventoryItem transition (empty cursor picks up, a held
|
||
bag places), mirroring the paper-doll/bag-slot drag routing. -->
|
||
<OnDragStart>BenillaBagBarSlot_Place(self)</OnDragStart>
|
||
<OnReceiveDrag>BenillaBagBarSlot_Place(self)</OnReceiveDrag>
|
||
</Scripts>
|
||
</CheckButton>
|
||
<CheckButton name="CharacterBag2Slot" parent="MainMenuBarArtFrame">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors>
|
||
<Anchor point="RIGHT" relativeTo="CharacterBag1Slot" relativePoint="LEFT"><Offset><AbsDimension x="-6" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers><Layer level="BACKGROUND"><Texture name="$parentIconTexture"/></Layer></Layers>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button; container id 3. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, 3)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<NormalTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</NormalTexture>
|
||
<!-- The same ring again as the DISABLED art, so the slot keeps its frame while
|
||
Disable_BagButtons has the row greyed under the game menu (decision 0674). A button
|
||
with no DisabledTexture draws NO state texture when disabled
|
||
(`ButtonState::region_visible`) — the ring would blink out of the bar entirely. The
|
||
reference needs no such line because its widget keeps the previously shown texture up
|
||
when the new state's slot is empty (`SetState 0x779790`'s gated hide); ours states it
|
||
instead of relying on that. -->
|
||
<DisabledTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</DisabledTexture>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>BenillaBagBarSlot_OnLoad(self, 3)</OnLoad>
|
||
<OnClick>BenillaBagBarSlot_OnClick(self)</OnClick>
|
||
<OnEvent>BenillaBagBarSlot_OnEvent(self)</OnEvent>
|
||
<OnEnter>BagSlotButton_OnEnter()</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
<!-- The drag trio: OnDragStart picks the equipped bag up, OnReceiveDrag drops a carried
|
||
bag in — both the same PickupInventoryItem transition (empty cursor picks up, a held
|
||
bag places), mirroring the paper-doll/bag-slot drag routing. -->
|
||
<OnDragStart>BenillaBagBarSlot_Place(self)</OnDragStart>
|
||
<OnReceiveDrag>BenillaBagBarSlot_Place(self)</OnReceiveDrag>
|
||
</Scripts>
|
||
</CheckButton>
|
||
<CheckButton name="CharacterBag3Slot" parent="MainMenuBarArtFrame">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors>
|
||
<Anchor point="RIGHT" relativeTo="CharacterBag2Slot" relativePoint="LEFT"><Offset><AbsDimension x="-6" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers><Layer level="BACKGROUND"><Texture name="$parentIconTexture"/></Layer></Layers>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button; container id 4. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, 4)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<NormalTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</NormalTexture>
|
||
<!-- The same ring again as the DISABLED art, so the slot keeps its frame while
|
||
Disable_BagButtons has the row greyed under the game menu (decision 0674). A button
|
||
with no DisabledTexture draws NO state texture when disabled
|
||
(`ButtonState::region_visible`) — the ring would blink out of the bar entirely. The
|
||
reference needs no such line because its widget keeps the previously shown texture up
|
||
when the new state's slot is empty (`SetState 0x779790`'s gated hide); ours states it
|
||
instead of relying on that. -->
|
||
<DisabledTexture file="Interface\Buttons\UI-Quickslot2">
|
||
<Size><AbsDimension x="66" y="66"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</DisabledTexture>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>BenillaBagBarSlot_OnLoad(self, 4)</OnLoad>
|
||
<OnClick>BenillaBagBarSlot_OnClick(self)</OnClick>
|
||
<OnEvent>BenillaBagBarSlot_OnEvent(self)</OnEvent>
|
||
<OnEnter>BagSlotButton_OnEnter()</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
<!-- The drag trio: OnDragStart picks the equipped bag up, OnReceiveDrag drops a carried
|
||
bag in — both the same PickupInventoryItem transition (empty cursor picks up, a held
|
||
bag places), mirroring the paper-doll/bag-slot drag routing. -->
|
||
<OnDragStart>BenillaBagBarSlot_Place(self)</OnDragStart>
|
||
<OnReceiveDrag>BenillaBagBarSlot_Place(self)</OnReceiveDrag>
|
||
</Scripts>
|
||
</CheckButton>
|
||
|
||
<!--
|
||
The keyring button (decision 0765) — ref KeyRingButton, MainMenuBarBagButtons.xml l.142-199.
|
||
Sits at the FAR left of the bag row, past CharacterBag3Slot (the ref's CharacterBag3Slot),
|
||
and is authored HIDDEN: nothing reveals it but MainMenuBar_UpdateKeyRing, and only
|
||
while HasKey() — the point being that a character with no key has no keyring at all, and the
|
||
bar's plate has no socket for one.
|
||
|
||
18x39 and the TexCoords are the ref's exactly, and they are not arbitrary: the three state
|
||
atlases are 32x64 holding one 18x39 button, so 18/32 = 0.5625 and 39/64 = 0.609375 crop it
|
||
1:1. The chain gap is OUR row's -6 rather than the ref's -5, so the button seats evenly
|
||
against the 36px slots this bar scaled its own row to.
|
||
|
||
Unlike the five bag buttons it is NOT in BENILLA_BAG_BUTTONS: its art is a state texture, not
|
||
an $parentIcon layer, so Disable_BagButtons' SetDesaturation(b.icon) has nothing to grey —
|
||
and the ref leaves it out of its own Disable_BagButtons for the same reason.
|
||
-->
|
||
<CheckButton name="KeyRingButton" parent="MainMenuBarArtFrame" hidden="true">
|
||
<Size><AbsDimension x="18" y="39"/></Size>
|
||
<Anchors>
|
||
<Anchor point="RIGHT" relativeTo="CharacterBag3Slot" relativePoint="LEFT"><Offset><AbsDimension x="-6" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<!-- The item-push drop card (decision 0887, BenillaItemPushAnim_* above) — the ref's
|
||
$parentItemAnim, one per bag button; container id -2 (KEYRING_CONTAINER). The ref gives
|
||
the keyring one too (MainMenuBarBagButtons.xml l.152-160), and the byte selector really
|
||
does reach it: a push landing in player-array slots 81..112 resolves to -2, not 0. -->
|
||
<Frames>
|
||
<Frame name="$parentItemAnim" hidden="true">
|
||
<Size><AbsDimension x="36" y="36"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>BenillaItemPushAnim_OnLoad(self, -2, 0)</OnLoad>
|
||
<OnEvent>BenillaItemPushAnim_OnEvent(self)</OnEvent>
|
||
<OnUpdate>BenillaItemPushAnim_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<NormalTexture file="Interface\Buttons\UI-Button-KeyRing">
|
||
<TexCoords left="0" right="0.5625" top="0" bottom="0.609375"/>
|
||
</NormalTexture>
|
||
<PushedTexture file="Interface\Buttons\UI-Button-KeyRing-Down">
|
||
<TexCoords left="0" right="0.5625" top="0" bottom="0.609375"/>
|
||
</PushedTexture>
|
||
<HighlightTexture file="Interface\Buttons\UI-Button-KeyRing-Highlight" alphaMode="ADD">
|
||
<TexCoords left="0" right="0.5625" top="0" bottom="0.609375"/>
|
||
</HighlightTexture>
|
||
<!-- The lit ring while the keyring window is open — the bag row's own convention
|
||
(the ref drives the same state through UpdateMicroButtons' SetButtonState). -->
|
||
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>BenillaKeyRingButton_OnLoad(self)</OnLoad>
|
||
<OnEvent>BenillaKeyRingButton_OnEvent()</OnEvent>
|
||
<OnClick>BenillaKeyRingButton_OnClick(self)</OnClick>
|
||
<OnEnter>BenillaKeyRingButton_OnEnter(self)</OnEnter>
|
||
<OnLeave>BenillaBagBarButton_OnLeave()</OnLeave>
|
||
<!-- A key dragged onto the button files itself, the ref's own OnReceiveDrag (l.174-178). -->
|
||
<OnReceiveDrag>PutKeyInKeyRing()</OnReceiveDrag>
|
||
</Scripts>
|
||
</CheckButton>
|
||
</Ui>
|