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.
610 lines
24 KiB
610 lines
24 KiB
|
4 years ago
|
local Layout = {mediaPath = {}}
|
||
|
|
local SML, mediaRequired, anchoringQueued
|
||
|
|
local mediaPath = Layout.mediaPath
|
||
|
|
local backdropTbl = {insets = {}}
|
||
|
|
local _G = getfenv(0)
|
||
|
|
|
||
|
|
ShadowUF.Layout = Layout
|
||
|
|
|
||
|
|
-- Someone is using another mod that is forcing a media type for all mods using SML
|
||
|
|
function Layout:MediaForced(mediaType)
|
||
|
|
local oldPath = mediaPath[mediaType]
|
||
|
|
self:CheckMedia()
|
||
|
|
|
||
|
|
if( mediaPath[mediaType] ~= oldPath ) then
|
||
|
|
self:Reload()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function loadMedia(type, name, default)
|
||
|
|
if( name == "" ) then return "" end
|
||
|
|
|
||
|
|
local media = SML:Fetch(type, name, true)
|
||
|
|
if( not media ) then
|
||
|
|
mediaRequired = mediaRequired or {}
|
||
|
|
mediaRequired[type] = name
|
||
|
|
return default
|
||
|
|
end
|
||
|
|
|
||
|
|
return media
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Updates the background table
|
||
|
|
local function updateBackdrop()
|
||
|
|
-- Update the backdrop table
|
||
|
|
local backdrop = ShadowUF.db.profile.backdrop
|
||
|
|
backdropTbl.bgFile = mediaPath.background
|
||
|
|
if( mediaPath.border ~= "Interface\\None" ) then backdropTbl.edgeFile = mediaPath.border end
|
||
|
|
backdropTbl.tile = backdrop.tileSize > 0 and true or false
|
||
|
|
backdropTbl.edgeSize = backdrop.edgeSize == 0 and 1 or backdrop.edgeSize
|
||
|
|
backdropTbl.tileSize = backdrop.tileSize
|
||
|
|
backdropTbl.insets.left = backdrop.inset
|
||
|
|
backdropTbl.insets.right = backdrop.inset
|
||
|
|
backdropTbl.insets.top = backdrop.inset
|
||
|
|
backdropTbl.insets.bottom = backdrop.inset
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Tries to load media, if it fails it will default to whatever I set
|
||
|
|
function Layout:CheckMedia()
|
||
|
|
mediaPath[SML.MediaType.STATUSBAR] = loadMedia(SML.MediaType.STATUSBAR, ShadowUF.db.profile.bars.texture, "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\Aluminium")
|
||
|
|
mediaPath[SML.MediaType.FONT] = loadMedia(SML.MediaType.FONT, ShadowUF.db.profile.font.name, "Interface\\AddOns\\ShadowedUnitFrames\\media\\fonts\\Myriad Condensed Web.ttf")
|
||
|
|
mediaPath[SML.MediaType.BACKGROUND] = loadMedia(SML.MediaType.BACKGROUND, ShadowUF.db.profile.backdrop.backgroundTexture, "Interface\\ChatFrame\\ChatFrameBackground")
|
||
|
|
mediaPath[SML.MediaType.BORDER] = loadMedia(SML.MediaType.BORDER, ShadowUF.db.profile.backdrop.borderTexture, "")
|
||
|
|
|
||
|
|
updateBackdrop()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- We might not have had a media we required at initial load, wait for it to load and then update everything when it does
|
||
|
|
function Layout:MediaRegistered(event, mediaType, key)
|
||
|
|
if( mediaRequired and mediaRequired[mediaType] and mediaRequired[mediaType] == key ) then
|
||
|
|
mediaPath[mediaType] = SML:Fetch(mediaType, key)
|
||
|
|
mediaRequired[mediaType] = nil
|
||
|
|
|
||
|
|
self:Reload()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Helper functions
|
||
|
|
function Layout:ToggleVisibility(frame, visible)
|
||
|
|
if( frame and visible ) then
|
||
|
|
frame:Show()
|
||
|
|
elseif( frame ) then
|
||
|
|
frame:Hide()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:SetBarVisibility(frame, key, status)
|
||
|
|
if( frame.secureLocked ) then return end
|
||
|
|
|
||
|
|
-- Show the bar if it wasn't already
|
||
|
|
if( status and not frame[key]:IsVisible() ) then
|
||
|
|
ShadowUF.Tags:FastRegister(frame, frame[key])
|
||
|
|
|
||
|
|
frame[key].visibilityManaged = true
|
||
|
|
frame[key]:Show()
|
||
|
|
ShadowUF.Layout:PositionWidgets(frame, ShadowUF.db.profile.units[frame.unitType])
|
||
|
|
|
||
|
|
-- Hide the bar if it wasn't already
|
||
|
|
elseif( not status and frame[key]:IsVisible() ) then
|
||
|
|
ShadowUF.Tags:FastUnregister(frame, frame[key])
|
||
|
|
|
||
|
|
frame[key].visibilityManaged = nil
|
||
|
|
frame[key]:Hide()
|
||
|
|
ShadowUF.Layout:PositionWidgets(frame, ShadowUF.db.profile.units[frame.unitType])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
-- Frame changed somehow between when we first set it all up and now
|
||
|
|
function Layout:Reload(unit)
|
||
|
|
updateBackdrop()
|
||
|
|
|
||
|
|
-- Now update them
|
||
|
|
for frame in pairs(ShadowUF.Units.frameList) do
|
||
|
|
if( frame.unit and ( not unit or frame.unitType == unit ) and not frame.isHeaderFrame ) then
|
||
|
|
frame:SetVisibility()
|
||
|
|
self:Load(frame)
|
||
|
|
frame:FullUpdate()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for header in pairs(ShadowUF.Units.headerFrames) do
|
||
|
|
if( header.unitType and ( not unit or header.unitType == unit ) ) then
|
||
|
|
local config = ShadowUF.db.profile.units[header.unitType]
|
||
|
|
header:SetAttribute("style-height", config.height)
|
||
|
|
header:SetAttribute("style-width", config.width)
|
||
|
|
header:SetAttribute("style-scale", config.scale)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
ShadowUF:FireModuleEvent("OnLayoutReload", unit)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Do a full update
|
||
|
|
function Layout:Load(frame)
|
||
|
|
local unitConfig = ShadowUF.db.profile.units[frame.unitType]
|
||
|
|
|
||
|
|
-- About to set layout
|
||
|
|
ShadowUF:FireModuleEvent("OnPreLayoutApply", frame, unitConfig)
|
||
|
|
|
||
|
|
-- Figure out if we're secure locking
|
||
|
|
frame.secureLocked = nil
|
||
|
|
for _, module in pairs(ShadowUF.moduleOrder) do
|
||
|
|
if( frame.visibility[module.moduleKey] and ShadowUF.db.profile.units[frame.unitType][module.moduleKey] and
|
||
|
|
ShadowUF.db.profile.units[frame.unitType][module.moduleKey].secure and module:SecureLockable() ) then
|
||
|
|
frame.secureLocked = true
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Load all of the layout things
|
||
|
|
self:SetupFrame(frame, unitConfig)
|
||
|
|
self:SetupBars(frame, unitConfig)
|
||
|
|
self:PositionWidgets(frame, unitConfig)
|
||
|
|
self:SetupText(frame, unitConfig)
|
||
|
|
|
||
|
|
-- Layouts been fully set
|
||
|
|
ShadowUF:FireModuleEvent("OnLayoutApplied", frame, unitConfig)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Register it on file load because authors seem to do a bad job at registering the callbacks
|
||
|
|
SML = LibStub:GetLibrary("LibSharedMedia-3.0")
|
||
|
|
SML:Register(SML.MediaType.FONT, "Myriad Condensed Web", "Interface\\AddOns\\ShadowedUnitFrames\\media\\fonts\\Myriad Condensed Web.ttf")
|
||
|
|
SML:Register(SML.MediaType.BORDER, "Square Clean", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\ABFBorder")
|
||
|
|
SML:Register(SML.MediaType.BACKGROUND, "Chat Frame", "Interface\\ChatFrame\\ChatFrameBackground")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "BantoBar", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\banto")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Smooth", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\smooth")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Smooth v2","Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\Smoothv2")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Smoother", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\smoother")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Perl", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\perl")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Glaze", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\glaze")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Charcoal", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\Charcoal")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Otravi", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\otravi")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Striped", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\striped")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "LiteStep", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\LiteStep")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Aluminium", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\Aluminium")
|
||
|
|
SML:Register(SML.MediaType.STATUSBAR, "Minimalist", "Interface\\AddOns\\ShadowedUnitFrames\\media\\textures\\Minimalist")
|
||
|
|
|
||
|
|
function Layout:LoadSML()
|
||
|
|
SML.RegisterCallback(self, "LibSharedMedia_Registered", "MediaRegistered")
|
||
|
|
SML.RegisterCallback(self, "LibSharedMedia_SetGlobal", "MediaForced")
|
||
|
|
self:CheckMedia()
|
||
|
|
end
|
||
|
|
|
||
|
|
--[[
|
||
|
|
Keep in mind this is relative to where you're parenting it, RT will put the object outside of the frame, on the right side, at the top of it while ITR will put it inside the frame, at the top to the right
|
||
|
|
|
||
|
|
* Positions OUTSIDE the frame
|
||
|
|
RT = Right Top, RC = Right Center, RB = Right Bottom
|
||
|
|
LT = Left Top, LC = Left Center, LB = Left Bottom,
|
||
|
|
BL = Bottom Left, BC = Bottom Center, BR = Bottom Right
|
||
|
|
TR = Top Right, TC = Top Center, TL = Top Left
|
||
|
|
|
||
|
|
* Positions INSIDE the frame
|
||
|
|
CLI = Inside Center Left, CRI = Inside Center Right
|
||
|
|
TRI = Inside Top Right, TLI = Inside Top Left
|
||
|
|
BRI = Inside Bottom Right, BRI = Inside Bottom left
|
||
|
|
]]
|
||
|
|
|
||
|
|
local preDefPoint = {C = "CENTER", CLI = "LEFT", RT = "TOPLEFT", BC = "TOP", CRI = "RIGHT", LT = "TOPRIGHT", TR = "BOTTOMRIGHT", BL = "TOPLEFT", LB = "BOTTOMRIGHT", LC = "RIGHT", RB = "BOTTOMLEFT", RC = "LEFT", TC = "BOTTOM", BR = "TOPRIGHT", TL = "BOTTOMLEFT", BRI = "BOTTOMRIGHT", BLI = "BOTTOMLEFT", TRI = "TOPRIGHT", TLI = "TOPLEFT"}
|
||
|
|
local preDefRelative = {C = "CENTER", CLI = "LEFT", RT = "TOPRIGHT", BC = "BOTTOM", CRI = "RIGHT", LT = "TOPLEFT", TR = "TOPRIGHT", BL = "BOTTOMLEFT", LB = "BOTTOMLEFT", LC = "LEFT", RB = "BOTTOMRIGHT", RC = "RIGHT", TC = "TOP", BR = "BOTTOMRIGHT", TL = "TOPLEFT", BRI = "BOTTOMRIGHT", BLI = "BOTTOMLEFT", TRI = "TOPRIGHT", TLI = "TOPLEFT"}
|
||
|
|
local columnDirection = {RT = "RIGHT", C = "RIGHT", BC = "BOTTOM", LT = "LEFT", TR = "TOP", BL = "BOTTOM", LB = "LEFT", LC = "LEFT", TRI = "TOP", RB = "RIGHT", RC = "RIGHT", TC = "TOP", CLI = "RIGHT", TL = "TOP", BR = "BOTTOM", IBL = "RIGHT", IBR = "RIGHT", CRI = "RIGHT", TLI = "TOP"}
|
||
|
|
local auraDirection = {RT = "BOTTOM", C = "LEFT", BC = "LEFT", LT = "BOTTOM", TR = "LEFT", BL = "RIGHT", LB = "TOP", LC = "LEFT", TRI = "LEFT", RB = "TOP", RC = "LEFT", TC = "LEFT", CLI = "RIGHT", TL = "RIGHT", BR = "LEFT", IBL = "TOP", IBR = "TOP", CRI = "LEFT", TLI = "RIGHT"}
|
||
|
|
|
||
|
|
-- Figures out how text should be justified based on where it's anchoring
|
||
|
|
function Layout:GetJustify(config)
|
||
|
|
local point = config.anchorPoint and config.anchorPoint ~= "" and preDefPoint[config.anchorPoint] or config.point
|
||
|
|
if( point and point ~= "" ) then
|
||
|
|
if( string.match(point, "LEFT$") ) then
|
||
|
|
return "LEFT"
|
||
|
|
elseif( string.match(point, "RIGHT$") ) then
|
||
|
|
return "RIGHT"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return "CENTER"
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:GetPoint(key)
|
||
|
|
return preDefPoint[key] or "CENTER"
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:GetRelative(key)
|
||
|
|
return preDefRelative[key] or "CENTER"
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:GetColumnGrowth(key)
|
||
|
|
return columnDirection[key] or "DOWN"
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:GetAuraGrowth(key)
|
||
|
|
return auraDirection[key] or "LEFT"
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:ReverseDirection(key)
|
||
|
|
return key == "LEFT" and "RIGHT" or key == "RIGHT" and "LEFT" or key == "TOP" and "BOTTOM" or key == "BOTTOM" and "TOP"
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Gets the relative anchoring for Blizzards default raid frames, these differ from the split ones
|
||
|
|
function Layout:GetRelativeAnchor(point)
|
||
|
|
if( point == "TOP" ) then
|
||
|
|
return "BOTTOM", 0, -1
|
||
|
|
elseif( point == "BOTTOM" ) then
|
||
|
|
return "TOP", 0, 1
|
||
|
|
elseif( point == "LEFT" ) then
|
||
|
|
return "RIGHT", 1, 0
|
||
|
|
elseif( point == "RIGHT" ) then
|
||
|
|
return "LEFT", -1, 0
|
||
|
|
elseif( point == "TOPLEFT" ) then
|
||
|
|
return "BOTTOMRIGHT", 1, -1
|
||
|
|
elseif( point == "TOPRIGHT" ) then
|
||
|
|
return "BOTTOMLEFT", -1, -1
|
||
|
|
elseif( point == "BOTTOMLEFT" ) then
|
||
|
|
return "TOPRIGHT", 1, 1
|
||
|
|
elseif( point == "BOTTOMRIGHT" ) then
|
||
|
|
return "TOPLEFT", -1, 1
|
||
|
|
else
|
||
|
|
return "CENTER", 0, 0
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:GetSplitRelativeAnchor(point, columnPoint)
|
||
|
|
-- Column is growing to the RIGHT
|
||
|
|
if( columnPoint == "LEFT" ) then
|
||
|
|
return "TOPLEFT", "TOPRIGHT", 1, 0
|
||
|
|
-- Column is growing to the LEFT
|
||
|
|
elseif( columnPoint == "RIGHT" ) then
|
||
|
|
return "TOPRIGHT", "TOPLEFT", -1, 0
|
||
|
|
-- Column is growing DOWN
|
||
|
|
elseif( columnPoint == "TOP" ) then
|
||
|
|
return "TOP" .. point, "BOTTOM" .. point, 0, -1
|
||
|
|
-- Column is growing UP
|
||
|
|
elseif( columnPoint == "BOTTOM" ) then
|
||
|
|
return "BOTTOM" .. point, "TOP" .. point, 0, 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:AnchorFrame(parent, frame, config)
|
||
|
|
if( not config or not config.anchorTo or not config.x or not config.y ) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local anchorTo = config.anchorTo
|
||
|
|
local prefix = string.sub(config.anchorTo, 0, 1)
|
||
|
|
if( config.anchorTo == "$parent" ) then
|
||
|
|
anchorTo = parent
|
||
|
|
-- $ is used as an indicator of a sub-frame inside a parent, $healthBar -> parent.healthBar and so on
|
||
|
|
elseif( prefix == "$" ) then
|
||
|
|
anchorTo = parent[string.sub(config.anchorTo, 2)]
|
||
|
|
-- # is used as an indicator of an actual frame created by SUF, it lets us know that the frame might not be created yet
|
||
|
|
-- and if so, to watch for it to be created and fix the anchoring
|
||
|
|
elseif( prefix == "#" ) then
|
||
|
|
anchorTo = string.sub(config.anchorTo, 2)
|
||
|
|
|
||
|
|
-- The frame we wanted to anchor to doesn't exist yet, so will queue and wait for it to exist
|
||
|
|
if( not _G[anchorTo] ) then
|
||
|
|
frame.queuedParent = parent
|
||
|
|
frame.queuedConfig = config
|
||
|
|
frame.queuedName = anchorTo
|
||
|
|
|
||
|
|
anchoringQueued = anchoringQueued or {}
|
||
|
|
anchoringQueued[frame] = true
|
||
|
|
|
||
|
|
-- For the time being, will take over the frame we wanted to anchor to's position.
|
||
|
|
local unit = string.match(anchorTo, "SUFUnit(%w+)") or string.match(anchorTo, "SUFHeader(%w+)")
|
||
|
|
if( unit and ShadowUF.db.profile.positions[unit] ) then
|
||
|
|
self:AnchorFrame(parent, frame, ShadowUF.db.profile.positions[unit])
|
||
|
|
end
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if( config.block ) then
|
||
|
|
anchorTo = anchorTo.blocks[frame.blockID]
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Figure out where it's anchored
|
||
|
|
local point = config.point and config.point ~= "" and config.point or preDefPoint[config.anchorPoint] or "CENTER"
|
||
|
|
local relativePoint = config.relativePoint and config.relativePoint ~= "" and config.relativePoint or preDefRelative[config.anchorPoint] or "CENTER"
|
||
|
|
|
||
|
|
-- Effective scaling is only used for unit based frames and if they are anchored to UIParent
|
||
|
|
local scale = 1
|
||
|
|
if( config.anchorTo == "UIParent" and frame.unitType ) then
|
||
|
|
scale = frame:GetScale() * UIParent:GetScale()
|
||
|
|
end
|
||
|
|
|
||
|
|
frame:ClearAllPoints()
|
||
|
|
frame:SetPoint(point, anchorTo, relativePoint, config.x / scale, config.y / scale)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Setup the main frame
|
||
|
|
function Layout:SetupFrame(frame, config)
|
||
|
|
local backdrop = ShadowUF.db.profile.backdrop
|
||
|
|
frame.backdropInfo = backdropTbl
|
||
|
|
frame:ApplyBackdrop()
|
||
|
|
frame:SetBackdropColor(backdrop.backgroundColor.r, backdrop.backgroundColor.g, backdrop.backgroundColor.b, backdrop.backgroundColor.a)
|
||
|
|
frame:SetBackdropBorderColor(backdrop.borderColor.r, backdrop.borderColor.g, backdrop.borderColor.b, backdrop.borderColor.a)
|
||
|
|
|
||
|
|
-- Prevent these from updating while in combat to prevent tainting
|
||
|
|
if( not InCombatLockdown() ) then
|
||
|
|
frame:SetHeight(config.height)
|
||
|
|
frame:SetWidth(config.width)
|
||
|
|
frame:SetScale(config.scale)
|
||
|
|
|
||
|
|
-- Let the frame clip closer to the edge, not using inset + clip as that lets you move it too far in
|
||
|
|
local clamp = backdrop.inset + 0.20
|
||
|
|
frame:SetClampRectInsets(clamp, -clamp, -clamp, clamp)
|
||
|
|
frame:SetClampedToScreen(true)
|
||
|
|
|
||
|
|
-- This is wrong technically, I need to redo the backdrop stuff so it will accept insets and that will fit hitbox issues
|
||
|
|
-- for the time being, this is a temporary fix to it
|
||
|
|
local hit = backdrop.borderTexture == "None" and backdrop.inset or 0
|
||
|
|
frame:SetHitRectInsets(hit, hit, hit, hit)
|
||
|
|
|
||
|
|
if( not frame.ignoreAnchor ) then
|
||
|
|
self:AnchorFrame(frame.parent or UIParent, frame, ShadowUF.db.profile.positions[frame.unitType])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Check if we had anything parented to us
|
||
|
|
if( anchoringQueued ) then
|
||
|
|
for queued in pairs(anchoringQueued) do
|
||
|
|
if( queued.queuedName == frame:GetName() ) then
|
||
|
|
self:AnchorFrame(queued.queuedParent, queued, queued.queuedConfig)
|
||
|
|
|
||
|
|
queued.queuedParent = nil
|
||
|
|
queued.queuedConfig = nil
|
||
|
|
queued.queuedName = nil
|
||
|
|
anchoringQueued[queued] = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Setup bars
|
||
|
|
function Layout:SetupBars(frame, config)
|
||
|
|
for _, module in pairs(ShadowUF.modules) do
|
||
|
|
local key = module.moduleKey
|
||
|
|
local widget = frame[key]
|
||
|
|
if( widget and ( module.moduleHasBar or config[key] and config[key].isBar ) ) then
|
||
|
|
if( frame.visibility[key] and not frame[key].visibilityManaged and module.defaultVisibility == false ) then
|
||
|
|
self:ToggleVisibility(widget, false)
|
||
|
|
else
|
||
|
|
self:ToggleVisibility(widget, frame.visibility[key])
|
||
|
|
end
|
||
|
|
|
||
|
|
if( ( widget:IsShown() or ( not frame[key].visibilityManaged and module.defaultVisibility == false ) ) and widget.SetStatusBarTexture ) then
|
||
|
|
widget:SetStatusBarTexture(mediaPath.statusbar)
|
||
|
|
widget:GetStatusBarTexture():SetHorizTile(false)
|
||
|
|
|
||
|
|
widget:SetOrientation(config[key].vertical and "VERTICAL" or "HORIZONTAL")
|
||
|
|
widget:SetReverseFill(config[key].reverse and true or false)
|
||
|
|
end
|
||
|
|
|
||
|
|
if( widget.background ) then
|
||
|
|
if( config[key].background or config[key].invert ) then
|
||
|
|
widget.background:SetTexture(mediaPath.statusbar)
|
||
|
|
widget.background:SetHorizTile(false)
|
||
|
|
widget.background:Show()
|
||
|
|
|
||
|
|
widget.background.overrideColor = ShadowUF.db.profile.bars.backgroundColor or config[key].backgroundColor
|
||
|
|
|
||
|
|
if( widget.background.overrideColor ) then
|
||
|
|
widget.background:SetVertexColor(widget.background.overrideColor.r, widget.background.overrideColor.g, widget.background.overrideColor.b, ShadowUF.db.profile.bars.backgroundAlpha)
|
||
|
|
end
|
||
|
|
else
|
||
|
|
widget.background:Hide()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Setup text
|
||
|
|
function Layout:SetupFontString(fontString, extraSize)
|
||
|
|
local size = ShadowUF.db.profile.font.size + (extraSize or 0)
|
||
|
|
if( size <= 0 ) then size = 1 end
|
||
|
|
|
||
|
|
fontString:SetFont(mediaPath.font, size, ShadowUF.db.profile.font.extra)
|
||
|
|
|
||
|
|
if( ShadowUF.db.profile.font.shadowColor and ShadowUF.db.profile.font.shadowX and ShadowUF.db.profile.font.shadowY ) then
|
||
|
|
fontString:SetShadowColor(ShadowUF.db.profile.font.shadowColor.r, ShadowUF.db.profile.font.shadowColor.g, ShadowUF.db.profile.font.shadowColor.b, ShadowUF.db.profile.font.shadowColor.a)
|
||
|
|
fontString:SetShadowOffset(ShadowUF.db.profile.font.shadowX, ShadowUF.db.profile.font.shadowY)
|
||
|
|
else
|
||
|
|
fontString:SetShadowColor(0, 0, 0, 0)
|
||
|
|
fontString:SetShadowOffset(0, 0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local totalWeight = {}
|
||
|
|
function Layout:InitFontString(parent, frame, id, config, blockID)
|
||
|
|
local rowID = blockID and tonumber(id .. "." .. blockID) or id
|
||
|
|
|
||
|
|
local fontString = frame.fontStrings[rowID] or frame.highFrame:CreateFontString(nil, "ARTWORK")
|
||
|
|
fontString.configID = id
|
||
|
|
if( blockID ) then
|
||
|
|
fontString.blockID = blockID
|
||
|
|
fontString.block = parent.blocks[blockID]
|
||
|
|
end
|
||
|
|
|
||
|
|
self:SetupFontString(fontString, config.size)
|
||
|
|
fontString:SetTextColor(ShadowUF.db.profile.font.color.r, ShadowUF.db.profile.font.color.g, ShadowUF.db.profile.font.color.b, ShadowUF.db.profile.font.color.a)
|
||
|
|
fontString:SetText(config.text)
|
||
|
|
fontString:SetJustifyH(self:GetJustify(config))
|
||
|
|
self:AnchorFrame(frame, fontString, config)
|
||
|
|
|
||
|
|
-- We figure out the anchor point so we can put text in the same area with the same width requirements
|
||
|
|
local anchorPoint = columnDirection[config.anchorPoint]
|
||
|
|
if( string.len(config.anchorPoint) == 3 ) then anchorPoint = anchorPoint .. "I" end
|
||
|
|
|
||
|
|
fontString.parentBar = parent
|
||
|
|
fontString.availableWidth = parent:GetWidth() - config.x
|
||
|
|
fontString.widthID = config.anchorTo .. anchorPoint .. config.y
|
||
|
|
totalWeight[fontString.widthID] = (totalWeight[fontString.widthID] or 0) + config.width
|
||
|
|
|
||
|
|
ShadowUF.Tags:Register(frame, fontString, config.text)
|
||
|
|
fontString:UpdateTags()
|
||
|
|
fontString:Show()
|
||
|
|
|
||
|
|
frame.fontStrings[rowID] = fontString
|
||
|
|
end
|
||
|
|
|
||
|
|
function Layout:SetupText(frame, config)
|
||
|
|
-- Update tag text
|
||
|
|
frame.fontStrings = frame.fontStrings or {}
|
||
|
|
for _, fontString in pairs(frame.fontStrings) do
|
||
|
|
ShadowUF.Tags:Unregister(fontString)
|
||
|
|
fontString:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
for k in pairs(totalWeight) do totalWeight[k] = nil end
|
||
|
|
|
||
|
|
-- Update the actual text, and figure out the weighting information now
|
||
|
|
for id, row in pairs(config.text) do
|
||
|
|
local module = string.sub(row.anchorTo, 2)
|
||
|
|
local parent = row.anchorTo == "$parent" and frame or frame[module]
|
||
|
|
if( parent and ( ShadowUF.modules[module].defaultVisibility == false or parent:IsShown() ) and row.enabled and row.text ~= "" ) then
|
||
|
|
if( not row.block ) then
|
||
|
|
self:InitFontString(parent, frame, id, row, nil)
|
||
|
|
else
|
||
|
|
for blockID, block in pairs(parent.blocks) do
|
||
|
|
self:InitFontString(parent, frame, id, row, blockID)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Now set all of the width using our weightings
|
||
|
|
for _, fontString in pairs(frame.fontStrings) do
|
||
|
|
local id = fontString.configID
|
||
|
|
if( fontString:IsShown() ) then
|
||
|
|
fontString:SetWidth(fontString.availableWidth * (config.text[id].width / totalWeight[fontString.widthID]))
|
||
|
|
fontString:SetHeight(ShadowUF.db.profile.font.size + 1)
|
||
|
|
|
||
|
|
frame:RegisterUpdateFunc(fontString, "UpdateTags")
|
||
|
|
else
|
||
|
|
frame:UnregisterAll(fontString)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Setup the bar barOrder/info
|
||
|
|
local currentConfig
|
||
|
|
local function sortOrder(a, b)
|
||
|
|
return currentConfig[a].order < currentConfig[b].order
|
||
|
|
end
|
||
|
|
|
||
|
|
local barOrder = {}
|
||
|
|
function Layout:PositionWidgets(frame, config)
|
||
|
|
-- Deal with setting all of the bar heights
|
||
|
|
local totalWidgetWeight, totalBars, hasFullSize = 0, -1
|
||
|
|
|
||
|
|
-- Figure out total weighting as well as what bars are full sized
|
||
|
|
for i=#(barOrder), 1, -1 do table.remove(barOrder, i) end
|
||
|
|
for key, module in pairs(ShadowUF.modules) do
|
||
|
|
if( config[key] and not config[key].height ) then config[key].height = 0.50 end
|
||
|
|
|
||
|
|
if( ( module.moduleHasBar or config[key] and config[key].isBar ) and frame[key] and frame[key]:IsShown() and config[key].height > 0 ) then
|
||
|
|
totalWidgetWeight = totalWidgetWeight + config[key].height
|
||
|
|
totalBars = totalBars + 1
|
||
|
|
|
||
|
|
table.insert(barOrder, key)
|
||
|
|
|
||
|
|
config[key].order = config[key].order or 99
|
||
|
|
|
||
|
|
-- Decide whats full sized
|
||
|
|
if( not frame.visibility.portrait or config.portrait.isBar or config[key].order < config.portrait.fullBefore or config[key].order > config.portrait.fullAfter ) then
|
||
|
|
hasFullSize = true
|
||
|
|
frame[key].fullSize = true
|
||
|
|
else
|
||
|
|
frame[key].fullSize = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Sort the barOrder so it's all nice and orderly (:>)
|
||
|
|
currentConfig = config
|
||
|
|
table.sort(barOrder, sortOrder)
|
||
|
|
|
||
|
|
-- Now deal with setting the heights and figure out how large the portrait should be.
|
||
|
|
local clip = ShadowUF.db.profile.backdrop.inset + ShadowUF.db.profile.backdrop.clip
|
||
|
|
local clipDoubled = clip * 2
|
||
|
|
|
||
|
|
local portraitOffset, portraitAlignment, portraitAnchor, portraitWidth
|
||
|
|
if( not config.portrait.isBar ) then
|
||
|
|
self:ToggleVisibility(frame.portrait, frame.visibility.portrait)
|
||
|
|
|
||
|
|
if( frame.visibility.portrait ) then
|
||
|
|
-- Figure out portrait alignment
|
||
|
|
portraitAlignment = config.portrait.alignment
|
||
|
|
|
||
|
|
-- Set the portrait width so we can figure out the offset to use on bars, will do height and position later
|
||
|
|
portraitWidth = math.floor(frame:GetWidth() * config.portrait.width) - ShadowUF.db.profile.backdrop.inset
|
||
|
|
frame.portrait:SetWidth(portraitWidth - (portraitAlignment == "RIGHT" and 1 or 0.5))
|
||
|
|
|
||
|
|
-- Disable portrait if there isn't enough room
|
||
|
|
if( portraitWidth <= 0 ) then
|
||
|
|
frame.portrait:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- As well as how much to offset bars by (if it's using a left alignment) to keep them all fancy looking
|
||
|
|
portraitOffset = clip
|
||
|
|
if( portraitAlignment == "LEFT" ) then
|
||
|
|
portraitOffset = portraitOffset + portraitWidth
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Position and size everything
|
||
|
|
local portraitHeight, xOffset = 0, -clip
|
||
|
|
local availableHeight = frame:GetHeight() - clipDoubled - (math.abs(ShadowUF.db.profile.bars.spacing) * totalBars)
|
||
|
|
for id, key in pairs(barOrder) do
|
||
|
|
local bar = frame[key]
|
||
|
|
|
||
|
|
-- Position the actual bar based on it's type
|
||
|
|
if( bar.fullSize ) then
|
||
|
|
bar:SetWidth(frame:GetWidth() - clipDoubled)
|
||
|
|
bar:SetHeight(availableHeight * (config[key].height / totalWidgetWeight))
|
||
|
|
|
||
|
|
bar:ClearAllPoints()
|
||
|
|
bar:SetPoint("TOPLEFT", frame, "TOPLEFT", clip, xOffset)
|
||
|
|
else
|
||
|
|
bar:SetWidth(frame:GetWidth() - portraitWidth - clipDoubled)
|
||
|
|
bar:SetHeight(availableHeight * (config[key].height / totalWidgetWeight))
|
||
|
|
|
||
|
|
bar:ClearAllPoints()
|
||
|
|
bar:SetPoint("TOPLEFT", frame, "TOPLEFT", portraitOffset, xOffset)
|
||
|
|
|
||
|
|
portraitHeight = portraitHeight + bar:GetHeight()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Figure out where the portrait is going to be anchored to
|
||
|
|
if( not portraitAnchor and config[key].order >= config.portrait.fullBefore ) then
|
||
|
|
portraitAnchor = bar
|
||
|
|
end
|
||
|
|
|
||
|
|
xOffset = xOffset - bar:GetHeight() + ShadowUF.db.profile.bars.spacing
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Now position the portrait and set the height
|
||
|
|
if( frame.portrait and frame.portrait:IsShown() and portraitAnchor and portraitHeight > 0 ) then
|
||
|
|
if( portraitAlignment == "LEFT" ) then
|
||
|
|
frame.portrait:ClearAllPoints()
|
||
|
|
frame.portrait:SetPoint("TOPLEFT", portraitAnchor, "TOPLEFT", -frame.portrait:GetWidth() - 0.5, 0)
|
||
|
|
elseif( portraitAlignment == "RIGHT" ) then
|
||
|
|
frame.portrait:ClearAllPoints()
|
||
|
|
frame.portrait:SetPoint("TOPRIGHT", portraitAnchor, "TOPRIGHT", frame.portrait:GetWidth() + 1, 0)
|
||
|
|
end
|
||
|
|
|
||
|
|
if( hasFullSize ) then
|
||
|
|
frame.portrait:SetHeight(portraitHeight)
|
||
|
|
else
|
||
|
|
frame.portrait:SetHeight(frame:GetHeight() - clipDoubled)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
ShadowUF:FireModuleEvent("OnLayoutWidgets", frame, config)
|
||
|
|
end
|
||
|
|
|