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
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
|
|
|