1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-23 10:58:06 +11:00

Optimize Icecap Nexus

The things I have to destroy, the joy in it!
For all I remove the more I save, the better it is!
Perfection is when there is nothing to take away, and I revel in this task.
This commit is contained in:
20kdc 2018-04-25 22:57:25 +01:00
parent a22ac86b2d
commit 921425ada4
4 changed files with 185 additions and 240 deletions

View File

@ -26,72 +26,41 @@ local function addOnReg(p, f)
table.insert(onReg[p], f)
end
local function resumeWF(...)
local ok, e = coroutine.resume(...)
if not ok then
e = tostring(e)
neo.emergency(e)
nexus.startDialog(e, "ice")
end
return ok, e
end
nexus = {
createNexusThread = function (f, ...)
local t = coroutine.create(f)
local ok, cbi = resumeWF(t, ...)
if not ok then return end
local early = neo.requestAccess("x.neo.pub.window", theEventHandler)
if early then
local r = onReg["x.neo.pub.window"]
-- r should not be nil here
onReg["x.neo.pub.window"] = nil
for k, v in ipairs(r) do
v()
end
end
return function ()
local r = onReg["x.neo.pub.window"]
if not r then return end
for k, v in ipairs(r) do
if v == cbi then
table.remove(r, k)
return
end
end
end
end,
create = function (w, h, t)
local thr = coroutine.running()
create = function (w, h, t, c)
local function cb()
coroutine.resume(thr, neo.requestAccess("x.neo.pub.window"))
local e = neo.requestAccess("x.neo.pub.window", theEventHandler)
if e then
if onReg["x.neo.pub.window"] then
neo.emergency("icecap nexus prereg issue")
theEventHandler("k.registration", "x.neo.pub.window")
end
local dw = e(w, h, t)
c(dw)
everestWindows[dw.id] = function (...)
return c(dw, ...)
end
return true
end
end
if not cb() then
addOnReg("x.neo.pub.window", cb)
end
addOnReg("x.neo.pub.window", cb)
local everest = coroutine.yield(cb)
local dw = everest(w, h, title)
everestWindows[dw.id] = thr
return dw
end,
windows = everestWindows,
startDialog = function (tx, ti)
local fmt = require("fmttext")
local txl = fmt.fmtText(unicode.safeTextFormat(tx), 40)
fmt = nil
nexus.createNexusThread(function ()
local w = nexus.create(40, #txl, ti)
while true do
local ev, a = coroutine.yield()
if ev == "line" then
w.span(1, a, txl[a], 0xFFFFFF, 0)
elseif ev == "close" then
w.close()
return
local txl = require("fmttext").fmtText(unicode.safeTextFormat(tx), 40)
nexus.create(40, #txl, ti, function (w, ev, a)
if ev == "line" then
if not pcall(w.span, 1, a, txl[a], 0xFFFFFF, 0) then
everestWindows[dw.id] = nil
end
elseif ev == "close" then
w.close()
everestWindows[dw.id] = nil
end
end)
end,
close = function (wnd)
wnd.close()
everestWindows[wnd.id] = nil
end
}
@ -344,10 +313,7 @@ function theEventHandler(...)
elseif ev[1] == "x.neo.pub.window" then
local v = everestWindows[ev[2]]
if v then
resumeWF(v, table.unpack(ev, 3))
if coroutine.status(v) == "dead" then
everestWindows[ev[2]] = nil
end
v(table.unpack(ev, 3))
end
end
end

View File

@ -3,6 +3,7 @@
-- just don't bother with proper indent here
return function (event, nexus, retFunc, fs, pkg, mode)
local fmt = require("fmttext")
local class = "manage"
if mode ~= nil then
@ -13,17 +14,121 @@ if mode ~= nil then
end
end
local prepareNode
-- State
local w, h, ctrl = 30, 8, false
local l, selection, unknownTx
local node, wnd
local ccb = nil
local function cb(...)
local res, e = pcall(ccb, ...)
local function prepareNode(n)
node = n
l = node.list()
selection, unknownTx = 1, ""
wnd.setSize(w, h)
end
local function format(a)
if a <= 1 then
return false, fmt.pad(unicode.safeTextFormat(node.name), w, true, true)
end
local camY = math.max(1, selection - 3)
local idx = a + camY - 2
local utx = (" "):rep(w)
if node.unknownAvailable and idx == #l + 1 then
utx = "<OK>[" .. fmt.pad(unicode.safeTextFormat(unknownTx), w - 6, false, true, true) .. "]"
end
if l[idx] then
utx = "<" .. fmt.pad(unicode.safeTextFormat(l[idx][1]), w - 2, false, true) .. ">"
end
return selection == idx, utx
end
local function updateLine(a)
local colA, colB = 0xFFFFFF, 0
local sel, text = format(a)
if sel then
colB, colA = 0xFFFFFF, 0
end
wnd.span(1, a, text, colA, colB)
end
local function flush()
for i = 1, h do
updateLine(i)
end
end
local function key(ka, kc, down)
if kc == 29 then
ctrl = down
end
if not down then return end
if ctrl then
if kc == 200 then
h = math.max(2, h - 1)
elseif kc == 208 then
h = h + 1
elseif kc == 203 then
w = math.max(6, w - 1)
elseif kc == 205 then
w = w + 1
else
return
end
wnd.setSize(w, h)
return
elseif (ka == 9) or (kc == 208) then
local lo = selection
selection = selection + 1
local max = #l
if node.unknownAvailable then
max = max + 1
end
if selection > max then
selection = 1
end
elseif kc == 200 then
local lo = selection
selection = selection - 1
local max = #l
if node.unknownAvailable then
max = max + 1
end
if selection == 0 then
selection = max
end
elseif ka == 13 then
local aResult, res
if selection ~= #l + 1 then
aResult, res = l[selection][2]()
else
aResult, res = node.selectUnknown(unknownTx)
end
if aResult then
retFunc(res)
nexus.windows[wnd.id] = nil
wnd.close()
else
prepareNode(res)
end
elseif selection == #l + 1 then
if ka == 8 then
unknownTx = unicode.sub(unknownTx, 1, unicode.len(unknownTx) - 1)
elseif ka ~= 0 then
unknownTx = unknownTx .. unicode.char(ka)
end
end
flush()
end
local function key2(...)
local res, e = pcall(key, ...)
if not res then
prepareNode({
name = "F.M. Error",
list = function ()
local l = {}
for k, v in ipairs(fmt.fmtText(unicode.safeTextFormat(e), 25)) do
for k, v in ipairs(fmt.fmtText(unicode.safeTextFormat(e), w)) do
l[k] = {v, function () return true end}
end
return l
@ -34,170 +139,44 @@ local function cb(...)
end
end
local w, h = 30, 8
local function prepareNodeI(node)
local l = node.list()
-- Local State
-- Selection. Having this equal to #l + 1 means typing area ('unknown')
local selection = 1
local unknownTx = ""
--
local function format(a)
if a <= 1 then
return false, fmt.pad(unicode.safeTextFormat(node.name), w, true, true)
end
local camY = math.max(1, selection - 3)
local idx = a + camY - 2
local utx = (" "):rep(w)
if node.unknownAvailable and idx == #l + 1 then
utx = "<OK>[" .. fmt.pad(unicode.safeTextFormat(unknownTx), w - 6, false, true, true) .. "]"
end
if l[idx] then
utx = "<" .. fmt.pad(unicode.safeTextFormat(l[idx][1]), w - 2, false, true) .. ">"
end
return selection == idx, utx
nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c)
if not wnd then
wnd = w
prepareNode(require("sys-filevfs")(fs, mode))
end
local function updateLine(wnd, a)
local colA, colB = 0xFFFFFF, 0
local sel, text = format(a)
if sel then
colB, colA = 0xFFFFFF, 0
end
wnd.span(1, a, text, colA, colB)
if ev == "key" then
key2(a, b, c)
end
local function flush(wnd)
for i = 1, h do
updateLine(wnd, i)
if ev == "touch" then
local ns = b + math.max(1, selection - 3) - 2
local max = #l
if node.unknownAvailable then
max = max + 1
end
if ns == selection and ((selection ~= #l + 1) or (a <= 4)) then
key2(13, 0, true)
else
selection = math.min(math.max(1, ns), max)
flush()
end
end
local ctrl = false
local function key(wnd, ka, kc, down)
if kc == 29 then
ctrl = down
end
if not down then return end
if ctrl then
if kc == 200 then
h = math.max(2, h - 1)
elseif kc == 208 then
h = h + 1
elseif kc == 203 then
w = math.max(6, w - 1)
elseif kc == 205 then
w = w + 1
else
return
end
wnd.setSize(w, h)
return
end
if (ka == 9) or (kc == 208) then
local lo = selection
selection = selection + 1
local max = #l
if node.unknownAvailable then
max = max + 1
end
if selection > max then
selection = 1
end
flush(wnd)
return
end
if kc == 200 then
local lo = selection
selection = selection - 1
local max = #l
if node.unknownAvailable then
max = max + 1
end
if selection == 0 then
selection = max
end
flush(wnd)
return
end
if ka == 13 then
local aResult, res
if selection ~= #l + 1 then
aResult, res = l[selection][2]()
else
aResult, res = node.selectUnknown(unknownTx)
end
if aResult then
retFunc(res)
nexus.close(wnd)
else
prepareNode(res)
end
return
end
if selection == #l + 1 then
if ka == 8 then
unknownTx = unicode.sub(unknownTx, 1, unicode.len(unknownTx) - 1)
flush(wnd)
return
end
if ka ~= 0 then
unknownTx = unknownTx .. unicode.char(ka)
flush(wnd)
end
end
if ev == "line" then
updateLine(a)
end
return w, h, function (wnd, evt, a, b, c)
if evt == "key" then
key(wnd, a, b, c)
end
if evt == "touch" then
local ns = b + math.max(1, selection - 3) - 2
local max = #l
if node.unknownAvailable then
max = max + 1
end
if ns == selection and ((selection ~= #l + 1) or (a <= 4)) then
key(wnd, 13, 0, true)
else
selection = math.min(math.max(1, ns), max)
flush(wnd)
end
end
if evt == "line" then
updateLine(wnd, a)
end
if evt == "close" then
retFunc(nil)
nexus.close(wnd)
end
end
end
local text = class .. " " .. pkg
local window
function prepareNode(node)
local w, h, c = prepareNodeI(node)
ccb = c
window.setSize(w, h)
end
local closer = nexus.createNexusThread(function ()
window = nexus.create(25, 10, text)
prepareNode(require("sys-filevfs")(fs, mode))
while window do
cb(window, coroutine.yield())
if ev == "close" then
retFunc(nil)
nexus.windows[wnd.id] = nil
wnd.close()
end
end)
if not closer then
retFunc()
return
end
return function ()
retFunc()
closer()
if window then
nexus.close(window)
window = nil
if wnd then
nexus.windows[wnd.id] = nil
wnd.close()
wnd = nil
end
end

View File

@ -81,17 +81,17 @@ function getFsNode(fs, parent, fsc, path, mode)
local t
local confirmedDel = false
t = {
name = "DIR : " .. va .. path,
name = "DIR: " .. va .. path,
list = function ()
local n = {}
n[1] = {"..", function ()
return nil, parent
end}
for k, v in ipairs(fsc.list(path)) do
local nm = "[F] " .. v
local nm = "F: " .. v
local fp = path .. v
if fsc.isDirectory(fp) then
nm = "[D] " .. v
nm = "D: " .. v
end
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end}
end

View File

@ -56,31 +56,31 @@ return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc)
local buttons = {
{"<No>", function (w)
rsp(false)
nexus.close(w)
nexus.windows[w.id] = nil
w.close()
end},
{"<Always>", function (w)
if settings then
settings.setSetting("perm|" .. pkg .. "|" .. perm, "allow")
end
rsp(true)
nexus.close(w)
nexus.windows[w.id] = nil
w.close()
end},
{"<Yes>", function (w)
rsp(true)
nexus.close(w)
nexus.windows[w.id] = nil
w.close()
end}
}
nexus.createNexusThread(function ()
local window = nexus.create(totalW, #fmt, "security")
local cButton = 0
local ev, a, b, c
while true do
if not ev then
ev, a, b, c = coroutine.yield()
end
local cButton = 0
nexus.create(totalW, #fmt, "security", function (window, ev, a, b, c)
while ev do
if ev == "line" or ev == "touch" then
local cor = b
if ev == "line" then
local iev = ev
ev = nil
if iev == "line" then
cor = a
if fmt[a] then
window.span(1, a, fmt[a], 0xFFFFFF, 0)
@ -89,7 +89,7 @@ return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc)
if cor == #fmt then
local x = 1
for k, v in ipairs(buttons) do
if ev == "line" then
if iev == "line" then
if k ~= cButton + 1 then
window.span(x, a, v[1], 0xFFFFFF, 0)
else
@ -108,10 +108,10 @@ return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc)
end
elseif ev == "close" then
rsp(false)
nexus.close(window)
return
end
if ev == "key" then
nexus.windows[w.id] = nil
w.close()
ev = nil
elseif ev == "key" then
if c and (a == 9 or b == 205) then
cButton = (cButton + 1) % #buttons
ev = "line"