Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* Moved **Pixel-Perfect Scaling** to **General → Settings**, since it applies globally to both party and raid. (by Krathe)
* (Aura Designer) New icon and square indicators now default their **border inset to 0**, flush with the icon edge, matching the other indicator types. (by Krathe)
* (Auto Layouts) Saved layouts are tidied of leftover built-in text overrides after the Text Designer migration, so the override list no longer lists dead entries. (by Krathe)
* (Nicknames) **Northern Sky Raid Tools compatibility** — when NSRT is also set to put nicknames on DandersFrames frames, a one-time prompt lets you choose which addon decides the names shown on your frames (changeable later under **General → Nicknames → Name precedence**), so the two no longer silently fight. (by Maelareth)

### Bug Fixes

Expand Down
164 changes: 164 additions & 0 deletions Features/Nicknames.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,166 @@ end
-- INIT (called from Core.lua after PLAYER_LOGIN)
-- ============================================================

-- ============================================================
-- NSRT PRECEDENCE / CONFLICT PROMPT
-- Northern Sky Raid Tools can also be set to put nicknames on DandersFrames
-- frames; when its "DandersFrames" toggle is on it OVERWRITES DF:GetUnitName,
-- so the two would fight. We detect that, prompt the user once which should
-- win, and store the choice (framePrecedence) which DF:GetFrameName honours.
-- Entirely DF-side: we never modify NSRT, only READ its toggle.
-- The same choice can be changed later in the Nicknames options page.
-- ============================================================

-- True if NSRT is loaded AND configured to manage names on DandersFrames frames.
function NK:NSRTManagingNames()
return (C_AddOns and C_AddOns.IsAddOnLoaded and C_AddOns.IsAddOnLoaded("NorthernSkyRaidTools"))
and NSRT and NSRT.Settings
and NSRT.Settings["GlobalNickNames"]
and NSRT.Settings["DandersFrames"]
and true or false
end

-- Should DandersFrames' own nicknames win on our frames? Yes — unless the user
-- explicitly chose NSRT AND NSRT is actually managing names right now.
function NK:HasPrecedence()
local data = NK:GetDB()
if data and data.framePrecedence == "nsrt" and NK:NSRTManagingNames() then
return false
end
return true
end

-- The name to display on our own frames, honouring precedence. When DF wins we
-- resolve our own nickname first; when the user has chosen NSRT we ask NSRT's
-- own resolver DIRECTLY (NSAPI:GetName) so its name shows, bypassing our hook
-- (which would otherwise keep returning the DF nickname).
function NK:GetDisplayName(unit)
if NK:HasPrecedence() then
local nick = NK:Resolve(unit)
if nick then return nick end
return DF:GetUnitName(unit)
end
local raw = UnitName(unit)
if NSAPI and NSAPI.GetName and raw then
return NSAPI:GetName(raw, "DandersFrames") or raw
end
return raw or unit
end

-- Build + show the one-time conflict popup (DandersFrames' own alert style).
function NK:ShowConflictPopup()
if NK._conflictPopup then NK._conflictPopup:Show(); return end

local L = DF.L
local theme = (DF.GUI and DF.GUI.GetThemeColor and DF.GUI.GetThemeColor())
or { r = 0.9, g = 0.55, b = 0.15 }

local popup = CreateFrame("Frame", "DFNicknameConflictPopup", UIParent, "BackdropTemplate")
popup:SetSize(490, 250)
popup:SetPoint("CENTER")
popup:SetFrameStrata("FULLSCREEN_DIALOG")
popup:SetFrameLevel(200)
popup:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Buttons\\WHITE8x8", edgeSize = 2 })
popup:SetBackdropColor(0.1, 0.1, 0.1, 0.98)
popup:SetBackdropBorderColor(theme.r, theme.g, theme.b, 1)
popup:EnableMouse(true)
popup:SetMovable(true)
popup:RegisterForDrag("LeftButton")
popup:SetScript("OnDragStart", popup.StartMoving)
popup:SetScript("OnDragStop", popup.StopMovingOrSizing)
tinsert(UISpecialFrames, "DFNicknameConflictPopup") -- Esc closes (re-prompts next login)

local title = popup:CreateFontString(nil, "OVERLAY", "DFFontNormalLarge")
title:SetPoint("TOP", 0, -16)
title:SetText(L["Addon nicknames conflict"])
title:SetTextColor(1, 0.3, 0.3)

local warnTex = "Interface\\AddOns\\DandersFrames\\Media\\Icons\\warning"
local lw = popup:CreateTexture(nil, "OVERLAY"); lw:SetSize(18, 18)
lw:SetPoint("RIGHT", title, "LEFT", -8, 0); lw:SetTexture(warnTex); lw:SetVertexColor(1, 0.3, 0.3)
local rw = popup:CreateTexture(nil, "OVERLAY"); rw:SetSize(18, 18)
rw:SetPoint("LEFT", title, "RIGHT", 8, 0); rw:SetTexture(warnTex); rw:SetVertexColor(1, 0.3, 0.3)

local msg = popup:CreateFontString(nil, "OVERLAY", "DFFontHighlight")
msg:SetPoint("TOP", title, "BOTTOM", 0, -16)
msg:SetPoint("LEFT", 28, 0); msg:SetPoint("RIGHT", -28, 0); msg:SetJustifyH("CENTER")
msg:SetText(L["Both %s and %s are set to show nicknames on your frames.\n\nWhich one should decide the names shown here?"]
:format("|cffe68c26DandersFrames|r", "|cff6fb1e0Northern Sky Raid Tools|r"))

local sub = popup:CreateFontString(nil, "OVERLAY", "DFFontHighlightSmall")
sub:SetPoint("TOP", msg, "BOTTOM", 0, -12)
sub:SetPoint("LEFT", 28, 0); sub:SetPoint("RIGHT", -28, 0); sub:SetJustifyH("CENTER")
sub:SetText(L["This only changes who controls names on DandersFrames frames - you can change it later in Nicknames settings."])
sub:SetTextColor(0.7, 0.7, 0.7)

local function choose(pref)
local d = NK:GetDB(); if d then d.framePrecedence = pref end
popup:Hide()
NK:RefreshAllFrames()
end

local function makeButton(text, primary, onClick)
local b = CreateFrame("Button", nil, popup, "BackdropTemplate")
b:SetSize(225, 42)
b:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Buttons\\WHITE8x8", edgeSize = 1 })
if primary then
b:SetBackdropColor(theme.r * 0.3, theme.g * 0.3, theme.b * 0.3, 1)
b:SetBackdropBorderColor(theme.r, theme.g, theme.b, 1)
else
b:SetBackdropColor(0.15, 0.15, 0.15, 1)
b:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
end
local t = b:CreateFontString(nil, "OVERLAY", "DFFontHighlightSmall")
t:SetPoint("LEFT", 6, 0); t:SetPoint("RIGHT", -6, 0); t:SetJustifyH("CENTER")
t:SetWordWrap(true); t:SetText(text); t:SetTextColor(1, 1, 1)
b:SetScript("OnEnter", function(self) self:SetBackdropBorderColor(theme.r, theme.g, theme.b, 1) end)
b:SetScript("OnLeave", function(self)
if primary then self:SetBackdropBorderColor(theme.r, theme.g, theme.b, 1)
else self:SetBackdropBorderColor(0.4, 0.4, 0.4, 1) end
end)
b:SetScript("OnClick", onClick)
return b
end

local dfBtn = makeButton(L["Use %s nicknames"]:format("DandersFrames"), true, function() choose("self") end)
dfBtn:SetPoint("BOTTOM", -118, 16)
local nsBtn = makeButton(L["Use %s nicknames"]:format("Northern Sky Raid Tools"), false, function() choose("nsrt") end)
nsBtn:SetPoint("BOTTOM", 118, 16)

NK._conflictPopup = popup
popup:Show()
end

-- Prompt once if there's an unresolved DF/NSRT name conflict. Defers out of combat.
function NK:CheckConflictPrompt()
local data = NK:GetDB()
if not data or not data.enabled then return end
if data.framePrecedence ~= nil then return end -- already decided
-- Only prompt users who actually USE DF nicknames (enabled defaults true,
-- so without this every NSRT user would get the popup with nothing to
-- choose between). Once they add a first nickname, the conflict is real
-- and the popup appears at next login (framePrecedence is still nil).
local hasAny = (data.entries and #data.entries > 0)
or (NK.received and next(NK.received) ~= nil)
or (data.selfNick and data.selfNick ~= "")
if not hasAny then return end
if not NK:NSRTManagingNames() then return end -- no conflict
if InCombatLockdown and InCombatLockdown() then
if not NK._conflictCombatWatch then
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_REGEN_ENABLED")
f:SetScript("OnEvent", function(self)
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
NK._conflictCombatWatch = nil
NK:CheckConflictPrompt()
end)
NK._conflictCombatWatch = f
end
return
end
NK:ShowConflictPopup()
end

function NK:Init()
if self.initialized then return end
self.initialized = true
Expand All @@ -1059,4 +1219,8 @@ function NK:Init()

-- Make sure any names already on screen pick up existing rules.
NK:RefreshAllFrames()

-- If NSRT is also set to manage our frame names, prompt once which wins.
-- Delayed so NSRT's saved vars / settings are loaded first.
if C_Timer then C_Timer.After(3, function() NK:CheckConflictPrompt() end) end
end
2 changes: 1 addition & 1 deletion Frames/Bars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2119,7 +2119,7 @@ function DF:UpdateName(frame)

-- Use raid DB for raid frames, party DB for party frames
local db = DF:GetFrameDB(frame)
local name = DF:GetUnitName(frame.unit)
local name = DF:GetFrameName(frame.unit)

-- Truncate name if needed (UTF-8 aware)
if name then
Expand Down
14 changes: 14 additions & 0 deletions Frames/Core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,20 @@ function DF:GetUnitName(unit)
return UnitName(unit) or unit
end

-- Display name used by our own frame rendering. DandersFrames' native nicknames
-- resolve FIRST here, so they stay authoritative on our frames even when another
-- nickname addon (e.g. NSRT) overwrites DF:GetUnitName. NK:HasPrecedence() gates
-- this: it returns false only when the user has explicitly chosen to let the
-- other addon win, in which case we fall through to DF:GetUnitName (which that
-- addon may own) and finally the raw name.
function DF:GetFrameName(unit)
local NK = DF.Nicknames
if NK and NK.GetDisplayName then
return NK:GetDisplayName(unit)
end
return DF:GetUnitName(unit)
end

-- Iterator for all compact unit frames (player, party, raid)
-- Accepts a callback function OR returns an iterator if no callback provided
-- Usage with callback: DF:IterateCompactFrames(function(frame) ... end)
Expand Down
4 changes: 2 additions & 2 deletions Frames/Update.lua
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ function DF:UpdateUnitFrame(frame, source)
if hideLegacyText then
frame.nameText:Hide()
else
local name = DF:GetUnitName(unit) or unit
local name = DF:GetFrameName(unit) or unit
-- Truncate name if needed (UTF-8 aware)
local nameLength = db.nameTextLength or 0
if nameLength > 0 and DF:UTF8Len(name) > nameLength then
Expand Down Expand Up @@ -598,7 +598,7 @@ function DF:UpdateUnitFrame(frame, source)
if hideLegacyText then
frame.nameText:Hide()
else
local name = DF:GetUnitName(unit) or unit
local name = DF:GetFrameName(unit) or unit
-- Truncate name if needed (UTF-8 aware)
local nameLength = db.nameTextLength or 0
if nameLength > 0 and DF:UTF8Len(name) > nameLength then
Expand Down
7 changes: 7 additions & 0 deletions Locales/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,7 @@ L["Add a nickname"] = true
L["Add from"] = true
L["Add from:"] = true
L["Added"] = true
L["Addon nicknames conflict"] = true
L["All nicknames"] = true
L["Angle <name>"] = true
L["Apply to"] = true
Expand All @@ -1895,6 +1896,7 @@ L["Blocked: contained formatting codes"] = true
L["Blocked: contains a filtered word"] = true
L["Blocked: empty"] = true
L["Blocked: too long"] = true
L["Both %s and %s are set to show nicknames on your frames.\n\nWhich one should decide the names shown here?"] = true
L["Brackets [name]"] = true
L["Character / text"] = true
L["Contains"] = true
Expand All @@ -1911,6 +1913,8 @@ L["Mark nicknames"] = true
L["Marker style"] = true
L["Match"] = true
L["My added"] = true
L["Name precedence"] = true
L["Names on frames decided by"] = true
L["Needs re-link"] = true
L["Nickname"] = true
L["Nicknames"] = true
Expand All @@ -1919,6 +1923,7 @@ L["No characters found."] = true
L["No group members found."] = true
L["No nickname rules yet. Add one above."] = true
L["No nicknames received yet."] = true
L["Northern Sky Raid Tools can also show nicknames on DandersFrames frames. Choose which one decides the names shown here."] = true
L["Overlapping rule"] = true
L["Overlaps with rule(s) %s. For names they share, the rule higher in the list wins."] = true
L["Overridden"] = true
Expand All @@ -1937,6 +1942,8 @@ L["Source"] = true
L["Starts with"] = true
L["Starts with: matches any character whose name begins with this text."] = true
L["This Battle.net friend could not be matched after an update. Remove this rule and add them again."] = true
L["This only changes who controls names on DandersFrames frames - you can change it later in Nicknames settings."] = true
L["Use %s nicknames"] = true
L["You are not in a guild."] = true
L["Your nickname (broadcast)"] = true

Expand Down
30 changes: 30 additions & 0 deletions Options/NicknamesPage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,36 @@ function DF.BuildNicknamesPage(guiRef, pageRef, dbRef)
recvContent:SetHeight(mmax(1, n * ROW_HEIGHT))
end

-- ===== Name precedence (only shown when NSRT can also manage our names) =====
-- Northern Sky Raid Tools can also be set to put nicknames on DandersFrames
-- frames; when both are active they fight. This mirrors the one-time conflict
-- popup (Features/Nicknames.lua) so the choice can be changed here later.
if C_AddOns and C_AddOns.IsAddOnLoaded and C_AddOns.IsAddOnLoaded("NorthernSkyRaidTools") then
local precHeader = parent:CreateFontString(nil, "OVERLAY", "DFFontNormal")
precHeader:SetPoint("TOPLEFT", recvBg, "BOTTOMLEFT", 0, -18)
precHeader:SetText(L["Name precedence"])
do local pc = themeColor(); precHeader:SetTextColor(pc.r, pc.g, pc.b) end

local precDesc = parent:CreateFontString(nil, "OVERLAY", "DFFontDisableSmall")
precDesc:SetPoint("TOPLEFT", precHeader, "BOTTOMLEFT", 0, -6)
precDesc:SetWidth(LIST_WIDTH)
precDesc:SetJustifyH("LEFT")
precDesc:SetText(L["Northern Sky Raid Tools can also show nicknames on DandersFrames frames. Choose which one decides the names shown here."])

local precOpts = {
self = "DandersFrames", nsrt = "Northern Sky Raid Tools",
_order = { "self", "nsrt" },
}
local precDD = GUI:CreateDropdown(parent, L["Names on frames decided by"], precOpts, nil, nil, nil,
function() local d = NK:GetDB(); return (d and d.framePrecedence == "nsrt") and "nsrt" or "self" end,
function(v)
local d = NK:GetDB(); if d then d.framePrecedence = v end
NK:RefreshAllFrames()
end)
precDD:SetSize(220, 50)
precDD:SetPoint("TOPLEFT", precDesc, "BOTTOMLEFT", -4, -8)
end

-- Keep this panel in sync with changes made anywhere (e.g. incoming shares).
NK.onChange = Refresh
Refresh()
Expand Down
2 changes: 1 addition & 1 deletion TextDesigner/DataSource.lua
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ LiveSource.__index = LiveSource
function LiveSource:_isMock() return false end

function LiveSource:GetName()
if DF.GetUnitName then return DF:GetUnitName(self.unit) end
if DF.GetFrameName then return DF:GetFrameName(self.unit) end
return UnitName(self.unit) or ""
end

Expand Down