Refactor, add listview to requests view

Update line by line and do full redraw only when necessary.
This commit is contained in:
Ben 2024-06-02 00:52:58 +02:00
parent 7de3aefb8f
commit e414f229db
Signed by: ben
GPG key ID: 0F54A7ED232D3319
6 changed files with 164 additions and 77 deletions

61
listview.lua Normal file
View file

@ -0,0 +1,61 @@
local backingList = {}
local paginationOffset = 1
local frame = term.current()
local drawLine = nil
local function setTerm(termlike)
frame = termlike
end
local function setDrawLineFunc(drawLineFunc)
drawLine = drawLineFunc
end
local function redrawLine(idx)
if drawLine then
local tw, th = frame.getSize()
if idx >= paginationOffset and idx-paginationOffset <= th then
frame.setCursorPos(1,idx-paginationOffset+1)
drawLine(frame, backingList[idx])
end
end
end
local function itemAt(idx)
return backingList[idx]
end
local function updateItemAt(idx, item)
backingList[idx] = item
redrawLine(idx)
end
local function redraw()
if drawLine then
local tw, th = frame.getSize()
local backingIdx = paginationOffset
for idx = 1, th, 1 do
if backingList[backingIdx] ~= nil then
frame.setCursorPos(idx)
drawLine(frame, backingList[backingIdx])
end
end
end
end
local function updatePage(newOffset)
if newOffset ~= paginationOffset then
paginationOffset = newOffset
redraw()
end
end
return {
setTerm=setTerm,
setDrawLineFunc=setDrawLineFunc,
itemAt=itemAt,
updateItemAt=updateItemAt,
redraw=redraw,
updatePage=updatePage,
}

View file

@ -2,7 +2,11 @@ local config = require "config"
local colony = peripheral.wrap(config.colony_interface_side)
local orders = {}
local frame = term.current()
local function setTerm(termlike)
frame = termlike
end
local function fetch(wait_for)
orders = {}
@ -30,46 +34,45 @@ local function fetch(wait_for)
end
end
local function displayTab(self)
self.window.clear()
local tw,th = self.window.getSize()
frame.clear()
local tw,th = frame.getSize()
for i, val in pairs(orders) do
local line_num = (i-self.scrollPos)*2+1
if line_num > 0 and line_num < th-1 then
self.window.setTextColor(colors.lightGray)
self.window.setCursorPos(1,line_num)
self.window.write(val.id)
self.window.write(" ")
frame.setTextColor(colors.lightGray)
frame.setCursorPos(1,line_num)
frame.write(val.id)
frame.write(" ")
if val.pos then
self.window.write(val.pos.x .. "," .. val.pos.y .. "," .. val.pos.z)
self.window.write(" ")
frame.write(val.pos.x .. "," .. val.pos.y .. "," .. val.pos.z)
frame.write(" ")
end
self.window.setCursorPos(2,line_num+1)
self.window.setTextColor(colors.white)
frame.setCursorPos(2,line_num+1)
frame.setTextColor(colors.white)
if val.type then
self.window.write(val.type)
self.window.write(" ")
frame.write(val.type)
frame.write(" ")
end
if val.target then
self.window.write(val.target)
self.window.write(" ")
frame.write(val.target)
frame.write(" ")
end
if val.res_status then
self.window.setCursorPos(tw-2-#val.res_status, line_num)
self.window.write(val.res_status)
frame.setCursorPos(tw-2-#val.res_status, line_num)
frame.write(val.res_status)
else
self.window.setCursorPos(tw-2, line_num)
frame.setCursorPos(tw-2, line_num)
end
self.window.write(" ")
frame.write(" ")
if val.claimed then
self.window.setTextColor(colors.yellow)
self.window.write("C")
self.window.setTextColor(colors.white)
frame.setTextColor(colors.yellow)
frame.write("C")
frame.setTextColor(colors.white)
else
self.window.write(" ")
frame.write(" ")
end
self.window.write(" ")
frame.write(" ")
end
end
end
@ -78,8 +81,10 @@ local function onTouch(self, touch_x, touch_y)
return false
end
return {
name="orders",
setTerm=setTerm,
fetch=fetch,
displayTab=displayTab,
onTouch=onTouch,

View file

@ -1,8 +1,8 @@
local config = require "config"
local permset = require "permset"
local listview = require "listview"
local winhlp = require "winhlp"
-- to match click positions back to item names
local display_list = {}
-- list of allowed item names, will be requested
local allowed_items = permset.new(".allowed_items")
@ -12,24 +12,32 @@ if config.has_me then
end
local colony = peripheral.wrap(config.colony_interface_side)
local requests = {}
local frame = term.current()
local function setTerm(termlike)
frame = termlike
listview.setTerm(frame)
end
local function fetch(wait_for)
requests = {}
local reqs = colony.getRequests()
local me_items = nil
if config.has_me then
me_items = main_me.listItems()
end
local currentIdx = 1
for i, req in pairs(reqs) do
local found = false
if me_items then
local left_amount = req.count
for j, it in pairs(req.items) do
for k, have_it in pairs(me_items) do
-- TODO: check NBT
if have_it.name == it.name then
found = true
table.insert(requests, {req=req, answer=have_it})
listview.updateItemAt(currentIdx, {req=req, answer=have_it})
currentIdx = currentIdx + 1
if left_amount > 0 and permset.has(allowed_items, it.name) then
local export_amount = math.min(have_it.amount, left_amount)
left_amount = left_amount - export_amount
@ -40,66 +48,68 @@ local function fetch(wait_for)
end
end
if found == false then
table.insert(requests, {req=req, answer=nil})
listview.updateItemAt(currentIdx, {req=req, answer=nil})
currentIdx = currentIdx + 1
end
wait_for(config.step_sleep_time)
end
listview.clearAfter(currentIdx)
end
local function displayTab(self)
self.window.clear()
local tw,th = self.window.getSize()
display_list = {}
for i, val in pairs(requests) do
local line_num = i-self.scrollPos+1
if line_num > 0 and line_num < th then
self.window.setTextColor(colors.white)
self.window.setCursorPos(1,line_num)
self.window.write(val.req.name)
self.window.write(" ")
if val.answer == nil then
self.window.setTextColor(colors.orange)
self.window.write("N/A")
else
if permset.has(allowed_items, val.answer.name) then
self.window.setTextColor(colors.green)
else
self.window.setTextColor(colors.yellow)
end
self.window.write(val.answer.name)
display_list[line_num] = val.answer.name
self.window.setTextColor(colors.white)
self.window.setCursorPos(tw-4,line_num)
self.window.write(" [")
if permset.has(allowed_items, val.answer.name) then
self.window.setTextColor(colors.green)
self.window.write("X")
self.window.setTextColor(colors.white)
else
self.window.write(" ")
end
self.window.write("] ")
end
local function drawLine(termlike, obj)
termlike.setTextColor(colors.white)
termlike.write(obj.req.name)
termlike.write(" ")
if obj.answer == nil then
termlike.setTextColor(colors.orange)
local padding = winhlp.alignRight(termlike, 5)
termlike.write(string.format("%" .. padding+5 .. "s", " N/A "))
else
if permset.has(allowed_items, obj.answer.name) then
termlike.setTextColor(colors.green)
else
termlike.setTextColor(colors.yellow)
end
termlike.write(obj.answer.name)
termlike.setTextColor(colors.white)
local padding = winhlp.alignRight(termlike, 5)
termlike.write(string.format("%" .. padding+2 .. "s", " ["))
if permset.has(allowed_items, obj.answer.name) then
termlike.setTextColor(colors.green)
termlike.write("X")
termlike.setTextColor(colors.white)
else
termlike.write(" ")
end
termlike.write("] ")
end
end
listview.setDrawLineFunc(drawLine)
local function displayTab(self)
listview.updatePage(self.scrollPos)
end
local function onTouch(self, touch_x, touch_y)
local tw, th = self.window.getSize()
if touch_x > tw-5 and display_list[touch_y] ~= nil then
local item_name = display_list[touch_y]
if permset.has(allowed_items, item_name) then
permset.remove(allowed_items, item_name)
else
permset.add(allowed_items, item_name)
if touch_x > tw-5 then
local obj = listview.itemAt(touch_y)
if obj ~= nil and obj.answer ~= nil then
if permset.has(allowed_items, obj.answer.name) then
permset.remove(allowed_items, obj.answer.name)
else
permset.add(allowed_items, obj.answer.name)
end
return true
end
return true
end
return false
end
return {
name="requests",
setTerm=setTerm,
fetch=fetch,
displayTab=displayTab,
onTouch=onTouch,

View file

@ -1,13 +1,13 @@
local winhlp = require "winhlp"
local parent = term.current()
local frame = term.current()
local tabCount = 0
local allTabs = {}
local tabOrder = {}
local currentTab = nil
local function setTerm(newTerm)
parent = newTerm
local function setTerm(termlike)
frame = termlike
end
local function addTab(tab, orderIdx)
@ -16,8 +16,9 @@ local function addTab(tab, orderIdx)
if isCurrentTab then
currentTab = tab
end
local tw, th = parent.getSize()
tab.window = window.create(parent, 1, 1, tw, th, isCurrentTab)
local tw, th = frame.getSize()
tab.window = window.create(frame, 1, 1, tw, th, isCurrentTab)
tab.setTerm(tab.window)
tab.scrollPos = 1
tab.pageDown = function()
local tw, th = tab.window.getSize()
@ -75,7 +76,7 @@ local function getAllTabs()
end
local function updateSize()
local tw, th = parent.getSize()
local tw, th = frame.getSize()
for name, tab in pairs(allTabs) do
tab.window.reposition(1, 1, tw, th)
end

View file

@ -31,6 +31,7 @@ if update_update() then
download_file("permset.lua")
download_file("winhlp.lua")
download_file("tabview.lua")
download_file("listview.lua")
download_file("requests.lua")
download_file("orders.lua")
download_file("test.lua")

View file

@ -9,7 +9,16 @@ local function contains(window, x, y)
return x >= winX and y >= winY and x-winX < width and y-winY < height
end
local function alignRight(termlike, length)
local tw,th = termlike.getSize()
local x,y = termlike.getCursorPos()
termlike.setCursorPos(math.min(x, tw-length+1))
return math.max(0, tw-length-x)
end
return {
translate=translate,
contains=contains,
alignRight=alignRight,
}