You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2304 lines
70 KiB

local AS, L, S, R = unpack(AddOnSkins)
local _G, _ = _G
local tremove, unpack, next, ipairs, pairs = tremove, unpack, next, ipairs, pairs
local abs, min, max, floor = abs, min, max, floor
local strlower, strfind, type = strlower, strfind, type
local hooksecurefunc = hooksecurefunc
local GetPhysicalScreenSize = GetPhysicalScreenSize
local CopyTable = CopyTable
local CreateFrame = CreateFrame
local UIParent = UIParent
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
local LibStub = _G.LibStub
S.Classic = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC
S.Retail = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE
S.TBC = WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC
S.Wrath = WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC
S.Hider = CreateFrame('Frame')
S.Hider:Hide()
S.noop = function() end
local BlizzardRegions = { 'Left', 'Middle', 'Right', 'LeftDisabled', 'MiddleDisabled', 'RightDisabled', 'TopLeft', 'TopRight', 'BottomLeft', 'BottomRight', 'TopMiddle', 'MiddleLeft', 'MiddleRight', 'BottomMiddle', 'MiddleMiddle', 'Center', 'TopTex', 'TopLeftTex', 'TopRightTex', 'LeftTex', 'BottomTex', 'BottomLeftTex', 'BottomRightTex', 'RightTex', 'MiddleTex', 'TabSpacer', 'TabSpacer1', 'TabSpacer2', '_RightSeparator', '_LeftSeparator', 'Cover', 'Mid', 'Border', 'Background', 'Delimiter' }
local BlizzardFrames = { 'Inset', 'inset', 'InsetFrame', 'LeftInset', 'RightInset', 'NineSlice', 'BG', 'bgLeft', 'bgRight', 'border', 'Border', 'BorderFrame', 'bottomInset', 'BottomInset', 'FilligreeOverlay', 'PortraitOverlay', 'ArtOverlayFrame', 'Portrait', 'portrait', 'ScrollFrameBorder' }
local BlizzardTextureIDs = {
[137056] = true, -- Interface\\Tooltips\\UI-Tooltip-Background
[137057] = true, -- Interface\\Tooltips\\UI-Tooltip-Border
[131080] = true, -- Interface\\DialogFrame\\UI-DialogBox-Header
[130838] = true, -- Interface\\Buttons\\UI-PlusButton-UP
[130836] = true, -- Interface\\Buttons\\UI-PlusButton-DOWN
[130821] = true, -- Interface\\Buttons\\UI-MinusButton-UP
[130820] = true, -- Interface\\Buttons\\UI-MinusButton-DOWN
[251966] = true, -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background
[251963] = true, -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
[130843] = true, -- Interface\\Buttons\\UI-RadioButton
[130755] = true, -- Interface\\Buttons\\UI-CheckBox-Up
[130751] = true, -- Interface\\Buttons\\UI-CheckBox-Check
[130753] = true, -- Interface\\Buttons\\UI-CheckBox-Highlight
}
-- Depends on the arrow texture to be up by default.
S.ArrowRotation = {
up = 0,
down = 3.14,
left = 1.57,
right = -1.57,
}
S.Media = {
valueColor = { 1, 1, 1, 1 },
borderColor = { 0, 0, 0, 1 },
defaultBackdrop = { 0, 0, 0, 1 },
transparentBackdrop = { 0, 0, 0, .8 },
barTexture = 'Solid',
TexCoords = { .075, .925, .075, .925 },
ClearTexture = S.Retail and 0 or '',
Blank = AS.Libs.LSM:Fetch('statusbar', 'Solid'),
StatusBar = AS.Libs.LSM:Fetch('statusbar', 'Solid'),
Close = [[Interface\AddOns\AddOnSkins\Media\Textures\Close]],
Plus = [[Interface\AddOns\AddOnSkins\Media\Textures\Plus]],
Minus = [[Interface\AddOns\AddOnSkins\Media\Textures\Minus]],
QuestBang = [[Interface\AddOns\AddOnSkins\Media\Textures\UI-Icon-QuestBang]],
Arrow = [[Interface\AddOns\AddOnSkins\Media\Textures\Arrow]],
}
S.Templates = {}
S.Shadows = {}
S.Backdrops = {}
S.StatusBars = {}
S.Texts = {}
function AS:UpdateSettings()
for Frame in pairs(S.Templates) do
S:SetTemplate(Frame)
end
end
local shadowTemplate = { edgeFile = [[Interface\AddOns\AddOnSkins\Media\Textures\Shadows]], edgeSize = 3 }
local Media = S.Media
-- Toolkit API
S.mult = 1
S.border = 1
S.PixelMode = false
_, S.ScreenHeight = GetPhysicalScreenSize()
S.UIScale = 1
function S:Scale(number)
return S.mult * floor(number/S.mult + .5)
end
function S:GetPixelScale()
S.mult = max(0.4, min(1.15, 768 / S.ScreenHeight)) / UIParent:GetEffectiveScale()
S.border = S.mult * (AS:CheckOption('Theme') == 'ThickBorder' and 3 or AS:CheckOption('Theme') == 'TwoPixel' and 2 or 1)
S.PixelMode = AS:CheckOption('Theme') == 'PixelPerfect'
S.UIScale = UIParent:GetEffectiveScale()
end
function S:ColorGradient(perc, ...)
local value = select('#', ...)
if perc >= 1 then
return select(value - 2, ...)
elseif perc <= 0 then
return ...
end
local num = value / 3
local segment, relperc = math.modf(perc*(num-1))
local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...)
return r1+(r2-r1)*relperc, g1+(g2-g1)*relperc, b1+(b2-b1)*relperc
end
function S:Kill(Object)
if Object.UnregisterAllEvents then
Object:UnregisterAllEvents()
Object:SetParent(S.Hider)
else
Object.Show = Object.Hide
end
Object:Hide()
end
function S:AdjustForTheme(number, offset)
local Theme = AS:CheckOption('Theme')
local isNegative = number < 0
number = abs(number)
if Theme == 'TwoPixel' then
number = number + (offset or 1)
elseif Theme == 'ThickBorder' then
number = number + (offset or 2)
end
return isNegative and -number or number
end
-- 8.2 restricted frame check
function S:SetPointsRestricted(frame)
if frame and not pcall(frame.GetPoint, frame) then
return true
end
end
function S:SafeGetPoint(frame)
if frame and frame.GetPoint and not S:SetPointsRestricted(frame) then
return frame:GetPoint()
end
end
function S:WatchPixelSnap(frame, snap)
if (frame and not frame:IsForbidden()) and frame.PixelSnapDisabled and snap then
frame.PixelSnapDisabled = nil
end
end
function S:DisablePixelSnap(frame)
if (frame and not frame:IsForbidden()) and not frame.PixelSnapDisabled then
if frame.SetSnapToPixelGrid then
frame:SetSnapToPixelGrid(false)
frame:SetTexelSnappingBias(0)
elseif frame.GetStatusBarTexture then
local texture = frame:GetStatusBarTexture()
if type(texture) == 'table' and texture.SetSnapToPixelGrid then
texture:SetSnapToPixelGrid(false)
texture:SetTexelSnappingBias(0)
end
end
frame.PixelSnapDisabled = true
end
end
function S:BackdropFrameLevel(frame, level)
frame:SetFrameLevel(level)
if frame.oborder then frame.oborder:SetFrameLevel(level) end
if frame.iborder then frame.iborder:SetFrameLevel(level) end
end
function S:BackdropFrameLower(backdrop, parent)
local level = parent:GetFrameLevel()
local minus = level and (level - 1)
if minus and (minus >= 0) then
S:BackdropFrameLevel(backdrop, minus)
else
S:BackdropFrameLevel(backdrop, 0)
end
end
function S:Size(frame, width, height, ...)
local w = S:Scale(width)
frame:SetSize(w, (height and S:Scale(height)) or w, ...)
end
function S:Width(frame, width, ...)
frame:SetWidth(S:Scale(width), ...)
end
function S:Height(frame, height, ...)
frame:SetHeight(S:Scale(height), ...)
end
function S:Point(obj, arg1, arg2, arg3, arg4, arg5, ...)
if not arg2 then arg2 = obj:GetParent() end
if type(arg2) == 'number' then arg2 = S:Scale(arg2) end
if type(arg3) == 'number' then arg3 = S:Scale(arg3) end
if type(arg4) == 'number' then arg4 = S:Scale(arg4) end
if type(arg5) == 'number' then arg5 = S:Scale(arg5) end
obj:SetPoint(arg1, arg2, arg3, arg4, arg5, ...)
end
function S:GetAnchorOffsets(obj, xOffset, yOffset, noScale)
if not xOffset then xOffset = S.border end
if not yOffset then yOffset = S.border end
local x = (noScale and xOffset) or S:Scale(xOffset)
local y = (noScale and yOffset) or S:Scale(yOffset)
if S:SetPointsRestricted(obj) or obj:GetPoint() then
obj:ClearAllPoints()
end
S:DisablePixelSnap(obj)
return x, y
end
function S:SetOutside(obj, anchor, xOffset, yOffset, anchor2, noScale)
local x, y = S:GetAnchorOffsets(obj, xOffset, yOffset, noScale)
anchor = anchor or obj:GetParent()
obj:SetPoint('TOPLEFT', anchor, 'TOPLEFT', -x, y)
obj:SetPoint('BOTTOMRIGHT', anchor2 or anchor, 'BOTTOMRIGHT', x, -y)
end
function S:SetInside(obj, anchor, xOffset, yOffset, anchor2, noScale)
local x, y = S:GetAnchorOffsets(obj, xOffset, yOffset, noScale)
anchor = anchor or obj:GetParent()
obj:SetPoint('TOPLEFT', anchor, 'TOPLEFT', x, -y)
obj:SetPoint('BOTTOMRIGHT', anchor2 or anchor, 'BOTTOMRIGHT', -x, y)
end
do
local borders = { 'iborder', 'oborder' }
local borderBackdrop = { edgeFile = Media.Blank }
local backdrop = { edgeFile = Media.Blank }
local blank = { 0, 0, 0, 0 }
function S:GetTemplate(template)
if template == 'Custom' then
return AS:CheckOption('CustomBorderColor'), AS:CheckOption('CustomBackdropColor')
end
return Media.borderColor, template == 'Transparent' and Media.transparentBackdrop or Media.defaultBackdrop
end
function S:ToggleBorders(frame, enabled)
for _, which in pairs(borders) do
if frame[which] then
frame[which]:SetShown(enabled)
end
end
end
function S:SetTemplate(frame, template, glossTex, ignoreUpdates, _, _, _, noScale, noHook)
frame.template = template or AS:CheckOption('SkinTemplate')
frame.glossTex = glossTex and (type(glossTex) == 'string' and glossTex or AS.Libs.LSM:Fetch('statusbar', AS:CheckOption('StatusBarTexture')))
frame.forcedBorderColors = frame.template == 'NoBorder' and blank or frame.forcedBorderColors
frame.ignoreUpdates = ignoreUpdates
local borderColor, backdropColor = S:GetTemplate(frame.template)
if not frame.SetBackdrop then
_G.Mixin(frame, _G.BackdropTemplateMixin)
if not noHook then
frame:HookScript('OnSizeChanged', frame.OnBackdropSizeChanged)
end
end
if frame.template == 'NoBackdrop' then
frame:SetBackdrop()
S.Templates[frame] = nil
if frame.iborder then
frame.iborder:SetShown(false)
frame.oborder:SetShown(false)
end
else
local level = frame:GetFrameLevel()
local edgeSize = AS:CheckOption('Theme') == 'TwoPixel' and 2 or 1
backdrop.bgFile = frame.glossTex or Media.Blank
backdrop.edgeSize = noScale and edgeSize or S:Scale(edgeSize)
frame:SetBackdrop(backdrop)
if frame.callbackBackdropColor then
frame:callbackBackdropColor()
else
local r, g, b, a = unpack(backdropColor)
frame:SetBackdropColor(r, g, b, frame.customBackdropAlpha or a)
end
borderBackdrop.edgeSize = noScale and 1 or S:Scale(1)
for _, which in pairs(borders) do
local border = CreateFrame('Frame', nil, frame, 'BackdropTemplate')
border:SetBackdrop(borderBackdrop)
border:SetBackdropBorderColor(0, 0, 0, 1)
border:SetFrameLevel(level)
frame[which] = border
end
S:SetInside(frame.iborder, frame, 1, 1, nil, noScale)
S:SetOutside(frame.oborder, frame, 1, 1, nil, noScale)
frame.iborder:SetShown(frame.template == 'NoBorder' or AS:CheckOption('Theme') == 'TwoPixel')
frame.oborder:SetShown(frame.template == 'NoBorder' or AS:CheckOption('Theme') == 'TwoPixel')
if frame.forcedBorderColors then
borderColor = frame.forcedBorderColors
end
if frame.template ~= 'NoBorder' then
frame:SetBackdropBorderColor(unpack(borderColor))
end
S.Templates[frame] = not frame.ignoreUpdates and true
end
end
end
function S:CreateBackdrop(frame, template, glossTex, ignoreUpdates, _, _, _, noScale, allPoints, frameLevel)
local parent = (frame.IsObjectType and frame:IsObjectType('Texture') and frame:GetParent()) or frame
local backdrop = frame.backdrop or CreateFrame('Frame', nil, parent)
if not frame.backdrop then frame.backdrop = backdrop end
S:SetTemplate(backdrop, template, glossTex, ignoreUpdates, _, _, _, noScale)
if allPoints then
if allPoints == true then
backdrop:SetAllPoints()
else
backdrop:SetAllPoints(allPoints)
end
else
S:SetOutside(backdrop, frame, nil, nil, nil, noScale)
end
if frameLevel then
if frameLevel == true then
S:BackdropFrameLevel(backdrop, parent:GetFrameLevel())
else
S:BackdropFrameLevel(backdrop, frameLevel)
end
else
S:BackdropFrameLower(backdrop, parent)
end
end
function S:CreateShadow(frame, size, pass)
if not pass and frame.shadow then return end
if not size then size = 3 end
local offset = (S.PixelMode and size) or (size + 1)
local shadow = CreateFrame('Frame', nil, frame, 'BackdropTemplate')
shadow:SetFrameLevel(1)
shadow:SetFrameStrata(frame:GetFrameStrata())
S:SetOutside(shadow, frame, offset, offset, nil, true)
shadow:SetBackdrop(shadowTemplate)
shadow:SetBackdropColor(0, 0, 0, 0)
shadow:SetBackdropBorderColor(0, 0, 0, 0.9)
S.Shadows[shadow] = true
if pass then
return shadow
else
frame.shadow = shadow
end
end
local STRIP_TEX = 'Texture'
local STRIP_FONT = 'FontString'
local function StripRegion(which, object, kill, zero)
if kill then
object:Kill()
elseif zero then
object:SetAlpha(0)
elseif which == STRIP_TEX then
object:SetTexture('')
object:SetAtlas('')
elseif which == STRIP_FONT then
object:SetText('')
end
end
local function StripType(which, object, kill, zero)
if object:IsObjectType(which) then
StripRegion(which, object, kill, zero)
else
if which == STRIP_TEX then
local FrameName = object.GetName and object:GetName()
for _, Blizzard in pairs(BlizzardFrames) do
local BlizzFrame = object[Blizzard] or (FrameName and _G[FrameName..Blizzard])
if BlizzFrame and BlizzFrame.StripTextures then
S:StripTextures(BlizzFrame, kill, zero)
end
end
end
if object.GetNumRegions then
for _, region in next, { object:GetRegions() } do
if region and region.IsObjectType and region:IsObjectType(which) then
StripRegion(which, region, kill, zero)
end
end
end
end
end
function S:StripTextures(object, kill, zero)
StripType(STRIP_TEX, object, kill, zero)
end
function S:StripTexts(object, kill, zero)
StripType(STRIP_FONT, object, kill, zero)
end
function S:FontTemplate(fs, font, size, style, skip)
if not skip then -- ignore updates from UpdateFontTemplates
fs.font, fs.fontSize, fs.fontStyle = font, size, style
end
-- grab values from profile before conversion
if not style then style = AS:CheckOption('FontStyle') end
if not size then size = AS:CheckOption('FontSize') end
-- shadow mode when using 'NONE'
if style == 'NONE' then
fs:SetShadowOffset(1, -0.5)
fs:SetShadowColor(0, 0, 0, 1)
else
fs:SetShadowOffset(0, 0)
fs:SetShadowColor(0, 0, 0, 0)
end
-- convert because of bad values between versions
if style == 'NONE' and not S.Classic then
style = ''
elseif style == '' and S.Classic then
style = 'NONE'
end
fs:SetFont(font or AS.Libs.LSM:Fetch('font', AS:CheckOption('Font')), size, style)
S.Texts[fs] = true
end
function S:StyleButton(button, noHover, noPushed, noChecked)
if button.SetHighlightTexture and button.CreateTexture and not button.hover and not noHover then
local hover = button:CreateTexture()
S:SetInside(hover)
hover:SetBlendMode('ADD')
hover:SetColorTexture(1, 1, 1, 0.3)
button:SetHighlightTexture(hover)
button.hover = hover
end
if button.SetPushedTexture and button.CreateTexture and not button.pushed and not noPushed then
local pushed = button:CreateTexture()
S:SetInside(pushed)
pushed:SetBlendMode('ADD')
pushed:SetColorTexture(0.9, 0.8, 0.1, 0.3)
button:SetPushedTexture(pushed)
button.pushed = pushed
end
if button.SetCheckedTexture and button.CreateTexture and not button.checked and not noChecked then
local checked = button:CreateTexture()
S:SetInside(checked)
checked:SetBlendMode('ADD')
checked:SetColorTexture(1, 1, 1, 0.3)
button:SetCheckedTexture(checked)
button.checked = checked
end
if button.cooldown then
button.cooldown:SetDrawEdge(false)
S:SetInside(button.cooldown, button, 0, 0)
end
end
do
local function HighlightOnEnter(button)
local r, g, b = unpack(Media.valueColor)
button.HighlightTexture:SetVertexColor(r, g, b, 0.50)
button.HighlightTexture:Show()
end
local function HighlightOnLeave(button)
button.HighlightTexture:SetVertexColor(0, 0, 0, 0)
button.HighlightTexture:Hide()
end
function S:HandleCategoriesButtons(button, strip)
if button.isSkinned then return end
if button.SetNormalTexture then button:SetNormalTexture(Media.ClearTexture) end
if button.SetHighlightTexture then button:SetHighlightTexture(Media.ClearTexture) end
if button.SetPushedTexture then button:SetPushedTexture(Media.ClearTexture) end
if button.SetDisabledTexture then button:SetDisabledTexture(Media.ClearTexture) end
if strip then button:StripTextures() end
S:HandleBlizzardRegions(button)
button.HighlightTexture = button:CreateTexture(nil, "BACKGROUND") -- Try HIGHLIGHT
button.HighlightTexture:SetBlendMode("BLEND")
button.HighlightTexture:SetSize(button:GetSize())
S:Point(button.HighlightTexture, 'CENTER', button, 0, 2)
button.HighlightTexture:SetTexture(Media.Blank)
button.HighlightTexture:Hide()
button:HookScript('OnEnter', HighlightOnEnter)
button:HookScript('OnLeave', HighlightOnLeave)
button.isSkinned = true
end
end
do
local gradients = { 'leftGrad', 'rightGrad' }
function S:HandleButtonHighlight(frame, layer, color)
if frame.SetHighlightTexture then
frame:SetHighlightTexture(S.Media.ClearTexture)
end
local r, g, b = 0.9, 0.9, 0.9
if color then
r, g, b = color.r or color[1], color.g or color[2], color.b or color[3]
end
if not frame.leftGrad then
for _, which in pairs(gradients) do
local grad = frame:CreateTexture(nil, layer or 'HIGHLIGHT')
S:Height(grad, frame:GetHeight() * 0.95)
grad:SetTexture(Media.StatusBar)
frame[which] = grad
end
end
S:Point(frame.leftGrad, 'LEFT', frame, 'CENTER')
S:Point(frame.rightGrad, 'RIGHT', frame, 'CENTER')
if S.Retail or S.Wrath then
frame.leftGrad:SetGradient("Horizontal", { r, g, b, 0.35 }, { r, g, b, 0 })
frame.rightGrad:SetGradient("Horizontal", { r, g, b, 0 }, { r, g, b, 0.35 })
else
frame.leftGrad:SetGradientAlpha("Horizontal", r, g, b, 0.35, r, g, b, 0)
frame.rightGrad:SetGradientAlpha("Horizontal", r, g, b, 0, r, g, b, 0.35)
end
end
end
function S:HandlePointXY(frame, x, y)
local a, b, c, d, e = frame:GetPoint()
frame:SetPoint(a, b, c, x or d, y or e)
end
function S:HandleFrame(frame, setBackdrop, template, x1, y1, x2, y2)
local name = frame and frame.GetName and frame:GetName()
local insetFrame = frame.Inset or name and _G[name..'Inset']
local portraitFrame = frame.Portrait or frame.portrait or name and _G[name..'Portrait']
local portraitFrameOverlay = frame.PortraitOverlay or name and _G[name..'PortraitOverlay']
local artFrameOverlay = frame.ArtOverlayFrame or name and _G[name..'ArtOverlayFrame']
local closeButton = frame.CloseButton or name and _G[name..'CloseButton']
S:StripTextures(frame)
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 closeButton then
S:HandleCloseButton(closeButton)
end
if setBackdrop then
S:CreateBackdrop(frame, template or 'Transparent')
else
S:SetTemplate(frame, template or 'Transparent')
end
if frame.backdrop then
S:Point(frame.backdrop, 'TOPLEFT', x1 or 0, y1 or 0)
S:Point(frame.backdrop, 'BOTTOMRIGHT', x2 or 0, y2 or 0)
end
end
function S:HandleInsetFrame(frame)
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, createBackdrop, noStrip)
local name = frame and frame.GetName and frame:GetName()
local insetFrame = frame.Inset or name and _G[name..'Inset']
local portraitFrame = frame.Portrait or frame.portrait or name and _G[name..'Portrait']
local portraitFrameOverlay = frame.PortraitOverlay or name and _G[name..'PortraitOverlay']
local artFrameOverlay = frame.ArtOverlayFrame or name and _G[name..'ArtOverlayFrame']
local closeButton = frame.CloseButton or name and _G[name..'CloseButton']
if not noStrip then
S:StripTextures(frame)
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
end
if closeButton then
S:HandleCloseButton(closeButton)
end
if createBackdrop then
S:CreateBackdrop(frame, 'Transparent', nil, nil, nil, nil, nil, nil, true)
else
S:SetTemplate(frame, 'Transparent')
end
end
function S:SetBackdropBorderColor(frame, script)
if frame.backdrop then frame = frame.backdrop end
if frame.SetBackdropBorderColor then
frame:SetBackdropBorderColor(unpack(script == 'OnEnter' and Media.valueColor or Media.borderColor))
end
end
function S:SetModifiedBackdrop()
if self:IsEnabled() then
S:SetBackdropBorderColor(self, 'OnEnter')
end
end
function S:SetOriginalBackdrop()
if self:IsEnabled() then
S:SetBackdropBorderColor(self, 'OnLeave')
end
end
function S:SetDisabledBackdrop()
if self.GetFontString and self:GetFontString() ~= nil then
self:GetFontString():SetTextColor(.5, .5, .5)
end
if self:IsMouseOver() then
S:SetBackdropBorderColor(self, 'OnDisable')
end
end
function S:SetEnabledBackdrop()
if self.GetFontString and self:GetFontString() ~= nil then
self:GetFontString():SetTextColor(.5, .5, .5)
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
do -- We need to test this for the BGScore frame
S.PVPHonorXPBarFrames = {}
S.PVPHonorXPBarSkinned = false
local function SetNextAvailable(XPBar)
if not S.PVPHonorXPBarFrames[XPBar:GetParent():GetName()] then return end
S:StripTextures(XPBar)
if XPBar.Bar and not XPBar.Bar.backdrop then
S:CreateBackdrop(XPBar.Bar)
if XPBar.Bar.Background then
S:SetInside(XPBar.Bar.Background, 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()
S:Point(XPBar.Bar.OverlayFrame.Text, 'CENTER', XPBar.Bar)
end
end
if XPBar.PrestigeReward and XPBar.PrestigeReward.Accept then
XPBar.PrestigeReward.Accept:ClearAllPoints()
S:Point(XPBar.PrestigeReward.Accept, '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()
S:Point(XPBar.NextAvailable, 'LEFT', XPBar.Bar, 'RIGHT', 0, -2)
end
if not XPBar.NextAvailable.backdrop then
S:StripTextures(XPBar.NextAvailable)
S:CreateBackdrop(XPBar.NextAvailable)
if XPBar.NextAvailable.Icon then
local x = S.PixelMode and 1 or 2
S:Point(XPBar.NextAvailable.backdrop, 'TOPLEFT', XPBar.NextAvailable.Icon, -x, x)
S:Point(XPBar.NextAvailable.backdrop, 'BOTTOMRIGHT', XPBar.NextAvailable.Icon, x, -x)
end
end
if XPBar.NextAvailable.Icon then
S:HandleIcon(XPBar.NextAvailable.Icon)
end
end
end
function S:SkinPVPHonorXPBar(frame)
S.PVPHonorXPBarFrames[frame] = true
if S.PVPHonorXPBarSkinned then return end
S.PVPHonorXPBarSkinned = true
hooksecurefunc('PVPHonorXPBar_SetNextAvailable', SetNextAvailable)
end
end
function S:StatusBarColorGradient(bar, value, maxValue, backdrop)
if not (bar and value) then return end
local current = (not maxValue and value) or (value and maxValue and maxValue ~= 0 and value/maxValue)
if not current then return end
local r, g, b = S:ColorGradient(current, 0.8,0,0, 0.8,0.8,0, 0,0.8,0)
bar:SetStatusBarColor(r, g, b)
if not backdrop then
backdrop = bar.backdrop
end
if backdrop then
backdrop:SetBackdropColor(r * 0.25, g * 0.25, b * 0.25)
end
end
-- DropDownMenu library support
function S:SkinLibDropDownMenu(prefix)
if S[prefix..'_UIDropDownMenuSkinned'] then return end
local key = (prefix == 'L4' or prefix == 'L3') and 'L' or prefix
local bd = _G[key..'_DropDownList1Backdrop']
local mbd = _G[key..'_DropDownList1MenuBackdrop']
if bd and not bd.template then S:SetTemplate(bd) end
if mbd and not mbd.template then S:SetTemplate(mbd) end
S[prefix..'_UIDropDownMenuSkinned'] = true
local lib = prefix == 'L4' and LibStub.libs['LibUIDropDownMenu-4.0']
if (lib and lib.UIDropDownMenu_CreateFrames) or _G[key..'_UIDropDownMenu_CreateFrames'] then
hooksecurefunc(lib or _G, (lib and '' or key..'_') .. 'UIDropDownMenu_CreateFrames', function()
local lvls = _G[(key == 'Lib' and 'LIB' or key)..'_UIDROPDOWNMENU_MAXLEVELS']
local ddbd = lvls and _G[key..'_DropDownList'..lvls..'Backdrop']
local ddmbd = lvls and _G[key..'_DropDownList'..lvls..'MenuBackdrop']
if ddbd and not ddbd.template then S:SetTemplate(ddbd) end
if ddmbd and not ddmbd.template then S:SetTemplate(ddmbd) end
end)
end
end
function S:SkinTalentListButtons(frame)
local name = frame 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)
S:Point(frame.Inset, 'TOPLEFT', 4, -60)
S:Point(frame.Inset, 'BOTTOMRIGHT', -6, 26)
end
end
do
local quality = Enum.ItemQuality
local iconColors = {
['auctionhouse-itemicon-border-gray'] = ITEM_QUALITY_COLORS[quality.Poor],
['auctionhouse-itemicon-border-white'] = ITEM_QUALITY_COLORS[quality.Common or quality.Standard],
['auctionhouse-itemicon-border-green'] = ITEM_QUALITY_COLORS[quality.Uncommon or quality.Good],
['auctionhouse-itemicon-border-blue'] = ITEM_QUALITY_COLORS[quality.Rare],
['auctionhouse-itemicon-border-purple'] = ITEM_QUALITY_COLORS[quality.Epic],
['auctionhouse-itemicon-border-orange'] = ITEM_QUALITY_COLORS[quality.Legendary],
['auctionhouse-itemicon-border-artifact'] = ITEM_QUALITY_COLORS[quality.Artifact],
['auctionhouse-itemicon-border-account'] = ITEM_QUALITY_COLORS[quality.Heirloom]
}
local function hideBorder(border)
border:SetAlpha(0)
S:StripTextures(border)
end
local function colorAtlas(border, atlas)
local color = iconColors[atlas]
if not color then return end
hideBorder(border)
if border.customFunc then
local br, bg, bb = unpack(Media.borderColor)
border.customFunc(border, color.r, color.g, color.b, 1, br, bg, bb)
elseif border.customBackdrop then
border.customBackdrop:SetBackdropBorderColor(color.r, color.g, color.b)
end
end
local function colorVertex(border, r, g, b, a)
hideBorder(border)
if border.customFunc then
local br, bg, bb = unpack(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 borderHide(border)
local br, bg, bb = unpack(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
local function borderShown(border, show)
if not show then
borderHide(border)
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
hideBorder(border)
hooksecurefunc(border, 'SetAtlas', colorAtlas)
hooksecurefunc(border, 'SetVertexColor', colorVertex)
hooksecurefunc(border, 'SetShown', borderShown)
hooksecurefunc(border, 'Hide', borderHide)
border.IconBorderHooked = true
end
local r, g, b, a = border:GetVertexColor()
local atlas = iconColors[border.GetAtlas and border:GetAtlas()]
if customFunc then
border.customFunc = customFunc
local br, bg, bb = unpack(Media.borderColor)
customFunc(border, r, g, b, a, br, bg, bb)
elseif atlas then
backdrop:SetBackdropBorderColor(atlas.r, atlas.g, atlas.b, 1)
elseif r then
backdrop:SetBackdropBorderColor(r, g, b, a)
else
local br, bg, bb = unpack(Media.borderColor)
backdrop:SetBackdropBorderColor(br, bg, bb)
end
end
end
function S:HandleButton(button, strip, isDecline, noStyle, createBackdrop, template, noGlossTex, overrideTex, frameLevel, regionsKill, regionsZero)
if button.isSkinned then return end
if button.SetNormalTexture and not overrideTex then button:SetNormalTexture(S.Media.ClearTexture) end
if button.SetHighlightTexture then button:SetHighlightTexture(S.Media.ClearTexture) end
if button.SetPushedTexture then button:SetPushedTexture(S.Media.ClearTexture) end
if button.SetDisabledTexture then button:SetDisabledTexture(S.Media.ClearTexture) end
if strip then S:StripTextures(button) end
S:HandleBlizzardRegions(button, nil, regionsKill, regionsZero)
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(Media.Arrow)
button.Icon:SetRotation(S.ArrowRotation.right)
button.Icon:SetVertexColor(1, 1, 1)
end
end
if isDecline and button.Icon then
button.Icon:SetTexture(Media.Close)
end
if not noStyle then
if createBackdrop then
S:CreateBackdrop(button, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template, not noGlossTex, nil, nil, nil, nil, nil, true, frameLevel)
else
S:SetTemplate(button, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template, not noGlossTex)
end
button:HookScript('OnEnter', S.SetModifiedBackdrop)
button:HookScript('OnLeave', S.SetOriginalBackdrop)
button:HookScript('OnEnable', S.SetEnabledBackdrop)
button:HookScript('OnDisable', S.SetDisabledBackdrop)
end
button.isSkinned = true
end
do
local function GetElement(frame, element, useParent)
if useParent then frame = frame:GetParent() end
local child = frame[element]
if child then return child end
local name = frame:GetName()
if name then return _G[name..element] end
end
local function GetButton(frame, buttons)
for _, data in ipairs(buttons) do
if type(data) == 'string' then
local found = GetElement(frame, data)
if found then return found end
else -- has useParent
local found = GetElement(frame, data[1], data[2])
if found then return found end
end
end
end
local function ThumbStatus(frame)
if not frame.Thumb then
return
elseif not frame:IsEnabled() then
frame.Thumb.backdrop:SetBackdropColor(0.3, 0.3, 0.3)
return
end
local _, maxValue = frame:GetMinMaxValues()
if maxValue == 0 then
frame.Thumb.backdrop:SetBackdropColor(0.3, 0.3, 0.3)
else
frame.Thumb.backdrop:SetBackdropColor(unpack(Media.valueColor))
end
end
local function ThumbWatcher(frame)
hooksecurefunc(frame, 'Enable', ThumbStatus)
hooksecurefunc(frame, 'Disable', ThumbStatus)
hooksecurefunc(frame, 'SetEnabled', ThumbStatus)
hooksecurefunc(frame, 'SetMinMaxValues', ThumbStatus)
ThumbStatus(frame)
end
local upButtons = {'ScrollUpButton', 'UpButton', 'ScrollUp', {'scrollUp', true}, 'Back'}
local downButtons = {'ScrollDownButton', 'DownButton', 'ScrollDown', {'scrollDown', true}, 'Forward'}
local thumbButtons = {'ThumbTexture', 'thumbTexture', 'Thumb'}
function S:HandleScrollBar(scrollBar, thumbY, thumbX, template)
if scrollBar.backdrop then return end
local upButton, downButton = GetButton(scrollBar, upButtons), GetButton(scrollBar, downButtons)
local thumb = GetButton(scrollBar, thumbButtons) or (scrollBar.GetThumbTexture and scrollBar:GetThumbTexture())
S:StripTextures(scrollBar)
S:CreateBackdrop(scrollBar, template or 'Transparent', nil, nil, nil, nil, nil, nil, nil, true)
S:Point(scrollBar.backdrop, 'TOPLEFT', upButton or scrollBar, upButton and 'BOTTOMLEFT' or 'TOPLEFT', 0, 1)
S:Point(scrollBar.backdrop, 'BOTTOMRIGHT', downButton or scrollBar, upButton and 'TOPRIGHT' or 'BOTTOMRIGHT', 0, -1)
if scrollBar.Background then scrollBar.Background:Hide() end
if scrollBar.ScrollUpBorder then scrollBar.ScrollUpBorder:Hide() end
if scrollBar.ScrollDownBorder then scrollBar.ScrollDownBorder:Hide() end
local frameLevel = scrollBar:GetFrameLevel()
if upButton then
S:HandleNextPrevButton(upButton, 'up')
upButton:SetFrameLevel(frameLevel + 2)
end
if downButton then
S:HandleNextPrevButton(downButton, 'down')
downButton:SetFrameLevel(frameLevel + 2)
end
if thumb and not thumb.backdrop then
thumb:SetTexture()
S:CreateBackdrop(thumb, nil, true, true, nil, nil, nil, nil, nil, frameLevel + 1)
if not scrollBar.Thumb then
scrollBar.Thumb = thumb
end
if thumb.backdrop then
if not thumbX then thumbX = 0 end
if not thumbY then thumbY = 0 end
S:Point(thumb.backdrop, 'TOPLEFT', thumb, thumbX, -thumbY)
S:Point(thumb.backdrop, 'BOTTOMRIGHT', thumb, -thumbX, thumbY)
if scrollBar.SetEnabled then
ThumbWatcher(scrollBar)
else
thumb.backdrop:SetBackdropColor(unpack(Media.valueColor))
end
end
end
end
-- WoWTrimScrollBar
local function ReskinScrollBarArrow(frame, direction)
S:HandleNextPrevButton(frame, direction)
if frame.Texture then
frame.Texture:SetAlpha(0)
if frame.Overlay then
frame.Overlay:SetAlpha(0)
end
else
S:StripTextures(frame)
end
end
local function ThumbOnEnter(frame)
local r, g, b = unpack(Media.valueColor)
local thumb = frame.thumb or frame
if thumb.backdrop then
thumb.backdrop:SetBackdropColor(r, g, b, .75)
end
end
local function ThumbOnLeave(frame)
local r, g, b = unpack(Media.valueColor)
local thumb = frame.thumb or frame
if thumb.backdrop and not thumb.__isActive then
thumb.backdrop:SetBackdropColor(r, g, b, .25)
end
end
local function ThumbOnMouseDown(frame)
local r, g, b = unpack(Media.valueColor)
local thumb = frame.thumb or frame
thumb.__isActive = true
if thumb.backdrop then
thumb.backdrop:SetBackdropColor(r, g, b, .75)
end
end
local function ThumbOnMouseUp(frame)
local r, g, b = unpack(Media.valueColor)
local thumb = frame.thumb or frame
thumb.__isActive = nil
if thumb.backdrop then
thumb.backdrop:SetBackdropColor(r, g, b, .25)
end
end
function S:HandleTrimScrollBar(scrollBar, small)
S:StripTextures(scrollBar)
ReskinScrollBarArrow(scrollBar.Back, 'up')
ReskinScrollBarArrow(scrollBar.Forward, 'down')
if scrollBar.Background then
scrollBar.Background:Hide()
end
local track = scrollBar.Track
if track then
track:DisableDrawLayer('ARTWORK')
end
local thumb = scrollBar:GetThumb()
if thumb then
thumb:DisableDrawLayer('BACKGROUND')
S:CreateBackdrop(thumb)
thumb.backdrop:SetFrameLevel(thumb:GetFrameLevel()+1)
local r, g, b = unpack(Media.valueColor)
thumb.backdrop:SetBackdropColor(r, g, b, .25)
if not small then
S:Point(thumb.backdrop, 'TOPLEFT', 4, -1)
S:Point(thumb.backdrop, 'BOTTOMRIGHT', -4, 1)
end
thumb:HookScript('OnEnter', ThumbOnEnter)
thumb:HookScript('OnLeave', ThumbOnLeave)
thumb:HookScript('OnMouseUp', ThumbOnMouseUp)
thumb:HookScript('OnMouseDown', ThumbOnMouseDown)
end
end
end
do --Tab Regions
local tabs = { 'LeftDisabled', 'MiddleDisabled', 'RightDisabled', 'Left', 'Middle', 'Right' }
function S:HandleTab(tab, noBackdrop, template)
if not tab or (tab.backdrop and not noBackdrop) then return end
for _, object in pairs(tabs) do
if tab[object] then
tab[object]:SetTexture()
else
local textureName = tab:GetName() and _G[tab:GetName()..object]
if textureName then
textureName:SetTexture()
end
end
end
local highlightTex = tab.GetHighlightTexture and tab:GetHighlightTexture()
if highlightTex then
highlightTex:SetTexture()
else
S:StripTextures(tab)
end
if not noBackdrop then
S:CreateBackdrop(tab, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template)
local spacing = S.Retail and 3 or 10
S:Point(tab.backdrop, 'TOPLEFT', spacing, S.PixelMode and -1 or -3)
S:Point(tab.backdrop, 'BOTTOMRIGHT', -spacing, 3)
end
end
end
function S:HandleRotateButton(button)
if button.isSkinned then return end
S:SetTemplate(button)
S:Size(button, button:GetWidth() - 14, button:GetHeight() - 14)
local normTex = button:GetNormalTexture()
local pushTex = button:GetPushedTexture()
local highlightTex = button:GetHighlightTexture()
S:SetInside(normTex)
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)
button.isSkinned = true
end
do
local btns = { MaximizeButton = 'up', MinimizeButton = 'down' }
local function buttonOnEnter(button)
local r,g,b = unpack(Media.valueColor)
button:GetNormalTexture():SetVertexColor(r,g,b)
button:GetPushedTexture():SetVertexColor(r,g,b)
end
local function buttonOnLeave(button)
button:GetNormalTexture():SetVertexColor(1, 1, 1)
button:GetPushedTexture():SetVertexColor(1, 1, 1)
end
function S:HandleMaxMinFrame(frame)
if frame.isSkinned then return end
S:StripTextures(frame, true)
for name, direction in pairs(btns) do
local button = frame[name]
if button then
S:Size(button, 14, 14)
button:ClearAllPoints()
S:Point(button, 'CENTER')
button:SetHitRectInsets(1, 1, 1, 1)
S:Kill(button:GetHighlightTexture())
button:SetScript('OnEnter', buttonOnEnter)
button:SetScript('OnLeave', buttonOnLeave)
button:SetNormalTexture(Media.Arrow)
button:GetNormalTexture():SetRotation(S.ArrowRotation[direction])
button:SetPushedTexture(Media.Arrow)
button:GetPushedTexture():SetRotation(S.ArrowRotation[direction])
end
end
frame.isSkinned = true
end
end
function S:HandleBlizzardRegions(frame, name, kill, zero)
if not name then name = frame.GetName and frame:GetName() end
for _, area in pairs(BlizzardRegions) do
local object = (name and _G[name..area]) or frame[area]
if object then
if kill then
S:Kill(object)
elseif zero then
object:SetAlpha(0)
else
object:Hide()
end
end
end
end
function S:HandleEditBox(editBox, template)
if editBox.backdrop then return end
S:CreateBackdrop(editBox, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template, nil, nil, nil, nil, nil, nil, nil, true)
editBox.backdrop:SetPoint('TOPLEFT', -2, 0)
editBox.backdrop:SetPoint('BOTTOMRIGHT')
S:HandleBlizzardRegions(editBox)
local EditBoxName = editBox:GetName()
if EditBoxName and (strfind(EditBoxName, 'Silver') or strfind(EditBoxName, 'Copper')) then
S:Point(editBox.backdrop, 'BOTTOMRIGHT', -12, -2)
end
end
function S:HandleDropDownBox(dropDown, width, pos, template)
local frameName = dropDown.GetName and dropDown:GetName()
local button = dropDown.Button or frameName and (_G[frameName..'Button'] or _G[frameName..'_Button'])
local text = frameName and _G[frameName..'Text'] or dropDown.Text
local icon = dropDown.Icon
if not width then
width = 155
end
S:Width(dropDown, width)
S:StripTextures(dropDown)
S:CreateBackdrop(dropDown, template)
dropDown:SetFrameLevel(dropDown:GetFrameLevel() + 2)
S:Point(dropDown.backdrop, 'TOPLEFT', 20, -2)
S:Point(dropDown.backdrop, 'BOTTOMRIGHT', button, 'BOTTOMRIGHT', 2, -2)
button:ClearAllPoints()
if pos then
S:Point(button, 'TOPRIGHT', dropDown.Right, -20, -21)
else
S:Point(button, 'RIGHT', dropDown, 'RIGHT', -10, 3)
end
button.SetPoint = S.noop
S:HandleNextPrevButton(button, 'down')
if text then
text:ClearAllPoints()
S:Point(text, 'RIGHT', button, 'LEFT', -2, 0)
end
if icon then
S:Point(icon, 'LEFT', 23, 0)
end
end
function S:HandleStatusBar(statusBar, color, template, ignoreColor)
statusBar:SetFrameLevel(statusBar:GetFrameLevel() + 1)
S:StripTextures(statusBar)
S:CreateBackdrop(statusBar, template or 'Transparent')
statusBar:SetStatusBarTexture(Media.StatusBar)
if not ignoreColor then
statusBar:SetStatusBarColor(unpack(color or AS:CheckOption('StatusBarColor')))
end
S.StatusBars[statusBar] = true
end
do
local function checkNormalTexture(checkBox, texture) if texture ~= Media.ClearTexture then checkBox:SetNormalTexture(Media.ClearTexture) end end
local function checkPushedTexture(checkBox, texture) if texture ~= Media.ClearTexture then checkBox:SetPushedTexture(Media.ClearTexture) end end
local function checkHighlightTexture(checkBox, texture) if texture ~= Media.ClearTexture then checkBox:SetHighlightTexture(Media.ClearTexture) end end
local function checkCheckedTexture(checkBox, texture)
if texture == Media.StatusBar then return end
checkBox:SetCheckedTexture(Media.StatusBar)
end
local function checkOnDisable(checkBox)
if not checkBox.SetDisabledTexture then return end
checkBox:SetDisabledTexture(checkBox:GetChecked() and Media.StatusBar or '')
end
function S:HandleCheckBox(checkBox, noBackdrop, noReplaceTextures, frameLevel, template)
if checkBox.isSkinned then return end
S:StripTextures(checkBox)
if noBackdrop then
S:Size(checkBox, 16)
else
S:CreateBackdrop(checkBox, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template, nil, nil, nil, nil, nil, nil, nil, frameLevel)
S:SetInside(checkBox.backdrop, nil, 4, 4)
end
if not noReplaceTextures then
if checkBox.SetCheckedTexture then
checkBox:SetCheckedTexture(Media.StatusBar)
local checkedTexture = checkBox:GetCheckedTexture()
checkedTexture:SetVertexColor(1, .82, 0, 0.8)
S:SetInside(checkedTexture, checkBox.backdrop)
end
if checkBox.SetDisabledTexture then
checkBox:SetDisabledTexture(Media.StatusBar)
local disabledTexture = checkBox:GetDisabledTexture()
disabledTexture:SetVertexColor(.6, .6, .6, .8)
S:SetInside(disabledTexture, checkBox.backdrop)
end
checkBox:HookScript('OnDisable', checkOnDisable)
hooksecurefunc(checkBox, 'SetNormalTexture', checkNormalTexture)
hooksecurefunc(checkBox, 'SetPushedTexture', checkPushedTexture)
hooksecurefunc(checkBox, 'SetCheckedTexture', checkCheckedTexture)
hooksecurefunc(checkBox, 'SetHighlightTexture', checkHighlightTexture)
end
checkBox.isSkinned = true
end
end
do
local background = [[Interface\Minimap\UI-Minimap-Background]]
local function buttonNormalTexture(button, texture) if texture ~= Media.ClearTexture then button:SetNormalTexture(Media.ClearTexture) end end
local function buttonPushedTexture(button, texture) if texture ~= Media.ClearTexture then button:SetPushedTexture(Media.ClearTexture) end end
local function buttonDisabledTexture(button, texture) if texture ~= Media.ClearTexture then button:SetDisabledTexture(Media.ClearTexture) end end
local function buttonHighlightTexture(button, texture) if texture ~= Media.ClearTexture then button:SetHighlightTexture(Media.ClearTexture) end end
function S:HandleRadioButton(button)
if button.isSkinned then return end
local InsideMask = button:CreateMaskTexture()
InsideMask:SetTexture(background, 'CLAMPTOBLACKADDITIVE', 'CLAMPTOBLACKADDITIVE')
S:Size(InsideMask, 10, 10)
S:Point(InsideMask, 'CENTER')
button.InsideMask = InsideMask
local OutsideMask = button:CreateMaskTexture()
OutsideMask:SetTexture(background, 'CLAMPTOBLACKADDITIVE', 'CLAMPTOBLACKADDITIVE')
S:Size(OutsideMask, 13, 13)
S:Point(OutsideMask, 'CENTER')
button.OutsideMask = OutsideMask
button:SetCheckedTexture(Media.StatusBar)
button:SetNormalTexture(Media.StatusBar)
button:SetHighlightTexture(Media.StatusBar)
button:SetDisabledTexture(Media.StatusBar)
local Check = button:GetCheckedTexture()
Check:SetVertexColor(unpack(Media.valueColor))
Check:SetTexCoord(0, 1, 0, 1)
S:SetInside(Check)
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()
S:SetOutside(Normal)
Normal:SetTexCoord(0, 1, 0, 1)
Normal:SetVertexColor(unpack(Media.borderColor))
Normal:AddMaskTexture(OutsideMask)
local Disabled = button:GetDisabledTexture()
Disabled:SetVertexColor(.3, .3, .3)
Disabled:AddMaskTexture(OutsideMask)
hooksecurefunc(button, 'SetNormalTexture', buttonNormalTexture)
hooksecurefunc(button, 'SetPushedTexture', buttonPushedTexture)
hooksecurefunc(button, 'SetDisabledTexture', buttonDisabledTexture)
hooksecurefunc(button, 'SetHighlightTexture', buttonHighlightTexture)
button.isSkinned = true
end
end
function S:HandleIcon(icon, backdrop, frameLevel)
icon:SetTexCoord(unpack(Media.TexCoords))
if icon:GetDrawLayer() ~= 'ARTWORK' then
icon:SetDrawLayer('ARTWORK')
end
S:DisablePixelSnap(icon)
if backdrop and not icon.backdrop then
S:CreateBackdrop(icon, nil, nil, nil, nil, nil, nil, nil, nil, frameLevel)
end
end
function S:HandleItemButton(button, setInside)
if button.isSkinned then return end
local name = button:GetName()
local icon = button.icon or button.Icon or button.IconTexture or button.iconTexture or (name and (_G[name..'IconTexture'] or _G[name..'Icon']))
local texture = icon and icon.GetTexture and icon:GetTexture()
S:StripTextures(button)
S:CreateBackdrop(button, nil, true, nil, nil, nil, nil, nil, true)
S:StyleButton(button)
if icon then
S:HandleIcon(icon)
if setInside then
S:SetInside(icon, button)
else
S:SetOutside(button.backdrop, icon, 1, 1)
end
icon:SetParent(button.backdrop)
if texture then
icon:SetTexture(texture)
end
end
button.isSkinned = true
end
do
local closeOnEnter = function(btn) if btn.Texture then btn.Texture:SetVertexColor(unpack(Media.valueColor)) end end
local closeOnLeave = function(btn) if btn.Texture then btn.Texture:SetVertexColor(1, 1, 1) end end
function S:HandleCloseButton(button, point, x, y)
S:StripTextures(button)
if not button.Texture then
button.Texture = button:CreateTexture(nil, 'OVERLAY')
S:Point(button.Texture, 'CENTER')
button.Texture:SetTexture(Media.Close)
S:Size(button.Texture, 12, 12)
button:HookScript('OnEnter', closeOnEnter)
button:HookScript('OnLeave', closeOnLeave)
button:SetHitRectInsets(6, 6, 7, 7)
end
if point then
S:Point(button, 'TOPRIGHT', point, 'TOPRIGHT', x or 2, y or 2)
end
end
function S:HandleNextPrevButton(button, arrowDir, color, noBackdrop, stripTexts, frameLevel)
if button.isSkinned then return end
if not arrowDir then
arrowDir = 'down'
local name = button: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
S:StripTextures(button)
if button.Texture then
button.Texture:SetAlpha(0)
end
if not noBackdrop then
S:HandleButton(button, nil, nil, true, nil, nil, nil, nil, frameLevel)
end
if stripTexts then
S:StripTexts(button)
end
button:SetNormalTexture(Media.Arrow)
button:SetPushedTexture(Media.Arrow)
button:SetDisabledTexture(Media.Arrow)
local Normal, Disabled, Pushed = button:GetNormalTexture(), button:GetDisabledTexture(), button:GetPushedTexture()
if noBackdrop then
S:Size(button, 20, 20)
Disabled:SetVertexColor(.5, .5, .5)
button.Texture = Normal
if not color then
button:HookScript('OnEnter', closeOnEnter)
button:HookScript('OnLeave', closeOnLeave)
end
else
S:Size(button, 18, 18)
Disabled:SetVertexColor(.3, .3, .3)
end
S:SetInside(Normal)
S:SetInside(Pushed)
S:SetInside(Disabled)
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
button.isSkinned = true
end
end
function S:HandleSliderFrame(frame, template, frameLevel)
local orientation = frame:GetOrientation()
local size = 12
if frame.SetBackdrop then
frame:SetBackdrop()
end
S:StripTextures(frame)
frame:SetThumbTexture(Media.StatusBar)
if not frame.backdrop then
S:CreateBackdrop(frame, AS:CheckOption('ElvUIStyle', 'ElvUI') and 'Default' or template, nil, nil, nil, nil, nil, nil, true, frameLevel)
end
local thumb = frame:GetThumbTexture()
thumb:SetVertexColor(1, .82, 0, 0.8)
S:Size(thumb, size - 2)
if orientation == 'VERTICAL' then
S:Width(frame, size)
else
S:Height(frame, size)
for _, region in next, { frame:GetRegions() } do
if region:IsObjectType('FontString') then
local point, anchor, anchorPoint, x, y = region:GetPoint()
if anchorPoint and strfind(anchorPoint, 'BOTTOM') then
S:Point(region, point, anchor, anchorPoint, x, y - 4)
end
end
end
end
end
-- Needs Redone
function S:CleanTexture(Object, Kill, Alpha)
if Kill then
S:Kill(Object)
elseif Alpha then
Object:SetAlpha(0)
else
Object:SetTexture('')
end
end
function S:StripTexture(Object, Texture, Kill, Alpha)
if Object:IsObjectType('Texture') and type(Object:GetTexture()) == 'string' and strlower(Object:GetTexture()) == strlower(Texture) then
S:CleanTexture(Object, Kill, Alpha)
else
if Object.GetNumRegions then
for _, Region in next, { Object:GetRegions() } do
if Region and Region:IsObjectType('Texture') and type(Region:GetTexture()) == 'string' and strlower(Region:GetTexture()) == strlower(Texture) then
S:CleanTexture(Region, Kill, Alpha)
end
end
end
end
end
local function Desaturate(self, value)
if value ~= true then self:SetDesaturated(true) end
end
function S:Desaturate(frame)
if frame.IsObjectType and (frame:IsObjectType('Button') or frame:IsObjectType('CheckButton')) then
local Normal, Pushed, Highlight = frame:GetNormalTexture(), frame:GetPushedTexture(), frame:GetHighlightTexture()
if Normal then
Normal:SetDesaturated(true)
hooksecurefunc(Normal, 'SetDesaturated', Desaturate)
end
if Pushed then
Pushed:SetDesaturated(true)
hooksecurefunc(Pushed, 'SetDesaturated', Desaturate)
end
if Highlight then
Highlight:SetDesaturated(true)
hooksecurefunc(Highlight, 'SetDesaturated', Desaturate)
end
end
end
function S:HandleTooltip(tooltip, scale, showHook)
S:HandleBlizzardRegions(tooltip)
S:SetTemplate(tooltip, nil, nil, nil, nil, nil, nil, nil, true)
if showHook then
tooltip:HookScript('OnShow', function(tt) S:SetTemplate(tt) end)
end
if scale then
tooltip:SetScale(S.UIScale)
end
end
local function EnumObjectsHelper(enumFuncs, yieldFunc, iobj)
local depth = #enumFuncs
local i = 1
local obj
repeat
if (iobj) then
obj = enumFuncs[1](iobj, i)
else
obj = enumFuncs[1](i)
end
if (obj) then
if (depth == 1) then
yieldFunc(obj)
else
local innerEnumFuncs = CopyTable(enumFuncs)
tremove(innerEnumFuncs, 1)
EnumObjectsHelper(innerEnumFuncs, yieldFunc, obj)
end
end
i = i + 1
until not obj
end
function S:EnumObjects(enumFuncs, yieldFunc)
if (type(enumFuncs) == 'function') then
enumFuncs = {enumFuncs}
end
EnumObjectsHelper(enumFuncs, yieldFunc)
end
-- ToDO: DF => UpdateME => Credits: NDUI
local sparkTexture = [[Interface\CastingBar\UI-CastingBar-Spark]]
function S:HandleStepSlider(frame, minimal)
local slider = frame.Slider
if not slider then return end
S:StripTextures(frame)
slider:DisableDrawLayer('ARTWORK')
local thumb = slider.Thumb
if thumb then
thumb:SetTexture(sparkTexture)
thumb:SetBlendMode('ADD')
thumb:SetSize(20, 30)
end
local offset = minimal and 10 or 13
S:CreateBackdrop(slider)
slider.backdrop:SetPoint('TOPLEFT', 10, -offset)
slider.backdrop:SetPoint('BOTTOMRIGHT', -10, offset)
if not slider.barStep then
local step = CreateFrame('StatusBar', nil, slider.backdrop)
S:HandleStatusBar(step, {1, .8, 0, .5})
step:SetPoint('TOPLEFT', slider.backdrop, S.mult, -S.mult)
step:SetPoint('BOTTOMLEFT', slider.backdrop, S.mult, S.mult)
step:SetPoint('RIGHT', thumb, 'CENTER')
slider.barStep = step
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
S:StripTextures(xpbar)
S:HandleStatusBar(xpbar)
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
S:HandleIcon(icon)
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
S:HandleIcon(icon)
end
end
end
local function UpdateFollowerQuality(self, followerInfo)
if followerInfo then
local color = S.QualityColors[followerInfo.quality or 1]
self.Portrait.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
end
end
do
S.FollowerListUpdateDataFrames = {}
local function UpdateFollower(button)
if not S.Retail then
S:SetTemplate(button, button.mode == 'CATEGORY' and 'NoBackdrop' or 'Transparent')
end
local category = button.Category
if category then
category:ClearAllPoints()
S:Point(category, 'TOP', button, 'TOP', 0, -4)
end
local follower = button.Follower
if follower then
if not follower.template then
S:SetTemplate(follower)
follower.Name:SetWordWrap(false)
follower.Selection:SetTexture()
follower.AbilitiesBG:SetTexture()
follower.BusyFrame:SetAllPoints()
follower.BG:Hide()
local hl = follower:GetHighlightTexture()
hl:SetColorTexture(0.9, 0.9, 0.9, 0.25)
S:SetInside(hl)
end
local counters = follower.Counters
if counters then
for _, counter in next, counters do
if not counter.template then
S:SetTemplate(counter)
if counter.Border then
counter.Border:SetTexture()
end
if counter.Icon then
S:HandleIcon(counter.Icon)
S:SetInside(counter.Icon)
end
end
end
end
local portrait = follower.PortraitFrame
if portrait then
S:HandleGarrisonPortrait(portrait, true)
portrait:ClearAllPoints()
S:Point(portrait, 'TOPLEFT', 3, -3)
if not follower.PortraitFrameStyled then
hooksecurefunc(portrait, 'SetupPortrait', UpdateFollowerQuality)
follower.PortraitFrameStyled = true
end
local quality = portrait.quality or (follower.info and follower.info.quality)
local color = portrait.backdrop and ITEM_QUALITY_COLORS[quality]
if color then -- sometimes it doesn't have this data since DF
portrait.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
end
end
if follower.Selection then
if follower.Selection:IsShown() then
follower:SetBackdropColor(0.9, 0.8, 0.1, 0.25)
else
follower:SetBackdropColor(0, 0, 0, 0.5)
end
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]
if button then
local index = offset + i -- adjust index
if index <= numFollowers then
UpdateFollower(button)
end
end
end
end
local function UpdateListScroll(dataFrame)
if not (dataFrame and dataFrame.listScroll) or not S.FollowerListUpdateDataFrames[dataFrame:GetName()] then return end
local buttons = dataFrame.listScroll.buttons
local offset = _G.HybridScrollFrame_GetOffset(dataFrame.listScroll)
S:HandleFollowerListOnUpdateDataFunc(buttons, buttons and #buttons, offset, dataFrame.listScroll and #dataFrame.listScroll)
end
function S:HandleFollowerListOnUpdateData(frame)
if frame == 'GarrisonLandingPageFollowerList' and (not AS:IsSkinEnabled(nil, 'orderhall') or not AS:IsSkinEnabled(nil, 'garrison')) 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
if _G.GarrisonFollowerList_InitButton then
hooksecurefunc(_G, 'GarrisonFollowerList_InitButton', UpdateFollower)
else
hooksecurefunc(_G[frame], 'UpdateData', UpdateListScroll) -- pre DF
end
end
end
-- Shared Template on LandingPage/Orderhall-/Garrison-FollowerList
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, updateAtlas)
local main = portrait.Portrait
if not main then return end
if not main.backdrop then
S:CreateBackdrop(main)
end
local level = portrait.Level or portrait.LevelText
if level then
level:ClearAllPoints()
S:Point(level, 'BOTTOM', portrait, 0, 15)
S:FontTemplate(level, nil, 14, 'OUTLINE')
if portrait.LevelCircle then portrait.LevelCircle:Hide() end
if portrait.LevelBorder then portrait.LevelBorder:SetScale(.0001) end
end
if portrait.PortraitRing then
portrait.PortraitRing:Hide()
portrait.PortraitRingQuality:SetTexture('')
portrait.PortraitRingCover:SetColorTexture(0, 0, 0)
portrait.PortraitRingCover:SetAllPoints(main.backdrop)
end
if portrait.Empty then
portrait.Empty:SetColorTexture(0, 0, 0)
portrait.Empty:SetAllPoints(main)
end
if portrait.Highlight then portrait.Highlight:Hide() end
if portrait.PuckBorder then portrait.PuckBorder:SetAlpha(0) end
if portrait.TroopStackBorder1 then portrait.TroopStackBorder1:SetAlpha(0) end
if portrait.TroopStackBorder2 then portrait.TroopStackBorder2:SetAlpha(0) end
if portrait.HealthBar then
portrait.HealthBar.Border:Hide()
local roleIcon = portrait.HealthBar.RoleIcon
roleIcon:ClearAllPoints()
S:Point(roleIcon, 'CENTER', main.backdrop, 'TOPRIGHT')
if updateAtlas then
HandleFollowerRole(roleIcon, roleIcon:GetAtlas())
else
hooksecurefunc(roleIcon, 'SetAtlas', HandleFollowerRole)
end
local background = portrait.HealthBar.Background
background:SetAlpha(0)
S:SetInside(background, main.backdrop, 2, 1) -- unsnap it
S:Point(background, 'TOPLEFT', main.backdrop, 'BOTTOMLEFT', 2, 7)
portrait.HealthBar.Health:SetTexture(S.Media.StatusBar)
end
end
do
local function selectionOffset(frame)
local point, anchor, relativePoint, xOffset = frame:GetPoint()
if xOffset <= 0 then
local x = frame.BorderBox and 4 or 38 -- adjust values for wrath
local y = frame.BorderBox and 0 or -10
frame:ClearAllPoints()
S:Point(frame, point, (frame == _G.MacroPopupFrame and _G.MacroFrame) or anchor, relativePoint, strfind(point, 'LEFT') and x or -x, y)
end
end
local function handleButton(button, i, buttonNameTemplate)
local icon, texture = button.Icon or _G[buttonNameTemplate..i..'Icon']
if icon then
S:HandleIcon(icon)
S:SetInside(icon, button)
texture = icon:GetTexture() -- keep this before strip textures
end
S:HandleFrame(button)
S:StyleButton(button, nil, true)
if texture then
icon:SetTexture(texture)
end
end
function S:HandleIconSelectionFrame(frame, numIcons, buttonNameTemplate, nameOverride, dontOffset)
if frame.isSkinned then
return
elseif not S.Retail and (nameOverride and nameOverride ~= 'MacroPopup') then -- skip macros because it skins on show
frame:Show() -- spawn the info so we can skin the buttons
if frame.Update then frame:Update() end -- guild bank popup has update function
frame:Hide() -- can hide it right away
end
if not dontOffset then -- place it off to the side of parent with correct offsets
frame:HookScript('OnShow', selectionOffset)
frame:Height(frame:GetHeight() + 10)
end
local borderBox = frame.BorderBox or _G.BorderBox -- it's a sub frame only on retail, on wrath it's a global?
local frameName = nameOverride or frame:GetName() -- we need override in case Blizzard fucks up the naming (guild bank)
local scrollFrame = frame.ScrollFrame or _G[frameName..'ScrollFrame']
local editBox = (borderBox and borderBox.IconSelectorEditBox) or frame.EditBox or _G[frameName..'EditBox']
local cancel = frame.CancelButton or (borderBox and borderBox.CancelButton) or _G[frameName..'Cancel']
local okay = frame.OkayButton or (borderBox and borderBox.OkayButton) or _G[frameName..'Okay']
S:HandleFrame(frame)
if borderBox then
S:StripTextures(borderBox)
local button = borderBox.SelectedIconArea and borderBox.SelectedIconArea.SelectedIconButton
if button then
button:DisableDrawLayer('BACKGROUND')
S:HandleItemButton(button, true)
end
end
cancel:ClearAllPoints()
cancel:SetPoint('BOTTOMRIGHT', frame, -4, 4)
S:HandleButton(cancel)
okay:ClearAllPoints()
okay:SetPoint('RIGHT', cancel, 'LEFT', -10, 0)
S:HandleButton(okay)
if editBox then
editBox:DisableDrawLayer('BACKGROUND')
S:HandleEditBox(editBox)
end
if numIcons then
S:StripTextures(scrollFrame)
scrollFrame:Height(scrollFrame:GetHeight() + 10)
S:HandleScrollBar(scrollFrame.ScrollBar)
for i = 1, numIcons do
local button = _G[buttonNameTemplate..i]
if button then
handleButton(button, i, buttonNameTemplate)
end
end
else
S:HandleTrimScrollBar(frame.IconSelector.ScrollBar)
for _, button in next, { frame.IconSelector.ScrollBox.ScrollTarget:GetChildren() } do
handleButton(button)
end
end
frame.isSkinned = true
end
end
do -- Handle collapse
local function UpdateCollapseTexture(button, texture, skip)
if skip then return end
if type(texture) == 'number' then -- 130821 minus, 130838 plus
button:SetNormalTexture(texture == 130838 and S.Media.Plus or S.Media.Minus, true)
elseif strfind(texture, 'Plus') or strfind(texture, 'Closed') then
button:SetNormalTexture(S.Media.Plus, true)
elseif strfind(texture, 'Minus') or strfind(texture, 'Open') then
button:SetNormalTexture(S.Media.Minus, true)
end
end
local function syncPushTexture(button, _, skip)
if skip then return end
local normal = button:GetNormalTexture():GetTexture()
button:SetPushedTexture(normal, true)
end
function S:HandleCollapseTexture(button, syncPushed)
if syncPushed then -- not needed always
hooksecurefunc(button, 'SetPushedTexture', syncPushTexture)
syncPushTexture(button)
else
button:SetPushedTexture(S.Media.ClearTexture)
end
hooksecurefunc(button, 'SetNormalTexture', UpdateCollapseTexture)
UpdateCollapseTexture(button, button:GetNormalTexture():GetTexture())
end
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 not bar or bar.backdrop then return end
S:CreateBackdrop(bar)
bar:SetScale(0.99) -- lol yes, this will keep it placed correctly for Simpy
if bar.BGLeft then bar.BGLeft:SetAlpha(0) end
if bar.BGRight then bar.BGRight:SetAlpha(0) end
if bar.BGCenter then bar.BGCenter:SetAlpha(0) end
if bar.BorderLeft then bar.BorderLeft:SetAlpha(0) end
if bar.BorderRight then bar.BorderRight:SetAlpha(0) end
if bar.BorderCenter then bar.BorderCenter:SetAlpha(0) end
end
do
local function handleBar(bar)
if not bar or bar.backdrop then return end
S:CreateBackdrop(bar)
if bar.BG then bar.BG:SetAlpha(0) end
if bar.Spark then bar.Spark:SetAlpha(0) end
if bar.SparkGlow then bar.SparkGlow:SetAlpha(0) end
if bar.BorderLeft then bar.BorderLeft:SetAlpha(0) end
if bar.BorderRight then bar.BorderRight:SetAlpha(0) end
if bar.BorderCenter then bar.BorderCenter:SetAlpha(0) end
if bar.BorderGlow then bar.BorderGlow:SetAlpha(0) end
end
function S:SkinDoubleStatusBarWidget(widgetFrame)
handleBar(widgetFrame.LeftBar)
handleBar(widgetFrame.RightBar)
end
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 not text then return end
text:SetTextColor(1, 1, 1)
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, true)
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',
}
if S.Retail then
S.WidgetSkinningFuncs[W.SpellDisplay] = 'SkinSpellDisplay'
S.WidgetSkinningFuncs[W.TextureAndText] = 'SkinTextureAndTextWidget'
S.WidgetSkinningFuncs[W.DoubleStateIconRow] = 'SkinDoubleStateIconRow'
S.WidgetSkinningFuncs[W.TextureAndTextRow] = 'SkinTextureAndTextRowWidget'
S.WidgetSkinningFuncs[W.ZoneControl] = 'SkinZoneControl'
S.WidgetSkinningFuncs[W.CaptureZone] = 'SkinCaptureZone'
end
end
function S:SkinWidgetContainer(widget)
local typeFunc = S.WidgetSkinningFuncs[widget.widgetType]
if typeFunc and S[typeFunc] then
S[typeFunc](S, widget)
end
end
function S:UpdateAllWidgets()
for _, widget in pairs(_G.UIWidgetTopCenterContainerFrame.widgetFrames) do
S:SkinWidgetContainer(widget)
end
end
function S:PLAYER_LOGIN()
S:GetPixelScale()
if S.Retail then
S:RegisterEvent('PLAYER_ENTERING_WORLD', 'UpdateAllWidgets')
S:RegisterEvent('UPDATE_ALL_UI_WIDGETS', 'UpdateAllWidgets')
end
end
S:RegisterEvent('PLAYER_LOGIN')