The talent, vanity and wardrobe frames are built from the same handful of
widget templates, but each module carried its own copy of the handling:
close buttons, panels, dropdown pills, tabs and the ADDON_LOADED loader
were all written out three times. The copies had drifted -- tab backdrop
insets of 3 against 2, tabs grown in one frame and not the other, the
wardrobe clearing only three of the six tab textures -- and that drift is
what reads in-game as the same control looking different depending on which
tab you're on.
Modules/Skinning.lua now owns each of those behaviours once, and the three
modules call into it. Where the copies disagreed the values are unified;
tab growth is gated on the tab actually having a label, since growing an
icon-only tab just pushes its icon off the layout, and the SetChecked hook
is guarded because hooksecurefunc errors outright on a missing method.
Titles are pinned to Arial Narrow at 13: the vanity store titled in Friz
Quadrata while the other two used Arial Narrow. Frame scale is left as the
server set it, so the vanity title still renders slightly larger than the
others.
Two things deliberately not shared: the vanity frame still skips
StripTextures, since its currency counters are regions of the frame itself,
and the talent frame's bottom-bar dropdowns stay on their own path -- they
are a different widget, a native dropdown plus a separate caret button.
Outer panel, close button, and the top-left portrait medallion get the
same first-pass treatment as Vanity/Talent, plus the item collection
panel: native background/border art stripped from Collection and its
InsetOverlay/ShadowOverlay decoration, the 3D model preview's vanilla
border removed, and the action buttons, search box, Filter/Order By
dropdowns, page arrows, and category tabs skinned to match.
Left native for a later pass: the icon grid contents, item slot
buttons, and character model itself.
Skins the outer window, close button, search box, Filter dropdown
(and its arrow and popup panel), Purchase/Deliver buttons, and the
grid pager arrows. Removes nothing else -- the portrait originally
suspected at the top-left corner turned out not to exist as a
separate element, and the card grid/preview panel are left native.
Flattens the custom talent window into the ElvUI look: frame chrome, close
buttons, tabs, bottom bar, dropdowns and their popups, the list scrollbars,
and the spec choice cards' action buttons. The talent tree itself is left
alone -- its node borders encode rank and availability.
Most of the work is in keeping the skin applied. The frames restore their
native art on refresh in three different ways, and none of them fire an
event to hook:
- The scroll arrows re-show a region StripTextures had hidden, so the arrow
buttons re-hide it from their own update, matching by file so ElvUI's
panel pieces (which are regions of the same button on this client) survive.
- The pooled menu rows put their hover and selection art back when a scroll
refills them, without firing OnShow, so the strip runs from the row update
behind a cheap texture compare.
- The talent frame's close button keeps its absolute frame level while
TreeView rides along when the frame is raised, so the level bump re-applies
on every show.
Row fills and the selection edge are textures on the row rather than an ElvUI
backdrop: the backdrop is a child frame and covered the row's icon and text at
every frame level available to it.
Move CoA settings from E.global/E.private into a proper AceDB-3.0 database
(CoA.db, SavedVariables ElvUI_CoADB) with a Profiles options tab, since
ElvUI doesn't ship AceDBOptions-3.0 (vendored under Libraries/).
Add ClassResources.lua: hooks the custom-class resource frames (segment
bar, orb, bar, multi-cast bar) into ElvUI's Toggle Anchors, with a
per-frame hide checkbox in a new "Class Resources" options tab.
Add DispelHighlight.lua: highlights dispellable debuffs on unitframes,
with talent-aware filtering for custom classes.
Fix mover/anchor reliability for Class Resources and the Instance
(LayerPicker) button:
- Movers were only retried until the target frame existed, not until the
mover was actually created, so frames that start at zero size (e.g. a
resource bar before that resource is ever active) permanently lost
their mover.
- Class resource frames re-anchor themselves on refresh, stomping the
mover's anchor; hook SetPoint to snap back to the mover holder whenever
something else repositions the frame.
- Native click-drag on these frames ends with the engine calling SetPoint
directly, severing the mover anchor entirely. Permanently block drag
(script and RegisterForDrag) instead of clearing it once.
Strips the native tooltip-style backdrop pieces off the LayerPickerFrame button and applies the ElvUI backdrop/button style, gated by a new Instance checkbox in the Skins tab.