--- @type StdUi local StdUi = LibStub and LibStub('StdUi', true); if not StdUi then return end local module, version = 'Grid', 4; if not StdUi:UpgradeNeeded(module, version) then return end; --- Creates frame list that reuses frames and is based on array data --- @param parent Frame --- @param create function --- @param update function --- @param data table --- @param padding number --- @param oX number --- @param oY number --- @param limitFn function function StdUi:ObjectList(parent, itemsTable, create, update, data, padding, oX, oY, limitFn) local this = self; oX = oX or 1; oY = oY or -1; padding = padding or 0; if not itemsTable then itemsTable = {}; end for i = 1, #itemsTable do itemsTable[i]:Hide(); end local totalHeight = -oY; local i = 1; for key, value in pairs(data) do local itemFrame = itemsTable[i]; if not itemFrame then if type(create) == 'string' then -- create a widget and anchor it to itemsTable[i] = this[create](this, parent); else itemsTable[i] = create(parent, value, i, key); end itemFrame = itemsTable[i]; end -- If you create simple widget you need to handle anchoring yourself update(parent, itemFrame, value, i, key); itemFrame:Show(); totalHeight = totalHeight + itemFrame:GetHeight(); if i == 1 then -- glue first item to offset this:GlueTop(itemFrame, parent, oX, oY, 'LEFT'); else -- glue next items to previous this:GlueBelow(itemFrame, itemsTable[i - 1], 0, -padding); totalHeight = totalHeight + padding; end if limitFn and limitFn(i, totalHeight, itemFrame:GetHeight()) then break; end i = i + 1; end return itemsTable, totalHeight; end --- Creates frame list that reuses frames and is based on array data --- @param parent Frame --- @param create function --- @param update function --- @param data table --- @param paddingX number --- @param paddingY number --- @param oX number --- @param oY number function StdUi:ObjectGrid(parent, itemsMatrix, create, update, data, paddingX, paddingY, oX, oY) oX = oX or 1; oY = oY or -1; paddingX = paddingX or 0; paddingY = paddingY or 0; if not itemsMatrix then itemsMatrix = {}; end for y = 1, #itemsMatrix do for x = 1, #itemsMatrix[y] do itemsMatrix[y][x]:Hide(); end end for rowI = 1, #data do local row = data[rowI]; for colI = 1, #row do if not itemsMatrix[rowI] then -- whole row does not exist yet itemsMatrix[rowI] = {}; end local itemFrame = itemsMatrix[rowI][colI]; if not itemFrame then if type(create) == 'string' then -- create a widget and set parent it to itemFrame = self[create](self, parent); else itemFrame = create(parent, data[rowI][colI], rowI, colI); end itemsMatrix[rowI][colI] = itemFrame; end -- If you create simple widget you need to handle anchoring yourself update(parent, itemFrame, data[rowI][colI], rowI, colI); itemFrame:Show(); if rowI == 1 and colI == 1 then -- glue first item to offset self:GlueTop(itemFrame, parent, oX, oY, 'LEFT'); else if colI == 1 then -- glue first item in column to previous row self:GlueBelow(itemFrame, itemsMatrix[rowI - 1][colI], 0, -paddingY, 'LEFT'); else -- glue next column to previous column self:GlueRight(itemFrame, itemsMatrix[rowI][colI - 1], paddingX, 0); end end end end end StdUi:RegisterModule(module, version);