diff --git a/startup.lua b/startup.lua index d94be2b..0cfcd7f 100644 --- a/startup.lua +++ b/startup.lua @@ -1,14 +1,48 @@ +--[[ + .startup.boot + delay + description: delays amount before starting the default selection + default: 1.5 + + preload + description : runs before menu is displayed, can be used for password + locking, drive encryption, etc. + example : { [1] = '/path/somefile.lua', [2] = 'path2/another.lua' } + + menu + description: array of menu entries (see .startup.boot for examples) +]] + local colors = _G.colors local os = _G.os local settings = _G.settings local term = _G.term -local bootOptions = { - { prompt = os.version() }, - { prompt = 'Opus' , args = { '/sys/boot/opus.boot' } }, - { prompt = 'Opus Shell' , args = { '/sys/boot/opus.boot', 'sys/apps/shell.lua' } }, - { prompt = 'Opus Kiosk' , args = { '/sys/boot/kiosk.boot' } }, -} +local function loadBootOptions() + if not fs.exists('.startup.boot') then + local f = fs.open('.startup.boot', 'w') + f.write(textutils.serialize({ + delay = 1.5, + preload = { }, + menu = { + { prompt = os.version() }, + { prompt = 'Opus' , args = { '/sys/boot/opus.boot' } }, + { prompt = 'Opus Shell' , args = { '/sys/boot/opus.boot', 'sys/apps/shell.lua' } }, + { prompt = 'Opus Kiosk' , args = { '/sys/boot/kiosk.boot' } }, + }, + })) + f.close() + end + + local f = fs.open('.startup.boot', 'r') + local options = textutils.unserialize(f.readAll()) + f.close() + + return options +end + +local bootOptions = loadBootOptions() + local bootOption = 2 if settings then settings.load('.settings') @@ -17,69 +51,63 @@ end local function startupMenu() local x, y = term.getSize() - local align, selected = 0, 1 + local align, selected = 0, bootOption + local function redraw() local title = "Boot Options:" term.clear() term.setTextColor(colors.white) - term.setCursorPos((x/2)-(#title/2), (y/2)-(#bootOptions/2)-1) + term.setCursorPos((x/2)-(#title/2), (y/2)-(#bootOptions.menu/2)-1) term.write(title) - for i = 1, #bootOptions do - local txt = i..". "..bootOptions[i].prompt - term.setCursorPos((x/2)-(align/2), (y/2)-(#bootOptions/2)+i) + for i, item in pairs(bootOptions.menu) do + local txt = i .. ". " .. item.prompt + term.setCursorPos((x/2)-(align/2), (y/2)-(#bootOptions.menu/2)+i) term.write(txt) end end - for i = 1, #bootOptions do - if (bootOptions[i].prompt):len() > align then - align = (bootOptions[i].prompt):len() + for _, item in pairs(bootOptions.menu) do + if #item.prompt > align then + align = #item.prompt end end redraw() - repeat - term.setCursorPos((x/2)-(align/2)-2, (y/2)-(#bootOptions/2)+selected) - if term.isColor() then - term.setTextColor(colors.yellow) - else - term.setTextColor(colors.lightGray) - end + while true do + term.setCursorPos((x/2)-(align/2)-2, (y/2)-(#bootOptions.menu/2)+selected) + term.setTextColor(term.isColor() and colors.yellow or colors.lightGray) + term.write(">") - local k = ({os.pullEvent()}) - if k[1] == "mouse_scroll" then - if k[2] == 1 then - k = keys.down - else - k = keys.up - end - elseif k[1] == "key" then - k = k[2] - else - k = nil + local event, key = os.pullEvent() + if event == "mouse_scroll" then + key = key == 1 and keys.down or keys.up + elseif event == 'key_up' then + key = nil -- only process key events end - if k then - if k == keys.enter or k == keys.right then - return selected - elseif k == keys.down then - if selected == #bootOptions then - selected = 0 - end - selected = selected+1 - elseif k == keys.up then - if selected == 1 then - selected = #bootOptions+1 - end - selected = selected-1 - elseif k >= keys.one and k <= #bootOptions+1 and k < keys.zero then - selected = k-1 - return selected + + if key == keys.enter or key == keys.right then + return selected + elseif key == keys.down then + if selected == #bootOptions.menu then + selected = 0 + end + selected = selected + 1 + elseif key == keys.up then + if selected == 1 then + selected = #bootOptions.menu + 1 + end + selected = selected - 1 + elseif event == 'char' then + key = tonumber(key) or 0 + if bootOptions.menu[key] then + return key end - local cx, cy = term.getCursorPos() - term.setCursorPos(cx-1, cy) - term.write(" ") end - until true == false + + local cx, cy = term.getCursorPos() + term.setCursorPos(cx-1, cy) + term.write(" ") + end end local function splash() @@ -120,13 +148,17 @@ end term.clear() splash() -local timerId = os.startTimer(1.5) +for _, v in pairs(bootOptions.preload) do + os.run(_ENV, v) +end + +local timerId = os.startTimer(bootOptions.delay) while true do local e, id = os.pullEvent() if e == 'timer' and id == timerId then break end - if e == 'char' then + if e == 'char' or e == 'key' then bootOption = startupMenu() if settings then settings.set('opus.boot_option', bootOption) @@ -138,9 +170,9 @@ end term.clear() term.setCursorPos(1, 1) -if bootOptions[bootOption].args then - os.run(_ENV, table.unpack(bootOptions[bootOption].args)) +if bootOptions.menu[bootOption].args then + os.run(_ENV, table.unpack(bootOptions.menu[bootOption].args)) else - print(bootOptions[bootOption].prompt) + print(bootOptions.menu[bootOption].prompt) end diff --git a/sys/modules/opus/cbor.lua b/sys/modules/opus/cbor.lua index a55df44..95e41ca 100644 --- a/sys/modules/opus/cbor.lua +++ b/sys/modules/opus/cbor.lua @@ -14,7 +14,7 @@ end local setmetatable = setmetatable; local getmetatable = getmetatable; -local dbg_getmetatable = debug.getmetatable; +local dbg_getmetatable = debug and debug.getmetatable; local assert = assert; local error = error; local type = type; diff --git a/sys/modules/opus/entry.lua b/sys/modules/opus/entry.lua index 0029ded..693fe87 100644 --- a/sys/modules/opus/entry.lua +++ b/sys/modules/opus/entry.lua @@ -195,7 +195,7 @@ end function Entry:paste(ie) if #ie.text > 0 then if self.mark.active then - self:delete() + self:delete() end self:insertText(self.pos, ie.text) end @@ -347,16 +347,16 @@ local mappings = { -- [ 'control-y' ] = Entry.paste, -- well this won't work... [ 'mouse_doubleclick' ] = Entry.markWord, - [ 'shift-left' ] = Entry.markLeft, - [ 'shift-right' ] = Entry.markRight, - [ 'mouse_down' ] = Entry.markAnchor, - [ 'mouse_drag' ] = Entry.markTo, - [ 'shift-mouse_click' ] = Entry.markTo, - [ 'control-a' ] = Entry.markAll, - [ 'control-shift-right' ] = Entry.markNextWord, - [ 'control-shift-left' ] = Entry.markPrevWord, - [ 'shift-end' ] = Entry.markEnd, - [ 'shift-home' ] = Entry.markHome, + [ 'shift-left' ] = Entry.markLeft, + [ 'shift-right' ] = Entry.markRight, + [ 'mouse_down' ] = Entry.markAnchor, + [ 'mouse_drag' ] = Entry.markTo, + [ 'shift-mouse_click' ] = Entry.markTo, + [ 'control-a' ] = Entry.markAll, + [ 'control-shift-right' ] = Entry.markNextWord, + [ 'control-shift-left' ] = Entry.markPrevWord, + [ 'shift-end' ] = Entry.markEnd, + [ 'shift-home' ] = Entry.markHome, } function Entry:process(ie) @@ -369,7 +369,7 @@ function Entry:process(ie) local line = self.value local wasMarking = self.mark.continue - self.mark.continue = false + self.mark.continue = false action(self, ie) @@ -378,7 +378,7 @@ function Entry:process(ie) self:updateScroll() if not self.mark.continue and wasMarking then - self:unmark() + self:unmark() end return true