Implement page scrolling (seperate into runScrollableGrid)
This commit is contained in:
+119
-103
@@ -434,55 +434,9 @@ local function drawItem(img, cellX, cellY, count, offsetY)
|
||||
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 = 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 function runScrollableGrid(options)
|
||||
local entries = {}
|
||||
local counts = {}
|
||||
local visibleItemCount = 0
|
||||
local totalRows = 0
|
||||
local maxScrollRow = 0
|
||||
@@ -543,25 +497,12 @@ drawOverview = function()
|
||||
end
|
||||
end
|
||||
|
||||
local function renderOverview()
|
||||
itemCounts = getMeItemCounts(items)
|
||||
local function refreshGridData()
|
||||
entries, counts = options.getEntriesAndCounts()
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
totalRows = math.ceil(#sortedItemIds / columns)
|
||||
local function renderGrid()
|
||||
totalRows = math.ceil(#entries / columns)
|
||||
maxScrollRow = math.max(0, totalRows - rowsPerView)
|
||||
currentScrollRow = clampScrollRow(currentScrollRow)
|
||||
targetScrollRow = clampScrollRow(targetScrollRow)
|
||||
@@ -569,27 +510,29 @@ drawOverview = function()
|
||||
local firstVisibleRow = math.floor(currentScrollRow)
|
||||
local rowOffsetPixels = -math.floor((currentScrollRow - firstVisibleRow) * rowStepPixels + 0.5)
|
||||
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()
|
||||
|
||||
if options.drawChrome then
|
||||
options.drawChrome()
|
||||
end
|
||||
|
||||
for i = firstVisibleIndex, lastVisibleIndex do
|
||||
local itemId = sortedItemIds[i]
|
||||
local item = getItemById(itemId)
|
||||
local icon = getItemIcon(item) or getFallbackIcon()
|
||||
local entry = entries[i]
|
||||
local relativeIndex = i - firstVisibleIndex
|
||||
local col = relativeIndex % columns
|
||||
local row = math.floor(relativeIndex / columns)
|
||||
drawItem(
|
||||
icon,
|
||||
options.getIcon(entry),
|
||||
baseCellX + colStepCells * col,
|
||||
baseCellY + rowStepCells * row,
|
||||
itemCounts[itemId] or 0,
|
||||
counts[options.getId(entry)] or 0,
|
||||
rowOffsetPixels
|
||||
)
|
||||
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 downButtonY = cellToPixelY(SCREEN_HEIGHT - scrollbarButtonHeight + 1)
|
||||
@@ -612,15 +555,17 @@ drawOverview = function()
|
||||
frame:drawBuffer()
|
||||
end
|
||||
|
||||
renderOverview()
|
||||
refreshTimer = os.startTimer(30)
|
||||
refreshGridData()
|
||||
renderGrid()
|
||||
refreshTimer = os.startTimer(options.refreshSeconds or 30)
|
||||
|
||||
while true do
|
||||
local event, p1, x, y = os.pullEvent()
|
||||
|
||||
if event == "timer" and p1 == refreshTimer then
|
||||
renderOverview()
|
||||
refreshTimer = os.startTimer(30)
|
||||
refreshGridData()
|
||||
renderGrid()
|
||||
refreshTimer = os.startTimer(options.refreshSeconds or 30)
|
||||
scheduleAnimation()
|
||||
elseif event == "timer" and p1 == animationTimer then
|
||||
local delta = targetScrollRow - currentScrollRow
|
||||
@@ -646,9 +591,11 @@ drawOverview = function()
|
||||
end
|
||||
end
|
||||
|
||||
renderOverview()
|
||||
renderGrid()
|
||||
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
|
||||
scrollTo(targetScrollRow - 1)
|
||||
elseif y > SCREEN_HEIGHT - scrollbarButtonHeight then
|
||||
@@ -657,26 +604,14 @@ drawOverview = function()
|
||||
local touchPixelY = cellToPixelY(y) + 1
|
||||
local thumbY, thumbHeight = getThumbMetrics()
|
||||
|
||||
if touchPixelY < thumbY 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
|
||||
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
|
||||
if (touchPixelY < thumbY or touchPixelY > thumbY + thumbHeight - 1) and 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
|
||||
else
|
||||
@@ -689,9 +624,10 @@ drawOverview = function()
|
||||
if col >= 0 and col < columns and row >= 0 and row < rowsPerView + 1 then
|
||||
local index = (firstVisibleRow + row) * columns + col + 1
|
||||
|
||||
if index >= 1 and index <= #sortedItemIds and index <= firstVisibleRow * columns + visibleItemCount + columns then
|
||||
drawPage(sortedItemIds[index])
|
||||
return
|
||||
if index >= 1 and index <= #entries and index <= firstVisibleRow * columns + visibleItemCount + columns then
|
||||
if options.onSelect(entries[index], index) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -699,6 +635,86 @@ drawOverview = function()
|
||||
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
|
||||
|
||||
drawOverview()
|
||||
|
||||
term.redirect(oldTerm)
|
||||
|
||||
Reference in New Issue
Block a user