Skin the Challenges frame's Rewards tab
The tab's twenty-nine children all exist on a cold reload, before it has ever been opened, so this goes through SkinContents with the rest of the window rather than needing a hook on the tab's own OnShow -- which a tab switch would have wanted, since switching tabs fires nothing. None of the Trials tab's naming carries over. Its search box is TrialsTabSearch and its filter a FilterDropDown, where these are StoreTabSearchBox and Filter, so every suffix was confirmed rather than copied and the divergence is written down for the four tabs still to do. The Filter is the one widget that had to be read twice. Structurally it is a plain Button -- no Middle texture, no Button child, no Text fontstring -- so the test the Interface Options sweep settled on says it is not a dropdown. By art it plainly is: the same nine Silver-Button slices and ChatFrameExpandArrow caret the Trials filter wears. Dropdown matches on the art rather than on the naming, so it takes it unchanged; the structural test is only ever a shortcut to that question and here it answers it wrongly. The grid is a fixed pool of twenty-one cards built up front, not one built per page, so a single pass covers every card the tab will ever show and nothing hangs off a page-change hook. The icon crop is the exception and is re-applied from a hook on the texture's SetTexture: the store refills the pool in place on every search, filter and page change, and SetTexture resets a texture's coords, so a one-shot crop survives exactly until the first page turn and then the native icon borders come back on every card at once. The slot plate underneath needs no such watch -- StripArtByFile noops its SetTexture, so a refill that re-arts it writes nothing. Cards take HandleButton's useCreateBackdrop path rather than its default SetTemplate one, which is what makes their padding possible: a template is drawn as regions of the button and can only ever match its rect, and the rect is tight -- 140x32 around a 32px icon, so the icon met the top and bottom edges and the name ran to the right one. A backdrop is a child frame that can be set outside it. Same reasoning as the window panel's, one level down. The hover colouring follows either way, since it resolves button.backdrop before the button itself. The two headings above the grid are Buttons by type but captions by function, so their atlas art comes off and nothing goes back: a backdrop would draw a box around a caption, and the HIGHLIGHT layer would light it up under a cursor with nothing behind it. They are walked off the layout rather than named, the set being one per reward vendor. Left alone deliberately: the Currency button, which carries the trophy icon and its counter as its only two regions and no frame art at all, and PageText, which is a region of the tab itself -- the same trap as the vanity store's counters. Nothing here blind-strips the tab. No scroll bar is wired either; the grid pages rather than scrolls and has no scroll frame to hang one off. Everything reuses an existing helper, so the shared layer is unchanged.
This commit is contained in:
+149
-2
@@ -129,8 +129,13 @@ local function UpdatePanelTop(frame)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Per-tab contents. Each of the six tabs owns its own copy of these widgets
|
-- Per-tab contents. Each of the six tabs owns its own copy of these widgets
|
||||||
-- rather than sharing one set, so they're skinned per tab; only the Trials tab
|
-- rather than sharing one set, so they're skinned per tab; Trials and Rewards
|
||||||
-- is done so far and the rest follow the same shape.
|
-- are done and the rest follow the same shape.
|
||||||
|
--
|
||||||
|
-- Nothing about one tab's naming carries to the next: the Trials search box is
|
||||||
|
-- "...TrialsTabSearch" and its filter a "...FilterDropDown", where the Rewards
|
||||||
|
-- pair are "...StoreTabSearchBox" and "...Filter" (probed). Every suffix on a
|
||||||
|
-- new tab is worth confirming rather than copying.
|
||||||
local TRIALS_TAB = FRAME_NAME.."TrialsTab"
|
local TRIALS_TAB = FRAME_NAME.."TrialsTab"
|
||||||
local TRIALS_LIST = TRIALS_TAB.."Challenges"
|
local TRIALS_LIST = TRIALS_TAB.."Challenges"
|
||||||
local TRIALS_SCROLL = TRIALS_LIST.."ScrollFrame"
|
local TRIALS_SCROLL = TRIALS_LIST.."ScrollFrame"
|
||||||
@@ -165,6 +170,147 @@ local function SkinTrialsTab()
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local STORE_TAB = FRAME_NAME.."StoreTab"
|
||||||
|
local STORE_LAYOUT = STORE_TAB.."StoreButtonLayout"
|
||||||
|
|
||||||
|
-- Walked to the first missing index rather than against the twenty-one that
|
||||||
|
-- exist today, the same shape as the tab row: this count is a page size, and a
|
||||||
|
-- page size is exactly the sort of thing a content patch moves.
|
||||||
|
local MAX_SLOTS = 40
|
||||||
|
|
||||||
|
-- The bevelled empty-slot plate every bag and auction square on this client
|
||||||
|
-- draws, here behind each reward card (probed). The dashes are escaped because
|
||||||
|
-- StripArtByFile matches with find, where an unescaped dash is a pattern range.
|
||||||
|
local SLOT_ART = "UI%-AuctionFrame%-ItemSlot"
|
||||||
|
|
||||||
|
-- The card's rect is drawn tight around its contents: 140x32 with a 32px icon,
|
||||||
|
-- so the icon meets the top and bottom edges exactly and the name runs to the
|
||||||
|
-- right one. The native plate hid that by bleeding a bevel outwards; a flat
|
||||||
|
-- backdrop on the same rect just looks cramped. The grid leaves far more room
|
||||||
|
-- than this between cards -- tens of pixels each way -- so the box is grown
|
||||||
|
-- rather than the contents moved in, which would fight the store's own layout.
|
||||||
|
local CARD_PADDING = 4
|
||||||
|
|
||||||
|
-- The headings above the grid are drawn out of the quest log's atlas by tex
|
||||||
|
-- coord (probed: three slices plus the button's own NormalTexture, all one
|
||||||
|
-- file). Cleared by file rather than stripped so the label survives.
|
||||||
|
local HEADING_ART = "questmaplogatlas"
|
||||||
|
|
||||||
|
-- A row rather than an item square: 140x32 with a 32px icon flush left, then
|
||||||
|
-- the name, then a SimpleHTML cost (probed). The icon is a region of the button
|
||||||
|
-- itself rather than sitting in a frame of its own, unlike the talent menu's
|
||||||
|
-- rows, so it takes the crop but not a backdrop of its own.
|
||||||
|
--
|
||||||
|
-- The card takes HandleButton's useCreateBackdrop path rather than its default
|
||||||
|
-- SetTemplate one, which is what makes the padding possible at all: a template
|
||||||
|
-- is drawn as regions of the button and can only ever match its rect, while a
|
||||||
|
-- backdrop is a child frame that can be set outside it. Same reasoning as the
|
||||||
|
-- window panel's, one level down. Skin:Button's hover colouring follows either
|
||||||
|
-- way -- it resolves button.backdrop before the button itself.
|
||||||
|
--
|
||||||
|
-- The native hover square needs nothing by name: it's a plain region on the
|
||||||
|
-- HIGHLIGHT layer (probed), which is the whole layer Skin:Button's
|
||||||
|
-- StripHighlightArt takes.
|
||||||
|
--
|
||||||
|
-- The crop is re-applied from a hook rather than set once. The grid is a fixed
|
||||||
|
-- pool the store refills in place on every search, filter and page change, and
|
||||||
|
-- SetTexture resets a texture's coords -- so a one-shot crop would survive
|
||||||
|
-- exactly until the first page turn, and the native icon borders would come
|
||||||
|
-- back on every card at once. The plate underneath needs no such watch:
|
||||||
|
-- StripArtByFile noops its SetTexture, so a refill that re-arts it writes
|
||||||
|
-- nothing.
|
||||||
|
local function SkinStoreCard(slot)
|
||||||
|
if not slot then return end
|
||||||
|
|
||||||
|
Skin:StripArtByFile(slot, SLOT_ART)
|
||||||
|
Skin:Button(slot, nil, nil, true)
|
||||||
|
|
||||||
|
-- Re-set on every pass rather than once: SetOutside writes fixed points, so
|
||||||
|
-- a UI scale change that moves what a pixel is leaves them stale.
|
||||||
|
if slot.backdrop then
|
||||||
|
slot.backdrop:SetOutside(slot, CARD_PADDING, CARD_PADDING)
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = slot:GetName()
|
||||||
|
local icon = name and _G[name.."Icon"]
|
||||||
|
if not icon then return end
|
||||||
|
|
||||||
|
icon:SetTexCoord(unpack(E.TexCoords))
|
||||||
|
|
||||||
|
-- Guarded separately from Skin:Button's own flag, and for the same reason it
|
||||||
|
-- guards its own: this runs again on every show, and hooksecurefunc stacks
|
||||||
|
-- handlers rather than replacing them.
|
||||||
|
if not slot.CoAIconHooked then
|
||||||
|
slot.CoAIconHooked = true
|
||||||
|
|
||||||
|
hooksecurefunc(icon, "SetTexture", function(texture)
|
||||||
|
texture:SetTexCoord(unpack(E.TexCoords))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- "Trial Master's Rewards" and its sibling for the build vendor are Buttons by
|
||||||
|
-- type, but they aren't buttons: they're the grid's section headings, drawn as
|
||||||
|
-- a stylised plaque and doing nothing when clicked. So they get their art taken
|
||||||
|
-- off and nothing put back -- no backdrop, which would draw a box around a
|
||||||
|
-- caption and read as clickable, and no hover border for the same reason. The
|
||||||
|
-- HIGHLIGHT layer goes too, or the caption lights up under the cursor with
|
||||||
|
-- nothing behind it.
|
||||||
|
--
|
||||||
|
-- Walked off the layout rather than named, since the set is one per reward
|
||||||
|
-- vendor and grows with content. Same reasoning as the tab row.
|
||||||
|
local function SkinStoreHeadings()
|
||||||
|
local layout = _G[STORE_LAYOUT]
|
||||||
|
if not layout then return end
|
||||||
|
|
||||||
|
for i = 1, layout:GetNumChildren() do
|
||||||
|
local heading = select(i, layout:GetChildren())
|
||||||
|
|
||||||
|
Skin:StripArtByFile(heading, HEADING_ART)
|
||||||
|
Skin:StripHighlightArt(heading)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Everything on this tab exists before it has ever been opened (probed: the
|
||||||
|
-- same twenty-nine children on a cold reload as after a click), so it goes
|
||||||
|
-- through SkinContents with the rest rather than needing a hook on the tab's
|
||||||
|
-- own OnShow.
|
||||||
|
--
|
||||||
|
-- Two things here are deliberately left alone. The Currency button carries the
|
||||||
|
-- trophy icon and the "Trial Master's Trophy: 0" counter as its only two
|
||||||
|
-- regions and no frame art at all, so there's nothing to strip and a backdrop
|
||||||
|
-- would only make a label look clickable. PageText is a FontString region of
|
||||||
|
-- the tab itself -- the same trap as the vanity store's counters, and the
|
||||||
|
-- reason Skin:Panel grew keepTextures -- so nothing here blind-strips the tab.
|
||||||
|
--
|
||||||
|
-- No scroll bar is wired: the grid pages rather than scrolls, and there's no
|
||||||
|
-- scroll frame anywhere under the tab to hang one off (probed).
|
||||||
|
local function SkinStoreTab()
|
||||||
|
Skin:SearchBox(_G[STORE_TAB.."SearchBox"])
|
||||||
|
|
||||||
|
-- Not a dropdown by structure -- no Middle texture, no Button child, no Text
|
||||||
|
-- fontstring, just a plain Button (probed) -- but it is one by art: the same
|
||||||
|
-- nine "UI-Silver-Button" slices and ChatFrameExpandArrow caret the Trials
|
||||||
|
-- filter wears. Skin:Dropdown matches on the art rather than on the naming,
|
||||||
|
-- so it takes this one too; the Middle-plus-Button structural test is only
|
||||||
|
-- ever a shortcut to that question, and here it answers it wrongly.
|
||||||
|
Skin:Dropdown(_G[STORE_TAB.."Filter"])
|
||||||
|
|
||||||
|
-- Stock "UI-SquareButton" arrows (probed), unlike the hand-built bar on the
|
||||||
|
-- Trials list, so these go through the ElvUI handler unaided.
|
||||||
|
Skin:NextPrevButton(_G[STORE_TAB.."PreviousPageButton"], "left")
|
||||||
|
Skin:NextPrevButton(_G[STORE_TAB.."NextPageButton"], "right")
|
||||||
|
|
||||||
|
SkinStoreHeadings()
|
||||||
|
|
||||||
|
for i = 1, MAX_SLOTS do
|
||||||
|
local slot = _G[STORE_TAB.."Slot"..i]
|
||||||
|
if not slot then break end
|
||||||
|
|
||||||
|
SkinStoreCard(slot)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- The close button is anchored inside the frame's own top-right corner, which
|
-- The close button is anchored inside the frame's own top-right corner, which
|
||||||
-- stopped being the corner the player sees once the panel grew up over the title
|
-- stopped being the corner the player sees once the panel grew up over the title
|
||||||
-- band -- it ends up floating a title's height below the top edge. Re-anchored
|
-- band -- it ends up floating a title's height below the top edge. Re-anchored
|
||||||
@@ -195,6 +341,7 @@ local function SkinContents()
|
|||||||
SkinTabs()
|
SkinTabs()
|
||||||
AnchorTabRow()
|
AnchorTabRow()
|
||||||
SkinTrialsTab()
|
SkinTrialsTab()
|
||||||
|
SkinStoreTab()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function SkinFrame(frame)
|
local function SkinFrame(frame)
|
||||||
|
|||||||
Reference in New Issue
Block a user