Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pocket_todo.lua
- -- A pocket computer todo list with notes, completed section, clickable buttons, and backup command
- -- Data files
- local TODO_FILE = "todo.txt"
- local NOTES_FILE = "notes.txt"
- local COMPLETED_FILE = "completed.txt"
- -- Data tables
- local items = {}
- local notes = ""
- local completed = {}
- -- Utility: load list from file
- local function loadList(file, tbl)
- if fs.exists(file) then
- local f = fs.open(file, "r")
- local line = f.readLine()
- while line do
- table.insert(tbl, line)
- line = f.readLine()
- end
- f.close()
- end
- end
- -- Initial load
- loadList(TODO_FILE, items)
- loadList(COMPLETED_FILE, completed)
- if fs.exists(NOTES_FILE) then
- local f = fs.open(NOTES_FILE, "r")
- notes = f.readAll() or ""
- f.close()
- end
- -- Utility: save all data
- local function save()
- local f = fs.open(TODO_FILE, "w")
- for _,v in ipairs(items) do f.writeLine(v) end
- f.close()
- local f2 = fs.open(COMPLETED_FILE, "w")
- for _,v in ipairs(completed) do f2.writeLine(v) end
- f2.close()
- local f3 = fs.open(NOTES_FILE, "w")
- f3.write(notes)
- f3.close()
- end
- -- Button mapping
- local buttons = {}
- -- Redraw UI to term
- local function redraw()
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1,1)
- term.setTextColor(colors.white)
- local w,h = term.getSize()
- local y = 1
- buttons = {}
- -- Notes section
- if notes:match("%S") then
- term.setCursorPos(1,y)
- term.write("Notes:")
- y = y + 1
- local line = notes
- if #line > w then line = line:sub(1, w-3) .. "..." end
- term.setCursorPos(1, y)
- term.write(line)
- y = y + 1
- -- blank line after notes
- y = y + 1
- end
- -- To-Do List
- if y <= h then
- term.setCursorPos(1,y)
- term.write("To-Do List:")
- y = y + 1
- for i = 1, math.min(#items, h - y) do
- local text = string.format("%2d. %s", i, items[i])
- if #text > w-6 then text = text:sub(1, w-9) .. "..." end
- term.setCursorPos(1, y + i - 1)
- term.write(text)
- -- Done button
- local bx = w - 3
- term.setCursorPos(bx, y + i - 1)
- term.write("[D]")
- table.insert(buttons, {x1 = bx, x2 = bx + 2, y = y + i - 1, type = "done", idx = i})
- end
- y = y + math.min(#items, h - y) + 1
- end
- -- Completed Section
- if #completed > 0 and y <= h then
- term.setCursorPos(1,y)
- term.write("Completed:")
- y = y + 1
- for i = 1, math.min(#completed, h - y + 1) do
- local entry = completed[i]
- local text = "- " .. entry
- if #text > w-10 then text = text:sub(1, w-13) .. "..." end
- term.setCursorPos(1, y + i - 1)
- term.write(text)
- -- Restore button
- local rx = w - 7
- term.setCursorPos(rx, y + i - 1)
- term.write("[R]")
- table.insert(buttons, {x1 = rx, x2 = rx + 2, y = y + i - 1, type = "restore", idx = i})
- -- Delete button
- local dx = w - 3
- term.setCursorPos(dx, y + i - 1)
- term.write("[X]")
- table.insert(buttons, {x1 = dx, x2 = dx + 2, y = y + i - 1, type = "delete", idx = i})
- end
- end
- end
- -- Handle mouse clicks
- local function handleClick(x,y)
- for _,b in ipairs(buttons) do
- if y == b.y and x >= b.x1 and x <= b.x2 then
- if b.type == "done" then
- table.insert(completed, items[b.idx])
- table.remove(items, b.idx)
- elseif b.type == "restore" then
- table.insert(items, completed[b.idx])
- table.remove(completed, b.idx)
- elseif b.type == "delete" then
- table.remove(completed, b.idx)
- end
- save()
- redraw()
- return
- end
- end
- end
- -- Initial draw
- redraw()
- -- Main loops: mouse and command
- parallel.waitForAny(
- function()
- while true do
- local event, button, x, y = os.pullEvent("mouse_click")
- if button == 1 then handleClick(x,y) end
- end
- end,
- function()
- while true do
- term.setCursorPos(1,1)
- local input = read()
- local cmd, rest = input:match("^(%S+)%s*(.*)$")
- if not cmd then
- cmd = input
- rest = ""
- end
- if cmd=="add" and #rest>0 then
- table.insert(items,rest)
- elseif cmd=="remove" and tonumber(rest) and items[tonumber(rest)] then
- table.remove(items,tonumber(rest))
- elseif cmd=="done" and tonumber(rest) and items[tonumber(rest)] then
- table.insert(completed,items[tonumber(rest)]); table.remove(items,tonumber(rest))
- elseif cmd=="clear" then
- items = {}
- elseif cmd=="clearcompleted" then
- completed = {}
- elseif cmd=="backup" then
- -- delete existing backups to prevent file exists errors
- if fs.exists(BUP_TODO) then fs.delete(BUP_TODO) end
- if fs.exists(BUP_COMPLETED) then fs.delete(BUP_COMPLETED) end
- if fs.exists(BUP_NOTES) then fs.delete(BUP_NOTES) end
- -- perform backup
- if fs.exists(TODO_FILE) then fs.copy(TODO_FILE, BUP_TODO) end
- if fs.exists(COMPLETED_FILE) then fs.copy(COMPLETED_FILE, BUP_COMPLETED) end
- if fs.exists(NOTES_FILE) then fs.copy(NOTES_FILE, BUP_NOTES) end
- print("Backup complete.")
- os.sleep(0.5)
- elseif cmd=="sync" then
- -- delete existing files before sync
- if fs.exists(TODO_FILE) then fs.delete(TODO_FILE) end
- if fs.exists(COMPLETED_FILE) then fs.delete(COMPLETED_FILE) end
- if fs.exists(NOTES_FILE) then fs.delete(NOTES_FILE) end
- -- overwrite existing files from backup
- if fs.exists(BUP_TODO) then fs.copy(BUP_TODO, TODO_FILE) end
- if fs.exists(BUP_COMPLETED) then fs.copy(BUP_COMPLETED, COMPLETED_FILE) end
- if fs.exists(BUP_NOTES) then fs.copy(BUP_NOTES, NOTES_FILE) end
- -- reload data
- items = loadList(TODO_FILE)
- completed = loadList(COMPLETED_FILE)
- if fs.exists(NOTES_FILE) then local f = fs.open(NOTES_FILE, "r"); notes = f.readAll() or ""; f.close() else notes = "" end
- print("Sync complete.")
- os.sleep(0.5)
- elseif cmd=="note" then
- notes = rest or ""
- elseif cmd=="clearnote" then
- notes = ""
- elseif cmd=="exit" then
- print("Goodbye!") os.exit()
- else
- print("Invalid command. Press Enter to continue.") read()
- end
- save()
- redraw()
- end
- end
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement