Files
pfUI/modules/focus.lua
T
Brues 6f5c225ec3 Drive unit frame visibility from events
Every unit frame re-checked its visibility five times a second. Now
group, target and pet events re-check it in OnEvent, which also runs
while a frame is hidden, and the focus module already re-checks focus
and focustarget on PLAYER_FOCUS_CHANGED.

Only the frames with a tick keep the 0.2 second poll. They show another
unit's target or a pet that can go out of sight, and no event reports
either. The focus target frame now gets the same tick as targettarget,
because no event reports the focus changing its target.

Unlock mode and /pftest have no event, so they re-check every frame
when they change. RegisterUnitWatch does not fit here. It polls on the
same 0.2 second timer, and it only shows a unit that exists, without
the pet range, raid grid and group hiding rules.
2026-10-31 02:04:20 -05:00

97 lines
3.2 KiB
Lua

pfUI:RegisterModule("focus", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
pfUI.uf.focus = pfUI.uf:CreateUnitFrame("Focus", nil, C.unitframes.focus)
pfUI.uf.focus:UpdateFrameSize()
pfUI.uf.focus:SetPoint("BOTTOMLEFT", UIParent, "BOTTOM", 220, 220)
UpdateMovable(pfUI.uf.focus)
pfUI.uf.focus:Hide()
pfUI.uf.focustarget = pfUI.uf:CreateUnitFrame("FocusTarget", nil, C.unitframes.focustarget, .2)
pfUI.uf.focustarget:UpdateFrameSize()
pfUI.uf.focustarget:SetPoint("BOTTOMLEFT", pfUI.uf.focus, "TOP", 0, 10)
UpdateMovable(pfUI.uf.focustarget)
pfUI.uf.focustarget:Hide()
-- PLAYER_FOCUS_CHANGED drives immediate refresh on focus assign / clear.
-- Between events, ClassicAPI fires UNIT_* (health/mana/aura/...) with
-- arg1 == "focus" and arg1 == "focustarget", so the bars update
-- event-driven like target. No event reports the focus changing its
-- target, so focustarget ticks like targettarget.
pfUI.events:RegisterFrameEventAndCallback("PLAYER_FOCUS_CHANGED", function()
pfUI.uf.focus.instantRefresh = true
pfUI.uf:RefreshUnit(pfUI.uf.focus, "all")
pfUI.uf.focustarget.instantRefresh = true
pfUI.uf:RefreshUnit(pfUI.uf.focustarget, "all")
end)
end)
-- /focus and /clearfocus live in ClassicAPI's SlashCommandsRegistry now.
-- `/focus Name` takes the nearest prefix match; /focusname tries the exact
-- name first, so "Bob" still wins over a nearer "Bobby".
pfUI.api.RegisterSlashCommand("PFFOCUSNAME", { '/focusname', '/pffocusname' }, function(msg)
if msg == "" then return end
local unit = UnitTokenFromName(msg, true) or UnitTokenFromName(msg)
if unit then
FocusUnit(unit)
end
end, true)
pfUI.api.RegisterSlashCommand("PFCASTFOCUS", { '/castfocus', '/pfcastfocus' }, function(msg)
local focusGUID = UnitGUID("focus")
if not focusGUID or focusGUID == "0x0000000000000000" then
UIErrorsFrame:AddMessage(SPELL_FAILED_BAD_TARGETS, 1, 0, 0)
return
end
local func = pfUI.api.TryMemoizedFuncLoadstringForSpellCasts(msg)
-- GUID-based cast (Nampower) - no target toggle needed
if not func then
CastSpellByName(msg, focusGUID)
return
end
-- Lua-function cast: short target swap via GUID
local prevGUID = UnitGUID("target")
local prevPlayer = UnitIsUnit("target", "player")
TargetUnit(focusGUID)
if UnitGUID("target") ~= focusGUID then
if prevGUID and prevGUID ~= "0x0000000000000000" then
TargetUnit(prevGUID)
elseif prevPlayer then
TargetUnit("player")
else
TargetLastTarget()
end
UIErrorsFrame:AddMessage(SPELL_FAILED_BAD_TARGETS, 1, 0, 0)
return
end
func()
if prevGUID and prevGUID ~= "0x0000000000000000" then
TargetUnit(prevGUID)
elseif prevPlayer then
TargetUnit("player")
else
TargetLastTarget()
end
end, true)
pfUI.api.RegisterSlashCommand("PFSWAPFOCUS", { '/swapfocus', '/pfswapfocus' }, function(msg)
local targetGUID = UnitGUID("target")
local oldFocusGUID = UnitGUID("focus")
if targetGUID and targetGUID ~= "0x0000000000000000" then
FocusUnit("target")
if oldFocusGUID and oldFocusGUID ~= "0x0000000000000000" then
TargetUnit(oldFocusGUID)
end
end
end, true)