Fix bindings not working on raid frames (#5)
This commit fixes an issue where using bindings on raid frames were not working at all. The root cause of the issue was that raid frames were not included, nor updated to the internal table of supported frames. Since raid frames, specifically the compact raid frames, are dynamic and added to the UI on-demand, active raid frames must be re-collected again every time there's a change in the group's or raid's roster (incl. pets). To implement this, I created a handler that collects active raid frames and maintains the addon's internal `self.ccframes` table by always keeping the default frames while refreshing the active raid frames and pruning the staled ones. The created handler reacts to messages returned by the following events: * `PLAYER_ENTERING_WORLD` * `RAID_ROSTER_UPDATE` * `PARTY_MEMBERS_CHANGED` * `UNIT_PET` * `CVAR_UPDATE`
This commit is contained in:
+125
-6
@@ -1,7 +1,9 @@
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Clique by Cladhaire <cladhaire@gmail.com>
|
||||
----------------------------------------------------------------------------------]] Clique = {
|
||||
Locals = {}
|
||||
----------------------------------------------------------------------------------]]
|
||||
|
||||
Clique = {
|
||||
Locals = {},
|
||||
}
|
||||
|
||||
assert(DongleStub, string.format("Clique requires DongleStub."))
|
||||
@@ -32,6 +34,26 @@ function Clique:Enable()
|
||||
char = {
|
||||
switchSpec = false,
|
||||
downClick = false
|
||||
},
|
||||
frames = {
|
||||
PlayerFrame,
|
||||
PetFrame,
|
||||
PartyMemberFrame1,
|
||||
PartyMemberFrame2,
|
||||
PartyMemberFrame3,
|
||||
PartyMemberFrame4,
|
||||
PartyMemberFrame1PetFrame,
|
||||
PartyMemberFrame2PetFrame,
|
||||
PartyMemberFrame3PetFrame,
|
||||
PartyMemberFrame4PetFrame,
|
||||
TargetFrame,
|
||||
TargetFrameToT,
|
||||
FocusFrame,
|
||||
FocusFrameToT,
|
||||
Boss1TargetFrame,
|
||||
Boss2TargetFrame,
|
||||
Boss3TargetFrame,
|
||||
Boss4TargetFrame,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +95,12 @@ function Clique:Enable()
|
||||
self:RegisterEvent("ASCENSION_CA_SPECIALIZATION_ACTIVE_ID_CHANGED")
|
||||
self:RegisterEvent("ADDON_LOADED")
|
||||
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
self:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
self:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
self:RegisterEvent("UNIT_PET")
|
||||
self:RegisterEvent("CVAR_UPDATE")
|
||||
|
||||
-- Change to correct profile based on talent spec
|
||||
if self.db.char.switchSpec then
|
||||
self.silentProfile = true
|
||||
@@ -129,10 +157,7 @@ function Clique:Enable()
|
||||
end
|
||||
|
||||
function Clique:EnableFrames()
|
||||
local tbl = {PlayerFrame, PetFrame, PartyMemberFrame1, PartyMemberFrame2, PartyMemberFrame3, PartyMemberFrame4,
|
||||
PartyMemberFrame1PetFrame, PartyMemberFrame2PetFrame, PartyMemberFrame3PetFrame,
|
||||
PartyMemberFrame4PetFrame, TargetFrame, TargetFrameToT, FocusFrame, FocusFrameToT, Boss1TargetFrame,
|
||||
Boss2TargetFrame, Boss3TargetFrame, Boss4TargetFrame}
|
||||
local tbl = self.defaults.frames
|
||||
|
||||
for i, frame in pairs(tbl) do
|
||||
rawset(self.ccframes, frame, true)
|
||||
@@ -766,3 +791,97 @@ function Clique:ADDON_LOADED(event, addon)
|
||||
self:EnableArenaFrames()
|
||||
end
|
||||
end
|
||||
|
||||
-- Check whether the user is in a raid group or has raid-style party frames (CompactRaidFrames) enabled
|
||||
function Clique:IsInRaidOrHasRaidFramesEnabled()
|
||||
return IsInRaid() or GetCVarBool("useCompactPartyFrames")
|
||||
end
|
||||
|
||||
-- Remove stale frames from `self.ccframes` that are no longer valid.
|
||||
--
|
||||
-- Ensures we only store the default frames and currently active raid frames.
|
||||
function Clique:CleanStaleCCFrames(frames)
|
||||
local validFrames = {}
|
||||
|
||||
-- add default frames
|
||||
for _, f in ipairs(self.defaults.frames) do
|
||||
validFrames[f] = true
|
||||
end
|
||||
|
||||
-- add provided frames (e.g. dynamic raid frames)
|
||||
for _, f in ipairs(frames) do
|
||||
validFrames[f] = true
|
||||
end
|
||||
|
||||
-- prune stale frames that are no longer valid
|
||||
for f in pairs(self.ccframes) do
|
||||
if not validFrames[f] then
|
||||
self.ccframes[f] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Enumerate and return currently active raid frames
|
||||
--
|
||||
-- NOTE: CompactRaidFrames, or rather all raid frames in general – for either a
|
||||
-- player or their pets – should be defined in the following format:
|
||||
-- CompactRaidFrame{index} e.g. CompactRaidFrame1.
|
||||
function Clique:GetActiveRaidFrames()
|
||||
local frames = {}
|
||||
|
||||
local frame = EnumerateFrames()
|
||||
while frame do
|
||||
local name = frame:GetName()
|
||||
-- include only raid frames starting with `CompactRaidFrame` and ending with
|
||||
-- a digit while having a valid unit value (ensures the frame belongs to a
|
||||
-- player)
|
||||
if name and name:find("^CompactRaidFrame%d+$") and frame.unit then
|
||||
table.insert(frames, frame)
|
||||
end
|
||||
|
||||
frame = EnumerateFrames(frame)
|
||||
end
|
||||
|
||||
return frames
|
||||
end
|
||||
|
||||
-- Collect currently active raid frames, prune stale ones and re-register valid
|
||||
-- ones
|
||||
function Clique:EnableRaidFrames()
|
||||
local raidFrames = self:GetActiveRaidFrames()
|
||||
self:CleanStaleCCFrames(raidFrames)
|
||||
for _, f in ipairs(raidFrames) do
|
||||
self:RegisterFrame(f)
|
||||
end
|
||||
end
|
||||
|
||||
-- Shared event handler for syncing dynamic raid/party frame changes
|
||||
--
|
||||
-- NOTE: CompactRaidFrames, or rather all raid frames in general, are dynamic and are added to the
|
||||
-- UIParent's "frame tree" on-demand, which requires hooking into multiple
|
||||
-- different events that gets fired when the party or raid group roster changes.
|
||||
-- Pets or CVar -related events need special handling and thus are separated.
|
||||
local function HandleRaidFrameSync(self, event, unit)
|
||||
if not self:IsInRaidOrHasRaidFramesEnabled() then return end
|
||||
|
||||
if event == "UNIT_PET" then
|
||||
-- only refresh if the pet belongs to player/party/raid
|
||||
if unit == "player" or unit:match("^party%d+$") or unit:match("^raid%d+$") then
|
||||
self:EnableRaidFrames()
|
||||
end
|
||||
elseif event == "CVAR_UPDATE" then
|
||||
-- sync raid frames when toggling the interface option on/off
|
||||
if unit == "USE_RAID_STYLE_PARTY_FRAMES" then
|
||||
self:EnableRaidFrames()
|
||||
end
|
||||
else
|
||||
self:EnableRaidFrames()
|
||||
end
|
||||
end
|
||||
|
||||
-- Bind handler to events
|
||||
Clique.PLAYER_ENTERING_WORLD = HandleRaidFrameSync
|
||||
Clique.RAID_ROSTER_UPDATE = HandleRaidFrameSync
|
||||
Clique.PARTY_MEMBERS_CHANGED = HandleRaidFrameSync
|
||||
Clique.UNIT_PET = HandleRaidFrameSync
|
||||
Clique.CVAR_UPDATE = HandleRaidFrameSync
|
||||
|
||||
Reference in New Issue
Block a user