transition to kernel
This commit is contained in:
@@ -1,38 +1,227 @@
|
||||
local colors = _G.colors
|
||||
local term = _G.term
|
||||
local _gsub = string.gsub
|
||||
local _rep = string.rep
|
||||
local _sub = string.sub
|
||||
|
||||
local Terminal = { }
|
||||
|
||||
function Terminal.scrollable(win, parent)
|
||||
local w, h = win.getSize()
|
||||
local _, ph = parent.getSize()
|
||||
-- add scrolling functions to a window
|
||||
function Terminal.scrollable(win, maxScroll)
|
||||
local lines = { }
|
||||
local scrollPos = 0
|
||||
local scp = win.setCursorPos
|
||||
local oblit, oreposition = win.blit, win.reposition
|
||||
|
||||
win.setCursorPos = function(x, y)
|
||||
_G._p = y
|
||||
if y > scrollPos + ph then
|
||||
win.scrollTo(y - ph)
|
||||
local palette = { }
|
||||
for n = 1, 16 do
|
||||
palette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n)
|
||||
end
|
||||
|
||||
maxScroll = maxScroll or 100
|
||||
|
||||
-- should only do if window is visible...
|
||||
local function redraw()
|
||||
local _, h = win.getSize()
|
||||
local x, y = win.getCursorPos()
|
||||
for i = 1, h do
|
||||
local line = lines[i + scrollPos]
|
||||
if line and line.dirty then
|
||||
win.setCursorPos(1, i)
|
||||
oblit(line.text, line.fg, line.bg)
|
||||
line.dirty = false
|
||||
end
|
||||
end
|
||||
scp(x, y)
|
||||
win.setCursorPos(x, y)
|
||||
end
|
||||
|
||||
win.scrollUp = function()
|
||||
win.scrollTo(scrollPos - 1)
|
||||
end
|
||||
local function scrollTo(p, forceRedraw)
|
||||
local _, h = win.getSize()
|
||||
local ms = #lines - h -- max scroll
|
||||
p = math.min(math.max(p, 0), ms) -- normalize
|
||||
|
||||
win.scrollDown = function()
|
||||
win.scrollTo(scrollPos + 1)
|
||||
end
|
||||
|
||||
win.scrollTo = function(p)
|
||||
p = math.min(math.max(p, 0), h - ph)
|
||||
if p ~= scrollPos then
|
||||
if p ~= scrollPos or forceRedraw then
|
||||
scrollPos = p
|
||||
win.reposition(1, -scrollPos + 1, w, h)
|
||||
for _, line in pairs(lines) do
|
||||
line.dirty = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function win.write(text)
|
||||
local _, h = win.getSize()
|
||||
|
||||
scrollTo(#lines - h)
|
||||
win.blit(tostring(text),
|
||||
_rep(palette[win.getTextColor()], #text),
|
||||
_rep(palette[win.getBackgroundColor()], #text))
|
||||
local x, y = win.getCursorPos()
|
||||
win.setCursorPos(x + #text, y)
|
||||
end
|
||||
|
||||
function win.clearLine()
|
||||
local w, h = win.getSize()
|
||||
local _, y = win.getCursorPos()
|
||||
|
||||
scrollTo(#lines - h)
|
||||
lines[y + scrollPos] = {
|
||||
text = _rep(' ', w),
|
||||
fg = _rep(palette[win.getTextColor()], w),
|
||||
bg = _rep(palette[win.getBackgroundColor()], w),
|
||||
dirty = true,
|
||||
}
|
||||
redraw()
|
||||
end
|
||||
|
||||
function win.blit(text, fg, bg)
|
||||
local x, y = win.getCursorPos()
|
||||
local w, h = win.getSize()
|
||||
|
||||
if y > 0 and y <= h and x <= w then
|
||||
local width = #text
|
||||
|
||||
-- fix ffs
|
||||
if x < 1 then
|
||||
text = _sub(text, 2 - x)
|
||||
if bg then
|
||||
bg = _sub(bg, 2 - x)
|
||||
end
|
||||
if bg then
|
||||
fg = _sub(fg, 2 - x)
|
||||
end
|
||||
width = width + x - 1
|
||||
x = 1
|
||||
end
|
||||
|
||||
if x + width - 1 > w then
|
||||
text = _sub(text, 1, w - x + 1)
|
||||
if bg then
|
||||
bg = _sub(bg, 1, w - x + 1)
|
||||
end
|
||||
if bg then
|
||||
fg = _sub(fg, 1, w - x + 1)
|
||||
end
|
||||
width = #text
|
||||
end
|
||||
|
||||
if width > 0 then
|
||||
local function replace(sstr, pos, rstr)
|
||||
if pos == 1 and width == w then
|
||||
return rstr
|
||||
elseif pos == 1 then
|
||||
return rstr .. _sub(sstr, pos+width)
|
||||
elseif pos + width > w then
|
||||
return _sub(sstr, 1, pos-1) .. rstr
|
||||
end
|
||||
return _sub(sstr, 1, pos-1) .. rstr .. _sub(sstr, pos+width)
|
||||
end
|
||||
|
||||
local line = lines[y + scrollPos]
|
||||
line.dirty = true
|
||||
line.text = replace(line.text, x, text, width)
|
||||
if fg then
|
||||
line.fg = replace(line.fg, x, fg, width)
|
||||
end
|
||||
if bg then
|
||||
line.bg = replace(line.bg, x, bg, width)
|
||||
end
|
||||
end
|
||||
end
|
||||
redraw()
|
||||
end
|
||||
|
||||
function win.clear()
|
||||
local w, h = win.getSize()
|
||||
|
||||
local text = _rep(' ', w)
|
||||
local fg = _rep(palette[win.getTextColor()], w)
|
||||
local bg = _rep(palette[win.getBackgroundColor()], w)
|
||||
lines = { }
|
||||
for y = 1, h do
|
||||
lines[y] = {
|
||||
dirty = true,
|
||||
text = text,
|
||||
fg = fg,
|
||||
bg = bg,
|
||||
}
|
||||
end
|
||||
scrollPos = 0
|
||||
redraw()
|
||||
end
|
||||
|
||||
-- doesn't support negative scrolling...
|
||||
function win.scroll(n)
|
||||
local w = win.getSize()
|
||||
|
||||
for _ = 1, n do
|
||||
lines[#lines + 1] = {
|
||||
text = _rep(' ', w),
|
||||
fg = _rep(palette[win.getTextColor()], w),
|
||||
bg = _rep(palette[win.getBackgroundColor()], w),
|
||||
}
|
||||
end
|
||||
|
||||
while #lines > maxScroll do
|
||||
table.remove(lines, 1)
|
||||
end
|
||||
|
||||
scrollTo(maxScroll, true)
|
||||
redraw()
|
||||
end
|
||||
|
||||
function win.scrollUp()
|
||||
scrollTo(scrollPos - 1)
|
||||
redraw()
|
||||
end
|
||||
|
||||
function win.scrollDown()
|
||||
scrollTo(scrollPos + 1)
|
||||
redraw()
|
||||
end
|
||||
|
||||
function win.reposition(x, y, nw, nh)
|
||||
local w, h = win.getSize()
|
||||
local D = (nh or h) - h
|
||||
|
||||
if D > 0 then
|
||||
for _ = 1, D do
|
||||
lines[#lines + 1] = {
|
||||
text = _rep(' ', w),
|
||||
fg = _rep(palette[win.getTextColor()], w),
|
||||
bg = _rep(palette[win.getBackgroundColor()], w),
|
||||
}
|
||||
end
|
||||
elseif D < 0 then
|
||||
for _ = D, -1 do
|
||||
lines[#lines] = nil
|
||||
end
|
||||
end
|
||||
return oreposition(x, y, nw, nh)
|
||||
end
|
||||
|
||||
win.clear()
|
||||
end
|
||||
|
||||
-- get windows contents
|
||||
function Terminal.getContents(win, parent)
|
||||
local oblit, oscp = parent.blit, parent.setCursorPos
|
||||
local lines = { }
|
||||
|
||||
parent.blit = function(text, fg, bg)
|
||||
lines[#lines + 1] = {
|
||||
text = text,
|
||||
fg = fg,
|
||||
bg = bg,
|
||||
}
|
||||
end
|
||||
parent.setCursorPos = function() end
|
||||
|
||||
win.setVisible(true)
|
||||
win.redraw()
|
||||
|
||||
parent.blit = oblit
|
||||
parent.setCursorPos = oscp
|
||||
|
||||
return lines
|
||||
end
|
||||
|
||||
function Terminal.toGrayscale(ct)
|
||||
|
||||
Reference in New Issue
Block a user