- GetInventorySlotInfo folds case the way the client does, and gains the twelve bag-slot rows the shipped data really carries - ChatTypeGroup exists for addons that register their own chat types at file scope — one missing table was taking five addons down - GetChannelList answers in join order, shaped by the addons that consume it, and the harness's `--why` can now open any demand count - the survey seats a spellbook, and the shapeshift bar's shelf art exists hidden, both exposing paths an empty fixture could never reach Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
259 lines
16 KiB
XML
259 lines
16 KiB
XML
<Ui>
|
|
<!--
|
|
The stance/shapeshift bar (vanilla ShapeshiftBarFrame, ref-BonusActionBarFrame.xml/.lua —
|
|
extracted from patch.MPQ). Warrior stances, druid forms, rogue Stealth: one CheckButton per
|
|
known form, checked = the ACTIVE form (the descriptor's UNIT_FIELD_BYTES_1 byte-2 form,
|
|
wow-re bonusbar-shapeshift.md), grey icon when not castable, cooldown swipe, click casts
|
|
the form (`crate::ui_shapeshift` drains CastShapeshiftForm onto the wire).
|
|
|
|
Geometry QUOTED from the ref, permanently in its RAISED mode (ShapeshiftBar_UpdatePosition's
|
|
MultiBarBottomLeft.isShowing branch — our bottom multibars are ALWAYS ON, MultiBars.xml):
|
|
frame BOTTOMLEFT at MainMenuBar TOPLEFT +(30,45); the ShapeshiftBarEnds/Middle shelf art
|
|
HIDDEN (raised mode hides it, so it is not modeled at all); buttons 30x30, button1 at frame
|
|
BOTTOMLEFT +(11,3), chained +7; NormalTexture UI-Quickslot2 at the raised mode's 50x50
|
|
(ref l.236-237), CENTER (0,-1) like the action template. Max 10 slots (NUM_SHAPESHIFT_SLOTS).
|
|
|
|
Ref divergences (deliberate):
|
|
- ONE refresh event: the app diffs the whole pushed form list (identity, active, castable,
|
|
cooldown) and fires UPDATE_SHAPESHIFT_FORMS on any change — so the ref's separate
|
|
Update/UpdateState split over six events (SPELL_UPDATE_COOLDOWN/_USABLE,
|
|
PLAYER_AURAS_CHANGED, UPDATE_INVENTORY_ALERTS "Wha??", ACTIONBAR_PAGE_CHANGED) collapses
|
|
into Update on UPDATE_SHAPESHIFT_FORMS + PLAYER_ENTERING_WORLD.
|
|
- No lastSelected bookkeeping (ref ShapeshiftBar_ChangeForm) — checked state is always
|
|
re-derived from the pushed `isActive`, never locally latched: the server's form byte is
|
|
the truth and the app re-pushes on its every change. (Verified dead in the ref itself:
|
|
`lastSelected` is written twice and read nowhere in the shipped FrameXML.)
|
|
-->
|
|
<Script><![CDATA[
|
|
NUM_SHAPESHIFT_SLOTS = 10
|
|
|
|
-- RIGHT-CLICK IS DEAD HERE, and deliberately (decision 1030 reverting 1027). The ref's
|
|
-- ShapeshiftButtonTemplate registers NOTHING: it inherits ActionButtonTemplate and then
|
|
-- overrides <OnLoad> with a body that only scales the cooldown, so the
|
|
-- `RegisterForClicks("LeftButtonUp","RightButtonUp")` that ActionButton_OnLoad gives every
|
|
-- other action-style button (ref ActionButton.lua:109) is lost and the default
|
|
-- {LeftButtonUp} stands. A right-press therefore neither flashes the pushed art
|
|
-- (0x77924b gates that on the same mask) nor casts. It reads like a Blizzard oversight
|
|
-- and it is the only bar that behaves this way — reproduced anyway, because the director
|
|
-- checked it against the reference and called faithful.
|
|
function BenillaShapeshiftButton_OnLoad(button, index)
|
|
button.index = index
|
|
button.icon = getglobal(button:GetName() .. "Icon")
|
|
button.cooldown = getglobal(button:GetName() .. "Cooldown")
|
|
end
|
|
|
|
-- The CheckButton widget toggles itself BEFORE OnClick fires (the widget contract); the
|
|
-- ref immediately reverts that toggle (ShapeshiftButtonTemplate OnClick, ref-
|
|
-- BonusActionBarFrame.xml l.31-38), so the checked ring never follows the click — only
|
|
-- the isActive repaint. That is what keeps a warrior's ACTIVE stance lit through the
|
|
-- click's silent wire no-op (stances never cancel — the 0x4b4963 guard), and a druid
|
|
-- form/Stealth lit until the server actually confirms the shift-out. The revert is
|
|
-- unconditional, which is why no click here can leave a lit form dark — unlike the pet
|
|
-- bar's flat SetChecked(0), which needs a repaint to be correct.
|
|
function BenillaShapeshiftButton_OnClick(button)
|
|
if button:GetChecked() then
|
|
button:SetChecked(nil)
|
|
else
|
|
button:SetChecked(1)
|
|
end
|
|
CastShapeshiftForm(button.index)
|
|
end
|
|
|
|
-- Hover: the form's spell tooltip through the engine channel (ref ShapeshiftBar's
|
|
-- GameTooltip:SetShapeshift; decision 0274 P2). Anchor: the ref's ShapeshiftButton
|
|
-- OnEnter (BonusActionBarFrame.xml l.40-45) takes the default corner when UberTooltips
|
|
-- is "1" — its byte-verified stock default (ActionBar.xml has the read) — so the branch
|
|
-- collapses to the default corner here too.
|
|
function BenillaShapeshiftButton_OnEnter(button)
|
|
if not GameTooltip then return end -- engine tests load file subsets
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, button)
|
|
GameTooltip:SetShapeshift(button.index)
|
|
end
|
|
|
|
function BenillaShapeshiftButton_OnLeave(button)
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
-- Ref ShapeshiftBar_Update + ShapeshiftBar_UpdateState fused (SCOPE note above): size the
|
|
-- bar to the form count (hide the whole frame at 0 — a formless class never shows it),
|
|
-- then paint each button — icon, checked (active), the 1.0/0.4 castable tint (ref l.210-214),
|
|
-- cooldown swipe (CooldownFrame_SetTimer, Cooldown.xml's shared transcription).
|
|
function ShapeshiftBar_Update()
|
|
local numForms = GetNumShapeshiftForms()
|
|
if numForms > 0 then
|
|
ShapeshiftBarFrame:Show()
|
|
else
|
|
ShapeshiftBarFrame:Hide()
|
|
end
|
|
for i = 1, NUM_SHAPESHIFT_SLOTS do
|
|
local button = getglobal("ShapeshiftButton" .. i)
|
|
if i <= numForms then
|
|
local texture, name, isActive, isCastable = GetShapeshiftFormInfo(i)
|
|
button.icon:SetTexture(texture or BENILLA_FALLBACK_ICON)
|
|
local start, duration, enable = GetShapeshiftFormCooldown(i)
|
|
CooldownFrame_SetTimer(button.cooldown, start, duration, enable)
|
|
if isActive then
|
|
button:SetChecked(1)
|
|
else
|
|
button:SetChecked(0)
|
|
end
|
|
if isCastable then
|
|
button.icon:SetVertexColor(1.0, 1.0, 1.0)
|
|
else
|
|
button.icon:SetVertexColor(0.4, 0.4, 0.4)
|
|
end
|
|
button:Show()
|
|
else
|
|
button:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
function ShapeshiftBar_OnLoad()
|
|
local frame = this
|
|
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
frame:RegisterEvent("UPDATE_SHAPESHIFT_FORMS")
|
|
ShapeshiftBar_Update()
|
|
end
|
|
|
|
function ShapeshiftBar_OnEvent()
|
|
local frame = this
|
|
ShapeshiftBar_Update()
|
|
end
|
|
]]></Script>
|
|
|
|
<!--
|
|
One stance button (ref ShapeshiftButtonTemplate: 30x30, inherits ActionButtonTemplate's
|
|
art set): icon fills (BACKGROUND); Cooldown child (the ref SetScale(.83)s the 36px
|
|
template's — ours is sized 30x30 directly); the raised-mode 50x50 UI-Quickslot2 ring
|
|
CENTER (0,-1); the action template's pushed/highlight/checked trio.
|
|
-->
|
|
<CheckButton name="BenillaShapeshiftButtonTemplate" virtual="true">
|
|
<Size><AbsDimension x="30" y="30"/></Size>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="$parentIcon"/>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<Cooldown name="$parentCooldown" hidden="true">
|
|
<Size><AbsDimension x="30" y="30"/></Size>
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="0" y="-1"/></Offset></Anchor>
|
|
</Anchors>
|
|
</Cooldown>
|
|
</Frames>
|
|
<NormalTexture name="$parentNormalTexture" file="Interface\Buttons\UI-Quickslot2">
|
|
<Size><AbsDimension x="50" y="50"/></Size>
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="0" y="-1"/></Offset></Anchor>
|
|
</Anchors>
|
|
</NormalTexture>
|
|
<PushedTexture file="Interface\Buttons\UI-Quickslot-Depress"/>
|
|
<HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
|
|
<CheckedTexture file="Interface\Buttons\CheckButtonHilight" alphaMode="ADD"/>
|
|
<Scripts>
|
|
<OnClick>BenillaShapeshiftButton_OnClick(self)</OnClick>
|
|
<OnEnter>BenillaShapeshiftButton_OnEnter(self)</OnEnter>
|
|
<OnLeave>BenillaShapeshiftButton_OnLeave(self)</OnLeave>
|
|
</Scripts>
|
|
</CheckButton>
|
|
|
|
<Frame name="ShapeshiftBarFrame" hidden="true">
|
|
<Size><AbsDimension x="29" y="32"/></Size>
|
|
<Anchors>
|
|
<Anchor point="BOTTOMLEFT" relativeTo="MainMenuBar" relativePoint="TOPLEFT"><Offset><AbsDimension x="30" y="45"/></Offset></Anchor>
|
|
</Anchors>
|
|
<!-- The shelf art (ref BonusActionBarFrame.xml l.220-249), declared HIDDEN.
|
|
|
|
The header above says this art "is not modeled at all" because raised mode hides it and
|
|
we are permanently raised. That reasoning was right about the PIXELS and wrong about
|
|
the NAMES: 1219/1223 settled that the reference does not choose between shown and
|
|
absent, and "we don't show it" is not a reason for it not to exist. Four frames landed
|
|
on that principle; these are the first REGIONS to, which is why the sweep that closed
|
|
the class missed them — it ran over the frames/tables ranking, and a Texture is
|
|
neither.
|
|
|
|
Two corpus addons index them, and both do pure LAYOUT — they do not use the art, they
|
|
move it, exactly the shape 1223 found for BonusActionBarFrame:
|
|
zBarEx/zMainBar.lua:288-290 SetParent(MainMenuBar) on all three
|
|
CT_BottomBar.lua:681-692 ClearAllPoints + SetPoint off-screen
|
|
Absent, `ShapeshiftBarLeft:ClearAllPoints()` is `attempt to index global` and takes the
|
|
addon's whole handler with it.
|
|
|
|
Geometry and TexCoords quoted: Left and Right are two crops of ONE `ShapeshiftBarEnds`
|
|
file (0..0.453125 and 0.453125..0.875), Middle its own. hidden="true" is the state
|
|
raised mode leaves them in, so this still draws nothing. -->
|
|
<Layers>
|
|
<Layer level="OVERLAY">
|
|
<Texture name="ShapeshiftBarLeft" file="Interface\ShapeshiftBar\ShapeshiftBarEnds" hidden="true">
|
|
<Size><AbsDimension x="45" y="50"/></Size>
|
|
<Anchors><Anchor point="BOTTOMLEFT"/></Anchors>
|
|
<TexCoords left="0" right="0.453125" top="0" bottom="1"/>
|
|
</Texture>
|
|
<Texture name="ShapeshiftBarMiddle" file="Interface\ShapeshiftBar\ShapeshiftBarMiddle" hidden="true">
|
|
<Size><AbsDimension x="38" y="50"/></Size>
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftBarLeft" relativePoint="RIGHT"/></Anchors>
|
|
<TexCoords left="0" right="1" top="0" bottom="1"/>
|
|
</Texture>
|
|
<Texture name="ShapeshiftBarRight" file="Interface\ShapeshiftBar\ShapeshiftBarEnds" hidden="true">
|
|
<Size><AbsDimension x="42" y="50"/></Size>
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftBarMiddle" relativePoint="RIGHT"/></Anchors>
|
|
<TexCoords left="0.453125" right="0.875" top="0" bottom="1"/>
|
|
</Texture>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<CheckButton name="ShapeshiftButton1" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="11" y="3"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 1)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton2" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton1" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 2)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton3" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton2" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 3)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton4" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton3" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 4)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton5" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton4" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 5)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton6" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton5" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 6)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton7" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton6" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 7)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton8" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton7" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 8)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton9" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton8" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 9)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="ShapeshiftButton10" inherits="BenillaShapeshiftButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="ShapeshiftButton9" relativePoint="RIGHT"><Offset><AbsDimension x="7" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaShapeshiftButton_OnLoad(self, 10)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
</Frames>
|
|
<Scripts>
|
|
<OnLoad>ShapeshiftBar_OnLoad()</OnLoad>
|
|
<OnEvent>ShapeshiftBar_OnEvent()</OnEvent>
|
|
<!-- The stance bar is the pet/stance term of the managed bottom-stack positions
|
|
(UIParent.xml, decision 0272): its show/hide re-fires the pass, exactly the
|
|
ref's BonusActionBarFrame.xml:350-355. -->
|
|
<OnShow>UIParent_ManageFramePositions()</OnShow>
|
|
<OnHide>UIParent_ManageFramePositions()</OnHide>
|
|
</Scripts>
|
|
</Frame>
|
|
</Ui>
|