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.

260 lines
7.8 KiB

local WIT, core = ...
local AceGUI = LibStub("AceGUI-3.0")
function core.UI.Grid(options)
options = options or {}
local self = AceGUI:Create("SimpleGroup")
local minWidth = options.MinWidth
self.Columns = options.Columns or {}
self.IsExpandabled = options.IsExpandabled ~= nil and options.IsExpandabled or true
self.DetailsRowHeaderResource = options.DetailsRowHeaderResource or "Loot"
self.Sort = options.Sort or { Column = nil, Direction = nil }
self.SearchTerm = options.SearchTerm
local function onColumnClicked(column)
if not column.IsSortable() then return end
if self.Sort.Column == column then
self.Sort.Direction = self.Sort.Direction ~= "ASC" and "ASC" or "DESC"
else
self.Sort = {
Column = column,
Direction = "ASC",
}
end
self.Reload()
end
local function sortRows(rows)
if not self.Sort.Column then return rows end
table.sort(rows, function(a, b)
local valA = self.Sort.Column.GetSortValue(a)
local valB = self.Sort.Column.GetSortValue(b)
local idA = a.Data.Id or 0
local idB = b.Data.Id or 0
if self.Sort.Direction == "ASC" then
return valA == valB and idA < idB or valA < valB
else
return valA == valB and idA > idB or valA > valB
end
end)
return rows
end
local function matchFilter(row, columns)
for _, column in pairs(columns) do
if column.GetFilterValue and strfind(column.GetFilterValue(row), self.SearchTerm) then
return true
end
end
end
local function filterRows(rows)
if not self.SearchTerm or self.SearchTerm == "" then return rows end
local visibleColumns = self.GetVisibleColumns(rows)
local results = {}
for _, row in pairs(rows) do
if matchFilter(row, visibleColumns) then
table.insert(results, row)
end
end
return results
end
function self.GetData()
return self.Data
end
function self.GetDetailsRowData(row)
return row.Data.Results
end
function self.GetRows()
if not self.Rows then
self.Rows = {}
local data = self.GetData()
for _, data in pairs(data) do
local row = { Data = data }
for _, column in pairs(self.Columns) do
row[column.Name] = column.Value(data)
end
table.insert(self.Rows, row)
end
end
return sortRows(filterRows(self.Rows))
end
local function DrawDetailsRow(row, isAlternateRow)
local data = self.GetDetailsRowData(row)
if not data or #(data) == 0 then return end
local group = AceGUI:Create("SimpleGroup")
group:SetFullWidth(true)
if isAlternateRow == true then
group.background = group.frame:CreateTexture(nil, "BACKGROUND")
group.background:SetPoint("TOPLEFT", group.frame, "TOPLEFT", 0, -2)
group.background:SetPoint("BOTTOMRIGHT", group.frame, "BOTTOMRIGHT", 0, -2)
group.background:SetColorTexture(0.5, 0.5, 0.5, 0.3)
group:SetCallback("OnRelease", function(self)
self.background:Hide()
end)
end
local header = AceGUI:Create("Label")
header:SetFullWidth(true)
header:SetText(" " .. core.GetString(self.DetailsRowHeaderResource))
group:AddChild(header)
for _, item in pairs(data) do
if item.Quantity and type(item.Quantity) == "string" then item.Quantity = tonumber(item.Quantity) end
local itemLabel = core.UI.ItemLinkLabel(item, { Prefix = " ", Suffix = (item.Quantity or 1) > 1 and (" x" .. (item.Quantity or 1)) or "" })
group:AddChild(itemLabel)
end
self:AddChild(group)
end
local function Draw()
local rows = self.GetRows()
local visibleColumns = self.GetVisibleColumns(rows)
local columnWidth = {}
local columnCount = 0
local totalWidth = 0
local fixedWidth = 0
local isFullWidth = false
local header = AceGUI:Create("SimpleGroup")
header:SetLayout("Flow")
header:SetFullWidth(true)
header.background = header.frame:CreateTexture(nil, "BACKGROUND")
header.background:SetPoint("TOPLEFT", header.frame, "TOPLEFT", 0, -2)
header.background:SetPoint("BOTTOMRIGHT", header.frame, "BOTTOMRIGHT", 0, -1)
header.background:SetColorTexture(0.5, 0.5, 0.5, 0.3)
header:SetCallback("OnRelease", function(self)
self.background:Hide()
end)
for key, column in pairs(visibleColumns) do
columnWidth[key] = column.GetColumnMinWidth(rows) + 5
totalWidth = totalWidth + columnWidth[key]
if not column.IsFixedSize then
columnCount = columnCount + 1
end
end
if minWidth then
minWidth = math.floor(minWidth)
local diff = minWidth - 45 - totalWidth
isFullWidth = diff > 0
self:SetFullWidth(false)
if diff > 0 then
local additionalWidth = math.floor(diff / columnCount)
for key, width in pairs(columnWidth) do
if not visibleColumns[key].IsFixedSize then
columnWidth[key] = width + additionalWidth
end
end
self:SetFullWidth(true)
else
self:SetWidth(totalWidth + 45)
end
else
self:SetFullWidth(true)
end
for key, column in pairs(visibleColumns) do
local headerCell = column.GetHeaderCell(onColumnClicked)
headerCell:SetWidth(columnWidth[key])
header:AddChild(headerCell)
end
self:AddChild(header)
local isAlternateRow = false
for _, row in pairs(rows) do
local group = AceGUI:Create("SimpleGroup")
group:SetLayout("Flow")
group:SetFullWidth(true)
if isAlternateRow == true then
group.background = group.frame:CreateTexture(nil, "BACKGROUND")
group.background:SetPoint("TOPLEFT", group.frame, "TOPLEFT", 0, -2)
group.background:SetPoint("BOTTOMRIGHT", group.frame, "BOTTOMRIGHT", 0, -2)
group.background:SetColorTexture(0.5, 0.5, 0.5, 0.3)
group:SetCallback("OnRelease", function(self)
self.background:Hide()
end)
end
for key, column in pairs(visibleColumns) do
local cell = column.GetCell(row, self)
cell:SetWidth(columnWidth[key])
group:AddChild(cell)
end
self:AddChild(group)
if row.Expanded then
DrawDetailsRow(row, isAlternateRow)
end
isAlternateRow = not isAlternateRow
end
end
function self.Show(data)
self.Data = data
self.ClearCache()
self.Reload()
end
function self.Reload()
self:ReleaseChildren()
Draw()
self:Fire("OnReload")
end
function self.Search(term)
self.SearchTerm = strlower(term)
self.Reload()
end
function self.ClearCache()
self.Rows = nil
end
function self.GetVisibleColumns(rows)
local visibleColumns = {}
for _, column in pairs(self.Columns) do
if column.IsVisible(self, rows) then
table.insert(visibleColumns, column)
end
end
return visibleColumns
end
return self
end