mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 15:46:56 +00:00
7efc3334ae
Hook GameTooltip:SetUnitAura to append the caster's name; every pfUI aura tooltip (player buffs, buffwatch, unitframes) routes through it, so one hook covers them all. Resolve the name from the live sourceUnit token, falling back to the sourceGUID name cache (players only) when the token is gone. Gated behind a new tooltip.aurasource option (off by default) with a matching "Show Aura Caster" checkbox. The toggle reloads the UI, so the hook is installed conditionally at load rather than re-checking the flag per tooltip.
284 lines
10 KiB
Lua
284 lines
10 KiB
Lua
pfUI:RegisterModule("tooltip", function ()
|
|
local rawborder, default_border = GetBorderSize()
|
|
|
|
pfUI.tooltip = CreateFrame('Frame', "pfTooltip", GameTooltip)
|
|
pfUI.tooltip.anchorframe = CreateFrame('Frame', "pfTooltipAnchor", UIParent)
|
|
pfUI.tooltip.anchorframe:SetSize(128, 72)
|
|
pfUI.tooltip.anchorframe:SetPoint("TOP", UIParent, "TOP", 0, -50)
|
|
pfUI.tooltip.anchorframe:Hide()
|
|
UpdateMovable(pfUI.tooltip.anchorframe)
|
|
|
|
function pfUI.tooltip:GetAnchorPoint()
|
|
local prefix = "TOP"
|
|
local suffix = "RIGHT"
|
|
local px, py = UIParent:GetCenter()
|
|
local tx, ty = this.anchorframe:GetCenter()
|
|
if (tx < px) then
|
|
suffix = "LEFT"
|
|
end
|
|
if (ty < py) then
|
|
prefix = "BOTTOM"
|
|
end
|
|
return prefix..suffix
|
|
end
|
|
|
|
if C.tooltip.position == "cursor" then
|
|
-- Cursor mode makes the tooltip follow the mouse. The client has no
|
|
-- mouse-move event, so following means polling GetCursorPosition() via an
|
|
-- invisible follower frame that the tooltip anchors to. The follower is
|
|
-- only shown while a tooltip is visible -- an OnUpdate fires only while its
|
|
-- frame is shown, so the poll stops the moment the tooltip hides instead
|
|
-- of running forever.
|
|
local follower, Reposition
|
|
if C.tooltip.cursoralign ~= "native" then
|
|
local size = tonumber(C.tooltip.cursoroffset) * 2
|
|
follower = CreateFrame("Frame", nil, UIParent)
|
|
follower:SetSize(size, size)
|
|
follower:Hide()
|
|
|
|
Reposition = function()
|
|
local scale = UIParent:GetScale()
|
|
local x, y = GetCursorPosition()
|
|
follower:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x/scale, y/scale)
|
|
if C.tooltip.cursoralign == "top" then
|
|
follower:SetWidth(GameTooltip:GetWidth())
|
|
end
|
|
end
|
|
|
|
follower:SetScript("OnUpdate", function()
|
|
-- throttle - cursor following doesn't need to be every frame
|
|
if (this.tick or 0) > GetTime() then return end
|
|
this.tick = GetTime() + (pfUI.throttle and pfUI.throttle:Get("tooltip_cursor") or 0.1)
|
|
Reposition()
|
|
end)
|
|
|
|
-- stop polling as soon as the tooltip is gone
|
|
pfUI.tooltip:SetScript("OnHide", function() follower:Hide() end)
|
|
end
|
|
|
|
function _G.GameTooltip_SetDefaultAnchor(tooltip, parent)
|
|
tooltip:SetOwner(parent, "ANCHOR_CURSOR")
|
|
if not follower then return end
|
|
|
|
-- position the follower right away so the tooltip doesn't flash at a
|
|
-- stale spot before the first OnUpdate tick
|
|
follower:Show()
|
|
Reposition()
|
|
|
|
if C.tooltip.cursoralign == "top" then
|
|
tooltip:SetPoint("BOTTOMLEFT", follower, "TOPLEFT", 0, 0)
|
|
elseif C.tooltip.cursoralign == "left" then
|
|
tooltip:SetPoint("BOTTOMRIGHT", follower, "LEFT", 0, 0)
|
|
elseif C.tooltip.cursoralign == "right" then
|
|
tooltip:SetPoint("BOTTOMLEFT", follower, "RIGHT", 0, 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
function pfUI.tooltip:GetUnit()
|
|
pfUI.tooltip.unit = "none"
|
|
if GameTooltip:HasUnit() then
|
|
local _, guid = GameTooltip:GetUnitGUID()
|
|
local token = guid and UnitTokenFromGUID(guid)
|
|
if token then pfUI.tooltip.unit = token end
|
|
end
|
|
return pfUI.tooltip.unit
|
|
end
|
|
|
|
pfUI.tooltip.dodge = {
|
|
"pfPanelRight", "pfChatRight"
|
|
}
|
|
|
|
if C.appearance.bags.movable == "0" then
|
|
table.insert(pfUI.tooltip.dodge, "pfBag")
|
|
end
|
|
|
|
pfUI.tooltip:SetAllPoints()
|
|
pfUI.tooltip:SetScript("OnShow", function()
|
|
pfUI.tooltip:Update()
|
|
if GameTooltip:GetAnchorType() == "ANCHOR_NONE" then
|
|
GameTooltip:ClearAllPoints()
|
|
if C.tooltip.position == "bottom" then
|
|
if pfUI.panel and pfUI.panel.right:IsShown() then
|
|
GameTooltip:SetPoint("BOTTOMRIGHT", pfUI.panel.right, "TOPRIGHT", 0, default_border*2)
|
|
else
|
|
GameTooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -5, 5)
|
|
end
|
|
elseif C.tooltip.position == "chat" then
|
|
local anchor = nil
|
|
|
|
for _, frame in pairs(pfUI.tooltip.dodge) do
|
|
if _G[frame] and _G[frame]:IsShown() then
|
|
anchor = _G[frame]
|
|
end
|
|
end
|
|
|
|
if anchor then
|
|
GameTooltip:SetPoint("BOTTOMRIGHT", anchor, "TOPRIGHT", 0, default_border*3)
|
|
else
|
|
GameTooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -5, 5)
|
|
end
|
|
elseif C.tooltip.position == "free" then
|
|
local point = this:GetAnchorPoint()
|
|
if point then
|
|
GameTooltip:SetPoint(point, this.anchorframe, point, 0, 0)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
pfUI.tooltipStatusBar = CreateFrame('Frame', nil, GameTooltipStatusBar)
|
|
pfUI.tooltipStatusBar:SetPoint("TOPLEFT", 0, 8)
|
|
pfUI.tooltipStatusBar:SetPoint("TOPRIGHT", 0, 8)
|
|
pfUI.tooltipStatusBar:SetHeight(12)
|
|
pfUI.tooltipStatusBar:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
|
pfUI.tooltipStatusBar:SetScript("OnEvent", function()
|
|
this.name = UnitName("mouseover")
|
|
this.level = UnitLevel("mouseover")
|
|
end)
|
|
|
|
pfUI.tooltipStatusBar.text = CreateFrame("Frame", nil, pfUI.tooltipStatusBar)
|
|
pfUI.tooltipStatusBar.text:SetFrameLevel(16)
|
|
pfUI.tooltipStatusBar.text:SetAllPoints()
|
|
|
|
pfUI.tooltipStatusBar.HP = pfUI.tooltipStatusBar.text:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
|
pfUI.tooltipStatusBar.HP:SetAllPoints()
|
|
pfUI.tooltipStatusBar.HP:SetNonSpaceWrap(false)
|
|
pfUI.tooltipStatusBar.HP:SetFontObject(GameFontWhite)
|
|
pfUI.tooltipStatusBar.HP:SetFont(C.tooltip.font_tooltip, C.tooltip.font_tooltip_size + 2, "OUTLINE")
|
|
|
|
if GameTooltip.SetClampRectInsets then
|
|
GameTooltip:SetClampRectInsets(0, 0, 16, 0)
|
|
else
|
|
GameTooltipStatusBar:SetClampedToScreen(true)
|
|
pfUI.tooltipStatusBar:SetClampedToScreen(true)
|
|
end
|
|
|
|
pfUI.tooltipStatusBar:SetScript("OnUpdate", function()
|
|
local hp = GameTooltipStatusBar:GetValue()
|
|
local _, hpmax = GameTooltipStatusBar:GetMinMaxValues()
|
|
local rhp, rhpmax, estimated
|
|
|
|
if hpmax > 100 or (round(hpmax/100*hp) ~= hp) then
|
|
rhp, rhpmax = hp, hpmax
|
|
elseif pfUI.libhealth and pfUI.libhealth.enabled then
|
|
rhp, rhpmax, estimated = pfUI.libhealth:GetUnitHealthByName(this.name, this.level, tonumber(hp), tonumber(hpmax))
|
|
end
|
|
|
|
if C.tooltip.alwaysperc == "0" and ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
|
pfUI.tooltipStatusBar.HP:SetText(string.format("%s / %s", Abbreviate(rhp), Abbreviate(rhpmax)))
|
|
elseif hpmax > 0 then
|
|
pfUI.tooltipStatusBar.HP:SetText(string.format("%s%%", ceil(hp/hpmax*100)))
|
|
else
|
|
pfUI.tooltipStatusBar.HP:SetText("")
|
|
end
|
|
end)
|
|
|
|
GameTooltipStatusBar:SetHeight(8)
|
|
GameTooltipStatusBar:ClearAllPoints()
|
|
GameTooltipStatusBar:SetPoint("BOTTOMLEFT", GameTooltip, "TOPLEFT", 0, default_border)
|
|
GameTooltipStatusBar:SetPoint("BOTTOMRIGHT", GameTooltip, "TOPRIGHT", 0, default_border)
|
|
GameTooltipStatusBar:SetStatusBarTexture(pfUI.media[C.tooltip.statusbar.texture])
|
|
CreateBackdrop(GameTooltipStatusBar, nil, nil, tonumber(C.tooltip.alpha))
|
|
CreateBackdropShadow(GameTooltipStatusBar)
|
|
|
|
GameTooltipStatusBar.SetStatusBarColor_orig = GameTooltipStatusBar.SetStatusBarColor
|
|
GameTooltipStatusBar.SetStatusBarColor = function() return end
|
|
|
|
function pfUI.tooltip:Update()
|
|
local unit = pfUI.tooltip:GetUnit()
|
|
if unit == "none" then
|
|
-- process item tooltips
|
|
if C.tooltip.itemid == "1" and GameTooltip:HasItem() then
|
|
local _, _, itemID = GameTooltip:GetItem()
|
|
GameTooltip:AddLine(T["ItemID"] .. ": " .. itemID, .25,.5,1)
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
local pvpname = UnitPVPName(unit)
|
|
local name = UnitName(unit)
|
|
local validTarget, target = pcall(UnitName, unit .. 'target')
|
|
local class = UnitClassBase(unit)
|
|
local guild, rankstr, rankid = GetGuildInfo(unit)
|
|
local reaction = UnitReaction(unit, "player")
|
|
local pvptitle = gsub(gsub(pvpname or name, name, "", 1), "^%s*(.-)%s*$", "%1")
|
|
local hp = UnitHealth(unit)
|
|
local hpm = UnitHealthMax(unit)
|
|
|
|
if name then
|
|
if UnitIsPlayer(unit) and class then
|
|
local color = PFUI_CLASS_COLORS[class]
|
|
GameTooltipStatusBar:SetStatusBarColor_orig(color:GetRGB())
|
|
GameTooltip:SetBackdropBorderColor(color:GetRGB())
|
|
GameTooltipTextLeft1:SetText("|c" .. color.colorStr .. name)
|
|
elseif reaction then
|
|
local color = UnitReactionColor[reaction]
|
|
GameTooltipStatusBar:SetStatusBarColor_orig(color.r, color.g, color.b)
|
|
GameTooltip:SetBackdropBorderColor(color.r, color.g, color.b)
|
|
end
|
|
if pvptitle ~= name and pvptitle ~= "" then
|
|
GameTooltip:AppendText(" |cff666666["..pvptitle.."]|r")
|
|
end
|
|
end
|
|
|
|
if guild then
|
|
local rank = ""
|
|
local lead = ""
|
|
if C.tooltip.extguild == "1" then
|
|
if rankstr then rank = " |cffaaaaaa(" .. rankstr .. ")" end
|
|
if rankid and rankid == 0 then lead = "|cffffcc00*|r" end
|
|
end
|
|
|
|
GameTooltip:AddLine("<" .. guild .. ">" .. lead .. rank, 0.3, 1, 0.5)
|
|
end
|
|
|
|
if validTarget and target then
|
|
local targetClass = UnitClassBase(unit .. "target")
|
|
local targetReaction = UnitReaction("player",unit .. "target")
|
|
if UnitIsPlayer(unit .. "target") and targetClass then
|
|
local color = PFUI_CLASS_COLORS[targetClass]
|
|
GameTooltip:AddLine(target, color.r, color.g, color.b)
|
|
elseif targetReaction then
|
|
local color = UnitReactionColor[targetReaction]
|
|
if color then
|
|
GameTooltip:AddLine(target, color.r, color.g, color.b)
|
|
else
|
|
GameTooltip:AddLine(target, .5, .5, .5)
|
|
end
|
|
end
|
|
end
|
|
|
|
if C.tooltip.movespeed == "1" then
|
|
local currentSpeed = GetUnitSpeed(unit)
|
|
if currentSpeed and currentSpeed > 0 then
|
|
local pct = floor(currentSpeed / 7 * 100 + 0.5)
|
|
GameTooltip:AddLine(T["Speed"] .. ": " .. pct .. "%", 0.7, 0.7, 1)
|
|
end
|
|
end
|
|
|
|
if hp and hpm then
|
|
if hp >= 1000 then hp = round(hp / 1000, 1) .. "k" end
|
|
if hpm >= 1000 then hpm = round(hpm / 1000, 1) .. "k" end
|
|
pfUI.tooltipStatusBar.HP:SetText(hp .. " / " .. hpm)
|
|
end
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
if C.tooltip.aurasource == "1" then
|
|
hooksecurefunc(GameTooltip, "SetUnitAura", function(self, ...)
|
|
local aura = C_UnitAuras.GetAuraDataByIndex(unpack(arg))
|
|
if not aura then return end
|
|
local caster = aura.sourceUnit and UnitName(aura.sourceUnit)
|
|
if not caster and aura.sourceGUID then
|
|
caster = UnitNameFromGUID(aura.sourceGUID)
|
|
end
|
|
if not caster or caster == "" then return end
|
|
self:AddLine(T["Cast by"] .. ": " .. caster, .7, .7, 1)
|
|
self:Show()
|
|
end)
|
|
end
|
|
end)
|