Files
coa-weakauras/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua
T
Bunny67 f2e1a0928d init
2020-06-02 23:40:06 +03:00

222 lines
6.4 KiB
Lua

local MAJOR_VERSION = "LibGetFrame-1.0"
local MINOR_VERSION = 9
if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
local lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
if not lib then return end
lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
local callbacks = lib.callbacks
local GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, C_Timer, UnitIsUnit, SecureButton_GetUnit = GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, C_Timer, UnitIsUnit, SecureButton_GetUnit
local tinsert, CopyTable, wipe = tinsert, CopyTable, wipe
local maxDepth = 50
local defaultFramePriorities = {
-- raid frames
[1] = "^Vd1", -- vuhdo
[2] = "^Vd2", -- vuhdo
[3] = "^Vd3", -- vuhdo
[4] = "^Vd4", -- vuhdo
[5] = "^Vd5", -- vuhdo
[6] = "^Vd", -- vuhdo
[7] = "^HealBot", -- healbot
[8] = "^GridLayout", -- grid
[9] = "^Grid2Layout", -- grid2
[10] = "^ElvUF_RaidGroup", -- elv
[11] = "^oUF_bdGrid", -- bdgrid
[12] = "^oUF.*raid", -- generic oUF
[13] = "^LimeGroup", -- lime
[14] = "^SUFHeaderraid", -- suf
[15] = "^CompactRaid", -- blizz
-- party frames
[16] = "^AleaUI_GroupHeader", -- Alea
[17] = "^SUFHeaderparty", --suf
[18] = "^ElvUF_PartyGroup", -- elv
[19] = "^oUF.*party", -- generic oUF
[20] = "^PitBull4_Groups_Party", -- pitbull4
[21] = "^CompactParty", -- blizz
-- player frame
[22] = "^SUFUnitplayer",
[23] = "^PitBull4_Frames_Player",
[24] = "^ElvUF_Player",
[25] = "^oUF.*player",
[26] = "^PlayerFrame",
}
local defaultPlayerFrames = {
"SUFUnitplayer",
"PitBull4_Frames_Player",
"ElvUF_Player",
"oUF_TukuiPlayer",
"PlayerFrame",
}
local defaultTargetFrames = {
"SUFUnittarget",
"PitBull4_Frames_Target",
"ElvUF_Target",
"TargetFrame",
"oUF_TukuiTarget",
}
local defaultTargettargetFrames = {
"SUFUnittargetarget",
"PitBull4_Frames_Target's target",
"ElvUF_TargetTarget",
"TargetTargetFrame",
"oUF_TukuiTargetTarget",
}
local GetFramesCache = {}
local function ScanFrames(depth, frame, ...)
if not frame then return end
if depth < maxDepth
and frame.IsForbidden
and not frame:IsForbidden()
then
local frameType = frame:GetObjectType()
if frameType == "Frame" or frameType == "Button" then
ScanFrames(depth + 1, frame:GetChildren())
end
if frameType == "Button" then
local unit = SecureButton_GetUnit(frame)
local name = frame:GetName()
if unit and frame:IsVisible() and name then
GetFramesCache[frame] = name
end
end
end
ScanFrames(depth, ...)
end
local wait = false
local function ScanForUnitFrames(noDelay)
if noDelay then
wipe(GetFramesCache)
ScanFrames(0, UIParent)
callbacks:Fire("GETFRAME_REFRESH")
elseif not wait then
wait = true
C_Timer:After(1, function()
wipe(GetFramesCache)
ScanFrames(0, UIParent)
wait = false
callbacks:Fire("GETFRAME_REFRESH")
end)
end
end
local function isFrameFiltered(name, ignoredFrames)
for _, filter in pairs(ignoredFrames) do
if name:find(filter) then
return true
end
end
return false
end
local function GetUnitFrames(target, ignoredFrames)
if not UnitExists(target) then
if type(target) == "string" and target:find("Player") then
target = select(6, GetPlayerInfoByGUID(target))
else
target = target:gsub(" .*", "")
if not UnitExists(target) then
return
end
end
end
local frames
for frame, frameName in pairs(GetFramesCache) do
local unit = SecureButton_GetUnit(frame)
if unit and UnitIsUnit(unit, target)
and not isFrameFiltered(frameName, ignoredFrames)
then
frames = frames or {}
frames[frame] = frameName
end
end
return frames
end
local function ElvuiWorkaround(frame)
if IsAddOnLoaded("ElvUI") and frame and frame:GetName():find("^ElvUF_") and frame.Health then
return frame.Health
else
return frame
end
end
local defaultOptions = {
framePriorities = defaultFramePriorities,
ignorePlayerFrame = true,
ignoreTargetFrame = true,
ignoreTargettargetFrame = true,
playerFrames = defaultPlayerFrames,
targetFrames = defaultTargetFrames,
targettargetFrames = defaultTargettargetFrames,
ignoreFrames = {
"PitBull4_Frames_Target's target's target"
},
returnAll = false,
}
local GetFramesCacheListener
local function Init(noDelay)
GetFramesCacheListener = CreateFrame("Frame")
GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_DISABLED")
GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_ENABLED")
GetFramesCacheListener:RegisterEvent("PLAYER_ENTERING_WORLD")
GetFramesCacheListener:RegisterEvent("PARTY_MEMBERS_CHANGED")
GetFramesCacheListener:RegisterEvent("RAID_ROSTER_UPDATE")
GetFramesCacheListener:SetScript("OnEvent", function() ScanForUnitFrames(false) end)
ScanForUnitFrames(noDelay)
end
function lib.GetUnitFrame(target, opt)
if type(GetFramesCacheListener) ~= "table" then Init(true) end
opt = opt or {}
setmetatable(opt, { __index = defaultOptions })
if not target then return end
local ignoredFrames = CopyTable(opt.ignoreFrames)
if opt.ignorePlayerFrame then
for _,v in pairs(opt.playerFrames) do
tinsert(ignoredFrames, v)
end
end
if opt.ignoreTargetFrame then
for _,v in pairs(opt.targetFrames) do
tinsert(ignoredFrames, v)
end
end
if opt.ignoreTargettargetFrame then
for _,v in pairs(opt.targettargetFrames) do
tinsert(ignoredFrames, v)
end
end
local frames = GetUnitFrames(target, ignoredFrames)
if not frames then return end
if not opt.returnAll then
for i = 1, #opt.framePriorities do
for frame, frameName in pairs(frames) do
if frameName:find(opt.framePriorities[i]) then
return ElvuiWorkaround(frame)
end
end
end
local next = next
return ElvuiWorkaround(next(frames))
else
for frame in pairs(frames) do
frames[frame] = ElvuiWorkaround(frame)
end
return frames
end
end
lib.GetFrame = lib.GetUnitFrame -- compatibility