You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
9.2 KiB

local _,rematch = ...
local L = rematch.localization
local C = rematch.constants
local settings = rematch.settings
rematch.badges = {}
--[[
Badges are small non-interactive icons placed to the right of list buttons to show if
the pet is leveling, in a team, etc; or a team has a target, has preferences, etc;
or any purpose.
There are four lists:
"pets" : pets in the pet list, queue or loadouts
"teams" : teams in the team list
"targets" : targets in the target list (id is npcID)
"groups" : team group headers
To register a badge (within this addon and outside it), use:
Rematch.badges:RegisterBadge(list,name,icon,coords,callback)
list (string) is one of the above four lists (can be anything but Rematch only adds badges for these)
name (string) is a unique-per-list identifier for the badge
icon (string,number,function) is the icon of the badge; if a function it should return a string/number icon
coords (table,function) is the texcoords of the badge; if a function it should return texcoords
callback (function) is a function that returns true if the given id's list/name badge should be shown
]]
-- indexed by list ("pets", "teams", "targets"), an ordered list of badge info for the list
local badges = {}
rematch.events:Register(rematch.badges,"PLAYER_LOGIN",function(self)
--[[ pets: badges for pet lists (queue too) ]]
-- leveling: whether pet is leveling
self:RegisterBadge("pets","leveling","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.375,0.5,0.125,0.25},
function(self,petID) -- callback
return not self.forQueue and (not settings.HideLevelingBadges or rematch.petHerder:GetActionID()=="leveling") and rematch.petInfo:Fetch(petID).isLeveling
end
)
-- team: whether pet is in a team
self:RegisterBadge("pets","team","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.5,0.625,0.125,0.25},
function(self,petID) -- callback
return not settings.HideTeamBadges and rematch.petInfo.inTeams
end
)
-- marker: pet tag for the pet
self:RegisterBadge("pets","marker","Interface\\AddOns\\Rematch\\textures\\badges-borderless",
function(self,petID) -- coords
local marker = rematch.petInfo:Fetch(petID).marker
if marker and marker>=1 and marker<=8 then
return (marker-1)*0.125,marker*0.125,0.25,0.375
end
end,
function(self,petID) -- callback
local actionID = rematch.petHerder:GetActionID()
return (not settings.HideMarkerBadges or (actionID and actionID:match("marker"))) and rematch.petInfo:Fetch(petID).marker
end
)
-- new: whether pet is new/wrapped (sorted to top of list)
self:RegisterBadge("pets","new","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.625,0.75,0.75,0.875},
function(self,petID) -- callback
return rematch.petInfo:Fetch(petID).isStickied
end
)
-- cage: whether pet can be caged (only shown while pet harder up with "cage" actionID)
self:RegisterBadge("pets","cage","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.875,1,0.75,0.875},
function(self,petID) -- callback
if rematch.petHerder:GetActionID()=="cage" then
local petInfo = rematch.petInfo:Fetch(petID)
return petInfo.isTradable and not petInfo.isInjured and not petInfo.isSlotted and (not petInfo.inTeams or rematch.dialog.Canvas.CheckButton:GetChecked())
end
end
)
--[[ groups: badges for groups (team headers) ]]
-- preferences: whether group has any preferences
self:RegisterBadge("groups","preferences","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.75,0.875,0.125,0.25},
function(self,groupID)
if not settings.HidePreferenceBadges then
local group = groupID and rematch.savedGroups[groupID]
return group and group.preferences
end
end
)
--[[ teams: badges for teams ]]
-- preferences: whether team has any targets
self:RegisterBadge("teams","targets","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.375,0.5,0.375,0.5},
function(self,teamID)
if not settings.HideTargetBadges then
local team = teamID and rematch.savedTeams[teamID]
return team and team.targets
end
end
)
-- preferences: whether team has any preferences
self:RegisterBadge("teams","preferences","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.75,0.875,0.125,0.25},
function(self,teamID)
if not settings.HidePreferenceBadges then
local team = teamID and rematch.savedTeams[teamID]
return team and team.preferences
end
end
)
--[[ targets: badges for targets (npcIDs; not using actual targetID) ]]
-- teams: whether target has any teams
self:RegisterBadge("targets","teams","Interface\\AddOns\\Rematch\\textures\\badges-borderless",{0.5,0.625,0.125,0.25},
function(self,npcID)
return not settings.HideTeamBadges and rematch.savedTargets[npcID]
end
)
end)
-- list: generally "pets", "teams" or "targets", used by AddBadges to determine badge set (required)
-- name,icon,coords,callback get added to badges in the order they're registered
function rematch.badges:RegisterBadge(list,name,icon,coords,callback)
assert(type(list)=="string" and list:len()>0,"Invalid list name: "..(list or "nil"))
assert(type(name)=="string" and name:len()>0,"Invalid badge name: "..(name or "nil"))
assert(type(callback)=="function","Invalid callback function for "..name.." badge")
-- if this list hasn't been started, start one
if not badges[list] then
badges[list] = {}
end
-- if badge already exists, remove it
rematch.badges:UnregisterBadge(list,name,true)
-- add badge to registered badges
tinsert(badges[list],{
name = name,
icon = icon or C.UNKNOWN_ICON,
coords = coords,
callback = callback
})
end
-- removes a registered badge (noUpdate=true to not update the UI)
function rematch.badges:UnregisterBadge(list,name,noUpdate)
for i=#badges[list],1,-1 do
if badges[list][i].name==name then
tremove(badges[list],i)
end
end
if not noUpdate and rematch.frame:IsVisible() then
rematch.frame:Update()
end
end
--[[ the following are called by the list updates and should never need to be called outside of one ]]
-- array: parentArray of textures attached to a button (button.Badges)
-- list: generally "pets", "teams" or "targets"; the set of badges registered
-- id: the petID, teamID, groupID, targetID or headerID to add badges for (passed to callbacks)
-- anchorPoint: anchor point of the first badge
-- relativeTo: the frame/region the first badge is anchored to
-- relativePoint: anchor point from the frame/region the first badge is anchored to
-- xoff: x offset for first badge
-- yoff: y offset for first badge
-- xdir: -1 to place badges right to left; 1 to place badges left to right
-- returns: width of the badges
function rematch.badges:AddBadges(array,list,id,anchorPoint,relativeTo,relativePoint,xoff,yoff,xdir)
-- first clear all badges
rematch.badges:ClearBadges(array)
-- go through each registered badge for the list and show it
local arrayIndex = 1
local parent = array[1]:GetParent()
local width = 0
for _,info in ipairs(badges[list]) do
-- this badge should show if callback returns true
if info.callback(parent,id) then
if not array[arrayIndex] then
array[arrayIndex] = parent:CreateTexture(nil,"ARTWORK")
array[arrayIndex]:SetSize(C.BADGE_SIZE,C.BADGE_SIZE)
end
local badge = array[arrayIndex]
badge:SetTexture(type(info.icon)=="function" and info.icon(parent,id) or info.icon)
local x1,x2,y1,y2
if type(info.coords)=="function" then
x1,x2,y1,y2 = info.coords(parent,id)
elseif type(info.coords)=="table" then
x1,x2,y1,y2 = info.coords[1],info.coords[2],info.coords[3],info.coords[4]
end
if x1 and x2 and y1 and y2 then
badge:SetTexCoord(x1,x2,y1,y2)
else
badge:SetTexCoord(0,1,0,1)
end
badge:ClearAllPoints()
badge:SetPoint(anchorPoint,relativeTo,relativePoint,xoff,yoff)
badge:Show()
width = width + C.BADGE_SIZE + 1
xoff = xoff + (C.BADGE_SIZE + 1)*xdir -- adjust x position of next badge (xdir -1 will go left, 1 right)
arrayIndex = arrayIndex + 1
end
end
-- badges all placed, return width of badges
return width
end
-- clears badges in the given parentArray
function rematch.badges:ClearBadges(array)
for _,badge in ipairs(array) do
badge:Hide()
end
end