1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-09-07 03:38:46 +10:00
OC-KittenOS/code/libs/sys-filedialog.lua
20kdc 7bde8fee55 Finish lowering memory use, R1
Since this is after the technical "release", version numbers have been bumped to 1.

Changes before this commit for R1:
 Kernel memory usage reduction schemes, with some security fixes.
 Still need to deal w/ proxies (see later)
Changes in this commit:
 Some various little things in apps
 CLAW inet actually works now on 192K
 sys-icecap no longer uses the event/neoux combination,
  and now handles Everest disappearance as a mass-close,
  but still handles Everest not being around on window create.
 So it still handles every situation that matters.
 neoux no longer handles everest crash protection.
 Security policy and filedialog obviously don't use neoux anymore.
 Kernel now only guarantees parsing, not event-loop, by executeAsync
 This is safer and allows app-launcher to get rid of NeoUX by
  any means necessary.
 wrapMeta cache now exists, and proxies get wrapMeta'd to deal with
  various low-priority security shenanigans.
 This is a *stopgap* until I work out how to force OCEmu to give me
  totally accurate boot-time memory figures, so I can create the
  ultimate lowmem proxy. I'm calling it "puppet". FG knows why.
2018-03-30 13:37:02 +01:00

187 lines
3.7 KiB
Lua

-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- 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
if mode then
class = "save"
else
class = "load"
end
end
local prepareNode
local ccb = nil
local function cb(...)
local res, e = pcall(ccb, ...)
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
l[k] = {v, function () return true end}
end
return l
end,
unknownAvailable = false,
selectUnknown = function (text) end
})
end
end
local function prepareNodeI(node)
local l = node.list()
local w, h = 30, 8
-- 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 true, true, node.name
end
local camY = math.max(1, selection - 3)
local idx = a + camY - 2
if node.unknownAvailable then
if idx == #l + 1 then
return selection == #l + 1, false, ":" .. unknownTx
end
end
if l[idx] then
return selection == idx, false, l[idx][1]
end
return true, true, "~~~"
end
local function updateLine(wnd, a)
local colA, colB = 0xFFFFFF, 0
local sel, cen, text = format(a)
if sel then
colB, colA = 0xFFFFFF, 0
end
wnd.span(1, a, fmt.pad(unicode.safeTextFormat(text), w, cen, true), colA, colB)
end
local function flush(wnd)
for i = 1, h do
updateLine(wnd, i)
end
end
local function key(wnd, ka, kc, down)
if not down then 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
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 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)
if not closer then
retFunc()
return
end
return function ()
retFunc()
closer()
if window then
nexus.close(window)
window = nil
end
end
-- end bad indent
end