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

View file

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

View file

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

View file

@ -31,6 +31,7 @@ if update_update() then
download_file("permset.lua") download_file("permset.lua")
download_file("winhlp.lua") download_file("winhlp.lua")
download_file("tabview.lua") download_file("tabview.lua")
download_file("listview.lua")
download_file("requests.lua") download_file("requests.lua")
download_file("orders.lua") download_file("orders.lua")
download_file("test.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 return x >= winX and y >= winY and x-winX < width and y-winY < height
end 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 { return {
translate=translate, translate=translate,
contains=contains, contains=contains,
alignRight=alignRight,
} }