2023-02-18 22:58:16 +00:00
|
|
|
-- Greenhouse is a simple text scrolling handler for terminal programs.
|
2023-02-18 20:57:27 +00:00
|
|
|
-- The idea is that it can be set a region to do its scrolling and paging
|
|
|
|
-- job and then the user can draw whatever outside it.
|
|
|
|
-- This reduces code duplication for the message viewer
|
|
|
|
-- and flowerbook.
|
|
|
|
|
|
|
|
local ansikit = require 'ansikit'
|
|
|
|
local terminal = require 'terminal'
|
|
|
|
local Object = require 'nature.object'
|
|
|
|
|
|
|
|
local Greenhouse = Object:extend()
|
|
|
|
|
|
|
|
function Greenhouse:new(sink)
|
|
|
|
local size = terminal.size()
|
|
|
|
self.region = size
|
|
|
|
self.start = 1
|
2023-02-18 21:57:03 +00:00
|
|
|
self.offset = 1
|
2023-02-18 20:57:27 +00:00
|
|
|
self.sink = sink
|
2023-02-19 20:53:39 +00:00
|
|
|
self.pages = {}
|
|
|
|
self.curPage = 1
|
2023-02-18 20:57:27 +00:00
|
|
|
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
|
2023-02-19 20:53:39 +00:00
|
|
|
function Greenhouse:addPage(page)
|
|
|
|
table.insert(self.pages, page)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Greenhouse:updateCurrentPage(text)
|
|
|
|
local page = self.pages[self.curPage]
|
|
|
|
page:setText(text)
|
2023-02-18 20:57:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function Greenhouse:draw()
|
2023-02-19 20:53:39 +00:00
|
|
|
local lines = self.pages[self.curPage].lines
|
2023-02-18 20:57:27 +00:00
|
|
|
self.sink:write(ansikit.getCSI(self.start .. ';1', 'H'))
|
2023-02-19 20:53:39 +00:00
|
|
|
self.sink:write(ansikit.getCSI(2, 'J'))
|
2023-02-18 20:57:27 +00:00
|
|
|
|
2023-02-19 20:53:39 +00:00
|
|
|
-- the -2 negate is for the command and status line
|
|
|
|
for i = self.offset, self.offset + (self.region.height - self.start) - 2 do
|
|
|
|
if i > #lines then break end
|
|
|
|
self.sink:writeln('\r' .. lines[i]:gsub('\t', ' '):sub(0, self.region.width - 2))
|
2023-02-18 20:57:27 +00:00
|
|
|
end
|
2023-02-18 22:58:16 +00:00
|
|
|
self.sink:write '\r'
|
2023-02-19 20:53:39 +00:00
|
|
|
|
|
|
|
self.sink:write(ansikit.getCSI(self.region.height - self.start.. ';1', 'H'))
|
|
|
|
self.sink:writeln(string.format('Page %d', self.curPage))
|
2023-02-18 20:57:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function Greenhouse:scroll(direction)
|
2023-02-19 20:53:39 +00:00
|
|
|
local lines = self.pages[self.curPage].lines
|
|
|
|
|
2023-02-18 22:58:44 +00:00
|
|
|
local oldOffset = self.offset
|
2023-02-18 20:57:27 +00:00
|
|
|
if direction == 'down' then
|
2023-02-19 20:53:39 +00:00
|
|
|
self.offset = math.min(self.offset + 1, #lines)
|
2023-02-18 20:57:27 +00:00
|
|
|
elseif direction == 'up' then
|
2023-02-18 21:57:46 +00:00
|
|
|
self.offset = math.max(self.offset - 1, 1)
|
2023-02-18 20:57:27 +00:00
|
|
|
end
|
2023-02-18 22:58:44 +00:00
|
|
|
|
|
|
|
if self.offset ~= oldOffset then self:draw() end
|
2023-02-18 22:58:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function Greenhouse:update()
|
|
|
|
local size = terminal.size()
|
|
|
|
self.region = size
|
|
|
|
|
2023-02-18 20:57:27 +00:00
|
|
|
self:draw()
|
|
|
|
end
|
|
|
|
|
2023-02-19 20:53:39 +00:00
|
|
|
function Greenhouse:next()
|
2023-02-19 21:05:25 +00:00
|
|
|
local oldCurrent = self.curPage
|
2023-02-19 20:53:39 +00:00
|
|
|
self.curPage = math.min(self.curPage + 1, #self.pages)
|
2023-02-19 21:05:25 +00:00
|
|
|
if self.curPage ~= oldCurrent then
|
|
|
|
self.offset = 1
|
|
|
|
self:draw()
|
|
|
|
end
|
2023-02-19 20:53:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function Greenhouse:previous()
|
2023-02-19 21:05:25 +00:00
|
|
|
local oldCurrent = self.curPage
|
2023-02-19 20:53:39 +00:00
|
|
|
self.curPage = math.max(self.curPage - 1, 1)
|
2023-02-19 21:05:25 +00:00
|
|
|
if self.curPage ~= oldCurrent then
|
|
|
|
self.offset = 1
|
|
|
|
self:draw()
|
|
|
|
end
|
2023-02-19 20:53:39 +00:00
|
|
|
end
|
|
|
|
|
2023-02-18 20:57:27 +00:00
|
|
|
return Greenhouse
|