transitions and Lua improvements

This commit is contained in:
kepler155c@gmail.com 2016-12-18 14:38:48 -05:00
parent 3fdd7336f1
commit 4435a14ed1
7 changed files with 420 additions and 260 deletions

View File

@ -15,7 +15,7 @@ UI:configure('Lua', ...)
local command = '' local command = ''
local history = History.load('.lua_history', 25) local history = History.load('.lua_history', 25)
local resultsPage = UI.Page({ local page = UI.Page({
menuBar = UI.MenuBar({ menuBar = UI.MenuBar({
buttons = { buttons = {
{ text = 'Local', event = 'local' }, { text = 'Local', event = 'local' },
@ -47,7 +47,7 @@ local resultsPage = UI.Page({
notification = UI.Notification(), notification = UI.Notification(),
}) })
function resultsPage:setPrompt(value, focus) function page:setPrompt(value, focus)
self.prompt:setValue(value) self.prompt:setValue(value)
self.prompt.scroll = 0 self.prompt.scroll = 0
self.prompt:setPosition(#value) self.prompt:setPosition(#value)
@ -59,29 +59,29 @@ function resultsPage:setPrompt(value, focus)
self.prompt:draw() self.prompt:draw()
if focus then if focus then
resultsPage:setFocus(self.prompt) page:setFocus(self.prompt)
end end
end end
function resultsPage:enable() function page:enable()
self:setFocus(self.prompt) self:setFocus(self.prompt)
UI.Page.enable(self) UI.Page.enable(self)
end end
function resultsPage:eventHandler(event) function page:eventHandler(event)
if event.type == 'global' then if event.type == 'global' then
resultsPage:setPrompt('', true) page:setPrompt('', true)
self:executeStatement('getfenv(0)') self:executeStatement('getfenv(0)')
command = nil command = nil
elseif event.type == 'local' then elseif event.type == 'local' then
resultsPage:setPrompt('', true) page:setPrompt('', true)
self:executeStatement('getfenv(1)') self:executeStatement('getfenv(1)')
command = nil command = nil
elseif event.type == 'device' then elseif event.type == 'device' then
resultsPage:setPrompt('device', true) page:setPrompt('device', true)
self:executeStatement('device') self:executeStatement('device')
elseif event.type == 'history_back' then elseif event.type == 'history_back' then
@ -128,7 +128,7 @@ function resultsPage:eventHandler(event)
return true return true
end end
function resultsPage:setResult(result) function page:setResult(result)
local t = { } local t = { }
local function safeValue(v) local function safeValue(v)
@ -169,7 +169,7 @@ function resultsPage:setResult(result)
self:draw() self:draw()
end end
function resultsPage.grid:eventHandler(event) function page.grid:eventHandler(event)
local entry = self:getSelected() local entry = self:getSelected()
@ -199,18 +199,18 @@ function resultsPage.grid:eventHandler(event)
if event.type == 'grid_focus_row' then if event.type == 'grid_focus_row' then
if self.focused then if self.focused then
resultsPage:setPrompt(commandAppend()) page:setPrompt(commandAppend())
end end
elseif event.type == 'grid_select' then elseif event.type == 'grid_select' then
resultsPage:setPrompt(commandAppend(), true) page:setPrompt(commandAppend(), true)
resultsPage:executeStatement(commandAppend()) page:executeStatement(commandAppend())
else else
return UI.Grid.eventHandler(self, event) return UI.Grid.eventHandler(self, event)
end end
return true return true
end end
function resultsPage:rawExecute(s) function page:rawExecute(s)
local fn, m = loadstring("return (" .. s .. ')', 'lua') local fn, m = loadstring("return (" .. s .. ')', 'lua')
if not fn then if not fn then
@ -225,7 +225,7 @@ function resultsPage:rawExecute(s)
return fn, m return fn, m
end end
function resultsPage:executeStatement(statement) function page:executeStatement(statement)
command = statement command = statement
@ -242,6 +242,12 @@ function resultsPage:executeStatement(statement)
end end
end end
UI:setPage(resultsPage) sandboxEnv.args = { ... }
if sandboxEnv.args[1] then
command = 'args[1]'
page:setResult(sandboxEnv.args[1])
end
UI:setPage(page)
Event.pullEvents() Event.pullEvents()
UI.term:reset() UI.term:reset()

View File

@ -75,7 +75,7 @@ local systemPage = UI.Page {
value = 'Label' value = 'Label'
}, },
label = UI.TextEntry { label = UI.TextEntry {
x = 9, y = 2, rex = -12, x = 9, y = 2, rex = -4,
limit = 32, limit = 32,
value = os.getComputerLabel(), value = os.getComputerLabel(),
backgroundFocusColor = colors.black, backgroundFocusColor = colors.black,

View File

@ -212,7 +212,7 @@ function enderChestUnload()
turtle.select(1) turtle.select(1)
turtle.drop(64) turtle.drop(64)
turtle.digDown() turtle.digDown()
end end
end end
@ -246,8 +246,9 @@ function makeWalkableTunnel(action, tpt, pt)
if action ~= 'turn' and not Point.compare(tpt, { x = 0, z = 0 }) then -- not at source if action ~= 'turn' and not Point.compare(tpt, { x = 0, z = 0 }) then -- not at source
if not Point.compare(tpt, pt) then -- not at dest if not Point.compare(tpt, pt) then -- not at dest
local r, block = turtle.inspectUp() local r, block = turtle.inspectUp()
if r and block.name ~= 'minecraft:cobblestone' then if r and not turtle.isTurtleAtSide('top') then
if block.name ~= 'minecraft:chest' then if block.name ~= 'minecraft:cobblestone' and
block.name ~= 'minecraft:chest' then
turtle.digUp() turtle.digUp()
end end
end end
@ -483,7 +484,10 @@ function boreCommand()
turtle.clearMoveCallback() turtle.clearMoveCallback()
-- location is either mined, currently being mined or is the
-- dropoff point for a turtle
if inspect(turtle.getAction('up'), 'minecraft:cobblestone') or if inspect(turtle.getAction('up'), 'minecraft:cobblestone') or
inspect(turtle.getAction('up'), 'minecraft:chest') or
inspect(turtle.getAction('down'), 'minecraft:cobblestone') then inspect(turtle.getAction('down'), 'minecraft:cobblestone') then
return true return true
end end

View File

@ -1,68 +1,144 @@
local resolver, loader local DEFAULT_UPATH = 'https://raw.githubusercontent.com/kepler155c/opus/master/sys/apis'
local PASTEBIN_URL = 'http://pastebin.com/raw'
local GIT_URL = 'https://raw.githubusercontent.com/'
local function resolveFile(filename, dir, lua_path) local function shellSearcher(modname, env, shell)
local fname = modname:gsub('%.', '/') .. '.lua'
if filename:sub(1, 1) == "/" then if shell and type(shell.dir) == 'function' then
if not fs.exists(filename) then local path = shell.resolve(fname)
error('Unable to load: ' .. filename, 2)
end
return filename
end
if dir then
local path = fs.combine(dir, filename)
if fs.exists(path) and not fs.isDir(path) then if fs.exists(path) and not fs.isDir(path) then
return path return loadfile(path, env)
end end
end end
end
if lua_path then local function pathSearcher(modname, env, shell)
for dir in string.gmatch(lua_path, "[^:]+") do local fname = modname:gsub('%.', '/') .. '.lua'
local path = fs.combine(dir, filename)
if fs.exists(path) and not fs.isDir(path) then for dir in string.gmatch(package.path, "[^:]+") do
return path local path = fs.combine(dir, fname)
if fs.exists(path) and not fs.isDir(path) then
return loadfile(path, env)
end
end
end
-- fix broken http get
local syncLocks = { }
local function sync(obj, fn)
local key = tostring(obj)
if syncLocks[key] then
local cos = tostring(coroutine.running())
table.insert(syncLocks[key], cos)
repeat
local _, co = os.pullEvent('sync_lock')
until co == cos
else
syncLocks[key] = { }
end
local s, m = pcall(fn)
local co = table.remove(syncLocks[key], 1)
if co then
os.queueEvent('sync_lock', co)
else
syncLocks[key] = nil
end
if not s then
error(m)
end
end
local function loadUrl(url)
local c
sync(url, function()
local h = http.get(url)
if h then
c = h.readAll()
h.close()
end
end)
if c and #c > 0 then
return c
end
end
-- require('BniCQPVf')
local function pastebinSearcher(modname, env, shell)
if #modname == 8 and not modname:match('%W') then
local url = PASTEBIN_URL .. '/' .. modname
local c = loadUrl(url)
if c then
return load(c, modname, nil, env)
end
end
end
-- require('kepler155c.opus.master.sys.apis.util')
local function gitSearcher(modname, env, shell)
local fname = modname:gsub('%.', '/') .. '.lua'
local _, count = fname:gsub("/", "")
if count >= 3 then
local url = GIT_URL .. '/' .. modname
local c = loadUrl(url)
if c then
return load(c, modname, nil, env)
end
end
end
local function urlSearcher(modname, env, shell)
local fname = modname:gsub('%.', '/') .. '.lua'
if fname:sub(1, 1) ~= '/' then
for entry in string.gmatch(package.upath, "[^;]+") do
local url = entry .. '/' .. fname
local c = loadUrl(url)
if c then
return load(c, modname, nil, env)
end end
end end
end end
error('Unable to load: ' .. filename, 2)
end end
_G.package = {
path = LUA_PATH or 'sys/apis',
upath = LUA_UPATH or DEFAULT_UPATH,
loaders = {
shellSearcher,
pathSearcher,
pastebinSearcher,
gitSearcher,
urlSearcher,
}
}
local function requireWrapper(env) local function requireWrapper(env)
local modules = { } local loaded = { }
return function(filename) return function(modname)
local dir = DIR if loaded[modname] then
if not dir and shell and type(shell.dir) == 'function' then return loaded[modname]
dir = shell.dir()
end end
local fname = resolver(filename:gsub('%.', '/') .. '.lua', for _,searcher in ipairs(package.loaders) do
dir or '', LUA_PATH or '/sys/apis') local fn = searcher(modname, env, shell)
if fn then
local rname = fname:gsub('%/', '.'):gsub('%.lua', '') local module, msg = fn(modname, env)
if not module then
local module = modules[rname] error(msg)
if not module then end
loaded[modname] = module
local f, err = loader(fname, env) return module
if not f then end
error(err)
end
module = f(rname)
modules[rname] = module
end end
error('Unable to find module ' .. modname)
return module
end end
end end
local args = { ... }
resolver = args[1] or resolveFile
loader = args[2] or loadfile
return function(env) return function(env)
setfenv(requireWrapper, env) setfenv(requireWrapper, env)
return requireWrapper(env) return requireWrapper(env)

View File

@ -120,6 +120,18 @@ function Terminal.toGrayscale(ct)
end end
end end
function Terminal.getNullTerm(ct)
local nt = Terminal.copy(ct)
local methods = { 'blit', 'clear', 'clearLine', 'scroll',
'setCursorBlink', 'setCursorPos', 'write' }
for _,v in pairs(methods) do
nt[v] = function() end
end
return nt
end
function Terminal.copy(ot) function Terminal.copy(ot)
local ct = { } local ct = { }
for k,v in pairs(ot) do for k,v in pairs(ot) do

View File

@ -1,6 +1,8 @@
local Util = require('util') local Util = require('util')
local class = require('class') local class = require('class')
local Event = require('event') local Event = require('event')
local Tween = require('tween')
local Region = require('region')
local mapColorToGray = { local mapColorToGray = {
[ colors.white ] = colors.white, [ colors.white ] = colors.white,
@ -21,43 +23,16 @@ local mapColorToGray = {
[ colors.black ] = colors.black, [ colors.black ] = colors.black,
} }
local mapColorToPaint = { local mapColorToPaint = { }
[ colors.white ] = '0', for n = 1, 16 do
[ colors.orange ] = '1', mapColorToPaint[2 ^ (n - 1)] = string.sub("0123456789abcdef", n, n)
[ colors.magenta ] = '2', end
[ colors.lightBlue ] = '3',
[ colors.yellow ] = '4',
[ colors.lime ] = '5',
[ colors.pink ] = '6',
[ colors.gray ] = '7',
[ colors.lightGray ] = '8',
[ colors.cyan ] = '9',
[ colors.purple ] = 'a',
[ colors.blue ] = 'b',
[ colors.brown ] = 'c',
[ colors.green ] = 'd',
[ colors.red ] = 'e',
[ colors.black ] = 'f',
}
local mapGrayToPaint = { local mapGrayToPaint = { }
[ colors.white ] = '0', for n = 0, 15 do
[ colors.orange ] = '8', local gs = mapColorToGray[2 ^ n]
[ colors.magenta ] = '8', mapGrayToPaint[2 ^ n] = mapColorToPaint[gs]
[ colors.lightBlue ] = '8', end
[ colors.yellow ] = '8',
[ colors.lime ] = '8',
[ colors.pink ] = '8',
[ colors.gray ] = '7',
[ colors.lightGray ] = '8',
[ colors.cyan ] = '8',
[ colors.purple ] = '7',
[ colors.blue ] = '7',
[ colors.brown ] = '7',
[ colors.green ] = '8',
[ colors.red ] = '7',
[ colors.black ] = 'f',
}
local function colorToGrayScale(c) local function colorToGrayScale(c)
return mapColorToGray[c] return mapColorToGray[c]
@ -91,24 +66,6 @@ end
--[[-- Top Level Manager --]]-- --[[-- Top Level Manager --]]--
local Manager = class() local Manager = class()
Manager.effect = {
slideLeft = {
type = 'slideLeft',
ticks = 12,
easing = 'outBounce',
},
slideRight = {
type = 'slideRight',
ticks = 12,
easing = 'outBounce',
},
explode = {
type = 'explode',
ticks = 12,
easing = 'outBounce',
},
}
function Manager:init(args) function Manager:init(args)
local control = false local control = false
local shift = false local shift = false
@ -153,7 +110,13 @@ function Manager:init(args)
end) end)
Event.addHandler('mouse_click', function(h, button, x, y) Event.addHandler('mouse_click', function(h, button, x, y)
if self.currentPage then
if button == 1 and shift and control then -- hack
local event = self:pointToChild(self.target, x, y)
multishell.openTab({ path = 'apps/Lua.lua', args = { event.element }, focused = true })
elseif self.currentPage then
if not self.currentPage.parent.device.side then if not self.currentPage.parent.device.side then
self:click(button, x, y) self:click(button, x, y)
end end
@ -411,6 +374,7 @@ function Manager:setPage(pageOrName, ...)
if page == self.currentPage then if page == self.currentPage then
page:draw() page:draw()
else else
local needSync
if self.currentPage then if self.currentPage then
if self.currentPage.focused then if self.currentPage.focused then
self.currentPage.focused.focused = false self.currentPage.focused.focused = false
@ -418,6 +382,8 @@ function Manager:setPage(pageOrName, ...)
end end
self.currentPage:disable() self.currentPage:disable()
page.previousPage = self.currentPage page.previousPage = self.currentPage
else
needSync = true
end end
self.currentPage = page self.currentPage = page
self.currentPage:clear(page.backgroundColor) self.currentPage:clear(page.backgroundColor)
@ -428,7 +394,9 @@ function Manager:setPage(pageOrName, ...)
self.currentPage.focused:focus() self.currentPage.focused:focus()
end end
self:capture(self.currentPage) self:capture(self.currentPage)
page:sync() if needSync then
page:sync() -- first time a page has been set
end
end end
end end
@ -734,6 +702,17 @@ function UI.Window:print(text, bg, fg, indent)
end end
end end
--[[
TODO
local test = "\027[0;1;33mYou tell foo, \"// Test string.\"\027[0;37mbar"
for sequence, text in string.gmatch (test, "\027%[([0-9;]+)m([^\027]+)") do
for ansi in string.gmatch (sequence, "%d+") do
print ("ANSI code: ", ansi)
end -- for
print ("Text: ", text)
end
--]]
local lines = Util.split(text) local lines = Util.split(text)
for k,line in pairs(lines) do for k,line in pairs(lines) do
local lx = 1 local lx = 1
@ -822,13 +801,13 @@ function UI.Window:scrollIntoView()
end end
end end
function UI.Window:setTransition(effect, x, y, width, height) function UI.Window:addTransition(effect, x, y, width, height)
if self.parent then if self.parent then
x = x or 1 x = x or 1
y = y or 1 y = y or 1
width = width or self.width width = width or self.width
height = height or self.height height = height or self.height
self.parent:setTransition(effect, x + self.x, y + self.y - 1, width, height) self.parent:addTransition(effect, x + self.x - 1, y + self.y - 1, width, height)
end end
end end
@ -850,6 +829,144 @@ function UI.Window:eventHandler(event)
return false return false
end end
--[[-- Blit data manipulation --]]--
local Blob = class()
function Blob:init(args)
self.x = 1
self.y = 1
self.lines = { }
Util.merge(self, args)
for i = 1, self.ey - self.y + 1 do
self.lines[i] = { }
end
end
function Blob:copy()
local b = Blob({ x = self.x, y = self.y, ex = self.ex, ey = self.ey })
for i = 1, self.ey - self.y + 1 do
b.lines[i].text = self.lines[i].text
b.lines[i].fg = self.lines[i].fg
b.lines[i].bg = self.lines[i].bg
end
return b
end
function Blob:write(y, text, fg, bg)
self.lines[y].dirty = true
self.lines[y].text = text
self.lines[y].fg = fg
self.lines[y].bg = bg
end
function Blob:reset()
self.region = nil
end
function Blob:punch(rect)
if not self.regions then
self.regions = Region.new(self.x, self.y, self.ex, self.ey)
end
self.regions:subRect(rect.x, rect.y, rect.ex, rect.ey)
end
function Blob:blitClipped(device)
for _,region in ipairs(self.regions.region) do
self:blit(device,
{ x = region[1], y = region[2], ex = region[3], ey = region[4] },
{ x = region[1], y = region[2] })
end
end
function Blob:blit(device, src, tgt)
for i = 0, src.ey - src.y do
local line = self.lines[src.y + i]
local t, fg, bg = line.text, line.fg, line.bg
if src.x > 1 or src.ex < self.ex then
t = t:sub(src.x, src.ex)
fg = fg:sub(src.x, src.ex)
bg = bg:sub(src.x, src.ex)
end
device.setCursorPos(tgt.x, tgt.y + i)
device.blit(t, fg, bg)
end
end
--[[-- TransitionSlideLeft --]]--
UI.TransitionSlideLeft = class()
UI.TransitionSlideLeft.defaults = {
UIElement = 'TransitionSlideLeft',
ticks = 12,
easing = 'outBounce',
}
function UI.TransitionSlideLeft:init(args)
local defaults = UI:getDefaults(UI.TransitionSlideLeft, args)
UI.setProperties(self, defaults)
self.pos = { x = self.ex }
self.tween = Tween.new(self.ticks, self.pos, { x = self.x }, self.easing)
self.lastx = 0
end
function UI.TransitionSlideLeft:update(device, screen, lastScreen)
self.tween:update(1)
local x = math.floor(self.pos.x)
if x ~= self.lastx then
self.lastx = x
lastScreen:blit(device, {
x = self.ex - x + self.x,
y = self.y,
ex = self.ex,
ey = self.ey },
{ x = self.x, y = self.y })
screen:blit(device, {
x = self.x,
y = self.y,
ex = self.ex - x + self.x + 1,
ey = self.ey },
{ x = x, y = self.y })
end
return self.pos.x ~= self.x
end
--[[-- TransitionSlideRight --]]--
UI.TransitionSlideRight = class()
UI.TransitionSlideRight.defaults = {
UIElement = 'TransitionSlideRight',
ticks = 12,
easing = 'outBounce',
}
function UI.TransitionSlideRight:init(args)
local defaults = UI:getDefaults(UI.TransitionSlideLeft, args)
UI.setProperties(self, defaults)
self.pos = { x = self.x }
self.tween = Tween.new(self.ticks, self.pos, { x = self.ex }, self.easing)
self.lastx = 0
end
function UI.TransitionSlideRight:update(device, screen, lastScreen)
self.tween:update(1)
local x = math.floor(self.pos.x)
if x ~= self.lastx then
self.lastx = x
lastScreen:blit(device, {
x = self.x,
y = self.y,
ex = self.ex - x + self.x + 1,
ey = self.ey },
{ x = x, y = self.y })
screen:blit(device, {
x = self.ex - x + self.x,
y = self.y,
ex = self.ex + 1,
ey = self.ey },
{ x = self.x, y = self.y })
end
return self.pos.x ~= self.ex
end
--[[-- Terminal for computer / advanced computer / monitor --]]-- --[[-- Terminal for computer / advanced computer / monitor --]]--
UI.Device = class(UI.Window) UI.Device = class(UI.Window)
UI.Device.defaults = { UI.Device.defaults = {
@ -858,9 +975,7 @@ UI.Device.defaults = {
textColor = colors.white, textColor = colors.white,
textScale = 1, textScale = 1,
effectsEnabled = true, effectsEnabled = true,
lines = { },
} }
function UI.Device:init(args) function UI.Device:init(args)
local defaults = UI:getDefaults(UI.Device) local defaults = UI:getDefaults(UI.Device)
defaults.device = term.current() defaults.device = term.current()
@ -879,6 +994,16 @@ function UI.Device:init(args)
UI.Window.init(self, defaults) UI.Window.init(self, defaults)
self.blob = Blob({
x = 1, y = 1, ex = self.width, ey = self.height
})
for i = 1, self.height do
self.blob:write(i,
string.rep(' ', self.width),
string.rep(colorToPaintColor(self.backgroundColor, self.isColor), self.width),
string.rep(colorToPaintColor(self.textColor, self.isColor), self.width))
end
self.isColor = self.device.isColor() self.isColor = self.device.isColor()
end end
@ -914,131 +1039,74 @@ function UI.Device:reset()
self.device.setCursorPos(1, 1) self.device.setCursorPos(1, 1)
end end
function UI.Device:setTransition(effect, x, y, width, height) function UI.Device:addTransition(effect, x, y, width, height)
if not self.transition then if not self.transitions then
self.transition = effect self.transitions = { }
effect.x = x
effect.y = y
effect.width = width
effect.height = height
for i = y, y + height - 1 do
local line = self.lines[i]
if line then
line.transition = true
end
end
end end
if type(effect) == 'string' then
local c
if effect == 'slideLeft' then
c = UI.TransitionSlideLeft
else
c = UI.TransitionSlideRight
end
effect = c {
x = x,
y = y,
ex = x + width - 1,
ey = y + height - 1,
}
end
table.insert(self.transitions, effect)
end end
function UI.Device:runTransition(effect) function UI.Device:runTransitions(transitions)
if not self.Tween then for _,t in ipairs(transitions) do
self.Tween = require('tween') self.blob:punch(t) -- punch out the effect areas
end end
self.blob:blitClipped(self.device) -- and blit the remainder
self.blob:reset()
if effect.type == 'slideLeft' or effect.type == 'slideRight' then while true do
for y, line in ipairs(self.lines) do for _,k in ipairs(Util.keys(transitions)) do
if not line.transition then local transition = transitions[k]
self.device.setCursorPos(1, y) if not transition:update(self.device, self.blob, self.lastScreen) then
self.device.blit(line.text, line.fg, line.bg) transitions[k] = nil
end end
end end
if Util.empty(transitions) then
local pos = { x = 1 } break
local tween = self.Tween.new(effect.ticks, pos, { x = self.width }, effect.easing) end
Event.sleep()
local lastx = 0
repeat
tween:update(1)
local x = math.floor(pos.x)
if x ~= lastx then
lastx = x
for y, line in pairs(self.lines) do
if line.transition then
if effect.type == 'slideLeft' then
local text = self.lastScreen[y].text .. line.text
local bg = self.lastScreen[y].bg .. line.bg
local fg = self.lastScreen[y].fg .. line.fg
self.device.setCursorPos(1 - x, y)
self.device.blit(text, fg, bg)
else
local text = line.text .. self.lastScreen[y].text
local bg = line.bg .. self.lastScreen[y].bg
local fg = line.fg .. self.lastScreen[y].fg
self.device.setCursorPos(-self.width + x + 1, y)
self.device.blit(text, fg, bg)
end
end
end
end
os.sleep()
until pos.x == self.width
elseif effect.type == 'explode' then
local pos = { x = 1 }
local tween = self.Tween.new(effect.ticks, pos, { x = 100 }, effect.easing)
local mx = math.floor(effect.width / 2)
local my = math.floor(effect.height / 2)
local function replace(sstr, pos, rstr, width)
return sstr:sub(1, pos-1) .. rstr .. sstr:sub(pos+width)
end
debug('running')
repeat
tween:update(1)
local ux = math.floor(effect.width * pos.x / 200)
local uy = math.floor(effect.height * pos.x / 200)
local width = ux * 2
local sx = mx - ux + 1
debug({ pos.x, ux, uy })
for y = my - uy, my + uy do
local line = self.lines[y]
if line then
self.device.setCursorPos(1, y)
self.device.blit(
replace(self.lastScreen[y].text, sx, line.text:sub(sx, sx + width - 1), width),
replace(self.lastScreen[y].fg, sx, line.fg:sub(sx, sx + width - 1), width),
replace(self.lastScreen[y].bg, sx, line.bg:sub(sx, sx + width - 1), width))
end
end
os.sleep(.4)
until pos.x == 100
debug('done running')
end
for y, line in ipairs(self.lines) do
line.dirty = false
line.transition = false
end end
end end
function UI.Device:sync() function UI.Device:sync()
local transition local transitions
if self.transition and self.effectsEnabled then if self.transitions and self.effectsEnabled then
for y, line in pairs(self.lines) do transitions = self.transitions
if line.dirty then self.transitions = nil
transition = self.transition
break
end
end
self.transition = nil
end end
if transition then if transitions then
self:runTransition(transition) self:runTransitions(transitions)
else else
for y, line in pairs(self.lines) do for y, line in pairs(self.blob.lines) do
if line.dirty then if line.dirty then
self.device.setCursorPos(1, y) self.device.setCursorPos(1, y)
self.device.blit(line.text, line.fg, line.bg) self.device.blit(line.text, line.fg, line.bg)
line.dirty = false
end end
end end
end end
self.lastScreen = Util.deepCopy(self.lines) self.lastScreen = self.blob:copy()
for y, line in ipairs(self.blob.lines) do
line.dirty = false
end
if self:getCursorBlink() then if self:getCursorBlink() then
self.device.setCursorPos(self.cursorX, self.cursorY) self.device.setCursorPos(self.cursorX, self.cursorY)
@ -1049,14 +1117,6 @@ function UI.Device:write(x, y, text, bg, tc)
if y > 0 and y <= self.height and x <= self.width then if y > 0 and y <= self.height and x <= self.width then
if not self.lines[y] then
self.lines[y] = {
text = string.rep(' ', self.width),
bg = string.rep(colorToPaintColor(self.backgroundColor, self.isColor), self.width),
fg = string.rep(colorToPaintColor(self.textColor, self.isColor), self.width),
}
end
local width = #text local width = #text
if x < 1 then if x < 1 then
@ -1080,7 +1140,7 @@ function UI.Device:write(x, y, text, bg, tc)
return sstr:sub(1, pos-1) .. string.rep(rstr, width) .. sstr:sub(pos+width) return sstr:sub(1, pos-1) .. string.rep(rstr, width) .. sstr:sub(pos+width)
end end
local line = self.lines[y] local line = self.blob.lines[y]
line.dirty = true line.dirty = true
line.text = replace(line.text, x, text, width) line.text = replace(line.text, x, text, width)
if bg then if bg then
@ -2113,9 +2173,9 @@ function UI.Tabs:eventHandler(event)
for _,tab in ipairs(self.children) do for _,tab in ipairs(self.children) do
if tab ~= self.tabBar then if tab ~= self.tabBar then
if event.current > event.last then if event.current > event.last then
tab:setTransition(UI.effect.slideLeft) tab:addTransition('slideLeft')
else else
tab:setTransition(UI.effect.slideRight) tab:addTransition('slideRight')
end end
break break
end end
@ -2145,7 +2205,7 @@ function UI.WindowScroller:nextChild()
for i = 1, #self.children do for i = 1, #self.children do
if self.children[i].enabled then if self.children[i].enabled then
if i < #self.children then if i < #self.children then
self:setTransition(UI.effect.slideLeft) self:addTransition('slideLeft')
self.children[i]:disable() self.children[i]:disable()
self.children[i + 1]:enable() self.children[i + 1]:enable()
end end
@ -2158,7 +2218,7 @@ function UI.WindowScroller:prevChild()
for i = 1, #self.children do for i = 1, #self.children do
if self.children[i].enabled then if self.children[i].enabled then
if i - 1 > 0 then if i - 1 > 0 then
self:setTransition(UI.effect.slideRight) self:addTransition('slideRight')
self.children[i]:disable() self.children[i]:disable()
self.children[i - 1]:enable() self.children[i - 1]:enable()
end end

View File

@ -457,28 +457,30 @@ end
local function getopt( arg, options ) local function getopt( arg, options )
local tab = {} local tab = {}
for k, v in ipairs(arg) do for k, v in ipairs(arg) do
if string.sub( v, 1, 2) == "--" then if type(v) == 'string' then
local x = string.find( v, "=", 1, true ) if string.sub( v, 1, 2) == "--" then
if x then tab[ string.sub( v, 3, x-1 ) ] = string.sub( v, x+1 ) local x = string.find( v, "=", 1, true )
else tab[ string.sub( v, 3 ) ] = true if x then tab[ string.sub( v, 3, x-1 ) ] = string.sub( v, x+1 )
end else tab[ string.sub( v, 3 ) ] = true
elseif string.sub( v, 1, 1 ) == "-" then end
local y = 2 elseif string.sub( v, 1, 1 ) == "-" then
local l = string.len(v) local y = 2
local jopt local l = string.len(v)
while ( y <= l ) do local jopt
jopt = string.sub( v, y, y ) while ( y <= l ) do
if string.find( options, jopt, 1, true ) then jopt = string.sub( v, y, y )
if y < l then if string.find( options, jopt, 1, true ) then
tab[ jopt ] = string.sub( v, y+1 ) if y < l then
y = l tab[ jopt ] = string.sub( v, y+1 )
else y = l
tab[ jopt ] = arg[ k + 1 ] else
end tab[ jopt ] = arg[ k + 1 ]
else end
tab[ jopt ] = true else
tab[ jopt ] = true
end
y = y + 1
end end
y = y + 1
end end
end end
end end