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

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