local apps = {} local windows = loadfile("/libs/windows.lua")() local containers = loadfile("/libs/containers.lua")() local focusedapp = nil local home_button = "[------]" local launcherappid = "com.ruffles.launcher" local launcherapp = nil _G.app = {} function _G.app.focusapp(pid) print("focusing "..pid) focusedapp = apps[pid] end function _G.app.getApps() local out = {} for _,f in ipairs(fs.list("/apps-meta")) do if fs.exists(fs.combine("/apps-meta",f)) then local file = fs.open(fs.combine("/apps-meta",f),"r") if file then out[#out+1] = textutils.unserialise(file.readAll()) file.close() end end end return out end function _G.app.closeApp(pid) if pid == focusedapp then app.focusapp(-1) apps[pid] = nil else apps[pid] = nil end end function _G.app.getRunningApps() local pids = {} for k,_ in pairs(apps) do pids[#pids+1] = k end return pids end function _G.app.getTitle(pid) if not apps[pid] then return false, "Process not found" end return apps[pid].title end function _G.app.getDetail(pid) if not apps[pid] then return false, "Process not found" end local registered_apps = app.getApps() local appid = apps[pid].id local appdetails = nil local msg = "Details not found (likely doesn't have a metadata file)" for _,registered_app in ipairs(registered_apps) do if registered_app.appid == appid then appdetails = registered_app msg = nil break end end return appdetails, msg end function _G.app.launch(id,perms,parentperms) if parentperms then for k,v in pairs(perms) do if v and not parentperms[k] then return false, "Unable to grant permission: "..k end end end local w,h = term.getSize() if not fs.exists(fs.combine("/apps",id)) then return false,"App Not Found" end local win = windows.create(id,w,h-2,1,2) local env = containers.getENV(fs.combine("/apps",id), win, perms) local appobj = {win=win,co=nil,id=id,title=id} function env.setAppTitle(str) appobj.title=tostring(str) end appobj.co = coroutine.create(function () containers.start(env) end) local pid = -1 for k=1,#apps+1 do if apps[k] == nil then apps[k] = appobj pid = k end end app.focusapp(pid) return pid end local function render() while true do local w,h = term.getSize() if focusedapp and focusedapp.win then local window = focusedapp.win for cy = 1, window.h do term.setCursorPos(window.x, window.y + cy - 1) local line, fg, bg = "", "", "" for cx = 1, window.w do if window.buffer[cx] then local cell = window.buffer[cx][cy] if cell then line = line .. cell.char fg = fg .. ("0123456789abcdef"):sub(math.log(cell.tc, 2) + 1, math.log(cell.tc, 2) + 1) bg = bg .. ("0123456789abcdef"):sub(math.log(cell.bc, 2) + 1, math.log(cell.bc, 2) + 1) else line = line .. " " fg = fg .. "0" bg = bg .. "f" end else line = line .. " " fg = fg .. "0" bg = bg .. "f" end end term.blit(line, fg, bg) end end term.setCursorPos(1,1) term.setBackgroundColor(colors.black) if focusedapp then term.setBackgroundColor(focusedapp.win.getMostCommonBackgroundColor()) end term.clearLine() term.write(os.date("%I:%M %p")) local candidate = network.getCandidate() local right = "id: "..tostring(candidate.id).." dist: "..tostring(math.floor(candidate.distance+0.5)).." m" if candidate.id == -1 then right = "disconnected" end term.setCursorPos(w-right:len()+1,1) term.write(right) term.setCursorPos((w/2)-(home_button:len()/2)+1,h) term.clearLine() term.write(home_button) term.setCursorPos(1,h) if focusedapp then local window = focusedapp.win if window then term.setCursorPos(window.cursorX,window.cursorY) term.setCursorBlink(window.cursorBlink) else term.setCursorBlink(false) end end sleep(1/20) end end local function process() while true do local event = {os.pullEvent()} if event[1] == "mouse_click" then local w,h = term.getSize() if event[2] == 1 and event[3] >= (w/2)-(home_button:len()/2)+1 and event[3] <= (w/2)-(home_button:len()/2)+home_button:len() and event[4] == h then app.focusapp(launcherapp) end event[4] = event[4]-1 elseif event[1] == "mouse_up" then event[4] = event[4]-1 elseif event[1] == "mouse_drag" then event[4] = event[4]-1 elseif event[1] == "mouse_scroll" then event[4] = event[4]-1 end if focusedapp then if focusedapp.filter == nil or focusedapp.filter == event[1] then local success, content = coroutine.resume(focusedapp.co,table.unpack(event)) if success then focusedapp.filter = content else app.focusapp(-1) end end end for k,v in pairs(apps) do if (v.filter == nil or v.filter == event[1]) and v ~= focusedapp and event[1] ~= "mouse_click" and event[1] ~= "mouse_up" and event[1] ~= "mouse_drag" and event[1] ~= "mouse_scroll" and event[1] ~= "char" and event[1] ~= "key" and event[1] ~= "key_up" then local success, content = coroutine.resume(v.co,table.unpack(event)) if success then v.filter = content end end end end end print("launching launcher app..") launcherapp = app.launch(launcherappid,{http=true,app=true,repo=true,network=true,peripheral=true}) print("launched launcher app") parallel.waitForAny(process,render,network.run)