can now use named colors

This commit is contained in:
kepler155c@gmail.com 2020-04-21 22:32:12 -06:00
parent e703c7f7b6
commit 5933f8c40f
42 changed files with 308 additions and 400 deletions

View File

@ -1,7 +1,6 @@
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
local help = _G.help local help = _G.help
UI:configure('Help', ...) UI:configure('Help', ...)
@ -12,11 +11,11 @@ for _,topic in pairs(help.topics()) do
end end
UI:addPage('main', UI.Page { UI:addPage('main', UI.Page {
labelText = UI.Text { UI.Text {
x = 3, y = 2, x = 3, y = 2,
value = 'Search', value = 'Search',
}, },
filter = UI.TextEntry { UI.TextEntry {
x = 10, y = 2, ex = -3, x = 10, y = 2, ex = -3,
limit = 32, limit = 32,
}, },
@ -38,9 +37,7 @@ UI:addPage('main', UI.Page {
elseif event.type == 'grid_select' then elseif event.type == 'grid_select' then
if self.grid:getSelected() then if self.grid:getSelected() then
local name = self.grid:getSelected().name UI:setPage('topic', self.grid:getSelected().name)
UI:setPage('topic', name)
end end
elseif event.type == 'text_change' then elseif event.type == 'text_change' then
@ -57,6 +54,7 @@ UI:addPage('main', UI.Page {
self.grid:update() self.grid:update()
self.grid:setIndex(1) self.grid:setIndex(1)
self.grid:draw() self.grid:draw()
else else
return UI.Page.eventHandler(self, event) return UI.Page.eventHandler(self, event)
end end
@ -64,13 +62,12 @@ UI:addPage('main', UI.Page {
}) })
UI:addPage('topic', UI.Page { UI:addPage('topic', UI.Page {
backgroundColor = colors.black, backgroundColor = 'black',
titleBar = UI.TitleBar { titleBar = UI.TitleBar {
title = 'text', title = 'text',
event = 'back', event = 'back',
}, },
helpText = UI.TextArea { helpText = UI.TextArea {
backgroundColor = colors.black,
x = 2, ex = -1, y = 3, ey = -2, x = 2, ex = -1, y = 3, ey = -2,
}, },
accelerators = { accelerators = {

View File

@ -58,14 +58,14 @@ local page = UI.Page {
}, },
[2] = UI.Tab { [2] = UI.Tab {
tabTitle = 'Output', tabTitle = 'Output',
backgroundColor = colors.black, backgroundColor = 'black',
output = UI.Embedded { output = UI.Embedded {
y = 2, y = 2,
maxScroll = 1000, maxScroll = 1000,
backgroundColor = colors.black, backgroundColor = 'black',
}, },
draw = function(self) draw = function(self)
self:write(1, 1, string.rep('\131', self.width), colors.black, UI.colors.primary) self:write(1, 1, string.rep('\131', self.width), 'black', 'primary')
self:drawChildren() self:drawChildren()
end, end,
}, },
@ -162,7 +162,7 @@ function page:eventHandler(event)
local sz = #value local sz = #value
local pos = self.prompt.entry.pos local pos = self.prompt.entry.pos
self:setPrompt(autocomplete(sandboxEnv, value, self.prompt.entry.pos)) self:setPrompt(autocomplete(sandboxEnv, value, self.prompt.entry.pos))
self.prompt:setPosition(pos + #value - sz) self.prompt:setPosition(pos + #(self.prompt.value or '') - sz)
self.prompt:updateCursor() self.prompt:updateCursor()
elseif event.type == 'device' then elseif event.type == 'device' then
@ -201,7 +201,6 @@ function page:eventHandler(event)
command = nil command = nil
self.grid:setValues(t) self.grid:setValues(t)
self.grid:setIndex(1) self.grid:setIndex(1)
self.grid:adjustWidth()
self:draw() self:draw()
end end
return true return true
@ -248,7 +247,6 @@ function page:setResult(result)
end end
self.grid:setValues(t) self.grid:setValues(t)
self.grid:setIndex(1) self.grid:setIndex(1)
self.grid:adjustWidth()
self:draw() self:draw()
end end

View File

@ -4,7 +4,6 @@ local Socket = require('opus.socket')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
local device = _G.device local device = _G.device
local network = _G.network local network = _G.network
local os = _G.os local os = _G.os
@ -58,7 +57,7 @@ local page = UI.Page {
autospace = true, autospace = true,
getRowTextColor = function(self, row, selected) getRowTextColor = function(self, row, selected)
if not row.active then if not row.active then
return colors.lightGray return 'lightGray'
end end
return UI.Grid.getRowTextColor(self, row, selected) return UI.Grid.getRowTextColor(self, row, selected)
end, end,

View File

@ -10,7 +10,6 @@ local Tween = require('opus.ui.tween')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
local device = _G.device local device = _G.device
local fs = _G.fs local fs = _G.fs
local os = _G.os local os = _G.os
@ -94,8 +93,8 @@ local page = UI.Page {
tabBar = UI.TabBar { tabBar = UI.TabBar {
ey = -2, ey = -2,
width = 8, width = 8,
selectedBackgroundColor = UI.colors.primary, selectedBackgroundColor = 'primary',
backgroundColor = UI.colors.tertiary, backgroundColor = 'tertiary',
layout = function(self) layout = function(self)
self.height = nil self.height = nil
UI.TabBar.layout(self) UI.TabBar.layout(self)
@ -103,7 +102,7 @@ local page = UI.Page {
}, },
tray = UI.Window { tray = UI.Window {
y = -1, width = 8, y = -1, width = 8,
backgroundColor = UI.colors.tertiary, backgroundColor = 'tertiary',
newApp = UI.FlatButton { newApp = UI.FlatButton {
x = 2, x = 2,
text = '+', event = 'new', text = '+', event = 'new',
@ -150,7 +149,7 @@ local page = UI.Page {
text = 'Load', event = 'loadIcon', help = 'Load icon file', text = 'Load', event = 'loadIcon', help = 'Load icon file',
}, },
image = UI.NftImage { image = UI.NftImage {
backgroundColor = colors.black, backgroundColor = 'black',
y = 6, x = 2, height = 3, width = 8, y = 6, x = 2, height = 3, width = 8,
}, },
}, },
@ -330,9 +329,9 @@ function page.container:setCategory(categoryName, animate)
text = program.title, text = program.title,
centered = false, centered = false,
backgroundColor = self:getProperty('backgroundColor'), backgroundColor = self:getProperty('backgroundColor'),
backgroundFocusColor = colors.gray, backgroundFocusColor = 'gray',
textColor = colors.white, textColor = 'white',
textFocusColor = colors.white, textFocusColor = 'white',
event = 'button', event = 'button',
app = program, app = program,
} }
@ -349,9 +348,9 @@ function page.container:setCategory(categoryName, animate)
y = 4, y = 4,
text = title, text = title,
backgroundColor = self:getProperty('backgroundColor'), backgroundColor = self:getProperty('backgroundColor'),
backgroundFocusColor = colors.gray, backgroundFocusColor = 'gray',
textColor = colors.white, textColor = 'white',
textFocusColor = colors.white, textFocusColor = 'white',
width = #title + 2, width = #title + 2,
event = 'button', event = 'button',
app = program, app = program,
@ -590,7 +589,6 @@ function page.editor:eventHandler(event)
elseif event.type == 'focus_change' then elseif event.type == 'focus_change' then
self.statusBar:setStatus(event.focused.help or '') self.statusBar:setStatus(event.focused.help or '')
self.statusBar:draw()
elseif event.type == 'editIcon' then elseif event.type == 'editIcon' then
local filename = '/tmp/editing.nft' local filename = '/tmp/editing.nft'

View File

@ -150,7 +150,6 @@ page = UI.Page {
}) })
end end
self.tabs.properties.grid:setValues(t) self.tabs.properties.grid:setValues(t)
self.tabs.properties.grid:update()
self.tabs.properties.grid:draw() self.tabs.properties.grid:draw()
t = { } t = { }
@ -162,7 +161,6 @@ page = UI.Page {
end end
end end
self.tabs.methodsTab.grid:setValues(t) self.tabs.methodsTab.grid:setValues(t)
self.tabs.methodsTab.grid:update()
self.tabs.methodsTab.grid:draw() self.tabs.methodsTab.grid:draw()
elseif event.type == 'edit_property' then elseif event.type == 'edit_property' then
@ -184,7 +182,7 @@ page = UI.Page {
} }
self.ox = math.max(self.ox + sizing[event.ie.code][1], 1) self.ox = math.max(self.ox + sizing[event.ie.code][1], 1)
self.oy = math.max(self.oy + sizing[event.ie.code][2], 1) self.oy = math.max(self.oy + sizing[event.ie.code][2], 1)
UI.term.device.clear() UI.term:clear()
self:resize() self:resize()
self:draw() self:draw()
end end

View File

@ -2,8 +2,6 @@ local Array = require('opus.array')
local Config = require('opus.config') local Config = require('opus.config')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
local tab = UI.Tab { local tab = UI.Tab {
tabTitle = 'Preferred', tabTitle = 'Preferred',
description = 'Select preferred applications', description = 'Select preferred applications',
@ -25,7 +23,7 @@ local tab = UI.Tab {
}, },
getRowTextColor = function(self, row) getRowTextColor = function(self, row)
if row == self.values[1] then if row == self.values[1] then
return colors.yellow return 'yellow'
end end
return UI.Grid.getRowTextColor(self, row) return UI.Grid.getRowTextColor(self, row)
end, end,

View File

@ -2,8 +2,6 @@ local Ansi = require('opus.ansi')
local Config = require('opus.config') local Config = require('opus.config')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
if _G.http.websocket then if _G.http.websocket then
local config = Config.load('cloud') local config = Config.load('cloud')
@ -29,8 +27,8 @@ if _G.http.websocket then
}, },
labelText = UI.TextArea { labelText = UI.TextArea {
x = 2, ex = -2, y = 5, ey = -4, x = 2, ex = -2, y = 5, ey = -4,
textColor = colors.yellow, textColor = 'yellow',
backgroundColor = colors.black, backgroundColor = 'black',
marginLeft = 1, marginRight = 1, marginTop = 1, marginLeft = 1, marginRight = 1, marginTop = 1,
value = string.format( value = string.format(
[[Use a non-changing cloud key. Note that only a single computer can use this session at one time. [[Use a non-changing cloud key. Note that only a single computer can use this session at one time.

View File

@ -2,8 +2,6 @@ local Security = require('opus.security')
local SHA = require('opus.crypto.sha2') local SHA = require('opus.crypto.sha2')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
return UI.Tab { return UI.Tab {
tabTitle = 'Password', tabTitle = 'Password',
description = 'Wireless network password', description = 'Wireless network password',
@ -26,8 +24,8 @@ return UI.Tab {
}, },
info = UI.TextArea { info = UI.TextArea {
x = 2, ex = -2, y = 5, ey = -4, x = 2, ex = -2, y = 5, ey = -4,
backgroundColor = colors.black, backgroundColor = 'black',
textColor = colors.yellow, textColor = 'yellow',
inactive = true, inactive = true,
marginLeft = 1, marginRight = 1, marginTop = 1, marginLeft = 1, marginRight = 1, marginTop = 1,
value = 'Add a password to enable other computers to connect to this one.', value = 'Add a password to enable other computers to connect to this one.',

View File

@ -1,3 +1,4 @@
local Blit = require('opus.ui.blit')
local Config = require('opus.config') local Config = require('opus.config')
local trace = require('opus.trace') local trace = require('opus.trace')
local Util = require('opus.util') local Util = require('opus.util')
@ -45,6 +46,7 @@ local config = {
Config.load('multishell', config) Config.load('multishell', config)
local _colors = parentTerm.isColor() and config.color or config.standard local _colors = parentTerm.isColor() and config.color or config.standard
local palette = parentTerm.isColor() and Blit.colorPalette or Blit.grayscalePalette
local function redrawMenu() local function redrawMenu()
if not tabsDirty then if not tabsDirty then
@ -205,17 +207,11 @@ end)
kernel.hook('multishell_redraw', function() kernel.hook('multishell_redraw', function()
tabsDirty = false tabsDirty = false
local function write(x, text, bg, fg) local blit = Blit(w, {
parentTerm.setBackgroundColor(bg) bg = _colors.tabBarBackgroundColor,
parentTerm.setTextColor(fg) fg = _colors.textColor,
parentTerm.setCursorPos(x, 1) palette = palette,
parentTerm.write(text) })
end
local bg = _colors.tabBarBackgroundColor
parentTerm.setBackgroundColor(bg)
parentTerm.setCursorPos(1, 1)
parentTerm.clearLine()
local currentTab = kernel.getFocused() local currentTab = kernel.getFocused()
@ -252,21 +248,26 @@ kernel.hook('multishell_redraw', function()
tabX = tabX + tab.width tabX = tabX + tab.width
if tab ~= currentTab then if tab ~= currentTab then
local textColor = tab.isDead and _colors.errorColor or _colors.textColor local textColor = tab.isDead and _colors.errorColor or _colors.textColor
write(tab.sx, tab.title:sub(1, tab.width - 1), blit:write(tab.sx, tab.title:sub(1, tab.width - 1),
_colors.backgroundColor, textColor) _colors.backgroundColor, textColor)
end end
end end
end end
if currentTab then if currentTab then
write(currentTab.sx - 1, if currentTab.sx then
' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ', blit:write(currentTab.sx - 1,
_colors.focusBackgroundColor, _colors.focusTextColor) ' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ',
_colors.focusBackgroundColor, _colors.focusTextColor)
end
if not currentTab.noTerminate then if not currentTab.noTerminate then
write(w, closeInd, _colors.backgroundColor, _colors.focusTextColor) blit:write(w, closeInd, nil, _colors.focusTextColor)
end end
end end
parentTerm.setCursorPos(1, 1)
parentTerm.blit(blit.text, blit.fg, blit.bg)
if currentTab and currentTab.window then if currentTab and currentTab.window then
currentTab.window.restoreCursor() currentTab.window.restoreCursor()
end end

View File

@ -1,3 +1,5 @@
local Util = require('opus.util')
local Array = { } local Array = { }
function Array.filter(it, f) function Array.filter(it, f)
@ -19,4 +21,6 @@ function Array.removeByValue(t, e)
end end
end end
Array.find = Util.find
return Array return Array

View File

@ -1,7 +1,6 @@
local Util = require('opus.util') local Util = require('opus.util')
local fs = _G.fs local fs = _G.fs
local shell = _ENV.shell
local Config = { } local Config = { }
@ -25,23 +24,6 @@ function Config.load(fname, data)
return data return data
end end
function Config.loadWithCheck(fname, data)
local filename = 'usr/config/' .. fname
if not fs.exists(filename) then
Config.load(fname, data)
print()
print('The configuration file has been created.')
print('The file name is: ' .. filename)
print()
_G.printError('Press enter to configure')
_G.read()
shell.run('edit ' .. filename)
end
return Config.load(fname, data)
end
function Config.update(fname, data) function Config.update(fname, data)
local filename = 'usr/config/' .. fname local filename = 'usr/config/' .. fname
Util.writeTable(filename, data) Util.writeTable(filename, data)

View File

@ -24,9 +24,9 @@ function git.list(repository)
local function getContents() local function getContents()
local dataUrl = string.format(TREE_URL, user, repo, branch) local dataUrl = string.format(TREE_URL, user, repo, branch)
local contents, msg = Util.httpGet(dataUrl,TREE_HEADERS) local contents, msg = Util.httpGet(dataUrl, TREE_HEADERS)
if not contents then if not contents then
error(_sformat('Failed to download %s\n%s', dataUrl, msg), 2) error(string.format('Failed to download %s\n%s', dataUrl, msg), 2)
else else
return json.decode(contents) return json.decode(contents)
end end

View File

@ -36,7 +36,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
local maxScroll = 100 local maxScroll = 100
local cx, cy = 1, 1 local cx, cy = 1, 1
local blink = false local blink = false
local bg, fg = parent.getBackgroundColor(), parent.getTextColor() local _bg, _fg = parent.getBackgroundColor(), parent.getTextColor()
win.canvas = Canvas({ win.canvas = Canvas({
x = sx, x = sx,
@ -45,6 +45,8 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
height = h, height = h,
isColor = parent.isColor(), isColor = parent.isColor(),
offy = 0, offy = 0,
bg = _bg,
fg = _fg,
}) })
local function update() local function update()
@ -67,7 +69,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
function win.write(str) function win.write(str)
str = tostring(str) or '' str = tostring(str) or ''
win.canvas:write(cx, cy + win.canvas.offy, str, bg, fg) win.canvas:write(cx, cy + win.canvas.offy, str, win.canvas.bg, win.canvas.fg)
win.setCursorPos(cx + #str, cy) win.setCursorPos(cx + #str, cy)
update() update()
end end
@ -83,7 +85,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
for i = #win.canvas.lines, win.canvas.height + 1, -1 do for i = #win.canvas.lines, win.canvas.height + 1, -1 do
win.canvas.lines[i] = nil win.canvas.lines[i] = nil
end end
win.canvas:clear(bg, fg) win.canvas:clear()
update() update()
end end
@ -93,7 +95,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
end end
function win.clearLine() function win.clearLine()
win.canvas:clearLine(cy + win.canvas.offy, bg, fg) win.canvas:clearLine(cy + win.canvas.offy)
win.setCursorPos(cx, cy) win.setCursorPos(cx, cy)
update() update()
end end
@ -126,7 +128,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
win.isColour = win.isColor win.isColour = win.isColor
function win.setTextColor(c) function win.setTextColor(c)
fg = c win.canvas.fg = c
end end
win.setTextColour = win.setTextColor win.setTextColour = win.setTextColor
@ -146,7 +148,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
win.setPaletteColour = win.setPaletteColor win.setPaletteColour = win.setPaletteColor
function win.setBackgroundColor(c) function win.setBackgroundColor(c)
bg = c win.canvas.bg = c
end end
win.setBackgroundColour = win.setBackgroundColor win.setBackgroundColour = win.setBackgroundColor
@ -160,7 +162,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
local lines = #win.canvas.lines local lines = #win.canvas.lines
for i = 1, n do for i = 1, n do
win.canvas.lines[lines + i] = { } win.canvas.lines[lines + i] = { }
win.canvas:clearLine(lines + i, bg, fg) win.canvas:clearLine(lines + i)
end end
while #win.canvas.lines > maxScroll do while #win.canvas.lines > maxScroll do
table.remove(win.canvas.lines, 1) table.remove(win.canvas.lines, 1)
@ -172,12 +174,12 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
end end
function win.getTextColor() function win.getTextColor()
return fg return win.canvas.fg
end end
win.getTextColour = win.getTextColor win.getTextColour = win.getTextColor
function win.getBackgroundColor() function win.getBackgroundColor()
return bg return win.canvas.bg
end end
win.getBackgroundColour = win.getBackgroundColor win.getBackgroundColour = win.getBackgroundColor
@ -201,7 +203,7 @@ function Terminal.window(parent, sx, sy, w, h, isVisible)
function win.restoreCursor() function win.restoreCursor()
if isVisible then if isVisible then
win.setCursorPos(cx, cy) win.setCursorPos(cx, cy)
win.setTextColor(fg) win.setTextColor(win.canvas.fg)
win.setCursorBlink(blink) win.setCursorBlink(blink)
end end
end end

View File

@ -1,14 +1,13 @@
local Array = require('opus.array') local Array = require('opus.array')
local Blit = require('opus.ui.blit') local Blit = require('opus.ui.blit')
local Canvas = require('opus.ui.canvas')
local class = require('opus.class') local class = require('opus.class')
local Event = require('opus.event') local Event = require('opus.event')
local Input = require('opus.input') local Input = require('opus.input')
local Transition = require('opus.ui.transition') local Transition = require('opus.ui.transition')
local Util = require('opus.util') local Util = require('opus.util')
local Canvas = require('opus.ui.canvas')
local _rep = string.rep local _rep = string.rep
local _sub = string.sub
local colors = _G.colors local colors = _G.colors
local device = _G.device local device = _G.device
local fs = _G.fs local fs = _G.fs
@ -191,11 +190,7 @@ function UI:configure(appName, ...)
end end
if defaults.theme then if defaults.theme then
for k,v in pairs(defaults.theme) do Util.deepMerge(self.theme, defaults.theme)
if self[k] and self[k].defaults then
Util.merge(self[k].defaults, v)
end
end
end end
end end
@ -217,6 +212,9 @@ function UI:generateTheme(filename)
local t = { } local t = { }
local function getName(d) local function getName(d)
if type(d) == 'string' then
return string.format("'%s'", d)
end
for c, n in pairs(colors) do for c, n in pairs(colors) do
if n == d then if n == d then
return 'colors.' .. c return 'colors.' .. c
@ -434,7 +432,6 @@ UI.Window.defaults = {
UIElement = 'Window', UIElement = 'Window',
x = 1, x = 1,
y = 1, y = 1,
-- z = 0, -- eventually...
offx = 0, offx = 0,
offy = 0, offy = 0,
cursorX = 1, cursorX = 1,
@ -771,11 +768,8 @@ function UI.Window:centeredWrite(y, text, bg, fg)
if #text >= self.width then if #text >= self.width then
self:write(1, y, text, bg, fg) self:write(1, y, text, bg, fg)
else else
local space = math.floor((self.width-#text) / 2) local x = math.floor((self.width-#text) / 2) + 1
local filler = _rep(' ', space + 1) self:write(x, y, text, bg, fg)
local str = _sub(filler, 1, space) .. text
str = str .. _sub(filler, self.width - #str + 1)
self:write(1, y, str, bg, fg)
end end
end end
@ -1076,6 +1070,9 @@ function UI.Device:sync()
if self:getCursorBlink() then if self:getCursorBlink() then
self.device.setCursorPos(self.cursorX, self.cursorY) self.device.setCursorPos(self.cursorX, self.cursorY)
if self.isColor then
self.device.setTextColor(colors.orange)
end
self.device.setCursorBlink(true) self.device.setCursorBlink(true)
end end
end end
@ -1117,6 +1114,11 @@ loadComponents()
UI:loadTheme('usr/config/ui.theme') UI:loadTheme('usr/config/ui.theme')
Util.merge(UI.Window.defaults, UI.theme.Window) Util.merge(UI.Window.defaults, UI.theme.Window)
Util.merge(UI.colors, UI.theme.colors) Util.merge(UI.colors, UI.theme.colors)
UI:setDefaultDevice(UI.Device({ device = term.current() })) UI:setDefaultDevice(UI.Device())
for k,v in pairs(UI.colors) do
Canvas.colorPalette[k] = Canvas.colorPalette[v]
Canvas.grayscalePalette[k] = Canvas.grayscalePalette[v]
end
return UI return UI

View File

@ -1,16 +1,91 @@
local class = require('opus.class')
local colors = _G.colors local colors = _G.colors
local _rep = string.rep
local _sub = string.sub
local Blit = class() local Blit = { }
function Blit:init(t, cs) Blit.colorPalette = { }
if type(t) == 'string' then Blit.grayscalePalette = { }
t = Blit.toblit(t, cs or { })
end for n = 1, 16 do
self.text = t.text Blit.colorPalette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n)
self.bg = t.bg Blit.grayscalePalette[2 ^ (n - 1)] = _sub("088888878877787f", n, n)
self.fg = t.fg end
-- default palette
Blit.palette = Blit.colorPalette
function Blit:init(t, args)
if args then
for k,v in pairs(args) do
self[k] = v
end
end
if type(t) == 'string' then
-- create a blit from a string
self.text, self.bg, self.fg = Blit.toblit(t, args or { })
elseif type(t) == 'number' then
-- create a fixed width blit
self.width = t
self.text = _rep(' ', self.width)
self.bg = _rep(self.palette[args.bg], self.width)
self.fg = _rep(self.palette[args.fg], self.width)
else
self.text = t.text
self.bg = t.bg
self.fg = t.fg
end
end
function Blit:write(x, text, bg, fg)
self:insert(x, text,
bg and _rep(self.palette[bg], #text),
fg and _rep(self.palette[fg], #text))
end
function Blit:insert(x, text, bg, fg)
if x <= self.width then
local width = #text
local tx, tex
if x < 1 then
tx = 2 - x
width = width + x - 1
x = 1
end
if x + width - 1 > self.width then
tex = self.width - x + (tx or 1)
width = tex - (tx or 1) + 1
end
if width > 0 then
local function replace(sstr, rstr)
if tx or tex then
rstr = _sub(rstr, tx or 1, tex)
end
if x == 1 and width == self.width then
return rstr
elseif x == 1 then
return rstr .. _sub(sstr, x + width)
elseif x + width > self.width then
return _sub(sstr, 1, x - 1) .. rstr
end
return _sub(sstr, 1, x - 1) .. rstr .. _sub(sstr, x + width)
end
self.text = replace(self.text, text)
if fg then
self.fg = replace(self.fg, fg)
end
if bg then
self.bg = replace(self.bg, bg)
end
end
end
end end
function Blit:sub(s, e) function Blit:sub(s, e)
@ -22,7 +97,6 @@ function Blit:sub(s, e)
end end
function Blit:wrap(max) function Blit:wrap(max)
local index = 1
local lines = { } local lines = { }
local data = self local data = self
@ -31,7 +105,7 @@ function Blit:wrap(max)
table.insert(lines, data) table.insert(lines, data)
break break
elseif data.text:sub(max+1, max+1) == ' ' then elseif data.text:sub(max+1, max+1) == ' ' then
table.insert(lines, data:sub(index, max)) table.insert(lines, data:sub(1, max))
data = data:sub(max + 2) data = data:sub(max + 2)
else else
local x = data.text:sub(1, max) local x = data.text:sub(1, max)
@ -56,18 +130,20 @@ function Blit.toblit(str, cs)
if not cs.cbg then if not cs.cbg then
-- reset colors -- reset colors
cs.rbg = cs.palette[cs.bg or colors.black] cs.rbg = cs.bg or colors.black
cs.rfg = cs.palette[cs.fg or colors.white] cs.rfg = cs.fg or colors.white
-- current colors -- current colors
cs.cbg = cs.rbg cs.cbg = cs.rbg
cs.cfg = cs.rfg cs.cfg = cs.rfg
cs.palette = cs.palette or Blit.palette
end end
str = str:gsub('(.-)\027%[([%d;]+)m', str = str:gsub('(.-)\027%[([%d;]+)m',
function(k, seq) function(k, seq)
text = text .. k text = text .. k
bg = bg .. string.rep(cs.cbg, #k) bg = bg .. string.rep(cs.palette[cs.cbg], #k)
fg = fg .. string.rep(cs.cfg, #k) fg = fg .. string.rep(cs.palette[cs.cfg], #k)
for color in string.gmatch(seq, "%d+") do for color in string.gmatch(seq, "%d+") do
color = tonumber(color) color = tonumber(color)
if color == 0 then if color == 0 then
@ -75,20 +151,24 @@ function Blit.toblit(str, cs)
cs.cfg = cs.rfg cs.cfg = cs.rfg
cs.cbg = cs.rbg cs.cbg = cs.rbg
elseif color > 20 then elseif color > 20 then
cs.cbg = string.sub("0123456789abcdef", color - 21, color - 21) cs.cbg = 2 ^ (color - 21)
else else
cs.cfg = string.sub("0123456789abcdef", color, color) cs.cfg = 2 ^ (color - 1)
end end
end end
return k return k
end) end)
local k = str:sub(#text + 1) local k = str:sub(#text + 1)
return { return text .. k,
text = text .. k, bg .. string.rep(cs.palette[cs.cbg], #k),
bg = bg .. string.rep(cs.cbg, #k), fg .. string.rep(cs.palette[cs.cfg], #k)
fg = fg .. string.rep(cs.cfg, #k),
}
end end
return Blit return setmetatable(Blit, {
__call = function(_, ...)
local obj = setmetatable({ }, { __index = Blit })
obj:init(...)
return obj
end
})

View File

@ -9,16 +9,21 @@ local colors = _G.colors
local Canvas = class() local Canvas = class()
Canvas.colorPalette = { } local function genPalette(map)
Canvas.darkPalette = { } local t = { }
Canvas.grayscalePalette = { } local rcolors = Util.transpose(colors)
for n = 1, 16 do
for n = 1, 16 do local pow = 2 ^ (n - 1)
Canvas.colorPalette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n) local ch = _sub(map, n, n)
Canvas.grayscalePalette[2 ^ (n - 1)] = _sub("088888878877787f", n, n) t[pow] = ch
Canvas.darkPalette[2 ^ (n - 1)] = _sub("8777777f77fff77f", n, n) t[rcolors[pow]] = ch
end
return t
end end
Canvas.colorPalette = genPalette('0123456789abcdef')
Canvas.grayscalePalette = genPalette('088888878877787f')
--[[ --[[
A canvas can have more lines than canvas.height in order to scroll A canvas can have more lines than canvas.height in order to scroll
@ -119,19 +124,12 @@ function Canvas:copy()
end end
function Canvas:addLayer(layer) function Canvas:addLayer(layer)
local canvas = Canvas({ layer.parent = self
x = layer.x,
y = layer.y,
width = layer.width,
height = layer.height,
isColor = self.isColor,
})
canvas.parent = self
if not self.children then if not self.children then
self.children = { } self.children = { }
end end
table.insert(self.children, canvas) table.insert(self.children, 1, layer)
return canvas return layer
end end
function Canvas:removeLayer() function Canvas:removeLayer()
@ -177,54 +175,42 @@ end
function Canvas:blit(x, y, text, bg, fg) function Canvas:blit(x, y, text, bg, fg)
if y > 0 and y <= #self.lines and x <= self.width then if y > 0 and y <= #self.lines and x <= self.width then
local width = #text local width = #text
local tx, tex
-- fix ffs
if x < 1 then if x < 1 then
text = _sub(text, 2 - x) tx = 2 - x
if bg then
bg = _sub(bg, 2 - x)
end
if fg then
fg = _sub(fg, 2 - x)
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 = _sub(text, 1, self.width - x + 1) tex = self.width - x + (tx or 1)
if bg then width = tex - (tx or 1) + 1
bg = _sub(bg, 1, self.width - x + 1)
end
if fg then
fg = _sub(fg, 1, self.width - x + 1)
end
width = #text
end end
if width > 0 then if width > 0 then
local function replace(sstr, rstr)
local function replace(sstr, pos, rstr) if tx or tex then
if pos == 1 and width == self.width then rstr = _sub(rstr, tx or 1, tex)
return rstr
elseif pos == 1 then
return rstr .. _sub(sstr, pos+width)
elseif pos + width > self.width then
return _sub(sstr, 1, pos-1) .. rstr
end end
return _sub(sstr, 1, pos-1) .. rstr .. _sub(sstr, pos+width) if x == 1 and width == self.width then
return rstr
elseif x == 1 then
return rstr .. _sub(sstr, x + width)
elseif x + width > self.width then
return _sub(sstr, 1, x - 1) .. rstr
end
return _sub(sstr, 1, x - 1) .. rstr .. _sub(sstr, x + width)
end end
local line = self.lines[y] local line = self.lines[y]
if line then line.dirty = true
line.dirty = true line.text = replace(line.text, text)
line.text = replace(line.text, x, text, width) if fg then
if fg then line.fg = replace(line.fg, fg)
line.fg = replace(line.fg, x, fg, width) end
end if bg then
if bg then line.bg = replace(line.bg, bg)
line.bg = replace(line.bg, x, bg, width)
end
end end
end end
end end
@ -383,9 +369,6 @@ function Canvas:__renderLayers(device, offset, doubleBuffer)
end end
function Canvas:__blitRect(device, src, tgt, doubleBuffer) function Canvas:__blitRect(device, src, tgt, doubleBuffer)
src = src or { x = 1, y = 1, ex = self.ex - self.x + 1, ey = self.ey - self.y + 1 }
tgt = tgt or self
-- for visualizing updates on the screen -- for visualizing updates on the screen
--[[ --[[
if Canvas.__visualize or self.visualize then if Canvas.__visualize or self.visualize then
@ -426,16 +409,4 @@ function Canvas:__blitRect(device, src, tgt, doubleBuffer)
end end
end end
if not ({ ... })[1] then
local UI = require('opus.ui')
UI:setPage(UI.Page {
button = UI.Button {
x = 5, y = 5,
text = 'abc'
}
})
UI:start()
end
return Canvas return Canvas

View File

@ -2,17 +2,15 @@ local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.Button = class(UI.Window) UI.Button = class(UI.Window)
UI.Button.defaults = { UI.Button.defaults = {
UIElement = 'Button', UIElement = 'Button',
text = 'button', text = 'button',
backgroundColor = colors.lightGray, backgroundColor = 'lightGray',
backgroundFocusColor = colors.gray, backgroundFocusColor = 'gray',
textFocusColor = colors.white, textFocusColor = 'white',
textInactiveColor = colors.gray, textInactiveColor = 'gray',
textColor = colors.black, textColor = 'black',
centered = true, centered = true,
height = 1, height = 1,
focusIndicator = ' ', focusIndicator = ' ',
@ -73,7 +71,7 @@ function UI.Button.example()
}, },
button2 = UI.Button { button2 = UI.Button {
x = 2, y = 4, x = 2, y = 4,
backgroundColor = colors.green, backgroundColor = 'green',
event = 'custom_event', event = 'custom_event',
}, },
button3 = UI.Button { button3 = UI.Button {

View File

@ -1,8 +1,6 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.Checkbox = class(UI.Window) UI.Checkbox = class(UI.Window)
UI.Checkbox.defaults = { UI.Checkbox.defaults = {
UIElement = 'Checkbox', UIElement = 'Checkbox',
@ -11,9 +9,9 @@ UI.Checkbox.defaults = {
leftMarker = UI.extChars and '\124' or '[', leftMarker = UI.extChars and '\124' or '[',
rightMarker = UI.extChars and '\124' or ']', rightMarker = UI.extChars and '\124' or ']',
value = false, value = false,
textColor = colors.white, textColor = 'white',
backgroundColor = colors.black, backgroundColor = 'black',
backgroundFocusColor = colors.lightGray, backgroundFocusColor = 'lightGray',
height = 1, height = 1,
width = 3, width = 3,
accelerators = { accelerators = {

View File

@ -1,8 +1,6 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.Dialog = class(UI.SlideOut) UI.Dialog = class(UI.SlideOut)
UI.Dialog.defaults = { UI.Dialog.defaults = {
UIElement = 'Dialog', UIElement = 'Dialog',
@ -33,7 +31,7 @@ function UI.Dialog.example()
cancelEvent = 'slide_hide', cancelEvent = 'slide_hide',
text = UI.Text { text = UI.Text {
x = 5, y = 1, width = 20, x = 5, y = 1, width = 20,
textColor = colors.gray, textColor = 'gray',
}, },
textEntry = UI.TextEntry { textEntry = UI.TextEntry {
formKey = 'level', formKey = 'level',

View File

@ -2,12 +2,10 @@ local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.DropMenu = class(UI.MenuBar) UI.DropMenu = class(UI.MenuBar)
UI.DropMenu.defaults = { UI.DropMenu.defaults = {
UIElement = 'DropMenu', UIElement = 'DropMenu',
backgroundColor = colors.white, backgroundColor = 'white',
buttonClass = 'DropMenuItem', buttonClass = 'DropMenuItem',
} }
function UI.DropMenu:layout() function UI.DropMenu:layout()

View File

@ -1,16 +1,14 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.DropMenuItem = class(UI.Button) UI.DropMenuItem = class(UI.Button)
UI.DropMenuItem.defaults = { UI.DropMenuItem.defaults = {
UIElement = 'DropMenuItem', UIElement = 'DropMenuItem',
textColor = colors.black, textColor = 'black',
backgroundColor = colors.white, backgroundColor = 'white',
textFocusColor = colors.white, textFocusColor = 'white',
textInactiveColor = colors.lightGray, textInactiveColor = 'lightGray',
backgroundFocusColor = colors.lightGray, backgroundFocusColor = 'lightGray',
} }
function UI.DropMenuItem:eventHandler(event) function UI.DropMenuItem:eventHandler(event)
if event.type == 'button_activate' then if event.type == 'button_activate' then

View File

@ -3,13 +3,11 @@ local Event = require('opus.event')
local Terminal = require('opus.terminal') local Terminal = require('opus.terminal')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.Embedded = class(UI.Window) UI.Embedded = class(UI.Window)
UI.Embedded.defaults = { UI.Embedded.defaults = {
UIElement = 'Embedded', UIElement = 'Embedded',
backgroundColor = colors.black, backgroundColor = 'black',
textColor = colors.white, textColor = 'white',
maxScroll = 100, maxScroll = 100,
accelerators = { accelerators = {
up = 'scroll_up', up = 'scroll_up',

View File

@ -1,13 +1,11 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.FlatButton = class(UI.Button) UI.FlatButton = class(UI.Button)
UI.FlatButton.defaults = { UI.FlatButton.defaults = {
UIElement = 'FlatButton', UIElement = 'FlatButton',
textColor = colors.black, textColor = 'black',
textFocusColor = colors.white, textFocusColor = 'white',
noPadding = true, noPadding = true,
} }
function UI.FlatButton:setParent() function UI.FlatButton:setParent()

View File

@ -2,8 +2,6 @@ local class = require('opus.class')
local Sound = require('opus.sound') local Sound = require('opus.sound')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.Form = class(UI.Window) UI.Form = class(UI.Window)
UI.Form.defaults = { UI.Form.defaults = {
UIElement = 'Form', UIElement = 'Form',
@ -68,7 +66,7 @@ function UI.Form:createForm()
table.insert(self.children, UI.Text { table.insert(self.children, UI.Text {
x = self.margin, x = self.margin,
y = child.y, y = child.y,
textColor = colors.black, textColor = 'black',
width = #child.formLabel, width = #child.formLabel,
value = child.formLabel, value = child.formLabel,
}) })

View File

@ -2,10 +2,8 @@ local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
local os = _G.os local os = _G.os
local _rep = string.rep local _rep = string.rep
local _sub = string.sub
local function safeValue(v) local function safeValue(v)
local t = type(v) local t = type(v)
@ -23,18 +21,7 @@ function Writer:init(element, y)
end end
function Writer:write(s, width, align, bg, fg) function Writer:write(s, width, align, bg, fg)
local len = #tostring(s or '') s = Util.widthify(s, width, align)
if len > width then
s = _sub(s, 1, width)
end
local padding = len < width and _rep(' ', width - len)
if padding then
if align == 'right' then
s = padding .. s
else
s = s .. padding
end
end
self.element:write(self.x, self.y, s, bg, fg) self.element:write(self.x, self.y, s, bg, fg)
self.x = self.x + width self.x = self.x + width
end end
@ -56,16 +43,16 @@ UI.Grid.defaults = {
disableHeader = false, disableHeader = false,
headerHeight = 1, headerHeight = 1,
marginRight = 0, marginRight = 0,
textColor = colors.white, textColor = 'white',
textSelectedColor = colors.white, textSelectedColor = 'white',
backgroundColor = colors.black, backgroundColor = 'black',
backgroundSelectedColor = colors.gray, backgroundSelectedColor = 'gray',
headerBackgroundColor = UI.colors.primary, headerBackgroundColor = 'primary',
headerTextColor = colors.white, headerTextColor = 'white',
headerSortColor = colors.yellow, headerSortColor = 'yellow',
unfocusedTextSelectedColor = colors.white, unfocusedTextSelectedColor = 'white',
unfocusedBackgroundSelectedColor = colors.gray, unfocusedBackgroundSelectedColor = 'gray',
focusIndicator = UI.extChars and '\183' or '>', focusIndicator = UI.extChars and '\26' or '>',
sortIndicator = ' ', sortIndicator = ' ',
inverseSortIndicator = UI.extChars and '\24' or '^', inverseSortIndicator = UI.extChars and '\24' or '^',
values = { }, values = { },
@ -522,7 +509,7 @@ function UI.Grid.example()
values = values, values = values,
columns = { columns = {
{ heading = 'key', key = 'key', width = 6, }, { heading = 'key', key = 'key', width = 6, },
{ heading = 'value', key = 'value', textColor = colors.yellow }, { heading = 'value', key = 'value', textColor = 'yellow' },
}, },
}, },
autospace = UI.Grid { autospace = UI.Grid {

View File

@ -1,15 +1,13 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.MenuBar = class(UI.Window) UI.MenuBar = class(UI.Window)
UI.MenuBar.defaults = { UI.MenuBar.defaults = {
UIElement = 'MenuBar', UIElement = 'MenuBar',
buttons = { }, buttons = { },
height = 1, height = 1,
backgroundColor = UI.colors.secondary, backgroundColor = 'secondary',
textColor = colors.black, textColor = 'black',
spacing = 2, spacing = 2,
lastx = 1, lastx = 1,
buttonClass = 'MenuItem', buttonClass = 'MenuItem',

View File

@ -5,5 +5,5 @@ UI.MenuItem = class(UI.FlatButton)
UI.MenuItem.defaults = { UI.MenuItem.defaults = {
UIElement = 'MenuItem', UIElement = 'MenuItem',
noPadding = false, noPadding = false,
textInactiveColor = colors.gray, textInactiveColor = 'gray',
} }

View File

@ -5,7 +5,7 @@ UI.MiniSlideOut = class(UI.SlideOut)
UI.MiniSlideOut.defaults = { UI.MiniSlideOut.defaults = {
UIElement = 'MiniSlideOut', UIElement = 'MiniSlideOut',
noFill = true, noFill = true,
backgroundColor = UI.colors.primary, backgroundColor = 'primary',
height = 1, height = 1,
} }
function UI.MiniSlideOut:postInit() function UI.MiniSlideOut:postInit()

View File

@ -4,36 +4,34 @@ local Sound = require('opus.sound')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.Notification = class(UI.Window) UI.Notification = class(UI.Window)
UI.Notification.defaults = { UI.Notification.defaults = {
UIElement = 'Notification', UIElement = 'Notification',
backgroundColor = colors.gray, backgroundColor = 'gray',
closeInd = UI.extChars and '\215' or '*', closeInd = UI.extChars and '\215' or '*',
height = 3, height = 3,
timeout = 3, timeout = 3,
anchor = 'bottom', anchor = 'bottom',
} }
function UI.Notification:draw() function UI.Notification.draw()
end end
function UI.Notification:enable() function UI.Notification.enable()
end end
function UI.Notification:error(value, timeout) function UI.Notification:error(value, timeout)
self.backgroundColor = colors.red self.backgroundColor = 'red'
Sound.play('entity.villager.no', .5) Sound.play('entity.villager.no', .5)
self:display(value, timeout) self:display(value, timeout)
end end
function UI.Notification:info(value, timeout) function UI.Notification:info(value, timeout)
self.backgroundColor = colors.lightGray self.backgroundColor = 'lightGray'
self:display(value, timeout) self:display(value, timeout)
end end
function UI.Notification:success(value, timeout) function UI.Notification:success(value, timeout)
self.backgroundColor = colors.green self.backgroundColor = 'green'
self:display(value, timeout) self:display(value, timeout)
end end

View File

@ -2,8 +2,6 @@ local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.Page = class(UI.Window) UI.Page = class(UI.Window)
UI.Page.defaults = { UI.Page.defaults = {
UIElement = 'Page', UIElement = 'Page',
@ -16,8 +14,8 @@ UI.Page.defaults = {
up = 'focus_prev', up = 'focus_prev',
scroll_up = 'focus_prev', scroll_up = 'focus_prev',
}, },
backgroundColor = UI.colors.primary, backgroundColor = 'primary',
textColor = colors.white, textColor = 'white',
} }
function UI.Page:postInit() function UI.Page:postInit()
self.parent = self.parent or UI.term self.parent = self.parent or UI.term

View File

@ -1,35 +1,28 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.ProgressBar = class(UI.Window) UI.ProgressBar = class(UI.Window)
UI.ProgressBar.defaults = { UI.ProgressBar.defaults = {
UIElement = 'ProgressBar', UIElement = 'ProgressBar',
backgroundColor = colors.gray, backgroundColor = 'gray',
height = 1, height = 1,
progressColor = colors.lime, progressColor = 'lime',
progressChar = UI.extChars and '\153' or ' ', progressChar = UI.extChars and '\153' or ' ',
fillChar = ' ', fillChar = ' ',
fillColor = colors.gray, fillColor = 'gray',
textColor = colors.green, textColor = 'green',
value = 0, value = 0,
} }
function UI.ProgressBar:draw() function UI.ProgressBar:draw()
local width = math.ceil(self.value / 100 * self.width) local width = math.ceil(self.value / 100 * self.width)
local filler = string.rep(self.fillChar, self.width) self:fillArea(width + 1, 1, self.width - width, self.height, self.fillChar, nil, self.fillColor)
local progress = string.rep(self.progressChar, width) self:fillArea(1, 1, width, self.height, self.progressChar, self.progressColor)
for i = 1, self.height do
self:write(1, i, filler, nil, self.fillColor)
self:write(1, i, progress, self.progressColor)
end
end end
function UI.ProgressBar.example() function UI.ProgressBar.example()
return UI.ProgressBar { return UI.ProgressBar {
x = 2, ex = -2, y = 2, x = 2, ex = -2, y = 2, height = 2,
focus = function() end, focus = function() end,
enable = function(self) enable = function(self)
require('opus.event').onInterval(.25, function() require('opus.event').onInterval(.25, function()

View File

@ -15,13 +15,13 @@ function UI.Question:postInit()
self.yes_button = UI.Button { self.yes_button = UI.Button {
x = x, x = x,
text = 'Yes', text = 'Yes',
backgroundColor = UI.colors.primary, backgroundColor = 'primary',
event = 'question_yes', event = 'question_yes',
} }
self.no_button = UI.Button { self.no_button = UI.Button {
x = x + 5, x = x + 5,
text = 'No', text = 'No',
backgroundColor = UI.colors.primary, backgroundColor = 'primary',
event = 'question_no', event = 'question_no',
} }
end end

View File

@ -30,7 +30,7 @@ end
function UI.SlideOut:draw() function UI.SlideOut:draw()
if not self.noFill then if not self.noFill then
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), colors.black, colors.gray) self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), 'black', 'gray')
end end
self:drawChildren() self:drawChildren()
end end

View File

@ -2,17 +2,15 @@ local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.Slider = class(UI.Window) UI.Slider = class(UI.Window)
UI.Slider.defaults = { UI.Slider.defaults = {
UIElement = 'Slider', UIElement = 'Slider',
height = 1, height = 1,
barChar = UI.extChars and '\140' or '-', barChar = UI.extChars and '\140' or '-',
barColor = colors.gray, barColor = 'gray',
sliderChar = UI.extChars and '\143' or '\124', sliderChar = UI.extChars and '\143' or '\124',
sliderColor = colors.blue, sliderColor = 'blue',
sliderFocusColor = colors.lightBlue, sliderFocusColor = 'lightBlue',
leftBorder = UI.extChars and '\141' or '\124', leftBorder = UI.extChars and '\141' or '\124',
rightBorder = UI.extChars and '\142' or '\124', rightBorder = UI.extChars and '\142' or '\124',
value = 0, value = 0,

View File

@ -3,13 +3,11 @@ local Event = require('opus.event')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
UI.StatusBar = class(UI.Window) UI.StatusBar = class(UI.Window)
UI.StatusBar.defaults = { UI.StatusBar.defaults = {
UIElement = 'StatusBar', UIElement = 'StatusBar',
backgroundColor = colors.lightGray, backgroundColor = 'lightGray',
textColor = colors.gray, textColor = 'gray',
height = 1, height = 1,
ey = -1, ey = -1,
} }

View File

@ -6,9 +6,9 @@ UI.TabBar = class(UI.MenuBar)
UI.TabBar.defaults = { UI.TabBar.defaults = {
UIElement = 'TabBar', UIElement = 'TabBar',
buttonClass = 'TabBarMenuItem', buttonClass = 'TabBarMenuItem',
backgroundColor = colors.black, backgroundColor = 'black',
selectedBackgroundColor = UI.colors.primary, selectedBackgroundColor = 'primary',
unselectedBackgroundColor = UI.colors.tertiary, unselectedBackgroundColor = 'tertiary',
} }
function UI.TabBar:enable() function UI.TabBar:enable()
UI.MenuBar.enable(self) UI.MenuBar.enable(self)

View File

@ -5,7 +5,7 @@ UI.TabBarMenuItem = class(UI.Button)
UI.TabBarMenuItem.defaults = { UI.TabBarMenuItem.defaults = {
UIElement = 'TabBarMenuItem', UIElement = 'TabBarMenuItem',
event = 'tab_select', event = 'tab_select',
textInactiveColor = colors.lightGray, textInactiveColor = 'lightGray',
} }
function UI.TabBarMenuItem:draw() function UI.TabBarMenuItem:draw()
if self.selected then if self.selected then

View File

@ -14,7 +14,7 @@ function UI.TextArea:setText(text)
self:draw() self:draw()
end end
function UI.TextArea:focus() function UI.TextArea.focus()
-- allow keyboard scrolling -- allow keyboard scrolling
end end
@ -25,6 +25,7 @@ function UI.TextArea:draw()
end end
function UI.TextArea.example() function UI.TextArea.example()
local Ansi = require('opus.ansi')
return UI.Window { return UI.Window {
backgroundColor = 2048, backgroundColor = 2048,
t1 = UI.TextArea { t1 = UI.TextArea {
@ -33,14 +34,16 @@ function UI.TextArea.example()
}, },
t2 = UI.TextArea { t2 = UI.TextArea {
y = 5, y = 5,
value = [[1 backgroundColor = 'green',
value = string.format([[now %%is the %stime %sfor%s all good men to come to the aid of their country.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
3 3
4 4
5 5
6 6
7 7
8]] 8]], Ansi.yellow, Ansi.onred, Ansi.reset),
} }
} }
end end

View File

@ -3,7 +3,6 @@ local entry = require('opus.entry')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors
local _rep = string.rep local _rep = string.rep
local function transform(directive) local function transform(directive)
@ -21,11 +20,11 @@ UI.TextEntry.defaults = {
UIElement = 'TextEntry', UIElement = 'TextEntry',
shadowText = '', shadowText = '',
focused = false, focused = false,
textColor = colors.white, textColor = 'white',
shadowTextColor = colors.gray, shadowTextColor = 'gray',
markBackgroundColor = colors.gray, markBackgroundColor = 'gray',
backgroundColor = colors.black, -- colors.lightGray, backgroundColor = 'black',
backgroundFocusColor = colors.black, --lightGray, backgroundFocusColor = 'black',
height = 1, height = 1,
limit = 6, limit = 6,
cursorBlink = true, cursorBlink = true,

View File

@ -1,39 +1,6 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
local _rep = string.rep
local _sub = string.sub
-- For manipulating text in a fixed width string
local SB = class()
function SB:init(width)
self.width = width
self.buf = _rep(' ', width)
end
function SB:insert(x, str, width)
if x < 1 then
x = self.width + x + 1
end
width = width or #str
if x + width - 1 > self.width then
width = self.width - x
end
if width > 0 then
self.buf = _sub(self.buf, 1, x - 1) .. _sub(str, 1, width) .. _sub(self.buf, x + width)
end
end
function SB:fill(x, ch, width)
width = width or self.width - x + 1
self:insert(x, _rep(ch, width))
end
function SB:center(str)
self:insert(math.max(1, math.ceil((self.width - #str + 1) / 2)), str)
end
function SB:get()
return self.buf
end
UI.TitleBar = class(UI.Window) UI.TitleBar = class(UI.Window)
UI.TitleBar.defaults = { UI.TitleBar.defaults = {
UIElement = 'TitleBar', UIElement = 'TitleBar',
@ -43,15 +10,11 @@ UI.TitleBar.defaults = {
closeInd = UI.extChars and '\215' or '*', closeInd = UI.extChars and '\215' or '*',
} }
function UI.TitleBar:draw() function UI.TitleBar:draw()
local sb = SB(self.width) self:fillArea(2, 1, self.width - 2, 1, self.frameChar)
sb:fill(2, self.frameChar, sb.width - 3) self:centeredWrite(1, string.format(' %s ', self.title))
sb:center(string.format(' %s ', self.title))
if self.previousPage or self.event then if self.previousPage or self.event then
sb:insert(-1, self.closeInd) self:write(self.width - 1, 1, ' ' .. self.closeInd)
else
sb:insert(-2, self.frameChar)
end end
self:write(1, 1, sb:get())
end end
function UI.TitleBar:eventHandler(event) function UI.TitleBar:eventHandler(event)
@ -78,7 +41,7 @@ function UI.TitleBar:eventHandler(event)
self.parent:reposition(self.parent.x, self.anchor.oy + event.dy, self.width, self.anchor.h - d) self.parent:reposition(self.parent.x, self.anchor.oy + event.dy, self.width, self.anchor.h - d)
end end
else --if self.moveable then elseif self.moveable then
local d = event.dy local d = event.dy
if self.anchor.oy + d > 0 and self.anchor.oy + d <= self.parent.parent.height then if self.anchor.oy + d > 0 and self.anchor.oy + d <= self.parent.parent.height then
self.parent:move(self.anchor.ox + event.dx, self.anchor.oy + event.dy) self.parent:move(self.anchor.ox + event.dx, self.anchor.oy + event.dy)
@ -91,9 +54,9 @@ function UI.TitleBar.example()
return UI.Window { return UI.Window {
win1 = UI.Window { win1 = UI.Window {
x = 9, y = 2, ex = -7, ey = -3, x = 9, y = 2, ex = -7, ey = -3,
backgroundColor = colors.green, backgroundColor = 'green',
titleBar = UI.TitleBar { titleBar = UI.TitleBar {
title = 'test', moveable = true, title = 'A really, really, really long title', moveable = true,
}, },
button1 = UI.Button { button1 = UI.Button {
x = 2, y = 3, x = 2, y = 3,
@ -105,9 +68,10 @@ function UI.TitleBar.example()
}, },
win2 = UI.Window { win2 = UI.Window {
x = 7, y = 3, ex = -9, ey = -2, x = 7, y = 3, ex = -9, ey = -2,
backgroundColor = colors.orange, backgroundColor = 'orange',
titleBar = UI.TitleBar { titleBar = UI.TitleBar {
title = 'test', moveable = true, title = 'test', moveable = true,
event = 'none',
}, },
button1 = UI.Button { button1 = UI.Button {
x = 2, y = 3, x = 2, y = 3,

View File

@ -1,13 +1,11 @@
local class = require('opus.class') local class = require('opus.class')
local UI = require('opus.ui') local UI = require('opus.ui')
local colors = _G.colors
UI.VerticalMeter = class(UI.Window) UI.VerticalMeter = class(UI.Window)
UI.VerticalMeter.defaults = { UI.VerticalMeter.defaults = {
UIElement = 'VerticalMeter', UIElement = 'VerticalMeter',
backgroundColor = colors.gray, backgroundColor = 'gray',
meterColor = colors.lime, meterColor = 'lime',
width = 1, width = 1,
value = 0, value = 0,
} }
@ -30,4 +28,4 @@ function UI.VerticalMeter.example()
return UI.VerticalMeter.enable(self) return UI.VerticalMeter.enable(self)
end end
} }
end end

View File

@ -669,42 +669,8 @@ function Util.trimr(s)
end end
-- end http://snippets.luacode.org/?p=snippets/trim_whitespace_from_string_76 -- end http://snippets.luacode.org/?p=snippets/trim_whitespace_from_string_76
-- word wrapping based on: local function wrap(text, max, lines)
-- https://www.rosettacode.org/wiki/Word_wrap#Lua and
-- http://lua-users.org/wiki/StringRecipes
local function paragraphwrap(text, linewidth, res)
linewidth = linewidth or 75
local spaceleft = linewidth
local line = { }
for word in text:gmatch("%S+") do
local len = #word + 1
--if colorMode then
-- word:gsub('()@([@%d])', function(pos, c) len = len - 2 end)
--end
if len > spaceleft then
table.insert(res, table.concat(line, ' '))
line = { word }
spaceleft = linewidth - len - 1
else
table.insert(line, word)
spaceleft = spaceleft - len
end
end
table.insert(res, table.concat(line, ' '))
return table.concat(res, '\n')
end
-- end word wrapping
--[[
-- better wrapping - needs further testing before replacing the current wrapping
functions
local function wrap(text, max)
local index = 1 local index = 1
local lines = { }
repeat repeat
if #text <= max then if #text <= max then
table.insert(lines, text) table.insert(lines, text)
@ -722,14 +688,12 @@ local function wrap(text, max)
until not text or #text == 0 until not text or #text == 0
return lines return lines
end end
]]
function Util.wordWrap(str, limit) function Util.wordWrap(str, limit)
local longLines = Util.split(str)
local lines = { } local lines = { }
for _,line in ipairs(longLines) do for _,line in ipairs(Util.split(str)) do
paragraphwrap(line, limit, lines) wrap(line, limit, lines)
end end
return lines return lines