Implement page scrolling (seperate into runScrollableGrid)

This commit is contained in:
Max
2026-06-01 05:12:24 +02:00
parent 8a5e4a0fb1
commit d381ac1693
+110 -94
View File
@@ -434,55 +434,9 @@ local function drawItem(img, cellX, cellY, count, offsetY)
end end
end end
local function drawPage(base_id) local function runScrollableGrid(options)
local pageItems = getPageItems(base_id) local entries = {}
local defaultIcon = getFallbackIcon() local counts = {}
local backIcon = getBackButton()
local backWidth, backHeight = imageSize(backIcon)
local backX = SCREEN_WIDTH - backWidth + 1
local pageItemIds = {}
local visibleItemCount = math.min(#pageItems, 9)
for i = 1, visibleItemCount do
pageItemIds[i] = pageItems[i].id
end
local function renderPage()
local itemCounts = getMeItemCounts(pageItemIds)
frame.buffer:clear()
drawNfpScaled(frame.buffer, backIcon, (backX - 1) * 2 + 1, 1)
for i = 1, visibleItemCount do
local item = pageItems[i]
local icon = getItemIcon(item) or defaultIcon
drawItem(icon, 4+(8+4)*((i-1)%3), 2+(5+1)*math.floor((i-1)/3), itemCounts[item.id] or 0)
end
assertBufferValid(frame)
frame:drawBuffer()
end
renderPage()
local refreshTimer = os.startTimer(5)
while true do
local event, p1, x, y = os.pullEvent()
if event == "timer" and p1 == refreshTimer then
renderPage()
refreshTimer = os.startTimer(5)
elseif event == "monitor_touch" and p1 == monName and x >= backX and x < backX + backWidth and y >= 1 and y <= backHeight then
drawOverview()
return
end
end
end
drawOverview = function()
local items = getBaseItemIds()
local sortedItemIds = {}
local itemCounts = {}
local visibleItemCount = 0 local visibleItemCount = 0
local totalRows = 0 local totalRows = 0
local maxScrollRow = 0 local maxScrollRow = 0
@@ -543,25 +497,12 @@ drawOverview = function()
end end
end end
local function renderOverview() local function refreshGridData()
itemCounts = getMeItemCounts(items) entries, counts = options.getEntriesAndCounts()
for i = 1, #items do
sortedItemIds[i] = items[i]
end end
table.sort(sortedItemIds, function(a, b) local function renderGrid()
local countA = itemCounts[a] or 0 totalRows = math.ceil(#entries / columns)
local countB = itemCounts[b] or 0
if countA ~= countB then
return countA > countB
end
return a < b
end)
totalRows = math.ceil(#sortedItemIds / columns)
maxScrollRow = math.max(0, totalRows - rowsPerView) maxScrollRow = math.max(0, totalRows - rowsPerView)
currentScrollRow = clampScrollRow(currentScrollRow) currentScrollRow = clampScrollRow(currentScrollRow)
targetScrollRow = clampScrollRow(targetScrollRow) targetScrollRow = clampScrollRow(targetScrollRow)
@@ -569,27 +510,29 @@ drawOverview = function()
local firstVisibleRow = math.floor(currentScrollRow) local firstVisibleRow = math.floor(currentScrollRow)
local rowOffsetPixels = -math.floor((currentScrollRow - firstVisibleRow) * rowStepPixels + 0.5) local rowOffsetPixels = -math.floor((currentScrollRow - firstVisibleRow) * rowStepPixels + 0.5)
local firstVisibleIndex = firstVisibleRow * columns + 1 local firstVisibleIndex = firstVisibleRow * columns + 1
local lastVisibleIndex = math.min(#sortedItemIds, (firstVisibleRow + rowsPerView + 1) * columns) local lastVisibleIndex = math.min(#entries, (firstVisibleRow + rowsPerView + 1) * columns)
frame.buffer:clear() frame.buffer:clear()
if options.drawChrome then
options.drawChrome()
end
for i = firstVisibleIndex, lastVisibleIndex do for i = firstVisibleIndex, lastVisibleIndex do
local itemId = sortedItemIds[i] local entry = entries[i]
local item = getItemById(itemId)
local icon = getItemIcon(item) or getFallbackIcon()
local relativeIndex = i - firstVisibleIndex local relativeIndex = i - firstVisibleIndex
local col = relativeIndex % columns local col = relativeIndex % columns
local row = math.floor(relativeIndex / columns) local row = math.floor(relativeIndex / columns)
drawItem( drawItem(
icon, options.getIcon(entry),
baseCellX + colStepCells * col, baseCellX + colStepCells * col,
baseCellY + rowStepCells * row, baseCellY + rowStepCells * row,
itemCounts[itemId] or 0, counts[options.getId(entry)] or 0,
rowOffsetPixels rowOffsetPixels
) )
end end
visibleItemCount = math.max(0, math.min(#sortedItemIds - firstVisibleRow * columns, rowsPerView * columns)) visibleItemCount = math.max(0, math.min(#entries - firstVisibleRow * columns, rowsPerView * columns))
local upButtonY = cellToPixelY(1) local upButtonY = cellToPixelY(1)
local downButtonY = cellToPixelY(SCREEN_HEIGHT - scrollbarButtonHeight + 1) local downButtonY = cellToPixelY(SCREEN_HEIGHT - scrollbarButtonHeight + 1)
@@ -612,15 +555,17 @@ drawOverview = function()
frame:drawBuffer() frame:drawBuffer()
end end
renderOverview() refreshGridData()
refreshTimer = os.startTimer(30) renderGrid()
refreshTimer = os.startTimer(options.refreshSeconds or 30)
while true do while true do
local event, p1, x, y = os.pullEvent() local event, p1, x, y = os.pullEvent()
if event == "timer" and p1 == refreshTimer then if event == "timer" and p1 == refreshTimer then
renderOverview() refreshGridData()
refreshTimer = os.startTimer(30) renderGrid()
refreshTimer = os.startTimer(options.refreshSeconds or 30)
scheduleAnimation() scheduleAnimation()
elseif event == "timer" and p1 == animationTimer then elseif event == "timer" and p1 == animationTimer then
local delta = targetScrollRow - currentScrollRow local delta = targetScrollRow - currentScrollRow
@@ -646,9 +591,11 @@ drawOverview = function()
end end
end end
renderOverview() renderGrid()
elseif event == "monitor_touch" and p1 == monName then elseif event == "monitor_touch" and p1 == monName then
if x >= scrollbarX and x < scrollbarX + scrollbarWidth then if options.handleChromeTouch and options.handleChromeTouch(x, y) then
return
elseif x >= scrollbarX and x < scrollbarX + scrollbarWidth then
if y <= scrollbarButtonHeight then if y <= scrollbarButtonHeight then
scrollTo(targetScrollRow - 1) scrollTo(targetScrollRow - 1)
elseif y > SCREEN_HEIGHT - scrollbarButtonHeight then elseif y > SCREEN_HEIGHT - scrollbarButtonHeight then
@@ -657,8 +604,7 @@ drawOverview = function()
local touchPixelY = cellToPixelY(y) + 1 local touchPixelY = cellToPixelY(y) + 1
local thumbY, thumbHeight = getThumbMetrics() local thumbY, thumbHeight = getThumbMetrics()
if touchPixelY < thumbY then if (touchPixelY < thumbY or touchPixelY > thumbY + thumbHeight - 1) and maxScrollRow > 0 then
if maxScrollRow > 0 then
local thumbTravel = scrollbarTrackPixelHeight - thumbHeight local thumbTravel = scrollbarTrackPixelHeight - thumbHeight
local targetPixelY = math.max( local targetPixelY = math.max(
scrollbarTrackPixelY, scrollbarTrackPixelY,
@@ -667,17 +613,6 @@ drawOverview = function()
local progress = (targetPixelY - scrollbarTrackPixelY) / math.max(1, thumbTravel) local progress = (targetPixelY - scrollbarTrackPixelY) / math.max(1, thumbTravel)
scrollTo(progress * maxScrollRow) scrollTo(progress * maxScrollRow)
end end
elseif touchPixelY > thumbY + thumbHeight - 1 then
if maxScrollRow > 0 then
local thumbTravel = scrollbarTrackPixelHeight - thumbHeight
local targetPixelY = math.max(
scrollbarTrackPixelY,
math.min(scrollbarTrackPixelY + thumbTravel, touchPixelY - math.floor(thumbHeight / 2))
)
local progress = (targetPixelY - scrollbarTrackPixelY) / math.max(1, thumbTravel)
scrollTo(progress * maxScrollRow)
end
end
end end
else else
local col = math.floor((x - baseCellX) / colStepCells) local col = math.floor((x - baseCellX) / colStepCells)
@@ -689,14 +624,95 @@ drawOverview = function()
if col >= 0 and col < columns and row >= 0 and row < rowsPerView + 1 then if col >= 0 and col < columns and row >= 0 and row < rowsPerView + 1 then
local index = (firstVisibleRow + row) * columns + col + 1 local index = (firstVisibleRow + row) * columns + col + 1
if index >= 1 and index <= #sortedItemIds and index <= firstVisibleRow * columns + visibleItemCount + columns then if index >= 1 and index <= #entries and index <= firstVisibleRow * columns + visibleItemCount + columns then
drawPage(sortedItemIds[index]) if options.onSelect(entries[index], index) then
return return
end end
end end
end end
end end
end end
end
end
local function drawPage(base_id)
local pageItems = getPageItems(base_id)
local defaultIcon = getFallbackIcon()
local backIcon = getBackButton()
local backWidth, backHeight = imageSize(backIcon)
local backX = 1
local pageItemIds = {}
for i = 1, #pageItems do
pageItemIds[i] = pageItems[i].id
end
runScrollableGrid({
refreshSeconds = 5,
getEntriesAndCounts = function()
return pageItems, getMeItemCounts(pageItemIds)
end,
getId = function(entry)
return entry.id
end,
getIcon = function(entry)
return getItemIcon(entry) or defaultIcon
end,
drawChrome = function()
drawNfpScaled(frame.buffer, backIcon, cellToPixelX(backX), 1)
end,
handleChromeTouch = function(x, y)
if x >= backX and x < backX + backWidth and y >= 1 and y <= backHeight then
drawOverview()
return true
end
return false
end,
onSelect = function()
return false
end,
})
end
drawOverview = function()
local items = getBaseItemIds()
local defaultIcon = getFallbackIcon()
runScrollableGrid({
refreshSeconds = 30,
getEntriesAndCounts = function()
local itemCounts = getMeItemCounts(items)
local sortedItemIds = {}
for i = 1, #items do
sortedItemIds[i] = items[i]
end
table.sort(sortedItemIds, function(a, b)
local countA = itemCounts[a] or 0
local countB = itemCounts[b] or 0
if countA ~= countB then
return countA > countB
end
return a < b
end)
return sortedItemIds, itemCounts
end,
getId = function(entry)
return entry
end,
getIcon = function(entry)
return getItemIcon(getItemById(entry)) or defaultIcon
end,
onSelect = function(entry)
drawPage(entry)
return true
end,
})
end end
drawOverview() drawOverview()