Implement page scrolling (seperate into runScrollableGrid)
This commit is contained in:
+110
-94
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user