Files
benilla-octo/crates/benilla-app/assets/ui/HelpFrame.xml
T
SamandClaude Fable 5 1c4cc147f5 GM tickets are in, and a login failure shows the string 1.12 shows
- GM tickets, end to end: five request/answer pairs, the seven Help-window bindings, three events and `GMTicketCategory.dbc` — the ten categories `HelpFrame.lua` keys 1..10 live in a DBC nothing here had ever opened (the four `TICKET_TYPE` strings feed a dropdown 1.12 never gave a frame); the category is one byte on the wire (a u32 would shift the map id and position and file every ticket at a garbage spot), and `UPDATETEXT` carries it too, which vmangos stores and cmangos swallows as the first character of the text — faithful to the client, the divergence recorded
- the engine re-asks for the ticket after a create or update succeeds and on a status push (the ask opcode has three callers in the reference, two of them engine legs with no idempotence guard) — which is why the shipped FrameXML registers no handler for the three response opcodes and still repaints; without that leg the form stays a form for ten minutes; `UPDATE_GM_STATUS` is a signed passthrough (`0xFFFFFFFF` → −1), the five ticket verbs drain through one ordered queue because call order is wire order, and the Help micro button — drawn, hovering and a no-op since the micro menu landed — is live
- a typed wrong password reads the reference's long "check the spelling of the account name and password" (0x04 and 0x05 share one jump-table arm — the client cannot say "wrong password", and the lockout cmangos's header describes does not exist in the binary), unknown codes read "Disconnected from server" rather than "Authentication failed", and every realmd row of the old map was in the wrong one: the two login-status enums have two key tables and two dialog paths, and a server source can only ever verify the codes, never which string the client draws for them

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 17:20:24 +07:00

1670 lines
106 KiB
XML

<Ui>
<!--
benilla's GM help window — the trouble-ticket panel the Help micro button opens, plus the
ticket-status toast that hangs under the buff row while a ticket is open.
The house convention, as MailFrame.xml and AuctionFrame.xml state it: the geometry, art
paths, sizes, offsets, anchors and texcoords below are QUOTED from the reference
`WoW/_extracted_framexml/HelpFrame.xml` (cited inline as `ref-xml l.N`) — they are
measurements, not expression. **THE LUA IS OURS.** The reference's `HelpFrame.lua` is the
SPECIFICATION — which functions an addon may call, the event vocabulary, and every branch's
observable effect are read off it (`ref-lua l.N`) — and how any of it is spelled here is
this file's own business. It is folded into the inline script block below rather than
shipped as a second `.lua`, which is this house's shape for every transcribed window.
NAMES ARE THE REFERENCE'S, not `Benilla*`-prefixed. `ToggleHelpFrame`, `HelpFrame`,
`TicketStatusFrame` and `HelpFrame_ShowFrame` are the names the reference's own
MainMenuBarMicroButtons and StaticPopup entries reach by, and MicroMenu.xml is a straight
transcription that now calls the first of them. Same posture as MicroMenu/FriendsFrame.
── THE ENGINE SEAM ─────────────────────────────────────────────────────────────────────
Six bindings, all of them the reference's own declarations: `GetGMTicket()`,
`NewGMTicket(category, text)`, `UpdateGMTicket(category, text)`, `DeleteGMTicket()`,
`GetGMStatus()` and `Stuck()`, plus `GetGMTicketCategories()` — a flat vararg list
`id1, name1, id2, name2, …` sourced from `GMTicketCategory.dbc`. That DBC ships exactly ten
rows and its ids ARE the wire category values (1 Stuck, 2 Behavior/Harassment, 3 Guild,
4 Item, 5 Environmental, 6 Non-Quest/Creep, 7 Quest/Quest NPC, 8 Technical,
9 Account/Billing, 10 Character) — which is WHY `HELPFRAME_FRAMES` and `GENERAL_HELPFRAME`
below are keyed 1..10: the keys are the DBC ids, so `HelpFrameGM_UpdateCategories`'s
`button.key = <id>` transcribes unchanged and a click carries the wire value straight into
`NewGMTicket`.
── THE STRING TABLE ─────────────────────────────────────────────────────────────────────
We ship none of Blizzard's text (AuctionFrame.xml's header carries the law):
`GlobalStrings.lua` is EXECUTED off the player's own patch chain at boot. In XML a
SCREAMING_SNAKE `text` attribute IS a global-string lookup (loader/mod.rs `resolve_text`,
wow-re `FrameScript_GetText 0x703bf0`), which is the reference's own mechanism and is used
verbatim throughout the markup below. In Lua every read goes through
`gs(key[, fallback])`, because a harness that loads only this XML has no string table and a
nil global there would take a whole repaint down. A fallback is a SHAPE ("%s"), never a
translation — only `GM_TICKET_WAIT_TIME` needs one; every other key is plain prose whose
shape is the empty string.
── WHAT IS DELIBERATELY NOT HERE ────────────────────────────────────────────────────────
1 · **The GM survey.** `Blizzard_GMSurveyUI` is a separate addon and a separate decision.
The three places the reference reaches it (`HelpFrameOpenTicket_OnEvent`'s
`GMSURVEY_DISPLAY` arm, `TicketStatusFrame.hasGMSurvey`, and the survey branch shared by
`TicketStatusButton`'s OnClick and the toast's OnMouseUp) are transcribed STRUCTURALLY —
the event is still registered, the flag still exists, the branch is still taken first —
but the body is a no-op that cannot error. In particular `GMSurveyFrame_LoadUI()` is NOT
called: no such global exists here, and calling it would abort the handler. Deferred,
not forgotten.
2 · **`HelpFrameOpenTicketDropDown_*` (ref-lua l.361-387) is DEAD and is dropped.** Four
functions with no frame: grepping the whole 1.12 extraction for
`HelpFrameOpenTicketDropDown` finds only those four definitions and ONE more hit —
ref-xml l.750, where `HelpFrameOpenTicket`'s `<OnShow>` body is
`HelpFrameOpenTicketDropDown_OnShow();` behind a Lua line comment, commented
out by Blizzard itself. No `<Frame>`,
`<Button>` or `CreateFrame` anywhere declares that name, so
`UIDropDownMenu_Initialize(this, …)` in `_OnLoad` could never have run and
`UIDropDownMenu_SetSelectedID(HelpFrameOpenTicketDropDown, …)` in `_OnClick` would
index a nil global. `TICKET_TYPE1..4` (GlobalStrings.lua l.4239-4242) feed only
`_Initialize` and are therefore dead with it. The ticket's category comes from the GM
category button that was clicked instead (`HelpFrameOpenTicket.ticketType`).
3 · **The `<OnUpdate>ScrollingEdit_OnUpdate()</OnUpdate>` on the ticket editor** (ref-xml
l.700-702). `ScrollingEdit_OnTextChanged` and `_OnCursorChanged` both ship
(ScrollTemplates.xml) and are wired below; `_OnUpdate` deliberately does not — it needs
the caret's own pixel offset from the font engine, which our EditBox does not report
yet, and that file names it rather than stubbing it. Wiring a call to a nil global would
abort the editor's OnUpdate every frame, so the handler is absent. Consequence: typing
past the bottom of the 378px view does not auto-scroll; the bar still does.
4 · **HELP_TICKET's close button and its 350px width** (ref StaticPopup.lua l.1591-1597).
Our shared StaticPopupTemplate (UiPanels.xml) declares no `$parentCloseButton`, and
`StaticPopup_Show`'s width arm says so in its own comment ("HELP_TICKET's 350 arm waits
for that dialog"). Both halves are the ENGINE's to grow, not this window's, so the
dialog shows at the standard 320 with no corner X. It is not a trap: clicking the ticket
icon again hides it (`TicketStatus_OnClick`'s middle branch, ref-xml l.1490-1492), which
is the reference's own second way out. Its two labels ("Edit My Ticket" / "Abandon My
Ticket") also sit in the engine's fixed 120px buttons — UiPanels.xml's own named
narrowing.
── FRAMES NOTHING REACHES TODAY (transcribed anyway, so nobody "fixes" a non-bug) ───────
`HelpFrameStuck` (ref-xml l.1301-1378) and `HelpFrameBug` (ref-xml l.1380-1392) are
unreachable in 1.12. Every caller of `HelpFrame_ShowFrame` in the whole extraction passes
"Home", "GMHome", "OpenTicket", or a GM category id 1..10 (grepped: ref-lua l.177/504/540,
ref-xml l.378/593/975/1105/1255/1285/1373, StaticPopup.lua l.351) — never "Stuck" and never
"Bug". `HELPFRAME_FRAMES["Stuck"]` therefore never fires, because ticket category 1
("Stuck") routes through `HELPFRAME_FRAMES[1]` to `HelpFrameGeneral`, which
`GENERAL_HELPFRAME[1]` dresses with the unstick button. There is no `HELPFRAME_FRAMES`
"Bug" key at all — `HelpFrameBug` is a bare divider frame with no route to it. Both are
transcribed because they are the reference's own layout and a later
`HelpFrame_ShowFrame("Stuck")` would want them intact.
── DELIBERATE DIVERGENCES (each stated where it stands, listed here so they are countable) ─
1 · The GM category list is the house FAUX scroll kit (ScrollTemplates.xml, decisions
0247/0250/0251): a plain `<Frame inherits="FauxScrollFrameTemplate">`, not the
reference's `<ScrollFrame>`, so its `<OnVerticalScroll>` body (ref-xml l.564-566) has
nothing to fire and is replaced by an `updateFunc`. The three loose trough textures the
reference hangs beside each bar (ref-xml l.517-560 and l.642-685) become the kit's
shared `BenillaScrollTroughTemplate`, whose seat law was derived from exactly these
offsets. ReputationFrame.xml's precedent.
2 · The ticket editor's scroll frame IS a real `UIPanelScrollFrameTemplate`, so its bar is
always up and `BenillaScrollBar_SetShown` (the only thing that seats a trough) never
runs for it. Its trough is seated explicitly in the frame's OnLoad through the kit's own
public `BenillaScrollTrough_Seat`. GuildInfoFrameScrollFrame (FriendsFrame.xml) simply
has no trough; that is an omission, not a law, and the reference draws the channel here.
3 · "Fit the button to its label" reads the Button's own `GetTextWidth()` (which forwards to
the label's unwrapped `GetStringWidth`, script/button.rs) rather than the reference's
`…Text:GetWidth()`. Same number for a non-wrapping label; the laid-out width is the one
that feeds itself its own previous output (decision 0997's measured feedback loop). The
fit also moves from the button's `<OnLoad>` to its page's `<OnShow>`, because a measure
taken before the atlas has seen the string answers 0 and nothing would re-run it.
4 · `TicketStatusFrame_OnEvent`'s "no ticket" leg re-anchors `TemporaryEnchantFrame` back to
TOPRIGHT **(-175, -13)**, not the reference's (-180, -13) (ref-lua l.498). -175 is what
BuffFrame.xml (and ref-BuffFrame.xml l.390-394) actually declares, so the reference
nudges the frame 5px left after every ticket closes and never puts it back. A typo, not
a mechanism — MicroMenu.xml's precedent for not reproducing one.
5 · `HELP_TICKET`'s OnCancel drops the reference's `local currentFrame = this:GetParent()` /
`dialogFrame.data = currentFrame` pair (StaticPopup.lua l.357-361). Our engine calls
`OnCancel(data, reason)` as a plain function with no `this`, and nothing ever reads that
data — `HELP_TICKET_ABANDON_CONFIRM`'s OnAccept calls `DeleteGMTicket()` with no
argument. Keeping it would be two lines that can only throw.
6 · The reference's Lua-5.0 `arg`/`arg.n` vararg table is written the 5.1-native way,
`select("#", ...)` / `select(i, ...)` (this VM is lua51 — TalentFrame.xml's precedent),
and its `for k, v in <table> do` generic-for becomes `ipairs`.
7 · `elapsedTime = 0` (ref-lua l.164) is dropped: a global assigned once and read nowhere in
the whole extraction. `refreshTime` (ref-lua l.495/548) becomes a file-local rather than
a leaked global — it is read by exactly one function in this file.
8 · `message("Not enough bullets! Tell Derek")` (ref-lua l.260/284) is dropped. It is a
Blizzard developer assert naming a Blizzard engineer, not UI text, and the branch is
unreachable: `MAX_GENERAL_BULLETS` is 10 and the longest configured run is 7.
9 · `HelpFrameOpenTicket_OnEvent`'s `ticketFrameHeight`/`twoLineHeight` locals are dropped:
assigned on three legs and read on none, even in the reference — the toast sizes itself
from its two measured FontStrings. ReputationFrame.xml's precedent.
── TWO FIDELITY NOTES A LATER READER WOULD OTHERWISE MISREAD AS BUGS ────────────────────
· `HelpFrame_OnEvent`'s `UPDATE_GM_STATUS` arm branches on arg1 == 1 (queue up) and
arg1 == -1 (queue down AND pop HELP_TICKET_QUEUE_DISABLED). Against the vmangos server
benilla talks to, `SMSG_GMTICKETSYSTEMSTATUS` only ever carries 0 or 1 — so the -1 leg is
transcribed faithfully and is simply unreachable here today.
· `CATEGORY_TO_NOT_DISPLAY` (ref-lua l.305) suppresses one category's action button. Its
ONLY setter in the whole extraction is `Localization.lua`'s `LocalizeFrames()` (l.23,
`= 9`) — an enGB-only adjustment that hides the Billing & Account button because EU
billing went somewhere else. benilla ships no Localization.lua (GameTime.xml's header
makes the same note about `TwentyFourHourTime`), so the global is nil, the guard never
fires, and category 9 keeps its button. That is the enUS behaviour.
-->
<Script><![CDATA[
-- One GlobalString read. See this file's header: the table is the player's own, executed
-- off their chain at boot, and absent in a bare-XML harness.
local function gs(key, fallback)
local value = getglobal(key)
if value and value ~= "" then
return value
end
return fallback or ""
end
-- ── Constants (ref-lua l.1-2, l.160-166) ────────────────────────────────────────────────
HELPFRAME_BULLET_SPACING = -3 -- ref-lua l.1
HELPFRAME_SECTION_SPACING = -20 -- ref-lua l.2
MAX_GENERAL_BULLETS = 10 -- ref-lua l.160
NUM_GM_CATEGORIES_TO_DISPLAY = 10 -- ref-lua l.161
GMTICKET_CHECK_INTERVAL = 600 -- ref-lua l.162: 10 minutes
-- The petition queue starts ASSUMED UP (ref-lua l.166), so the window is usable before the
-- first UPDATE_GM_STATUS lands. Public because the HELP_TICKET dialog below reads it.
PETITION_QUEUE_ACTIVE = 1
-- Seconds until the next GetGMTicket poll while a ticket is open (ref-lua l.495/548). A
-- file-local, not the reference's leaked global: one reader, in this file.
local refreshTime
-- ref-lua l.5-8. Defined before GENERAL_HELPFRAME because that table stores it as a value;
-- the reference's own comment on this is "Ugly, but needs to be up here".
function HelpFrameUnstick_OnClick()
Stuck()
HideUIPanel(HelpFrame)
end
-- ── The category → page routing table (ref-lua l.11-27) ────────────────────────────────
-- The numeric keys ARE the GMTicketCategory.dbc ids (this file's header): whatever
-- GetGMTicketCategories() hands a button becomes both the page key and the wire category.
-- Nine of the ten land on the one HelpFrameGeneral page, which GENERAL_HELPFRAME below
-- re-dresses per category; only 2 (Behavior/Harassment) has a page of its own.
HELPFRAME_FRAMES = {}
HELPFRAME_FRAMES[1] = { name = "HelpFrameGeneral" } -- Stuck
HELPFRAME_FRAMES[2] = { name = "HelpFrameHarassment" } -- Behavior / Harassment
HELPFRAME_FRAMES[3] = { name = "HelpFrameGeneral" } -- Guild
HELPFRAME_FRAMES[4] = { name = "HelpFrameGeneral" } -- Item
HELPFRAME_FRAMES[5] = { name = "HelpFrameGeneral" } -- Environmental
HELPFRAME_FRAMES[6] = { name = "HelpFrameGeneral" } -- Non-Quest NPC / Creep
HELPFRAME_FRAMES[7] = { name = "HelpFrameGeneral" } -- Quest / Quest NPC
HELPFRAME_FRAMES[8] = { name = "HelpFrameGeneral" } -- Technical
HELPFRAME_FRAMES[9] = { name = "HelpFrameGeneral" } -- Account / Billing
HELPFRAME_FRAMES[10] = { name = "HelpFrameGeneral" } -- Character
-- Unreachable today (this file's header): category 1 routes to HelpFrameGeneral above, and
-- nothing anywhere passes "Stuck". Kept because the page exists and the route is the
-- reference's own.
HELPFRAME_FRAMES["Stuck"] = { name = "HelpFrameStuck" }
HELPFRAME_FRAMES["GMHome"] = { name = "HelpFrameGM" }
HELPFRAME_FRAMES["Home"] = { name = "HelpFrameHome" }
HELPFRAME_FRAMES["OpenTicket"] = { name = "HelpFrameOpenTicket" }
-- ── The nine dressings of the shared general page (ref-lua l.29-158) ───────────────────
-- Every string is a gs() read (header). Categories 1..10 minus 2 (its own page); note the
-- reference configures no entry for 2, which is exactly why 2 is the one with a page.
GENERAL_HELPFRAME = {}
-- 1 · Stuck. The only entry with a click override and a second button: its primary action is
-- the client-side unstick, and button2 falls through to the normal "page a GM" path
-- (HelpFrameGeneralButton_OnClick's else leg). ref-lua l.30-36.
GENERAL_HELPFRAME[1] = {
title = gs("STUCK_OPTION"), -- GlobalStrings l.4207
titleText = gs("HELPFRAME_STUCK_TEXT1"), -- l.2232
buttonText = gs("STUCK_BUTTON_TEXT"), -- l.4206
buttonOnClickFunc = HelpFrameUnstick_OnClick,
button2Text = gs("STUCK_BUTTON2_TEXT"), -- l.4205
}
-- 3 · Guild. ref-lua l.37-47.
GENERAL_HELPFRAME[3] = {
title = gs("HELPFRAME_GUILD_TITLE"), -- l.2179
titleText = gs("HELPFRAME_GUILD_TEXT"), -- l.2178
bulletTitle1 = gs("HELPFRAME_GUILD_BULLET_TITLE1"), -- l.2176
bullets1 = {
gs("HELPFRAME_GUILD_BULLET1"), -- l.2173
gs("HELPFRAME_GUILD_BULLET2"), -- l.2174
gs("HELPFRAME_GUILD_BULLET3"), -- l.2175
},
buttonText = gs("HELPFRAME_GUILD_BUTTON_TEXT"), -- l.2177
}
-- 4 · Item. ref-lua l.48-65.
GENERAL_HELPFRAME[4] = {
title = gs("HELPFRAME_ITEM_TITLE"), -- l.2203
titleText = gs("HELPFRAME_ITEM_TEXT"), -- l.2202
bulletTitle1 = gs("HELPFRAME_ITEM_BULLET_TITLE1"), -- l.2199
bullets1 = {
gs("HELPFRAME_ITEM_BULLET1"), -- l.2192
gs("HELPFRAME_ITEM_BULLET2"), -- l.2193
gs("HELPFRAME_ITEM_BULLET3"), -- l.2194
gs("HELPFRAME_ITEM_BULLET4"), -- l.2195
gs("HELPFRAME_ITEM_BULLET5"), -- l.2196
},
bulletTitle2 = gs("HELPFRAME_ITEM_BULLET_TITLE2"), -- l.2200
bullets2 = {
gs("HELPFRAME_ITEM_BULLET6"), -- l.2197
gs("HELPFRAME_ITEM_BULLET7"), -- l.2198
},
buttonText = gs("HELPFRAME_ITEM_BUTTON_TEXT"), -- l.2201
}
-- 5 · Environmental. ref-lua l.66-83.
GENERAL_HELPFRAME[5] = {
title = gs("HELPFRAME_ENVIRONMENTAL_TITLE"), -- l.2168
titleText = gs("HELPFRAME_ENVIRONMENTAL_TEXT"), -- l.2167
bulletTitle1 = gs("HELPFRAME_ENVIRONMENTAL_BULLET_TITLE1"), -- l.2164
bullets1 = {
gs("HELPFRAME_ENVIRONMENTAL_BULLET1"), -- l.2158
gs("HELPFRAME_ENVIRONMENTAL_BULLET2"), -- l.2159
gs("HELPFRAME_ENVIRONMENTAL_BULLET3"), -- l.2160
gs("HELPFRAME_ENVIRONMENTAL_BULLET4"), -- l.2161
},
bulletTitle2 = gs("HELPFRAME_ENVIRONMENTAL_BULLET_TITLE2"), -- l.2165
bullets2 = {
gs("HELPFRAME_ENVIRONMENTAL_BULLET5"), -- l.2162
gs("HELPFRAME_ENVIRONMENTAL_BULLET6"), -- l.2163
},
buttonText = gs("HELPFRAME_ENVIRONMENTAL_BUTTON_TEXT"), -- l.2166
}
-- 6 · Non-Quest NPC / Creep. ref-lua l.84-102.
GENERAL_HELPFRAME[6] = {
title = gs("HELPFRAME_NONQUEST_TITLE"), -- l.2215
titleText = gs("HELPFRAME_NONQUEST_TEXT"), -- l.2214
bulletTitle1 = gs("HELPFRAME_NONQUEST_BULLET_TITLE1"), -- l.2211
bullets1 = {
gs("HELPFRAME_NONQUEST_BULLET1"), -- l.2204
gs("HELPFRAME_NONQUEST_BULLET2"), -- l.2205
gs("HELPFRAME_NONQUEST_BULLET3"), -- l.2206
gs("HELPFRAME_NONQUEST_BULLET4"), -- l.2207
},
bulletTitle2 = gs("HELPFRAME_NONQUEST_BULLET_TITLE2"), -- l.2212
bullets2 = {
gs("HELPFRAME_NONQUEST_BULLET5"), -- l.2208
gs("HELPFRAME_NONQUEST_BULLET6"), -- l.2209
gs("HELPFRAME_NONQUEST_BULLET7"), -- l.2210
},
buttonText = gs("HELPFRAME_NONQUEST_BUTTON_TEXT"), -- l.2213
}
-- 7 · Quest / Quest NPC. ref-lua l.103-118.
GENERAL_HELPFRAME[7] = {
title = gs("HELPFRAME_QUEST_TITLE"), -- l.2229
titleText = gs("HELPFRAME_QUEST_TEXT"), -- l.2228
bulletTitle1 = gs("HELPFRAME_QUEST_BULLET_TITLE1"), -- l.2225
bullets1 = {
gs("HELPFRAME_QUEST_BULLET1"), -- l.2220
gs("HELPFRAME_QUEST_BULLET2"), -- l.2221
gs("HELPFRAME_QUEST_BULLET3"), -- l.2222
},
bulletTitle2 = gs("HELPFRAME_QUEST_BULLET_TITLE2"), -- l.2226
bullets2 = {
gs("HELPFRAME_QUEST_BULLET4"), -- l.2223
gs("HELPFRAME_QUEST_BULLET5"), -- l.2224
},
buttonText = gs("HELPFRAME_QUEST_BUTTON_TEXT"), -- l.2227
}
-- 8 · Technical. The one entry with an endText but NO button: the reference routes technical
-- issues to the support site, not to a GM (ref-lua l.119-133 — note it sets `endText` from
-- the _BULLET_TITLE2 key, which is that key's real content here).
GENERAL_HELPFRAME[8] = {
title = gs("HELPFRAME_TECHNICAL_TITLE"), -- l.2246
titleText = gs("HELPFRAME_TECHNICAL_TEXT"), -- l.2245
bulletTitle1 = gs("HELPFRAME_TECHNICAL_BULLET_TITLE1"), -- l.2242
bullets1 = {
gs("HELPFRAME_TECHNICAL_BULLET1"), -- l.2235
gs("HELPFRAME_TECHNICAL_BULLET2"), -- l.2236
gs("HELPFRAME_TECHNICAL_BULLET3"), -- l.2237
gs("HELPFRAME_TECHNICAL_BULLET4"), -- l.2238
gs("HELPFRAME_TECHNICAL_BULLET5"), -- l.2239
gs("HELPFRAME_TECHNICAL_BULLET6"), -- l.2240
gs("HELPFRAME_TECHNICAL_BULLET7"), -- l.2241
},
endText = gs("HELPFRAME_TECHNICAL_BULLET_TITLE2"), -- l.2243
}
-- 9 · Account / Billing. ref-lua l.134-145. The reference's bullets1 stops at BULLET3;
-- HELPFRAME_ACCOUNT_BULLET4 (l.2141) exists in the string table and is unused — transcribed
-- as written rather than "completed".
GENERAL_HELPFRAME[9] = {
title = gs("HELPFRAME_ACCOUNT_TITLE"), -- l.2146
titleText = gs("HELPFRAME_ACCOUNT_TEXT"), -- l.2145
bulletTitle1 = gs("HELPFRAME_ACCOUNT_BULLET_TITLE1"), -- l.2142
bullets1 = {
gs("HELPFRAME_ACCOUNT_BULLET1"), -- l.2138
gs("HELPFRAME_ACCOUNT_BULLET2"), -- l.2139
gs("HELPFRAME_ACCOUNT_BULLET3"), -- l.2140
},
endText = gs("HELPFRAME_ACCOUNT_ENDTEXT"), -- l.2144
buttonText = gs("HELPFRAME_ACCOUNT_BUTTON_TEXT"), -- l.2143
}
-- 10 · Character. ref-lua l.146-158.
GENERAL_HELPFRAME[10] = {
title = gs("HELPFRAME_CHARACTER_TITLE"), -- l.2157
titleText = gs("HELPFRAME_CHARACTER_TEXT"), -- l.2156
bulletTitle1 = gs("HELPFRAME_CHARACTER_BULLET_TITLE1"), -- l.2154
bullets1 = {
gs("HELPFRAME_CHARACTER_BULLET1"), -- l.2149
gs("HELPFRAME_CHARACTER_BULLET2"), -- l.2150
gs("HELPFRAME_CHARACTER_BULLET3"), -- l.2151
gs("HELPFRAME_CHARACTER_BULLET4"), -- l.2152
gs("HELPFRAME_CHARACTER_BULLET5"), -- l.2153
},
buttonText = gs("HELPFRAME_CHARACTER_BUTTON_TEXT"), -- l.2155
}
-- Fit a button to its label, the reference's arithmetic (`+40`, ref-xml l.375/1341 and
-- ref-lua l.307/334) on the house's measure verb. See divergence 3 in the header for why
-- this is `GetTextWidth` and not the label's laid-out `GetWidth`.
function HelpFrameButton_FitToText(button)
if not button then return end
button:SetWidth(button:GetTextWidth() + 40)
end
-- ── The window (ref-lua l.168-194) ─────────────────────────────────────────────────────
-- The reference's tab handling is commented out in its own OnLoad (ref-lua l.170-171) and
-- OnShow (l.176) — 1.12 ships this window with no tab strip — so it is not transcribed.
function HelpFrame_OnLoad(frame)
frame:RegisterEvent("UPDATE_GM_STATUS")
end
function HelpFrame_OnShow(frame)
HelpFrame_ShowFrame("Home")
if UpdateMicroButtons then UpdateMicroButtons() end
PlaySound("igCharacterInfoOpen")
GetGMStatus()
end
-- ref-lua l.183-194. arg1 == 1 means the petition queue is up; anything else takes it down,
-- and -1 additionally says so out loud. Against vmangos, SMSG_GMTICKETSYSTEMSTATUS only
-- ever carries 0 or 1, so the -1 leg is faithful but unreachable here (header note).
function HelpFrame_OnEvent()
if event == "UPDATE_GM_STATUS" then
if arg1 == 1 then
PETITION_QUEUE_ACTIVE = 1
else
PETITION_QUEUE_ACTIVE = nil
if arg1 == -1 then
StaticPopup_Show("HELP_TICKET_QUEUE_DISABLED")
end
end
end
end
-- ref-lua l.196-229. `key` is either a HELPFRAME_FRAMES key (a category id, "Home",
-- "GMHome", "OpenTicket") or something unknown, which falls through to the ticket editor —
-- the reference's own default, and what makes a category with no route still openable.
function HelpFrame_ShowFrame(key, ticketType)
if HelpFrame.openFrame then
HelpFrame.openFrame:Hide()
end
-- Asking for the editor with the queue down closes the window and says why.
if key == "OpenTicket" and not PETITION_QUEUE_ACTIVE then
HideUIPanel(HelpFrame)
StaticPopup_Show("HELP_TICKET_QUEUE_DISABLED")
return
end
local frame
local frameInfo = HELPFRAME_FRAMES[key]
if frameInfo then
local targetName = frameInfo.name
if targetName == "HelpFrameGeneral" then
HelpFrame_SetupGeneralFrame(key)
end
frame = getglobal(targetName)
else
frame = getglobal(HELPFRAME_FRAMES["OpenTicket"].name)
end
frame:Show()
HelpFrame.openFrame = frame
if ticketType then
HelpFrameOpenTicket.ticketType = ticketType
end
end
-- ref-lua l.231-349. The shared general page re-dressed for one category: a title, body
-- text, up to two bullet sections with their own headings, an optional trailing paragraph,
-- and up to two action buttons — each element re-anchored to whatever ended up above it,
-- which is why this is a chain of SetPoints rather than a static layout.
function HelpFrame_SetupGeneralFrame(key)
local info = GENERAL_HELPFRAME[key]
if not info then
return
end
if info.title then
HelpFrameGeneralTitle:SetText(info.title)
end
if info.titleText then
HelpFrameGeneralTitleText:SetText(info.titleText)
end
if info.bulletTitle1 then
HelpFrameBulletTitle1:SetText(info.bulletTitle1)
else
HelpFrameBulletTitle1:SetText("")
end
local bulletIndex = 1
local bullet
if info.bullets1 then
for index, value in ipairs(info.bullets1) do
bullet = getglobal("HelpFrameGeneralBullet" .. bulletIndex)
-- Unreachable: MAX_GENERAL_BULLETS is 10 and the longest run configured above
-- is 7. The reference's `message(...)` dev assert is dropped (header, 8).
if bullet then
getglobal("HelpFrameGeneralBullet" .. bulletIndex .. "Text"):SetText(value)
bullet:Show()
if index > 1 then
bullet:SetPoint("TOPLEFT", "HelpFrameGeneralBullet" .. (bulletIndex - 1),
"BOTTOMLEFT", 0, HELPFRAME_BULLET_SPACING)
end
bulletIndex = bulletIndex + 1
end
end
end
if info.bulletTitle2 then
HelpFrameBulletTitle2:Show()
HelpFrameBulletTitle2:SetPoint("TOPLEFT",
"HelpFrameGeneralBullet" .. (bulletIndex - 1), "BOTTOMLEFT", -5,
HELPFRAME_SECTION_SPACING)
HelpFrameBulletTitle2:SetText(info.bulletTitle2)
else
HelpFrameBulletTitle2:Hide()
end
if info.bullets2 then
for index, value in ipairs(info.bullets2) do
bullet = getglobal("HelpFrameGeneralBullet" .. bulletIndex)
if bullet then
getglobal("HelpFrameGeneralBullet" .. bulletIndex .. "Text"):SetText(value)
bullet:Show()
if index == 1 then
bullet:SetPoint("TOPLEFT", "HelpFrameBulletTitle2", "BOTTOMLEFT", 5,
HELPFRAME_BULLET_SPACING)
else
bullet:SetPoint("TOPLEFT", "HelpFrameGeneralBullet" .. (bulletIndex - 1),
"BOTTOMLEFT", 0, HELPFRAME_BULLET_SPACING)
end
bulletIndex = bulletIndex + 1
end
end
end
for i = bulletIndex, MAX_GENERAL_BULLETS do
getglobal("HelpFrameGeneralBullet" .. i):Hide()
end
-- Floor of 2, so a category with NO bullets still has "bullet 1" to anchor under
-- (ref-lua l.293; the anchors below all read bulletIndex-1).
bulletIndex = max(bulletIndex, 2)
if info.endText then
HelpFrameEndText:SetText(info.endText)
HelpFrameEndText:SetPoint("TOPLEFT",
"HelpFrameGeneralBullet" .. (bulletIndex - 1), "BOTTOMLEFT", -5,
HELPFRAME_SECTION_SPACING)
HelpFrameEndText:Show()
else
HelpFrameEndText:Hide()
end
-- The action button. CATEGORY_TO_NOT_DISPLAY is nil here — its only setter is
-- Localization.lua's enGB LocalizeFrames(), which benilla does not ship (header note).
if info.buttonText
and (not (CATEGORY_TO_NOT_DISPLAY and (CATEGORY_TO_NOT_DISPLAY == key))) then
HelpFrameGeneralButton:SetText(info.buttonText)
HelpFrameButton_FitToText(HelpFrameGeneralButton)
if info.endText then
HelpFrameGeneralButton:SetPoint("TOP", "HelpFrameEndText", "BOTTOM", 0,
HELPFRAME_SECTION_SPACING)
else
HelpFrameGeneralButton:SetPoint("TOP",
"HelpFrameGeneralBullet" .. (bulletIndex - 1), "BOTTOM", 0,
HELPFRAME_SECTION_SPACING)
end
HelpFrameGeneralButton.onClick = info.buttonOnClickFunc
HelpFrameGeneralButton:Show()
else
HelpFrameGeneralButton:Hide()
end
-- titleText2 / button2 (ref-lua l.322-348). No configured entry sets titleText2, so the
-- -300 x-offset below never runs today; kept because button2 (Stuck's "Page a GM") does.
if info.titleText2 then
HelpFrameGeneralTitleText2:SetText(info.titleText2)
HelpFrameGeneralTitleText2:SetPoint("TOPLEFT", "HelpFrameGeneralButton", "BOTTOM",
-300, HELPFRAME_SECTION_SPACING)
HelpFrameGeneralTitleText2:Show()
else
HelpFrameGeneralTitleText2:Hide()
end
if info.button2Text then
HelpFrameGeneralButton2:SetText(info.button2Text)
HelpFrameButton_FitToText(HelpFrameGeneralButton2)
if info.titleText2 then
HelpFrameGeneralButton2:SetPoint("TOP", "HelpFrameGeneralTitleText2", "BOTTOM",
0, HELPFRAME_SECTION_SPACING)
else
HelpFrameGeneralButton2:SetPoint("TOP", "HelpFrameGeneralButton", "BOTTOM", 0,
HELPFRAME_SECTION_SPACING)
end
HelpFrameGeneralButton2.onClick = info.button2OnClickFunc
HelpFrameGeneralButton2:Show()
else
HelpFrameGeneralButton2:Hide()
end
end
-- ref-lua l.351-359. Opening the window dismisses both ticket dialogs — you are about to be
-- shown the same choice in a bigger frame.
function ToggleHelpFrame()
if HelpFrame:IsVisible() then
HideUIPanel(HelpFrame)
else
ShowUIPanel(HelpFrame)
StaticPopup_Hide("HELP_TICKET_ABANDON_CONFIRM")
StaticPopup_Hide("HELP_TICKET")
end
end
-- ── The ticket editor (ref-lua l.389-486) ──────────────────────────────────────────────
-- UPDATE_TICKET's arguments, the reference's own block comment (ref-lua l.409-423):
-- arg1 category · arg2 description · arg3 ticket age (days) · arg4 oldest ticket (days)
-- arg5 how stale that oldest-ticket figure is (days; > 1 hour means bad data)
-- arg6 assigned-to-GM flag (0 no, 1 a GM, 2 the escalation queue)
-- arg7 opened-by-GM flag (0 never, 1 yes)
function HelpFrameOpenTicket_OnEvent(eventName)
-- The GM SURVEY branch, structurally faithful and deliberately inert (header, 1). The
-- reference dresses the toast as a survey invitation, flashes it, and returns; we take
-- the same early return so nothing below can misread a survey event as a ticket, but we
-- neither paint nor flash it, because GMSurveyFrame_LoadUI (the thing the toast would
-- then open) does not exist here. CHOSEN_FOR_GMSURVEY (GlobalStrings l.749) and
-- UIFrameFlash go with it.
if eventName == "GMSURVEY_DISPLAY" then
return
end
if arg1 and arg1 ~= 0 then
-- There IS an open ticket.
TicketStatusTitleText:SetText(gs("TICKET_STATUS1")) -- GlobalStrings l.4238
HelpFrameOpenTicket.ticketType = arg1
HelpFrameOpenTicketText:SetText(arg2)
-- The reference's `ticketFrameHeight` (35 / 40 / 52) is DEAD WEIGHT and is
-- dropped: it is assigned on three legs (ref-lua l.424, 444, 451) and read on
-- none — the toast's height comes from the measured text at l.460, below.
-- ReputationFrame.xml's precedent for dropping the reference's own unread locals.
local statusText
HelpFrameOpenTicket.ticketTimer = nil
if arg7 == 1 then
-- A GM has already opened it: no estimate, just a state.
if arg6 == 2 then
statusText = gs("GM_TICKET_ESCALATED") -- l.2020
else
statusText = gs("GM_TICKET_SERVICE_SOON") -- l.2022
end
else
-- Estimate = how much older the oldest open ticket is than yours, in seconds.
local estimatedWaitTime = (arg4 - arg3) * 24 * 60 * 60
if estimatedWaitTime < 0 then
estimatedWaitTime = 0
end
-- 0.042 days is ~1 hour: the reference's own "this data is stale, do not quote a
-- number" threshold (its comment at ref-lua l.415).
if arg4 < 0 or arg5 < 0 or arg5 > 0.042 then
statusText = gs("GM_TICKET_UNAVAILABLE") -- l.2023
elseif estimatedWaitTime > 7200 then
statusText = gs("GM_TICKET_HIGH_VOLUME") -- l.2021
elseif estimatedWaitTime > 300 then
statusText = format(gs("GM_TICKET_WAIT_TIME", "%s"),
SecondsToTime(estimatedWaitTime, 1)) -- l.2024
-- Only this leg arms the live countdown below.
HelpFrameOpenTicket.ticketTimer = estimatedWaitTime
else
statusText = gs("GM_TICKET_SERVICE_SOON") -- l.2022
end
end
if statusText then
TicketStatusTime:Show()
TicketStatusTime:SetText(statusText)
TicketStatusFrame:SetHeight(TicketStatusTitleText:GetHeight()
+ TicketStatusTime:GetHeight() + 20)
end
HelpFrameOpenTicket.hasTicket = 1
HelpFrameOpenTicketSubmit:SetText(gs("EDIT_TICKET")) -- l.965
HelpFrameOpenTicketCancel:SetText(gs("EXIT")) -- l.1933
HelpFrameOpenTicketLabel:SetText(gs("HELPFRAME_OPENTICKET_EDITTEXT")) -- l.2216
else
-- No open ticket. On the wire the server answers a no-ticket
-- CMSG_GMTICKET_GETTICKET with a status-only body and the app fires UPDATE_TICKET
-- with a single arg1 = 0 — this leg is what puts the form back to SUBMIT/CANCEL,
-- so it is load-bearing, not defensive.
HelpFrameOpenTicketText:SetText("")
HelpFrameOpenTicket.hasTicket = nil
HelpFrameOpenTicketSubmit:SetText(gs("SUBMIT")) -- l.4211
HelpFrameOpenTicketCancel:SetText(gs("CANCEL")) -- l.465
HelpFrameOpenTicketLabel:SetText(gs("HELPFRAME_OPENTICKET_TEXT")) -- l.2217
end
end
-- ref-lua l.478-486. Edit vs create is the only difference, and both close the window.
function HelpFrameOpenTicketSubmit_OnClick()
if HelpFrameOpenTicket.hasTicket then
UpdateGMTicket(HelpFrameOpenTicket.ticketType, HelpFrameOpenTicketText:GetText())
else
NewGMTicket(HelpFrameOpenTicket.ticketType, HelpFrameOpenTicketText:GetText())
end
HideUIPanel(HelpFrame)
end
-- ── The toast (ref-lua l.488-501) ──────────────────────────────────────────────────────
-- Entering the world asks for the ticket; every UPDATE_TICKET after that shows or hides the
-- toast, and the temporary-enchant column steps down out of its way. The -175 restore is
-- BuffFrame's own declared anchor, not the reference's -180 (header, 4).
function TicketStatusFrame_OnEvent(frame)
if event == "PLAYER_ENTERING_WORLD" then
GetGMTicket()
elseif arg1 ~= 0 then
frame:Show()
if TemporaryEnchantFrame then
TemporaryEnchantFrame:SetPoint("TOPRIGHT", "UIParent", "TOPRIGHT", -205,
-frame:GetHeight())
end
refreshTime = GMTICKET_CHECK_INTERVAL
else
frame:Hide()
if TemporaryEnchantFrame then
TemporaryEnchantFrame:SetPoint("TOPRIGHT", "UIParent", "TOPRIGHT", -175, -13)
end
end
end
-- ref-lua l.544-561. Two independent timers on one tick: a 10-minute re-poll of the server,
-- and the local countdown of the estimate it last gave us. Runs only while the toast is up.
function TicketStatus_OnUpdate(elapsed)
if HelpFrameOpenTicket.hasTicket then
if refreshTime then
refreshTime = refreshTime - elapsed
if refreshTime <= 0 then
refreshTime = GMTICKET_CHECK_INTERVAL
GetGMTicket()
end
end
if HelpFrameOpenTicket.ticketTimer then
HelpFrameOpenTicket.ticketTimer = HelpFrameOpenTicket.ticketTimer - elapsed
TicketStatusTime:SetText(format(gs("GM_TICKET_WAIT_TIME", "%s"),
SecondsToTime(HelpFrameOpenTicket.ticketTimer, 1)))
end
end
end
-- The toast's click. The reference writes this body TWICE — TicketStatusButton's OnClick
-- (ref-xml l.1485-1496) and the frame's own OnMouseUp (ref-xml l.1513-1524) are character
-- for character identical, because the 32px icon does not cover the whole 208px toast.
-- One function, wired from both.
function TicketStatus_OnClick()
if TicketStatusFrame.hasGMSurvey then
-- The survey branch (header, 1): the reference opens GMSurveyFrame and hides the
-- toast. Deferred, and deliberately not stubbed into "hide the toast" — that would
-- silently eat a survey the player agreed to take.
return
elseif StaticPopup_Visible("HELP_TICKET_ABANDON_CONFIRM")
or StaticPopup_Visible("HELP_TICKET") then
StaticPopup_Hide("HELP_TICKET_ABANDON_CONFIRM")
StaticPopup_Hide("HELP_TICKET")
elseif not HelpFrame:IsVisible() then
StaticPopup_Show("HELP_TICKET")
end
end
-- ── The GM category list (ref-lua l.503-534) ───────────────────────────────────────────
function HelpFrameButton_OnClick(button)
HelpFrame_ShowFrame(button.key, button.ticketType)
end
function HelpFrameGM_Update()
HelpFrameGM_UpdateCategories(GetGMTicketCategories())
end
-- The vararg is a FLAT id/name list, so row i reads the pair at 2*(offset+i)-1. Lua-5.0
-- `arg.n`/`arg[i]` written the 5.1 way (header, 6).
function HelpFrameGM_UpdateCategories(...)
local n = select("#", ...)
local offset = FauxScrollFrame_GetOffset(HelpFrameGMScrollFrame)
for i = 1, NUM_GM_CATEGORIES_TO_DISPLAY do
getglobal("HelpFrameButton" .. i):Hide()
end
for i = 1, NUM_GM_CATEGORIES_TO_DISPLAY do
local index = 2 * (offset + i) - 1
local button = getglobal("HelpFrameButton" .. i)
local text = getglobal("HelpFrameButton" .. i .. "Text")
if index <= n then
-- Both reads are pinned to ONE value: `select(i, ...)` returns the whole tail,
-- and as the last argument of a call that tail would expand.
local id = select(index, ...)
local name = select(index + 1, ...)
text:SetText(name)
-- key AND ticketType are the same DBC id: one picks the page, the other rides
-- the wire (this file's header).
button.key = id
button.ticketType = id
button:Show()
else
button:Hide()
end
end
-- n/2 categories, 37px a row. With the ten DBC rows against ten displayed this leaves
-- the bar (and its trough) hidden, which is the reference's look too.
FauxScrollFrame_Update(HelpFrameGMScrollFrame, n / 2, NUM_GM_CATEGORIES_TO_DISPLAY, 37)
end
-- ref-lua l.536-542. A configured override (only Stuck has one) or the default route into
-- the ticket editor.
function HelpFrameGeneralButton_OnClick(button)
if button.onClick then
button.onClick()
else
HelpFrame_ShowFrame("OpenTicket")
end
end
-- The eight harassment tips. Done here rather than in eight XML `<OnLoad>` bodies because
-- gs() is this chunk's local — an XML script body is a separate chunk and cannot see it.
function HelpFrameHarassment_OnLoad()
local tips = {
VerbalAbuseTip1 = "VERBAL_HARASSMENT_TEXT2", -- GlobalStrings l.4460
VerbalAbuseTip2 = "VERBAL_HARASSMENT_TEXT3", -- l.4461
VerbalAbuseTip3 = "VERBAL_HARASSMENT_TEXT4", -- l.4463
PhysicalAbuseTip1 = "PHYSICAL_HARASSMENT_TEXT2", -- l.3066
PhysicalAbuseTip2 = "PHYSICAL_HARASSMENT_TEXT3", -- l.3063
PhysicalAbuseTip3 = "PHYSICAL_HARASSMENT_TEXT4", -- l.3065
PhysicalAbuseTip4 = "PHYSICAL_HARASSMENT_TEXT5", -- l.3064
PhysicalAbuseTip5 = "PHYSICAL_HARASSMENT_TEXT6", -- l.3068
}
for name, key in pairs(tips) do
local label = getglobal(name .. "Text")
if label then
label:SetText(gs(key))
end
end
end
-- ── The three ticket dialogs ───────────────────────────────────────────────────────────
-- Registered HERE, not in UiPanels.xml, and that is this house's rule rather than a
-- preference: only the generic DELETE_ITEM lives with the engine; every other entry ships
-- with the window that raises it (BinderConfirm, MailFrame, AuctionFrame, BankFrame,
-- PetActionBar, …). All three of these are raised from this file and from nowhere else —
-- HELP_TICKET_QUEUE_DISABLED by HelpFrame_OnEvent and HelpFrame_ShowFrame, HELP_TICKET by
-- the toast's click, HELP_TICKET_ABANDON_CONFIRM by HELP_TICKET's own Cancel.
--
-- Note the nesting: HELP_TICKET's Cancel shows ABANDON_CONFIRM *before* the click's own
-- hide, so a second dialog instance must be free. STATICPOPUP_NUMDIALOGS is 2 and this is
-- the second flow (after decline-a-res) that needs both.
-- StaticPopup.lua l.163-168.
StaticPopupDialogs["HELP_TICKET_QUEUE_DISABLED"] = {
text = gs("HELP_TICKET_QUEUE_DISABLED"), -- GlobalStrings l.2270
button1 = gs("OKAY"), -- l.2818
showAlert = 1,
timeout = 0,
}
-- StaticPopup.lua l.331-343.
StaticPopupDialogs["HELP_TICKET_ABANDON_CONFIRM"] = {
text = gs("HELP_TICKET_ABANDON_CONFIRM"), -- l.2267
button1 = gs("YES"), -- l.5463
button2 = gs("NO"), -- l.2794
OnAccept = function()
DeleteGMTicket()
end,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
}
-- StaticPopup.lua l.344-364. No hideOnEscape, by the reference's own omission: the choice
-- is Edit or Abandon, and ESC is neither. The way out is the ticket icon (TicketStatus_OnClick).
StaticPopupDialogs["HELP_TICKET"] = {
text = gs("HELP_TICKET_EDIT_ABANDON"), -- l.2269
button1 = gs("HELP_TICKET_EDIT"), -- l.2268
button2 = gs("HELP_TICKET_ABANDON"), -- l.2266
OnAccept = function()
if PETITION_QUEUE_ACTIVE then
ShowUIPanel(HelpFrame)
HelpFrame_ShowFrame("OpenTicket")
else
HideUIPanel(HelpFrame)
StaticPopup_Show("HELP_TICKET_QUEUE_DISABLED")
end
end,
-- The reference stashes the raising frame on the new dialog and never reads it back
-- (header, 5).
OnCancel = function()
StaticPopup_Show("HELP_TICKET_ABANDON_CONFIRM")
end,
timeout = 0,
whileDead = 1,
}
]]></Script>
<!-- ── The four templates (ref-xml l.4-126, geometry verbatim) ──────────────────────────────
A bullet row: the quest window's bullet glyph with a 548-wide wrapping label beside it.
550x12 is the ROW's declared size and is smaller than the label's — the label overflows it
downward, which is what lets a two-line bullet still chain from the next one's TOPLEFT
anchor at the reference's own -3/-5 spacings. -->
<Frame name="HelpFrameBulletPointTemplate" virtual="true">
<Size><AbsDimension x="550" y="12"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture file="Interface\QuestFrame\UI-Quest-BulletPoint">
<Size><AbsDimension x="16" y="16"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Texture>
<FontString name="$parentText" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size><AbsDimension x="548" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="17" y="-3"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
<!-- The horizontal rule (ref-xml l.38-77): one 256x64 sheet cut into three bands stacked in v
(0..0.3125 left cap, 0.3125..0.625 middle, 0.625..0.9375 right cap) and laid end to end.
The middle's +1 y-offset is the reference's own. -->
<Frame name="HelpFrameDividerTemplate" virtual="true">
<Size><AbsDimension x="577" y="19"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentLeft" file="Interface\HelpFrame\HelpFrameDivider">
<Size><AbsDimension x="256" y="20"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<TexCoords left="0" right="1.0" top="0" bottom="0.3125"/>
</Texture>
<Texture name="$parentMiddle" file="Interface\HelpFrame\HelpFrameDivider">
<Size><AbsDimension x="256" y="20"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"><Offset><AbsDimension x="0" y="1"/></Offset></Anchor>
</Anchors>
<TexCoords left="0" right="1.0" top="0.3125" bottom="0.625"/>
</Texture>
<Texture name="$parentRight" file="Interface\HelpFrame\HelpFrameDivider">
<Size><AbsDimension x="65" y="20"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentMiddle" relativePoint="RIGHT"/>
</Anchors>
<TexCoords left="0" right="0.25390625" top="0.625" bottom="0.9375"/>
</Texture>
</Layer>
</Layers>
</Frame>
<!-- A list row (ref-xml l.78-119): bullet glyph, a bold label and a small description under it,
with the HelpFrame highlight sheet cropped to its top 0.578125 as the hover. No scripts —
the GM variant below adds the only click this template has. -->
<Button name="HelpFrameHomeButtonTemplate" virtual="true">
<Size><AbsDimension x="568" y="37"/></Size>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentText" inherits="GameFontNormal">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="22" y="-4"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentDescription" inherits="GameFontHighlightSmall">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor>
</Anchors>
</FontString>
<Texture file="Interface\QuestFrame\UI-Quest-BulletPoint">
<Size><AbsDimension x="16" y="16"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
</Texture>
</Layer>
</Layers>
<HighlightTexture file="Interface\HelpFrame\HelpFrameButton-Highlight" alphaMode="ADD">
<TexCoords left="0" right="1.0" top="0" bottom="0.578125"/>
</HighlightTexture>
</Button>
<!-- ref-xml l.120-126. `$parentDescription` is never filled on this variant: the GM list's rows
carry only the DBC category name, which HelpFrameGM_UpdateCategories writes into
`$parentText`. That blank second line is the reference's own look. -->
<Button name="GMCategoryButtonTemplate" inherits="HelpFrameHomeButtonTemplate" virtual="true">
<Scripts>
<OnClick>HelpFrameButton_OnClick(self)</OnClick>
</Scripts>
</Button>
<!-- ── The window (ref-xml l.127-1409) ─────────────────────────────────────────────────────
640x512 of six plate pieces (four 256x256 quadrant/edge tiles and two 128-wide right-hand
caps), the shared dialog header band, and six full-bleed pages that take turns. The
`<HitRectInsets>` keeps the right 44px and bottom 13px of the plate out of the mouse rect —
the art bleeds past the drawn frame there.
`parent="UIParent"` is the reference's and is kept verbatim (ItemTextFrame.xml's
precedent); it is inert in this engine, which has no cross-file parent attachment and
screen-parents a bare toplevel anyway. `movable` is the reference's too and is equally
inert: this window declares no drag scripts, so it never actually moves. -->
<Frame name="HelpFrame" toplevel="true" parent="UIParent" movable="true" enableMouse="true" hidden="true">
<Size><AbsDimension x="640" y="512"/></Size>
<Anchors><Anchor point="CENTER"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
<HitRectInsets><AbsInset left="0" right="44" top="0" bottom="13"/></HitRectInsets>
<Layers>
<Layer level="BACKGROUND">
<Texture file="Interface\HelpFrame\HelpFrame-TopLeft">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
</Texture>
<Texture file="Interface\HelpFrame\HelpFrame-Top">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="256" y="0"/></Offset></Anchor></Anchors>
</Texture>
<Texture file="Interface\HelpFrame\HelpFrame-TopRight">
<Size><AbsDimension x="128" y="256"/></Size>
<Anchors><Anchor point="TOPRIGHT"/></Anchors>
</Texture>
<Texture file="Interface\HelpFrame\HelpFrame-BotLeft">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="BOTTOMLEFT"/></Anchors>
</Texture>
<Texture file="Interface\HelpFrame\HelpFrame-Bottom">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="256" y="0"/></Offset></Anchor></Anchors>
</Texture>
<Texture file="Interface\HelpFrame\HelpFrame-BotRight">
<Size><AbsDimension x="128" y="256"/></Size>
<Anchors><Anchor point="BOTTOMRIGHT"/></Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<Texture name="HelpFrameHeader" file="Interface\DialogFrame\UI-DialogBox-Header">
<Size><AbsDimension x="336" y="64"/></Size>
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="-12" y="12"/></Offset></Anchor></Anchors>
</Texture>
<FontString inherits="GameFontNormal" text="HELP_FRAME_TITLE">
<Anchors>
<Anchor point="TOP" relativeTo="HelpFrameHeader"><Offset><AbsDimension x="0" y="-14"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="HelpFrameCloseButton" inherits="UIPanelCloseButton">
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-42" y="-3"/></Offset></Anchor></Anchors>
</Button>
<!-- ── Page 1 · Home (ref-xml l.236-397) ─────────────────────────────────────────────
The "what a GM can and cannot help with" preamble. Every page is `setAllPoints` +
`hidden`, and HelpFrame_ShowFrame swaps exactly one of them in. -->
<Frame name="HelpFrameHome" setAllPoints="true" hidden="true">
<Layers>
<Layer level="ARTWORK">
<FontString name="HelpFrameHomeTitle" inherits="GameFontNormalLarge" text="PETITION_GAME_MASTER" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="25" y="-65"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="HelpFrameHomeText1" inherits="GameFontHighlight" text="HELPFRAME_HOME_TEXT1" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeTitle" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue1Header" inherits="GameFontNormal" text="HELPFRAME_HOME_ISSUE1_HEADER" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeText1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="10" y="-10"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue1" inherits="GameFontHighlightSmall" text="HELPFRAME_HOME_ISSUE1" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeIssue1Header" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue2Header" inherits="GameFontNormal" text="HELPFRAME_HOME_ISSUE2_HEADER" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeIssue1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue2" inherits="GameFontHighlightSmall" text="HELPFRAME_HOME_ISSUE2" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeIssue2Header" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue3Header" inherits="GameFontNormal" text="HELPFRAME_HOME_ISSUE3_HEADER" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeIssue2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeIssue3" inherits="GameFontHighlightSmall" text="HELPFRAME_HOME_ISSUE3" justifyH="LEFT">
<Size><AbsDimension x="540" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomeIssue3Header" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
<!-- The PvP policy link. The declared height of **-5** is the reference's
own (ref-xml l.337) and is kept verbatim, because it is not inert: the
client's `CSimpleFontString::GetHeight 0x772a60` takes the authored
value whenever it is not exactly 0.0 and only then floors it at one
FrameXML unit (wow-re `region-size-fallback.md` §3, which this engine
implements identically — layout.rs's FONTSTRING_MIN_SPAN). So this line's
BOX is one unit tall in the real client too, and HelpFrameHomeText2
below — which hangs off that box's BOTTOMLEFT at -25 — rides up over the
link. Correcting it here would be a divergence, not a fix. -->
<FontString name="HelpFrameHomePvpPolicyUrl" inherits="GameFontNormal" text="PVP_POLICY_URL">
<Size><AbsDimension x="550" y="-5"/></Size>
<Anchors>
<Anchor point="TOP" relativeTo="HelpFrameHomeIssue3" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameHomeText2" inherits="GameFontHighlight" text="HELPFRAME_HOME_TEXT2" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHomePvpPolicyUrl" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-25"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- ref-xml l.362-381. The reference fits this button to its label in the
button's own OnLoad; ours does it from the page's OnShow (header, 3). -->
<Button name="HelpFrameHomeIssues" inherits="UIPanelButtonTemplate2" text="HELPFRAME_HOME_BUTTON_TEXT">
<Size><AbsDimension x="250" y="22"/></Size>
<Anchors>
<Anchor point="TOP" relativeTo="HelpFrameHomeText2" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-40"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("GMHome")</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameHomeCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HideUIPanel(HelpFrame)</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnShow>HelpFrameButton_FitToText(HelpFrameHomeIssues)</OnShow>
</Scripts>
</Frame>
<!-- ── Page 2 · Page a GM (ref-xml l.399-603) ────────────────────────────────────────
The ten category rows over the faux scroll kit. Ten rows against ten DBC categories
means the bar and its trough stay hidden (FauxScrollFrame_Update's own gate), which
is the reference's look as well. -->
<Frame name="HelpFrameGM" setAllPoints="true" hidden="true">
<Layers>
<Layer level="BACKGROUND">
<FontString inherits="GameFontHighlightSmall" text="HELPFRAME_HOME_TEXT">
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-60"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="HelpFrameButton1" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="-80"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton2" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton3" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton4" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton3" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton5" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton4" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton6" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton5" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton7" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton6" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton8" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton7" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton9" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton8" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<Button name="HelpFrameButton10" inherits="GMCategoryButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameButton9" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Button>
<!-- The bar's TROUGH, replacing the reference's three loose textures
(ref-xml l.517-560). No anchors of its own: it seats itself on its bar the
first time BenillaScrollBar_SetShown touches it, at the very hang those
reference offsets define. Declared BEFORE the faux frame so it draws
beneath the bar. -->
<Frame name="HelpFrameGMScrollFrameScrollBarTrough" inherits="BenillaScrollTroughTemplate"/>
<!-- ref-xml l.504-568: 540x410 at the page's TOPRIGHT(-80,-54). A plain
`<Frame>` on the house faux kit, so the reference's `<OnVerticalScroll>`
(`FauxScrollFrame_OnVerticalScroll(37, HelpFrameGM_Update)`) has nothing to
fire and becomes `updateFunc` instead (header, 1). The instance's OnLoad
REPLACES the template's, so ScrollFrame_OnLoad is re-issued here. -->
<Frame name="HelpFrameGMScrollFrame" inherits="FauxScrollFrameTemplate">
<Size><AbsDimension x="540" y="410"/></Size>
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-80" y="-54"/></Offset></Anchor></Anchors>
<Scripts>
<OnLoad>
ScrollFrame_OnLoad()
self.updateFunc = HelpFrameGM_Update
</OnLoad>
</Scripts>
</Frame>
<Button name="HelpFrameGMCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HideUIPanel(HelpFrame)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameGMBack" inherits="GameMenuButtonTemplate" text="BACK">
<Anchors>
<Anchor point="RIGHT" relativeTo="HelpFrameGMCancel" relativePoint="LEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("Home")</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnShow>HelpFrameGM_Update()</OnShow>
</Scripts>
</Frame>
<!-- ── Page 3 · The ticket editor (ref-xml l.605-753) ────────────────────────────────
`letters="500"` is the reference's own cap and is kept verbatim; note the client
engine separately truncates the outgoing description to 1999 characters before the
packet leaves, so the box's limit is the tighter of the two and the engine cap sits
behind it unreached. -->
<Frame name="HelpFrameOpenTicket" setAllPoints="true" hidden="true">
<Layers>
<Layer level="BACKGROUND">
<FontString name="HelpFrameOpenTicketLabel" inherits="GameFontHighlight" text="HELPFRAME_OPENTICKET_TEXT">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="25" y="-58"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="HelpFrameOpenTicketDivider" inherits="HelpFrameDividerTemplate">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="12" y="-72"/></Offset></Anchor></Anchors>
</Frame>
<!-- This bar is on a REAL scroll frame, so it is always up and
BenillaScrollBar_SetShown — the only thing that seats a trough — never runs
for it. Seated explicitly below through the kit's own public seat verb
(header, 2), replacing the reference's three loose textures at
ref-xml l.642-685. -->
<Frame name="HelpFrameOpenTicketScrollFrameScrollBarTrough" inherits="BenillaScrollTroughTemplate"/>
<ScrollFrame name="HelpFrameOpenTicketScrollFrame" inherits="UIPanelScrollFrameTemplate">
<Size><AbsDimension x="540" y="378"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameOpenTicketDivider" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="8" y="4"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnLoad>
ScrollFrame_OnLoad()
local trough = getglobal(self:GetName() .. "ScrollBarTrough")
BenillaScrollTrough_Seat(trough, getglobal(self:GetName() .. "ScrollBar"))
trough:Show()
</OnLoad>
</Scripts>
<ScrollChild>
<!-- ref-xml l.689-708. 541 wide inside a 540 view, which is the
reference's own arithmetic. The `<OnUpdate>ScrollingEdit_OnUpdate()`
the reference wires here is deliberately absent (header, 3).
No `autoFocus` attribute, exactly as the reference declares none —
but the consequence differs: the UI.xsd defaults it TRUE, while
this engine applies the C++ ctor default (flags=0, off) uniformly
to XML and CreateFrame alike (loader/widgets.rs l.278-281). So the
reference's box takes the keyboard the moment the page shows and
ours waits for a click. That is an engine-wide policy, not this
window's choice, and restating it as `autoFocus="false"` here would
only hide it. -->
<EditBox name="HelpFrameOpenTicketText" multiLine="true" letters="500">
<Size><AbsDimension x="541" y="357"/></Size>
<Scripts>
<OnTextChanged>ScrollingEdit_OnTextChanged()</OnTextChanged>
<OnCursorChanged>ScrollingEdit_OnCursorChanged(arg1, arg2, arg3, arg4)</OnCursorChanged>
<OnEscapePressed>HideUIPanel(HelpFrame)</OnEscapePressed>
</Scripts>
<FontString inherits="ChatFontNormal"/>
</EditBox>
</ScrollChild>
</ScrollFrame>
<!-- Cancel re-asks the server for the ticket before closing: the box may hold
edits that were never submitted, and the next open must show what the
SERVER has, not what was typed (ref-xml l.720-723). -->
<Button name="HelpFrameOpenTicketCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>
GetGMTicket()
HideUIPanel(HelpFrame)
</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameOpenTicketSubmit" inherits="GameMenuButtonTemplate" text="SUBMIT">
<Anchors>
<Anchor point="RIGHT" relativeTo="HelpFrameOpenTicketCancel" relativePoint="LEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrameOpenTicketSubmit_OnClick()</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnLoad>
self:RegisterEvent("UPDATE_TICKET")
self:RegisterEvent("GMSURVEY_DISPLAY")
</OnLoad>
<OnEvent>HelpFrameOpenTicket_OnEvent(event)</OnEvent>
<!-- The reference's `<OnShow>` body is its own commented-out
`HelpFrameOpenTicketDropDown_OnShow()` (ref-xml l.750) — the dead dropdown
(header, 2). Nothing replaces it: the editor is filled by UPDATE_TICKET,
which the Cancel path above and TicketStatusFrame's world-entry poll both
provoke. -->
</Scripts>
</Frame>
<!-- ── Page 4 · The shared general page (ref-xml l.755-980) ──────────────────────────
Nine of the ten categories land here; HelpFrame_SetupGeneralFrame re-dresses and
re-anchors everything below before the page is shown. BulletTitle2 and EndText
declare a bare TOPLEFT (0,0) because that anchor is always replaced in Lua. -->
<Frame name="HelpFrameGeneral" setAllPoints="true" hidden="true">
<Layers>
<Layer level="ARTWORK">
<FontString name="HelpFrameGeneralTitle" inherits="GameFontNormalLarge" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="25" y="-65"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="HelpFrameGeneralTitleText" inherits="GameFontHighlight" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralTitle" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor>
</Anchors>
</FontString>
<!-- Declared on the same anchor as its sibling above (ref-xml l.782-793) and
re-seated in Lua when a category actually uses it. None does today. -->
<FontString name="HelpFrameGeneralTitleText2" inherits="GameFontHighlight" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralTitle" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameBulletTitle1" inherits="GameFontNormal" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="HelpFrameBulletTitle2" inherits="GameFontNormal" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="HelpFrameEndText" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="HelpFrameGeneralBullet1" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameBulletTitle1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="5" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet2" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet3" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet4" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet3" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet5" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet4" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet6" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet5" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet7" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet6" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet8" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet7" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet9" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet8" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<Frame name="HelpFrameGeneralBullet10" inherits="HelpFrameBulletPointTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="HelpFrameGeneralBullet9" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
</Frame>
<!-- Both action buttons declare the same throwaway TOP (0,15); the setup
function seats them under whatever the page ended up with. -->
<Button name="HelpFrameGeneralButton" inherits="UIPanelButtonTemplate2">
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="15"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HelpFrameGeneralButton_OnClick(self)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameGeneralButton2" inherits="UIPanelButtonTemplate2">
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="15"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HelpFrameGeneralButton_OnClick(self)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameGeneralCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HideUIPanel(HelpFrame)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameGeneralBack" inherits="GameMenuButtonTemplate" text="BACK">
<Anchors>
<Anchor point="RIGHT" relativeTo="HelpFrameGeneralCancel" relativePoint="LEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("GMHome")</OnClick>
</Scripts>
</Button>
</Frames>
</Frame>
<!-- ── Page 5 · Harassment (ref-xml l.983-1299) ──────────────────────────────────────
The one category with a page of its own (id 2): two sections, each a heading, a
definition, a "the following are NOT" list, and its own report button. Both buttons
go to the same place. The eight tip strings are filled from Lua (this file's
HelpFrameHarassment_OnLoad) rather than from eight XML OnLoad bodies. -->
<Frame name="HelpFrameHarassment" setAllPoints="true" hidden="true">
<Layers>
<Layer level="BACKGROUND">
<FontString name="HelpFrameHarassmentText" inherits="GameFontHighlight" text="HARASSMENT_TEXT">
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-60"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="HelpFrameVerbalHarassment">
<Size><AbsDimension x="564" y="165"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="-86"/></Offset></Anchor></Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentText" inherits="GameFontNormal" text="VERBAL_HARASSMENT" justifyH="LEFT">
<Size><AbsDimension x="560" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="5" y="-5"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentDescription" inherits="GameFontHighlightSmall" text="VERBAL_HARASSMENT_DESCRIPTION" justifyH="LEFT">
<Size><AbsDimension x="560" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="$parentTipText" inherits="GameFontNormalSmall" text="VERBAL_HARASSMENT_TEXT1" justifyH="LEFT">
<Size><AbsDimension x="560" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentDescription" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-15"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="VerbalAbuseTip1" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentTipText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-3" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="VerbalAbuseTip2" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="VerbalAbuseTip1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="VerbalAbuseTip3" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="VerbalAbuseTip2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Button name="HelpFrameVerbalHarassmentButton" inherits="UIPanelButtonTemplate2" text="REPORT_VERBAL_HARASSMENT">
<Size><AbsDimension x="200" y="22"/></Size>
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="15"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("OpenTicket")</OnClick>
</Scripts>
</Button>
</Frames>
</Frame>
<Frame name="HelpFrameHarassmentDivider2" inherits="HelpFrameDividerTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameVerbalHarassment" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-9" y="13"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="HelpFramePhysicalHarassment">
<Size><AbsDimension x="568" y="220"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameHarassmentDivider2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="9" y="5"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentText" inherits="GameFontNormal" text="PHYSICAL_HARASSMENT" justifyH="LEFT">
<Size><AbsDimension x="564" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="5" y="-5"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentDescription" inherits="GameFontHighlightSmall" text="PHYSICAL_HARASSMENT_DESCRIPTION" justifyH="LEFT">
<Size><AbsDimension x="564" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor>
</Anchors>
</FontString>
<FontString name="$parentTipText" inherits="GameFontNormalSmall" text="PHYSICAL_HARASSMENT_TEXT1" justifyH="LEFT">
<Size><AbsDimension x="564" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentDescription" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-15"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="PhysicalAbuseTip1" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentTipText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-3" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="PhysicalAbuseTip2" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="PhysicalAbuseTip1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="PhysicalAbuseTip3" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="PhysicalAbuseTip2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="PhysicalAbuseTip4" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="PhysicalAbuseTip3" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="PhysicalAbuseTip5" inherits="HelpFrameBulletPointTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="PhysicalAbuseTip4" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
</Anchors>
</Frame>
<Button name="HelpFramePhysicalHarassmentButton" inherits="UIPanelButtonTemplate2" text="REPORT_PHYSICAL_HARASSMENT">
<Size><AbsDimension x="200" y="22"/></Size>
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="15"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("OpenTicket")</OnClick>
</Scripts>
</Button>
</Frames>
</Frame>
<Button name="HelpFrameHarassmentCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HideUIPanel(HelpFrame)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameHarassmentBack" inherits="GameMenuButtonTemplate" text="BACK">
<Anchors>
<Anchor point="RIGHT" relativeTo="HelpFrameHarassmentCancel" relativePoint="LEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("GMHome")</OnClick>
</Scripts>
</Button>
<!-- Declared last, as the reference does (ref-xml l.1289-1297) — it anchors to
the page itself, so nothing depends on its position in the list. -->
<Frame name="HelpFrameHarassmentDivider" inherits="HelpFrameDividerTemplate">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="12" y="-70"/></Offset></Anchor></Anchors>
</Frame>
</Frames>
<Scripts>
<OnLoad>HelpFrameHarassment_OnLoad()</OnLoad>
</Scripts>
</Frame>
<!-- ── Page 6 · Stuck (ref-xml l.1301-1378) — UNREACHABLE TODAY, and that is not a bug.
Nothing anywhere passes "Stuck" to HelpFrame_ShowFrame: category id 1 is "Stuck" on
the wire and routes through HELPFRAME_FRAMES[1] to the general page, which
GENERAL_HELPFRAME[1] dresses with this same title, text and unstick button. This
page is the reference's own layout and a later HelpFrame_ShowFrame("Stuck") would
want it, so it is transcribed rather than dropped. See this file's header. -->
<Frame name="HelpFrameStuck" setAllPoints="true" hidden="true">
<Layers>
<Layer level="ARTWORK">
<FontString name="HelpFrameStuckTitle" inherits="GameFontNormalLarge" text="STUCK_OPTION" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="25" y="-65"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="HelpFrameStuckText1" inherits="GameFontHighlight" text="HELPFRAME_STUCK_TEXT1" justifyH="LEFT">
<Size><AbsDimension x="550" y="0"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HelpFrameStuckTitle" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="HelpFrameStuckStuck" inherits="UIPanelButtonTemplate2" text="STUCK_BUTTON_TEXT">
<Anchors>
<Anchor point="TOP" relativeTo="HelpFrameStuckText1" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-25"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>
Stuck()
HideUIPanel(HelpFrame)
</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameStuckCancel" inherits="GameMenuButtonTemplate" text="CANCEL">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-53" y="21"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>HideUIPanel(HelpFrame)</OnClick>
</Scripts>
</Button>
<Button name="HelpFrameStuckBack" inherits="GameMenuButtonTemplate" text="BACK">
<Anchors>
<Anchor point="RIGHT" relativeTo="HelpFrameStuckCancel" relativePoint="LEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnClick>HelpFrame_ShowFrame("GMHome")</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnShow>HelpFrameButton_FitToText(HelpFrameStuckStuck)</OnShow>
</Scripts>
</Frame>
<!-- ── Page 7 · Bug (ref-xml l.1380-1392) — UNREACHABLE, and emptier still. There is no
HELPFRAME_FRAMES "Bug" key at all, so no caller could reach it even by name; the
page is a single divider with nothing above or below it, which is what the
reference ships. Transcribed for the same reason as Stuck above. -->
<Frame name="HelpFrameBug" setAllPoints="true" hidden="true">
<Frames>
<Frame name="HelpFrameBugDivider" inherits="HelpFrameDividerTemplate">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="12" y="-223"/></Offset></Anchor></Anchors>
</Frame>
</Frames>
</Frame>
</Frames>
<Scripts>
<OnLoad>HelpFrame_OnLoad(self)</OnLoad>
<OnShow>HelpFrame_OnShow(self)</OnShow>
<OnEvent>HelpFrame_OnEvent()</OnEvent>
<OnHide>
PlaySound("igCharacterInfoClose")
if UpdateMicroButtons then UpdateMicroButtons() end
</OnHide>
</Scripts>
</Frame>
<!-- ── The ticket toast (ref-xml l.1410-1526) ───────────────────────────────────────────────
A tooltip-skinned 208x52 panel in the top-right corner with the open-ticket icon, shown
whenever the player has a ticket outstanding and clickable anywhere on its surface. Its
height is rewritten from the text it ends up holding (HelpFrameOpenTicket_OnEvent).
`movable` is the reference's and is inert for the same reason as the window's. -->
<Frame name="TicketStatusFrame" toplevel="true" parent="UIParent" movable="true" enableMouse="true" hidden="true">
<Size><AbsDimension x="208" y="52"/></Size>
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-180" y="0"/></Offset></Anchor></Anchors>
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize><AbsValue val="16"/></EdgeSize>
<TileSize><AbsValue val="16"/></TileSize>
<BackgroundInsets><AbsInset left="5" right="5" top="5" bottom="5"/></BackgroundInsets>
</Backdrop>
<Layers>
<Layer level="ARTWORK">
<FontString name="TicketStatusTitleText" inherits="GameFontNormalSmall" justifyH="LEFT">
<Size x="168" y="0"/>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-8"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="TicketStatusTime" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size x="168" y="0"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="TicketStatusTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="TicketStatusButton">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-3" y="0"/></Offset></Anchor></Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture file="Interface\HelpFrame\OpenTicketIcon">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnClick>TicketStatus_OnClick()</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<!-- The tooltip skin's colours, guarded the way this house guards every cross-file
global reached at load (GameTooltip.xml loads far above in the toc; harness tests
load subsets). -->
<OnLoad>
if TOOLTIP_DEFAULT_COLOR then
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
end
if TOOLTIP_DEFAULT_BACKGROUND_COLOR then
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
end
self:RegisterEvent("UPDATE_TICKET")
self:RegisterEvent("PLAYER_ENTERING_WORLD")
</OnLoad>
<OnEvent>TicketStatusFrame_OnEvent(self)</OnEvent>
<OnUpdate>TicketStatus_OnUpdate(arg1)</OnUpdate>
<!-- The reference repeats the button's whole click body here because the 32px icon does
not cover the 208px toast (ref-xml l.1513-1524, character-identical to l.1485-1496).
One shared function instead. -->
<OnMouseUp>TicketStatus_OnClick()</OnMouseUp>
</Scripts>
</Frame>
</Ui>