1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-27 04:48:05 +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) table.insert(onReg[p], f)
end 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 = { nexus = {
createNexusThread = function (f, ...) create = function (w, h, t, c)
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()
local function cb() 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 end
addOnReg("x.neo.pub.window", cb)
local everest = coroutine.yield(cb)
local dw = everest(w, h, title)
everestWindows[dw.id] = thr
return dw return dw
end, end,
windows = everestWindows,
startDialog = function (tx, ti) startDialog = function (tx, ti)
local fmt = require("fmttext") local txl = require("fmttext").fmtText(unicode.safeTextFormat(tx), 40)
local txl = fmt.fmtText(unicode.safeTextFormat(tx), 40) nexus.create(40, #txl, ti, function (w, ev, a)
fmt = nil if ev == "line" then
nexus.createNexusThread(function () if not pcall(w.span, 1, a, txl[a], 0xFFFFFF, 0) then
local w = nexus.create(40, #txl, ti) everestWindows[dw.id] = nil
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
end end
elseif ev == "close" then
w.close()
everestWindows[dw.id] = nil
end end
end) end)
end,
close = function (wnd)
wnd.close()
everestWindows[wnd.id] = nil
end end
} }
@ -344,10 +313,7 @@ function theEventHandler(...)
elseif ev[1] == "x.neo.pub.window" then elseif ev[1] == "x.neo.pub.window" then
local v = everestWindows[ev[2]] local v = everestWindows[ev[2]]
if v then if v then
resumeWF(v, table.unpack(ev, 3)) v(table.unpack(ev, 3))
if coroutine.status(v) == "dead" then
everestWindows[ev[2]] = nil
end
end end
end end
end end

View File

@ -3,6 +3,7 @@
-- just don't bother with proper indent here -- just don't bother with proper indent here
return function (event, nexus, retFunc, fs, pkg, mode) return function (event, nexus, retFunc, fs, pkg, mode)
local fmt = require("fmttext") local fmt = require("fmttext")
local class = "manage" local class = "manage"
if mode ~= nil then if mode ~= nil then
@ -13,17 +14,121 @@ if mode ~= nil then
end end
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 function prepareNode(n)
local res, e = pcall(ccb, ...) 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 if not res then
prepareNode({ prepareNode({
name = "F.M. Error", name = "F.M. Error",
list = function () list = function ()
local l = {} 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} l[k] = {v, function () return true end}
end end
return l return l
@ -34,170 +139,44 @@ local function cb(...)
end end
end end
local w, h = 30, 8 nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c)
if not wnd then
local function prepareNodeI(node) wnd = w
local l = node.list() prepareNode(require("sys-filevfs")(fs, mode))
-- 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
end end
local function updateLine(wnd, a) if ev == "key" then
local colA, colB = 0xFFFFFF, 0 key2(a, b, c)
local sel, text = format(a)
if sel then
colB, colA = 0xFFFFFF, 0
end
wnd.span(1, a, text, colA, colB)
end end
local function flush(wnd) if ev == "touch" then
for i = 1, h do local ns = b + math.max(1, selection - 3) - 2
updateLine(wnd, i) 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
end end
local ctrl = false if ev == "line" then
local function key(wnd, ka, kc, down) updateLine(a)
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
end end
return w, h, function (wnd, evt, a, b, c) if ev == "close" then
if evt == "key" then retFunc(nil)
key(wnd, a, b, c) nexus.windows[wnd.id] = nil
end wnd.close()
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())
end end
end) end)
if not closer then
retFunc()
return
end
return function () return function ()
retFunc() retFunc()
closer() closer()
if window then if wnd then
nexus.close(window) nexus.windows[wnd.id] = nil
window = nil wnd.close()
wnd = nil
end end
end end

View File

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

View File

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