canvas palette

This commit is contained in:
kepler155c@gmail.com 2017-10-06 03:07:24 -04:00
parent f0846c8daa
commit fc69d4be83
8 changed files with 131 additions and 120 deletions

View File

@ -110,10 +110,7 @@ function Terminal.toGrayscale(ct)
local function translate(s) local function translate(s)
if s then if s then
for k,v in pairs(bcolors) do s = _sgsub(s, "%w", bcolors)
s = _sgsub(s, k, v)
end
-- s = _sgsub(s, "%d+", bcolors) -- not working in cc 1.75 ???
end end
return s return s
end end

View File

@ -4,8 +4,8 @@ local Event = require('event')
local Tween = require('ui.tween') local Tween = require('ui.tween')
local Util = require('util') local Util = require('util')
local _srep = string.rep local _rep = string.rep
local _ssub = string.sub local _sub = string.sub
local function safeValue(v) local function safeValue(v)
local t = type(v) local t = type(v)
@ -652,17 +652,23 @@ function UI.Window:setTextScale(textScale)
self.parent:setTextScale(textScale) self.parent:setTextScale(textScale)
end end
function UI.Window:clear(bg) function UI.Window:clear(bg, ...)
self:clearArea(1 + self.offx, 1 + self.offy, self.width, self.height, bg) debug(bg)
debug({...})
if self.canvas then
self.canvas:clear(bg or self.backgroundColor)
else
self:clearArea(1 + self.offx, 1 + self.offy, self.width, self.height, bg)
end
end end
function UI.Window:clearLine(y, bg) function UI.Window:clearLine(y, bg)
self:write(1, y, _srep(' ', self.width), bg) self:write(1, y, _rep(' ', self.width), bg)
end end
function UI.Window:clearArea(x, y, width, height, bg) function UI.Window:clearArea(x, y, width, height, bg)
if width > 0 then if width > 0 then
local filler = _srep(' ', width) local filler = _rep(' ', width)
for i = 0, height - 1 do for i = 0, height - 1 do
self:write(x, y + i, filler, bg) self:write(x, y + i, filler, bg)
end end
@ -689,9 +695,9 @@ function UI.Window:centeredWrite(y, text, bg, fg)
self:write(1, y, text, bg) self:write(1, y, text, bg)
else else
local space = math.floor((self.width-#text) / 2) local space = math.floor((self.width-#text) / 2)
local filler = _srep(' ', space + 1) local filler = _rep(' ', space + 1)
local str = _ssub(filler, 1, space) .. text local str = _sub(filler, 1, space) .. text
str = str .. _ssub(filler, self.width - #str + 1) str = str .. _sub(filler, self.width - #str + 1)
self:write(1, y, str, bg, fg) self:write(1, y, str, bg, fg)
end end
end end
@ -702,15 +708,15 @@ function UI.Window:print(text, bg, fg, indent)
local function nextWord(line, cx) local function nextWord(line, cx)
local result = { line:find("(%w+)", cx) } local result = { line:find("(%w+)", cx) }
if #result > 1 and result[2] > cx then if #result > 1 and result[2] > cx then
return _ssub(line, cx, result[2] + 1) return _sub(line, cx, result[2] + 1)
elseif #result > 0 and result[1] == cx then elseif #result > 0 and result[1] == cx then
result = { line:find("(%w+)", result[2] + 1) } result = { line:find("(%w+)", result[2] + 1) }
if #result > 0 then if #result > 0 then
return _ssub(line, cx, result[1] + 1) return _sub(line, cx, result[1] + 1)
end end
end end
if cx <= #line then if cx <= #line then
return _ssub(line, cx, #line) return _sub(line, cx, #line)
end end
end end
@ -723,9 +729,9 @@ function UI.Window:print(text, bg, fg, indent)
break break
end end
if pos < s then if pos < s then
table.insert(t, _ssub(f, pos, s - 1)) table.insert(t, _sub(f, pos, s - 1))
end end
local seq = _ssub(f, s) local seq = _sub(f, s)
seq = seq:match("\027%[([%d;]+)m") seq = seq:match("\027%[([%d;]+)m")
local e = { } local e = { }
for color in string.gmatch(seq, "%d+") do for color in string.gmatch(seq, "%d+") do
@ -743,7 +749,7 @@ function UI.Window:print(text, bg, fg, indent)
pos = s + #seq + 3 pos = s + #seq + 3
end end
if pos < #f then if pos < #f then
table.insert(t, _ssub(f, pos)) table.insert(t, _sub(f, pos))
end end
return t return t
end end
@ -1031,7 +1037,7 @@ function UI.Device:init(args)
self.isColor = self.device.isColor() self.isColor = self.device.isColor()
self.canvas = Canvas({ self.canvas = Canvas({
x = 1, y = 1, ex = self.width, ey = self.height, x = 1, y = 1, width = self.width, height = self.height,
isColor = self.isColor, isColor = self.isColor,
}) })
self.canvas:clear(self.backgroundColor, self.textColor) self.canvas:clear(self.backgroundColor, self.textColor)
@ -1158,11 +1164,11 @@ end
function UI.StringBuffer:insert(s, width) function UI.StringBuffer:insert(s, width)
local len = #tostring(s or '') local len = #tostring(s or '')
if len > width then if len > width then
s = _ssub(s, 1, width) s = _sub(s, 1, width)
end end
table.insert(self.buffer, s) table.insert(self.buffer, s)
if len < width then if len < width then
table.insert(self.buffer, _srep(' ', width - len)) table.insert(self.buffer, _rep(' ', width - len))
end end
end end
@ -1179,7 +1185,7 @@ local SB = { }
function SB:new(width) function SB:new(width)
return setmetatable({ return setmetatable({
width = width, width = width,
buf = _srep(' ', width) buf = _rep(' ', width)
}, { __index = SB }) }, { __index = SB })
end end
function SB:insert(x, str, width) function SB:insert(x, str, width)
@ -1191,12 +1197,12 @@ function SB:insert(x, str, width)
width = self.width - x width = self.width - x
end end
if width > 0 then if width > 0 then
self.buf = _ssub(self.buf, 1, x - 1) .. _ssub(str, 1, width) .. _ssub(self.buf, x + width) self.buf = _sub(self.buf, 1, x - 1) .. _sub(str, 1, width) .. _sub(self.buf, x + width)
end end
end end
function SB:fill(x, ch, width) function SB:fill(x, ch, width)
width = width or self.width - x + 1 width = width or self.width - x + 1
self:insert(x, _srep(ch, width)) self:insert(x, _rep(ch, width))
end end
function SB:center(str) function SB:center(str)
self:insert(math.max(1, math.ceil((self.width - #str + 1) / 2)), str) self:insert(math.max(1, math.ceil((self.width - #str + 1) / 2)), str)
@ -2015,8 +2021,8 @@ UI.TitleBar = class(UI.Window)
UI.TitleBar.defaults = { UI.TitleBar.defaults = {
UIElement = 'TitleBar', UIElement = 'TitleBar',
height = 1, height = 1,
textColor = colors.lightGray, textColor = colors.white,
backgroundColor = colors.gray, backgroundColor = colors.cyan,
title = '', title = '',
frameChar = '-', frameChar = '-',
closeInd = '*', closeInd = '*',
@ -2646,7 +2652,7 @@ UI.Button.defaults = {
textColor = colors.white, textColor = colors.white,
centered = true, centered = true,
height = 1, height = 1,
focusIndicator = '>', focusIndicator = ' ',
event = 'button_press', event = 'button_press',
accelerators = { accelerators = {
space = 'button_activate', space = 'button_activate',
@ -2675,9 +2681,9 @@ function UI.Button:draw()
fg = self.textFocusColor fg = self.textFocusColor
ind = self.focusIndicator ind = self.focusIndicator
end end
self:clear(bg)
local text = ind .. self.text .. ' ' local text = ind .. self.text .. ' '
if self.centered then if self.centered then
self:clear(bg)
self:centeredWrite(1 + math.floor(self.height / 2), text, bg, fg) self:centeredWrite(1 + math.floor(self.height / 2), text, bg, fg)
else else
self:write(1, 1, Util.widthify(text, self.width), bg, fg) self:write(1, 1, Util.widthify(text, self.width), bg, fg)
@ -3172,7 +3178,14 @@ function UI.Dialog:setParent()
self.y = math.floor((self.parent.height - self.height) / 2) + 1 self.y = math.floor((self.parent.height - self.height) / 2) + 1
end end
function UI.Dialog:disable()
self.previousPage.canvas.palette = self.oldPalette
UI.Page.disable(self)
end
function UI.Dialog:enable(...) function UI.Dialog:enable(...)
self.oldPalette = self.previousPage.canvas.palette
self.previousPage.canvas:applyPalette(Canvas.darkPalette)
self:addTransition('grow') self:addTransition('grow')
UI.Page.enable(self, ...) UI.Page.enable(self, ...)
end end

View File

@ -2,50 +2,41 @@ local class = require('class')
local Region = require('ui.region') local Region = require('ui.region')
local Util = require('util') local Util = require('util')
local _srep = string.rep local _rep = string.rep
local _ssub = string.sub local _sub = string.sub
local _gsub = string.gsub
local mapColorToGray = {
[ colors.white ] = colors.white,
[ colors.orange ] = colors.lightGray,
[ colors.magenta ] = colors.lightGray,
[ colors.lightBlue ] = colors.lightGray,
[ colors.yellow ] = colors.lightGray,
[ colors.lime ] = colors.lightGray,
[ colors.pink ] = colors.lightGray,
[ colors.gray ] = colors.gray,
[ colors.lightGray ] = colors.lightGray,
[ colors.cyan ] = colors.lightGray,
[ colors.purple ] = colors.gray,
[ colors.blue ] = colors.gray,
[ colors.brown ] = colors.gray,
[ colors.green ] = colors.lightGray,
[ colors.red ] = colors.gray,
[ colors.black ] = colors.black,
}
local mapColorToPaint = { }
for n = 1, 16 do
mapColorToPaint[2 ^ (n - 1)] = _ssub("0123456789abcdef", n, n)
end
local mapGrayToPaint = { }
for n = 0, 15 do
local gs = mapColorToGray[2 ^ n]
mapGrayToPaint[2 ^ n] = mapColorToPaint[gs]
end
local Canvas = class() local Canvas = class()
function Canvas:init(args)
Canvas.colorPalette = { }
Canvas.darkPalette = { }
Canvas.grayscalePalette = { }
for n = 1, 16 do
Canvas.colorPalette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n)
Canvas.grayscalePalette[2 ^ (n - 1)] = _sub("088888878877787f", n, n)
Canvas.darkPalette[2 ^ (n - 1)] = _sub("8777777f77fff77f", n, n)
end
function Canvas:init(args)
self.x = 1 self.x = 1
self.y = 1 self.y = 1
self.bg = colors.black
self.fg = colors.white
self.layers = { } self.layers = { }
Util.merge(self, args) Util.merge(self, args)
self.height = self.ey - self.y + 1 self.ex = self.x + self.width - 1
self.width = self.ex - self.x + 1 self.ey = self.y + self.height - 1
if not self.palette then
if self.isColor then
self.palette = Canvas.colorPalette
else
self.palette = Canvas.grayscalePalette
end
end
self.lines = { } self.lines = { }
for i = 1, self.height do for i = 1, self.height do
@ -64,29 +55,25 @@ function Canvas:resize(w, h)
if w ~= self.width then if w ~= self.width then
for i = 1, self.height do for i = 1, self.height do
self.lines[i] = { } self.lines[i] = { dirty = true }
end end
end end
self.ex = self.x + w - 1 self.ex = self.x + w - 1
self.ey = self.y + h - 1 self.ey = self.y + h - 1
self.width = w self.width = w
self.height = h self.height = h
self:dirty()
end
function Canvas:colorToPaintColor(c)
if self.isColor then
return mapColorToPaint[c]
end
return mapGrayToPaint[c]
end end
function Canvas:copy() function Canvas:copy()
local b = Canvas({ x = self.x, y = self.y, ex = self.ex, ey = self.ey }) local b = Canvas({
for i = 1, self.ey - self.y + 1 do x = self.x,
y = self.y,
width = self.width,
height = self.height,
isColor = self.isColor,
})
for i = 1, self.height do
b.lines[i].text = self.lines[i].text b.lines[i].text = self.lines[i].text
b.lines[i].fg = self.lines[i].fg b.lines[i].fg = self.lines[i].fg
b.lines[i].bg = self.lines[i].bg b.lines[i].bg = self.lines[i].bg
@ -96,10 +83,10 @@ end
function Canvas:addLayer(layer, bg, fg) function Canvas:addLayer(layer, bg, fg)
local canvas = Canvas({ local canvas = Canvas({
x = layer.x, x = layer.x,
y = layer.y, y = layer.y,
ex = layer.x + layer.width - 1, width = layer.width,
ey = layer.y + layer.height - 1, height = layer.height,
isColor = self.isColor, isColor = self.isColor,
}) })
canvas:clear(bg, fg) canvas:clear(bg, fg)
@ -129,10 +116,10 @@ end
function Canvas:write(x, y, text, bg, fg) function Canvas:write(x, y, text, bg, fg)
if bg then if bg then
bg = _srep(self:colorToPaintColor(bg), #text) bg = _rep(self.palette[bg], #text)
end end
if fg then if fg then
fg = _srep(self:colorToPaintColor(fg), #text) fg = _rep(self.palette[fg], #text)
end end
self:writeBlit(x, y, text, bg, fg) self:writeBlit(x, y, text, bg, fg)
end end
@ -144,24 +131,24 @@ function Canvas:writeBlit(x, y, text, bg, fg)
-- fix ffs -- fix ffs
if x < 1 then if x < 1 then
text = _ssub(text, 2 - x) text = _sub(text, 2 - x)
if bg then if bg then
bg = _ssub(bg, 2 - x) bg = _sub(bg, 2 - x)
end end
if bg then if bg then
fg = _ssub(fg, 2 - x) fg = _sub(fg, 2 - x)
end end
width = width + x - 1 width = width + x - 1
x = 1 x = 1
end end
if x + width - 1 > self.width then if x + width - 1 > self.width then
text = _ssub(text, 1, self.width - x + 1) text = _sub(text, 1, self.width - x + 1)
if bg then if bg then
bg = _ssub(bg, 1, self.width - x + 1) bg = _sub(bg, 1, self.width - x + 1)
end end
if bg then if bg then
fg = _ssub(fg, 1, self.width - x + 1) fg = _sub(fg, 1, self.width - x + 1)
end end
width = #text width = #text
end end
@ -172,11 +159,11 @@ function Canvas:writeBlit(x, y, text, bg, fg)
if pos == 1 and width == self.width then if pos == 1 and width == self.width then
return rstr return rstr
elseif pos == 1 then elseif pos == 1 then
return rstr .. _ssub(sstr, pos+width) return rstr .. _sub(sstr, pos+width)
elseif pos + width > self.width then elseif pos + width > self.width then
return _ssub(sstr, 1, pos-1) .. rstr return _sub(sstr, 1, pos-1) .. rstr
end end
return _ssub(sstr, 1, pos-1) .. rstr .. _ssub(sstr, pos+width) return _sub(sstr, 1, pos-1) .. rstr .. _sub(sstr, pos+width)
end end
local line = self.lines[y] local line = self.lines[y]
@ -204,11 +191,10 @@ function Canvas:reset()
end end
function Canvas:clear(bg, fg) function Canvas:clear(bg, fg)
local width = self.ex - self.x + 1 local text = _rep(' ', self.width)
local text = _srep(' ', width) fg = _rep(self.palette[fg or self.fg], self.width)
fg = _srep(self:colorToPaintColor(fg), width) bg = _rep(self.palette[bg or self.bg], self.width)
bg = _srep(self:colorToPaintColor(bg), width) for i = 1, self.height do
for i = 1, self.ey - self.y + 1 do
self:writeLine(i, text, fg, bg) self:writeLine(i, text, fg, bg)
end end
end end
@ -293,9 +279,9 @@ function Canvas:blit(device, src, tgt)
if line and line.dirty then if line and line.dirty then
local t, fg, bg = line.text, line.fg, line.bg local t, fg, bg = line.text, line.fg, line.bg
if src.x > 1 or src.ex < self.ex then if src.x > 1 or src.ex < self.ex then
t = _ssub(t, src.x, src.ex) t = _sub(t, src.x, src.ex)
fg = _ssub(fg, src.x, src.ex) fg = _sub(fg, src.x, src.ex)
bg = _ssub(bg, src.x, src.ex) bg = _sub(bg, src.x, src.ex)
end end
--if tgt.y + i > self.ey then -- wrong place to do clipping ?? --if tgt.y + i > self.ey then -- wrong place to do clipping ??
-- break -- break
@ -306,15 +292,31 @@ function Canvas:blit(device, src, tgt)
end end
end end
function Canvas:applyPalette(palette)
local lookup = { }
for n = 1, 16 do
lookup[self.palette[2 ^ (n - 1)]] = palette[2 ^ (n - 1)]
end
for _, l in pairs(self.lines) do
l.fg = _gsub(l.fg, '%w', lookup)
l.bg = _gsub(l.bg, '%w', lookup)
l.dirty = true
end
self.palette = palette
end
function Canvas.convertWindow(win, parent, x, y) function Canvas.convertWindow(win, parent, x, y)
local w, h = win.getSize() local w, h = win.getSize()
win.canvas = Canvas({ win.canvas = Canvas({
x = x, x = x,
y = y, y = y,
ex = x + w - 1, width = w,
ey = y + h - 1, height = h,
isColor = win.isColor(), isColor = win.isColor(),
}) })
@ -326,7 +328,7 @@ function Canvas.convertWindow(win, parent, x, y)
local x, y = win.getCursorPos() local x, y = win.getCursorPos()
win.canvas:write(1, win.canvas:write(1,
y, y,
_srep(' ', win.canvas.width), _rep(' ', win.canvas.width),
win.getBackgroundColor(), win.getBackgroundColor(),
win.getTextColor()) win.getTextColor())
end end

View File

@ -23,7 +23,7 @@ return function(args)
-- rey = args.rey or -3, -- rey = args.rey or -3,
height = args.height, height = args.height,
width = args.width, width = args.width,
title = 'Select file', title = 'Select File',
grid = UI.ScrollingGrid { grid = UI.ScrollingGrid {
x = 2, x = 2,
y = 2, y = 2,

View File

@ -433,7 +433,7 @@ local formWidth = math.max(UI.term.width - 8, 26)
local editor = UI.Dialog { local editor = UI.Dialog {
height = 11, height = 11,
width = formWidth, width = formWidth,
title = 'Edit application', title = 'Edit Application',
form = UI.Form { form = UI.Form {
y = 2, y = 2,
height = 9, height = 9,

View File

@ -494,7 +494,7 @@ local function startup()
if session then if session then
for _,v in pairs(session) do for _,v in pairs(session) do
multishell.openTab(v) --multishell.openTab(v)
end end
end end
@ -505,7 +505,7 @@ local function startup()
end end
-- Begin -- Begin
parentTerm.clear() --parentTerm.clear()
multishell.openTab({ multishell.openTab({
focused = true, focused = true,

View File

@ -1,18 +1,17 @@
-- Loads the Opus environment regardless if the file system is local or not -- Loads the Opus environment regardless if the file system is local or not
local w, h = term.getSize() local w, h = term.getSize()
local str = 'Loading Opus...'
term.setTextColor(colors.white) term.setTextColor(colors.white)
if term.isColor() then if term.isColor() then
term.setBackgroundColor(colors.cyan) term.setBackgroundColor(colors.black)
term.clear() term.clear()
local opus = { local opus = {
'9999900', 'fffff00',
'999907000', 'ffff07000',
'9900770b00 4444', 'ff00770b00 4444',
'99077777444444444', 'ff077777444444444',
'907777744444444444', 'f07777744444444444',
'90000777444444444', 'f0000777444444444',
'070000111744444', '070000111744444',
'777770000', '777770000',
'7777000000', '7777000000',
@ -25,8 +24,8 @@ if term.isColor() then
end end
end end
term.setCursorPos((w - #str) / 2, h) term.setCursorPos((w - 18) / 2, h)
term.write(str) term.write('Loading Opus...')
term.setCursorPos(w, h) term.setCursorPos(w, h)
local GIT_REPO = 'kepler155c/opus/develop' local GIT_REPO = 'kepler155c/opus/develop'

View File

@ -6,7 +6,7 @@
downArrowChar = '\31', downArrowChar = '\31',
}, },
Button = { Button = {
focusIndicator = '\183', --focusIndicator = '\183',
}, },
Grid = { Grid = {
focusIndicator = '\183', focusIndicator = '\183',