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.

218 lines
6.3 KiB

--[[
AutoSizeGridView.lua
@Author : DengSir (tdaddon@163.com)
@Link : https://dengsir.github.io
]]
local MAJOR, MINOR = 'AutoSizeGridView', 3
local GUI = LibStub('tdGUI-1.0')
local AutoSizeGridView = GUI:NewClass(MAJOR, MINOR, 'Frame', 'Refresh', 'View', 'Select', 'Owner', 'Backdrop')
if not AutoSizeGridView then return end
function AutoSizeGridView:Constructor()
self._buttons = {}
self._layouts = {}
local scrollBar = CreateFrame('Slider', nil, self, 'UIPanelScrollBarTemplate') do
self.scrollBar = scrollBar
self.scrollUp = scrollBar.ScrollUpButton
self.scrollDown = scrollBar.ScrollDownButton
scrollBar.thumbTexture = scrollBar.ThumbTexture
scrollBar:SetValueStep(1)
scrollBar:SetStepsPerPage(1)
scrollBar:SetPoint('TOPRIGHT', 0, -18)
scrollBar:SetPoint('BOTTOMRIGHT', 0, 18)
scrollBar:SetScript('OnValueChanged', function(scrollBar, value)
HybridScrollFrame_UpdateButtonStates(self, value)
self:SetOffset(value)
end)
scrollBar:SetScript('OnMinMaxChanged', function(scrollBar, minValue, maxValue)
scrollBar:SetShown(minValue ~= maxValue)
end)
scrollBar:SetScript('OnShow', function(scrollBar)
self:Refresh()
end)
scrollBar:SetScript('OnHide', function(scrollBar)
self:Refresh()
end)
end
self:SetSelectMode('NONE')
self:EnableMouseWheel(true)
self:SetScript('OnShow', self.Refresh)
self:SetScript('OnMouseWheel', self.OnMouseWheel)
end
function AutoSizeGridView:GetColumnLayout(column)
if not self._layouts[column] then
self._layouts[column] = CreateFrame('Frame', nil, self)
end
return self._layouts[column]
end
function AutoSizeGridView:SetOffset(value)
local offset = math.floor(value + 0.5)
if self._offset ~= offset then
self._offset = offset
self:Refresh()
end
end
function AutoSizeGridView:GetOffset()
return self._offset or 1
end
function AutoSizeGridView:OnMouseWheel(delta)
self.scrollBar:SetValue(self.scrollBar:GetValue() - self.scrollBar:GetValueStep() * delta)
end
function AutoSizeGridView:Update()
self:UpdateScrollBar()
self:UpdateItems()
end
function AutoSizeGridView:GetMaxCount()
return self:GetRowCount() * self:GetColumnCount()
end
function AutoSizeGridView:UpdateScrollBar()
local maxCount = self:GetMaxCount()
local itemCount = self:GetItemCount()
local maxValue = itemCount <= maxCount and 1 or itemCount - maxCount + 1
self.scrollBar:SetMinMaxValues(1, maxValue)
self.scrollBar:SetValue(self:GetOffset())
end
function AutoSizeGridView:UpdateItems()
local offset = self:GetOffset()
local maxCount = min(self:GetColumnCount() * self:GetRowCount(), self:GetItemCount())
local columnCount = self:GetColumnCount()
local rowCount = self:GetRowCount()
local left, right, top, bottom = self:GetPadding()
local spacingV, spacingH = self:GetItemSpacing()
local itemHeight = self:GetItemHeight()
local columnWidths = {}
offset = ceil((offset - 1) / columnCount) * columnCount + 1
for i = 1, columnCount do
self:GetColumnLayout(i)
end
for i, layout in ipairs(self._layouts) do
if i > columnCount then
layout:Hide()
else
layout:ClearAllPoints()
layout:SetSize(1, 1)
layout:Show()
if i == 1 then
layout:SetPoint('TOPLEFT', left, -top)
else
layout:SetPoint('TOPLEFT', self:GetColumnLayout(i-1), 'TOPRIGHT', spacingH, 0)
end
end
end
for i = 1, maxCount do
local button = self:GetButton(i)
local index = offset + i - 1
local column = (index - 1) % columnCount + 1
if self:GetItem(index) then
button:SetID(index)
button:SetChecked(self:IsSelected(index))
button:Show()
button:FireFormat()
local layout = self:GetColumnLayout(column)
local autoWidth = button:GetAutoWidth()
if layout:GetWidth() < autoWidth then
layout:SetWidth(autoWidth)
columnWidths[column] = autoWidth
end
local row = floor((i-1)/columnCount)
local col = (i-1)%columnCount
local y = -row*(itemHeight+spacingV)
button:SetParent(layout)
button:ClearAllPoints()
button:SetPoint('TOPLEFT', layout, 'TOPLEFT', 0, y)
button:SetPoint('TOPRIGHT', layout, 'TOPRIGHT', 0, y)
button:SetHeight(itemHeight)
else
button:Hide()
end
end
for i = maxCount + 1, #self._buttons do
self:GetButton(i):Hide()
end
local width = 0 do
for i = 1, columnCount do
width = width + (columnWidths[i] or 0)
end
width = width + left + right + (columnCount - 1) * spacingH
end
self:SetSize(width, top+bottom+rowCount*(itemHeight+spacingV)-spacingV)
end
function AutoSizeGridView:UpdateItemPosition(i)
end
function AutoSizeGridView:SetColumnCount(columnCount)
self._columnCount = columnCount
self:SetScrollStep(columnCount)
end
function AutoSizeGridView:GetColumnCount()
return self._columnCount or 1
end
function AutoSizeGridView:SetRowCount(rowCount)
self._rowCount = rowCount
end
function AutoSizeGridView:GetRowCount()
if not self._rowCount then
local itemCount = self:GetItemCount()
local columnCount = self:GetColumnCount()
if columnCount == 0 then
return 0
end
return math.ceil(itemCount / columnCount)
end
return self._rowCount
end
function AutoSizeGridView:SetItemSpacing(itemSpacingV, itemSpacingH)
self.itemSpacingV, self.itemSpacingH = itemSpacingV, itemSpacingH
end
function AutoSizeGridView:GetItemSpacing()
return self.itemSpacingV or 0,
self.itemSpacingH or self.itemSpacingV or 0
end
function AutoSizeGridView:GetScrollBarFixedWidth()
return self.scrollBar:IsShown() and self.scrollBar:GetWidth() or 0
end
function AutoSizeGridView:SetScrollStep(scrollStep)
self.scrollBar.scrollStep = scrollStep
self.scrollBar:SetValueStep(scrollStep)
-- self.scrollBar:SetStepsPerPage(scrollStep)
end
function AutoSizeGridView:GetScrollStep()
return self.scrollBar.scrollStep
end