1487 lines
43 KiB
Lua
1487 lines
43 KiB
Lua
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
|
local S = E:GetModule('Skins')
|
|
|
|
local _G = _G
|
|
local tinsert, xpcall, next = tinsert, xpcall, next
|
|
local unpack, assert, pairs, ipairs, select, type, strfind = unpack, assert, pairs, ipairs, select, type, strfind
|
|
|
|
local CreateFrame = CreateFrame
|
|
local hooksecurefunc = hooksecurefunc
|
|
local IsAddOnLoaded = IsAddOnLoaded
|
|
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
|
|
|
|
S.allowBypass = {}
|
|
S.addonsToLoad = {}
|
|
S.nonAddonsToLoad = {}
|
|
|
|
S.Blizzard = {}
|
|
S.Blizzard.Regions = {
|
|
'Left',
|
|
'Middle',
|
|
'Right',
|
|
'Mid',
|
|
'LeftDisabled',
|
|
'MiddleDisabled',
|
|
'RightDisabled',
|
|
'TopLeft',
|
|
'TopRight',
|
|
'BottomLeft',
|
|
'BottomRight',
|
|
'TopMiddle',
|
|
'MiddleLeft',
|
|
'MiddleRight',
|
|
'BottomMiddle',
|
|
'MiddleMiddle',
|
|
'TabSpacer',
|
|
'TabSpacer1',
|
|
'TabSpacer2',
|
|
'_RightSeparator',
|
|
'_LeftSeparator',
|
|
'Cover',
|
|
'Border',
|
|
'Background',
|
|
'TopTex',
|
|
'TopLeftTex',
|
|
'TopRightTex',
|
|
'LeftTex',
|
|
'BottomTex',
|
|
'BottomLeftTex',
|
|
'BottomRightTex',
|
|
'RightTex',
|
|
'MiddleTex',
|
|
'Center',
|
|
-- 9.0 might want these later? (achievement frame uses them and maybe something else)
|
|
--'BottomEdge',
|
|
--'LeftEdge',
|
|
--'RightEdge',
|
|
--'TopEdge',
|
|
--'TopLeftCorner',
|
|
--'TopRightCorner',
|
|
--'BottomLeftCorner',
|
|
--'BottomRightCorner',
|
|
}
|
|
|
|
-- Depends on the arrow texture to be up by default.
|
|
S.ArrowRotation = {
|
|
up = 0,
|
|
down = 3.14,
|
|
left = 1.57,
|
|
right = -1.57,
|
|
}
|
|
|
|
function S:HandleInsetFrame(frame)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
if frame.InsetBorderTop then frame.InsetBorderTop:Hide() end
|
|
if frame.InsetBorderTopLeft then frame.InsetBorderTopLeft:Hide() end
|
|
if frame.InsetBorderTopRight then frame.InsetBorderTopRight:Hide() end
|
|
|
|
if frame.InsetBorderBottom then frame.InsetBorderBottom:Hide() end
|
|
if frame.InsetBorderBottomLeft then frame.InsetBorderBottomLeft:Hide() end
|
|
if frame.InsetBorderBottomRight then frame.InsetBorderBottomRight:Hide() end
|
|
|
|
if frame.InsetBorderLeft then frame.InsetBorderLeft:Hide() end
|
|
if frame.InsetBorderRight then frame.InsetBorderRight:Hide() end
|
|
|
|
if frame.Bg then frame.Bg:Hide() end
|
|
end
|
|
|
|
-- All frames that have a Portrait
|
|
function S:HandlePortraitFrame(frame, setTemplate)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
local name = frame and frame.GetName and frame:GetName()
|
|
local insetFrame = name and _G[name..'Inset'] or frame.Inset
|
|
local portraitFrame = name and _G[name..'Portrait'] or frame.Portrait or frame.portrait
|
|
local portraitFrameOverlay = name and _G[name..'PortraitOverlay'] or frame.PortraitOverlay
|
|
local artFrameOverlay = name and _G[name..'ArtOverlayFrame'] or frame.ArtOverlayFrame
|
|
|
|
frame:StripTextures()
|
|
|
|
if portraitFrame then portraitFrame:SetAlpha(0) end
|
|
if portraitFrameOverlay then portraitFrameOverlay:SetAlpha(0) end
|
|
if artFrameOverlay then artFrameOverlay:SetAlpha(0) end
|
|
|
|
if insetFrame then
|
|
S:HandleInsetFrame(insetFrame)
|
|
end
|
|
|
|
if frame.CloseButton then
|
|
S:HandleCloseButton(frame.CloseButton)
|
|
end
|
|
|
|
if setTemplate then
|
|
frame:SetTemplate('Transparent')
|
|
else
|
|
frame:CreateBackdrop('Transparent')
|
|
frame.backdrop:SetAllPoints()
|
|
end
|
|
end
|
|
|
|
function S:SetModifiedBackdrop()
|
|
if self:IsEnabled() then
|
|
if self.backdrop then self = self.backdrop end
|
|
if self.SetBackdropBorderColor then
|
|
self:SetBackdropBorderColor(unpack(E.media.rgbvaluecolor))
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:SetOriginalBackdrop()
|
|
if self:IsEnabled() then
|
|
if self.backdrop then self = self.backdrop end
|
|
if self.SetBackdropBorderColor then
|
|
self:SetBackdropBorderColor(unpack(E.media.bordercolor))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- function to handle the recap button script
|
|
function S:UpdateRecapButton()
|
|
-- when UpdateRecapButton runs and enables the button, it unsets OnEnter
|
|
-- we need to reset it with ours. blizzard will replace it when the button
|
|
-- is disabled. so, we don't have to worry about anything else.
|
|
if self and self.button4 and self.button4:IsEnabled() then
|
|
self.button4:SetScript('OnEnter', S.SetModifiedBackdrop)
|
|
self.button4:SetScript('OnLeave', S.SetOriginalBackdrop)
|
|
end
|
|
end
|
|
|
|
-- We need to test this for the BGScore frame
|
|
S.PVPHonorXPBarFrames = {}
|
|
S.PVPHonorXPBarSkinned = false
|
|
|
|
function S:SkinPVPHonorXPBar(frame)
|
|
S.PVPHonorXPBarFrames[frame] = true
|
|
|
|
if S.PVPHonorXPBarSkinned then return end
|
|
S.PVPHonorXPBarSkinned = true
|
|
|
|
hooksecurefunc('PVPHonorXPBar_SetNextAvailable', function(XPBar)
|
|
if not S.PVPHonorXPBarFrames[XPBar:GetParent():GetName()] then return end
|
|
XPBar:StripTextures() --XPBar
|
|
|
|
if XPBar.Bar and not XPBar.Bar.backdrop then
|
|
XPBar.Bar:CreateBackdrop()
|
|
if XPBar.Bar.Background then
|
|
XPBar.Bar.Background:SetInside(XPBar.Bar.backdrop)
|
|
end
|
|
if XPBar.Bar.Spark then
|
|
XPBar.Bar.Spark:SetAlpha(0)
|
|
end
|
|
if XPBar.Bar.OverlayFrame and XPBar.Bar.OverlayFrame.Text then
|
|
XPBar.Bar.OverlayFrame.Text:ClearAllPoints()
|
|
XPBar.Bar.OverlayFrame.Text:Point('CENTER', XPBar.Bar)
|
|
end
|
|
end
|
|
|
|
if XPBar.PrestigeReward and XPBar.PrestigeReward.Accept then
|
|
XPBar.PrestigeReward.Accept:ClearAllPoints()
|
|
XPBar.PrestigeReward.Accept:Point('TOP', XPBar.PrestigeReward, 'BOTTOM', 0, 0)
|
|
if not XPBar.PrestigeReward.Accept.template then
|
|
S:HandleButton(XPBar.PrestigeReward.Accept)
|
|
end
|
|
end
|
|
|
|
if XPBar.NextAvailable then
|
|
if XPBar.Bar then
|
|
XPBar.NextAvailable:ClearAllPoints()
|
|
XPBar.NextAvailable:Point('LEFT', XPBar.Bar, 'RIGHT', 0, -2)
|
|
end
|
|
|
|
if not XPBar.NextAvailable.backdrop then
|
|
XPBar.NextAvailable:StripTextures()
|
|
XPBar.NextAvailable:CreateBackdrop()
|
|
if XPBar.NextAvailable.Icon then
|
|
XPBar.NextAvailable.backdrop:Point('TOPLEFT', XPBar.NextAvailable.Icon, -(E.PixelMode and 1 or 2), (E.PixelMode and 1 or 2))
|
|
XPBar.NextAvailable.backdrop:Point('BOTTOMRIGHT', XPBar.NextAvailable.Icon, (E.PixelMode and 1 or 2), -(E.PixelMode and 1 or 2))
|
|
end
|
|
end
|
|
|
|
if XPBar.NextAvailable.Icon then
|
|
XPBar.NextAvailable.Icon:SetDrawLayer('ARTWORK')
|
|
XPBar.NextAvailable.Icon:SetTexCoord(unpack(E.TexCoords))
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
function S:StatusBarColorGradient(bar, value, max, backdrop)
|
|
local current = (not max and value) or (value and max and max ~= 0 and value/max)
|
|
if not (bar and current) then return end
|
|
local r, g, b = E:ColorGradient(current, 0.8,0,0, 0.8,0.8,0, 0,0.8,0)
|
|
local bg = backdrop or bar.backdrop
|
|
if bg then bg:SetBackdropColor(r*0.25, g*0.25, b*0.25) end
|
|
bar:SetStatusBarColor(r, g, b)
|
|
end
|
|
|
|
-- DropDownMenu library support
|
|
function S:SkinLibDropDownMenu(prefix)
|
|
if _G[prefix..'_UIDropDownMenu_CreateFrames'] and not S[prefix..'_UIDropDownMenuSkinned'] then
|
|
local bd = _G[prefix..'_DropDownList1Backdrop']
|
|
local mbd = _G[prefix..'_DropDownList1MenuBackdrop']
|
|
if bd and not bd.template then bd:SetTemplate('Transparent') end
|
|
if mbd and not mbd.template then mbd:SetTemplate('Transparent') end
|
|
|
|
S[prefix..'_UIDropDownMenuSkinned'] = true
|
|
hooksecurefunc(prefix..'_UIDropDownMenu_CreateFrames', function()
|
|
local lvls = _G[(prefix == 'Lib' and 'LIB' or prefix)..'_UIDROPDOWNMENU_MAXLEVELS'];
|
|
local ddbd = lvls and _G[prefix..'_DropDownList'..lvls..'Backdrop'];
|
|
local ddmbd = lvls and _G[prefix..'_DropDownList'..lvls..'MenuBackdrop'];
|
|
if ddbd and not ddbd.template then ddbd:SetTemplate('Transparent') end
|
|
if ddmbd and not ddmbd.template then ddmbd:SetTemplate('Transparent') end
|
|
end)
|
|
end
|
|
end
|
|
|
|
function S:SkinTalentListButtons(frame)
|
|
local name = frame and frame.GetName and frame:GetName()
|
|
if name then
|
|
local bcl = _G[name..'BtnCornerLeft']
|
|
local bcr = _G[name..'BtnCornerRight']
|
|
local bbb = _G[name..'ButtonBottomBorder']
|
|
if bcl then bcl:SetTexture() end
|
|
if bcr then bcr:SetTexture() end
|
|
if bbb then bbb:SetTexture() end
|
|
end
|
|
|
|
if frame.Inset then
|
|
S:HandleInsetFrame(frame.Inset)
|
|
|
|
frame.Inset:Point('TOPLEFT', 4, -60)
|
|
frame.Inset:Point('BOTTOMRIGHT', -6, 26)
|
|
end
|
|
end
|
|
|
|
do
|
|
local function iconBorderColor(border, r, g, b, a)
|
|
border:StripTextures()
|
|
|
|
if border.customFunc then
|
|
local br, bg, bb = unpack(E.media.bordercolor)
|
|
border.customFunc(border, r, g, b, a, br, bg, bb)
|
|
elseif border.customBackdrop then
|
|
border.customBackdrop:SetBackdropBorderColor(r, g, b)
|
|
end
|
|
end
|
|
|
|
local function iconBorderHide(border)
|
|
local br, bg, bb = unpack(E.media.bordercolor)
|
|
if border.customFunc then
|
|
local r, g, b, a = border:GetVertexColor()
|
|
border.customFunc(border, r, g, b, a, br, bg, bb)
|
|
elseif border.customBackdrop then
|
|
border.customBackdrop:SetBackdropBorderColor(br, bg, bb)
|
|
end
|
|
end
|
|
|
|
function S:HandleIconBorder(border, backdrop, customFunc)
|
|
if not backdrop then
|
|
local parent = border:GetParent()
|
|
backdrop = parent.backdrop or parent
|
|
end
|
|
|
|
border.customBackdrop = backdrop
|
|
|
|
if not border.IconBorderHooked then
|
|
border:StripTextures()
|
|
|
|
hooksecurefunc(border, 'SetVertexColor', iconBorderColor)
|
|
hooksecurefunc(border, 'Hide', iconBorderHide)
|
|
|
|
border.IconBorderHooked = true
|
|
end
|
|
|
|
local r, g, b, a = border:GetVertexColor()
|
|
if customFunc then
|
|
border.customFunc = customFunc
|
|
local br, bg, bb = unpack(E.media.bordercolor)
|
|
customFunc(border, r, g, b, a, br, bg, bb)
|
|
elseif r then
|
|
backdrop:SetBackdropBorderColor(r, g, b, a)
|
|
else
|
|
local br, bg, bb = unpack(E.media.bordercolor)
|
|
backdrop:SetBackdropBorderColor(br, bg, bb)
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:HandleButton(button, strip, isDeclineButton, noStyle, setTemplate, styleTemplate, noGlossTex, override)
|
|
assert(button, 'doesnt exist!')
|
|
|
|
if button.isSkinned then return end
|
|
|
|
if button.SetNormalTexture and not override then button:SetNormalTexture('') end
|
|
if button.SetHighlightTexture then button:SetHighlightTexture('') end
|
|
if button.SetPushedTexture then button:SetPushedTexture('') end
|
|
if button.SetDisabledTexture then button:SetDisabledTexture('') end
|
|
|
|
if strip then button:StripTextures() end
|
|
S:HandleBlizzardRegions(button)
|
|
|
|
if button.Icon then
|
|
local Texture = button.Icon:GetTexture()
|
|
if Texture and (type(Texture) == 'string' and strfind(Texture, [[Interface\ChatFrame\ChatFrameExpandArrow]])) then
|
|
button.Icon:SetTexture(E.Media.Textures.ArrowUp)
|
|
button.Icon:SetRotation(S.ArrowRotation.right)
|
|
button.Icon:SetVertexColor(1, 1, 1)
|
|
end
|
|
end
|
|
|
|
if isDeclineButton then
|
|
if button.Icon then
|
|
button.Icon:SetTexture(E.Media.Textures.Close)
|
|
end
|
|
end
|
|
|
|
if not noStyle then
|
|
if setTemplate then
|
|
button:SetTemplate(styleTemplate, not noGlossTex)
|
|
else
|
|
button:CreateBackdrop(styleTemplate, not noGlossTex)
|
|
button.backdrop:SetAllPoints()
|
|
end
|
|
|
|
button:HookScript('OnEnter', S.SetModifiedBackdrop)
|
|
button:HookScript('OnLeave', S.SetOriginalBackdrop)
|
|
end
|
|
|
|
button.isSkinned = true
|
|
end
|
|
|
|
do
|
|
local function GrabScrollBarElement(frame, element)
|
|
local FrameName = frame:GetName()
|
|
return frame[element] or FrameName and (_G[FrameName..element] or strfind(FrameName, element)) or nil
|
|
end
|
|
|
|
function S:HandleScrollBar(frame, thumbTrimY, thumbTrimX)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
if frame.backdrop then return end
|
|
local parent = frame:GetParent()
|
|
local ScrollUpButton = GrabScrollBarElement(frame, 'ScrollUpButton') or GrabScrollBarElement(frame, 'UpButton') or GrabScrollBarElement(frame, 'ScrollUp') or GrabScrollBarElement(parent, 'scrollUp')
|
|
local ScrollDownButton = GrabScrollBarElement(frame, 'ScrollDownButton') or GrabScrollBarElement(frame, 'DownButton') or GrabScrollBarElement(frame, 'ScrollDown') or GrabScrollBarElement(parent, 'scrollDown')
|
|
local Thumb = GrabScrollBarElement(frame, 'ThumbTexture') or GrabScrollBarElement(frame, 'thumbTexture') or frame.GetThumbTexture and frame:GetThumbTexture()
|
|
|
|
frame:StripTextures()
|
|
frame:CreateBackdrop()
|
|
frame.backdrop:Point('TOPLEFT', ScrollUpButton or frame, ScrollUpButton and 'BOTTOMLEFT' or 'TOPLEFT', 0, 0)
|
|
frame.backdrop:Point('BOTTOMRIGHT', ScrollDownButton or frame, ScrollUpButton and 'TOPRIGHT' or 'BOTTOMRIGHT', 0, 0)
|
|
frame.backdrop:SetFrameLevel(frame.backdrop:GetFrameLevel() + 1)
|
|
|
|
if frame.ScrollUpBorder then
|
|
frame.ScrollUpBorder:Hide()
|
|
end
|
|
if frame.ScrollDownBorder then
|
|
frame.ScrollDownBorder:Hide()
|
|
end
|
|
|
|
for _, Button in pairs({ ScrollUpButton, ScrollDownButton }) do
|
|
if Button then
|
|
S:HandleNextPrevButton(Button)
|
|
end
|
|
end
|
|
|
|
if Thumb and not Thumb.backdrop then
|
|
Thumb:SetTexture()
|
|
Thumb:CreateBackdrop(nil, true, true)
|
|
if not thumbTrimY then thumbTrimY = 3 end
|
|
if not thumbTrimX then thumbTrimX = 2 end
|
|
Thumb.backdrop:Point('TOPLEFT', Thumb, 'TOPLEFT', 2, -thumbTrimY)
|
|
Thumb.backdrop:Point('BOTTOMRIGHT', Thumb, 'BOTTOMRIGHT', -thumbTrimX, thumbTrimY)
|
|
Thumb.backdrop:SetFrameLevel(Thumb.backdrop:GetFrameLevel() + 2)
|
|
Thumb.backdrop:SetBackdropColor(0.6, 0.6, 0.6)
|
|
|
|
frame.Thumb = Thumb
|
|
end
|
|
end
|
|
end
|
|
|
|
do --Tab Regions
|
|
local tabs = {
|
|
'LeftDisabled',
|
|
'MiddleDisabled',
|
|
'RightDisabled',
|
|
'Left',
|
|
'Middle',
|
|
'Right'
|
|
}
|
|
|
|
function S:HandleTab(tab, noBackdrop)
|
|
if not tab or (tab.backdrop and not noBackdrop) then return end
|
|
|
|
for _, object in pairs(tabs) do
|
|
local tex = _G[tab:GetName()..object]
|
|
if tex then
|
|
tex:SetTexture()
|
|
end
|
|
end
|
|
|
|
local highlightTex = tab.GetHighlightTexture and tab:GetHighlightTexture()
|
|
if highlightTex then
|
|
highlightTex:SetTexture()
|
|
else
|
|
tab:StripTextures()
|
|
end
|
|
|
|
if not noBackdrop then
|
|
tab:CreateBackdrop()
|
|
tab.backdrop:Point('TOPLEFT', 10, E.PixelMode and -1 or -3)
|
|
tab.backdrop:Point('BOTTOMRIGHT', -10, 3)
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:HandleRotateButton(btn)
|
|
if btn.isSkinned then return end
|
|
|
|
btn:CreateBackdrop()
|
|
btn:Size(btn:GetWidth() - 14, btn:GetHeight() - 14)
|
|
|
|
local normTex = btn:GetNormalTexture()
|
|
local pushTex = btn:GetPushedTexture()
|
|
local highlightTex = btn:GetHighlightTexture()
|
|
|
|
normTex:SetInside()
|
|
normTex:SetTexCoord(0.3, 0.29, 0.3, 0.65, 0.69, 0.29, 0.69, 0.65)
|
|
|
|
pushTex:SetAllPoints(normTex)
|
|
pushTex:SetTexCoord(0.3, 0.29, 0.3, 0.65, 0.69, 0.29, 0.69, 0.65)
|
|
|
|
highlightTex:SetAllPoints(normTex)
|
|
highlightTex:SetColorTexture(1, 1, 1, 0.3)
|
|
|
|
btn.isSkinned = true
|
|
end
|
|
|
|
do
|
|
local btns = {MaximizeButton = 'up', MinimizeButton = 'down'}
|
|
function S:HandleMaxMinFrame(frame)
|
|
assert(frame, 'does not exist.')
|
|
|
|
if frame.isSkinned then return end
|
|
|
|
frame:StripTextures(true)
|
|
|
|
for name, direction in pairs(btns) do
|
|
local button = frame[name]
|
|
if button then
|
|
button:Size(14, 14)
|
|
button:ClearAllPoints()
|
|
button:Point('CENTER')
|
|
button:SetHitRectInsets(1, 1, 1, 1)
|
|
button:GetHighlightTexture():Kill()
|
|
|
|
button:SetScript('OnEnter', function(btn)
|
|
local r,g,b = unpack(E.media.rgbvaluecolor)
|
|
btn:GetNormalTexture():SetVertexColor(r,g,b)
|
|
btn:GetPushedTexture():SetVertexColor(r,g,b)
|
|
end)
|
|
|
|
button:SetScript('OnLeave', function(btn)
|
|
btn:GetNormalTexture():SetVertexColor(1, 1, 1)
|
|
btn:GetPushedTexture():SetVertexColor(1, 1, 1)
|
|
end)
|
|
|
|
button:SetNormalTexture(E.Media.Textures.ArrowUp)
|
|
button:GetNormalTexture():SetRotation(S.ArrowRotation[direction])
|
|
|
|
button:SetPushedTexture(E.Media.Textures.ArrowUp)
|
|
button:GetPushedTexture():SetRotation(S.ArrowRotation[direction])
|
|
end
|
|
end
|
|
|
|
frame.isSkinned = true
|
|
end
|
|
end
|
|
|
|
function S:HandleBlizzardRegions(frame, name, kill)
|
|
if not name then name = frame.GetName and frame:GetName() end
|
|
for _, area in pairs(S.Blizzard.Regions) do
|
|
local object = (name and _G[name..area]) or frame[area]
|
|
if object then
|
|
if kill then
|
|
object:Kill()
|
|
else
|
|
object:SetAlpha(0)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:HandleEditBox(frame)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
if frame.backdrop then return end
|
|
|
|
frame:CreateBackdrop()
|
|
frame.backdrop:SetFrameLevel(frame:GetFrameLevel())
|
|
S:HandleBlizzardRegions(frame)
|
|
|
|
local EditBoxName = frame:GetName()
|
|
if EditBoxName and (strfind(EditBoxName, 'Silver') or strfind(EditBoxName, 'Copper')) then
|
|
frame.backdrop:Point('BOTTOMRIGHT', -12, -2)
|
|
end
|
|
end
|
|
|
|
function S:HandleDropDownBox(frame, width, pos)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
local frameName = frame.GetName and frame:GetName()
|
|
local button = frame.Button or frameName and (_G[frameName..'Button'] or _G[frameName..'_Button'])
|
|
local text = frameName and _G[frameName..'Text'] or frame.Text
|
|
local icon = frame.Icon
|
|
|
|
if not width then
|
|
width = 155
|
|
end
|
|
|
|
frame:StripTextures()
|
|
frame:Width(width)
|
|
|
|
frame:CreateBackdrop()
|
|
frame:SetFrameLevel(frame:GetFrameLevel() + 2)
|
|
frame.backdrop:Point('TOPLEFT', 20, -2)
|
|
frame.backdrop:Point('BOTTOMRIGHT', button, 'BOTTOMRIGHT', 2, -2)
|
|
|
|
button:ClearAllPoints()
|
|
|
|
if pos then
|
|
button:Point('TOPRIGHT', frame.Right, -20, -21)
|
|
else
|
|
button:Point('RIGHT', frame, 'RIGHT', -10, 3)
|
|
end
|
|
|
|
button.SetPoint = E.noop
|
|
S:HandleNextPrevButton(button)
|
|
|
|
if text then
|
|
text:ClearAllPoints()
|
|
text:Point('RIGHT', button, 'LEFT', -2, 0)
|
|
end
|
|
|
|
if icon then
|
|
icon:Point('LEFT', 23, 0)
|
|
end
|
|
end
|
|
|
|
function S:HandleStatusBar(frame, color)
|
|
frame:SetFrameLevel(frame:GetFrameLevel() + 1)
|
|
frame:StripTextures()
|
|
frame:CreateBackdrop('Transparent')
|
|
frame:SetStatusBarTexture(E.media.normTex)
|
|
frame:SetStatusBarColor(unpack(color or {.01, .39, .1}))
|
|
E:RegisterStatusBar(frame)
|
|
end
|
|
|
|
do
|
|
local check = [[Interface\Buttons\UI-CheckBox-Check]]
|
|
local disabled = [[Interface\Buttons\UI-CheckBox-Check-Disabled]]
|
|
function S:HandleCheckBox(frame, noBackdrop, noReplaceTextures)
|
|
assert(frame, 'does not exist.')
|
|
|
|
if frame.isSkinned then return end
|
|
|
|
frame:StripTextures()
|
|
|
|
if noBackdrop then
|
|
frame:Size(16)
|
|
else
|
|
frame:CreateBackdrop()
|
|
frame.backdrop:SetInside(nil, 4, 4)
|
|
end
|
|
|
|
if not noReplaceTextures then
|
|
if frame.SetCheckedTexture then
|
|
if E.private.skins.checkBoxSkin then
|
|
frame:SetCheckedTexture(E.Media.Textures.Melli)
|
|
|
|
local checkedTexture = frame:GetCheckedTexture()
|
|
checkedTexture:SetVertexColor(1, .82, 0, 0.8)
|
|
checkedTexture:SetInside(frame.backdrop)
|
|
else
|
|
frame:SetCheckedTexture(check)
|
|
|
|
if noBackdrop then
|
|
frame:GetCheckedTexture():SetInside(nil, -4, -4)
|
|
end
|
|
end
|
|
end
|
|
|
|
if frame.SetDisabledTexture then
|
|
if E.private.skins.checkBoxSkin then
|
|
frame:SetDisabledTexture(E.Media.Textures.Melli)
|
|
|
|
local disabledTexture = frame:GetDisabledTexture()
|
|
disabledTexture:SetVertexColor(.6, .6, .6, .8)
|
|
disabledTexture:SetInside(frame.backdrop)
|
|
else
|
|
frame:SetDisabledTexture(disabled)
|
|
|
|
if noBackdrop then
|
|
frame:GetDisabledTexture():SetInside(nil, -4, -4)
|
|
end
|
|
end
|
|
end
|
|
|
|
frame:HookScript('OnDisable', function(checkbox)
|
|
if not checkbox.SetDisabledTexture then return; end
|
|
if checkbox:GetChecked() then
|
|
if E.private.skins.checkBoxSkin then
|
|
checkbox:SetDisabledTexture(E.Media.Textures.Melli)
|
|
else
|
|
checkbox:SetDisabledTexture(disabled)
|
|
end
|
|
else
|
|
checkbox:SetDisabledTexture('')
|
|
end
|
|
end)
|
|
|
|
hooksecurefunc(frame, 'SetNormalTexture', function(checkbox, texPath)
|
|
if texPath ~= '' then checkbox:SetNormalTexture('') end
|
|
end)
|
|
hooksecurefunc(frame, 'SetPushedTexture', function(checkbox, texPath)
|
|
if texPath ~= '' then checkbox:SetPushedTexture('') end
|
|
end)
|
|
hooksecurefunc(frame, 'SetHighlightTexture', function(checkbox, texPath)
|
|
if texPath ~= '' then checkbox:SetHighlightTexture('') end
|
|
end)
|
|
hooksecurefunc(frame, 'SetCheckedTexture', function(checkbox, texPath)
|
|
if texPath == E.Media.Textures.Melli or texPath == check then return end
|
|
if E.private.skins.checkBoxSkin then
|
|
checkbox:SetCheckedTexture(E.Media.Textures.Melli)
|
|
else
|
|
checkbox:SetCheckedTexture(check)
|
|
end
|
|
end)
|
|
end
|
|
|
|
frame.isSkinned = true
|
|
end
|
|
end
|
|
|
|
function S:HandleRadioButton(Button)
|
|
if Button.isSkinned then return end
|
|
|
|
local InsideMask = Button:CreateMaskTexture()
|
|
InsideMask:SetTexture([[Interface\Minimap\UI-Minimap-Background]], 'CLAMPTOBLACKADDITIVE', 'CLAMPTOBLACKADDITIVE')
|
|
InsideMask:Size(10, 10)
|
|
InsideMask:Point('CENTER')
|
|
|
|
Button.InsideMask = InsideMask
|
|
|
|
local OutsideMask = Button:CreateMaskTexture()
|
|
OutsideMask:SetTexture([[Interface\Minimap\UI-Minimap-Background]], 'CLAMPTOBLACKADDITIVE', 'CLAMPTOBLACKADDITIVE')
|
|
OutsideMask:Size(13, 13)
|
|
OutsideMask:Point('CENTER')
|
|
|
|
Button.OutsideMask = OutsideMask
|
|
|
|
Button:SetCheckedTexture(E.media.normTex)
|
|
Button:SetNormalTexture(E.media.normTex)
|
|
Button:SetHighlightTexture(E.media.normTex)
|
|
Button:SetDisabledTexture(E.media.normTex)
|
|
|
|
local Check = Button:GetCheckedTexture()
|
|
Check:SetVertexColor(unpack(E.media.rgbvaluecolor))
|
|
Check:SetTexCoord(0, 1, 0, 1)
|
|
Check:SetInside()
|
|
Check:AddMaskTexture(InsideMask)
|
|
|
|
local Highlight = Button:GetHighlightTexture()
|
|
Highlight:SetTexCoord(0, 1, 0, 1)
|
|
Highlight:SetVertexColor(1, 1, 1)
|
|
Highlight:AddMaskTexture(InsideMask)
|
|
|
|
local Normal = Button:GetNormalTexture()
|
|
Normal:SetOutside()
|
|
Normal:SetTexCoord(0, 1, 0, 1)
|
|
Normal:SetVertexColor(unpack(E.media.bordercolor))
|
|
Normal:AddMaskTexture(OutsideMask)
|
|
|
|
local Disabled = Button:GetDisabledTexture()
|
|
Disabled:SetVertexColor(.3, .3, .3)
|
|
Disabled:AddMaskTexture(OutsideMask)
|
|
|
|
hooksecurefunc(Button, 'SetNormalTexture', function(f, t) if t ~= '' then f:SetNormalTexture('') end end)
|
|
hooksecurefunc(Button, 'SetPushedTexture', function(f, t) if t ~= '' then f:SetPushedTexture('') end end)
|
|
hooksecurefunc(Button, 'SetHighlightTexture', function(f, t) if t ~= '' then f:SetHighlightTexture('') end end)
|
|
hooksecurefunc(Button, 'SetDisabledTexture', function(f, t) if t ~= '' then f:SetDisabledTexture('') end end)
|
|
|
|
Button.isSkinned = true
|
|
end
|
|
|
|
function S:HandleIcon(icon, backdrop)
|
|
icon:SetTexCoord(unpack(E.TexCoords))
|
|
|
|
if backdrop and not icon.backdrop then
|
|
icon:CreateBackdrop()
|
|
end
|
|
end
|
|
|
|
function S:HandleItemButton(b, shrinkIcon)
|
|
if b.isSkinned then return; end
|
|
|
|
local name = b:GetName()
|
|
local icon = b.icon or b.Icon or b.IconTexture or b.iconTexture or (name and (_G[name..'IconTexture'] or _G[name..'Icon']))
|
|
local texture = icon and icon.GetTexture and icon:GetTexture()
|
|
|
|
b:StripTextures()
|
|
b:CreateBackdrop(nil, true)
|
|
b:StyleButton()
|
|
|
|
if icon then
|
|
icon:SetTexCoord(unpack(E.TexCoords))
|
|
|
|
-- create a backdrop around the icon
|
|
if shrinkIcon then
|
|
b.backdrop:SetAllPoints()
|
|
icon:SetInside(b)
|
|
else
|
|
b.backdrop:SetOutside(icon, 1, 1)
|
|
end
|
|
|
|
icon:SetParent(b.backdrop)
|
|
|
|
if texture then
|
|
icon:SetTexture(texture)
|
|
end
|
|
end
|
|
|
|
b.isSkinned = true
|
|
end
|
|
|
|
local handleCloseButtonOnEnter = function(btn) if btn.Texture then btn.Texture:SetVertexColor(unpack(E.media.rgbvaluecolor)) end end
|
|
local handleCloseButtonOnLeave = function(btn) if btn.Texture then btn.Texture:SetVertexColor(1, 1, 1) end end
|
|
|
|
function S:HandleCloseButton(f, point, x, y)
|
|
assert(f, 'doenst exist!')
|
|
|
|
f:StripTextures()
|
|
|
|
if not f.Texture then
|
|
f.Texture = f:CreateTexture(nil, 'OVERLAY')
|
|
f.Texture:Point('CENTER')
|
|
f.Texture:SetTexture(E.Media.Textures.Close)
|
|
f.Texture:Size(12, 12)
|
|
f:HookScript('OnEnter', handleCloseButtonOnEnter)
|
|
f:HookScript('OnLeave', handleCloseButtonOnLeave)
|
|
f:SetHitRectInsets(6, 6, 7, 7)
|
|
end
|
|
|
|
if point then
|
|
f:Point('TOPRIGHT', point, 'TOPRIGHT', x or 2, y or 2)
|
|
end
|
|
end
|
|
|
|
function S:HandleSliderFrame(frame)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
local orientation = frame:GetOrientation()
|
|
local SIZE = 12
|
|
|
|
frame:SetBackdrop()
|
|
frame:StripTextures()
|
|
frame:SetThumbTexture(E.Media.Textures.Melli)
|
|
|
|
if not frame.backdrop then
|
|
frame:CreateBackdrop()
|
|
frame.backdrop:SetAllPoints()
|
|
end
|
|
|
|
local thumb = frame:GetThumbTexture()
|
|
thumb:SetVertexColor(1, .82, 0, 0.8)
|
|
thumb:Size(SIZE-2,SIZE-2)
|
|
|
|
if orientation == 'VERTICAL' then
|
|
frame:Width(SIZE)
|
|
else
|
|
frame:Height(SIZE)
|
|
|
|
for i=1, frame:GetNumRegions() do
|
|
local region = select(i, frame:GetRegions())
|
|
if region and region:IsObjectType('FontString') then
|
|
local point, anchor, anchorPoint, x, y = region:GetPoint()
|
|
if strfind(anchorPoint, 'BOTTOM') then
|
|
region:Point(point, anchor, anchorPoint, x, y - 4)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- TODO: Update the function for BFA/Shadowlands
|
|
function S:HandleFollowerAbilities(followerList)
|
|
local followerTab = followerList and followerList.followerTab
|
|
local abilityFrame = followerTab.AbilitiesFrame
|
|
if not abilityFrame then return end
|
|
|
|
local abilities = abilityFrame.Abilities
|
|
if abilities then
|
|
for i = 1, #abilities do
|
|
local iconButton = abilities[i].IconButton
|
|
local icon = iconButton and iconButton.Icon
|
|
if icon then
|
|
iconButton.Border:SetAlpha(0)
|
|
S:HandleIcon(icon, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
local equipment = abilityFrame.Equipment
|
|
if equipment then
|
|
for i = 1, #equipment do
|
|
local equip = equipment[i]
|
|
if equip then
|
|
equip.Border:SetAlpha(0)
|
|
equip.BG:SetAlpha(0)
|
|
S:HandleIcon(equip.Icon, true)
|
|
equip.Icon.backdrop:SetBackdropColor(1, 1, 1, .15)
|
|
end
|
|
end
|
|
end
|
|
|
|
local combatAllySpell = abilityFrame.CombatAllySpell
|
|
if combatAllySpell then
|
|
for i = 1, #combatAllySpell do
|
|
local icon = combatAllySpell[i].iconTexture
|
|
if icon then
|
|
S:HandleIcon(icon, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
local xpbar = followerTab.XPBar
|
|
if xpbar and not xpbar.backdrop then
|
|
xpbar:StripTextures()
|
|
xpbar:SetStatusBarTexture(E.media.normTex)
|
|
xpbar:CreateBackdrop('Transparent')
|
|
end
|
|
end
|
|
|
|
function S:HandleShipFollowerPage(followerTab)
|
|
local traits = followerTab.Traits
|
|
for i = 1, #traits do
|
|
local icon = traits[i].Portrait
|
|
local border = traits[i].Border
|
|
border:SetTexture() -- I think the default border looks nice, not sure if we want to replace that
|
|
-- The landing page icons display inner borders
|
|
if followerTab.isLandingPage then
|
|
icon:SetTexCoord(unpack(E.TexCoords))
|
|
end
|
|
end
|
|
|
|
local equipment = followerTab.EquipmentFrame.Equipment
|
|
for i = 1, #equipment do
|
|
local icon = equipment[i].Icon
|
|
local border = equipment[i].Border
|
|
border:SetAtlas('ShipMission_ShipFollower-TypeFrame') -- This border is ugly though, use the traits border instead
|
|
-- The landing page icons display inner borders
|
|
if followerTab.isLandingPage then
|
|
icon:SetTexCoord(unpack(E.TexCoords))
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:HandleFollowerListOnUpdateDataFunc(Buttons, numButtons, offset, numFollowers)
|
|
if not Buttons or (not numButtons or numButtons == 0) or not offset or not numFollowers then return end
|
|
|
|
for i = 1, numButtons do
|
|
local button = Buttons[i]
|
|
local index = offset + i -- adjust index
|
|
|
|
if button then
|
|
local fl = button.Follower
|
|
if (index <= numFollowers) and not button.backdrop then
|
|
if button.mode == 'CATEGORY' then
|
|
button:CreateBackdrop('Transparent')
|
|
else
|
|
button:CreateBackdrop('NoBackdrop')
|
|
end
|
|
|
|
if button.Category then
|
|
button.Category:ClearAllPoints()
|
|
button.Category:Point('TOP', button, 'TOP', 0, -4)
|
|
end
|
|
|
|
if fl and not fl.backdrop then
|
|
fl:CreateBackdrop()
|
|
fl.Name:SetWordWrap(false)
|
|
fl.BG:Hide()
|
|
fl.Selection:SetTexture()
|
|
fl.AbilitiesBG:SetTexture()
|
|
fl.BusyFrame:SetAllPoints()
|
|
|
|
local hl = fl:GetHighlightTexture()
|
|
hl:SetColorTexture(0.9, 0.9, 0.9, 0.25)
|
|
hl:SetAllPoints()
|
|
|
|
if fl.Counters then
|
|
for y = 1, #fl.Counters do
|
|
local counter = fl.Counters[y]
|
|
if counter and not counter.backdrop then
|
|
counter:CreateBackdrop()
|
|
counter.backdrop:SetAllPoints()
|
|
counter.backdrop:SetFrameLevel(counter:GetFrameLevel())
|
|
|
|
if counter.Border then
|
|
counter.Border:SetTexture()
|
|
end
|
|
if counter.Icon then
|
|
counter.Icon:SetTexCoord(unpack(E.TexCoords))
|
|
counter.Icon:SetInside()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if fl.PortraitFrame and not fl.PortraitFrameStyled then
|
|
S:HandleGarrisonPortrait(fl.PortraitFrame)
|
|
fl.PortraitFrame:ClearAllPoints()
|
|
fl.PortraitFrame:Point('TOPLEFT', 3, -3)
|
|
fl.PortraitFrameStyled = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if fl and fl.Selection and fl.backdrop then
|
|
if fl.Selection:IsShown() then
|
|
fl.backdrop:SetBackdropColor(0.9, 0.8, 0.1, 0.25)
|
|
else
|
|
fl.backdrop:SetBackdropColor(0, 0, 0, 0.5)
|
|
end
|
|
end
|
|
|
|
if fl and fl.PortraitFrame and fl.PortraitFrame.quality then
|
|
local color = ITEM_QUALITY_COLORS[fl.PortraitFrame.quality]
|
|
if color and fl.PortraitFrame.backdrop then
|
|
fl.PortraitFrame.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
S.FollowerListUpdateDataFrames = {}
|
|
function S:HandleFollowerListOnUpdateData(frame)
|
|
if frame == 'GarrisonLandingPageFollowerList' and (E.private.skins.blizzard.orderhall ~= true or E.private.skins.blizzard.garrison ~= true) then
|
|
return -- Only hook this frame if both Garrison and Orderhall skins are enabled because it's shared.
|
|
end
|
|
|
|
if S.FollowerListUpdateDataFrames[frame] then return end -- make sure we don't double hook `GarrisonLandingPageFollowerList`
|
|
S.FollowerListUpdateDataFrames[frame] = true
|
|
|
|
hooksecurefunc(_G[frame], 'UpdateData', function(dataFrame)
|
|
if not S.FollowerListUpdateDataFrames[frame] or (not dataFrame or not dataFrame.listScroll) then return end
|
|
local buttons, list = dataFrame.listScroll.buttons, dataFrame.followersList
|
|
local offset = _G.HybridScrollFrame_GetOffset(dataFrame.listScroll)
|
|
|
|
S:HandleFollowerListOnUpdateDataFunc(buttons, buttons and #buttons, offset, list and #list)
|
|
end)
|
|
end
|
|
|
|
-- Shared Template on LandingPage/Orderhall-/Garrison-FollowerList
|
|
-- 9.0 Shadowland: Needs Update
|
|
local ReplacedRoleTex = {
|
|
['Adventures-Tank'] = 'Soulbinds_Tree_Conduit_Icon_Protect',
|
|
['Adventures-Healer'] = 'ui_adv_health',
|
|
['Adventures-DPS'] = 'ui_adv_atk',
|
|
['Adventures-DPS-Ranged'] = 'Soulbinds_Tree_Conduit_Icon_Utility',
|
|
}
|
|
|
|
local function HandleFollowerRole(roleIcon, atlas)
|
|
local newAtlas = ReplacedRoleTex[atlas]
|
|
if newAtlas then
|
|
roleIcon:SetAtlas(newAtlas)
|
|
end
|
|
end
|
|
|
|
function S:HandleGarrisonPortrait(portrait)
|
|
if not portrait.Portrait then return end
|
|
|
|
local level = portrait.Level or portrait.LevelText
|
|
if level then
|
|
level:ClearAllPoints()
|
|
level:Point('BOTTOM', portrait, 0, 12)
|
|
level:FontTemplate(nil, 12, 'OUTLINE')
|
|
if portrait.LevelCircle then portrait.LevelCircle:Hide() end
|
|
if portrait.LevelBorder then portrait.LevelBorder:SetScale(.0001) end
|
|
end
|
|
|
|
portrait.Portrait:CreateBackdrop('Transparent')
|
|
|
|
if portrait.PortraitRing then
|
|
portrait.PortraitRing:Hide()
|
|
portrait.PortraitRingQuality:SetTexture('')
|
|
portrait.PortraitRingCover:SetColorTexture(0, 0, 0)
|
|
portrait.PortraitRingCover:SetAllPoints(portrait.Portrait.backdrop)
|
|
end
|
|
|
|
if portrait.Empty then
|
|
portrait.Empty:SetColorTexture(0, 0, 0)
|
|
portrait.Empty:SetAllPoints(portrait.Portrait)
|
|
end
|
|
|
|
if portrait.Highlight then portrait.Highlight:Hide() end
|
|
if portrait.PuckBorder then portrait.PuckBorder:SetAlpha(0) end
|
|
|
|
if portrait.HealthBar then
|
|
portrait.HealthBar.Border:Hide()
|
|
|
|
local roleIcon = portrait.HealthBar.RoleIcon
|
|
roleIcon:ClearAllPoints()
|
|
roleIcon:Point('CENTER', portrait.Portrait.backdrop, 'TOPRIGHT')
|
|
hooksecurefunc(roleIcon, 'SetAtlas', HandleFollowerRole)
|
|
|
|
local background = portrait.HealthBar.Background
|
|
background:SetAlpha(0)
|
|
background:ClearAllPoints()
|
|
background:Point('TOPLEFT', portrait.Portrait.backdrop, 'BOTTOMLEFT', 1, 6)
|
|
background:Point('BOTTOMRIGHT', portrait.Portrait.backdrop, 'BOTTOMRIGHT', -1, 1)
|
|
portrait.HealthBar.Health:SetTexture(E.media.normTex)
|
|
end
|
|
end
|
|
|
|
-- Interface\SharedXML\SharedUIPanelTemplatex.xml - line 780
|
|
function S:HandleTooltipBorderedFrame(frame)
|
|
assert(frame, 'doesnt exist!')
|
|
|
|
if frame.BorderTopLeft then frame.BorderTopLeft:Hide() end
|
|
if frame.BorderTopRight then frame.BorderTopRight:Hide() end
|
|
|
|
if frame.BorderBottomLeft then frame.BorderBottomLeft:Hide() end
|
|
if frame.BorderBottomRight then frame.BorderBottomRight:Hide() end
|
|
|
|
if frame.BorderTop then frame.BorderTop:Hide() end
|
|
if frame.BorderBottom then frame.BorderBottom:Hide() end
|
|
if frame.BorderLeft then frame.BorderLeft:Hide() end
|
|
if frame.BorderRight then frame.BorderRight:Hide() end
|
|
|
|
if frame.Background then frame.Background:Hide() end
|
|
|
|
frame:CreateBackdrop('Transparent')
|
|
end
|
|
|
|
function S:HandleIconSelectionFrame(frame, numIcons, buttonNameTemplate, frameNameOverride)
|
|
assert(frame, 'HandleIconSelectionFrame: frame argument missing')
|
|
assert(numIcons and type(numIcons) == 'number', 'HandleIconSelectionFrame: numIcons argument missing or not a number')
|
|
assert(buttonNameTemplate and type(buttonNameTemplate) == 'string', 'HandleIconSelectionFrame: buttonNameTemplate argument missing or not a string')
|
|
|
|
local frameName = frameNameOverride or frame:GetName() --We need override in case Blizzard fucks up the naming (guild bank)
|
|
local scrollFrame = _G[frameName..'ScrollFrame']
|
|
local editBox = _G[frameName..'EditBox']
|
|
|
|
frame:StripTextures()
|
|
frame.BorderBox:StripTextures()
|
|
scrollFrame:StripTextures()
|
|
editBox:DisableDrawLayer('BACKGROUND') -- Removes textures around it
|
|
|
|
frame:CreateBackdrop('Transparent')
|
|
frame:Height(frame:GetHeight() + 10)
|
|
scrollFrame:Height(scrollFrame:GetHeight() + 10)
|
|
|
|
for i = 1, numIcons do
|
|
local button = _G[buttonNameTemplate..i]
|
|
if button then
|
|
button:StripTextures()
|
|
button:CreateBackdrop()
|
|
button:StyleButton(true)
|
|
|
|
local icon = _G[buttonNameTemplate..i..'Icon']
|
|
if icon then
|
|
icon:SetTexCoord(unpack(E.TexCoords))
|
|
icon:Point('TOPLEFT', 1, -1)
|
|
icon:Point('BOTTOMRIGHT', -1, 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:HandleNextPrevButton(btn, arrowDir, color, noBackdrop, stripTexts)
|
|
if btn.isSkinned then return end
|
|
|
|
if not arrowDir then
|
|
arrowDir = 'down'
|
|
local name = btn:GetDebugName()
|
|
local ButtonName = name and name:lower()
|
|
if ButtonName then
|
|
if strfind(ButtonName, 'left') or strfind(ButtonName, 'prev') or strfind(ButtonName, 'decrement') or strfind(ButtonName, 'backward') or strfind(ButtonName, 'back') then
|
|
arrowDir = 'left'
|
|
elseif strfind(ButtonName, 'right') or strfind(ButtonName, 'next') or strfind(ButtonName, 'increment') or strfind(ButtonName, 'forward') then
|
|
arrowDir = 'right'
|
|
elseif strfind(ButtonName, 'scrollup') or strfind(ButtonName, 'upbutton') or strfind(ButtonName, 'top') or strfind(ButtonName, 'asc') or strfind(ButtonName, 'home') or strfind(ButtonName, 'maximize') then
|
|
arrowDir = 'up'
|
|
end
|
|
end
|
|
end
|
|
|
|
btn:StripTextures()
|
|
if not noBackdrop then
|
|
S:HandleButton(btn)
|
|
end
|
|
|
|
if stripTexts then
|
|
btn:StripTexts()
|
|
end
|
|
|
|
btn:SetNormalTexture(E.Media.Textures.ArrowUp)
|
|
btn:SetPushedTexture(E.Media.Textures.ArrowUp)
|
|
btn:SetDisabledTexture(E.Media.Textures.ArrowUp)
|
|
|
|
local Normal, Disabled, Pushed = btn:GetNormalTexture(), btn:GetDisabledTexture(), btn:GetPushedTexture()
|
|
|
|
if noBackdrop then
|
|
btn:Size(20, 20)
|
|
Disabled:SetVertexColor(.5, .5, .5)
|
|
btn.Texture = Normal
|
|
|
|
if not color then
|
|
btn:HookScript('OnEnter', handleCloseButtonOnEnter)
|
|
btn:HookScript('OnLeave', handleCloseButtonOnLeave)
|
|
end
|
|
else
|
|
btn:Size(18, 18)
|
|
Disabled:SetVertexColor(.3, .3, .3)
|
|
end
|
|
|
|
Normal:SetInside()
|
|
Pushed:SetInside()
|
|
Disabled:SetInside()
|
|
|
|
Normal:SetTexCoord(0, 1, 0, 1)
|
|
Pushed:SetTexCoord(0, 1, 0, 1)
|
|
Disabled:SetTexCoord(0, 1, 0, 1)
|
|
|
|
local rotation = S.ArrowRotation[arrowDir]
|
|
if rotation then
|
|
Normal:SetRotation(rotation)
|
|
Pushed:SetRotation(rotation)
|
|
Disabled:SetRotation(rotation)
|
|
end
|
|
|
|
if color then
|
|
Normal:SetVertexColor(color.r, color.g, color.b)
|
|
else
|
|
Normal:SetVertexColor(1, 1, 1)
|
|
end
|
|
|
|
btn.isSkinned = true
|
|
end
|
|
|
|
-- World Map related Skinning functions used for WoW 8.0
|
|
function S:WorldMapMixin_AddOverlayFrame(frame, templateName)
|
|
S[templateName](frame.overlayFrames[#frame.overlayFrames])
|
|
end
|
|
|
|
-- UIWidgets
|
|
function S:SkinIconAndTextWidget()
|
|
end
|
|
|
|
-- For now see the function below
|
|
function S:SkinCaptureBarWidget()
|
|
end
|
|
|
|
function S:SkinStatusBarWidget(widgetFrame)
|
|
local bar = widgetFrame.Bar
|
|
if bar and not bar.IsSkinned then
|
|
-- Hide StatusBar textures
|
|
if bar.BorderLeft then bar.BorderLeft:Hide() end
|
|
if bar.BorderRight then bar.BorderRight:Hide() end
|
|
if bar.BorderCenter then bar.BorderCenter:Hide() end
|
|
if bar.BGLeft then bar.BGLeft:Hide() end
|
|
if bar.BGRight then bar.BGRight:Hide() end
|
|
if bar.BGCenter then bar.BGCenter:Hide() end
|
|
|
|
if not bar.backdrop then
|
|
bar:CreateBackdrop()
|
|
end
|
|
|
|
bar.backdrop:Point('TOPLEFT', -2, 2)
|
|
bar.backdrop:Point('BOTTOMRIGHT', 2, -2)
|
|
|
|
bar.IsSkinned = true
|
|
end
|
|
end
|
|
|
|
-- For now see the function below
|
|
function S:SkinDoubleStatusBarWidget()
|
|
end
|
|
|
|
function S:SkinIconTextAndBackgroundWidget()
|
|
end
|
|
|
|
function S:SkinDoubleIconAndTextWidget()
|
|
end
|
|
|
|
function S:SkinStackedResourceTrackerWidget()
|
|
end
|
|
|
|
function S:SkinIconTextAndCurrenciesWidget()
|
|
end
|
|
|
|
function S:SkinTextWithStateWidget(widgetFrame)
|
|
local text = widgetFrame.Text
|
|
|
|
if text then
|
|
text:SetTextColor(1, 1, 1)
|
|
end
|
|
end
|
|
|
|
function S:SkinHorizontalCurrenciesWidget()
|
|
end
|
|
|
|
function S:SkinBulletTextListWidget()
|
|
end
|
|
|
|
function S:SkinScenarioHeaderCurrenciesAndBackgroundWidget()
|
|
end
|
|
|
|
function S:SkinTextureAndTextWidget()
|
|
end
|
|
|
|
function S:SkinSpellDisplay(widgetFrame)
|
|
local spell = widgetFrame.Spell
|
|
if not spell then return end
|
|
|
|
if spell.Border then
|
|
spell.Border:Hide()
|
|
end
|
|
|
|
if spell.Text then
|
|
spell.Text:SetTextColor(1, 1, 1)
|
|
end
|
|
|
|
if spell.Icon then
|
|
S:HandleIcon(spell.Icon)
|
|
|
|
if not spell.Icon.backdrop then
|
|
spell.Icon:CreateBackdrop()
|
|
end
|
|
|
|
local x = E.PixelMode and 1 or 2
|
|
spell.Icon.backdrop:ClearAllPoints()
|
|
spell.Icon.backdrop:Point('TOPLEFT', spell.Icon, -x, x)
|
|
spell.Icon.backdrop:Point('BOTTOMRIGHT', spell.Icon, x, -x)
|
|
end
|
|
end
|
|
|
|
function S:SkinDoubleStateIconRow()
|
|
end
|
|
|
|
function S:SkinTextureAndTextRowWidget()
|
|
end
|
|
|
|
function S:SkinZoneControl()
|
|
end
|
|
|
|
function S:SkinCaptureZone()
|
|
end
|
|
|
|
do
|
|
local W = Enum.UIWidgetVisualizationType
|
|
S.WidgetSkinningFuncs = {
|
|
[W.IconAndText] = 'SkinIconAndTextWidget',
|
|
[W.CaptureBar] = 'SkinCaptureBarWidget',
|
|
[W.StatusBar] = 'SkinStatusBarWidget',
|
|
[W.DoubleStatusBar] = 'SkinDoubleStatusBarWidget',
|
|
[W.IconTextAndBackground] = 'SkinIconTextAndBackgroundWidget',
|
|
[W.DoubleIconAndText] = 'SkinDoubleIconAndTextWidget',
|
|
[W.StackedResourceTracker] = 'SkinStackedResourceTrackerWidget',
|
|
[W.IconTextAndCurrencies] = 'SkinIconTextAndCurrenciesWidget',
|
|
[W.TextWithState] = 'SkinTextWithStateWidget',
|
|
[W.HorizontalCurrencies] = 'SkinHorizontalCurrenciesWidget',
|
|
[W.BulletTextList] = 'SkinBulletTextListWidget',
|
|
[W.ScenarioHeaderCurrenciesAndBackground] = 'SkinScenarioHeaderCurrenciesAndBackgroundWidget',
|
|
[W.TextureAndText] = 'SkinTextureAndTextWidget',
|
|
[W.SpellDisplay] = 'SkinSpellDisplay',
|
|
[W.DoubleStateIconRow] = 'SkinDoubleStateIconRow',
|
|
[W.TextureAndTextRow] = 'SkinTextureAndTextRowWidget',
|
|
[W.ZoneControl] = 'SkinZoneControl',
|
|
[W.CaptureZone] = 'SkinCaptureZone'
|
|
}
|
|
end
|
|
|
|
function S:SkinWidgetContainer(widgetContainer)
|
|
for _, child in ipairs({widgetContainer:GetChildren()}) do
|
|
if S.WidgetSkinningFuncs[child.widgetType] then
|
|
S[S.WidgetSkinningFuncs[child.widgetType]](S, child)
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:ADDON_LOADED(_, addonName)
|
|
if not self.allowBypass[addonName] and not E.initialized then
|
|
return
|
|
end
|
|
|
|
local object = self.addonsToLoad[addonName]
|
|
if object then
|
|
S:CallLoadedAddon(addonName, object)
|
|
end
|
|
end
|
|
|
|
-- EXAMPLE:
|
|
--- S:AddCallbackForAddon('Details', 'MyAddon_Details', MyAddon.SkinDetails)
|
|
---- arg1: Addon name (same as the toc): MyAddon.toc (without extension)
|
|
---- arg2: Given name (try to use something that won't be used by someone else)
|
|
---- arg3: load function (preferably not-local)
|
|
-- this is used for loading skins that should be executed when the addon loads (including blizzard addons that load later).
|
|
-- please add a given name, non-given-name is specific for elvui core addon.
|
|
function S:AddCallbackForAddon(addonName, name, func, forceLoad, bypass, position) -- arg2: name is 'given name'; see example above.
|
|
local load = (name == 'function' and name) or (not func and (S[name] or S[addonName]))
|
|
S:RegisterSkin(addonName, load or func, forceLoad, bypass, position)
|
|
end
|
|
|
|
-- nonAddonsToLoad:
|
|
--- this is used for loading skins when our skin init function executes.
|
|
--- please add a given name, non-given-name is specific for elvui core addon.
|
|
function S:AddCallback(name, func, position) -- arg1: name is 'given name'
|
|
local load = (name == 'function' and name) or (not func and S[name])
|
|
S:RegisterSkin('ElvUI', load or func, nil, nil, position)
|
|
end
|
|
|
|
local function errorhandler(err)
|
|
return _G.geterrorhandler()(err)
|
|
end
|
|
|
|
function S:RegisterSkin(addonName, func, forceLoad, bypass, position)
|
|
if bypass then
|
|
self.allowBypass[addonName] = true
|
|
end
|
|
|
|
if forceLoad then
|
|
xpcall(func, errorhandler)
|
|
self.addonsToLoad[addonName] = nil
|
|
elseif addonName == 'ElvUI' then
|
|
if position then
|
|
tinsert(self.nonAddonsToLoad, position, func)
|
|
else
|
|
tinsert(self.nonAddonsToLoad, func)
|
|
end
|
|
else
|
|
local addon = self.addonsToLoad[addonName]
|
|
if not addon then
|
|
self.addonsToLoad[addonName] = {}
|
|
addon = self.addonsToLoad[addonName]
|
|
end
|
|
|
|
if position then
|
|
tinsert(addon, position, func)
|
|
else
|
|
tinsert(addon, func)
|
|
end
|
|
end
|
|
end
|
|
|
|
function S:CallLoadedAddon(addonName, object)
|
|
for _, func in next, object do
|
|
xpcall(func, errorhandler)
|
|
end
|
|
|
|
self.addonsToLoad[addonName] = nil
|
|
end
|
|
|
|
function S:Initialize()
|
|
self.Initialized = true
|
|
self.db = E.private.skins
|
|
|
|
for index, func in next, self.nonAddonsToLoad do
|
|
xpcall(func, errorhandler)
|
|
self.nonAddonsToLoad[index] = nil
|
|
end
|
|
|
|
for addonName, object in pairs(self.addonsToLoad) do
|
|
local isLoaded, isFinished = IsAddOnLoaded(addonName)
|
|
if isLoaded and isFinished then
|
|
S:CallLoadedAddon(addonName, object)
|
|
end
|
|
end
|
|
|
|
-- Early Skin Handling (populated before ElvUI is loaded from the Ace3 file)
|
|
if E.private.skins.ace3Enable and S.EarlyAceWidgets then
|
|
for _, n in next, S.EarlyAceWidgets do
|
|
if n.SetLayout then
|
|
S:Ace3_RegisterAsContainer(n)
|
|
else
|
|
S:Ace3_RegisterAsWidget(n)
|
|
end
|
|
end
|
|
for _, n in next, S.EarlyAceTooltips do
|
|
S:Ace3_SkinTooltip(_G.LibStub(n, true))
|
|
end
|
|
end
|
|
if S.EarlyDropdowns then
|
|
for _, n in next, S.EarlyDropdowns do
|
|
S:SkinLibDropDownMenu(n)
|
|
end
|
|
end
|
|
|
|
do -- Credits ShestakUI
|
|
hooksecurefunc(_G.UIWidgetTemplateCaptureBarMixin, 'Setup', function(info)
|
|
info.LeftLine:SetAlpha(0)
|
|
info.RightLine:SetAlpha(0)
|
|
info.BarBackground:SetAlpha(0)
|
|
info.Glow1:SetAlpha(0)
|
|
info.Glow2:SetAlpha(0)
|
|
info.Glow3:SetAlpha(0)
|
|
|
|
info.LeftBar:SetTexture(E.media.normTex)
|
|
info.NeutralBar:SetTexture(E.media.normTex)
|
|
info.RightBar:SetTexture(E.media.normTex)
|
|
|
|
info.LeftBar:SetVertexColor(0.2, 0.6, 1)
|
|
info.NeutralBar:SetVertexColor(0.8, 0.8, 0.8)
|
|
info.RightBar:SetVertexColor(0.9, 0.2, 0.2)
|
|
|
|
if not info.backdrop then
|
|
info:CreateBackdrop()
|
|
info.backdrop:Point('TOPLEFT', info.LeftBar, -2, 2)
|
|
info.backdrop:Point('BOTTOMRIGHT', info.RightBar, 2, -2)
|
|
end
|
|
end)
|
|
|
|
local frame = CreateFrame('Frame')
|
|
frame:RegisterEvent('PLAYER_ENTERING_WORLD')
|
|
frame:RegisterEvent('UPDATE_ALL_UI_WIDGETS')
|
|
frame:SetScript('OnEvent', function()
|
|
for _, widgetFrame in pairs(_G.UIWidgetTopCenterContainerFrame.widgetFrames) do
|
|
if widgetFrame.widgetType == _G.Enum.UIWidgetVisualizationType.DoubleStatusBar then
|
|
for _, bar in pairs({widgetFrame.LeftBar, widgetFrame.RightBar}) do
|
|
if not bar.IsSkinned then
|
|
bar.BG:SetAlpha(0)
|
|
bar.BorderLeft:SetAlpha(0)
|
|
bar.BorderRight:SetAlpha(0)
|
|
bar.BorderCenter:SetAlpha(0)
|
|
bar.Spark:SetAlpha(0)
|
|
bar.SparkGlow:SetAlpha(0)
|
|
bar.BorderGlow:SetAlpha(0)
|
|
|
|
bar:CreateBackdrop('Transparent')
|
|
|
|
bar.IsSkinned = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
--[[hooksecurefunc('TriStateCheckbox_SetState', function(_, checkButton)
|
|
if checkButton.forceSaturation then
|
|
local tex = checkButton:GetCheckedTexture()
|
|
if checkButton.state == 2 then
|
|
tex:SetDesaturated(false)
|
|
tex:SetVertexColor(unpack(E.media.rgbvaluecolor))
|
|
elseif checkButton.state == 1 then
|
|
tex:SetVertexColor(0.6, 0.6, 0.6)
|
|
end
|
|
end
|
|
end)]]
|
|
end
|
|
|
|
-- Keep this outside, it's used for skinning addons before ElvUI load
|
|
S:RegisterEvent('ADDON_LOADED')
|
|
|
|
E:RegisterModule(S:GetName())
|