Advertisement
Alexr360

Todo List

Apr 26th, 2025 (edited)
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.98 KB | None | 0 0
  1. -- todo.lua
  2. -- A simple terminal+monitor todo list with notes, completed section, clickable buttons including restore, backup, and sync commands
  3.  
  4. -- CONFIGURATION: change this if your monitor is on a fixed side
  5. local MONITOR_SIDE = nil  -- or e.g. "right", "left", "back"
  6.  
  7. -- Determine monitor peripheral and side name
  8. local monitorSide
  9. if MONITOR_SIDE then
  10.   monitorSide = MONITOR_SIDE
  11. else
  12.   for _, side in ipairs(peripheral.getNames()) do
  13.     if peripheral.getType(side) == "monitor" then
  14.       monitorSide = side
  15.       break
  16.     end
  17.   end
  18. end
  19. local monitor = monitorSide and peripheral.wrap(monitorSide)
  20. if not monitor then
  21.   error("No monitor found! Attach a monitor and try again.")
  22. end
  23.  
  24. -- Text settings
  25. monitor.setTextScale(0.5)
  26. monitor.setBackgroundColor(colors.black)
  27. monitor.setTextColor(colors.white)
  28.  
  29. -- Data files
  30. local TODO_FILE = "todo.txt"
  31. local NOTES_FILE = "notes.txt"
  32. local COMPLETED_FILE = "completed.txt"
  33.  
  34. -- Backup paths
  35. local DISK = "/disk/"
  36. local BUP_TODO = DISK .. TODO_FILE
  37. local BUP_NOTES = DISK .. NOTES_FILE
  38. local BUP_COMPLETED = DISK .. COMPLETED_FILE
  39.  
  40. -- Data tables
  41. local items = {}
  42. local notes = ""
  43. local completed = {}
  44.  
  45. -- Utility: load list from file into table
  46. local function loadList(file)
  47.   local tbl = {}
  48.   if fs.exists(file) then
  49.     local f = fs.open(file, "r")
  50.     local line = f.readLine()
  51.     while line do
  52.       table.insert(tbl, line)
  53.       line = f.readLine()
  54.     end
  55.     f.close()
  56.   end
  57.   return tbl
  58. end
  59.  
  60. -- Initial load
  61. items = loadList(TODO_FILE)
  62. completed = loadList(COMPLETED_FILE)
  63. if fs.exists(NOTES_FILE) then
  64.   local f = fs.open(NOTES_FILE, "r")
  65.   notes = f.readAll() or ""
  66.   f.close()
  67. end
  68.  
  69. -- Utility: save all data
  70. local function save()
  71.   local f = fs.open(TODO_FILE, "w") for _,v in ipairs(items) do f.writeLine(v) end f.close()
  72.   local f2 = fs.open(COMPLETED_FILE, "w") for _,v in ipairs(completed) do f2.writeLine(v) end f2.close()
  73.   local f3 = fs.open(NOTES_FILE, "w") f3.write(notes) f3.close()
  74. end
  75.  
  76. -- Button mapping
  77. local buttons = {}
  78.  
  79. -- Redraw monitor with buttons
  80. local function redraw()
  81.   monitor.clear()
  82.   local w,h = monitor.getSize()
  83.   local y = 1
  84.   buttons = {}
  85.  
  86.   -- Notes section
  87.   if notes:match("%S") then
  88.     monitor.setCursorPos(1,y) monitor.write("Notes:") y=y+1
  89.     local noteLine = notes
  90.     if #noteLine > w then noteLine = noteLine:sub(1,w-3).."..." end
  91.     monitor.setCursorPos(1,y) monitor.write(noteLine) y=y+1
  92.     -- blank line after notes
  93.     y=y+1
  94.   end
  95.  
  96.   -- To-Do List
  97.   monitor.setCursorPos(1,y) monitor.write("To-Do List:") y=y+1
  98.   for i=1,math.min(#items, h-y) do
  99.     local text = string.format("%2d. %s", i, items[i])
  100.     if #text > w-6 then text = text:sub(1,w-9).."..." end
  101.     monitor.setCursorPos(1,y+i-1) monitor.write(text)
  102.     -- Done button
  103.     local bx = w-3
  104.     monitor.setCursorPos(bx, y+i-1) monitor.write("[D]")
  105.     table.insert(buttons, {x1=bx, x2=bx+2, y=y+i-1, type="done", idx=i})
  106.   end
  107.   y = y + math.min(#items,h-y) + 1
  108.  
  109.   -- Completed Section
  110.   if #completed > 0 and y < h then
  111.     monitor.setCursorPos(1,y) monitor.write("Completed:") y=y+1
  112.     for i=1,math.min(#completed, h-y+1) do
  113.       local entry = completed[i]
  114.       local text = "- "..entry
  115.       if #text > w-10 then text = text:sub(1,w-13).."..." end
  116.       monitor.setCursorPos(1,y+i-1) monitor.write(text)
  117.       -- Restore button
  118.       local rx = w-7
  119.       monitor.setCursorPos(rx, y+i-1) monitor.write("[R]")
  120.       table.insert(buttons, {x1=rx, x2=rx+2, y=y+i-1, type="restore", idx=i})
  121.       -- Delete button
  122.       local dx = w-3
  123.       monitor.setCursorPos(dx, y+i-1) monitor.write("[X]")
  124.       table.insert(buttons, {x1=dx, x2=dx+2, y=y+i-1, type="delete", idx=i})
  125.     end
  126.   end
  127. end
  128.  
  129. -- Handle touch events
  130. local function handleTouch(x,y)
  131.   for _,b in ipairs(buttons) do
  132.     if y==b.y and x>=b.x1 and x<=b.x2 then
  133.       if b.type=="done" then
  134.         table.insert(completed, items[b.idx]); table.remove(items, b.idx)
  135.       elseif b.type=="restore" then
  136.         table.insert(items, completed[b.idx]); table.remove(completed, b.idx)
  137.       elseif b.type=="delete" then
  138.         table.remove(completed, b.idx)
  139.       end
  140.       save()
  141.       redraw()
  142.       return
  143.     end
  144.   end
  145. end
  146.  
  147. -- Initial draw
  148. redraw()
  149.  
  150. -- Main loops: touch handler and command handler
  151. parallel.waitForAny(
  152.   function()
  153.     while true do
  154.       local event, side, x, y = os.pullEvent("monitor_touch")
  155.       if side==monitorSide then handleTouch(x,y) end
  156.     end
  157.   end,
  158.   function()
  159.     while true do
  160.       term.clear() term.setCursorPos(1,1)
  161.       print("Commands: add <item>, note <text>, clearnote")
  162.       io.write("Command: ")
  163.       local input = read()
  164.       local cmd, rest = input:match("^(%S+)%s*(.*)$")
  165.       if not cmd then
  166.         cmd = input
  167.         rest = ""
  168.       end
  169.       if cmd=="add" and #rest>0 then
  170.         table.insert(items,rest)
  171.       elseif cmd=="remove" and tonumber(rest) and items[tonumber(rest)] then
  172.         table.remove(items,tonumber(rest))
  173.       elseif cmd=="done" and tonumber(rest) and items[tonumber(rest)] then
  174.         table.insert(completed,items[tonumber(rest)]); table.remove(items,tonumber(rest))
  175.       elseif cmd=="clear" then
  176.         items = {}
  177.       elseif cmd=="clearcompleted" then
  178.         completed = {}
  179.       elseif cmd=="backup" then
  180.         -- delete existing backups to prevent file exists errors
  181.         if fs.exists(BUP_TODO) then fs.delete(BUP_TODO) end
  182.         if fs.exists(BUP_COMPLETED) then fs.delete(BUP_COMPLETED) end
  183.         if fs.exists(BUP_NOTES) then fs.delete(BUP_NOTES) end
  184.         -- perform backup
  185.         if fs.exists(TODO_FILE) then fs.copy(TODO_FILE, BUP_TODO) end
  186.         if fs.exists(COMPLETED_FILE) then fs.copy(COMPLETED_FILE, BUP_COMPLETED) end
  187.         if fs.exists(NOTES_FILE) then fs.copy(NOTES_FILE, BUP_NOTES) end
  188.         print("Backup complete.")
  189.         os.sleep(0.5)
  190.       elseif cmd=="sync" then
  191.         -- delete existing files before sync
  192.         if fs.exists(TODO_FILE) then fs.delete(TODO_FILE) end
  193.         if fs.exists(COMPLETED_FILE) then fs.delete(COMPLETED_FILE) end
  194.         if fs.exists(NOTES_FILE) then fs.delete(NOTES_FILE) end
  195.         -- overwrite existing files from backup
  196.         if fs.exists(BUP_TODO) then fs.copy(BUP_TODO, TODO_FILE) end
  197.         if fs.exists(BUP_COMPLETED) then fs.copy(BUP_COMPLETED, COMPLETED_FILE) end
  198.         if fs.exists(BUP_NOTES) then fs.copy(BUP_NOTES, NOTES_FILE) end
  199.         -- reload data
  200.         items = loadList(TODO_FILE)
  201.         completed = loadList(COMPLETED_FILE)
  202.         if fs.exists(NOTES_FILE) then local f = fs.open(NOTES_FILE, "r"); notes = f.readAll() or ""; f.close() else notes = "" end
  203.         print("Sync complete.")
  204.         os.sleep(0.5)
  205.       elseif cmd=="note" then
  206.         notes = rest or ""
  207.       elseif cmd=="clearnote" then
  208.         notes = ""
  209.       elseif cmd=="exit" then
  210.         print("Goodbye!") os.exit()
  211.       else
  212.         print("Invalid command. Press Enter to continue.") read()
  213.       end
  214.       save()
  215.       redraw()
  216.     end
  217.   end
  218. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement