- The keyring is built. Your first key makes the keyring button appear by the bags, opening the window the original keeps its dungeon keys in — the server had been sending the keys all along; nothing had ever shown them. - Keys open their doors now. The client used to cast the open as a bare spell, which the server rightly refuses; it now sends the item-use the original sends, carrying which key from which slot. The tooltip plays along: "Locked" turns the soft green when something you carry opens it, and a key stops inventing a "Use: Opening" line it never had. - A building can own the sky: a WMO can name its own painted skybox, and Stratholme's burning city now draws its near-black-to-red dome instead of the zone's khaki gradient. The exact rule for when it applies settles in the next snapshot. - Signpost tooltips follow the cursor again — the tooltip anchor forks per object class, corner for doors, cursor for signs — and the Blasted Lands lightning stops striking the same spot for ever: a placed doodad re-rolls its animation variation every play-window, like the original. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
967 lines
59 KiB
XML
967 lines
59 KiB
XML
<Ui>
|
|
<!--
|
|
benilla's main action bar, RE-SKINNED to the real 1.12 MainMenuBar (decision 0068 slice-1;
|
|
dressing arc, decision 0084). The geometry + art below are QUOTED from the real FrameXML
|
|
(scratchpad refs, line citations inline): ref-MainMenuBar.xml (the bar art, end caps, XP bar),
|
|
ref-ActionBarFrame.xml (the 12-button anchor chain + page buttons), ref-ActionButtonTemplate.xml
|
|
(the button template). The Lua data flow is UNCHANGED — the vanilla page formula, the
|
|
ACTIONBAR_SLOT_CHANGED repaint, HasAction/GetActionTexture in, UseAction out.
|
|
|
|
Structure mirrors the real hierarchy so the draw order falls out of the frame tree:
|
|
BenillaActionBar (1024x53, BOTTOM of screen)
|
|
├─ BenillaExpBar (StatusBar, TOP) — drawn first ⇒ lowest
|
|
└─ BenillaActionBarArtFrame (fills the bar) — dwarf strips + end caps over the XP bar
|
|
└─ 12 buttons + page up/down — child frames ⇒ over the art
|
|
(The real client gets the same order via RaiseFrameLevel(MainMenuBarArtFrame); our loader's
|
|
later-sibling-is-higher + child-over-parent rules reproduce it without the explicit raise.)
|
|
|
|
SCOPE / real-client divergences (noted, not bugs):
|
|
- No frame scale: the real bar is UIParent-scaled; we render 1:1. Geometry is otherwise exact.
|
|
- Page up/down + the page number are ART ONLY (we have no bar paging — only the bonus-bar
|
|
offset; ref-ActionBarFrame.xml l.159-217). The page number renders a static "1".
|
|
- HotKey renders the static binding labels — always non-empty, so the ref's RANGE_INDICATOR
|
|
dot path (shown only when a button has NO binding text, ActionButton_UpdateHotkeys) never
|
|
applies; the out-of-range read is the hotkey's red tint (the OnUpdate range timer below).
|
|
- The state/feedback layer (decision 0137 phase 4) is the ref ActionButton.lua transcribed:
|
|
UpdateState (checked on IsCurrentAction/IsAutoRepeatAction), UpdateUsable (the 1/1/1 ·
|
|
0.5/0.5/1 · 0.4/0.4/0.4 vertex-color trio), UpdateCooldown (CooldownFrame_SetTimer),
|
|
the Border's equipped green, and the 0.4 s Flash blink — with ONE structural deviation:
|
|
the event set registers on the BAR frame and fans to all 12 buttons, instead of the
|
|
ref's per-button Register/Unregister churn on HasAction (12 fixed buttons make the
|
|
skip-empties optimization noise; the handlers themselves are the ref's).
|
|
- Count (decision 0216 §7, slice 4): the ref gates it on IsConsumableAction; we simplify to
|
|
"an ITEM-kind action with a positive bag count" (GetActionCount always answers 0 for a
|
|
non-item kind, so the gate is really just `count > 0`) — not every consumable is
|
|
detectable as such without the full consumable-flag column, which nothing else needs yet.
|
|
- Empty-slot grid (ref ActionButton.lua:241-259's ShowGrid/HideGrid, a per-button COUNTER):
|
|
simplified to one bar-level BOOLEAN — the cursor is a single global payload, so no two
|
|
"shows" can ever nest, and a counter would just be a boolean with extra steps. Unlike the
|
|
ref (which HIDES an empty, non-grid slot entirely), our bar always shows all 12 wells; the
|
|
grid only swaps an EMPTY slot's ring art between the occupied and empty Quickslot textures
|
|
— the default (nothing held) look is unchanged from before this slice, no capture regression.
|
|
- Exhaustion tick + rest fill, XP text (hover/cvar-gated), MaxLevelBar: OUT. The bar's
|
|
right-hand cluster is otherwise complete — the backpack toggle + four bag slots live in
|
|
BagFrame.xml and the eight micro buttons in MicroMenu.xml (both anchored into
|
|
BenillaActionBarArtFrame and seated over the art by BenillaActionBarArt_SeatAbove below),
|
|
and the performance meter is at the foot of this file. The KEYRING landed with decision
|
|
0765: its button and container live in BagFrame.xml (the ref's own split —
|
|
MainMenuBarBagButtons.xml / ContainerFrame.lua), and the bar's half of it — swapping the
|
|
two right-hand strips to the keyring art and sliding the performance meter over to make
|
|
room — is BenillaMainMenuBar_UpdateKeyRing below, exactly where the ref keeps it
|
|
(MainMenuBar.lua l.174-183).
|
|
-->
|
|
<Script><![CDATA[
|
|
BENILLA_FALLBACK_ICON = "Interface\\Icons\\INV_Misc_QuestionMark"
|
|
|
|
-- Ref ActionButton.lua:4 / UIParent.lua: the flash blink period and the range-check cadence.
|
|
ATTACK_BUTTON_FLASH_TIME = 0.4
|
|
TOOLTIP_UPDATE_TIME = 0.2
|
|
|
|
-- CooldownFrame_SetTimer moved to Cooldown.xml (the ref's own file split) — the bag
|
|
-- slots share it, so it loads before both consumers.
|
|
|
|
-- The static key-binding label each button i shows in its HotKey corner (our bar binds
|
|
-- 1..9,0,-,= to slots 1..12). The real client derives these from GetBindingKey; we render
|
|
-- them statically since the bindings are fixed.
|
|
BENILLA_ACTIONBAR_HOTKEYS = { "1","2","3","4","5","6","7","8","9","0","-","=" }
|
|
|
|
-- Whether a placeable cursor payload is held (decision 0216 §7's ACTIONBAR_SHOWGRID/
|
|
-- _HIDEGRID pair, simplified to a boolean — see the SCOPE note above).
|
|
BENILLA_ACTIONBAR_GRID_SHOWN = false
|
|
|
|
-- Every live action button — the main bar's 12 plus the multibars' (MultiBars.xml joins
|
|
-- at OnLoad). The fan-out roster for the bar-level events below: the ref registers the
|
|
-- feedback events per-button; our bar-level fan needs the full set in one place.
|
|
BENILLA_ACTION_BUTTONS = {}
|
|
|
|
-- 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.
|
|
--
|
|
-- Why it's needed: those frames are top-level, so they default to a LOWER frame level than
|
|
-- the bar's own art (a child hierarchy — the ExpBar's dwarf notches + the metal/well art sit
|
|
-- at the bar's child level). Frame level dominates the flat painter's order, so the bar art
|
|
-- would paint OVER them — the ring shows but the centered icon is fully covered (the "empty
|
|
-- rings, no bag icons" bug). The bar's OWN 12 buttons avoid this by being CHILDREN of the art
|
|
-- frame (child-over-parent). (SetParent onto the art frame would be the structural twin, but
|
|
-- the engine keys draw order at creation and does not re-key on a runtime reparent, so the
|
|
-- explicit level is the reliable lever.) Lives here, with the frame it's about, because two
|
|
-- files now need it — it began as BagFrame.xml's private BenillaBagBar_SeatAboveActionBar.
|
|
function BenillaActionBarArt_SeatAbove(frame)
|
|
local art = getglobal("BenillaActionBarArtFrame")
|
|
if art then frame:SetFrameLevel(art:GetFrameLevel() + 1) end
|
|
end
|
|
|
|
-- ── The keyring's half of the bar (ref MainMenuBar_UpdateKeyRing, MainMenuBar.lua
|
|
-- l.174-183; decision 0765) ──────────────────────────────────────────────────────────────
|
|
-- The keyring is not just a button bolted onto the bar: the bar's two RIGHT-hand strips are
|
|
-- re-textured to a variant plate that has a socket for it, and the performance meter slides
|
|
-- 8px further left out of the way. Both atlases are 256-wide 43px strips at the same on-
|
|
-- screen size and anchors, so only the file + TexCoords change (UI-MainMenuBar-KeyRing is
|
|
-- 256x128 and holds exactly the two bands the ref names: 0.3359375 * 128 = 43px each).
|
|
--
|
|
-- Called by BenillaKeyRingButton's own OnEvent (BagFrame.xml). Everything is nil-guarded:
|
|
-- this file loads without BagFrame.xml in several harnesses, and BagFrame.xml loads without
|
|
-- this one in ~25 bag/bank/escape/merchant tests — either way the missing half no-ops.
|
|
--
|
|
-- DIVERGENCE (decision 0765): the ref latches this ON forever the first time HasKey() is
|
|
-- true, via the saved variable SHOW_KEYRING (and pulses the button for 60s to announce it).
|
|
-- This engine has no saved variables, and a session-scoped latch would leak across a
|
|
-- character switch — showing a keyring on a character with no key — so the state is derived
|
|
-- from HasKey() on every BAG_UPDATE instead, in BOTH directions. Observably identical
|
|
-- unless you destroy your last key, which then un-shows the keyring rather than leaving an
|
|
-- empty one behind. The 60s pulse is out, consistently with decision 0304's "no button
|
|
-- pulse" for the micro buttons.
|
|
function BenillaMainMenuBar_UpdateKeyRing()
|
|
local show = HasKey and HasKey()
|
|
-- The two right-hand strips (BenillaActionBarTexture2 at x=+128, Texture3 at x=+384),
|
|
-- keyring plate or the ordinary dwarf plate. The dwarf coords are this file's own
|
|
-- authored ones (see the strips below) — restated here because this is the only code
|
|
-- that ever changes them back.
|
|
local strips = {
|
|
{ name = "BenillaActionBarTexture2",
|
|
keyring = 0.6640625, keyringBottom = 1.0,
|
|
dwarf = 0.33203125, dwarfBottom = 0.5 },
|
|
{ name = "BenillaActionBarTexture3",
|
|
keyring = 0.1640625, keyringBottom = 0.5,
|
|
dwarf = 0.08203125, dwarfBottom = 0.25 },
|
|
}
|
|
for _, strip in ipairs(strips) do
|
|
local tex = getglobal(strip.name)
|
|
if tex then
|
|
if show then
|
|
tex:SetTexture("Interface\\MainMenuBar\\UI-MainMenuBar-KeyRing")
|
|
tex:SetTexCoord(0, 1, strip.keyring, strip.keyringBottom)
|
|
else
|
|
tex:SetTexture("Interface\\MainMenuBar\\UI-MainMenuBar-Dwarf")
|
|
tex:SetTexCoord(0, 1, strip.dwarf, strip.dwarfBottom)
|
|
end
|
|
end
|
|
end
|
|
-- The performance meter's recess moves with the plate: -227 without the keyring,
|
|
-- -235 with it (ref l.180). Its own comment at the foot of this file has the geometry.
|
|
local perf = getglobal("BenillaPerformanceBarFrame")
|
|
local bar = getglobal("BenillaActionBar")
|
|
if perf and bar then
|
|
perf:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", (show and -235) or -227, -10)
|
|
end
|
|
local button = getglobal("BenillaKeyRingButton")
|
|
if button then
|
|
if show then button:Show() else button:Hide() end
|
|
end
|
|
-- Losing the last key with the keyring open would strand an orphan window; the ref
|
|
-- can't reach this state (its latch is one-way), so this is ours to decide.
|
|
local frame = getglobal("BenillaKeyRingFrame")
|
|
if frame and not show and frame:IsShown() then frame:Hide() end
|
|
end
|
|
|
|
-- The wire/API action id the MAIN bar's button i displays (the vanilla page formula).
|
|
-- INTERNAL to BenillaActionButton_Action below — the ONLY caller. A button path that
|
|
-- reaches past it computes a MAIN-bar id for a multibar button (base ignored), which
|
|
-- reads as "the slot below": the tooltip hover did exactly that until 2026-07-21.
|
|
function BenillaActionBar_ActionFor(index)
|
|
local offset = GetBonusBarOffset()
|
|
local base = 0
|
|
if offset > 0 then
|
|
base = (6 + offset - 1) * 12
|
|
end
|
|
return base + index
|
|
end
|
|
|
|
-- The action id a specific BUTTON displays: the ref forks on the parent frame's NAME
|
|
-- (ActionButton_GetPagedID:446-467 — MultiBarBottomLeft ⇒ page 6, MultiBarBottomRight ⇒
|
|
-- page 5, else the paged/bonus formula); we carry the fork as data — a fixed per-button
|
|
-- page base set at OnLoad (MultiBars.xml), nil for the bonus-paged main bar.
|
|
function BenillaActionButton_Action(button)
|
|
if button.base then
|
|
return button.base + button.index
|
|
end
|
|
return BenillaActionBar_ActionFor(button.index)
|
|
end
|
|
|
|
-- Hover: SetAction's pure delegation (decision 0276 — a SPELL slot renders the spell
|
|
-- tooltip with its rank column, an ITEM slot the shared item renderer; ref
|
|
-- ActionButton_SetTooltip). The re-enter keeps it live across page flips.
|
|
-- Anchor: ref ActionButton_SetTooltip (ActionButton.lua l.366-372) branches on the
|
|
-- UberTooltips CVar — "1" → the default corner, else RIGHT/LEFT by bar. UberTooltips
|
|
-- registers with default "1" (byte-read: WoW.exe 0x48fdd9, default string 0x82e748;
|
|
-- sibling rows BlockTrades→"0", UnitNameRenderMode→"2" confirm the layout), and benilla
|
|
-- ships no CVar state, so the branch collapses to the stock-client one: action-bar
|
|
-- tooltips live at the screen's bottom-right, above the bags.
|
|
function BenillaActionButton_OnEnter(button)
|
|
if not GameTooltip then return end -- engine tests load file subsets
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, button)
|
|
GameTooltip:SetAction(BenillaActionButton_Action(button))
|
|
end
|
|
|
|
function BenillaActionButton_OnLoad(button, index, base)
|
|
button.index = index
|
|
button.base = base
|
|
button.icon = getglobal(button:GetName() .. "Icon")
|
|
button.hotkey = getglobal(button:GetName() .. "HotKey")
|
|
button.count = getglobal(button:GetName() .. "Count")
|
|
button.flash = getglobal(button:GetName() .. "Flash")
|
|
button.border = getglobal(button:GetName() .. "Border")
|
|
button.cooldown = getglobal(button:GetName() .. "Cooldown")
|
|
-- Ref ActionButton_OnLoad:104-106: the flash/range state the OnUpdate loop drives.
|
|
button.flashing = 0
|
|
button.flashtime = 0
|
|
button.rangeTimer = nil
|
|
if base then
|
|
-- Multibar buttons are unbound (ref Bindings.xml ships no default MULTIACTIONBAR*
|
|
-- keys): no static label. Their hotkey corner instead carries the ref's
|
|
-- RANGE_INDICATOR dot (ActionButton_UpdateHotkeys' no-binding leg, net effect:
|
|
-- a red dot only while out of range), painted by the OnUpdate range timer.
|
|
button.hotkey:SetText("")
|
|
else
|
|
button.hotkey:SetText(BENILLA_ACTIONBAR_HOTKEYS[index])
|
|
end
|
|
table.insert(BENILLA_ACTION_BUTTONS, button)
|
|
-- The drag trio (decision 0216 §3/§7): click-carry and drag share one downstream path
|
|
-- by construction (OnClick/OnDragStart both call PickupAction; OnReceiveDrag calls
|
|
-- PlaceAction — ref ActionBarFrame.xml:12-38). LOCK_ACTIONBAR stays the vanilla
|
|
-- default (unlocked), so unlike the ref's cvar guard, drag is always live here.
|
|
button:RegisterForDrag("LeftButton")
|
|
BenillaActionButton_Update(button)
|
|
end
|
|
|
|
-- Ref ActionBarFrame.xml:12-22's fork verbatim: shift picks up, else uses (checkCursor=1 —
|
|
-- the engine routes a click-with-payload to PlaceAction instead, decision 0216 §7).
|
|
function BenillaActionButton_OnClick(button)
|
|
local action = BenillaActionButton_Action(button)
|
|
if IsShiftKeyDown() then
|
|
PickupAction(action)
|
|
else
|
|
UseAction(action, 1)
|
|
end
|
|
BenillaActionButton_Update(button)
|
|
end
|
|
|
|
function BenillaActionButton_OnDragStart(button)
|
|
PickupAction(BenillaActionButton_Action(button))
|
|
BenillaActionButton_Update(button)
|
|
end
|
|
|
|
function BenillaActionButton_OnReceiveDrag(button)
|
|
PlaceAction(BenillaActionButton_Action(button))
|
|
BenillaActionButton_Update(button)
|
|
end
|
|
|
|
-- The default ACTIONBUTTON1..12 key bindings (ref Bindings.xml:121-127: keys 1..9,0,-,=
|
|
-- run ActionButtonDown on keystate "down" and ActionButtonUp on "up" via runOnUp), both
|
|
-- transcribed from ActionButton.lua:15-28/30-45 and routed here from the app's key feed.
|
|
-- DOWN pushes the button only from NORMAL; UP fires the action only from PUSHED — the
|
|
-- state pair is both the pushed visual and the debounce (a key-repeat DOWN or a stray UP
|
|
-- is a no-op). Calls UseAction DIRECTLY with NO checkCursor argument — unlike the
|
|
-- mouse-click fork above, a keybind never places (decision 0216 §7: the ref itself never
|
|
-- routes ActionButtonUp through OnClick, so this no longer goes through Click() either —
|
|
-- the two entry points share the id formula, not the click path). The ref's
|
|
-- BonusActionBar fork and the SELFACTIONBUTTON onSelf argument are not modeled (no bonus
|
|
-- bar frame, no self-cast modifier binding).
|
|
function BenillaActionButtonDown(index)
|
|
local button = getglobal("BenillaActionButton" .. index)
|
|
if ( button:GetButtonState() == "NORMAL" ) then
|
|
button:SetButtonState("PUSHED")
|
|
end
|
|
end
|
|
|
|
function BenillaActionButtonUp(index)
|
|
local button = getglobal("BenillaActionButton" .. index)
|
|
if ( button:GetButtonState() == "PUSHED" ) then
|
|
button:SetButtonState("NORMAL")
|
|
UseAction(BenillaActionButton_Action(button))
|
|
-- Ref ActionButtonUp:55-59: the checked ring reflects the use immediately.
|
|
BenillaActionButton_UpdateState(button)
|
|
end
|
|
end
|
|
|
|
-- Ref ActionButton_UpdateState:261-267 — the checked ring: the current action (Attack
|
|
-- while auto-attacking, the in-flight cast) or the live auto-repeat spell.
|
|
function BenillaActionButton_UpdateState(button)
|
|
local action = BenillaActionButton_Action(button)
|
|
if ( IsCurrentAction(action) or IsAutoRepeatAction(action) ) then
|
|
button:SetChecked(1)
|
|
else
|
|
button:SetChecked(0)
|
|
end
|
|
end
|
|
|
|
-- Ref ActionButton_UpdateUsable:269-283, verbatim colors: usable white; out of power the
|
|
-- blue-grey 0.5/0.5/1.0 on icon AND ring; otherwise-unusable the 0.4 grey icon only.
|
|
function BenillaActionButton_UpdateUsable(button)
|
|
local action = BenillaActionButton_Action(button)
|
|
local normalTexture = getglobal(button:GetName() .. "NormalTexture")
|
|
local isUsable, notEnoughMana = IsUsableAction(action)
|
|
if ( isUsable ) then
|
|
button.icon:SetVertexColor(1.0, 1.0, 1.0)
|
|
normalTexture:SetVertexColor(1.0, 1.0, 1.0)
|
|
elseif ( notEnoughMana ) then
|
|
button.icon:SetVertexColor(0.5, 0.5, 1.0)
|
|
normalTexture:SetVertexColor(0.5, 0.5, 1.0)
|
|
else
|
|
button.icon:SetVertexColor(0.4, 0.4, 0.4)
|
|
normalTexture:SetVertexColor(1.0, 1.0, 1.0)
|
|
end
|
|
end
|
|
|
|
-- Ref ActionButton_UpdateCooldown:294-298.
|
|
function BenillaActionButton_UpdateCooldown(button)
|
|
local start, duration, enable = GetActionCooldown(BenillaActionButton_Action(button))
|
|
CooldownFrame_SetTimer(button.cooldown, start, duration, enable)
|
|
end
|
|
|
|
-- Ref ActionButton_UpdateFlash/StartFlash/StopFlash/IsFlashing:469-496: the red blink on
|
|
-- an engaged Attack button / a live auto-repeat, toggled by the OnUpdate loop below.
|
|
function BenillaActionButton_UpdateFlash(button)
|
|
local action = BenillaActionButton_Action(button)
|
|
if ( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) ) then
|
|
BenillaActionButton_StartFlash(button)
|
|
else
|
|
BenillaActionButton_StopFlash(button)
|
|
end
|
|
end
|
|
|
|
function BenillaActionButton_StartFlash(button)
|
|
button.flashing = 1
|
|
button.flashtime = 0
|
|
BenillaActionButton_UpdateState(button)
|
|
end
|
|
|
|
function BenillaActionButton_StopFlash(button)
|
|
button.flashing = 0
|
|
button.flash:Hide()
|
|
BenillaActionButton_UpdateState(button)
|
|
end
|
|
|
|
-- Ref ActionButton_OnUpdate:384-428, minus the RANGE_INDICATOR dot (our hotkeys always
|
|
-- carry binding text — SCOPE note) and the tooltip refresh (no per-button tooltip yet):
|
|
-- the 0.4 s flash toggle, and the 0.2 s range recheck tinting the hotkey red/grey.
|
|
function BenillaActionButton_OnUpdate(button, elapsed)
|
|
if ( button.flashing == 1 ) then
|
|
button.flashtime = button.flashtime - elapsed
|
|
if ( button.flashtime <= 0 ) then
|
|
local overtime = -button.flashtime
|
|
if ( overtime >= ATTACK_BUTTON_FLASH_TIME ) then
|
|
overtime = 0
|
|
end
|
|
button.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
|
|
if ( button.flash:IsVisible() ) then
|
|
button.flash:Hide()
|
|
else
|
|
button.flash:Show()
|
|
end
|
|
end
|
|
end
|
|
if ( button.rangeTimer ) then
|
|
button.rangeTimer = button.rangeTimer - elapsed
|
|
if ( button.rangeTimer <= 0 ) then
|
|
if ( IsActionInRange(BenillaActionButton_Action(button)) == 0 ) then
|
|
-- An unbound (multibar) button has no label to tint: paint the ref's
|
|
-- RANGE_INDICATOR dot instead (net ref behavior — red dot iff out of range).
|
|
if button.base then
|
|
button.hotkey:SetText("●")
|
|
end
|
|
button.hotkey:SetVertexColor(1.0, 0.1, 0.1)
|
|
else
|
|
if button.base then
|
|
button.hotkey:SetText("")
|
|
end
|
|
button.hotkey:SetVertexColor(0.6, 0.6, 0.6)
|
|
end
|
|
button.rangeTimer = TOOLTIP_UPDATE_TIME
|
|
end
|
|
end
|
|
end
|
|
|
|
function BenillaActionButton_Update(button)
|
|
local action = BenillaActionButton_Action(button)
|
|
if HasAction(action) then
|
|
button.icon:SetTexture(GetActionTexture(action) or BENILLA_FALLBACK_ICON)
|
|
button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
|
|
button:Show()
|
|
button.rangeTimer = -1
|
|
local count = GetActionCount(action)
|
|
if count > 0 then
|
|
button.count:SetText(count)
|
|
else
|
|
button.count:SetText("")
|
|
end
|
|
BenillaActionButton_UpdateState(button)
|
|
BenillaActionButton_UpdateUsable(button)
|
|
BenillaActionButton_UpdateCooldown(button)
|
|
BenillaActionButton_UpdateFlash(button)
|
|
else
|
|
button.icon:SetTexture(nil)
|
|
button.count:SetText("")
|
|
button.cooldown:Hide()
|
|
button.rangeTimer = nil
|
|
button.hotkey:SetVertexColor(0.6, 0.6, 0.6)
|
|
button:SetChecked(0)
|
|
BenillaActionButton_StopFlash(button)
|
|
if button.base then
|
|
-- An EMPTY multibar well is the ref's own default: hidden entirely, appearing
|
|
-- as a drop-target ring only while a payload is held (ActionButton_Update's
|
|
-- showgrid==0 Hide; MultiActionBar_ShowAllGrids). Only the MAIN bar keeps our
|
|
-- always-visible wells divergence (the SCOPE note) — its art has sockets;
|
|
-- floating rings over bare world would not read as a bar.
|
|
button.hotkey:SetText("")
|
|
if BENILLA_ACTIONBAR_GRID_SHOWN then
|
|
button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
|
|
button:Show()
|
|
else
|
|
button:Hide()
|
|
end
|
|
else
|
|
-- While a payload is held, an empty slot shows the ref's own "no action" ring
|
|
-- (Interface\Buttons\UI-Quickslot) so it reads as a drop target; otherwise the
|
|
-- plain occupied-style ring, unchanged from before this slice (SCOPE note).
|
|
if BENILLA_ACTIONBAR_GRID_SHOWN then
|
|
button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
|
|
else
|
|
button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
|
|
end
|
|
end
|
|
end
|
|
-- Ref ActionButton_Update:221-228: the equipped-item green border.
|
|
if ( IsEquippedAction(action) ) then
|
|
button.border:SetVertexColor(0, 1.0, 0, 0.35)
|
|
button.border:Show()
|
|
else
|
|
button.border:Hide()
|
|
end
|
|
end
|
|
|
|
function BenillaActionBar_OnLoad(frame)
|
|
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
frame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
|
frame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
|
|
frame:RegisterEvent("ACTIONBAR_SHOWGRID")
|
|
frame:RegisterEvent("ACTIONBAR_HIDEGRID")
|
|
-- The state/feedback events (ref ActionButton_OnLoad's per-button set, registered
|
|
-- bar-level here — the SCOPE note): the app fires each on the byte-mapped client
|
|
-- edge (wow-re action-button-state-api.md).
|
|
frame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
|
|
frame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
|
|
frame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
|
|
frame:RegisterEvent("PLAYER_TARGET_CHANGED")
|
|
frame:RegisterEvent("PLAYER_AURAS_CHANGED")
|
|
frame:RegisterEvent("PLAYER_ENTER_COMBAT")
|
|
frame:RegisterEvent("PLAYER_LEAVE_COMBAT")
|
|
frame:RegisterEvent("START_AUTOREPEAT_SPELL")
|
|
frame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
|
|
end
|
|
|
|
-- Run one ref per-button handler over the OCCUPIED buttons (the bar-level fan — SCOPE
|
|
-- note). The HasAction gate is the ref's own semantics, load-bearing, not an optimization:
|
|
-- ActionButton.lua registers these handlers only while the button has an action ("All
|
|
-- event handlers below this line are only set when the button has an action"), so an
|
|
-- empty button never runs them — UpdateUsable on an empty would land its 0.4 grey
|
|
-- SetVertexColor on the texture-less icon region, which draws as a solid grey plate
|
|
-- (the director's empty-wells report, 2026-07-10).
|
|
function BenillaActionBar_ForEach(fn)
|
|
for i = 1, table.getn(BENILLA_ACTION_BUTTONS) do
|
|
local button = BENILLA_ACTION_BUTTONS[i]
|
|
if HasAction(BenillaActionButton_Action(button)) then
|
|
fn(button)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BenillaActionBar_OnEvent(frame)
|
|
-- ACTIONBAR_SLOT_CHANGED names its action in arg1; repaint just the button showing it.
|
|
if event == "ACTIONBAR_SLOT_CHANGED" and arg1 then
|
|
for i = 1, table.getn(BENILLA_ACTION_BUTTONS) do
|
|
local button = BENILLA_ACTION_BUTTONS[i]
|
|
if BenillaActionButton_Action(button) == arg1 then
|
|
BenillaActionButton_Update(button)
|
|
end
|
|
end
|
|
return
|
|
end
|
|
-- The ref ActionButton_OnEvent dispatch (l.332-362), fanned bar-level:
|
|
if event == "ACTIONBAR_UPDATE_STATE" then
|
|
BenillaActionBar_ForEach(BenillaActionButton_UpdateState)
|
|
return
|
|
end
|
|
if event == "ACTIONBAR_UPDATE_USABLE" or event == "ACTIONBAR_UPDATE_COOLDOWN" then
|
|
BenillaActionBar_ForEach(BenillaActionButton_UpdateUsable)
|
|
BenillaActionBar_ForEach(BenillaActionButton_UpdateCooldown)
|
|
return
|
|
end
|
|
if event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_AURAS_CHANGED" then
|
|
BenillaActionBar_ForEach(BenillaActionButton_UpdateUsable)
|
|
return
|
|
end
|
|
if event == "PLAYER_ENTER_COMBAT" then
|
|
BenillaActionBar_ForEach(function(b)
|
|
if IsAttackAction(BenillaActionButton_Action(b)) then
|
|
BenillaActionButton_StartFlash(b)
|
|
end
|
|
end)
|
|
return
|
|
end
|
|
if event == "PLAYER_LEAVE_COMBAT" then
|
|
BenillaActionBar_ForEach(function(b)
|
|
if IsAttackAction(BenillaActionButton_Action(b)) then
|
|
BenillaActionButton_StopFlash(b)
|
|
end
|
|
end)
|
|
return
|
|
end
|
|
if event == "START_AUTOREPEAT_SPELL" then
|
|
BenillaActionBar_ForEach(function(b)
|
|
if IsAutoRepeatAction(BenillaActionButton_Action(b)) then
|
|
BenillaActionButton_StartFlash(b)
|
|
end
|
|
end)
|
|
return
|
|
end
|
|
if event == "STOP_AUTOREPEAT_SPELL" then
|
|
BenillaActionBar_ForEach(function(b)
|
|
if b.flashing == 1 and not IsAttackAction(BenillaActionButton_Action(b)) then
|
|
BenillaActionButton_StopFlash(b)
|
|
end
|
|
end)
|
|
return
|
|
end
|
|
if event == "ACTIONBAR_SHOWGRID" or event == "ACTIONBAR_HIDEGRID" then
|
|
BENILLA_ACTIONBAR_GRID_SHOWN = (event == "ACTIONBAR_SHOWGRID")
|
|
end
|
|
for i = 1, table.getn(BENILLA_ACTION_BUTTONS) do
|
|
BenillaActionButton_Update(BENILLA_ACTION_BUTTONS[i])
|
|
end
|
|
end
|
|
|
|
-- The XP bar (ref-MainMenuBar.lua MainMenuExpBar_Update): value = current XP within the
|
|
-- level, max = XP-to-level. Both from the player-global UnitXP feed (PLAYER_XP /
|
|
-- PLAYER_NEXT_LEVEL_XP). currXP >= 0 so min(0,currXP) is just 0.
|
|
function BenillaExpBar_Update(bar)
|
|
local currXP = UnitXP("player")
|
|
local nextXP = UnitXPMax("player")
|
|
bar:SetMinMaxValues(0, nextXP)
|
|
bar:SetValue(currXP)
|
|
end
|
|
|
|
function BenillaExpBar_OnLoad(bar)
|
|
bar:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
bar:RegisterEvent("PLAYER_XP_UPDATE")
|
|
BenillaExpBar_Update(bar)
|
|
end
|
|
|
|
function BenillaExpBar_OnEvent(bar)
|
|
BenillaExpBar_Update(bar)
|
|
end
|
|
|
|
-- The XP bar's hover (ref-MainMenuBar.xml l.136-147, MainMenuExpBar's own OnEnter/OnLeave).
|
|
-- ref GlobalStrings.lua l.5461 / l.2789 (enUS), in the `X = X or` FALLBACK form: the app
|
|
-- runs the real localized GlobalStrings.lua off the patch chain BEFORE this file
|
|
-- (ui_script/mod.rs load_global_strings), so the installed locale wins and these copies
|
|
-- only fill in for the test harnesses, which load no patch chain. CombatText.xml's shape.
|
|
XPBAR_LABEL = XPBAR_LABEL or "XP Bar"
|
|
NEWBIE_TOOLTIP_XPBAR = NEWBIE_TOOLTIP_XPBAR or "The amount of experience (XP) you have earned. The color of the XP bar indicates your rest state: light blue for Rested, and purple for Normal. Rested players earn twice the experience they would normally gain from slaying a monster. Characters become less rested when they kill monsters, and more rested by spending time at or logging out at an inn or city."
|
|
|
|
-- The ref's OnEnter does three more things, all of them machinery we don't have yet, and
|
|
-- each one its own slice rather than a gap in this one:
|
|
-- TextStatusBar_UpdateTextString() + ShowTextStatusBarText(this) — the "1234/5678" numerals
|
|
-- that appear ON the bar while hovered. No TextStatusBar text layer exists here at all.
|
|
-- ExhaustionTick.timer = 1 and GameTooltip.canAddRestStateLine = 1 — the rest-state line
|
|
-- ("You should rest at an Inn", EXHAUST_TOOLTIP1-4) the exhaustion tick appends. There is
|
|
-- no rest-state feed, so there is nothing to append.
|
|
-- The trailing 1 is the ref's noNormalText: with detailed tips OFF this hover shows NOTHING
|
|
-- rather than a bare "XP Bar". Transcribed, though 1.12's default (0661) never takes it.
|
|
function BenillaExpBar_OnEnter(bar)
|
|
if not GameTooltip_AddNewbieTip then return end -- engine tests load file subsets
|
|
GameTooltip_AddNewbieTip(bar, XPBAR_LABEL, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_XPBAR, 1)
|
|
end
|
|
|
|
function BenillaExpBar_OnLeave()
|
|
if GameTooltip then GameTooltip:Hide() end
|
|
end
|
|
|
|
-- ── The performance ("ping") meter ────────────────────────────────────────────────────
|
|
-- ref-MainMenuBar.xml l.344-407: a 16x64 frame in the bar's own right-hand recess whose
|
|
-- 20x66 bar texture is TINTED green/yellow/red by the connection's latency, plus an
|
|
-- all-points button on top for the hover tooltip. The thresholds, the 10 s poll and the
|
|
-- inline handlers below are the ref's, transcribed out of its XML into named functions.
|
|
-- The meter shows LATENCY ONLY: 1.12 never scales the bar's height, only its color.
|
|
PERFORMANCEBAR_LOW_LATENCY = 300
|
|
PERFORMANCEBAR_MEDIUM_LATENCY = 600
|
|
PERFORMANCEBAR_UPDATE_INTERVAL = 10
|
|
|
|
-- ref-GlobalStrings.lua l.2659 / l.2689 / l.2746 (enUS), fallback form — see the XP bar's
|
|
-- note above for why these never override a real localized install.
|
|
MAINMENUBAR_LATENCY_LABEL = MAINMENUBAR_LATENCY_LABEL or "Latency:"
|
|
MILLISECONDS_ABBR = MILLISECONDS_ABBR or "ms"
|
|
NEWBIE_TOOLTIP_LATENCY = NEWBIE_TOOLTIP_LATENCY or "The average time it takes to talk with the game server. A low latency will display as a green bar, higher latencies will be yellow or even red. Consistently high latencies may indicate a problem with your Internet connection."
|
|
|
|
function BenillaPerformanceBar_OnLoad(frame)
|
|
frame.hover = nil
|
|
-- 0, not the interval: the ref's first OnUpdate tick runs the poll immediately, so the
|
|
-- bar is never briefly untinted (its texture is grey until the first SetVertexColor).
|
|
frame.updateInterval = 0
|
|
end
|
|
|
|
function BenillaPerformanceBar_TooltipText()
|
|
local _, _, latency = GetNetStats()
|
|
return MAINMENUBAR_LATENCY_LABEL .. " " .. latency .. MILLISECONDS_ABBR
|
|
end
|
|
|
|
-- ref l.389 (the held-open refresh) and l.400 (OnEnter), both the same call:
|
|
-- GameTooltip_AddNewbieTip(MAINMENUBAR_LATENCY_LABEL.." "..latency..MILLISECONDS_ABBR,
|
|
-- 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_LATENCY)
|
|
-- So the reference hover is TWO lines — the number, then the wrapped explanation — seated
|
|
-- at the default screen corner, not beside the meter (GameTooltip.xml, decision 0661).
|
|
function BenillaPerformanceBar_ShowTooltip(owner)
|
|
if not GameTooltip_AddNewbieTip then return end -- engine tests load file subsets
|
|
GameTooltip_AddNewbieTip(owner, BenillaPerformanceBar_TooltipText(), 1.0, 1.0, 1.0,
|
|
NEWBIE_TOOLTIP_LATENCY)
|
|
end
|
|
|
|
function BenillaPerformanceBar_OnUpdate(frame, elapsed)
|
|
if frame.updateInterval > 0 then
|
|
frame.updateInterval = frame.updateInterval - elapsed
|
|
return
|
|
end
|
|
frame.updateInterval = PERFORMANCEBAR_UPDATE_INTERVAL
|
|
local _, _, latency = GetNetStats()
|
|
if latency > PERFORMANCEBAR_MEDIUM_LATENCY then
|
|
BenillaPerformanceBar:SetVertexColor(1, 0, 0)
|
|
elseif latency > PERFORMANCEBAR_LOW_LATENCY then
|
|
BenillaPerformanceBar:SetVertexColor(1, 1, 0)
|
|
else
|
|
BenillaPerformanceBar:SetVertexColor(0, 1, 0)
|
|
end
|
|
-- Held-open tooltips re-read the number on the same 10 s beat (the ref's own refresh).
|
|
if frame.hover then
|
|
BenillaPerformanceBar_ShowTooltip(frame)
|
|
end
|
|
end
|
|
|
|
function BenillaPerformanceBar_OnEnter(button)
|
|
BenillaPerformanceBarFrame.hover = 1
|
|
BenillaPerformanceBar_ShowTooltip(button)
|
|
end
|
|
|
|
function BenillaPerformanceBar_OnLeave()
|
|
BenillaPerformanceBarFrame.hover = nil
|
|
if GameTooltip then GameTooltip:Hide() end
|
|
end
|
|
]]></Script>
|
|
|
|
<!--
|
|
One action button (ref-ActionButtonTemplate.xml, now the FULL template — decision 0137
|
|
phase 4): a CheckButton, 36x36 (l.3-6); icon fills the button (BACKGROUND, owner-sized,
|
|
l.8-10); Flash (UI-QuickslotRed, hidden — the auto-attack/auto-repeat blink) + HotKey
|
|
(l.11-24) + Count (l.25-33) on ARTWORK; Border (UI-ActionButton-Border 62x62 CENTER, ADD,
|
|
hidden — the equipped-item green ring, l.48-59) on OVERLAY; the Cooldown child (the ref's
|
|
CooldownFrameTemplate Model at 36x36 CENTER (0,-1), l.62-73 — ours is the native Cooldown
|
|
widget playing the same machine); NormalTexture = the 66x66 UI-Quickslot2 ring centered at
|
|
(0,-1) (l.74-85); PushedTexture UI-Quickslot-Depress (l.86); HighlightTexture
|
|
ButtonHilight-Square ADD (l.87); CheckedTexture CheckButtonHilight ADD (l.88 — the
|
|
IsCurrentAction/IsAutoRepeatAction ring). Only Name (macros) stays OUT.
|
|
-->
|
|
<CheckButton name="BenillaActionButtonTemplate" virtual="true">
|
|
<Size><AbsDimension x="36" y="36"/></Size>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="$parentIcon"/>
|
|
</Layer>
|
|
<Layer level="ARTWORK">
|
|
<Texture name="$parentFlash" file="Interface\Buttons\UI-QuickslotRed" hidden="true"/>
|
|
<FontString name="$parentHotKey" inherits="NumberFontNormalSmallGray" justifyH="RIGHT">
|
|
<Size><AbsDimension x="36" y="10"/></Size>
|
|
<Anchors>
|
|
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="-2" y="-2"/></Offset></Anchor>
|
|
</Anchors>
|
|
</FontString>
|
|
<FontString name="$parentCount" inherits="NumberFontNormal" justifyH="RIGHT">
|
|
<Anchors>
|
|
<Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-2" y="2"/></Offset></Anchor>
|
|
</Anchors>
|
|
</FontString>
|
|
</Layer>
|
|
<Layer level="OVERLAY">
|
|
<Texture name="$parentBorder" file="Interface\Buttons\UI-ActionButton-Border" hidden="true" alphaMode="ADD">
|
|
<Size><AbsDimension x="62" y="62"/></Size>
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
|
</Anchors>
|
|
</Texture>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<Cooldown name="$parentCooldown" hidden="true">
|
|
<Size><AbsDimension x="36" y="36"/></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="66" y="66"/></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>BenillaActionButton_OnClick(self)</OnClick>
|
|
<OnDragStart>BenillaActionButton_OnDragStart(self)</OnDragStart>
|
|
<OnReceiveDrag>BenillaActionButton_OnReceiveDrag(self)</OnReceiveDrag>
|
|
<OnUpdate>BenillaActionButton_OnUpdate(self, arg1)</OnUpdate>
|
|
<OnEnter>BenillaActionButton_OnEnter(self)</OnEnter>
|
|
<OnLeave>if GameTooltip then GameTooltip:Hide() end</OnLeave>
|
|
</Scripts>
|
|
</CheckButton>
|
|
|
|
<!-- The bar: 1024x53 anchored BOTTOM of the screen (ref-MainMenuBar.xml l.4-10). -->
|
|
<Frame name="BenillaActionBar">
|
|
<Size><AbsDimension x="1024" y="53"/></Size>
|
|
<Anchors>
|
|
<Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
|
</Anchors>
|
|
<Frames>
|
|
<!--
|
|
The XP StatusBar: 1024x13 anchored TOP of the bar (ref-MainMenuBar.xml l.12-18).
|
|
BarTexture UI-StatusBar, BarColor purple (0.58,0,0.55) (l.158-159); a solid black
|
|
a=0.5 BACKGROUND (l.89-93); and the 4 dwarf-notch OVERLAY strips (256x10, BOTTOM
|
|
x=-384/-128/128/384 y=3, the tick TexCoord bands l.36-87) that frame the fill.
|
|
Drawn first among the bar's children ⇒ lowest, so the dwarf art overlaps it (the
|
|
real RaiseFrameLevel(art) order).
|
|
-->
|
|
<!-- enableMouse: the ref's MainMenuExpBar takes the mouse for its own hover (l.136-147).
|
|
The strip is the bar's top 13 px, clear of every button on it. -->
|
|
<StatusBar name="BenillaExpBar" enableMouse="true">
|
|
<Size><AbsDimension x="1024" y="13"/></Size>
|
|
<Anchors>
|
|
<Anchor point="TOP" relativePoint="TOP"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
|
</Anchors>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture>
|
|
<Color r="0.0" g="0.0" b="0.0" a="0.5"/>
|
|
</Texture>
|
|
</Layer>
|
|
<Layer level="OVERLAY">
|
|
<Texture name="BenillaXPBarTexture0" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="10"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="-384" y="3"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.79296875" bottom="0.83203125"/>
|
|
</Texture>
|
|
<Texture name="BenillaXPBarTexture1" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="10"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="-128" y="3"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.54296875" bottom="0.58203125"/>
|
|
</Texture>
|
|
<Texture name="BenillaXPBarTexture2" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="10"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="128" y="3"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.29296875" bottom="0.33203125"/>
|
|
</Texture>
|
|
<Texture name="BenillaXPBarTexture3" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="10"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="384" y="3"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.04296875" bottom="0.08203125"/>
|
|
</Texture>
|
|
</Layer>
|
|
</Layers>
|
|
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
|
<BarColor r="0.58" g="0.0" b="0.55"/>
|
|
<Scripts>
|
|
<OnLoad>BenillaExpBar_OnLoad(self)</OnLoad>
|
|
<OnEvent>BenillaExpBar_OnEvent(self)</OnEvent>
|
|
<OnEnter>BenillaExpBar_OnEnter(self)</OnEnter>
|
|
<OnLeave>BenillaExpBar_OnLeave()</OnLeave>
|
|
</Scripts>
|
|
</StatusBar>
|
|
|
|
<!--
|
|
The art frame: fills the bar (ref-MainMenuBar.xml l.225-229). Carries the 4 dwarf
|
|
strips (ARTWORK) + the 2 end caps and page number (OVERLAY); the buttons are its
|
|
children so they draw over the art.
|
|
-->
|
|
<Frame name="BenillaActionBarArtFrame">
|
|
<Anchors>
|
|
<Anchor point="TOPLEFT" relativeTo="BenillaActionBar" relativePoint="TOPLEFT"/>
|
|
<Anchor point="BOTTOMRIGHT" relativeTo="BenillaActionBar" relativePoint="BOTTOMRIGHT"/>
|
|
</Anchors>
|
|
<Layers>
|
|
<!-- 4 dwarf strips: 256x43, BOTTOM x=-384/-128/128/384 y=0, TexCoord bands
|
|
(ref-MainMenuBar.xml l.232-283). Adjacent atlas rows ⇒ the joins are seamless. -->
|
|
<Layer level="ARTWORK">
|
|
<Texture name="BenillaActionBarTexture0" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="43"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="-384" y="0"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.83203125" bottom="1.0"/>
|
|
</Texture>
|
|
<Texture name="BenillaActionBarTexture1" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="43"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="-128" y="0"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.58203125" bottom="0.75"/>
|
|
</Texture>
|
|
<Texture name="BenillaActionBarTexture2" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="43"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="128" y="0"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.33203125" bottom="0.5"/>
|
|
</Texture>
|
|
<Texture name="BenillaActionBarTexture3" file="Interface\MainMenuBar\UI-MainMenuBar-Dwarf">
|
|
<Size><AbsDimension x="256" y="43"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="384" y="0"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="1.0" top="0.08203125" bottom="0.25"/>
|
|
</Texture>
|
|
</Layer>
|
|
<!-- End caps: UI-MainMenuBar-EndCap-Dwarf 128x128, BOTTOM x=-544 / +544; the RIGHT
|
|
cap mirrors its art with TexCoords (1.0, 0.0, 0.0, 1.0) so the lion faces
|
|
outward on both sides (ref-MainMenuBar.xml l.286-310; the mirrored-UV engine
|
|
fix landed in 87c97d7). Page number: GameFontNormalSmall CENTER (30,-5),
|
|
static "1" (l.311-319). -->
|
|
<Layer level="OVERLAY">
|
|
<Texture name="BenillaActionBarLeftEndCap" file="Interface\MainMenuBar\UI-MainMenuBar-EndCap-Dwarf">
|
|
<Size><AbsDimension x="128" y="128"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="-544" y="0"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<Texture name="BenillaActionBarRightEndCap" file="Interface\MainMenuBar\UI-MainMenuBar-EndCap-Dwarf">
|
|
<Size><AbsDimension x="128" y="128"/></Size>
|
|
<Anchors><Anchor point="BOTTOM" relativePoint="BOTTOM"><Offset><AbsDimension x="544" y="0"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="1.0" right="0.0" top="0.0" bottom="1.0"/>
|
|
</Texture>
|
|
<FontString name="BenillaActionBarPageNumber" inherits="GameFontNormalSmall" text="1">
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="30" y="-5"/></Offset></Anchor>
|
|
</Anchors>
|
|
</FontString>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<!-- The 12 buttons: Button1 at the art frame BOTTOMLEFT (8,4); 2..12 chain LEFT of
|
|
the previous's RIGHT +6,0 (ref-ActionBarFrame.xml l.51-158). Replaces our old
|
|
fixed 38px stride with the real 42px chain (36 wide + 6 gap). -->
|
|
<CheckButton name="BenillaActionButton1" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="8" y="4"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 1)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton2" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton1" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 2)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton3" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton2" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 3)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton4" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton3" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 4)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton5" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton4" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 5)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton6" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton5" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 6)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton7" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton6" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 7)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton8" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton7" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 8)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton9" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton8" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 9)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton10" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton9" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 10)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton11" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton10" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 11)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
<CheckButton name="BenillaActionButton12" inherits="BenillaActionButtonTemplate">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaActionButton11" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
|
|
<Scripts><OnLoad>BenillaActionButton_OnLoad(self, 12)</OnLoad></Scripts>
|
|
</CheckButton>
|
|
|
|
<!-- Page up/down: 32x32 at CENTER of the art frame's TOPLEFT +(522,-22)/(522,-42)
|
|
(ref-ActionBarFrame.xml l.159-217). ART ONLY — we have no bar paging, so the
|
|
clicks are no-ops (no OnClick handler). -->
|
|
<Button name="BenillaActionBarUpButton">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativeTo="BenillaActionBarArtFrame" relativePoint="TOPLEFT"><Offset><AbsDimension x="522" y="-22"/></Offset></Anchor>
|
|
</Anchors>
|
|
<NormalTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Up"/>
|
|
<PushedTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Down"/>
|
|
<HighlightTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Highlight" alphaMode="ADD"/>
|
|
</Button>
|
|
<Button name="BenillaActionBarDownButton">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors>
|
|
<Anchor point="CENTER" relativeTo="BenillaActionBarArtFrame" relativePoint="TOPLEFT"><Offset><AbsDimension x="522" y="-42"/></Offset></Anchor>
|
|
</Anchors>
|
|
<NormalTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Up"/>
|
|
<PushedTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Down"/>
|
|
<HighlightTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Highlight" alphaMode="ADD"/>
|
|
</Button>
|
|
</Frames>
|
|
</Frame>
|
|
|
|
<!-- The performance ("ping") meter (ref-MainMenuBar.xml l.344-407). 16x64 pinned to the
|
|
bar's BOTTOMRIGHT +(-227,-10) — the empty recess between the last micro button and
|
|
the bag slots, which the bar art leaves TRANSPARENT for exactly this. The 20x66
|
|
texture hangs off the frame's TOPRIGHT (so it overspills 4 left and 2 below), and
|
|
the frame itself hangs 10 below the bar, putting the bar's grey column in the slot.
|
|
|
|
frameStrata="LOW" is load-bearing, not decoration: the meter draws UNDER the bar art
|
|
and shows through its transparent window. At the default MEDIUM it would paint over
|
|
the metal surround, since the texture is wider than the slot. (The ref gets the same
|
|
order via strata too — MainMenuBar's OnLoad RaiseFrameLevel can't reach across it.)
|
|
|
|
The hover button is the ref's own split: a HIGH-strata all-points button, because the
|
|
LOW frame beneath the art can't take the mouse itself. The ref declares it as a
|
|
sibling with parent="MainMenuBarPerformanceBarFrame"; nesting it is the same frame
|
|
tree, and its explicit strata survives the parent's LOW subtree-force (attributes
|
|
apply before nested <Frames> are built).
|
|
|
|
The -227 authored here is the NO-keyring position; BenillaMainMenuBar_UpdateKeyRing
|
|
(top of this file) re-points it to -235 while the keyring is shown, the ref's own
|
|
shift (MainMenuBar.lua l.180). Both offsets live in that one function. -->
|
|
<Frame name="BenillaPerformanceBarFrame" frameStrata="LOW">
|
|
<Size><AbsDimension x="16" y="64"/></Size>
|
|
<Anchors>
|
|
<Anchor point="BOTTOMRIGHT" relativeTo="BenillaActionBar" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-227" y="-10"/></Offset></Anchor>
|
|
</Anchors>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="BenillaPerformanceBar" file="Interface\MainMenuBar\UI-MainMenuBar-PerformanceBar">
|
|
<Size><AbsDimension x="20" y="66"/></Size>
|
|
<Anchors><Anchor point="TOPRIGHT"/></Anchors>
|
|
</Texture>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<Button name="BenillaPerformanceBarButton" setAllPoints="true" frameStrata="HIGH">
|
|
<Scripts>
|
|
<OnEnter>BenillaPerformanceBar_OnEnter(self)</OnEnter>
|
|
<OnLeave>BenillaPerformanceBar_OnLeave()</OnLeave>
|
|
</Scripts>
|
|
</Button>
|
|
</Frames>
|
|
<Scripts>
|
|
<OnLoad>BenillaPerformanceBar_OnLoad(self)</OnLoad>
|
|
<OnUpdate>BenillaPerformanceBar_OnUpdate(self, arg1)</OnUpdate>
|
|
</Scripts>
|
|
</Frame>
|
|
</Frames>
|
|
<Scripts>
|
|
<OnLoad>BenillaActionBar_OnLoad(self)</OnLoad>
|
|
<OnEvent>BenillaActionBar_OnEvent(self)</OnEvent>
|
|
</Scripts>
|
|
</Frame>
|
|
</Ui>
|