diff --git a/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua b/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua index 532a33fd..4b34e48e 100644 --- a/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua +++ b/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua @@ -4003,6 +4003,96 @@ initFrame:SetScript("OnEvent", function(self) RegisterWidgetRefresh(UpdateCenterCogState) end + -- Row 5: Top Left Text + Top Right Text (above health bar) + local sharedTopTextRow + sharedTopTextRow, h = W:DualRow(parent, y, + { type="dropdown", text="Top Left Text", values=btbTextValues, order=btbTextOrder, + getValue=function() return SVal("topLeftContent", "none") end, + setValue=function(v) + SSet("topLeftContent", v) + UpdatePreview() + end }, + { type="dropdown", text="Top Right Text", values=btbTextValues, order=btbTextOrder, + getValue=function() return SVal("topRightContent", "none") end, + setValue=function(v) + SSet("topRightContent", v) + UpdatePreview() + end }); y = y - h + -- Cogwheel on Top Left Text + do + local topLeftRgn = sharedTopTextRow._leftRegion + local _, topLeftCogShowRaw = EllesmereUI.BuildCogPopup({ + title = "Top Left Text Settings", + rows = { + { type="toggle", label="Class Color", + get=function() return SVal("topLeftClassColor", false) end, + set=function(v) SSet("topLeftClassColor", v); UpdatePreview() end }, + { type="slider", label="Size", min=8, max=24, step=1, + get=function() return SVal("topLeftSize", 12) end, + set=function(v) SSet("topLeftSize", v); UpdatePreview() end }, + { type="slider", label="X", min=-50, max=50, step=1, + get=function() return SVal("topLeftX", 0) end, + set=function(v) SSet("topLeftX", v); UpdatePreview() end }, + { type="slider", label="Y", min=-30, max=30, step=1, + get=function() return SVal("topLeftY", 0) end, + set=function(v) SSet("topLeftY", v); UpdatePreview() end }, + }, + }) + local topLeftCogShow = topLeftCogShowRaw + local topLeftCogBtn = MakeCogBtn(topLeftRgn, topLeftCogShow) + local function UpdateTopLeftCogState() + local isNone = SVal("topLeftContent", "none") == "none" + topLeftCogBtn:SetAlpha(isNone and 0.15 or 0.4) + topLeftCogBtn:SetEnabled(not isNone) + end + topLeftCogBtn:SetScript("OnEnter", function(self) + if SVal("topLeftContent", "none") == "none" then + EllesmereUI.ShowWidgetTooltip(self, EllesmereUI.DisabledTooltip("This option requires a text selection other than none.")) + else self:SetAlpha(0.7) end + end) + topLeftCogBtn:SetScript("OnLeave", function(self) UpdateTopLeftCogState(); EllesmereUI.HideWidgetTooltip() end) + topLeftCogBtn:SetScript("OnClick", function(self) topLeftCogShow(self) end) + UpdateTopLeftCogState() + RegisterWidgetRefresh(UpdateTopLeftCogState) + end + -- Cogwheel on Top Right Text + do + local topRightRgn = sharedTopTextRow._rightRegion + local _, topRightCogShowRaw = EllesmereUI.BuildCogPopup({ + title = "Top Right Text Settings", + rows = { + { type="toggle", label="Class Color", + get=function() return SVal("topRightClassColor", false) end, + set=function(v) SSet("topRightClassColor", v); UpdatePreview() end }, + { type="slider", label="Size", min=8, max=24, step=1, + get=function() return SVal("topRightSize", 12) end, + set=function(v) SSet("topRightSize", v); UpdatePreview() end }, + { type="slider", label="X", min=-50, max=50, step=1, + get=function() return SVal("topRightX", 0) end, + set=function(v) SSet("topRightX", v); UpdatePreview() end }, + { type="slider", label="Y", min=-30, max=30, step=1, + get=function() return SVal("topRightY", 0) end, + set=function(v) SSet("topRightY", v); UpdatePreview() end }, + }, + }) + local topRightCogShow = topRightCogShowRaw + local topRightCogBtn = MakeCogBtn(topRightRgn, topRightCogShow) + local function UpdateTopRightCogState() + local isNone = SVal("topRightContent", "none") == "none" + topRightCogBtn:SetAlpha(isNone and 0.15 or 0.4) + topRightCogBtn:SetEnabled(not isNone) + end + topRightCogBtn:SetScript("OnEnter", function(self) + if SVal("topRightContent", "none") == "none" then + EllesmereUI.ShowWidgetTooltip(self, EllesmereUI.DisabledTooltip("This option requires a text selection other than none.")) + else self:SetAlpha(0.7) end + end) + topRightCogBtn:SetScript("OnLeave", function(self) UpdateTopRightCogState(); EllesmereUI.HideWidgetTooltip() end) + topRightCogBtn:SetScript("OnClick", function(self) topRightCogShow(self) end) + UpdateTopRightCogState() + RegisterWidgetRefresh(UpdateTopRightCogState) + end + _, h = W:Spacer(parent, y, 20); y = y - h ------------------------------------------------------------------- diff --git a/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua b/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua index d7efeea1..2cec9a7a 100644 --- a/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua +++ b/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua @@ -58,6 +58,16 @@ local defaults = { centerTextX = 0, centerTextY = 0, centerTextClassColor = false, + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, bottomTextBar = false, bottomTextBarHeight = 16, btbPosition = "bottom", @@ -207,6 +217,16 @@ local defaults = { centerTextX = 0, centerTextY = 0, centerTextClassColor = false, + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, bottomTextBar = false, bottomTextBarHeight = 16, btbPosition = "bottom", @@ -310,6 +330,16 @@ local defaults = { leftTextContent = "name", rightTextContent = "none", centerTextContent = "none", + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, borderSize = 1, borderColor = { r = 0, g = 0, b = 0 }, highlightColor = { r = 1, g = 1, b = 1 }, @@ -327,6 +357,16 @@ local defaults = { leftTextContent = "name", rightTextContent = "none", centerTextContent = "none", + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, borderSize = 1, borderColor = { r = 0, g = 0, b = 0 }, highlightColor = { r = 1, g = 1, b = 1 }, @@ -376,6 +416,16 @@ local defaults = { centerTextX = 0, centerTextY = 0, centerTextClassColor = false, + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, bottomTextBar = false, bottomTextBarHeight = 16, btbPosition = "bottom", @@ -470,6 +520,16 @@ local defaults = { leftTextContent = "name", rightTextContent = "perhp", centerTextContent = "none", + topLeftContent = "none", + topLeftSize = 12, + topLeftX = 0, + topLeftY = 0, + topLeftClassColor = false, + topRightContent = "none", + topRightSize = 12, + topRightX = 0, + topRightY = 0, + topRightClassColor = false, borderSize = 1, borderColor = { r = 0, g = 0, b = 0 }, highlightColor = { r = 1, g = 1, b = 1 }, @@ -2798,6 +2858,90 @@ local function StyleFullFrame(frame, unit) ApplyTextPositions(settings) frame._applyTextPositions = ApplyTextPositions + -- Top text overlay (above health bar) + local topTextOverlay = CreateFrame("Frame", nil, frame) + topTextOverlay:SetPoint("BOTTOMLEFT", frame.Health, "TOPLEFT", 0, 26) + topTextOverlay:SetPoint("BOTTOMRIGHT", frame.Health, "TOPRIGHT", 0, 26) + topTextOverlay:SetHeight(20) + topTextOverlay:SetFrameLevel(textOverlay:GetFrameLevel() + 5) + frame._topTextOverlay = topTextOverlay + + local topLeftText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topLeftText, settings.topLeftSize or 12) + topLeftText:SetWordWrap(false) + topLeftText:SetTextColor(1, 1, 1) + frame.TopLeftText = topLeftText + + local topRightText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topRightText, settings.topRightSize or 12) + topRightText:SetWordWrap(false) + topRightText:SetTextColor(1, 1, 1) + frame.TopRightText = topRightText + + local topLeftContent = settings.topLeftContent or "none" + local topRightContent = settings.topRightContent or "none" + + local function ApplyTopTextTags(tlc, trc) + local tltag = ContentToTag(tlc) + local trtag = ContentToTag(trc) + if topLeftText._curTag then frame:Untag(topLeftText); topLeftText._curTag = nil end + if topRightText._curTag then frame:Untag(topRightText); topRightText._curTag = nil end + if tltag then frame:Tag(topLeftText, tltag); topLeftText._curTag = tltag end + if trtag then frame:Tag(topRightText, trtag); topRightText._curTag = trtag end + if frame.UpdateTags then frame:UpdateTags() end + end + ApplyTopTextTags(topLeftContent, topRightContent) + frame._applyTopTextTags = ApplyTopTextTags + + local function ApplyTopTextPositions(s) + local tlc = s.topLeftContent or "none" + local trc = s.topRightContent or "none" + local tlsz = s.topLeftSize or 12 + local trsz = s.topRightSize or 12 + local tlxo = s.topLeftX or 0 + local tlyo = s.topLeftY or 0 + local trxo = s.topRightX or 0 + local tryo = s.topRightY or 0 + + SetFSFont(topLeftText, tlsz) + topLeftText:ClearAllPoints() + if tlc ~= "none" then + topLeftText:SetJustifyH("LEFT") + PP.Point(topLeftText, "BOTTOMLEFT", topTextOverlay, "BOTTOMLEFT", 5 + tlxo, tlyo) + topLeftText:Show() + ApplyClassColor(topLeftText, unit, s.topLeftClassColor) + else + topLeftText:Hide() + end + + SetFSFont(topRightText, trsz) + topRightText:ClearAllPoints() + if trc ~= "none" then + topRightText:SetJustifyH("RIGHT") + PP.Point(topRightText, "BOTTOMRIGHT", topTextOverlay, "BOTTOMRIGHT", -5 + trxo, tryo) + topRightText:Show() + ApplyClassColor(topRightText, unit, s.topRightClassColor) + else + topRightText:Hide() + end + + -- Constrain widths when both sides are active to prevent overlap + if tlc ~= "none" and trc ~= "none" then + local totalW = topTextOverlay:GetWidth() + if totalW and totalW > 0 then + local usedW = 20 + math.max(0, tlxo) + math.max(0, -trxo) + local halfW = (totalW - usedW) / 2 + topLeftText:SetWidth(math.max(halfW, 10)) + topRightText:SetWidth(math.max(halfW, 10)) + end + else + topLeftText:SetWidth(0) + topRightText:SetWidth(0) + end + end + ApplyTopTextPositions(settings) + frame._applyTopTextPositions = ApplyTopTextPositions + -- Bottom Text Bar if settings.bottomTextBar then local anchorFrame = (powerIsAtt and frame.Power) or frame.Health @@ -3012,6 +3156,90 @@ local function StyleFocusFrame(frame, unit) ApplyTextPositions(settings) frame._applyTextPositions = ApplyTextPositions + -- Top text overlay (above health bar) + local topTextOverlay = CreateFrame("Frame", nil, frame) + topTextOverlay:SetPoint("BOTTOMLEFT", frame.Health, "TOPLEFT", 0, 26) + topTextOverlay:SetPoint("BOTTOMRIGHT", frame.Health, "TOPRIGHT", 0, 26) + topTextOverlay:SetHeight(20) + topTextOverlay:SetFrameLevel(textOverlay:GetFrameLevel() + 5) + frame._topTextOverlay = topTextOverlay + + local topLeftText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topLeftText, settings.topLeftSize or 12) + topLeftText:SetWordWrap(false) + topLeftText:SetTextColor(1, 1, 1) + frame.TopLeftText = topLeftText + + local topRightText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topRightText, settings.topRightSize or 12) + topRightText:SetWordWrap(false) + topRightText:SetTextColor(1, 1, 1) + frame.TopRightText = topRightText + + local topLeftContent = settings.topLeftContent or "none" + local topRightContent = settings.topRightContent or "none" + + local function ApplyTopTextTags(tlc, trc) + local tltag = ContentToTag(tlc) + local trtag = ContentToTag(trc) + if topLeftText._curTag then frame:Untag(topLeftText); topLeftText._curTag = nil end + if topRightText._curTag then frame:Untag(topRightText); topRightText._curTag = nil end + if tltag then frame:Tag(topLeftText, tltag); topLeftText._curTag = tltag end + if trtag then frame:Tag(topRightText, trtag); topRightText._curTag = trtag end + if frame.UpdateTags then frame:UpdateTags() end + end + ApplyTopTextTags(topLeftContent, topRightContent) + frame._applyTopTextTags = ApplyTopTextTags + + local function ApplyTopTextPositions(s) + local tlc = s.topLeftContent or "none" + local trc = s.topRightContent or "none" + local tlsz = s.topLeftSize or 12 + local trsz = s.topRightSize or 12 + local tlxo = s.topLeftX or 0 + local tlyo = s.topLeftY or 0 + local trxo = s.topRightX or 0 + local tryo = s.topRightY or 0 + + SetFSFont(topLeftText, tlsz) + topLeftText:ClearAllPoints() + if tlc ~= "none" then + topLeftText:SetJustifyH("LEFT") + PP.Point(topLeftText, "BOTTOMLEFT", topTextOverlay, "BOTTOMLEFT", 5 + tlxo, tlyo) + topLeftText:Show() + ApplyClassColor(topLeftText, unit, s.topLeftClassColor) + else + topLeftText:Hide() + end + + SetFSFont(topRightText, trsz) + topRightText:ClearAllPoints() + if trc ~= "none" then + topRightText:SetJustifyH("RIGHT") + PP.Point(topRightText, "BOTTOMRIGHT", topTextOverlay, "BOTTOMRIGHT", -5 + trxo, tryo) + topRightText:Show() + ApplyClassColor(topRightText, unit, s.topRightClassColor) + else + topRightText:Hide() + end + + -- Constrain widths when both sides are active to prevent overlap + if tlc ~= "none" and trc ~= "none" then + local totalW = topTextOverlay:GetWidth() + if totalW and totalW > 0 then + local usedW = 20 + math.max(0, tlxo) + math.max(0, -trxo) + local halfW = (totalW - usedW) / 2 + topLeftText:SetWidth(math.max(halfW, 10)) + topRightText:SetWidth(math.max(halfW, 10)) + end + else + topLeftText:SetWidth(0) + topRightText:SetWidth(0) + end + end + ApplyTopTextPositions(settings) + frame._applyTopTextPositions = ApplyTopTextPositions + -- Bottom Text Bar if settings.bottomTextBar then local anchorFrame = (fPpIsAtt and frame.Power) or frame.Health @@ -3162,6 +3390,90 @@ local function StyleSimpleFrame(frame, unit) end ApplyTextPositions(settings) frame._applyTextPositions = ApplyTextPositions + + -- Top text overlay (above health bar) + local topTextOverlay = CreateFrame("Frame", nil, frame) + topTextOverlay:SetPoint("BOTTOMLEFT", health, "TOPLEFT", 0, 4) + topTextOverlay:SetPoint("BOTTOMRIGHT", health, "TOPRIGHT", 0, 4) + topTextOverlay:SetHeight(20) + topTextOverlay:SetFrameLevel(textOverlay:GetFrameLevel() + 5) + frame._topTextOverlay = topTextOverlay + + local topLeftText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topLeftText, settings.topLeftSize or 12) + topLeftText:SetWordWrap(false) + topLeftText:SetTextColor(1, 1, 1) + frame.TopLeftText = topLeftText + + local topRightText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topRightText, settings.topRightSize or 12) + topRightText:SetWordWrap(false) + topRightText:SetTextColor(1, 1, 1) + frame.TopRightText = topRightText + + local topLeftContent = settings.topLeftContent or "none" + local topRightContent = settings.topRightContent or "none" + + local function ApplyTopTextTags(tlc, trc) + local tltag = ContentToTag(tlc) + local trtag = ContentToTag(trc) + if topLeftText._curTag then frame:Untag(topLeftText); topLeftText._curTag = nil end + if topRightText._curTag then frame:Untag(topRightText); topRightText._curTag = nil end + if tltag then frame:Tag(topLeftText, tltag); topLeftText._curTag = tltag end + if trtag then frame:Tag(topRightText, trtag); topRightText._curTag = trtag end + if frame.UpdateTags then frame:UpdateTags() end + end + ApplyTopTextTags(topLeftContent, topRightContent) + frame._applyTopTextTags = ApplyTopTextTags + + local function ApplyTopTextPositions(s) + local tlc = s.topLeftContent or "none" + local trc = s.topRightContent or "none" + local tlsz = s.topLeftSize or 12 + local trsz = s.topRightSize or 12 + local tlxo = s.topLeftX or 0 + local tlyo = s.topLeftY or 0 + local trxo = s.topRightX or 0 + local tryo = s.topRightY or 0 + + SetFSFont(topLeftText, tlsz) + topLeftText:ClearAllPoints() + if tlc ~= "none" then + topLeftText:SetJustifyH("LEFT") + PP.Point(topLeftText, "BOTTOMLEFT", topTextOverlay, "BOTTOMLEFT", 5 + tlxo, tlyo) + topLeftText:Show() + ApplyClassColor(topLeftText, unit, s.topLeftClassColor) + else + topLeftText:Hide() + end + + SetFSFont(topRightText, trsz) + topRightText:ClearAllPoints() + if trc ~= "none" then + topRightText:SetJustifyH("RIGHT") + PP.Point(topRightText, "BOTTOMRIGHT", topTextOverlay, "BOTTOMRIGHT", -5 + trxo, tryo) + topRightText:Show() + ApplyClassColor(topRightText, unit, s.topRightClassColor) + else + topRightText:Hide() + end + + -- Constrain widths when both sides are active to prevent overlap + if tlc ~= "none" and trc ~= "none" then + local totalW = topTextOverlay:GetWidth() + if totalW and totalW > 0 then + local usedW = 20 + math.max(0, tlxo) + math.max(0, -trxo) + local halfW = (totalW - usedW) / 2 + topLeftText:SetWidth(math.max(halfW, 10)) + topRightText:SetWidth(math.max(halfW, 10)) + end + else + topLeftText:SetWidth(0) + topRightText:SetWidth(0) + end + end + ApplyTopTextPositions(settings) + frame._applyTopTextPositions = ApplyTopTextPositions end @@ -3318,6 +3630,90 @@ local function StylePetFrame(frame, unit) end ApplyTextPositions(settings) frame._applyTextPositions = ApplyTextPositions + + -- Top text overlay (above health bar) + local topTextOverlay = CreateFrame("Frame", nil, frame) + topTextOverlay:SetPoint("BOTTOMLEFT", health, "TOPLEFT", 0, 4) + topTextOverlay:SetPoint("BOTTOMRIGHT", health, "TOPRIGHT", 0, 4) + topTextOverlay:SetHeight(20) + topTextOverlay:SetFrameLevel(textOverlay:GetFrameLevel() + 5) + frame._topTextOverlay = topTextOverlay + + local topLeftText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topLeftText, settings.topLeftSize or 12) + topLeftText:SetWordWrap(false) + topLeftText:SetTextColor(1, 1, 1) + frame.TopLeftText = topLeftText + + local topRightText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topRightText, settings.topRightSize or 12) + topRightText:SetWordWrap(false) + topRightText:SetTextColor(1, 1, 1) + frame.TopRightText = topRightText + + local topLeftContent = settings.topLeftContent or "none" + local topRightContent = settings.topRightContent or "none" + + local function ApplyTopTextTags(tlc, trc) + local tltag = ContentToTag(tlc) + local trtag = ContentToTag(trc) + if topLeftText._curTag then frame:Untag(topLeftText); topLeftText._curTag = nil end + if topRightText._curTag then frame:Untag(topRightText); topRightText._curTag = nil end + if tltag then frame:Tag(topLeftText, tltag); topLeftText._curTag = tltag end + if trtag then frame:Tag(topRightText, trtag); topRightText._curTag = trtag end + if frame.UpdateTags then frame:UpdateTags() end + end + ApplyTopTextTags(topLeftContent, topRightContent) + frame._applyTopTextTags = ApplyTopTextTags + + local function ApplyTopTextPositions(s) + local tlc = s.topLeftContent or "none" + local trc = s.topRightContent or "none" + local tlsz = s.topLeftSize or 12 + local trsz = s.topRightSize or 12 + local tlxo = s.topLeftX or 0 + local tlyo = s.topLeftY or 0 + local trxo = s.topRightX or 0 + local tryo = s.topRightY or 0 + + SetFSFont(topLeftText, tlsz) + topLeftText:ClearAllPoints() + if tlc ~= "none" then + topLeftText:SetJustifyH("LEFT") + PP.Point(topLeftText, "BOTTOMLEFT", topTextOverlay, "BOTTOMLEFT", 5 + tlxo, tlyo) + topLeftText:Show() + ApplyClassColor(topLeftText, unit, s.topLeftClassColor) + else + topLeftText:Hide() + end + + SetFSFont(topRightText, trsz) + topRightText:ClearAllPoints() + if trc ~= "none" then + topRightText:SetJustifyH("RIGHT") + PP.Point(topRightText, "BOTTOMRIGHT", topTextOverlay, "BOTTOMRIGHT", -5 + trxo, tryo) + topRightText:Show() + ApplyClassColor(topRightText, unit, s.topRightClassColor) + else + topRightText:Hide() + end + + -- Constrain widths when both sides are active to prevent overlap + if tlc ~= "none" and trc ~= "none" then + local totalW = topTextOverlay:GetWidth() + if totalW and totalW > 0 then + local usedW = 20 + math.max(0, tlxo) + math.max(0, -trxo) + local halfW = (totalW - usedW) / 2 + topLeftText:SetWidth(math.max(halfW, 10)) + topRightText:SetWidth(math.max(halfW, 10)) + end + else + topLeftText:SetWidth(0) + topRightText:SetWidth(0) + end + end + ApplyTopTextPositions(settings) + frame._applyTopTextPositions = ApplyTopTextPositions end @@ -3453,6 +3849,90 @@ local function StyleBossFrame(frame, unit) end ApplyTextPositions(settings) frame._applyTextPositions = ApplyTextPositions + + -- Top text overlay (above health bar) + local topTextOverlay = CreateFrame("Frame", nil, frame) + topTextOverlay:SetPoint("BOTTOMLEFT", frame.Health, "TOPLEFT", 0, 26) + topTextOverlay:SetPoint("BOTTOMRIGHT", frame.Health, "TOPRIGHT", 0, 26) + topTextOverlay:SetHeight(20) + topTextOverlay:SetFrameLevel(textOverlay:GetFrameLevel() + 5) + frame._topTextOverlay = topTextOverlay + + local topLeftText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topLeftText, settings.topLeftSize or 12) + topLeftText:SetWordWrap(false) + topLeftText:SetTextColor(1, 1, 1) + frame.TopLeftText = topLeftText + + local topRightText = topTextOverlay:CreateFontString(nil, "OVERLAY") + SetFSFont(topRightText, settings.topRightSize or 12) + topRightText:SetWordWrap(false) + topRightText:SetTextColor(1, 1, 1) + frame.TopRightText = topRightText + + local topLeftContent = settings.topLeftContent or "none" + local topRightContent = settings.topRightContent or "none" + + local function ApplyTopTextTags(tlc, trc) + local tltag = ContentToTag(tlc) + local trtag = ContentToTag(trc) + if topLeftText._curTag then frame:Untag(topLeftText); topLeftText._curTag = nil end + if topRightText._curTag then frame:Untag(topRightText); topRightText._curTag = nil end + if tltag then frame:Tag(topLeftText, tltag); topLeftText._curTag = tltag end + if trtag then frame:Tag(topRightText, trtag); topRightText._curTag = trtag end + if frame.UpdateTags then frame:UpdateTags() end + end + ApplyTopTextTags(topLeftContent, topRightContent) + frame._applyTopTextTags = ApplyTopTextTags + + local function ApplyTopTextPositions(s) + local tlc = s.topLeftContent or "none" + local trc = s.topRightContent or "none" + local tlsz = s.topLeftSize or 12 + local trsz = s.topRightSize or 12 + local tlxo = s.topLeftX or 0 + local tlyo = s.topLeftY or 0 + local trxo = s.topRightX or 0 + local tryo = s.topRightY or 0 + + SetFSFont(topLeftText, tlsz) + topLeftText:ClearAllPoints() + if tlc ~= "none" then + topLeftText:SetJustifyH("LEFT") + PP.Point(topLeftText, "BOTTOMLEFT", topTextOverlay, "BOTTOMLEFT", 5 + tlxo, tlyo) + topLeftText:Show() + ApplyClassColor(topLeftText, unit, s.topLeftClassColor) + else + topLeftText:Hide() + end + + SetFSFont(topRightText, trsz) + topRightText:ClearAllPoints() + if trc ~= "none" then + topRightText:SetJustifyH("RIGHT") + PP.Point(topRightText, "BOTTOMRIGHT", topTextOverlay, "BOTTOMRIGHT", -5 + trxo, tryo) + topRightText:Show() + ApplyClassColor(topRightText, unit, s.topRightClassColor) + else + topRightText:Hide() + end + + -- Constrain widths when both sides are active to prevent overlap + if tlc ~= "none" and trc ~= "none" then + local totalW = topTextOverlay:GetWidth() + if totalW and totalW > 0 then + local usedW = 20 + math.max(0, tlxo) + math.max(0, -trxo) + local halfW = (totalW - usedW) / 2 + topLeftText:SetWidth(math.max(halfW, 10)) + topRightText:SetWidth(math.max(halfW, 10)) + end + else + topLeftText:SetWidth(0) + topRightText:SetWidth(0) + end + end + ApplyTopTextPositions(settings) + frame._applyTopTextPositions = ApplyTopTextPositions end @@ -4431,6 +4911,12 @@ local function ReloadFrames() if frame._applyTextPositions then frame._applyTextPositions(settings) end + if frame._applyTopTextTags then + frame._applyTopTextTags(settings.topLeftContent or "none", settings.topRightContent or "none") + end + if frame._applyTopTextPositions then + frame._applyTopTextPositions(settings) + end -- Bottom Text Bar update (player) if settings.bottomTextBar then @@ -4613,6 +5099,12 @@ local function ReloadFrames() if frame._applyTextPositions then frame._applyTextPositions(settings) end + if frame._applyTopTextTags then + frame._applyTopTextTags(settings.topLeftContent or "none", settings.topRightContent or "none") + end + if frame._applyTopTextPositions then + frame._applyTopTextPositions(settings) + end -- Bottom Text Bar update (target) ? must come before castbar so castbar can anchor to it local tPpBtbAnchor = (ppIsAtt and (settings.powerHeight or 0) > 0 and frame.Power and frame.Power:IsShown()) and frame.Power or frame.Health @@ -4941,6 +5433,12 @@ local function ReloadFrames() if frame._applyTextPositions then frame._applyTextPositions(settings) end + if frame._applyTopTextTags then + frame._applyTopTextTags(settings.topLeftContent or "none", settings.topRightContent or "none") + end + if frame._applyTopTextPositions then + frame._applyTopTextPositions(settings) + end -- Bottom Text Bar update (focus) ? must come before castbar so castbar can anchor to it local fPpBtbAnchor = (fPpIsAtt and frame.Power) or frame.Health @@ -5302,6 +5800,12 @@ local function ReloadFrames() if isMiniFrame and frame._applyTextPositions then frame._applyTextPositions(settings) end + if isMiniFrame and frame._applyTopTextTags then + frame._applyTopTextTags(settings.topLeftContent or "none", settings.topRightContent or "none") + end + if isMiniFrame and frame._applyTopTextPositions then + frame._applyTopTextPositions(settings) + end if frame.Castbar then local s = isMiniFrame and donorSettings or settings