Compare commits
10 Commits
81aca559c9
...
8d9abc8cb2
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d9abc8cb2 | |||
| 14961629f2 | |||
| 2a15e704b2 | |||
| 991bc5eb3e | |||
| 0a9380cd22 | |||
| d381ac1693 | |||
| 8a5e4a0fb1 | |||
| e5f7da3cc5 | |||
| 4f623656bb | |||
| acfc5e7324 |
+457
-98
@@ -1,12 +1,26 @@
|
||||
local mon = peripheral.find("monitor")
|
||||
assert(mon, "Kein Monitor gefunden")
|
||||
assert(mon, "No monitor found")
|
||||
local monName = peripheral.getName(mon)
|
||||
local SCREEN_WIDTH = 40
|
||||
|
||||
mon.setTextScale(0.5)
|
||||
|
||||
local SCREEN_WIDTH, SCREEN_HEIGHT = mon.getSize()
|
||||
|
||||
local oldTerm = term.redirect(mon)
|
||||
|
||||
local function ensureDependency(path, url)
|
||||
if fs.exists(path) then
|
||||
return
|
||||
end
|
||||
|
||||
assert(shell and type(shell.run) == "function", "Shell API is not available")
|
||||
assert(shell.run("wget", url, path) and fs.exists(path), "Could not download dependency: " .. path)
|
||||
end
|
||||
|
||||
ensureDependency("Pine3D.lua", "https://raw.githubusercontent.com/Xella37/Pine3D/main/Pine3D.lua")
|
||||
ensureDependency("betterblittle.lua", "https://raw.githubusercontent.com/Xella37/Pine3D/main/betterblittle.lua")
|
||||
ensureDependency("morefonts-pe.lua", "https://raw.githubusercontent.com/MichielP1807/more-fonts/main/pine3d/morefonts-pe.lua")
|
||||
|
||||
local Pine3D = require("Pine3D")
|
||||
local mf = require("morefonts-pe")
|
||||
|
||||
@@ -18,44 +32,88 @@ local chainItemsByBaseId
|
||||
local baseItemIds
|
||||
local itemById
|
||||
local defaultBaseId
|
||||
local whitelistLookup
|
||||
local fallbackIcon = false
|
||||
local backButton = false
|
||||
local scrollUpButton = false
|
||||
local scrollDownButton = false
|
||||
local overviewScrollCurrentRow = 0
|
||||
local overviewScrollTargetRow = 0
|
||||
local drawOverview
|
||||
|
||||
local function ensureWhitelistLoaded()
|
||||
if whitelistLookup ~= nil then
|
||||
return
|
||||
end
|
||||
|
||||
if not fs.exists("whitelist.json") then
|
||||
whitelistLookup = false
|
||||
return
|
||||
end
|
||||
|
||||
local file = assert(fs.open("whitelist.json", "r"))
|
||||
local data = textutils.unserializeJSON(file.readAll())
|
||||
file.close()
|
||||
|
||||
assert(type(data) == "table", "Invalid whitelist.json data")
|
||||
|
||||
if #data == 0 then
|
||||
whitelistLookup = false
|
||||
return
|
||||
end
|
||||
|
||||
whitelistLookup = {}
|
||||
|
||||
for i = 1, #data do
|
||||
local baseId = data[i]
|
||||
assert(type(baseId) == "string", "Invalid whitelist.json entry")
|
||||
whitelistLookup[baseId] = true
|
||||
end
|
||||
end
|
||||
|
||||
local function ensureChainsLoaded()
|
||||
if not chainItemsByBaseId then
|
||||
ensureWhitelistLoaded()
|
||||
|
||||
local file = assert(fs.open("atc_chains.json", "r"))
|
||||
local data = textutils.unserializeJSON(file.readAll())
|
||||
file.close()
|
||||
|
||||
assert(type(data) == "table" and type(data.chains) == "table", "Ungueltige JSON-Daten")
|
||||
assert(type(data) == "table" and type(data.chains) == "table", "Invalid JSON data")
|
||||
|
||||
chainItemsByBaseId = {}
|
||||
baseItemIds = {}
|
||||
itemById = {}
|
||||
|
||||
for _, chain in ipairs(data.chains) do
|
||||
if not defaultBaseId then
|
||||
defaultBaseId = chain.base_id
|
||||
end
|
||||
|
||||
baseItemIds[#baseItemIds + 1] = chain.base_id
|
||||
|
||||
local items = {}
|
||||
local itemCount = 0
|
||||
|
||||
for _, item in ipairs(chain.items or {}) do
|
||||
if item.stage ~= "item" then
|
||||
itemCount = itemCount + 1
|
||||
items[itemCount] = {
|
||||
id = item.item_id,
|
||||
icon_nfp = item.icon_nfp_16x16,
|
||||
}
|
||||
itemById[item.item_id] = items[itemCount]
|
||||
if not whitelistLookup or whitelistLookup[chain.base_id] then
|
||||
if not defaultBaseId then
|
||||
defaultBaseId = chain.base_id
|
||||
end
|
||||
end
|
||||
|
||||
chainItemsByBaseId[chain.base_id] = items
|
||||
baseItemIds[#baseItemIds + 1] = chain.base_id
|
||||
|
||||
local items = {}
|
||||
local itemCount = 0
|
||||
|
||||
for _, item in ipairs(chain.items or {}) do
|
||||
if item.stage == "item" then
|
||||
itemById[item.item_id] = {
|
||||
id = item.item_id,
|
||||
icon_nfp = item.icon_nfp_16x16,
|
||||
}
|
||||
else
|
||||
itemCount = itemCount + 1
|
||||
items[itemCount] = {
|
||||
id = item.item_id,
|
||||
icon_nfp = item.icon_nfp_16x16,
|
||||
}
|
||||
itemById[item.item_id] = items[itemCount]
|
||||
end
|
||||
end
|
||||
|
||||
chainItemsByBaseId[chain.base_id] = items
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -193,8 +251,24 @@ end
|
||||
|
||||
local function getFallbackIcon()
|
||||
if fallbackIcon == false then
|
||||
local ok, image = pcall(paintutils.loadImage, "/icons16/diamond16.nfp")
|
||||
fallbackIcon = ok and image or nil
|
||||
fallbackIcon = parseNfpImage(table.concat({
|
||||
"0000000000000000",
|
||||
"000000eeee000000",
|
||||
"00000eeeeee00000",
|
||||
"0000eee00eee0000",
|
||||
"00000e00000ee000",
|
||||
"0000000000eee000",
|
||||
"000000000eee0000",
|
||||
"00000000eee00000",
|
||||
"00000000ee000000",
|
||||
"0000000000000000",
|
||||
"00000000ee000000",
|
||||
"00000000ee000000",
|
||||
"0000000000000000",
|
||||
"0000000000000000",
|
||||
"0000000000000000",
|
||||
"0000000000000000",
|
||||
}, "\n"))
|
||||
end
|
||||
|
||||
return fallbackIcon
|
||||
@@ -212,6 +286,30 @@ local function getBackButton()
|
||||
return backButton
|
||||
end
|
||||
|
||||
local function getScrollUpButton()
|
||||
if scrollUpButton == false then
|
||||
scrollUpButton = parseNfpImage(table.concat({
|
||||
" 00 ",
|
||||
"0000",
|
||||
"0 0",
|
||||
}, "\n"))
|
||||
end
|
||||
|
||||
return scrollUpButton
|
||||
end
|
||||
|
||||
local function getScrollDownButton()
|
||||
if scrollDownButton == false then
|
||||
scrollDownButton = parseNfpImage(table.concat({
|
||||
"0 0",
|
||||
"0000",
|
||||
" 00 ",
|
||||
}, "\n"))
|
||||
end
|
||||
|
||||
return scrollDownButton
|
||||
end
|
||||
|
||||
local function imageSize(img)
|
||||
local w, h = 0, 0
|
||||
|
||||
@@ -266,16 +364,21 @@ local function drawNfpScaled(buffer, img, x, y, scaleX, scaleY)
|
||||
|
||||
for imgY, row in pairs(img) do
|
||||
for imgX, col in pairs(row) do
|
||||
-- WICHTIG:
|
||||
-- Nur echte ComputerCraft-Farben in den Pine3D-Buffer schreiben.
|
||||
-- Keine Strings, keine nils, keine 0.
|
||||
-- IMPORTANT:
|
||||
-- Only write real ComputerCraft colors into the Pine3D buffer.
|
||||
-- No strings, no nil values, no 0.
|
||||
if type(col) == "number" and col > 0 then
|
||||
local px = x + (imgX - 1) * scaleX
|
||||
local py = y + (imgY - 1) * scaleY
|
||||
|
||||
for dy = 0, scaleY - 1 do
|
||||
for dx = 0, scaleX - 1 do
|
||||
buffer:setPixel(px + dx, py + dy, col)
|
||||
local drawX = px + dx
|
||||
local drawY = py + dy
|
||||
|
||||
if drawX >= 1 and drawX <= buffer.width and drawY >= 1 and drawY <= buffer.height then
|
||||
buffer:setPixel(drawX, drawY, col)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -283,6 +386,31 @@ local function drawNfpScaled(buffer, img, x, y, scaleX, scaleY)
|
||||
end
|
||||
end
|
||||
|
||||
local function fillRect(buffer, x, y, width, height, color)
|
||||
local startX = math.max(1, x)
|
||||
local startY = math.max(1, y)
|
||||
local endX = math.min(buffer.width, x + width - 1)
|
||||
local endY = math.min(buffer.height, y + height - 1)
|
||||
|
||||
if startX > endX or startY > endY then
|
||||
return
|
||||
end
|
||||
|
||||
for py = startY, endY do
|
||||
for px = startX, endX do
|
||||
buffer:setPixel(px, py, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function cellToPixelX(cellX)
|
||||
return (cellX - 1) * 2 + 1
|
||||
end
|
||||
|
||||
local function cellToPixelY(cellY)
|
||||
return (cellY - 1) * 3 + 1
|
||||
end
|
||||
|
||||
local function assertBufferValid(frame)
|
||||
local valid = {
|
||||
[colors.white] = true,
|
||||
@@ -308,16 +436,16 @@ local function assertBufferValid(frame)
|
||||
local c = frame.buffer.colorValues[y][x]
|
||||
|
||||
if not valid[c] then
|
||||
error("Ungueltiger Pixel im Buffer bei x=" .. x .. ", y=" .. y .. ": " .. tostring(c))
|
||||
error("Invalid pixel in buffer at x=" .. x .. ", y=" .. y .. ": " .. tostring(c))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawItem(img, cellX, cellY, count)
|
||||
-- Normale Monitor-Zellen in Pine3D-Teletext-Pixel umrechnen.
|
||||
local x = (cellX - 1) * 2 + 1
|
||||
local y = (cellY - 1) * 3 + 1
|
||||
local function drawItem(img, cellX, cellY, count, offsetY)
|
||||
-- Convert normal monitor cells into Pine3D teletext pixels.
|
||||
local x = cellToPixelX(cellX)
|
||||
local y = cellToPixelY(cellY) + (offsetY or 0)
|
||||
|
||||
local imgW, imgH = 0, 0
|
||||
|
||||
@@ -326,7 +454,9 @@ local function drawItem(img, cellX, cellY, count)
|
||||
|
||||
if img then
|
||||
imgW, imgH = imageSize(img)
|
||||
drawNfpScaled(frame.buffer, img, x, y, scaleX, scaleY)
|
||||
if y <= frame.buffer.height and y + imgH * scaleY - 1 >= 1 then
|
||||
drawNfpScaled(frame.buffer, img, x, y, scaleX, scaleY)
|
||||
end
|
||||
end
|
||||
|
||||
local text = formatCount(count)
|
||||
@@ -345,11 +475,233 @@ local function drawItem(img, cellX, cellY, count)
|
||||
dy = 1,
|
||||
}
|
||||
|
||||
-- Schatten
|
||||
mf.writeOn(frame, text, colors.black, rightX + 1, bottomY + 1, options)
|
||||
if bottomY >= 1 and y <= frame.buffer.height then
|
||||
-- Shadow
|
||||
mf.writeOn(frame, text, colors.black, rightX + 1, bottomY + 1, options)
|
||||
|
||||
-- Weißer Count
|
||||
mf.writeOn(frame, text, colors.white, rightX, bottomY, options)
|
||||
-- White count
|
||||
mf.writeOn(frame, text, colors.white, rightX, bottomY, options)
|
||||
end
|
||||
end
|
||||
|
||||
local function runScrollableGrid(options)
|
||||
local entries = {}
|
||||
local counts = {}
|
||||
local visibleItemCount = 0
|
||||
local totalRows = 0
|
||||
local maxScrollRow = 0
|
||||
local currentScrollRow = 0
|
||||
local targetScrollRow = 0
|
||||
local refreshTimer
|
||||
local animationTimer
|
||||
|
||||
local columns = 3
|
||||
local rowsPerView = 3
|
||||
local baseCellX = 4
|
||||
local baseCellY = 2
|
||||
local colStepCells = 12
|
||||
local rowStepCells = 6
|
||||
local rowStepPixels = rowStepCells * 3
|
||||
local scrollbarX = SCREEN_WIDTH - 1
|
||||
local scrollbarWidth = 2
|
||||
local scrollbarButtonHeight = 3
|
||||
local scrollbarTrackY = scrollbarButtonHeight + 1
|
||||
local scrollbarTrackHeight = SCREEN_HEIGHT - scrollbarButtonHeight * 2
|
||||
local scrollbarPixelX = cellToPixelX(scrollbarX)
|
||||
local scrollbarPixelWidth = scrollbarWidth * 2
|
||||
local scrollbarTrackPixelY = cellToPixelY(scrollbarTrackY)
|
||||
local scrollbarTrackPixelHeight = math.max(0, scrollbarTrackHeight * 3)
|
||||
|
||||
if options.getInitialScrollState then
|
||||
local initialCurrentRow, initialTargetRow = options.getInitialScrollState()
|
||||
currentScrollRow = tonumber(initialCurrentRow) or 0
|
||||
targetScrollRow = tonumber(initialTargetRow) or currentScrollRow
|
||||
end
|
||||
|
||||
local function snapScrollRow(row)
|
||||
return math.floor((tonumber(row) or 0) + 0.5)
|
||||
end
|
||||
|
||||
local function persistScrollState()
|
||||
if options.setScrollState then
|
||||
options.setScrollState(snapScrollRow(targetScrollRow), snapScrollRow(targetScrollRow))
|
||||
end
|
||||
end
|
||||
|
||||
local function clampScrollRow(row)
|
||||
return math.max(0, math.min(maxScrollRow, row))
|
||||
end
|
||||
|
||||
local function getThumbMetrics()
|
||||
if scrollbarTrackPixelHeight <= 0 then
|
||||
return scrollbarTrackPixelY, 0
|
||||
end
|
||||
|
||||
if totalRows <= rowsPerView or maxScrollRow == 0 then
|
||||
return scrollbarTrackPixelY, scrollbarTrackPixelHeight
|
||||
end
|
||||
|
||||
local thumbHeight = math.max(4, math.floor(scrollbarTrackPixelHeight * rowsPerView / totalRows + 0.5))
|
||||
local thumbTravel = scrollbarTrackPixelHeight - thumbHeight
|
||||
local thumbY = scrollbarTrackPixelY + math.floor((currentScrollRow / maxScrollRow) * thumbTravel + 0.5)
|
||||
|
||||
return thumbY, thumbHeight
|
||||
end
|
||||
|
||||
local function scheduleAnimation()
|
||||
if not animationTimer and math.abs(targetScrollRow - currentScrollRow) > 0.001 then
|
||||
animationTimer = os.startTimer(0.05)
|
||||
end
|
||||
end
|
||||
|
||||
local function scrollTo(row)
|
||||
local clampedRow = clampScrollRow(snapScrollRow(row))
|
||||
|
||||
if clampedRow ~= targetScrollRow then
|
||||
targetScrollRow = clampedRow
|
||||
persistScrollState()
|
||||
scheduleAnimation()
|
||||
end
|
||||
end
|
||||
|
||||
local function refreshGridData()
|
||||
entries, counts = options.getEntriesAndCounts()
|
||||
end
|
||||
|
||||
local function renderGrid()
|
||||
totalRows = math.ceil(#entries / columns)
|
||||
maxScrollRow = math.max(0, totalRows - rowsPerView)
|
||||
currentScrollRow = clampScrollRow(currentScrollRow)
|
||||
targetScrollRow = clampScrollRow(snapScrollRow(targetScrollRow))
|
||||
persistScrollState()
|
||||
|
||||
local firstVisibleRow = math.floor(currentScrollRow)
|
||||
local rowOffsetPixels = -math.floor((currentScrollRow - firstVisibleRow) * rowStepPixels + 0.5)
|
||||
local firstVisibleIndex = firstVisibleRow * columns + 1
|
||||
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 entry = entries[i]
|
||||
local relativeIndex = i - firstVisibleIndex
|
||||
local col = relativeIndex % columns
|
||||
local row = math.floor(relativeIndex / columns)
|
||||
drawItem(
|
||||
options.getIcon(entry),
|
||||
baseCellX + colStepCells * col,
|
||||
baseCellY + rowStepCells * row,
|
||||
counts[options.getId(entry)] or 0,
|
||||
rowOffsetPixels
|
||||
)
|
||||
end
|
||||
|
||||
visibleItemCount = math.max(0, math.min(#entries - firstVisibleRow * columns, rowsPerView * columns))
|
||||
|
||||
local upButtonY = cellToPixelY(1)
|
||||
local downButtonY = cellToPixelY(SCREEN_HEIGHT - scrollbarButtonHeight + 1)
|
||||
local upColor = targetScrollRow > 0 and colors.gray or colors.lightGray
|
||||
local downColor = targetScrollRow < maxScrollRow and colors.gray or colors.lightGray
|
||||
local thumbY, thumbHeight = getThumbMetrics()
|
||||
|
||||
fillRect(frame.buffer, scrollbarPixelX, upButtonY, scrollbarPixelWidth, scrollbarButtonHeight * 3, upColor)
|
||||
fillRect(frame.buffer, scrollbarPixelX, downButtonY, scrollbarPixelWidth, scrollbarButtonHeight * 3, downColor)
|
||||
|
||||
if scrollbarTrackPixelHeight > 0 then
|
||||
fillRect(frame.buffer, scrollbarPixelX, scrollbarTrackPixelY, scrollbarPixelWidth, scrollbarTrackPixelHeight, colors.gray)
|
||||
fillRect(frame.buffer, scrollbarPixelX, thumbY, scrollbarPixelWidth, thumbHeight, colors.white)
|
||||
end
|
||||
|
||||
drawNfpScaled(frame.buffer, getScrollUpButton(), scrollbarPixelX, upButtonY + 2, 1, 1)
|
||||
drawNfpScaled(frame.buffer, getScrollDownButton(), scrollbarPixelX, downButtonY + 3, 1, 1)
|
||||
|
||||
assertBufferValid(frame)
|
||||
frame:drawBuffer()
|
||||
end
|
||||
|
||||
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
|
||||
refreshGridData()
|
||||
renderGrid()
|
||||
refreshTimer = os.startTimer(options.refreshSeconds or 30)
|
||||
scheduleAnimation()
|
||||
elseif event == "timer" and p1 == animationTimer then
|
||||
local delta = targetScrollRow - currentScrollRow
|
||||
|
||||
if math.abs(delta) <= 0.001 then
|
||||
currentScrollRow = targetScrollRow
|
||||
animationTimer = nil
|
||||
else
|
||||
local step = delta * 0.35
|
||||
|
||||
if step > 0 then
|
||||
step = math.max(0.08, math.min(step, 0.45))
|
||||
else
|
||||
step = math.min(-0.08, math.max(step, -0.45))
|
||||
end
|
||||
|
||||
if math.abs(step) >= math.abs(delta) then
|
||||
currentScrollRow = targetScrollRow
|
||||
animationTimer = nil
|
||||
else
|
||||
currentScrollRow = currentScrollRow + step
|
||||
animationTimer = os.startTimer(0.05)
|
||||
end
|
||||
end
|
||||
|
||||
persistScrollState()
|
||||
renderGrid()
|
||||
elseif event == "monitor_touch" and p1 == monName 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
|
||||
scrollTo(targetScrollRow + 1)
|
||||
elseif scrollbarTrackHeight > 0 then
|
||||
local touchPixelY = cellToPixelY(y) + 1
|
||||
local thumbY, thumbHeight = getThumbMetrics()
|
||||
|
||||
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
|
||||
local col = math.floor((x - baseCellX) / colStepCells)
|
||||
local firstVisibleRow = math.floor(currentScrollRow)
|
||||
local rowOffsetPixels = (currentScrollRow - firstVisibleRow) * rowStepPixels
|
||||
local touchPixelY = cellToPixelY(y) + 1
|
||||
local row = math.floor((touchPixelY - cellToPixelY(baseCellY) + rowOffsetPixels) / rowStepPixels)
|
||||
|
||||
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 <= #entries and index <= firstVisibleRow * columns + visibleItemCount + columns then
|
||||
if options.onSelect(entries[index], index) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawPage(base_id)
|
||||
@@ -357,79 +709,86 @@ local function drawPage(base_id)
|
||||
local defaultIcon = getFallbackIcon()
|
||||
local backIcon = getBackButton()
|
||||
local backWidth, backHeight = imageSize(backIcon)
|
||||
local backX = SCREEN_WIDTH - backWidth + 1
|
||||
local backX = 1
|
||||
local pageItemIds = {}
|
||||
local visibleItemCount = math.min(math.max(#pageItems, 9), 9)
|
||||
|
||||
for i = 1, visibleItemCount do
|
||||
for i = 1, #pageItems do
|
||||
pageItemIds[i] = pageItems[i].id
|
||||
end
|
||||
|
||||
local function renderPage()
|
||||
local itemCounts = getMeItemCounts(pageItemIds)
|
||||
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
|
||||
|
||||
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
|
||||
return false
|
||||
end,
|
||||
onSelect = function()
|
||||
return false
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
drawOverview = function()
|
||||
local items = getBaseItemIds()
|
||||
local visibleItemCount = math.min(math.max(#items, 9), 9)
|
||||
-- TODO LATER: get item counts from me-system using item, then sort items according to their counts and display the top 9. For now, just use random numbers.
|
||||
local defaultIcon = getFallbackIcon()
|
||||
|
||||
frame.buffer:clear()
|
||||
runScrollableGrid({
|
||||
refreshSeconds = 30,
|
||||
getInitialScrollState = function()
|
||||
return overviewScrollCurrentRow, overviewScrollTargetRow
|
||||
end,
|
||||
setScrollState = function(currentRow, targetRow)
|
||||
overviewScrollCurrentRow = currentRow
|
||||
overviewScrollTargetRow = targetRow
|
||||
end,
|
||||
getEntriesAndCounts = function()
|
||||
local itemCounts = getMeItemCounts(items)
|
||||
local sortedItemIds = {}
|
||||
|
||||
for i = 1, visibleItemCount do
|
||||
local item = getItemById(items[i])
|
||||
local icon = getItemIcon(item) or getFallbackIcon()
|
||||
drawItem(icon, 4+(8+4)*((i-1)%3), 2+(5+1)*math.floor((i-1)/3), math.random(0, 1000000000000))
|
||||
end
|
||||
|
||||
assertBufferValid(frame)
|
||||
frame:drawBuffer()
|
||||
|
||||
while true do
|
||||
local _, side, x, y = os.pullEvent("monitor_touch")
|
||||
|
||||
if side == monName then
|
||||
local col = math.floor((x - 4) / 12)
|
||||
local row = math.floor((y - 2) / 6)
|
||||
|
||||
if col >= 0 and col < 3 and row >= 0 and row < 3 then
|
||||
local index = row * 3 + col + 1
|
||||
|
||||
if index <= visibleItemCount then
|
||||
drawPage(items[index])
|
||||
return
|
||||
end
|
||||
for i = 1, #items do
|
||||
sortedItemIds[i] = items[i]
|
||||
end
|
||||
end
|
||||
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()
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
[
|
||||
|
||||
]
|
||||
Reference in New Issue
Block a user