Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- todo.lua
- -- A simple terminal+monitor todo list with notes, completed section, clickable buttons including restore, backup, and sync commands
- -- CONFIGURATION: change this if your monitor is on a fixed side
- local MONITOR_SIDE = nil -- or e.g. "right", "left", "back"
- -- Determine monitor peripheral and side name
- local monitorSide
- if MONITOR_SIDE then
- monitorSide = MONITOR_SIDE
- else
- for _, side in ipairs(peripheral.getNames()) do
- if peripheral.getType(side) == "monitor" then
- monitorSide = side
- break
- end
- end
- end
- local monitor = monitorSide and peripheral.wrap(monitorSide)
- if not monitor then
- error("No monitor found! Attach a monitor and try again.")
- end
- -- Text settings
- monitor.setTextScale(0.5)
- monitor.setBackgroundColor(colors.black)
- monitor.setTextColor(colors.white)
- -- Data files
- local TODO_FILE = "todo.txt"
- local NOTES_FILE = "notes.txt"
- local COMPLETED_FILE = "completed.txt"
- -- Backup paths
- local DISK = "/disk/"
- local BUP_TODO = DISK .. TODO_FILE
- local BUP_NOTES = DISK .. NOTES_FILE
- local BUP_COMPLETED = DISK .. COMPLETED_FILE
- -- Data tables
- local items = {}
- local notes = ""
- local completed = {}
- -- Utility: load list from file into table
- local function loadList(file)
- local 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
- return tbl
- end
- -- Initial load
- 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()
- 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 monitor with buttons
- local function redraw()
- monitor.clear()
- local w,h = monitor.getSize()
- local y = 1
- buttons = {}
- -- Notes section
- if notes:match("%S") then
- monitor.setCursorPos(1,y) monitor.write("Notes:") y=y+1
- local noteLine = notes
- if #noteLine > w then noteLine = noteLine:sub(1,w-3).."..." end
- monitor.setCursorPos(1,y) monitor.write(noteLine) y=y+1
- -- blank line after notes
- y=y+1
- end
- -- To-Do List
- monitor.setCursorPos(1,y) monitor.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
- monitor.setCursorPos(1,y+i-1) monitor.write(text)
- -- Done button
- local bx = w-3
- monitor.setCursorPos(bx, y+i-1) monitor.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
- -- Completed Section
- if #completed > 0 and y < h then
- monitor.setCursorPos(1,y) monitor.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
- monitor.setCursorPos(1,y+i-1) monitor.write(text)
- -- Restore button
- local rx = w-7
- monitor.setCursorPos(rx, y+i-1) monitor.write("[R]")
- table.insert(buttons, {x1=rx, x2=rx+2, y=y+i-1, type="restore", idx=i})
- -- Delete button
- local dx = w-3
- monitor.setCursorPos(dx, y+i-1) monitor.write("[X]")
- table.insert(buttons, {x1=dx, x2=dx+2, y=y+i-1, type="delete", idx=i})
- end
- end
- end
- -- Handle touch events
- local function handleTouch(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: touch handler and command handler
- parallel.waitForAny(
- function()
- while true do
- local event, side, x, y = os.pullEvent("monitor_touch")
- if side==monitorSide then handleTouch(x,y) end
- end
- end,
- function()
- while true do
- term.clear() term.setCursorPos(1,1)
- print("Commands: add <item>, note <text>, clearnote")
- io.write("Command: ")
- 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