diff --git a/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua b/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua index 8657c8a8..b65da95e 100644 --- a/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua +++ b/EllesmereUIUnitFrames/EUI_UnitFrames_Options.lua @@ -2776,6 +2776,11 @@ initFrame:SetScript("OnEvent", function(self) combatIndicatorSize = { player=true }, combatIndicatorX = { player=true }, combatIndicatorY = { player=true }, + leaderIndicatorEnabled = { player=true }, + leaderIndicatorSize = { player=true }, + leaderIndicatorPosition= { player=true }, + leaderIndicatorX = { player=true }, + leaderIndicatorY = { player=true }, buffAnchor = { player=true, target=true, focus=true }, buffGrowth = { player=true, target=true, focus=true }, maxBuffs = { player=true, target=true, focus=true }, @@ -6476,6 +6481,72 @@ initFrame:SetScript("OnEvent", function(self) UpdateRmCogState() end + -- Row 5: Leader Indicator toggle | Icon Size slider + inline directions cog (X/Y) + -- Only visible for player unit + local sharedAddRow5 + local function leaderIndOff() + return SValSupported("leaderIndicatorEnabled", true) == false + end + local function isPlayerUnit() + return selectedUnit == "player" + end + if isPlayerUnit() then + sharedAddRow5, h = W:DualRow(parent, y, + { type="toggle", text="Leader Indicator", + getValue=function() return SValSupported("leaderIndicatorEnabled", true) end, + setValue=function(v) + SSetSupported("leaderIndicatorEnabled", v) + EllesmereUI:RefreshPage() + end }, + { type="slider", text="Icon Size", min=8, max=48, step=1, + disabled=leaderIndOff, disabledTooltip="Leader Indicator", + getValue=function() return SValSupported("leaderIndicatorSize", 16) end, + setValue=function(v) SSetSupported("leaderIndicatorSize", v) end }); y = y - h + SApplySupport(sharedAddRow5._leftRegion, "leaderIndicatorEnabled") + SApplySupport(sharedAddRow5._rightRegion, "leaderIndicatorSize") + do + local rgn = sharedAddRow5._rightRegion + local leaderPosValues = { ["topleft"]="Top Left", ["topright"]="Top Right", ["bottomleft"]="Bottom Left", ["bottomright"]="Bottom Right", ["portrait"]="Portrait" } + local leaderPosOrder = { "topleft", "topright", "bottomleft", "bottomright", "portrait" } + local _, leaderCogShow = EllesmereUI.BuildCogPopup({ + title = "Leader Indicator Settings", + rows = { + { type="dropdown", label="Position", values=leaderPosValues, order=leaderPosOrder, + get=function() return SValSupported("leaderIndicatorPosition", "topleft") end, + set=function(v) SSetSupported("leaderIndicatorPosition", v) end }, + { type="slider", label="X Offset", min=-200, max=200, step=1, + get=function() return SValSupported("leaderIndicatorX", 0) end, + set=function(v) SSetSupported("leaderIndicatorX", v) end }, + { type="slider", label="Y Offset", min=-200, max=200, step=1, + get=function() return SValSupported("leaderIndicatorY", 0) end, + set=function(v) SSetSupported("leaderIndicatorY", v) end }, + }, + }) + local leaderCogBtn = MakeCogBtn(rgn, leaderCogShow) + local function UpdateLeaderCogState() + local off = leaderIndOff() + leaderCogBtn:SetAlpha(off and 0.15 or 0.4) + end + leaderCogBtn:SetScript("OnEnter", function(self) + if leaderIndOff() then + EllesmereUI.ShowWidgetTooltip(self, EllesmereUI.DisabledTooltip("Leader Indicator")) + else + self:SetAlpha(0.7) + end + end) + leaderCogBtn:SetScript("OnLeave", function(self) + EllesmereUI.HideWidgetTooltip() + UpdateLeaderCogState() + end) + leaderCogBtn:SetScript("OnClick", function(self) + if leaderIndOff() then return end + leaderCogShow(self) + end) + EllesmereUI.RegisterWidgetRefresh(UpdateLeaderCogState) + UpdateLeaderCogState() + end + end + ------------------------------------------------------------------- -- Return click mapping targets + total height ------------------------------------------------------------------- @@ -6497,6 +6568,7 @@ initFrame:SetScript("OnEvent", function(self) buffIcon = { section = sharedAddHeader, target = sharedAddRow2, slotSide = "left" }, debuffIcon = { section = sharedAddHeader, target = sharedAddRow3, slotSide = "left" }, raidMarker = { section = sharedAddHeader, target = sharedAddRow4, slotSide = "left" }, + leaderIndicator = { section = sharedAddHeader, target = sharedAddRow5, slotSide = "left" }, castBar = { section = sharedCastHeader, target = sharedCastRow1 }, castIcon = { section = sharedCastHeader, target = sharedCastRow1 }, castName = { section = sharedCastHeader, target = sharedCastRow1 }, diff --git a/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua b/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua index 6b62b5ef..61e12676 100644 --- a/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua +++ b/EllesmereUIUnitFrames/EllesmereUIUnitFrames.lua @@ -168,6 +168,11 @@ local defaults = { raidMarkerAlign = "right", raidMarkerX = 0, raidMarkerY = 0, + leaderIndicatorEnabled = true, + leaderIndicatorSize = 16, + leaderIndicatorPosition = "topleft", + leaderIndicatorX = 0, + leaderIndicatorY = 0, }, target = { frameWidth = 181, @@ -5729,6 +5734,11 @@ local function ReloadFrames() end end + -- Refresh leader indicator on player frame after settings change + if frames.player and frames.player._applyLeaderIndicator then + frames.player._applyLeaderIndicator() + end + --------------------------------------------------------------------------- -- Live-update raid target marker icon (size / alignment / X / Y / enabled) -- for player, target, and focus frames. Uses oUF's EnableElement / @@ -5983,6 +5993,76 @@ function InitializeFrames() end end + -- Leader indicator on player frame (shows crown icon when player is group/raid leader) + do + local pf = frames.player + local ps = db.profile.player + if pf and pf.Health then + -- Create holder frame ONCE + if not pf._leaderHolder then + pf._leaderHolder = CreateFrame("Frame", nil, pf) + pf._leaderHolder:SetAllPoints(pf) + local leaderTex = pf._leaderHolder:CreateTexture(nil, "OVERLAY", nil, 7) + leaderTex:Hide() + pf._leaderIndicator = leaderTex + -- Assign to oUF element so it auto-updates via LeaderIndicator element + pf.LeaderIndicator = leaderTex + end + pf._leaderHolder:SetFrameLevel(pf:GetFrameLevel() + 21) + + -- Helper: apply size, position, and visibility + local function ApplyLeaderIndicator() + local enabled = ps.leaderIndicatorEnabled ~= false + local sz = ps.leaderIndicatorSize or 16 + local pos = ps.leaderIndicatorPosition or "topleft" + local ox = ps.leaderIndicatorX or 0 + local oy = ps.leaderIndicatorY or 0 + + local leader = pf._leaderIndicator + leader:SetSize(sz, sz) + leader:ClearAllPoints() + + -- Anchor based on position setting + local anchorPoint, relPoint + if pos == "topleft" then + anchorPoint, relPoint = "TOPLEFT", "TOPLEFT" + elseif pos == "topright" then + anchorPoint, relPoint = "TOPRIGHT", "TOPRIGHT" + elseif pos == "bottomleft" then + anchorPoint, relPoint = "BOTTOMLEFT", "BOTTOMLEFT" + elseif pos == "bottomright" then + anchorPoint, relPoint = "BOTTOMRIGHT", "BOTTOMRIGHT" + elseif pos == "portrait" and pf.Portrait and pf.Portrait.backdrop then + leader:SetPoint("CENTER", pf.Portrait.backdrop, "CENTER", ox, oy) + if enabled then + pf:EnableElement("LeaderIndicator") + pf.LeaderIndicator:ForceUpdate() + else + pf:DisableElement("LeaderIndicator") + leader:Hide() + end + return + else + anchorPoint, relPoint = "TOPLEFT", "TOPLEFT" + end + + leader:SetPoint(anchorPoint, pf.Health or pf, relPoint, ox, oy) + + if enabled then + pf:EnableElement("LeaderIndicator") + pf.LeaderIndicator:ForceUpdate() + else + pf:DisableElement("LeaderIndicator") + leader:Hide() + end + end + pf._applyLeaderIndicator = ApplyLeaderIndicator + + -- Initial application + ApplyLeaderIndicator() + end + end + -- Castbar state is managed by ApplyBlizzCastbarState (called here and also -- from ReloadFrames so toggling the setting works without a /reload). ApplyBlizzCastbarState()