diff --git a/EllesmereUIRaidFrames/EUI_RaidFrames_AuraContainers.lua b/EllesmereUIRaidFrames/EUI_RaidFrames_AuraContainers.lua index 986f2ba98..8e590f992 100644 --- a/EllesmereUIRaidFrames/EUI_RaidFrames_AuraContainers.lua +++ b/EllesmereUIRaidFrames/EUI_RaidFrames_AuraContainers.lua @@ -1224,9 +1224,42 @@ local function ApplyBmIconGlow(button, dd, style) end end --- applyExtra for icon slots: shared text pass + opacity + BM frame levels. --- hideIcon = legacy text-only mode (icon/swipe/border hidden via style flags; --- duration text and stacks unaffected). +local function ApplyBmPandemicBorder(button, dd, style) + -- Register once during creation, including when disabled. The engine owns + -- visibility; settings only recolor the child textures on subsequent restyles. + if not dd.bmPandemic and not dd.bmRegistered and button.AddPandemicRegion then + local holder = CreateFrame("Frame", nil, button) + holder:SetAllPoints(button) + holder:EnableMouse(false) + holder:Hide() + dd.bmPandemic = holder + dd.bmPandemicEdges = {} + for i = 1, 4 do + dd.bmPandemicEdges[i] = holder:CreateTexture(nil, "OVERLAY") + end + local top, bottom, left, right = unpack(dd.bmPandemicEdges) + top:SetPoint("TOPLEFT"); top:SetPoint("TOPRIGHT") + bottom:SetPoint("BOTTOMLEFT"); bottom:SetPoint("BOTTOMRIGHT") + left:SetPoint("TOPLEFT"); left:SetPoint("BOTTOMLEFT") + right:SetPoint("TOPRIGHT"); right:SetPoint("BOTTOMRIGHT") + end + local holder = dd.bmPandemic + if not holder then return end + holder:SetFrameLevel(dd.stackCarrier:GetFrameLevel() - 1) + local width = style.bmPandemicWidth or 2 + local r, g, b = BmColor(style.bmPandemicColor, 1, 0.2, 0.2) + local alpha = style.bmPandemicEnabled and not style.hideIcon and 1 or 0 + for i, edge in ipairs(dd.bmPandemicEdges) do + if i <= 2 then edge:SetHeight(width) else edge:SetWidth(width) end + edge:SetColorTexture(r, g, b, alpha) + end + if not dd.bmPandemicBound then + button:AddPandemicRegion(holder) + dd.bmPandemicBound = true + end +end + +-- Icon text, opacity and frame levels also apply to text-only indicators. local function ApplyBmIconExtra(button, dd, style) ApplyRFDebuffText(button, dd, style) -- "Hide Icons" gate: like the hidden swipe (see AuraKit's style pass), a @@ -1277,6 +1310,7 @@ local function ApplyBmIconExtra(button, dd, style) if dd.stackCarrier then dd.stackCarrier:SetFrameLevel(base + BM_FRAMELVL_TEXT) end BmRebindDurationCurve(button, dd, style) ApplyBmIconGlow(button, dd, style) + ApplyBmPandemicBorder(button, dd, style) end -- Buff/HoT tooltip gate (profile-root "Hide Buff Tooltips", default hidden). Engine @@ -1331,6 +1365,9 @@ local function BuildBmIconStyle(ind, iscale, size) bmGlowR = ind.displayGlowR, bmGlowG = ind.displayGlowG, bmGlowB = ind.displayGlowB, + bmPandemicEnabled = ind.pandemicBorderEnabled == true, + bmPandemicColor = ind.pandemicBorderColor, + bmPandemicWidth = ind.pandemicBorderWidth or 2, applyExtra = ApplyBmIconExtra, } end @@ -1993,6 +2030,7 @@ local function BmVisualKey(kind, ind, size, font, spellID) if kind == "icon" then return FP(font, size, (ns.db and ns.db.profile and ns.db.profile.bmIconZoom) or 0.08, ind.iconOpacity, ind.hideIcon, ind.indBorderSize, CK(ind.indBorderColor), + ind.pandemicBorderEnabled, CK(ind.pandemicBorderColor), ind.pandemicBorderWidth, ind.showDuration, ind.showDurationText, ind.durationTextSize, CK(ind.durationTextColor), ind.durationTextOffsetX, ind.durationTextOffsetY, ind.thresholdEnabled, ind.threshold, CK(ind.thresholdColor), ind.showStacks, ind.stacksTextSize, CK(ind.stacksTextColor), diff --git a/EllesmereUIRaidFrames/EUI_RaidFrames_BuffManager.lua b/EllesmereUIRaidFrames/EUI_RaidFrames_BuffManager.lua index fa8e0e459..5862ec0fc 100644 --- a/EllesmereUIRaidFrames/EUI_RaidFrames_BuffManager.lua +++ b/EllesmereUIRaidFrames/EUI_RaidFrames_BuffManager.lua @@ -1620,8 +1620,13 @@ function ns.BM_ApplyPreviewIndicators(f, index, s) end if fr._bdr and PP then local ibs = pvHideIcon and 0 or (ind.indBorderSize or 1) + local pandemicPreview = indType == "icon" and isSelected + and ind.pandemicBorderEnabled and not pvHideIcon + if pandemicPreview then ibs = ind.pandemicBorderWidth or 2 end if ibs > 0 then - local ibc = ind.indBorderColor or { r=0, g=0, b=0 } + local ibc = pandemicPreview + and (ind.pandemicBorderColor or { r=1, g=0.2, b=0.2 }) + or ind.indBorderColor or { r=0, g=0, b=0 } PP.UpdateBorder(fr._bdr, ibs, ibc.r, ibc.g, ibc.b, 1) fr._bdr:Show() else @@ -4913,7 +4918,48 @@ function ns.BM_BuildPage(pageName, parent, yOffset) UpdateDispGlowState() end - -- THRESHOLD section (Enable, seconds, color, opacity) + if indType == "icon" then + _, h = W:SectionHeader(leftFrame, "PANDEMIC BORDER", sy); sy = sy - h + local pandemicOff = function() return not ind.pandemicBorderEnabled end + local pandemicRow = SettingsRow( + { type="toggle", text="Enable Pandemic Border", + tooltip="Highlights this indicator's icons during Blizzard's refresh window. Requires pandemic-region support from the game. The selected indicator previews the active border. Use a Lifebloom-only indicator to highlight only Lifebloom.", + getValue=function() return ind.pandemicBorderEnabled or false end, + setValue=function(v) ind.pandemicBorderEnabled = v; ReloadAndUpdate(); EllesmereUI:RefreshPage() end }, + { type="slider", text="Border Size", min=1, max=5, step=1, + disabled=pandemicOff, disabledTooltip="Enable Pandemic Border", + getValue=function() return ind.pandemicBorderWidth or 2 end, + setValue=function(v) ind.pandemicBorderWidth = v; ReloadAndUpdate() end }) + local rgn = pandemicRow._leftRegion + local swatch, updateSwatch = EllesmereUI.BuildColorSwatch( + rgn, pandemicRow:GetFrameLevel() + 3, + function() + local c = ind.pandemicBorderColor or { r=1, g=0.2, b=0.2 } + return c.r, c.g, c.b + end, + function(r, g, b) + ind.pandemicBorderColor = { r=r, g=g, b=b } + ReloadAndUpdate() + end, false, 20) + swatch:SetPoint("RIGHT", rgn._control, "LEFT", -8, 0) + local origClick = swatch:GetScript("OnClick") + swatch:SetScript("OnClick", function(self, ...) + if pandemicOff() then return end + if origClick then origClick(self, ...) end + end) + swatch:SetScript("OnEnter", function() + EllesmereUI.ShowWidgetTooltip(swatch, pandemicOff() + and EllesmereUI.DisabledTooltip("Enable Pandemic Border") or "Pandemic Border Color") + end) + swatch:SetScript("OnLeave", function() EllesmereUI.HideWidgetTooltip() end) + local function UpdatePandemicSwatch() + updateSwatch(); swatch:SetAlpha(pandemicOff() and 0.3 or 1) + end + EllesmereUI.RegisterWidgetRefresh(UpdatePandemicSwatch) + UpdatePandemicSwatch() + end + + -- Threshold text remains independent of the pandemic border. BuildThresholdRow() elseif typeInfo and typeInfo.placed then