- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that - the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down - a lost session ends at the login screen instead of silently re-authenticating and stealing the account back - a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
184 lines
9.1 KiB
XML
184 lines
9.1 KiB
XML
<!--
|
|
The shared status-bar readout machinery — the contract 1.12's TextStatusBar.lua/.xml defines
|
|
(decision 1082), written here in our own terms. A bar opts in by calling
|
|
TextStatusBar_Initialize() in its OnLoad (setting `textLockable`), wiring a FontString via
|
|
SetTextStatusBarText(bar, text), and routing its OnEnter/OnLeave/OnValueChanged through the
|
|
Show/Hide/Update functions here. The text is "value / max", shown while hovered (a lockShow
|
|
refcount) or always when the `statusBarText` cvar is "1" ("Status Text" in the options; our
|
|
GetCVar returns nil for a cvar the engine doesn't carry, which reads as OFF — the 1.12
|
|
default).
|
|
|
|
Customers: the XP bar (ActionBar.xml) and, since decision 1143, the player and pet frames'
|
|
health/power bars (UnitFrames.xml). `textLockable` is what the statusBarText cvar pins, and
|
|
which bars carry it is the REFERENCE's own split, not an omission of ours: 1.12 sets it on the
|
|
player's two bars, the pet's two and the XP bar, and on nothing else. The target frame's bars
|
|
are deliberately not lockable there — its numerals are hover-only — so ours have the machinery
|
|
wired and no text regions yet; the hover half needs mouse-enabled bars we do not have.
|
|
-->
|
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
|
<Script><![CDATA[
|
|
-- The readout has exactly three reasons to be on screen, and every function below is some
|
|
-- combination of them: the Status Text option pins it (only on a bar that opted in with
|
|
-- `textLockable`), the pointer is on the bar (a refcount, so nested hovers balance), or the
|
|
-- bar is showing its zero text — a phrase rather than a number, which stands on its own.
|
|
--
|
|
-- The option test is the one of the three that reads from outside the bar, and it is asked
|
|
-- from three places, so it lives here once. It takes the option's VALUE rather than calling
|
|
-- GetCVar itself: the CVAR_UPDATE handler is handed the new value along with the event and
|
|
-- must not go asking the engine for the one it is being told about.
|
|
local function optionPins(bar, setting)
|
|
return setting == "1" and bar.textLockable
|
|
end
|
|
|
|
-- `bar` is optional and falls back to `this`, the same shape TextStatusBar_UpdateTextString
|
|
-- below already has (and for the same reason): the ref calls this from a bar's own OnLoad,
|
|
-- where `this` is the bar, but our unit frames wire their children from ONE shared
|
|
-- BenillaUnitFrame_OnLoad that holds each bar as a value, not as `this` (decision 1143).
|
|
function TextStatusBar_Initialize(bar)
|
|
if not bar then
|
|
bar = this
|
|
end
|
|
bar:RegisterEvent("CVAR_UPDATE")
|
|
bar.lockShow = 0
|
|
end
|
|
|
|
-- Hand a bar the FontString its readout lives in. A bar without one is never an error
|
|
-- below — it simply has nothing to say, and every entry point here checks for that.
|
|
function SetTextStatusBarText(bar, text)
|
|
if not bar or not text then
|
|
return
|
|
end
|
|
bar.TextString = text
|
|
end
|
|
|
|
function TextStatusBar_OnEvent(cvar, value)
|
|
if event ~= "CVAR_UPDATE" or cvar ~= "STATUS_BAR_TEXT" or not this.TextString then
|
|
return
|
|
end
|
|
-- Switching the option ON pins the readout up at once. Switching it off only puts the
|
|
-- readout away when nothing else is holding it there: a hover in progress keeps its own,
|
|
-- and gets to hide it when it ends.
|
|
if optionPins(this, value) then
|
|
this.TextString:Show()
|
|
elseif this.lockShow == 0 then
|
|
this.TextString:Hide()
|
|
end
|
|
end
|
|
|
|
-- Repaint one bar's readout from the value it is currently carrying. `textStatusBar` is
|
|
-- optional and falls back to `this` for the same reason TextStatusBar_Initialize's is.
|
|
function TextStatusBar_UpdateTextString(textStatusBar)
|
|
if not textStatusBar then
|
|
textStatusBar = this
|
|
end
|
|
local readout = textStatusBar.TextString
|
|
if not readout then
|
|
return
|
|
end
|
|
local value = textStatusBar:GetValue()
|
|
local _, valueMax = textStatusBar:GetMinMaxValues()
|
|
-- No ceiling is not the same thing as a bar at zero (below): it means the bar does not
|
|
-- apply to this unit at all, so the BAR leaves the screen rather than reading out a
|
|
-- number. Its readout is left exactly as it stands and comes back with it.
|
|
if valueMax <= 0 then
|
|
textStatusBar:Hide()
|
|
return
|
|
end
|
|
textStatusBar:Show()
|
|
if value == 0 and textStatusBar.zeroText then
|
|
-- Empty, and this bar has a phrase for empty. The phrase displaces the numbers and
|
|
-- is shown outright: it is a message, so neither the option nor a hover gates it,
|
|
-- and `isZero` is the flag that tells the hover not to take it away again.
|
|
textStatusBar.isZero = 1
|
|
readout:SetText(textStatusBar.zeroText)
|
|
readout:Show()
|
|
return
|
|
end
|
|
textStatusBar.isZero = nil
|
|
if textStatusBar.prefix then
|
|
readout:SetText(textStatusBar.prefix .. " " .. value .. " / " .. valueMax)
|
|
else
|
|
readout:SetText(value .. " / " .. valueMax)
|
|
end
|
|
if optionPins(textStatusBar, GetCVar("statusBarText")) or textStatusBar.lockShow > 0 then
|
|
readout:Show()
|
|
else
|
|
readout:Hide()
|
|
end
|
|
end
|
|
|
|
function TextStatusBar_OnValueChanged()
|
|
TextStatusBar_UpdateTextString()
|
|
end
|
|
|
|
function SetTextStatusBarTextPrefix(bar, prefix)
|
|
if bar and bar.TextString then
|
|
bar.prefix = prefix
|
|
end
|
|
end
|
|
|
|
function SetTextStatusBarTextZeroText(bar, zeroText)
|
|
if bar and bar.TextString then
|
|
bar.zeroText = zeroText
|
|
end
|
|
end
|
|
|
|
-- One more hold on the readout. `lockShow` counts rather than flags because two things can
|
|
-- be holding it open at once: the character sheet takes a hold for as long as it is open
|
|
-- (CharacterFrame_OnShow, decision 1146) and a hover on the same bar takes a second one on
|
|
-- top. Only the last release puts the readout away, so the hover still balances.
|
|
function ShowTextStatusBarText(bar)
|
|
if bar and bar.TextString then
|
|
bar.lockShow = (bar.lockShow or 0) + 1
|
|
bar.TextString:Show()
|
|
end
|
|
end
|
|
|
|
-- One hold released. The count floors at none rather than going negative, so an unbalanced
|
|
-- release — a frame hidden out from under a hover — cannot strand the readout on screen.
|
|
function HideTextStatusBarText(bar)
|
|
if bar and bar.TextString then
|
|
bar.lockShow = math.max((bar.lockShow or 0) - 1, 0)
|
|
-- Releasing a hold only puts the readout away if none of the three reasons is left.
|
|
-- The ref reads `this.isZero` for the middle one — a leak of the handler's own frame
|
|
-- into a helper that otherwise takes `bar`. Equivalent at every call site (each
|
|
-- caller passes its handler's own frame), so it is written as `bar`, which also
|
|
-- keeps the function callable outside a handler, where `this` is nil.
|
|
if bar.lockShow > 0 or bar.isZero == 1
|
|
or optionPins(bar, GetCVar("statusBarText")) then
|
|
bar.TextString:Show()
|
|
else
|
|
bar.TextString:Hide()
|
|
end
|
|
end
|
|
end
|
|
]]></Script>
|
|
|
|
<!--
|
|
The opt-in template (ref-TextStatusBar.xml): every script routed through the functions
|
|
above. One transcription cut, named: the ref OnEnter's TargetFrame arm (re-anchor the unit
|
|
tooltip under the target frame's bars) references a TextStatusBar-inheriting TargetFrame
|
|
bar we don't build yet — it is dead until that slice, so it is left out rather than
|
|
shipped unreachable. A frame that overrides all five scripts (the XP bar does) takes only
|
|
the StatusBar widget type from inheriting this.
|
|
-->
|
|
<StatusBar name="TextStatusBar" virtual="true">
|
|
<Scripts>
|
|
<OnLoad>TextStatusBar_Initialize()</OnLoad>
|
|
<OnEvent>TextStatusBar_OnEvent(arg1, arg2)</OnEvent>
|
|
<OnEnter>
|
|
TextStatusBar_UpdateTextString()
|
|
ShowTextStatusBarText(this)
|
|
if this.tooltipTitle and GameTooltip_AddNewbieTip then
|
|
BenillaTooltip_AddNewbieTipFor(this, this.tooltipTitle, 1.0, 1.0, 1.0, this.tooltipText, 1)
|
|
end
|
|
</OnEnter>
|
|
<OnLeave>
|
|
HideTextStatusBarText(this)
|
|
if GameTooltip then GameTooltip:Hide() end
|
|
</OnLeave>
|
|
<OnValueChanged>TextStatusBar_OnValueChanged()</OnValueChanged>
|
|
</Scripts>
|
|
</StatusBar>
|
|
</Ui>
|