Advertisement
LegoStax

Standalone file explorer

Apr 28th, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.11 KB | None | 0 0
  1. -- Explorer App by LegoStax
  2. -- Originally designed for an upcoming security suite...
  3.  
  4. local RUNNING = false
  5. local PATH = "/"
  6. local COPYPATH = ""
  7. local CUTPATH = ""
  8. local w,h = term.getSize()
  9. local WALL = ""
  10. -- for drawing and scroll
  11. local beginFiles = 0
  12. local scrollpos = 1
  13. local greatestpos = 1
  14. local pospossible = 1
  15. local oldItems = nil
  16. local pos = nil
  17. local selectedItem = -1
  18.  
  19. if term.isColor() or term.isColour() then
  20.     RUNNING = true
  21. end
  22.  
  23. local function clear(bg)
  24.     bg = bg or colors.black
  25.     term.setBackgroundColor(bg)
  26.     term.clear()
  27.     term.setCursorPos(1,1)
  28. end
  29.  
  30. local function printPos(msg,x,y,bg,fg)
  31.     if bg then term.setBackgroundColor(bg) end
  32.     if fg then term.setTextColor(fg) end
  33.     term.setCursorPos(x,y)
  34.     term.write(msg)
  35. end
  36.  
  37. local function printCenter(msg,y,bg,fg)
  38.     local x = (w-msg:len())/2
  39.     printPos(msg,x,y,bg,fg)
  40.     return x
  41. end
  42.  
  43. local function listFiles(d)
  44.     local dir = nil
  45.     if d then
  46.         dir = shell.resolve(d)
  47.     else
  48.         dir = shell.dir()
  49.     end
  50.    
  51.     local all = fs.list(dir)
  52.     local files = {}
  53.     local folders = {}
  54.     local hidden = settings.get("list.show_hidden")
  55.     for n, item in pairs(all) do
  56.         if hidden or string.sub(item,1,1) ~= "." then
  57.             local path = fs.combine(dir, item)
  58.             if fs.isDir(path) then
  59.                 table.insert(folders, item)
  60.             else
  61.                 table.insert(files, item)
  62.             end
  63.         end
  64.     end
  65.     table.sort(folders)
  66.     table.sort(files)
  67.     return folders, files
  68. end
  69.  
  70. local function calculateItems()
  71.     local folders, files = listFiles(PATH)
  72.     local items = folders
  73.     beginFiles = #folders+1
  74.     for i = 1,#files do
  75.         table.insert(items,files[i])
  76.     end
  77.     -- calculate greatestpos
  78.     for i = 1,#items do
  79.         if items[i]:len() > greatestpos then
  80.             greatestpos = items[i]:len()
  81.         end
  82.     end
  83.     pospossible = #items-(h-3)
  84.     return items
  85. end
  86.  
  87. local function drawTopBar()
  88.     term.setBackgroundColor(colors.gray)
  89.     term.setCursorPos(1,1)
  90.     term.clearLine()
  91.     printPos("QuickScape",1,1,colors.gray,colors.white)
  92.     printPos(WALL,13,1,colors.gray,colors.red)
  93.     printPos("X",w,1,colors.red,colors.white)
  94. end
  95.  
  96. local function drawCurrentPath()
  97.     term.setBackgroundColor(colors.lightGray)
  98.     term.setCursorPos(1,2)
  99.     term.clearLine()
  100.     printPos(" <  "..PATH,1,2,colors.lightGray)
  101. end
  102.  
  103. local function drawItems(items)
  104.     if not items then
  105.         items = oldItems
  106.     end
  107.     oldItems = items
  108.    
  109.     term.setBackgroundColor(colors.white)
  110.     term.setTextColor(colors.blue)
  111.     term.setCursorPos(5,3)
  112.     for i = scrollpos,#items do
  113.         if i > #items then break end
  114.         if i == beginFiles then term.setTextColor(colors.black) end
  115.         if i == selectedItem then
  116.             term.setBackgroundColor(colors.blue)
  117.             term.setTextColor(colors.white)
  118.         else
  119.             term.setBackgroundColor(colors.white)
  120.             if i < beginFiles then term.setTextColor(colors.blue)
  121.             else term.setTextColor(colors.black) end
  122.         end
  123.         term.write(items[i])
  124.         term.setBackgroundColor(colors.white)
  125.         for i = 1,greatestpos do term.write(" ") end
  126.         local x,y = term.getCursorPos()
  127.         y = y+1
  128.         term.setCursorPos(5,y)
  129.         if y > h then break end
  130.     end
  131. end
  132.  
  133. local function rightClickMenu(x,y,mode)
  134.     if mode == 1 then -- file +11
  135.         printPos(" Cut       ",x,y,colors.gray,colors.white)
  136.         printPos(" Copy      ",x,y+1)
  137.         printPos(" Delete    ",x,y+2)
  138.         printPos(" Rename    ",x,y+3)
  139.         printPos(" Open With ",x,y+4)
  140.     elseif mode == 2 then -- folder +8
  141.         printPos(" Cut    ",x,y,colors.gray,colors.white)
  142.         printPos(" Copy   ",x,y+1)
  143.         printPos(" Delete ",x,y+2)
  144.         printPos(" Rename ",x,y+3)
  145.     else -- misc +12
  146.         printPos(" Paste      ",x,y,colors.gray,colors.white)
  147.         printPos(" New File   ",x,y+1)
  148.         printPos(" New Folder ",x,y+2)
  149.     end
  150. end
  151.  
  152. local function animSelected(msg,x,y,bg,fg)
  153.     printPos(msg,x,y,bg,fg)
  154.     sleep(0.1)
  155. end
  156.  
  157. local function errorBox(e)
  158.     printPos(e,1,1,colors.red,colors.white)
  159.    
  160.     while true do
  161.         local e = {os.pullEvent()}
  162.         if e[1] == "mouse_click" or e[1] == "key" then break end
  163.     end
  164. end
  165.  
  166. local function drawScreen()
  167.     clear(colors.white)
  168.     drawTopBar()
  169.     drawCurrentPath()
  170.     drawItems(calculateItems())
  171.     WALL = ""
  172. end
  173.  
  174. local function closeApp()
  175.     animSelected("X",w,1,colors.white,colors.red)
  176.     RUNNING = false
  177. end
  178.  
  179. local function logVars(msg)
  180.     local f = fs.open("logs", "a")
  181.     f.write("\n"..msg)
  182.     f.close()
  183. end
  184. -- 8:"New File" 10:"New Folder" 6:"Rename"
  185. local function prompt(msg,data)
  186.     local linepadding = ""
  187.     for i = 1,2+msg:len() do
  188.         linepadding = linepadding .. " "
  189.     end
  190.    
  191.     local y = math.floor(h/2)
  192.     printCenter(" "..msg.." ",y,colors.lightGray,colors.black)
  193.     printCenter(linepadding,y+1)
  194.     printCenter(linepadding,y+2)
  195.     local x = (w-msg:len())/2
  196.     term.setCursorPos(x,y+1)
  197.     if data then
  198.         for i = 1,data:len() do os.queueEvent("char", string.sub(data,i,i)) end
  199.     end
  200.     local input = read()
  201.     return input
  202. end
  203.  
  204. local function run(path)
  205.     shell.switchTab(shell.openTab(path))
  206.     --[[clear(colors.black)
  207.     printCenter("Awaiting term_resize", (h-1)/2)
  208.     local e = {os.pullEvent("term_resize")}
  209.     --w,h = e[2],e[3]
  210.     drawScreen()]]--
  211. end
  212.  
  213. local function rightClickHandler(x,y,mode,item)
  214.     local actualX, actualY = x,y
  215.     if mode == 1 then
  216.         if x > w-10 then
  217.             actualX = w-10
  218.         end
  219.         if y > h-4 then
  220.             actualY = h-4
  221.         end
  222.         rightClickMenu(actualX, actualY, 1)
  223.         while true do
  224.             local e = {os.pullEvent()}
  225.             if e[1] == "mouse_click" and e[2] == 1 then
  226.                 if e[3] == w and e[4] == 1 then
  227.                     closeApp()
  228.                     break
  229.                 elseif e[3] >= actualX and e[3] <= actualX+11 then
  230.                     if e[4] == actualY then -- cut
  231.                         animSelected(" Cut       ",actualX,actualY,colors.lightGray,colors.black)
  232.                         CUTPATH = shell.resolve(PATH..oldItems[item])
  233.                         COPYPATH = ""
  234.                         break
  235.                     elseif e[4] == actualY+1 then -- copy
  236.                         animSelected(" Copy      ",actualX,actualY+1,colors.lightGray,colors.black)
  237.                         COPYPATH = shell.resolve(PATH..oldItems[item])
  238.                         CUTPATH = ""
  239.                         break
  240.                     elseif e[4] == actualY+2 then -- delete
  241.                         animSelected(" Delete    ",actualX,actualY+2,colors.lightGray,colors.black)
  242.                         fs.delete(PATH..oldItems[item])
  243.                         selectedItem = -1
  244.                         break
  245.                     elseif e[4] == actualY+3 then -- rename
  246.                         animSelected(" Rename    ",actualX,actualY+3,colors.lightGray,colors.black)
  247.                         local newname = PATH..prompt("Rename",oldItems[item])
  248.                         if not newname == oldItems[item] and not fs.exists(newname) then fs.move(oldItems[item],newname) end
  249.                         break
  250.                     elseif e[4] == actualY+4 then -- open with
  251.                         animSelected(" Open With ",actualX,actualY+4,colors.lightGray,colors.black)
  252.                         local newx, newy = nil,nil
  253.                         if actualX > 7 then
  254.                             printPos(" Edit  ",actualX-7,actualY+3,colors.gray,colors.white)
  255.                             printPos(" Paint ",actualX-7,actualY+4,colors.gray,colors.white)
  256.                             newx = actualX-7
  257.                             newy = actualY+3
  258.                         else
  259.                             printPos(" Edit  ",actualX+11,actualY+3,colors.gray,colors.white)
  260.                             printPos(" Paint ",actualX+11,actualY+4,colors.gray,colors.white)
  261.                             newx = actualX+11
  262.                             newy = actualY+3
  263.                         end
  264.                         while true do
  265.                             local e = {os.pullEvent()}
  266.                             if e[1] == "mouse_click" and e[2] == 1 then
  267.                                 if e[3] == w and e[4] == 1 then
  268.                                     RUNNING = false
  269.                                     break
  270.                                 elseif e[3] >= newx and e[3] <= newx+7 then
  271.                                     if e[4] == newy then --edit
  272.                                         run("edit "..PATH..oldItems[item])
  273.                                         break
  274.                                     elseif e[4] == newy+1 then --paint
  275.                                         run("paint "..PATH..oldItems[item])
  276.                                         break
  277.                                     else break end
  278.                                 else break end
  279.                             end
  280.                         end
  281.                         break
  282.                     elseif e[4] > actualY+4 or e[4] < actualY then break end
  283.                 else
  284.                     break
  285.                 end
  286.             end
  287.         end
  288.     elseif mode == 2 then
  289.         if x > w-7 then
  290.             actualX = w-7
  291.         end
  292.         if y > w-3 then
  293.             actualY = w-3
  294.         end
  295.         rightClickMenu(actualX, actualY, 2)
  296.         while true do
  297.             local e = {os.pullEvent()}
  298.             if e[1] == "mouse_click" and e[2] == 1 then
  299.                 if e[3] == w and e[4] == 1 then
  300.                     closeApp()
  301.                     break
  302.                 elseif e[3] >= actualX and e[3] <= actualX+8 then
  303.                     if e[4] == actualY then -- cut
  304.                         animSelected(" Cut    ",actualX,actualY,colors.lightGray,colors.black)
  305.                         CUTPATH = shell.resolve(PATH..oldItems[item])
  306.                         COPYPATH = ""
  307.                         break
  308.                     elseif e[4] == actualY+1 then -- copy
  309.                         animSelected(" Copy   ",actualX,actualY+1,colors.lightGray,colors.black)
  310.                         COPYPATH = shell.resolve(PATH..oldItems[item])
  311.                         CUTPATH = ""
  312.                         break
  313.                     elseif e[4] == actualY+2 then -- delete
  314.                         animSelected(" Delete ",actualX,actualY+2,colors.lightGray,colors.black)
  315.                         fs.delete(PATH..oldItems[item])
  316.                         selectedItem = -1
  317.                         break
  318.                     elseif e[4] == actualY+3 then -- rename
  319.                         animSelected(" Rename ",actualX,actualY+3,colors.lightGray,colors.black)
  320.                         local newname = PATH..prompt("Rename",oldItems[item])
  321.                         if not newname == oldItems[item] and not fs.exists(newname) then fs.move(oldItems[item],newname) end
  322.                         break
  323.                     elseif e[4] > actualY+3 or e[4] < actualY then break end
  324.                 else
  325.                     break
  326.                 end
  327.             end
  328.         end
  329.     else
  330.         if x > w-11 then
  331.             actualX = w-11
  332.         end
  333.         if y > h-2 then
  334.             actualY = h-2
  335.         end
  336.         rightClickMenu(actualX, actualY, 3)
  337.         while true do
  338.             local e = {os.pullEvent()}
  339.             if e[1] == "mouse_click" and e[2] == 1 then
  340.                 if e[3] == w and e[4] == 1 then
  341.                     closeApp()
  342.                     break
  343.                 elseif e[3] >= actualX and e[3] <= actualX+12 then
  344.                     if e[4] == actualY then -- paste
  345.                         animSelected(" Paste      ",actualX,actualY,colors.lightGray,colors.black)
  346.                         if COPYPATH ~= "" then
  347.                             if not fs.exists(PATH..fs.getName(COPYPATH)) and fs.exists(COPYPATH) then fs.copy(COPYPATH, PATH..fs.getName(COPYPATH))
  348.                             else
  349.                                 WALL = "Error"
  350.                                 COPYPATH = ""
  351.                             end
  352.                         elseif CUTPATH ~= "" then
  353.                             if not fs.exists(PATH..fs.getName(CUTPATH)) and fs.exists(CUTPATH) then
  354.                                 fs.move(CUTPATH, PATH..fs.getName(CUTPATH))
  355.                                 CUTPATH = ""
  356.                             else
  357.                                 WALL = "Error"
  358.                                 CUTPATH = ""
  359.                             end
  360.                         else
  361.                             WALL = "Cut or Copy something first"
  362.                         end
  363.                         break
  364.                     elseif e[4] == actualY+1 then -- new file
  365.                         animSelected(" New File   ",actualX,actualY+1,colors.lightGray,colors.black)
  366.                         local newfile = PATH..prompt("New File")
  367.                         if not fs.exists(newfile) then
  368.                             local f = fs.open(newfile, "w")
  369.                             f.write("")
  370.                             f.close()
  371.                         else
  372.                             WALL = "Item exists"
  373.                         end
  374.                         break
  375.                     elseif e[4] == actualY+2 then -- new folder
  376.                         animSelected(" New Folder ",actualX,actualY+2,colors.lightGray,colors.black)
  377.                         local newfolder = PATH..prompt("New Folder")
  378.                         if not fs.exists(newfolder) then
  379.                             fs.makeDir(PATH..newfolder)
  380.                         else
  381.                             WALL = "Item exists"
  382.                         end
  383.                         break
  384.                     elseif e[4] > actualY+2 or e[4] < actualY then break end
  385.                 else
  386.                     break
  387.                 end
  388.             end
  389.         end
  390.     end
  391. end
  392.  
  393. local function evtHandler()
  394.     drawScreen()
  395.     while RUNNING do
  396.         local e = {os.pullEvent()}
  397.         if e[1] == "mouse_click" and e[2] == 1 and e[3] == w and e[4] == 1 then
  398.             closeApp()
  399.         elseif e[1] == "key" and e[2] == keys.q then
  400.             closeApp()
  401.         elseif e[1] == "mouse_scroll" then
  402.             if e[2] == 1 and scrollpos < pospossible then
  403.                 scrollpos = scrollpos+1
  404.             elseif e[2] == -1 and scrollpos > 1 then
  405.                 scrollpos = scrollpos-1
  406.             end
  407.             --logVars()
  408.             drawItems()
  409.         elseif e[1] == "mouse_click" and e[2] == 1 and e[3] >= 1 and e[3] <= 3 and e[4] == 2 then
  410.             animSelected(" < ",1,2,colors.gray,colors.lightGray)
  411.             if PATH ~= "/" then
  412.                 for i = PATH:len()-1,1,-1 do
  413.                     if string.sub(PATH,i,i) == "/" then
  414.                         PATH = string.sub(PATH,1,i)
  415.                         break
  416.                     end
  417.                 end
  418.                 selectedItem = -1
  419.                 scrollpos = 1
  420.                 drawScreen()
  421.             else
  422.                 printPos(" < ",1,2,colors.lightGray,colors.white)
  423.             end
  424.         elseif e[1] == "mouse_click" then
  425.             if e[4] >= 3 then
  426.                 pos = (e[4]-3)+scrollpos
  427.                 if pos <= #oldItems then
  428.                     if e[3] >= 5 and e[3] <= oldItems[pos]:len()+4 then
  429.                         if pos == selectedItem then
  430.                             if pos < beginFiles and e[2] == 1 then
  431.                                 PATH = PATH..oldItems[pos].."/"
  432.                                 selectedItem = -1
  433.                                 scrollpos = 1
  434.                                 drawScreen()
  435.                             elseif pos >= beginFiles and e[2] == 1 then
  436.                                 run(PATH..oldItems[pos])
  437.                             else
  438.                                 if pos < beginFiles and e[2] == 2 then -- folder mode
  439.                                     rightClickHandler(e[3],e[4],2,pos)
  440.                                     drawScreen()
  441.                                 elseif pos >= beginFiles and e[2] == 2 then -- file mode
  442.                                     rightClickHandler(e[3],e[4],1,pos)
  443.                                     drawScreen()
  444.                                 end
  445.                             end
  446.                         else
  447.                             selectedItem = pos
  448.                             drawItems()
  449.                             if pos >= beginFiles and e[2] == 2 then -- file mode
  450.                                 rightClickHandler(e[3],e[4],1,pos)
  451.                                 drawScreen()
  452.                             elseif pos < beginFiles and e[2] == 2 then -- folder mode
  453.                                 rightClickHandler(e[3],e[4],2,pos)
  454.                                 drawScreen()
  455.                             end
  456.                         end
  457.                     else
  458.                         selectedItem = -1
  459.                         drawItems()
  460.                         if e[2] == 2 then
  461.                             rightClickHandler(e[3],e[4],3,pos)
  462.                             drawScreen()
  463.                         end
  464.                     end
  465.                 else
  466.                     selectedItem = -1
  467.                     drawItems()
  468.                     if e[2] == 2 then
  469.                         rightClickHandler(e[3],e[4],3,pos)
  470.                         drawScreen()
  471.                     end
  472.                 end
  473.             end
  474.         elseif e[1] == "term_resize" then
  475.             w,h = term.getSize()
  476.             drawScreen()
  477.         end
  478.     end
  479. end
  480.  
  481. evtHandler()
  482. clear(colors.black)
  483. coroutine.yield()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement