- the social window's third tab is live — the roster in both its views, the member card with its promote/demote/remove verbs, the rank editor's thirteen permissions, the guild information board, and the invite, leave, kick and note dialogs behind them - setting your hearthstone at an innkeeper now asks before it takes and says so afterwards, and the innkeeper's gossip lines get their own icons back - unavailable talents grey out, and every greyed icon in the client now goes through the same luminance fold the original used - the buff tooltip's remaining-time line reads gold with the client's own hour/minute ladder, the macro editor takes a shift-click to paste a spell, trainer rows repaint after a purchase, and a long book page stops flickering its ellipsis Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1249 lines
84 KiB
XML
1249 lines
84 KiB
XML
<Ui>
|
|
<!--
|
|
benilla's talent window (decision 0304 §4, "The talent window" — same-session sibling of the
|
|
engine seam in `benilla-ui/src/script/talent.rs`): the 384x512 book chassis + the class-art
|
|
4-corner backdrop + the 3 tree tabs + the scrolled 8-tier x 4-column talent grid with its
|
|
prereq branch/arrow lines, dressed from the real 1.12 **load-on-demand addon**
|
|
`Blizzard_TalentUI.xml`/`.lua`/`Blizzard_TalentUITemplates.xml` — extracted from the MPQ
|
|
chain to `WoW/_extracted_addons/Blizzard_TalentUI/` in this worktree (line cites below are
|
|
into those three files directly).
|
|
|
|
Docks the left UIPanel slot exactly like Character/SpellBook/Gossip/Merchant/Quest/QuestLog
|
|
(`UiPanels.xml`'s `UIPanelWindows["BenillaTalentFrame"] = { area = "left", pushable = 6 }`,
|
|
the ref's own `pushable = 6` — one tier above the plain NPC-session windows' `0`, matching the
|
|
ref's row exactly) — so it competes for/replaces those windows, never stacks with them.
|
|
`ToggleTalentFrame()` (ref `TalentFrame_Toggle`, Blizzard_TalentUI.lua:73-79, RENAMED — see
|
|
below) is the show/hide entry point; the app's 'N' binding already calls it by this exact name
|
|
(`ui_script/input.rs:198-201`, landed ahead of this file per decision 0304's own pin).
|
|
|
|
ONE deliberate naming deviation from the ref, applied consistently: every frame this file
|
|
defines is Benilla-prefixed (`BenillaTalentFrame`, `BenillaTalentFrameTalent1`, …) — the same
|
|
posture every other window in this codebase already takes. Layered on top of that, `Toggle-
|
|
TalentFrame` (not the ref's own `TalentFrame_Toggle`) matches this codebase's established
|
|
`Toggle<Thing>` shape for a window's addon-facing entry point (`ToggleSpellBook`/
|
|
`ToggleCharacter`/`ToggleQuestLog` — SpellBookFrame.xml's header comment makes the identical
|
|
choice for the identical reason) — kept BARE, not Benilla-prefixed, matching that precedent.
|
|
|
|
SCOPE CALL — 3 tabs, not 5. The ref's own `MAX_TALENT_TABS = 5` is defensive headroom; 1.12
|
|
vanilla ships EXACTLY 3 talent trees for every class with no exception (Warrior Arms/Fury/
|
|
Protection, Mage Arcane/Fire/Frost, …, an unchanging 1.12 game-design fact, not a guess). This
|
|
file declares exactly 3 static tab buttons and renumbers the constant `BENILLA_MAX_TALENT_TABS
|
|
= 3` (Benilla-prefixed, not bare `MAX_TALENT_TABS`, since its VALUE differs from the ref's own
|
|
— a reader must not assume it still means 5). `BenillaTalentFrame_Update` additionally clamps
|
|
`PanelTemplates_SetNumTabs`'s own argument to this cap (`min(numTabs, BENILLA_MAX_TALENT_TABS)`
|
|
— a small defensive addition beyond the ref, which trusts its own 5 static tabs always
|
|
suffice): without it, a hypothetical `GetNumTalentTabs() > 3` would ask `PanelTemplates_
|
|
UpdateTabs` to index a `BenillaTalentFrameTab4` that doesn't exist and error. 1.12 data never
|
|
exceeds 3 (comment above) — the clamp just makes that assumption SAFE rather than merely
|
|
"safe by data luck", the honest version of the same trust the ref's own 5-tab headroom
|
|
expresses for ITS OWN assumption.
|
|
|
|
TAB STRIP — reuses the house's EXISTING tab kit, not a hand-rolled `BenillaTalentFrame.
|
|
selectedTab` variable. The task brief's own ENGINE API note flagged `PanelTemplates_*` as
|
|
unavailable ("implement your own small select/deselect Lua") — verified false this session:
|
|
`UiPanels.xml:502-578` already provides the FULL kit (`PanelTemplates_SetNumTabs/_SetTab/
|
|
_GetSelectedTab/_UpdateTabs/_SelectTab/_DeselectTab/_TabResize`), and `CharacterFrameTab-
|
|
ButtonTemplate` (`UiPanels.xml:603-654`) is ALREADY battle-tested by CharacterFrame.xml's own
|
|
tab. Better still: the REFERENCE's own `TalentTabTemplate` (Blizzard_TalentUITemplates.xml:3)
|
|
itself `inherits="CharacterFrameTabButtonTemplate"` — the exact same base template. Reusing
|
|
both here is therefore not a shortcut but the MORE faithful, MORE DRY choice: identical art,
|
|
identical selected/deselected mechanics, one less parallel implementation to maintain. Only
|
|
`TalentTabTemplate`'s OWN additions get a local sub-template (`BenillaTalentTabTemplate`
|
|
below): the OnClick + OnLeave (its `PLAYER_LEVEL_UP` level-9 pulse-flash OnLoad/OnEvent is
|
|
OMITTED — see Sounds/OMITs below). `TalentFrame.selectedTab` (read directly by the reference's
|
|
own `TalentButtonTemplate` inline OnEnter, Blizzard_TalentUITemplates.xml:92) and
|
|
`PanelTemplates_GetSelectedTab(TalentFrame)` (read by TalentFrame.lua's own functions) are
|
|
THE SAME FIELD — `PanelTemplates_SetTab` stores straight onto `frame.selectedTab` — so this
|
|
file spells each call site exactly as the reference itself does, not a benilla-
|
|
introduced inconsistency.
|
|
|
|
SCROLL DESIGN — a real ScrollFrame with a FIXED-HEIGHT child, not the reference's own dynamic
|
|
`UIPanelScrollFrameTemplate` (which auto-grows its child via a C-side `UpdateScrollChildRect`
|
|
this engine has no equivalent for — QuestLogFrame.xml's own documented gap: "the resolver
|
|
never grows a frame to fit content that overflows it"). The grid this window scrolls is
|
|
UNLIKE QuestLogFrame's variable quest-text pane: it is always EXACTLY 8 tiers of absolutely-
|
|
positioned buttons/branches/arrows, never resized by content — so instead of QuestLogFrame's
|
|
per-frame convergence loop (`_ResizeChild`/`_OnUpdate`, needed there because its text height is
|
|
data-dependent), the scroll child here is simply sized to a CONSTANT
|
|
`BENILLA_TALENT_SCROLL_CHILD_H = 504` (8 tiers x the ref's own 63px pitch — the task's own
|
|
sizing note): `INITIAL_TALENT_OFFSET_Y(20) + 7*63 + TALENT_BUTTON_SIZE(32) = 493 < 504`
|
|
covers even the lowest tier's own button with 11px to spare, and no branch/arrow ever paints
|
|
BELOW its own tier's row (verified against `BenillaTalentFrame_DrawLines` below: a talent's
|
|
`.down`/arrows only ever touch tiers at or above its own). No `UpdateScrollChildRect` call is
|
|
therefore needed anywhere (dropped from the ref's own per-tier-loop tail) — the range is a
|
|
load-time constant, not something to re-derive every Update.
|
|
|
|
The scrollbar reuses `BenillaScrollBarTemplate` (the real, DRAGGABLE `Slider`, decision 0250,
|
|
`ScrollTemplates.xml`) directly — NOT QuestLogFrame.xml's own hand-rolled "visual only, no
|
|
drag" bar. That file's header comment explicitly says "this engine has no Slider widget"; that
|
|
claim is now STALE (the Slider primitive landed after, decision 0250) — reusing the
|
|
since-real thing here is a rebase onto a landed primitive, not a fidelity regression. The
|
|
Slider's OWN `OnValueChanged` (inherited from `BenillaScrollBarTemplate`, wired to the FAUX
|
|
offset bookkeeping `BenillaFauxScrollBar_OnValueChanged`) is REPLACED (not chained past) by
|
|
this file's own override below — verified, not assumed: `apply_scripts`
|
|
(`benilla-ui/src/loader/scripts.rs`) walks EVERY `<Scripts>` block found after `inherits=`
|
|
merge and calls `SetScript` for each handler in order; `merge()` (`framexml.rs`) appends the
|
|
base template's children before the instance's own, so the base's `<Scripts>` registers first
|
|
and this file's own registers LAST — `SetScript` is a single-slot assignment, so the last
|
|
registration wins outright. `BenillaScrollBar_UpdateArrows`/`_Step` (ScrollTemplates.xml)
|
|
are reused as-is: both read only a Slider's own value/range/step, nothing faux-specific.
|
|
|
|
Named deferrals/OMITs (each re-cited at its own site below):
|
|
- `SetButtonPulse` (ref `TalentFrame_OnShow`/`_OnHide`/`TalentFrameTab_OnClick`'s
|
|
pulse-clear loop, and `TalentTabTemplate`'s own `PLAYER_LEVEL_UP` level-9 flash-hint
|
|
OnLoad/OnEvent): decision 0304's own Scope-calls section, "No microbutton pulse — the
|
|
reference pulses TalentMicroButton on point gain". The microbar itself has since landed
|
|
(`MicroMenu.xml`) and `UpdateMicroButtons()` is live in OnShow/OnHide below — but the
|
|
PULSE stays out: it rides `PLAYER_LEVEL_UP`, which this client never fires. All four
|
|
pulse sites drop cleanly (none gate anything else).
|
|
- `message(...)` (5 sites: the `numTalents > MAX_NUM_TALENTS` reminder, `_GetArrowTexture`/
|
|
`_GetBranchTexture`'s pool-exhaustion notices, and 3 sites in `_DrawLines`'s own layout-
|
|
blocked guards): no engine `message()` global exists (grepped `crates/benilla-ui/src`;
|
|
GossipFrame.xml's own "too many quests" message() is the same-shaped, already-accepted
|
|
OMIT in this codebase). Every site is a defensive diagnostic for a data bug 1.12's own
|
|
authored `Talent.dbc` never produces (no tree exceeds 20 talents/tab, no tree is laid out
|
|
blocked) — dropped outright, control flow (the `return`s / nil-propagation) kept intact.
|
|
The two texture-pool getters additionally gain a nil-guard at their TWO call sites
|
|
(`_SetArrowTexture`/`_SetBranchTexture`) beyond the reference's own behavior (which lets
|
|
its dropped `message()` call's nil flow straight into a `:SetTexCoord` crash) — a small,
|
|
documented safety margin now that the diagnostic is gone, not a behavior change for any
|
|
reachable (≤30 branches/arrows) input.
|
|
- `UIPanelCloseButton`/`UIPanelButtonTemplate`/`ItemButtonTemplate` (ref base templates):
|
|
none ship in this house dialect. The close button uses the house minimize-button art
|
|
(SpellBookFrame/CharacterFrame's own precedent); the bottom "Close" button locally
|
|
reconstructs `UIPanelButtonTemplate`'s art (`UI-Panel-Button-*`, StackSplit.xml's own
|
|
precedent for the identical gap); the talent button locally reconstructs exactly what
|
|
`ItemButtonTemplate` (`WoW/_extracted_framexml/ItemButtonTemplate.xml`, read this session)
|
|
contributes (37x37, the Quickslot2 ring, the icon Texture child) plus `TalentButtonTemplate`
|
|
(Blizzard_TalentUITemplates.xml)'s own additions (the EmptySlot backdrop, RankBorder, Rank
|
|
text) — CharacterFrame.xml's own `BenillaPaperDollItemSlotTemplate` is the identical-shape
|
|
precedent for this whole reconstruction move.
|
|
- `SetItemButtonTexture`: no engine equivalent (ENGINE API note). The icon Texture child
|
|
(`$parentIconTexture`) is `SetTexture`'d directly.
|
|
- `SetItemButtonDesaturated` IS the ref's own verb here (ItemButtonTemplate.xml, loaded far
|
|
above this file in the .toc), called exactly as the ref calls it. It used to be open-coded
|
|
as `SetVertexColor(0.65, 0.65, 0.65)` / restored to `(1, 1, 1)`, because the engine had no
|
|
desaturation and a dim tint was the whole of what a grey-out could be. Decision 1327 gave
|
|
the engine `Texture:SetDesaturated`, so the ref's verb now lands as greyscale AND the 0.65
|
|
dim — B162: at 0 talent points every unlearned icon in the real client goes greyscale, and
|
|
a 0.65 multiply on colourful art does not read as greyed out at all.
|
|
|
|
Engine-gap notes (transcribed anyway per this file's own instructions, or worked around):
|
|
- `text=` XML attributes are a LITERAL, verbatim `SetText` in this engine — verified,
|
|
`benilla-ui/src/loader/regions.rs:222-223` and `loader/widgets.rs:153-154` both pass the
|
|
attribute string straight through, no GlobalStrings lookup. The ref's own `text="TALENTS"`/
|
|
`text="CHARACTER_POINTS1_COLON"` (both static — neither FontString is EVER touched by
|
|
TalentFrame.lua, confirmed by reading the whole file this session) therefore become the
|
|
literal, properly-cased resolved strings ("Talents" / "Talent Points:") directly in this
|
|
file's XML, CharacterFrame.xml's own `text="Armor:"` precedent for exactly this class of
|
|
static label (its `ARMOR_COLON` Lua declaration exists for tooltip composition elsewhere,
|
|
never for driving that XML attribute). `TALENTS`/`CHARACTER_POINTS1_COLON` are still
|
|
declared below via the `X = X or "…"` idiom for citation/provenance only (unread by any
|
|
Lua in this file) — their exact wording is this session's best-known value for the real
|
|
1.12 GlobalStrings entry, NOT re-verified against a live extraction (none is present in
|
|
this worktree this session; `MASTERY_POINTS_SPENT`'s wording+line came from the task brief
|
|
itself and IS load-bearing, since it's genuinely `format()`-composed at runtime below).
|
|
- `HitRectInsets`: transcribed for fidelity; no loader wiring exists yet (CharacterFrame.
|
|
xml's own precedent note) — a harmless no-op today.
|
|
- `UNIT_PORTRAIT_UPDATE`: registered per the ref (`TalentFrame_OnLoad`); this engine never
|
|
fires it (grepped `crates/benilla-ui/src`, `crates/benilla/src`) — forward-compatible,
|
|
harmless, the same "transcribe the hook even if nothing drives it yet" posture as
|
|
HitRectInsets above.
|
|
- Bare `min`/`max`/`select` (used unqualified in `_DrawLines`/`_SetPrereqs` below): CONFIRMED
|
|
available — `min`/`max` are house-stdlib aliases for `math.min`/`math.max`
|
|
(`benilla-ui/src/script/stdlib.rs`), `select` is stock Lua 5.1. The ref's own `arg`/`arg.n`
|
|
Lua-5.0 vararg table (`_SetPrereqs`) is written the 5.1-native way
|
|
(WorldMapFrame.xml's own identical note) — replaced with `select("#", ...)`/
|
|
`select(i, ...)` over a trailing `...`, WorldMapFrame.xml's own precedent for the identical
|
|
substitution.
|
|
- `GetTalentTabInfo` called TWICE in a row by the ref's own `TalentFrame_Update` (l.152-154:
|
|
once truncated to just its first return for the `talentTabName` truthiness check, then
|
|
again for the full tuple — a real redundancy in the reference's own code, not a
|
|
byte-meaningful pattern) collapses to the ONE call already shared by both uses,
|
|
SpellBookFrame.xml's own `ToggleSpellBook` precedent for this exact class of cleanup
|
|
("a redundant-code cleanup, not a behavior change").
|
|
|
|
Sounds (decision 0090, cited verified this session per the task brief): `TalentScreenOpen`/
|
|
`TalentScreenClose` on Show/Hide (ids 6144/6145, ref `TalentFrame_OnShow`/`_OnHide`),
|
|
`igCharacterInfoTab` on tab click (id 841, ref `TalentFrameTab_OnClick`).
|
|
-->
|
|
<Script><![CDATA[
|
|
-- ── GlobalStrings values this window cites (ref-GlobalStrings.lua) — TALENTS/CHARACTER_
|
|
-- POINTS1_COLON are provenance-only (this file's header comment: their FontStrings are
|
|
-- static XML text, never Lua-read); MASTERY_POINTS_SPENT IS genuinely format()-composed
|
|
-- below and its wording+line are the task brief's own (GlobalStrings:2674). ────────────────
|
|
TALENTS = TALENTS or "Talents"
|
|
CHARACTER_POINTS1_COLON = CHARACTER_POINTS1_COLON or "Talent Points:"
|
|
MASTERY_POINTS_SPENT = MASTERY_POINTS_SPENT or "Points spent in %s Talents:" -- :2674
|
|
|
|
-- ── This window's own constants ─────────────────────────────────────────────────────────
|
|
--
|
|
-- Spec: ref Blizzard_TalentUI.lua:2-11. The NAMES and VALUES are the contract — a tree's
|
|
-- data is laid out against them and addons read them — so those are the reference's; the
|
|
-- grouping is ours, by what each one is for rather than by the order they happen to appear.
|
|
|
|
-- The tree's shape: eight rows of four cells, never more than twenty talents in one tree.
|
|
MAX_NUM_TALENT_TIERS = 8
|
|
NUM_TALENT_COLUMNS = 4
|
|
MAX_NUM_TALENTS = 20
|
|
|
|
-- Where that shape lands inside the scroll child: the first cell sits INITIAL_TALENT_
|
|
-- OFFSET_X/Y in from its top-left corner and every next one is a PITCH further along.
|
|
-- TALENT_BUTTON_SIZE is how far the connector art reaches out of a cell, NOT the talent
|
|
-- button's own 37px size — the two are independent (this file's header comment, "The
|
|
-- talent button"). Naming the pitch is what let the two places that used to spell out
|
|
-- `((n - 1) * 63) + INITIAL_TALENT_OFFSET_…` — the button placement and the connector draw
|
|
-- — collapse into the one `talentCellOrigin` below, so they cannot drift apart.
|
|
INITIAL_TALENT_OFFSET_X = 35
|
|
INITIAL_TALENT_OFFSET_Y = 20
|
|
TALENT_BUTTON_SIZE = 32
|
|
BENILLA_TALENT_GRID_PITCH = 63
|
|
|
|
-- The connector art comes out of two fixed pools, claimed in order by each repaint and
|
|
-- hidden again past the last one claimed (BenillaTalentFrame_Get*Texture below).
|
|
MAX_NUM_BRANCH_TEXTURES = 30
|
|
MAX_NUM_ARROW_TEXTURES = 30
|
|
|
|
-- One drawing-state cell per grid position — built once in OnLoad, cleared (never rebuilt)
|
|
-- by every repaint. What a cell records is written down at `clearBranchCell` below.
|
|
TALENT_BRANCH_ARRAY = {}
|
|
|
|
-- Benilla-prefixed + renumbered (5 -> 3): this file's header comment, "SCOPE CALL".
|
|
BENILLA_MAX_TALENT_TABS = 3
|
|
-- The scroll child's fixed height: this file's header comment, "SCROLL DESIGN".
|
|
BENILLA_TALENT_SCROLL_CHILD_H = 504
|
|
BENILLA_TALENT_SCROLL_FRAME_H = 332 -- the ref's own TalentFrameScrollFrame height (ref l.278)
|
|
BENILLA_TALENT_SCROLL_MAX = BENILLA_TALENT_SCROLL_CHILD_H - BENILLA_TALENT_SCROLL_FRAME_H
|
|
BENILLA_TALENT_SCROLL_STEP = 20 -- one wheel notch / arrow-click step (QuestLogFrame.xml's
|
|
-- own BENILLA_QUESTLOG_SCROLL_STEP precedent for a real
|
|
-- ScrollFrame's per-notch pixel step)
|
|
|
|
-- ── The branch/arrow atlases: CUT from the sheet, not typed out ─────────────────────────
|
|
--
|
|
-- Spec: the same two tables the reference builds (ref Blizzard_TalentUI.lua:13-69) — same
|
|
-- global names, same [direction][+1/-1] shape, same quads to the bit. Written our own way,
|
|
-- because what these are is not 104 fractions: both sheets are ONE STRIP of 32px cells
|
|
-- with the lit variant on the top row and the greyed variant directly beneath it, so a
|
|
-- direction is fully described by three facts — which cell carries its art, whether it is
|
|
-- drawn u-reversed, and how tall the drawn part of a row is. Those facts are the spec
|
|
-- below and the loop under them cuts the quads, which is both shorter and legible: the
|
|
-- strip's layout is visible in the source instead of implied by the numbers.
|
|
--
|
|
-- The grid is MEASURED, not inferred from the fractions — both BLPs pulled out of the
|
|
-- live patch chain this session (`mpqx <Data> 'Interface\TalentFrame\UI-Talent*.blp'`,
|
|
-- dimensions off the BLP2 header):
|
|
-- UI-TalentBranches 256 x 64 — seven 32px cells on a 33px pitch (x = 0, 33, 66, …)
|
|
-- UI-TalentArrows 64 x 64 — two 32px cells, butted, no gutter
|
|
-- Every edge is therefore n/256 or n/64 — exact binary fractions, so the divides below are
|
|
-- exact in doubles and these quads are bit-identical to the ones the reference lists.
|
|
--
|
|
-- Three things in the data that look like mistakes and are the sheet's own:
|
|
-- · `left` and `right` are the SAME quad. There is one piece of horizontal branch art;
|
|
-- which side of the button it lands on is the draw loop's doing (xOffset -/+
|
|
-- TALENT_BUTTON_SIZE in _Update below), not the sheet's.
|
|
-- · the corner pieces are drawn in ONE handedness — `topleft`/`bottomleft` are
|
|
-- `topright`/`bottomright` with u reversed (SetTexCoord reads left > right as a
|
|
-- mirror), which is how one drawing serves both.
|
|
-- · the two VERTICAL pieces take a 31px row, leaving a 2px gutter across the sheet's
|
|
-- middle, where every other cell takes the flat 32. The greyed row stays the lit
|
|
-- row's reflection through the midline either way — one `rowH` drives both.
|
|
local function talentSheetQuads(sheetW, sheetH, cellW, pitch, spec)
|
|
local quads = {}
|
|
for name, cell in pairs(spec) do
|
|
local u0, u1 = cell[1] * pitch / sheetW, (cell[1] * pitch + cellW) / sheetW
|
|
if cell.flip then u0, u1 = u1, u0 end
|
|
local v = (cell.rowH or cellW) / sheetH
|
|
quads[name] = { [1] = { u0, u1, 0, v }, [-1] = { u0, u1, 1 - v, 1.0 } }
|
|
end
|
|
return quads
|
|
end
|
|
|
|
-- Which cell serves which direction (the reference's own key names, which is where the
|
|
-- reading of each cell's art comes from): 0 `down`, 1 `up`, 2 the horizontal run, 3 the
|
|
-- bottom corners, 4 the top corners, 5 the T pointing down, 6 the T pointing up.
|
|
TALENT_BRANCH_TEXTURECOORDS = talentSheetQuads(256, 64, 32, 33, {
|
|
down = { 0, rowH = 31 },
|
|
up = { 1, rowH = 31 },
|
|
left = { 2 },
|
|
right = { 2 },
|
|
bottomright = { 3 },
|
|
bottomleft = { 3, flip = true },
|
|
topright = { 4 },
|
|
topleft = { 4, flip = true },
|
|
tdown = { 5 },
|
|
tup = { 6 },
|
|
})
|
|
|
|
-- cell 0 is the arrow that points up the column; cell 1 is the sideways one, mirrored for
|
|
-- the other hand.
|
|
TALENT_ARROW_TEXTURECOORDS = talentSheetQuads(64, 64, 32, 32, {
|
|
top = { 0 },
|
|
left = { 1 },
|
|
right = { 1, flip = true },
|
|
})
|
|
|
|
-- ── The branch grid ─────────────────────────────────────────────────────────────────────
|
|
--
|
|
-- A cell of TALENT_BRANCH_ARRAY holds the talent that occupies its grid position (`id`),
|
|
-- and the drawing state of the connector art passing THROUGH that position: four half-
|
|
-- branches (`up`/`down`/`left`/`right`, each the piece of a segment on this cell's side of
|
|
-- the join) and three arrowheads. Every one of those is either 0 — nothing drawn here — or
|
|
-- the ±1 that the draw pass indexes TALENT_BRANCH_TEXTURECOORDS/TALENT_ARROW_TEXTURECOORDS
|
|
-- by: +1 the lit art, -1 the greyed. That is the whole reason a met and an unmet prereq are
|
|
-- one code path in two colours rather than two code paths.
|
|
--
|
|
-- Clearing rather than rebuilding keeps the 32 cells allocated exactly once (OnLoad), and
|
|
-- puts their field set in ONE place instead of two that can drift apart.
|
|
local function clearBranchCell(cell)
|
|
cell.id = nil
|
|
cell.up, cell.down, cell.left, cell.right = 0, 0, 0, 0
|
|
cell.topArrow, cell.leftArrow, cell.rightArrow = 0, 0, 0
|
|
return cell
|
|
end
|
|
|
|
-- A grid cell's top-left corner inside the scroll child. The talent button seats exactly on
|
|
-- it; the connector art seats at the reference's own 2px inset from it (+2 x, -2 y).
|
|
local function talentCellOrigin(tier, column)
|
|
return (column - 1) * BENILLA_TALENT_GRID_PITCH + INITIAL_TALENT_OFFSET_X,
|
|
-((tier - 1) * BENILLA_TALENT_GRID_PITCH) - INITIAL_TALENT_OFFSET_Y
|
|
end
|
|
|
|
-- ── The window: toggle (ref TalentFrame_Toggle, l.73-79) ────────────────────────────────
|
|
-- Renamed ToggleTalentFrame — this file's header comment, "ONE deliberate naming deviation".
|
|
-- Kept BARE (not Benilla-prefixed) — the addon-facing entry point; the 'N' keybinding
|
|
-- already calls this by name (ui_script/input.rs).
|
|
function ToggleTalentFrame()
|
|
if BenillaTalentFrame:IsVisible() then
|
|
HideUIPanel(BenillaTalentFrame)
|
|
else
|
|
ShowUIPanel(BenillaTalentFrame)
|
|
end
|
|
end
|
|
|
|
-- ref TalentFrame_OnLoad (l.81-93).
|
|
function BenillaTalentFrame_OnLoad(frame)
|
|
PanelTemplates_SetNumTabs(frame, BENILLA_MAX_TALENT_TABS)
|
|
PanelTemplates_SetTab(frame, 1)
|
|
frame:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
|
frame:RegisterEvent("SPELLS_CHANGED")
|
|
-- UNIT_PORTRAIT_UPDATE: this file's header comment (engine-gap notes) — never fired
|
|
-- today, registered anyway for ref fidelity/forward-compat.
|
|
frame:RegisterEvent("UNIT_PORTRAIT_UPDATE")
|
|
-- The grid's one allocation: every repaint clears these same cells in place.
|
|
for i = 1, MAX_NUM_TALENT_TIERS do
|
|
TALENT_BRANCH_ARRAY[i] = {}
|
|
for j = 1, NUM_TALENT_COLUMNS do
|
|
TALENT_BRANCH_ARRAY[i][j] = clearBranchCell({})
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ref TalentFrame_OnShow (l.95-103): SetButtonPulse still OMITTED (decision 0304's own "No
|
|
-- microbutton pulse" scope call — the pulse rides PLAYER_LEVEL_UP, which this client never
|
|
-- fires). UpdateMicroButtons is LIVE as of the micro-menu slice (MicroMenu.xml).
|
|
function BenillaTalentFrame_OnShow()
|
|
if UpdateMicroButtons then UpdateMicroButtons() end
|
|
PlaySound("TalentScreenOpen")
|
|
BenillaTalentFrame_Update()
|
|
end
|
|
|
|
-- ref TalentFrame_OnHide (l.105-108).
|
|
function BenillaTalentFrame_OnHide()
|
|
if UpdateMicroButtons then UpdateMicroButtons() end
|
|
PlaySound("TalentScreenClose")
|
|
end
|
|
|
|
-- ref TalentFrame_OnEvent (l.110-118) — no IsVisible() guard: followed exactly as THIS
|
|
-- reference does it (it refreshes even while hidden; a different window guarding its own
|
|
-- OnEvent, e.g. SpellBookFrame, is that window's own choice, not borrowed here).
|
|
function BenillaTalentFrame_OnEvent(frame)
|
|
if event == "CHARACTER_POINTS_CHANGED" or event == "SPELLS_CHANGED" then
|
|
BenillaTalentFrame_Update()
|
|
elseif event == "UNIT_PORTRAIT_UPDATE" then
|
|
if arg1 == "player" then
|
|
SetPortraitTexture(getglobal("BenillaTalentFramePortrait"), "player")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ref TalentFrameTalent_OnEvent (Blizzard_TalentUITemplates.xml:120-124) — the hovered
|
|
-- button's own CHARACTER_POINTS_CHANGED re-poll. GameTooltip:IsOwned VERIFIED present
|
|
-- (`benilla-ui/src/script/tooltip/verbs.rs:107`), used as-is (not an emulation).
|
|
function BenillaTalentButton_OnEvent(button)
|
|
if GameTooltip:IsOwned(button) then
|
|
GameTooltip:SetTalent(PanelTemplates_GetSelectedTab(BenillaTalentFrame), button:GetID())
|
|
end
|
|
end
|
|
|
|
-- ref TalentFrame_Update (l.126-321) — the big one. See this file's header comment for the
|
|
-- SetItemButtonTexture/SetItemButtonDesaturated substitution, the message() drops, and the
|
|
-- GetTalentTabInfo double-call collapse.
|
|
function BenillaTalentFrame_Update()
|
|
-- Setup Tabs
|
|
local tab, name, iconTexture, pointsSpent, button
|
|
local numTabs = GetNumTalentTabs()
|
|
for i = 1, BENILLA_MAX_TALENT_TABS do
|
|
tab = getglobal("BenillaTalentFrameTab" .. i)
|
|
if i <= numTabs then
|
|
name, iconTexture, pointsSpent = GetTalentTabInfo(i)
|
|
if i == PanelTemplates_GetSelectedTab(BenillaTalentFrame) then
|
|
-- If tab is the selected tab set the points spent info
|
|
getglobal("BenillaTalentFrameSpentPoints"):SetText(
|
|
format(MASTERY_POINTS_SPENT, name) .. " " ..
|
|
HIGHLIGHT_FONT_COLOR_CODE .. pointsSpent .. FONT_COLOR_CODE_CLOSE)
|
|
BenillaTalentFrame.pointsSpent = pointsSpent
|
|
end
|
|
tab:SetText(name)
|
|
PanelTemplates_TabResize(10, tab)
|
|
tab:Show()
|
|
else
|
|
tab:Hide()
|
|
end
|
|
end
|
|
-- Defensive clamp beyond the ref: this file's header comment ("SCOPE CALL").
|
|
PanelTemplates_SetNumTabs(BenillaTalentFrame, min(numTabs, BENILLA_MAX_TALENT_TABS))
|
|
PanelTemplates_UpdateTabs(BenillaTalentFrame)
|
|
|
|
-- Setup Frame
|
|
SetPortraitTexture(getglobal("BenillaTalentFramePortrait"), "player")
|
|
BenillaTalentFrame_UpdateTalentPoints()
|
|
local selectedTab = PanelTemplates_GetSelectedTab(BenillaTalentFrame)
|
|
-- ref l.152-154's own double GetTalentTabInfo call collapses to one — this file's
|
|
-- header comment ("GetTalentTabInfo called TWICE").
|
|
local talentTabName, texture, points, fileName = GetTalentTabInfo(selectedTab)
|
|
local base
|
|
if talentTabName then
|
|
base = "Interface\\TalentFrame\\" .. fileName .. "-"
|
|
else
|
|
-- temporary default for classes without talents poor guys (ref's own comment)
|
|
base = "Interface\\TalentFrame\\MageFire-"
|
|
end
|
|
|
|
getglobal("BenillaTalentFrameBackgroundTopLeft"):SetTexture(base .. "TopLeft")
|
|
getglobal("BenillaTalentFrameBackgroundTopRight"):SetTexture(base .. "TopRight")
|
|
getglobal("BenillaTalentFrameBackgroundBottomLeft"):SetTexture(base .. "BottomLeft")
|
|
getglobal("BenillaTalentFrameBackgroundBottomRight"):SetTexture(base .. "BottomRight")
|
|
|
|
local numTalents = GetNumTalents(selectedTab)
|
|
-- ref's own "Too many talents in talent frame!" message() DROPPED — this file's header
|
|
-- comment (no engine message() global; a defensive diagnostic 1.12 data never trips).
|
|
|
|
BenillaTalentFrame_ResetBranches()
|
|
local tier, column, rank, maxRank, isExceptional, meetsPrereq
|
|
local forceDesaturated, tierUnlocked
|
|
for i = 1, MAX_NUM_TALENTS do
|
|
button = getglobal("BenillaTalentFrameTalent" .. i)
|
|
if i <= numTalents then
|
|
-- Set the button info
|
|
name, iconTexture, tier, column, rank, maxRank, isExceptional, meetsPrereq =
|
|
GetTalentInfo(selectedTab, i)
|
|
local buttonName = "BenillaTalentFrameTalent" .. i
|
|
getglobal(buttonName .. "Rank"):SetText(rank)
|
|
BenillaSetTalentButtonLocation(button, tier, column)
|
|
TALENT_BRANCH_ARRAY[tier][column].id = button:GetID()
|
|
|
|
-- If player has no talent points then show only talents with points in them
|
|
if BenillaTalentFrame.talentPoints <= 0 and rank == 0 then
|
|
forceDesaturated = 1
|
|
else
|
|
forceDesaturated = nil
|
|
end
|
|
|
|
-- If the player has spent at least 5 talent points in the previous tier
|
|
if (tier - 1) * 5 <= BenillaTalentFrame.pointsSpent then
|
|
tierUnlocked = 1
|
|
else
|
|
tierUnlocked = nil
|
|
end
|
|
|
|
-- SetItemButtonTexture(button, iconTexture): this file's header comment (ENGINE
|
|
-- API note) — set the icon Texture child directly. A nil texture (shouldn't
|
|
-- happen once fed, ui_talent.rs's own Talent.dbc x Spell.dbc join) leaves
|
|
-- whatever was last shown rather than erroring on a nil SetTexture.
|
|
if iconTexture then
|
|
getglobal(buttonName .. "IconTexture"):SetTexture(iconTexture)
|
|
end
|
|
|
|
-- Talent must meet prereqs or the player must have no points to spend
|
|
if BenillaTalentFrame_SetPrereqs(tier, column, forceDesaturated, tierUnlocked,
|
|
GetTalentPrereqs(selectedTab, i)) and meetsPrereq then
|
|
SetItemButtonDesaturated(button, nil)
|
|
|
|
if rank < maxRank then
|
|
-- Rank is green if not maxed out
|
|
getglobal(buttonName .. "Slot"):SetVertexColor(0.1, 1.0, 0.1)
|
|
getglobal(buttonName .. "Rank"):SetTextColor(
|
|
GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b)
|
|
else
|
|
getglobal(buttonName .. "Slot"):SetVertexColor(1.0, 0.82, 0)
|
|
getglobal(buttonName .. "Rank"):SetTextColor(
|
|
NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
|
end
|
|
getglobal(buttonName .. "RankBorder"):Show()
|
|
getglobal(buttonName .. "Rank"):Show()
|
|
else
|
|
SetItemButtonDesaturated(button, 1, 0.65, 0.65, 0.65)
|
|
getglobal(buttonName .. "Slot"):SetVertexColor(0.5, 0.5, 0.5)
|
|
if rank == 0 then
|
|
getglobal(buttonName .. "RankBorder"):Hide()
|
|
getglobal(buttonName .. "Rank"):Hide()
|
|
else
|
|
getglobal(buttonName .. "RankBorder"):SetVertexColor(0.5, 0.5, 0.5)
|
|
getglobal(buttonName .. "Rank"):SetTextColor(
|
|
GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b)
|
|
end
|
|
end
|
|
|
|
button:Show()
|
|
else
|
|
button:Hide()
|
|
end
|
|
end
|
|
|
|
-- Now paint the routes the pass above marked onto the grid (spec: ref l.232-320): walk
|
|
-- every cell in order, claim a pooled texture for each piece of art it asks for, and
|
|
-- hide whatever is left of the pools at the end. UpdateScrollChildRect() is DROPPED
|
|
-- from the tier loop's tail — this file's header comment ("SCROLL DESIGN": a fixed-
|
|
-- height child never needs its range re-derived).
|
|
--
|
|
-- `ignoreUp` deliberately survives from one cell to the NEXT: an empty cell carrying a
|
|
-- straight vertical through it draws its own `down` piece one row lower, so the cell
|
|
-- below must not draw the `up` piece again on top of it.
|
|
local node
|
|
local xOffset, yOffset
|
|
local ignoreUp
|
|
local tempNode
|
|
BenillaTalentFrame_ResetBranchTextureCount()
|
|
BenillaTalentFrame_ResetArrowTextureCount()
|
|
for i = 1, MAX_NUM_TALENT_TIERS do
|
|
for j = 1, NUM_TALENT_COLUMNS do
|
|
node = TALENT_BRANCH_ARRAY[i][j]
|
|
-- The cell's own corner, then the connector art's inset inside it.
|
|
xOffset, yOffset = talentCellOrigin(i, j)
|
|
xOffset, yOffset = xOffset + 2, yOffset - 2
|
|
|
|
if node.id then
|
|
-- Has talent
|
|
if node.up ~= 0 then
|
|
if not ignoreUp then
|
|
BenillaTalentFrame_SetBranchTexture(i, j,
|
|
TALENT_BRANCH_TEXTURECOORDS["up"][node.up], xOffset, yOffset + TALENT_BUTTON_SIZE)
|
|
else
|
|
ignoreUp = nil
|
|
end
|
|
end
|
|
if node.down ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j,
|
|
TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset, yOffset - TALENT_BUTTON_SIZE + 1)
|
|
end
|
|
if node.left ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j,
|
|
TALENT_BRANCH_TEXTURECOORDS["left"][node.left], xOffset - TALENT_BUTTON_SIZE, yOffset)
|
|
end
|
|
if node.right ~= 0 then
|
|
-- See if any connecting branches are gray and if so color them gray
|
|
tempNode = TALENT_BRANCH_ARRAY[i][j + 1]
|
|
if tempNode.left ~= 0 and tempNode.down < 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j - 1,
|
|
TALENT_BRANCH_TEXTURECOORDS["right"][tempNode.down], xOffset + TALENT_BUTTON_SIZE, yOffset)
|
|
else
|
|
BenillaTalentFrame_SetBranchTexture(i, j,
|
|
TALENT_BRANCH_TEXTURECOORDS["right"][node.right], xOffset + TALENT_BUTTON_SIZE + 1, yOffset)
|
|
end
|
|
end
|
|
-- Draw arrows
|
|
if node.rightArrow ~= 0 then
|
|
BenillaTalentFrame_SetArrowTexture(i, j,
|
|
TALENT_ARROW_TEXTURECOORDS["right"][node.rightArrow], xOffset + TALENT_BUTTON_SIZE / 2 + 5, yOffset)
|
|
end
|
|
if node.leftArrow ~= 0 then
|
|
BenillaTalentFrame_SetArrowTexture(i, j,
|
|
TALENT_ARROW_TEXTURECOORDS["left"][node.leftArrow], xOffset - TALENT_BUTTON_SIZE / 2 - 5, yOffset)
|
|
end
|
|
if node.topArrow ~= 0 then
|
|
BenillaTalentFrame_SetArrowTexture(i, j,
|
|
TALENT_ARROW_TEXTURECOORDS["top"][node.topArrow], xOffset, yOffset + TALENT_BUTTON_SIZE / 2 + 5)
|
|
end
|
|
else
|
|
-- Doesn't have a talent
|
|
if node.up ~= 0 and node.left ~= 0 and node.right ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["tup"][node.up], xOffset, yOffset)
|
|
elseif node.down ~= 0 and node.left ~= 0 and node.right ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["tdown"][node.down], xOffset, yOffset)
|
|
elseif node.left ~= 0 and node.down ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["topright"][node.left], xOffset, yOffset)
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset, yOffset - 32)
|
|
elseif node.left ~= 0 and node.up ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["bottomright"][node.left], xOffset, yOffset)
|
|
elseif node.left ~= 0 and node.right ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["right"][node.right], xOffset + TALENT_BUTTON_SIZE, yOffset)
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["left"][node.left], xOffset + 1, yOffset)
|
|
elseif node.right ~= 0 and node.down ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["topleft"][node.right], xOffset, yOffset)
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset, yOffset - 32)
|
|
elseif node.right ~= 0 and node.up ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["bottomleft"][node.right], xOffset, yOffset)
|
|
elseif node.up ~= 0 and node.down ~= 0 then
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["up"][node.up], xOffset, yOffset)
|
|
BenillaTalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset, yOffset - 32)
|
|
ignoreUp = 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Hide any unused branch textures
|
|
for i = BenillaTalentFrame_GetBranchTextureCount(), MAX_NUM_BRANCH_TEXTURES do
|
|
getglobal("BenillaTalentFrameBranch" .. i):Hide()
|
|
end
|
|
-- Hide any unused arrow textures
|
|
for i = BenillaTalentFrame_GetArrowTextureCount(), MAX_NUM_ARROW_TEXTURES do
|
|
getglobal("BenillaTalentFrameArrow" .. i):Hide()
|
|
end
|
|
end
|
|
|
|
function BenillaTalentFrame_SetArrowTexture(tier, column, texCoords, xOffset, yOffset)
|
|
local arrowTexture = BenillaTalentFrame_GetArrowTexture()
|
|
-- nil-guard beyond the ref: this file's header comment (message() drop).
|
|
if not arrowTexture then return end
|
|
arrowTexture:SetTexCoord(texCoords[1], texCoords[2], texCoords[3], texCoords[4])
|
|
arrowTexture:SetPoint("TOPLEFT", "BenillaTalentFrameScrollChild", "TOPLEFT", xOffset, yOffset)
|
|
end
|
|
|
|
function BenillaTalentFrame_SetBranchTexture(tier, column, texCoords, xOffset, yOffset)
|
|
local branchTexture = BenillaTalentFrame_GetBranchTexture()
|
|
if not branchTexture then return end
|
|
branchTexture:SetTexCoord(texCoords[1], texCoords[2], texCoords[3], texCoords[4])
|
|
branchTexture:SetPoint("TOPLEFT", "BenillaTalentFrameScrollChild", "TOPLEFT", xOffset, yOffset)
|
|
end
|
|
|
|
-- ref TalentFrame_GetArrowTexture (l.335-344): message() DROPPED (this file's header
|
|
-- comment) — the exhaustion path otherwise matches the ref's own (nil past the 30th; both
|
|
-- callers above now guard it, unlike the ref's own dropped-message-then-crash shape).
|
|
function BenillaTalentFrame_GetArrowTexture()
|
|
local arrowTexture = getglobal("BenillaTalentFrameArrow" .. BenillaTalentFrame.arrowIndex)
|
|
BenillaTalentFrame.arrowIndex = BenillaTalentFrame.arrowIndex + 1
|
|
if arrowTexture then
|
|
arrowTexture:Show()
|
|
end
|
|
return arrowTexture
|
|
end
|
|
|
|
function BenillaTalentFrame_GetBranchTexture()
|
|
local branchTexture = getglobal("BenillaTalentFrameBranch" .. BenillaTalentFrame.textureIndex)
|
|
BenillaTalentFrame.textureIndex = BenillaTalentFrame.textureIndex + 1
|
|
if branchTexture then
|
|
branchTexture:Show()
|
|
end
|
|
return branchTexture
|
|
end
|
|
|
|
function BenillaTalentFrame_ResetArrowTextureCount()
|
|
BenillaTalentFrame.arrowIndex = 1
|
|
end
|
|
|
|
function BenillaTalentFrame_ResetBranchTextureCount()
|
|
BenillaTalentFrame.textureIndex = 1
|
|
end
|
|
|
|
function BenillaTalentFrame_GetArrowTextureCount()
|
|
return BenillaTalentFrame.arrowIndex
|
|
end
|
|
|
|
function BenillaTalentFrame_GetBranchTextureCount()
|
|
return BenillaTalentFrame.textureIndex
|
|
end
|
|
|
|
-- ref TalentFrame_SetPrereqs (l.373-395) — the Lua 5.0 `arg`/`arg.n` vararg table replaced
|
|
-- with `select` (this file's header comment, WorldMapFrame.xml's own precedent). The four
|
|
-- named leading params already consume the ref's arg[1..4]; the trailing `...` is exactly
|
|
-- the ref's arg[5..n] prereq triplets.
|
|
function BenillaTalentFrame_SetPrereqs(buttonTier, buttonColumn, forceDesaturated, tierUnlocked, ...)
|
|
local requirementsMet
|
|
if tierUnlocked and not forceDesaturated then
|
|
requirementsMet = 1
|
|
else
|
|
requirementsMet = nil
|
|
end
|
|
local n = select("#", ...)
|
|
for i = 1, n, 3 do
|
|
local tier, column, isLearnable = select(i, ...)
|
|
if not isLearnable or forceDesaturated then
|
|
requirementsMet = nil
|
|
end
|
|
BenillaTalentFrame_DrawLines(buttonTier, buttonColumn, tier, column, requirementsMet)
|
|
end
|
|
return requirementsMet
|
|
end
|
|
|
|
-- ── Routing one prereq onto the grid ────────────────────────────────────────────────────
|
|
--
|
|
-- Spec: ref TalentFrame_DrawLines (l.398-527). A route is never stored as a path; each cell
|
|
-- it crosses simply records which of its own half-branches and arrowheads the route lit,
|
|
-- and the value recorded is the route's STATE — +1 met, -1 unmet — which is the very key
|
|
-- the draw pass looks the art up by (`clearBranchCell` above).
|
|
--
|
|
-- The one rule every leg obeys: a route may not run through a cell that holds a talent of
|
|
-- its own, because the connector art would land under that button. Each leg scans its span
|
|
-- first and abandons the whole route rather than draw over one. (The reference raises a
|
|
-- `message()` at three of those points; the diagnostic is dropped and the abandonment kept
|
|
-- — this file's header comment, "message()". No 1.12 tree trips any of them.)
|
|
--
|
|
-- These five are the grid's vocabulary; the routing below is written entirely in them.
|
|
|
|
-- One link of a vertical run: the lower half of the upper cell plus the upper half of the
|
|
-- cell beneath it. Two half-branches are what make one drawn segment.
|
|
local function linkDown(tier, column, state)
|
|
TALENT_BRANCH_ARRAY[tier][column].down = state
|
|
TALENT_BRANCH_ARRAY[tier + 1][column].up = state
|
|
end
|
|
|
|
-- The same across, left cell to right cell.
|
|
local function linkRight(tier, column, state)
|
|
TALENT_BRANCH_ARRAY[tier][column].right = state
|
|
TALENT_BRANCH_ARRAY[tier][column + 1].left = state
|
|
end
|
|
|
|
-- Does a talent sit anywhere in this span of one tier / of one column? (An empty span —
|
|
-- adjacent cells with nothing between them — is trivially clear.)
|
|
local function occupiedAcross(tier, fromColumn, toColumn)
|
|
for i = fromColumn, toColumn do
|
|
if TALENT_BRANCH_ARRAY[tier][i].id then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function occupiedDown(column, fromTier, toTier)
|
|
for i = fromTier, toTier do
|
|
if TALENT_BRANCH_ARRAY[i][column].id then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- The arrowhead on the dependent talent's own cell, pointing back along the way the route
|
|
-- came in — right if the prereq lies to the right of us, left if it lies to the left.
|
|
local function pointArrowSideways(cell, buttonColumn, column, state)
|
|
if buttonColumn < column then
|
|
cell.rightArrow = state
|
|
else
|
|
cell.leftArrow = state
|
|
end
|
|
end
|
|
|
|
-- Mark the route from a prerequisite at (tier, column) to the talent that depends on it at
|
|
-- (buttonTier, buttonColumn). Called once per prereq by BenillaTalentFrame_SetPrereqs.
|
|
function BenillaTalentFrame_DrawLines(buttonTier, buttonColumn, tier, column, requirementsMet)
|
|
local state = -1
|
|
if requirementsMet then state = 1 end
|
|
-- The dependent talent's own cell: SetPrereqs' caller has already stamped its `id`, so
|
|
-- it always exists. Every branch below ends by marking an arrowhead on it.
|
|
local cell = TALENT_BRANCH_ARRAY[buttonTier][buttonColumn]
|
|
|
|
-- STRAIGHT UP THE COLUMN. One vertical run, and the last link stops half short: the
|
|
-- talent's own cell wears the arrowhead where an `up` stub would otherwise go.
|
|
if buttonColumn == column then
|
|
if occupiedDown(column, tier + 1, buttonTier - 1) then return end
|
|
for i = tier, buttonTier - 1 do
|
|
if i + 1 < buttonTier then
|
|
linkDown(i, column, state)
|
|
else
|
|
TALENT_BRANCH_ARRAY[i][column].down = state
|
|
end
|
|
end
|
|
cell.topArrow = state
|
|
return
|
|
end
|
|
|
|
-- ALONG THE TIER. One horizontal run between the two columns, arrowhead on the side
|
|
-- the prereq lies. Both halves of every join are marked, including the talent's own.
|
|
if buttonTier == tier then
|
|
local left, right = min(buttonColumn, column), max(buttonColumn, column)
|
|
if occupiedAcross(tier, left + 1, right - 1) then return end
|
|
for i = left, right - 1 do
|
|
linkRight(tier, i, state)
|
|
end
|
|
pointArrowSideways(cell, buttonColumn, column, state)
|
|
return
|
|
end
|
|
|
|
-- DIAGONAL, so the route must turn one corner, and there are two corners to choose
|
|
-- from. Preferred: run ACROSS the prereq's own tier to our column, then DOWN it. What
|
|
-- has to be clear for that is the prereq's tier from the cell NEXT to the prereq
|
|
-- through to the corner at our own column — the prereq's own cell is where the route
|
|
-- starts, so it is never in its own way.
|
|
local left, right = min(buttonColumn, column), max(buttonColumn, column)
|
|
local from, to = left, right
|
|
if left == column then from = left + 1 else to = right - 1 end
|
|
if not occupiedAcross(tier, from, to) then
|
|
-- The corner and our own cell's top half, marked outright: the loop below covers
|
|
-- both, EXCEPT when the prereq sits below us and the run is empty.
|
|
TALENT_BRANCH_ARRAY[tier][buttonColumn].down = state
|
|
cell.up = state
|
|
for i = tier, buttonTier - 1 do
|
|
linkDown(i, buttonColumn, state)
|
|
end
|
|
for i = left, right - 1 do
|
|
linkRight(tier, i, state)
|
|
end
|
|
cell.topArrow = state
|
|
return
|
|
end
|
|
|
|
-- That corner is blocked, so take the other one: DOWN the prereq's column first, then
|
|
-- across our own tier — which now has to be the clear span, from our cell to the corner.
|
|
from, to = left, right
|
|
if left == buttonColumn then from = left + 1 else to = right - 1 end
|
|
if occupiedAcross(buttonTier, from, to) then return end
|
|
-- Two reference quirks live in these three lines and BOTH are deliberately kept, because
|
|
-- they are what the real client draws: the across leg is never marked at all (the
|
|
-- reference's own two lines for it are commented out at Blizzard_TalentUI.lua:508-509),
|
|
-- and each vertical segment is attributed to the OUTER halves of its two cells rather
|
|
-- than the facing ones — the mirror image of `linkDown`, which is why that helper is not
|
|
-- used here.
|
|
for i = tier, buttonTier - 1 do
|
|
TALENT_BRANCH_ARRAY[i][column].up = state
|
|
TALENT_BRANCH_ARRAY[i + 1][column].down = state
|
|
end
|
|
pointArrowSideways(cell, buttonColumn, column, state)
|
|
end
|
|
|
|
-- ref TalentFrameTalent_OnClick (Blizzard_TalentUITemplates.xml:97-99).
|
|
function BenillaTalentButton_OnClick(button)
|
|
LearnTalent(PanelTemplates_GetSelectedTab(BenillaTalentFrame), button:GetID())
|
|
end
|
|
|
|
-- ref TalentFrameTab_OnClick (l.533-540): the SetButtonPulse-clearing loop OMITTED — this
|
|
-- file's header comment (decision 0304's own "No microbutton pulse" scope call).
|
|
function BenillaTalentFrameTab_OnClick(tab)
|
|
PanelTemplates_SetTab(BenillaTalentFrame, tab:GetID())
|
|
BenillaTalentFrame_Update()
|
|
PlaySound("igCharacterInfoTab")
|
|
end
|
|
|
|
-- ref TalentFrame_UpdateTalentPoints (l.543-547).
|
|
function BenillaTalentFrame_UpdateTalentPoints()
|
|
local cp1, cp2 = UnitCharacterPoints("player")
|
|
getglobal("BenillaTalentFrameTalentPointsText"):SetText(cp1)
|
|
BenillaTalentFrame.talentPoints = cp1
|
|
end
|
|
|
|
-- Seat a talent button on its grid cell (spec: ref SetTalentButtonLocation, l.549-553) —
|
|
-- the same corner the connector art insets from, so the two can never drift apart.
|
|
function BenillaSetTalentButtonLocation(button, tier, column)
|
|
local x, y = talentCellOrigin(tier, column)
|
|
button:SetPoint("TOPLEFT", button:GetParent(), "TOPLEFT", x, y)
|
|
end
|
|
|
|
-- Back to a blank grid before a repaint re-derives it (spec: ref TalentFrame_ResetBranches,
|
|
-- l.555-568). The field set lives at `clearBranchCell`, shared with OnLoad's build.
|
|
function BenillaTalentFrame_ResetBranches()
|
|
for i = 1, MAX_NUM_TALENT_TIERS do
|
|
for j = 1, NUM_TALENT_COLUMNS do
|
|
clearBranchCell(TALENT_BRANCH_ARRAY[i][j])
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ref TalentButtonTemplate's own inline OnEnter (Blizzard_TalentUITemplates.xml:90-93) —
|
|
-- `BenillaTalentFrame.selectedTab` read directly, matching the ref's own choice at THIS
|
|
-- site (this file's header comment, "TAB STRIP").
|
|
function BenillaTalentButton_OnEnter(button)
|
|
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
|
|
GameTooltip:SetTalent(BenillaTalentFrame.selectedTab, button:GetID())
|
|
end
|
|
|
|
-- ── The scroll frame (this file's header comment, "SCROLL DESIGN") ──────────────────────
|
|
function BenillaTalentFrameScroll_OnLoad(scrollFrame)
|
|
scrollFrame:SetScrollChild(getglobal("BenillaTalentFrameScrollChild"))
|
|
local bar = getglobal("BenillaTalentFrameScrollBar")
|
|
bar:SetMinMaxValues(0, BENILLA_TALENT_SCROLL_MAX)
|
|
bar:SetValueStep(BENILLA_TALENT_SCROLL_STEP)
|
|
bar:SetValue(0)
|
|
end
|
|
|
|
-- The real-ScrollFrame half of the documented Slider<->ScrollFrame wiring (`slider.rs`'s
|
|
-- own header comment: "OnValueChanged -> this:GetParent():SetVerticalScroll(arg1)") —
|
|
-- REPLACES BenillaScrollBarTemplate's inherited faux-offset handler (this file's header
|
|
-- comment, verified via loader/scripts.rs). BenillaScrollBar_UpdateArrows is faux-
|
|
-- agnostic (ScrollTemplates.xml's own body) and reused as-is for the arrow enable state.
|
|
function BenillaTalentFrameScrollBar_OnValueChanged(scrollBar, value)
|
|
scrollBar:GetParent():SetVerticalScroll(value)
|
|
BenillaScrollBar_UpdateArrows(scrollBar)
|
|
end
|
|
]]></Script>
|
|
|
|
<!--
|
|
The tree tab (ref TalentTabTemplate, Blizzard_TalentUITemplates.xml:3-23): inherits the
|
|
house's own CharacterFrameTabButtonTemplate (UiPanels.xml) — this file's header comment,
|
|
"TAB STRIP". The ref's own PLAYER_LEVEL_UP OnLoad/OnEvent (the level-9 pulse-flash hint) is
|
|
OMITTED with SetButtonPulse (this file's header comment); the ref's own blank OnEnter has
|
|
nothing to transcribe either.
|
|
-->
|
|
<Button name="BenillaTalentTabTemplate" inherits="CharacterFrameTabButtonTemplate" virtual="true">
|
|
<Scripts>
|
|
<OnClick>BenillaTalentFrameTab_OnClick(self)</OnClick>
|
|
<OnLeave>GameTooltip:Hide()</OnLeave>
|
|
</Scripts>
|
|
</Button>
|
|
|
|
<!-- The branch/arrow art pool templates (ref TalentBranchTemplate/TalentArrowTemplate,
|
|
Blizzard_TalentUITemplates.xml:24-39, verbatim: 32x32, default TOPLEFT anchor — every
|
|
instance below is repositioned every Update via SetPoint, this default is just where an
|
|
instance sits before its first placement). -->
|
|
<Texture name="BenillaTalentBranchTemplate" file="Interface\TalentFrame\UI-TalentBranches" virtual="true">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
|
</Texture>
|
|
<Texture name="BenillaTalentArrowTemplate" file="Interface\TalentFrame\UI-TalentArrows" virtual="true">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
|
</Texture>
|
|
|
|
<!--
|
|
The talent button (ref TalentButtonTemplate inherits ItemButtonTemplate,
|
|
Blizzard_TalentUITemplates.xml:40-101 + WoW/_extracted_framexml/ItemButtonTemplate.xml, both
|
|
read in full this session — self-contained rather than inheriting a base ItemButtonTemplate,
|
|
this file's header comment ("OMITs") and CharacterFrame.xml's own BenillaPaperDollItemSlot-
|
|
Template precedent for the identical gap. 37x37 (ItemButtonTemplate's own real size —
|
|
TALENT_BUTTON_SIZE=32 is a GRID PITCH constant, not this button's rendered size; the two are
|
|
independent, verified against ItemButtonTemplate.xml's own unsized $parentIconTexture +
|
|
64x64 NormalTexture ring, which visually overlaps neighboring buttons by design at the 63px
|
|
pitch — matches the ref exactly). Cooldown/AutoCast (ItemButtonTemplate has neither anyway)
|
|
don't apply here. CHARACTER_POINTS_CHANGED re-poll while hovered (ref l.85-89).
|
|
-->
|
|
<Button name="BenillaTalentButtonTemplate" virtual="true">
|
|
<Size><AbsDimension x="37" y="37"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="$parentSlot" file="Interface\Buttons\UI-EmptySlot-White">
|
|
<Size><AbsDimension x="64" y="64"/></Size>
|
|
<Anchors><Anchor point="CENTER"/></Anchors>
|
|
</Texture>
|
|
</Layer>
|
|
<Layer level="BORDER">
|
|
<!-- ItemButtonTemplate's own icon Texture child: unsized/unanchored, verbatim (its
|
|
own XML, l.10) — CharacterFrame.xml's $parentIconTexture precedent for the
|
|
identical shape. -->
|
|
<Texture name="$parentIconTexture"/>
|
|
</Layer>
|
|
<Layer level="OVERLAY">
|
|
<Texture name="$parentRankBorder" file="Interface\TalentFrame\TalentFrame-RankBorder">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors><Anchor point="CENTER" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<FontString name="$parentRank" inherits="GameFontNormalSmall">
|
|
<Anchors><Anchor point="CENTER" relativeTo="$parentRankBorder"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
|
|
</FontString>
|
|
</Layer>
|
|
</Layers>
|
|
<NormalTexture name="$parentNormalTexture" file="Interface\Buttons\UI-Quickslot2">
|
|
<Size><AbsDimension x="64" y="64"/></Size>
|
|
<Anchors><Anchor point="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"/>
|
|
<Scripts>
|
|
<OnLoad>self:RegisterEvent("CHARACTER_POINTS_CHANGED")</OnLoad>
|
|
<OnEvent>BenillaTalentButton_OnEvent(self)</OnEvent>
|
|
<OnEnter>BenillaTalentButton_OnEnter(self)</OnEnter>
|
|
<OnLeave>GameTooltip:Hide()</OnLeave>
|
|
<OnClick>BenillaTalentButton_OnClick(self)</OnClick>
|
|
</Scripts>
|
|
</Button>
|
|
|
|
<Frame name="BenillaTalentFrame" hidden="true">
|
|
<!-- The real 384x512 window (ref Blizzard_TalentUI.xml:5-8). No <Anchors> — ShowUIPanel/
|
|
SetLeftFrame SetPoints this to the left slot on open (UiPanels.xml's own convention). -->
|
|
<Size><AbsDimension x="384" y="512"/></Size>
|
|
<!-- HitRectInsets: transcribed for fidelity; no loader wiring exists yet (this file's
|
|
header comment) — a harmless no-op today. -->
|
|
<HitRectInsets><AbsInset left="0" right="30" top="0" bottom="45"/></HitRectInsets>
|
|
<Layers>
|
|
<!-- Portrait 60x60 TOPLEFT (7,-6) (ref l.19-31). Set in OnShow/on refresh via
|
|
SetPortraitTexture (CharacterFrame.xml's own precedent) — "player" is a fixed
|
|
token here, this window only ever shows the local player. -->
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="BenillaTalentFramePortrait">
|
|
<Size><AbsDimension x="60" y="60"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="7" y="-6"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
</Layer>
|
|
<!-- The static chassis (ref l.34-82): the PaperDollInfoFrame top (shared with
|
|
CharacterFrame) + the TalentFrame-specific bottom, both class-agnostic. -->
|
|
<Layer level="BORDER">
|
|
<Texture file="Interface\PaperDollInfoFrame\UI-Character-General-TopLeft">
|
|
<Size><AbsDimension x="256" y="256"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="2" y="-1"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<Texture file="Interface\PaperDollInfoFrame\UI-Character-General-TopRight">
|
|
<Size><AbsDimension x="128" y="256"/></Size>
|
|
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="2" y="-1"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<Texture file="Interface\TalentFrame\UI-TalentFrame-BotLeft">
|
|
<Size><AbsDimension x="256" y="256"/></Size>
|
|
<Anchors><Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="2" y="-1"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<Texture file="Interface\TalentFrame\UI-TalentFrame-BotRight">
|
|
<Size><AbsDimension x="128" y="256"/></Size>
|
|
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="2" y="-1"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
</Layer>
|
|
<!-- The class-specific tree art (ref l.84-202): the 4 dynamic quadrants (retextured
|
|
every Update from `base`), the title, and the points-remaining/points-spent bar. -->
|
|
<Layer level="ARTWORK">
|
|
<Texture name="BenillaTalentFrameBackgroundTopLeft">
|
|
<Size><AbsDimension x="256" y="256"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="23" y="-77"/></Offset></Anchor></Anchors>
|
|
</Texture>
|
|
<Texture name="BenillaTalentFrameBackgroundTopRight">
|
|
<Size><AbsDimension x="64" y="256"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT" relativeTo="BenillaTalentFrameBackgroundTopLeft" relativePoint="TOPRIGHT"/></Anchors>
|
|
</Texture>
|
|
<Texture name="BenillaTalentFrameBackgroundBottomLeft">
|
|
<Size><AbsDimension x="256" y="128"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT" relativeTo="BenillaTalentFrameBackgroundTopLeft" relativePoint="BOTTOMLEFT"/></Anchors>
|
|
</Texture>
|
|
<Texture name="BenillaTalentFrameBackgroundBottomRight">
|
|
<Size><AbsDimension x="64" y="128"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT" relativeTo="BenillaTalentFrameBackgroundTopLeft" relativePoint="BOTTOMRIGHT"/></Anchors>
|
|
</Texture>
|
|
<!-- text="Talents": this file's header comment (engine-gap notes, text= is
|
|
literal — never Lua-read, the ref's own TalentFrameTitleText isn't either). -->
|
|
<FontString name="BenillaTalentFrameTitleText" inherits="GameFontNormal" text="Talents">
|
|
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-18"/></Offset></Anchor></Anchors>
|
|
</FontString>
|
|
<Texture name="BenillaTalentFramePointsLeft" file="Interface\Common\Common-Input-Border">
|
|
<Size><AbsDimension x="8" y="20"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT" relativeTo="BenillaTalentFrame"><Offset><AbsDimension x="75" y="-48"/></Offset></Anchor></Anchors>
|
|
<TexCoords left="0" right="0.0625" top="0" bottom="0.625"/>
|
|
</Texture>
|
|
<Texture name="BenillaTalentFramePointsMiddle" file="Interface\Common\Common-Input-Border">
|
|
<Size><AbsDimension x="248" y="20"/></Size>
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaTalentFramePointsLeft" relativePoint="RIGHT"/></Anchors>
|
|
<TexCoords left="0.0625" right="0.9375" top="0" bottom="0.625"/>
|
|
</Texture>
|
|
<Texture name="BenillaTalentFramePointsRight" file="Interface\Common\Common-Input-Border">
|
|
<Size><AbsDimension x="8" y="20"/></Size>
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaTalentFramePointsMiddle" relativePoint="RIGHT"/></Anchors>
|
|
<TexCoords left="0.9375" right="1.0" top="0" bottom="0.625"/>
|
|
</Texture>
|
|
<!-- Fed every Update by format(MASTERY_POINTS_SPENT, name) — the live global, not
|
|
static text (this file's header comment). -->
|
|
<FontString name="BenillaTalentFrameSpentPoints" inherits="GameFontNormalSmall">
|
|
<Anchors><Anchor point="TOP" relativeTo="BenillaTalentFramePointsMiddle"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
|
</FontString>
|
|
<!-- Fed by BenillaTalentFrame_UpdateTalentPoints (the unspent-points NUMBER). -->
|
|
<FontString name="BenillaTalentFrameTalentPointsText" inherits="GameFontHighlightSmall">
|
|
<Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="252" y="87"/></Offset></Anchor></Anchors>
|
|
</FontString>
|
|
<!-- text="Talent Points:": this file's header comment (engine-gap notes, same as
|
|
the title — TalentFrame.lua never touches this FontString either). -->
|
|
<FontString name="BenillaTalentFrameTalentPoints" inherits="GameFontNormalSmall" text="Talent Points:">
|
|
<Anchors><Anchor point="RIGHT" relativeTo="BenillaTalentFrameTalentPointsText" relativePoint="LEFT"><Offset><AbsDimension x="-3" y="0"/></Offset></Anchor></Anchors>
|
|
</FontString>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<!-- Close: the house minimize-button art (no UIPanelCloseButton template ships —
|
|
SpellBookFrame/CharacterFrame's own precedent), the same TOPRIGHT(-44,-25)
|
|
position as every other window's close button (ref l.205-213). -->
|
|
<Button name="BenillaTalentFrameCloseButton">
|
|
<Size><AbsDimension x="32" y="32"/></Size>
|
|
<Anchors><Anchor point="CENTER" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-44" y="-25"/></Offset></Anchor></Anchors>
|
|
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
|
|
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
|
|
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
|
|
<Scripts>
|
|
<OnClick>HideUIPanel(BenillaTalentFrame)</OnClick>
|
|
</Scripts>
|
|
</Button>
|
|
|
|
<!-- The bottom "Close" text button (ref TalentFrameCancelButton, l.214-230): a second,
|
|
redundant close affordance the ref genuinely ships (identical HideUIPanel action to
|
|
the X button above) — included for completeness, this file's header comment
|
|
("OMITs") notes no reason to drop it. UIPanelButtonTemplate reconstructed locally
|
|
(StackSplit.xml's own precedent for the identical gap); text="Close" is this file's
|
|
header comment's literal-text convention, not a GlobalStrings token read. -->
|
|
<Button name="BenillaTalentFrameCancelButton" text="Close">
|
|
<Size><AbsDimension x="80" y="22"/></Size>
|
|
<Anchors><Anchor point="CENTER" relativePoint="TOPLEFT"><Offset><AbsDimension x="305" y="-420"/></Offset></Anchor></Anchors>
|
|
<NormalFont inherits="GameFontNormal"/>
|
|
<HighlightFont inherits="GameFontHighlight"/>
|
|
<DisabledFont inherits="GameFontDisable"/>
|
|
<NormalTexture file="Interface\Buttons\UI-Panel-Button-Up"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></NormalTexture>
|
|
<PushedTexture file="Interface\Buttons\UI-Panel-Button-Down"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></PushedTexture>
|
|
<DisabledTexture file="Interface\Buttons\UI-Panel-Button-Disabled"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></DisabledTexture>
|
|
<HighlightTexture file="Interface\Buttons\UI-Panel-Button-Highlight" alphaMode="ADD"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></HighlightTexture>
|
|
<Scripts>
|
|
<OnClick>HideUIPanel(BenillaTalentFrame)</OnClick>
|
|
</Scripts>
|
|
</Button>
|
|
|
|
<!-- The 3 tree tabs (ref l.231-275, MAX_TALENT_TABS renumbered 5 -> 3, this file's
|
|
header comment "SCOPE CALL"). -->
|
|
<Button name="BenillaTalentFrameTab1" inherits="BenillaTalentTabTemplate" id="1">
|
|
<Anchors><Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="15" y="46"/></Offset></Anchor></Anchors>
|
|
</Button>
|
|
<Button name="BenillaTalentFrameTab2" inherits="BenillaTalentTabTemplate" id="2">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaTalentFrameTab1" relativePoint="RIGHT"><Offset><AbsDimension x="-15" y="0"/></Offset></Anchor></Anchors>
|
|
</Button>
|
|
<Button name="BenillaTalentFrameTab3" inherits="BenillaTalentTabTemplate" id="3">
|
|
<Anchors><Anchor point="LEFT" relativeTo="BenillaTalentFrameTab2" relativePoint="RIGHT"><Offset><AbsDimension x="-15" y="0"/></Offset></Anchor></Anchors>
|
|
</Button>
|
|
|
|
<!-- The scrolled talent grid (ref l.276-419: TalentFrameScrollFrame, UIPanelScrollFrame-
|
|
Template) — this file's header comment, "SCROLL DESIGN": a real ScrollFrame (decision
|
|
0112) with a FIXED-height child (BENILLA_TALENT_SCROLL_CHILD_H) and a reused real
|
|
Slider scrollbar (BenillaScrollBarTemplate, ScrollTemplates.xml), not the ref's own
|
|
dynamic UIPanelScrollFrameTemplate. -->
|
|
<ScrollFrame name="BenillaTalentFrameScroll">
|
|
<Size><AbsDimension x="296" y="332"/></Size>
|
|
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-65" y="-77"/></Offset></Anchor></Anchors>
|
|
<Frames>
|
|
<!-- The scrollbar: BenillaScrollBarTemplate's own geometry (ScrollTemplates.xml's
|
|
FauxScrollFrameTemplate, whose Slider anchor shape is reused directly
|
|
here without the Frame wrapper around it — this file's header comment). Its
|
|
inherited OnValueChanged is REPLACED below (not chained — verified). -->
|
|
<Slider name="BenillaTalentFrameScrollBar" inherits="BenillaScrollBarTemplate">
|
|
<Anchors>
|
|
<Anchor point="TOPLEFT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="6" y="-16"/></Offset></Anchor>
|
|
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="6" y="16"/></Offset></Anchor>
|
|
</Anchors>
|
|
<Scripts>
|
|
<OnValueChanged>BenillaTalentFrameScrollBar_OnValueChanged(self, arg1)</OnValueChanged>
|
|
</Scripts>
|
|
</Slider>
|
|
|
|
<!-- The scroll child (SetScrollChild'd in BenillaTalentFrameScroll_OnLoad below,
|
|
QuestLogFrame.xml's own real-ScrollFrame precedent for the wiring shape):
|
|
320 wide (the ref's own TalentFrameScrollChildFrame width, ref l.318-321),
|
|
504 tall (this file's header comment, "SCROLL DESIGN" — a load-time constant,
|
|
never resized). -->
|
|
<Frame name="BenillaTalentFrameScrollChild">
|
|
<Size><AbsDimension x="320" y="504"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
|
<Layers>
|
|
<Layer level="BACKGROUND">
|
|
<Texture name="BenillaTalentFrameBranch1" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch2" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch3" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch4" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch5" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch6" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch7" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch8" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch9" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch10" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch11" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch12" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch13" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch14" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch15" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch16" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch17" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch18" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch19" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch20" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch21" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch22" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch23" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch24" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch25" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch26" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch27" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch28" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch29" inherits="BenillaTalentBranchTemplate"/>
|
|
<Texture name="BenillaTalentFrameBranch30" inherits="BenillaTalentBranchTemplate"/>
|
|
</Layer>
|
|
</Layers>
|
|
<Frames>
|
|
<!-- The 20 talent buttons (ref l.360-379, MAX_NUM_TALENTS) — id=1..20 is
|
|
the button's own within-tab index (GetTalentInfo's 2nd arg / GetID()).
|
|
No static Anchors: BenillaSetTalentButtonLocation SetPoints each one
|
|
every Update, off its OWN template's default TOPLEFT. -->
|
|
<Button name="BenillaTalentFrameTalent1" inherits="BenillaTalentButtonTemplate" id="1"/>
|
|
<Button name="BenillaTalentFrameTalent2" inherits="BenillaTalentButtonTemplate" id="2"/>
|
|
<Button name="BenillaTalentFrameTalent3" inherits="BenillaTalentButtonTemplate" id="3"/>
|
|
<Button name="BenillaTalentFrameTalent4" inherits="BenillaTalentButtonTemplate" id="4"/>
|
|
<Button name="BenillaTalentFrameTalent5" inherits="BenillaTalentButtonTemplate" id="5"/>
|
|
<Button name="BenillaTalentFrameTalent6" inherits="BenillaTalentButtonTemplate" id="6"/>
|
|
<Button name="BenillaTalentFrameTalent7" inherits="BenillaTalentButtonTemplate" id="7"/>
|
|
<Button name="BenillaTalentFrameTalent8" inherits="BenillaTalentButtonTemplate" id="8"/>
|
|
<Button name="BenillaTalentFrameTalent9" inherits="BenillaTalentButtonTemplate" id="9"/>
|
|
<Button name="BenillaTalentFrameTalent10" inherits="BenillaTalentButtonTemplate" id="10"/>
|
|
<Button name="BenillaTalentFrameTalent11" inherits="BenillaTalentButtonTemplate" id="11"/>
|
|
<Button name="BenillaTalentFrameTalent12" inherits="BenillaTalentButtonTemplate" id="12"/>
|
|
<Button name="BenillaTalentFrameTalent13" inherits="BenillaTalentButtonTemplate" id="13"/>
|
|
<Button name="BenillaTalentFrameTalent14" inherits="BenillaTalentButtonTemplate" id="14"/>
|
|
<Button name="BenillaTalentFrameTalent15" inherits="BenillaTalentButtonTemplate" id="15"/>
|
|
<Button name="BenillaTalentFrameTalent16" inherits="BenillaTalentButtonTemplate" id="16"/>
|
|
<Button name="BenillaTalentFrameTalent17" inherits="BenillaTalentButtonTemplate" id="17"/>
|
|
<Button name="BenillaTalentFrameTalent18" inherits="BenillaTalentButtonTemplate" id="18"/>
|
|
<Button name="BenillaTalentFrameTalent19" inherits="BenillaTalentButtonTemplate" id="19"/>
|
|
<Button name="BenillaTalentFrameTalent20" inherits="BenillaTalentButtonTemplate" id="20"/>
|
|
|
|
<!-- The arrow-art pool (ref l.380-415: TalentFrameArrowFrame,
|
|
setAllPoints="true") — an explicit Size matching the scroll child
|
|
instead, the equivalent shape CharacterFrame.xml's paper doll takes. -->
|
|
<Frame name="BenillaTalentFrameArrowFrame">
|
|
<Size><AbsDimension x="320" y="504"/></Size>
|
|
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
|
<Layers>
|
|
<Layer level="OVERLAY">
|
|
<Texture name="BenillaTalentFrameArrow1" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow2" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow3" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow4" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow5" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow6" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow7" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow8" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow9" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow10" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow11" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow12" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow13" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow14" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow15" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow16" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow17" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow18" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow19" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow20" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow21" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow22" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow23" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow24" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow25" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow26" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow27" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow28" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow29" inherits="BenillaTalentArrowTemplate"/>
|
|
<Texture name="BenillaTalentFrameArrow30" inherits="BenillaTalentArrowTemplate"/>
|
|
</Layer>
|
|
</Layers>
|
|
</Frame>
|
|
</Frames>
|
|
</Frame>
|
|
</Frames>
|
|
<Scripts>
|
|
<OnLoad>BenillaTalentFrameScroll_OnLoad(self)</OnLoad>
|
|
<!-- WoW wheel convention: +1 per notch up (toward the top, decreasing scroll),
|
|
-1 down (ChatFrame.xml's own handler quotes the same convention). Reuses
|
|
BenillaScrollBar_Step (this file's header comment: generic, Slider-only). -->
|
|
<OnMouseWheel>BenillaScrollBar_Step(getglobal("BenillaTalentFrameScrollBar"), arg1 > 0 and -1 or 1)</OnMouseWheel>
|
|
<!-- The real ScrollFrame's own half of the documented pair (this file's header
|
|
comment / BenillaTalentFrameScrollBar_OnValueChanged's own comment). -->
|
|
<OnVerticalScroll>getglobal("BenillaTalentFrameScrollBar"):SetValue(arg1)</OnVerticalScroll>
|
|
</Scripts>
|
|
</ScrollFrame>
|
|
</Frames>
|
|
<Scripts>
|
|
<OnLoad>BenillaTalentFrame_OnLoad(self)</OnLoad>
|
|
<OnShow>BenillaTalentFrame_OnShow()</OnShow>
|
|
<OnHide>BenillaTalentFrame_OnHide()</OnHide>
|
|
<OnEvent>BenillaTalentFrame_OnEvent(self)</OnEvent>
|
|
</Scripts>
|
|
</Frame>
|
|
</Ui>
|