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.

146 lines
3.4 KiB

local _, addon = ...
local ButtonPoolMixin = {}
function ButtonPoolMixin.Reposition(pool)
if pool.parent:GetParent():GetWidth() == 0 then
-- until the frame is visible the width is 0
C_Timer.After(0.5, function()
pool:Reposition()
end)
return
end
local cols = math.floor((pool.parent:GetParent():GetWidth() - pool.offset) / (pool.buttonWidth + pool.buttonSpacing))
local index = 1
for _, button in pool:EnumerateActiveSorted() do
local col = (index - 1) % cols
local row = math.floor((index - 1) / cols)
local x = (pool.offset / 4) + (col * (pool.buttonWidth + pool.buttonSpacing))
local y = (pool.offset / 4) + (row * (pool.buttonHeight + pool.buttonSpacing))
button:ClearAllPoints()
button:SetPoint('TOPLEFT', x, -y)
index = index + 1
end
-- update the width of the parent so the buttons can be displayed properly
pool.parent:SetWidth(pool.parent:GetParent():GetWidth())
end
function ButtonPoolMixin:SetSortField(field)
self.sortField = field
end
do
local objects = {}
function ButtonPoolMixin:EnumerateActiveSorted()
table.wipe(objects)
for obj in self:EnumerateActive() do
table.insert(objects, obj)
end
local sortField = self.sortField
table.sort(objects, function(a, b)
return tostring(a[sortField]):lower() < tostring(b[sortField]):lower()
end)
return pairs(objects)
end
end
function ButtonPoolMixin:HasButtonBySortField(qualifier)
if self.sortField then
for button in self:EnumerateActive() do
if button[self.sortField] == qualifier then
return true
end
end
end
end
local function ReleaseButton(pool, button)
FramePool_HideAndClearAnchors(pool, button) -- super
-- reposition remaining buttons
pool:Reposition()
end
local function OnButtonEnter(self)
self.remove:Show()
if self.OnEnter then
self:OnEnter()
end
end
local function OnButtonLeave(self)
if not (self:IsMouseOver() or self.remove:IsMouseOver()) then
self.remove:Hide()
end
if self.OnLeave then
self:OnLeave()
end
end
local function OnRemoveLeave(self)
if not (self:IsMouseOver() or self:GetParent():IsMouseOver()) then
self:Hide()
end
end
local function OnRemoveClick(self)
local button = self:GetParent()
if button.OnRemove then
button:OnRemove()
end
button.pool:Release(button)
end
function ButtonPoolMixin.CreateButton(pool)
local button = pool:Acquire()
if not button.pool then
button.pool = pool
local remove = CreateFrame('Button', nil, button, 'UIPanelCloseButton')
remove:SetPoint('TOPRIGHT', 6, 8)
remove:SetSize(20, 22)
button.remove = remove
button:SetSize(pool.buttonWidth, pool.buttonHeight)
button:SetScript('OnEnter', OnButtonEnter)
button:SetScript('OnLeave', OnButtonLeave)
remove:SetScript('OnLeave', OnRemoveLeave)
remove:SetScript('OnClick', OnRemoveClick)
end
button:Show()
button.remove:Hide()
-- TODO: remove other metadata we attach
button.OnEnter = nil
button.OnLeave = nil
return button
end
function addon:CreateButtonPool(parent, offset, buttonWidth, buttonHeight, buttonSpacing)
local pool = CreateFramePool('Button', parent, 'BackdropTemplate', ReleaseButton)
pool:ReleaseAll()
pool.parent = parent
pool.offset = offset
pool.buttonWidth = buttonWidth
pool.buttonHeight = buttonHeight
pool.buttonSpacing = buttonSpacing
Mixin(pool, ButtonPoolMixin)
return pool
end