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:
parent
a22ac86b2d
commit
921425ada4
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user