ListView = { backingList = {}, length = 0, paginationPos = 1, frame = term.current(), drawEntry = nil, } function ListView:new(o) o = o or {} setmetatable(o, self) self.__index = self return o end function ListView:redrawEntry(idx) local tw, th = self.frame.getSize() if idx >= self.paginationPos and idx-self.paginationPos <= th then self.frame.setCursorPos(1, idx-self.paginationPos+1) if self.drawEntry then self.drawEntry(self.frame, self.backingList[idx]) else self.frame.setBackgroundColor(colors.red) self.frame.clearLine() self.frame.setBackgroundColor(colors.black) end end end function ListView:itemAt(idx) return self.backingList[idx] end function ListView:updateItemAt(idx, item) self.backingList[idx] = item if idx > self.length then self.length = idx end self:redrawEntry(idx) end function ListView:clearFrom(idx) local tw, th = self.frame.getSize() for j = self.length, idx, -1 do self.backingList[j] = nil end self.length = idx-1 for y = idx-self.paginationPos+1, th, 1 do self.frame.setCursorPos(1, y) self.frame.clearLine() end end function ListView:redraw() if self.drawEntry then local tw, th = self.frame.getSize() local backingIdx = self.paginationPos for idx = 1, th, 1 do self.frame.setCursorPos(1, idx) if self.backingList[backingIdx] == nil then self.frame.clearLine() else self.drawEntry(self.frame, self.backingList[backingIdx]) end backingIdx = backingIdx + 1 end else self.frame.setBackgroundColor(colors.red) self.frame.clear() self.frame.setBackgroundColor(colors.black) end end function ListView:updatePage(scrollPos) if scrollPos ~= self.paginationPos then self.paginationPos = scrollPos self:redraw() end end function ListView:updatePartial(filter) if self.drawEntry then local tw, th = self.frame.getSize() local backingIdx = self.paginationPos for idx = 1, th, 1 do self.frame.setCursorPos(1, idx) if self.backingList[backingIdx] ~= nil and filter(self.backingList[backingIdx]) then self.self.drawEntry(self.self.frame, self.backingList[backingIdx]) end backingIdx = backingIdx + 1 end end end return ListView