Advertisement
eniallator

EniOS with file system compression

Jun 4th, 2016
1,139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 44.90 KB | None | 0 0
  1. -- This is eniallator's OS that is in the form of a GUI.
  2. -- The way it works is through left click navigation right click drop down menu's so to get started just right click in the black space to create new folders/apps
  3. -- If you want to try to get a better understanding of how it works, then i have completely commented my code so feel free to read it.
  4. -- You can also search for folders/files by simply typing, This will only handle lowercase a-z characters, numbers and also backspaces. It's lowercase because it will search with the apps as lowercase.
  5. -- For full details on features/changelogs i have a computercraft forums link that i update whenever i make a change - http://www.computercraft.info/forums2/index.php?/topic/25954-enios-the-interactive-gui-os/
  6. --
  7. -- ================================================================================
  8. --
  9. -- To make your own apps, you can either run this program once (it will create a folder from which you can use pastebin/ even edit in to make apps). Or you can right click on the screen (not on an app and when the program is running) and you can choose App from the drop down menu.
  10. -- This has alot of features and configurable options e.g app icon size or even the colour theme, so be sure to look below at the variables and config to your liking.
  11.  
  12. -- =============================== User Config Below ==============================
  13.  
  14. local folderDir = "eniOSApps"
  15. local osVersion = "1.5.2"
  16. -- Defining folderDir as the folder you keep your apps in and the osVersion is the version of the os you are using
  17.  
  18. local editFile = ".EniOSEditFile"
  19. local runFile = ".EniOSRunFile"
  20. local compressedFileExtension = ".enicmprs"
  21. -- Defining the temporary files for compression and decompression aswell as the extension it uses
  22.  
  23. local appMaxHeight = 3
  24. local appMaxNameLength = 11
  25. -- appMaxHeight is the height of the icons on the page and namelength will not only concatenate the apps to that value, it will also be the width of the icons on the page
  26.  
  27. local pageNumber = 1
  28. -- Setting the page number that the program loads with
  29.  
  30. local colours = {
  31.   app = colors.blue,
  32.   folder = colors.lightBlue,
  33.   addNew = colors.cyan,
  34.   page = colors.green,
  35.   dropMenuTop = colors.gray,
  36.   dropMenuBottom = colors.lightGray,
  37.   infoText = colors.lightBlue,
  38.   decoText = colors.yellow,
  39.   searchBackground = colors.cyan,
  40.   filterBackground = colors.purple,
  41.   filterOn = colors.lime,
  42.   filterOff = colors.red
  43. }
  44. -- Colour theme for the apps and the page icons
  45.  
  46. -- ============================== End Of User Config ==============================
  47.  
  48. if fs.exists(folderDir) and not fs.isDir(folderDir) then
  49.  
  50.   error("folderDir variable is assigned to an already existing file.")
  51. end
  52. -- Seeing if the folderDir is a file already on the local computer
  53.  
  54. if not fs.exists(folderDir) then
  55.  
  56.   fs.makeDir(folderDir)
  57. end
  58. -- Making the folderDir if its not already made
  59.  
  60. shell.run("clear")
  61. term.setTextColor(colours.infoText)
  62. print("Setting things up...")
  63. -- The boot up message
  64.  
  65. local maxX,maxY = term.getSize()
  66. -- Getting the max dimensions of the screen
  67.  
  68. local searchFilterName = "Filter"
  69. -- The word that is displayed where the filter is
  70.  
  71. local activeFilterTags = {}
  72. -- Defining a table that i will be keeping the active filter tags in
  73.  
  74. local terminate = false
  75. -- Defining the terminate variable as false to use later on
  76.  
  77. local clipboard = nil
  78. -- Defining the clipBoard variable as nil for use later on
  79.  
  80. local addNewVisible = true
  81. -- Setting the AddNew icon to visible
  82.  
  83. local oldPullEvent = os.pullEvent
  84. os.pullEvent = os.pullEventRaw
  85. -- Defining os.pullEvent as os.pullEventRaw so that the read() function will use raw instead of the normal os.pullEvent
  86.  
  87. local dropMenuPower = {
  88.   Terminate = function() terminate = true end,
  89.   Restart = function() os.reboot() end,
  90.   Shutdown = function() os.shutdown() end
  91. }
  92. -- Functions that are called when the user left clicks the power button on the top right
  93.  
  94. local dropMenuFilterTags = {
  95.   Folders = function() checkFilterTags("Folders") end,
  96.   Files = function() checkFilterTags("Files") end,
  97.   Hidden = function() checkFilterTags("Hidden") end,
  98.   AddNew = function() checkAddNew() end
  99. }
  100. -- Tag Filters that will be displayed visually
  101.  
  102. local dropMenuFolders = {
  103.   Delete = function(name) fs.delete(appFolder .. "/" .. name) end,
  104.   Copy = function(name) clipboard = {appFolder, name} end
  105. }
  106. -- Functions that are called when the user right clicks an option for a folder in the drop menu
  107.  
  108. local dropMenuApps = {
  109.   Delete = function(name) fs.delete(appFolder .. "/" .. name) end,
  110.   Copy = function(name) clipboard = {appFolder, name} end,
  111.   Edit = function(name)
  112.  
  113.     local tempFile = fs.open(editFile,"w")
  114.     tempFile.write(decompress(appFolder .. "/" .. name))
  115.     tempFile.close()
  116.     -- Preparing the temporary file with the file to edit's contents
  117.  
  118.     shell.run("edit " .. editFile)
  119.     -- Editting the temporary file instead of the file from the file system
  120.  
  121.     local currFile = fs.open(appFolder .. "/" .. name, "w")
  122.     currFile.write(compress(editFile))
  123.     currFile.close()
  124.     -- Writing the compressed version of the file to the file system
  125.  
  126.     fs.delete(editFile)
  127.   end,
  128.   Rename = function(name)
  129.  
  130.     clearScreen()
  131.     term.setTextColor(colours.infoText)
  132.     print("Enter the new name of the app below or press enter again to not rename:")
  133.     -- Prompting the user for an input
  134.  
  135.     term.setTextColor(colors.white)
  136.     local newName = read() .. compressedFileExtension
  137.     -- Getting user input
  138.  
  139.     term.setTextColor(colours.infoText)
  140.     -- Setting the text colour so i don't have to set it in the if statements
  141.  
  142.     if not fs.exists(appFolder .. "/" .. newName) then
  143.       -- Checking if the name doesn't already exist in the current directory
  144.  
  145.       fs.move(appFolder .. "/" .. name, appFolder .. "/" .. newName)
  146.       print("File successfully renamed")
  147.       sleep(1)
  148.       -- If the directory already doesn't have an app/folder of that name then it will rename the app
  149.  
  150.     elseif newName == "" then
  151.       -- Checking if they have put anything in the read()
  152.  
  153.       print("New name not set")
  154.       sleep(1)
  155.       -- If they haven't put anything in the read() then it won't try to set a new name
  156.     else
  157.  
  158.       print("Name already exists in current directory")
  159.       sleep(1)
  160.       -- Informing the user that the name they chose already exists
  161.     end
  162.   end
  163. }
  164. -- Functions that are called when the user right clicks an option for an app in the drop menu
  165.  
  166. local dropMenuOpts = {
  167.   App = function()
  168.  
  169.     clearScreen()
  170.     eniOS()
  171.     -- Loading the OS version
  172.  
  173.     term.setCursorPos(1,2)
  174.     term.setTextColor(colours.infoText)
  175.     print("Enter name of new app below or leave blank to not create:")
  176.     term.setTextColor(colors.white)
  177.     -- Prompting the user to enter the new app name
  178.  
  179.     local appName = wordSplit(read())
  180.     -- Immediately splitting the user input at the spaces
  181.  
  182.     if appName[1] and not fs.exists(appFolder .. "/" .. appName[1]) then
  183.       -- Checking if the user inputted a app name and seeing if it exists already or not
  184.  
  185.       shell.run("edit " .. editFile)
  186.       -- Edit the new file
  187.  
  188.       if fs.exists(editFile) then
  189.         -- Seeing if the user has made any changes to the editted temporary file
  190.  
  191.         local userFile = fs.open(appFolder .. "/" .. appName[1] .. compressedFileExtension, "w")
  192.         userFile.write(compress(editFile))
  193.         userFile.close()
  194.         -- If the user has made changes to the temp file, it will compress the file and write the compressed version to the file system
  195.  
  196.         fs.delete(editFile)
  197.         -- Deleting the temporary file
  198.       end
  199.  
  200.     elseif appName[1] and fs.exists(appName[1]) then
  201.  
  202.       term.setTextColor(colours.infoText)
  203.       print("Name already exists")
  204.       sleep(1)
  205.       -- Notifying the user that the name already exists
  206.     else
  207.  
  208.       term.setTextColor(colours.infoText)
  209.       print("No new app created")
  210.       sleep(1)
  211.       -- If the user didn't enter something then it gives a message, sleeps (so the user can see the message) and then goes back to the app page
  212.     end
  213.   end,
  214.  
  215.   Folder = function()
  216.  
  217.     clearScreen()
  218.     eniOS()
  219.     -- Loading the OS version
  220.  
  221.     term.setCursorPos(1,2)
  222.     term.setTextColor(colours.infoText)
  223.     print("Enter the name of the new folder below or leave blank to not create:")
  224.     term.setTextColor(colors.white)
  225.     -- Prompting the user for the new folder name
  226.  
  227.     local folderName = wordSplit(read())
  228.     -- Immediately splitting the user input into a table
  229.  
  230.     if folderName[1] and not fs.exists(folderName[1]) then
  231.       -- Checking if the user inputted a app name and seeing if it exists already or not
  232.  
  233.       fs.makeDir(appFolder .. "/" .. folderName[1])
  234.       -- Makes the new folder
  235.  
  236.     elseif folderName[1] and fs.exists(folderName[1]) then
  237.       -- Catches if the user has inputted an folder name that already exists
  238.  
  239.       term.setTextColor(colours.infoText)
  240.       print("Name already exists")
  241.       sleep(1)
  242.       -- Notifying the user that the name they have inputted already exists
  243.     else
  244.  
  245.       term.setTextColor(colours.infoText)
  246.       print("No new folder created")
  247.       sleep(1)
  248.       -- If the user didn't enter something then it gives a message, sleeps (so the user can see the message) and then goes back to the app page
  249.     end
  250.   end
  251. }
  252. -- The drop menu you see if you don't right click on an app
  253.  
  254. if http then
  255.   -- First seeing if you have the http api enabled before doing anything
  256.  
  257.   local testFile = http.get("http://pastebin.com/raw.php?i=DSMHN2iF")
  258.  
  259.   if testFile then
  260.  
  261.     testPaste = testFile.readAll()
  262.     testFile.close()
  263.     -- Reading a test file that i have made just to make sure you can access pastebin.com
  264.   end
  265.  
  266.   if testPaste == "test" then
  267.     -- Seeing if the test paste has "test" in it's contents (should always return test)
  268.  
  269.     dropMenuOpts.Pastebin = function()
  270.       -- Adding the Pastebin option to the dropMenuOpts
  271.  
  272.       clearScreen()
  273.       eniOS()
  274.       -- Loading the OS version
  275.  
  276.       term.setCursorPos(1,2)
  277.       term.setTextColor(colours.infoText)
  278.       print("Enter the pastebin url after http://pastebin.com/ below or leave blank to not create:")
  279.       term.setTextColor(colors.white)
  280.       -- Prompting the user for the pastebin url
  281.  
  282.       local pasteURL = wordSplit(read())
  283.       -- Immediately splitting the user input into a table
  284.  
  285.       if pasteURL[1] then
  286.         -- Seeing if the user has entered anything
  287.  
  288.         local pasteFile = http.get("http://pastebin.com/raw.php?i=" .. textutils.urlEncode(pasteURL[1]))
  289.         local pasteContents = pasteFile.readAll()
  290.         pasteFile.close()
  291.         -- Getting the user's file from pastebin
  292.  
  293.         if pasteContents then
  294.           -- Checking if the pastebin url is valid and is actually a file
  295.  
  296.           term.setTextColor(colours.infoText)
  297.           print("Enter the file name you want to download as:")
  298.           term.setTextColor(colors.white)
  299.           -- Prompting the user for the file name to download as
  300.  
  301.           local pasteFile = wordSplit(read())
  302.           -- Getting the file name and splitting the user input into a table
  303.  
  304.           if pasteFile[1] and not fs.exists(appFolder .. "/" .. pasteFile[1]) then
  305.             -- Checking if the user has entered anything and also checking if the file already exists or not
  306.  
  307.             local file = fs.open(appFolder .. "/" .. pasteFile[1], "w")
  308.             file.write(pasteContents)
  309.             file.close()
  310.             -- If everything goes well it will make the file
  311.  
  312.             term.setTextColor(colours.infoText)
  313.             print("Successfully made file")
  314.             sleep(1)
  315.             -- Letting the user know it was successful
  316.  
  317.           elseif pasteFile[1] and fs.exists(appFolder .. pasteFile[1]) then
  318.             -- Catching if the use has entered a file name but it already exists
  319.  
  320.             term.setTextColor(colours.infoText)
  321.             print("File already exists. Press Y to force or enter another key to not force:")
  322.             local event, key, held = os.pullEvent("key")
  323.             -- Seeing if the user wants to force make the file
  324.  
  325.             if key == 21 then
  326.               -- In this case 21 is the key Y
  327.  
  328.               local file = fs.open(appFolder .. "/" .. pasteFile[1], "w")
  329.               file.write(pasteContents)
  330.               file.close()
  331.               -- Writing over the old file with the newly downloaded file
  332.  
  333.               term.setTextColor(colours.infoText)
  334.               print("Successfully force made file")
  335.               sleep(1)
  336.               -- Letting the use know that the file was replaced
  337.             else
  338.  
  339.               term.setTextColor(colours.infoText)
  340.               print("Aborted making the file")
  341.               sleep(1)
  342.               -- If the user hasn't entered a valid name e.g either spaces or nothing
  343.             end
  344.           end
  345.         else
  346.  
  347.           term.setTextColor(infoText)
  348.           print("Invalid paste URL")
  349.           sleep(1)
  350.           -- Letting the user know that the pastebin url's contents aren't there e.g invalid url
  351.         end
  352.       else
  353.  
  354.         term.setTextColor(colours.infoText)
  355.         print("No url specified")
  356.         sleep(1)
  357.         -- If no input was given it returns to the app page
  358.       end
  359.     end
  360.   end
  361. end
  362. -- First checking if the user can access pastebin.com and if they can then will add the pastebin option to dropMenuOpts
  363.  
  364. local filterTags = {
  365.  
  366.   Folders = function (tab)
  367.  
  368.     local out = {}
  369.     -- Defining the out table to be later returned
  370.  
  371.     for i=1, #tab do
  372.       -- Iterating for the amount of values the tab table has
  373.  
  374.       if not fs.isDir(appFolder .. "/" .. tab[i]) then
  375.  
  376.         table.insert(out,#out+1,tab[i])
  377.       end
  378.       -- Removing the folders from the table
  379.     end
  380.  
  381.     return out
  382.     -- Returning the filtered table
  383.   end,
  384.  
  385.   Files = function (tab)
  386.  
  387.     local out = {}
  388.     -- Defining the out table to be later returned
  389.  
  390.     for i=1,#tab do
  391.       -- Iterating for the amount of values the tab table has
  392.  
  393.       if fs.isDir(appFolder .. "/" .. tab[i]) then
  394.  
  395.         table.insert(out,#out+1,tab[i])
  396.       end
  397.       -- Removing the files from the table
  398.     end
  399.  
  400.     return out
  401.     -- Returning the filtered table
  402.   end,
  403.  
  404.   Hidden = function (tab)
  405.  
  406.     local out = {}
  407.     -- Defining the out table to be later returned
  408.  
  409.     for i=1,#tab do
  410.       -- Iterating for the amount of values the tab table has
  411.  
  412.       if tab[i]:sub(1,1) ~= "." then
  413.  
  414.         table.insert(out,#out+1,tab[i])
  415.       end
  416.       -- Adding the Filtered Files to the out table
  417.     end
  418.  
  419.     return out
  420.     -- Returning the filtered table
  421.   end,
  422.  
  423.   AddNew = function(tab) return tab end
  424. }
  425. -- The tags that the directory can be filtered for
  426.  
  427. local numFilterTags = 0
  428.  
  429. for key,val in pairs(dropMenuFilterTags) do
  430.  
  431.   numFilterTags = numFilterTags + 1
  432. end
  433. -- Getting the number of filter tags for later use
  434.  
  435. for key,val in pairs(dropMenuFilterTags) do
  436.   -- Iterating for the number of key/value pairs in dropMenuFilterTags
  437.  
  438.   if key == "Hidden" then
  439.     -- Seeing if the key is "Hidden"
  440.  
  441.     activeFilterTags[key] = true
  442.     -- Setting the key to activated
  443.   else
  444.  
  445.     activeFilterTags[key] = false
  446.     -- Setting the key to deactivated
  447.   end
  448. end
  449. -- Making the activeFilterTags table
  450.  
  451. local directoryBeforeSearch
  452. -- Declaring directoryBeforeSearch variable here so i can compare with it later on
  453.  
  454. function checkFilterTags(name)
  455.   if activeFilterTags[name] then
  456.     -- Seeing what the status of the filter was before
  457.  
  458.     activeFilterTags[name] = false
  459.     -- Removing the filter from the active tags list
  460.   else
  461.  
  462.     activeFilterTags[name] = true
  463.     pageNumber = 1
  464.     -- Adding the filter to the tags list aswell as resetting the page number so it won't error
  465.   end
  466. end
  467.  
  468. function checkAddNew()
  469.   if activeFilterTags.AddNew then
  470.     -- Seeing what the status of AddNew was before
  471.  
  472.     activeFilterTags.AddNew = false
  473.     addNewVisible = true
  474.     -- Removing AddNew from the active tags list and setting it's visibility to true
  475.   else
  476.  
  477.     activeFilterTags.AddNew = true
  478.     pageNumber = 1
  479.     addNewVisible = false
  480.     -- Adding AddNew to the tags list aswell as resetting the page number so it won't error and setting it's visibility to false
  481.   end
  482. end
  483.  
  484. function fileSort(fileTab,appFolder,searchWord)
  485.  
  486.   local out = {}
  487.   local files = {}
  488.  
  489.   for key,val in pairs(activeFilterTags) do
  490.     -- iterating over the activeFilterTags table
  491.  
  492.     if val then
  493.  
  494.       fileTab = filterTags[key](fileTab)
  495.       -- Assigning fileTab to the new table that the filterTags tag will return
  496.     end
  497.   end
  498.   -- Applying any filters that the user has put on
  499.  
  500.   directoryBeforeSearch = fileTab
  501.   -- Defining directoryBeforeSearch as fileTab before it has been filtered with the search word
  502.  
  503.   for i=1,#fileTab do
  504.  
  505.     local searchedName = fileTab[i]:lower():sub(1,#fileTab[i]-#compressedFileExtension)
  506.     -- Defining the searchedName variable for files
  507.  
  508.     if fs.isDir(appFolder .. "/" .. fileTab[i])  and fileTab[i]:lower():find(searchWord) then
  509.       -- First iterating for the amount of items in the fileTab table and then checking if its a directory and putting it in the appropriate table
  510.  
  511.       table.insert(out,#out+1,fileTab[i])
  512.  
  513.     elseif searchedName:find(searchWord) then
  514.       if fileTab[i]:lower():sub(#fileTab[i]-#compressedFileExtension+1,#fileTab[i]) ~= compressedFileExtension then
  515.  
  516.         local tempVarFile = fs.open(appFolder .. "/" .. fileTab[i],"r")
  517.         local tempVarFileContents = tempVarFile.readAll()
  518.         tempVarFile.close()
  519.  
  520.         local tempFile = fs.open(editFile,"w")
  521.         tempFile.write(tempVarFileContents)
  522.         tempFile.close()
  523.  
  524.         local actualFile = fs.open(appFolder .. "/" .. fileTab[i],"w")
  525.         actualFile.write(compress(editFile))
  526.         actualFile.close()
  527.  
  528.         fs.delete(editFile)
  529.  
  530.         fs.move(appFolder .. "/" .. fileTab[i], appFolder .. "/" .. fileTab[i] .. compressedFileExtension)
  531.       end
  532.  
  533.       table.insert(files,#files+1,fileTab[i])
  534.     end
  535.   end
  536.   -- Sorting the fileTab table into the files and out table
  537.  
  538.   for i=1,#files do
  539.  
  540.     table.insert(out,#out+1,files[i])
  541.   end
  542.   -- merging the files table with the out table
  543.  
  544.   if addNewVisible then
  545.     -- Checking if the visible var is true
  546.  
  547.     out[#out+1] = "+"
  548.     -- Making the addNew icon
  549.   end
  550.  
  551.   return out
  552.   -- Returning the sorted table
  553. end
  554. -- Function for sorting files and folders so that the folders will appear first
  555.  
  556. function fileToLines(file)
  557.  
  558.   local read = fs.open(file,"r")
  559.   local lines = {}
  560.  
  561.   while true do
  562.  
  563.     local currLine = read.readLine()
  564.  
  565.     if currLine then
  566.  
  567.       table.insert(lines, currLine)
  568.     else
  569.  
  570.       break
  571.     end
  572.   end
  573.   -- While loop to keep on adding the current line to a table and if theres no current line, it will break
  574.  
  575.   read.close()
  576.   return lines
  577. end
  578. -- Function to return a table of the lines of a file
  579.  
  580. function wordSplit(string)
  581.  
  582.   local out = {}
  583.  
  584.   for word in string:gmatch("%S+") do
  585.     -- Splitting the string at the spaces
  586.  
  587.     table.insert(out, word)
  588.     -- Inserting the value into a table
  589.   end
  590.  
  591.   return out
  592.   -- Returning the table
  593. end
  594. -- Receives a string and returns a table that's the string split at the spaces
  595.  
  596. function fillArea(tab)
  597.  
  598.   term.setBackgroundColor(tab[5])
  599.   -- Setting the right background colour
  600.  
  601.   for i=0,tab[4]-tab[2] do
  602.     -- Running for how many rows there are (indexes 2,4 == y values and indexes 1,3 == x values in the table)
  603.  
  604.     local j = 0
  605.  
  606.     while j <= tab[3]-tab[1] do
  607.       -- I use a while loop here because i iterate up with variable amounts
  608.  
  609.       term.setCursorPos(tab[1]+j,tab[2]+i)
  610.       -- Positioning the cursor for the next string whether it be a space or the word
  611.  
  612.       if tab[6] and math.floor(j-((tab[3]-tab[1])/2)+#tab[6]/2) == 0 and math.floor(i-(tab[4]-tab[2])/2) == 0 then
  613.         -- If statement seeing whether the iterators have hit the place where it should be writing the word out
  614.  
  615.         term.write(tab[6])
  616.         j = j + #tab[6]
  617.         -- Only runs when the above if statement has found the place where the word will be centered
  618.       else
  619.  
  620.         j = j + 1
  621.         term.write(" ")
  622.         -- Writing " " so the background text colour is visible
  623.       end
  624.     end
  625.   end
  626. end
  627. -- Defining the function for filling an area of the screen with a word centered in it
  628.  
  629. function checkNum(num)
  630.  
  631.   local out = ""
  632.  
  633.   while num > 254 do
  634.  
  635.     out = out .. string.char(0)
  636.     num = num - 254
  637.   end
  638.   -- While to iterate when num is bigger than 254
  639.  
  640.   if num >= 13 then num = num + 1 end
  641.   -- Making sure num isn't byte 13
  642.  
  643.   return out .. string.char(num)
  644.   -- Returning the bytes instead of the number.
  645. end
  646. -- Function that compression uses, if the number given in the arguments is bigger than 254 it will keep on adding the byte 0 to the return
  647.  
  648. function compress(fileName)
  649.  
  650.   local lines = fileToLines(fileName)
  651.   -- Splitting the file into it's lines in a table
  652.   local outTable = {{}}
  653.  
  654.   for line=1,#lines do
  655.  
  656.     local spaces = 0
  657.     local word = ""
  658.     outTable[line+1] = {}
  659.  
  660.     local function sortWord(word)
  661.       if #word > 0 then
  662.  
  663.         local wordFound = false
  664.  
  665.         for i=1,#outTable[1] do
  666.           -- Iterating over the first index of outTable
  667.  
  668.           if outTable[1][i] == word then
  669.             -- Checking if the word already exists or not
  670.  
  671.             table.insert(outTable[line+1],i+3)
  672.             wordFound = true
  673.             break
  674.           end
  675.         end
  676.  
  677.         if not wordFound then
  678.  
  679.           table.insert(outTable[1],word)
  680.           table.insert(outTable[line+1],#outTable[1]+3)
  681.         end
  682.         -- Adding the word to the index if it hasn't been found
  683.  
  684.       end
  685.     end
  686.     -- Function to add any new words to the index
  687.  
  688.     local function sortSpaces(spaces)
  689.       if spaces > 0 then
  690.  
  691.         if spaces > 1 then
  692.           -- Checking if the number of spaces is bigger than 1 so it can add a different byte depending on if it is or not
  693.  
  694.           table.insert(outTable[line+1],2)
  695.           table.insert(outTable[line+1],spaces)
  696.         else
  697.  
  698.           table.insert(outTable[line+1],3)
  699.         end
  700.       end
  701.     end
  702.     -- Function to handle spaces in the file
  703.  
  704.     local currLine = ""
  705.  
  706.     for i=1,#lines[line] do
  707.       -- For to handle the entire compression to convert the file into bytes
  708.  
  709.       local currChar = lines[line]:sub(i,i)
  710.  
  711.       if currChar == " " then
  712.         -- A crude way to split up the lines into words and spaces
  713.  
  714.         spaces = spaces + 1
  715.         sortWord(word)
  716.         word = ""
  717.       else
  718.  
  719.         word = word .. currChar
  720.         sortSpaces(spaces)
  721.         spaces = 0
  722.       end
  723.     end
  724.  
  725.     sortWord(word)
  726.     sortSpaces(spaces)
  727.   end
  728.  
  729.   local outString = ""
  730.  
  731.   for i=1,#outTable do
  732.     -- For loop to combine the outTable into an output string
  733.  
  734.     for j=1,#outTable[i] do
  735.       if i == 1 then
  736.         if #outString > 0 then outString = outString .. " " end
  737.  
  738.         outString = outString .. outTable[i][j]
  739.       else
  740.  
  741.         outString = outString .. checkNum(outTable[i][j])
  742.       end
  743.     end
  744.  
  745.     if i == 1 then
  746.       -- Adding the new line character to the end of the line. The index is always at line 1 so i choose to add a \n to the end of line 1
  747.  
  748.       outString = outString .. "\n"
  749.     else
  750.  
  751.       outString = outString .. string.char(1)
  752.     end
  753.   end
  754.  
  755.   return outString
  756. end
  757. -- The compression function
  758.  
  759. function decompress(fileName)
  760.  
  761.   local lines = fileToLines(fileName)
  762.   -- Splitting the file into it's lines in a table
  763.  
  764.   local index = wordSplit(lines[1])
  765.   -- Seperating the index table from the body table
  766.  
  767.   local body = {}
  768.   table.remove(lines,1)
  769.  
  770.   for line=1,#lines do
  771.     -- For to convert the compressed file into it's original lines and where the indexes should go
  772.  
  773.     if line > 1 then
  774.  
  775.       table.insert(body,10)
  776.     end
  777.     -- Inserting the character 10 every time the file goes onto a new line. This is because character 10 actually is the new line character
  778.  
  779.     for i=1,#lines[line] do
  780.       -- For loop to convert the bytes into the corresponding indexes
  781.  
  782.       local indexNum = string.byte(lines[line]:sub(i))
  783.  
  784.       if indexNum >= 13 then
  785.  
  786.         indexNum = indexNum - 1
  787.       end
  788.  
  789.       table.insert(body,indexNum)
  790.     end
  791.   end
  792.  
  793.   local counter = 1
  794.   local fullFile = ""
  795.  
  796.   while counter < #body do
  797.     -- While loop to convert the indexes into the corresponding words (aparts from the special characters)
  798.  
  799.     if body[counter] == 0 then
  800.       -- Checking if the current index is 0 and then converting it into it's actual index (because 0 means it's bigger than 254)
  801.  
  802.       local multiples = 0
  803.  
  804.       while body[counter] == 0 do
  805.  
  806.         counter = counter + 1
  807.         multiples = multiples + 254
  808.       end
  809.       -- Adding up the multiples of 254
  810.  
  811.       fullFile = fullFile .. index[body[counter] + multiples-3]
  812.       -- Inserting the corresponding word with the full index from adding the multiples and the current index
  813.  
  814.     elseif body[counter] == 1 then
  815.       -- Seeing if the current index is 1 which is the new line character
  816.  
  817.       fullFile = fullFile .. "\n"
  818.  
  819.     elseif body[counter] == 2 then
  820.       -- Seeing if the current index is 2 and then seeing what the next index is to make that next index * spaces.
  821.  
  822.       counter = counter + 1
  823.  
  824.       for i=1,body[counter] do
  825.  
  826.         fullFile = fullFile .. " "
  827.       end
  828.       -- Iterating for the amount of spaces that should be in and adding them
  829.  
  830.     elseif body[counter] == 3 then
  831.       -- Seeing if the current index is 3 and inserting a space into the file
  832.  
  833.       fullFile = fullFile .. " "
  834.  
  835.     else
  836.  
  837.       fullFile = fullFile .. index[body[counter]-3]
  838.     end
  839.     -- If nothing before has caught the index, the corresponding word to that index will be inserted into the file.
  840.  
  841.     counter = counter + 1
  842.   end
  843.  
  844.   return fullFile
  845. end
  846. -- The decompression function
  847.  
  848. function loadApps(appFolder,appFolderNav,searchWord)
  849.  
  850.   local pages = {}
  851.   local apps = fileSort(fs.list(appFolder),appFolder,searchWord)
  852.   -- Getting the app names from the appFolder
  853.  
  854.   local numberXApps = math.floor(maxX/(appMaxNameLength+1))
  855.   -- Seeing how many apps it can fit on one line
  856.  
  857.   if appFolderNav[2] then
  858.  
  859.     negY = 5
  860.   else
  861.  
  862.     negY = 3
  863.   end
  864.   -- Seeing whether or not there needs to be more space for other icons on the page or not
  865.  
  866.   local appsPerPage = math.floor((maxY-negY)/(appMaxHeight+1))*numberXApps
  867.   -- Seeing the total number of apps per page it can fit
  868.  
  869.   for i=1,math.ceil(#apps/appsPerPage) do
  870.     -- Running for the number of pages it has to create
  871.  
  872.     pages[i] = {}
  873.  
  874.     for j=0,appsPerPage-1 do
  875.       -- Running for the number of apps per page
  876.  
  877.       if not apps[1] then break end
  878.       -- Seeing if it has done all the apps in the table
  879.  
  880.       local shortenedAppName = "+"
  881.       -- Defining the shortenedAppName variable locally here
  882.  
  883.       if fs.isDir(appFolder .. "/" .. apps[1]) then
  884.  
  885.         iconType = "folder"
  886.         colour = colours.folder
  887.         -- Setting the iconType var to folder and setting the colour
  888.  
  889.         shortenedAppName = apps[1]:sub(1,appMaxNameLength)
  890.         -- Defining the shortened icon name for the app
  891.  
  892.       elseif apps[1] == "+" then
  893.  
  894.         iconType = "addNew"
  895.         colour = colours.addNew
  896.         -- Setting the iconType var to addNew and setting the colour
  897.  
  898.       else
  899.  
  900.         iconType = "file"
  901.         colour = colours.app
  902.         -- Setting the iconType var to file and setting the colour
  903.  
  904.         shortenedAppName = apps[1]:sub(1,#apps[1]-#compressedFileExtension):sub(1,appMaxNameLength)
  905.         -- Defining the shortened icon name for the app
  906.       end
  907.       -- Seeing what icon colour to display for apps[1]
  908.  
  909.       local indent = (j%numberXApps)*appMaxNameLength+(j%numberXApps)+2
  910.       -- Finding what the indent of the X value is
  911.  
  912.       pages[i][j+1] = {indent,negY+math.floor(j/numberXApps)*(appMaxHeight+1),indent+appMaxNameLength-1,appMaxHeight+negY-1+math.floor(j/numberXApps)*(appMaxHeight+1),colour,shortenedAppName,apps[1],iconType}
  913.       -- Making the value for each app in a table in the following format: {x1,y1,x2,y2,background colour, substringed app name (for display purposes), original app name, icon type}
  914.  
  915.       table.remove(apps,1)
  916.       -- Removing the last value from the table
  917.     end
  918.  
  919.     if not apps[1] then break end
  920.     -- Seeing if it has done all the apps in the table
  921.   end
  922.  
  923.   return pages
  924.   -- Returning the pages table after making it
  925. end
  926. -- Making a function to load the apps from the appFolder into a table thats split up into pages
  927.  
  928. function eniOS()
  929.  
  930.   term.setCursorPos(1,1)
  931.   term.setTextColor(colours.decoText)
  932.   term.write("EniOS Version: " .. osVersion)
  933.   term.setTextColor(colors.white)
  934. end
  935. -- Displaying the version number at the top left of the screen
  936.  
  937. function otherArea(pageNumber)
  938.   return {
  939.   plus = {maxX-math.ceil((maxX)/2)+1,maxY-1,maxX,maxY-1,colours.page,"page "..pageNumber+1},
  940.   minus = {1,maxY-1,math.floor((maxX)/2)-1,maxY-1,colours.page,"page "..pageNumber-1},
  941.   power = {maxX-2,1,maxX,1,colors.red,"O"},
  942.   back = {1,3,2,3,colours.page,"<"},
  943.   searchBar = {1,maxY,maxX-#searchFilterName-1,maxY,colours.searchBackground},
  944.   searchFilter = {maxX-#searchFilterName-1,maxY,maxX,maxY,colours.filterBackground,searchFilterName}
  945.   }
  946. end
  947. -- Getting the updated pageNumber for the pages aswell as setting the power button at the top right of the screen
  948.  
  949. function addPaste(tab)
  950.   if clipboard then
  951.  
  952.     dropMenuOpts.paste = function() paste() end
  953.   end
  954. end
  955. -- Function to add the paste option once you have a clipboard from using copy
  956.  
  957. function paste()
  958.   if appFolder ~= clipboard[1] then
  959.  
  960.     fs.copy(clipboard[1] .. "/" .. clipboard[2], appFolder .. "/" .. clipboard[2])
  961.   end
  962. end
  963. -- Function for pasting a file
  964.  
  965. function loadPage(pageNumber,appFolderNav,searchWord)
  966.  
  967.   local otherAreaTab = otherArea(pageNumber)
  968.   -- Getting the otherArea table with the updated pageNumber
  969.  
  970.   local topFolder = fs.list(folderDir)
  971.   -- Defining topFolder as the folders/files in the upper folder to be used later on
  972.  
  973.   eniOS()
  974.   -- displaying the OS Version
  975.  
  976.   if appFolderNav[2] then
  977.  
  978.     term.setBackgroundColor(colors.black)
  979.     term.setTextColor(colours.infoText)
  980.     -- Getting the colours ready
  981.  
  982.     local dirLink = "CC:" .. appFolderNav[2]
  983.     -- Defining the dirLink variable so it won't concatenate with what it was before
  984.  
  985.     for i=1,#appFolderNav-2 do
  986.  
  987.       dirLink = dirLink .. "/" .. appFolderNav[i+2]
  988.     end
  989.     -- Making the dirLink by conatenation without what folderDir is
  990.  
  991.     if #dirLink > maxX-4 then
  992.  
  993.       dirLink = dirLink:sub(#dirLink-maxX+4,#dirLink)
  994.     end
  995.  
  996.     term.setCursorPos(4,3)
  997.     term.write(dirLink)
  998.     term.setTextColor(colors.white)
  999.     -- Seeing if dirLink is longer than the page and making a sub string if it is when writing it out
  1000.   end
  1001.   -- Seeing if the user is in a folder and then displaying the back button and the directory link
  1002.  
  1003.   if appPages[1] then
  1004.     for i=1,#appPages[pageNumber] do
  1005.  
  1006.       fillArea(appPages[pageNumber][i])
  1007.     end
  1008.   end
  1009.   -- Displaying the app icons on the screen
  1010.  
  1011.   for key,val in pairs(otherAreaTab) do
  1012.     -- Iterating for all of the values in the otherAreaTab table
  1013.  
  1014.     local fillCatch = true
  1015.     -- Defining a variable so i can use it later on
  1016.  
  1017.     if key == "searchBar"then
  1018.       if directoryBeforeSearch[1] then
  1019.  
  1020.         fillArea(val)
  1021.       end
  1022.  
  1023.       fillCatch = false
  1024.     end
  1025.     -- Seeing if there are appPages then it will display the search bar
  1026.  
  1027.     if key == "minus" then
  1028.       if appPages[pageNumber-1] then
  1029.  
  1030.         fillArea(val)
  1031.       end
  1032.  
  1033.       fillCatch = false
  1034.     end
  1035.     -- Seeing if theres a table before displaying the previous page icon
  1036.  
  1037.     if key == "plus" then
  1038.       if appPages[pageNumber+1] then
  1039.  
  1040.         fillArea(val)
  1041.       end
  1042.  
  1043.       fillCatch = false
  1044.     end
  1045.     -- Seeing if theres a table before displaying the next page icon
  1046.  
  1047.     if key == "back" then
  1048.       if appFolderNav[2] then
  1049.  
  1050.         fillArea(val)
  1051.       end
  1052.  
  1053.       fillCatch = false
  1054.     end
  1055.     -- Seeing if the user is in a folder to see if it should display the back icon
  1056.  
  1057.     if fillCatch then
  1058.  
  1059.       fillArea(val)
  1060.     end
  1061.     -- Catching if the other if statements haven't returned true
  1062.   end
  1063.  
  1064.   if #searchWord > 0 then
  1065.     -- Checking if the searchWord has characters in it
  1066.  
  1067.     term.setTextColor(colors.white)
  1068.     term.setBackgroundColor(colours.searchBackground)
  1069.     term.setCursorPos(2,maxY)
  1070.     -- Getting ready for the text to be written
  1071.  
  1072.     local searchWordWrite = searchWord
  1073.     -- Defining another variable as searchWord so that it won't substring searchWord
  1074.  
  1075.     if #searchWord > maxX-5-#searchFilterName then
  1076.       -- Seeing if the searchWord string is longer than the screen
  1077.  
  1078.       searchWordWrite = searchWord:sub(#searchWord-maxX+5+#searchFilterName,#searchWord)
  1079.       -- Making a substring of searchWord so that it will fit on the string
  1080.     end
  1081.  
  1082.     term.write(searchWordWrite)
  1083.     term.setCursorBlink(true)
  1084.     term.setTextColor(colors.white)
  1085.     -- Writing searchWordWrite to the screen and then resetting the text colour
  1086.  
  1087.   elseif directoryBeforeSearch[1] then
  1088.  
  1089.     term.setCursorPos(2,maxY)
  1090.     term.setBackgroundColor(colours.searchBackground)
  1091.     term.setTextColor(colors.white)
  1092.     term.write("Type to search")
  1093.     -- Making place holder text for the search bar
  1094.  
  1095.   elseif not topFolder[1] and activeFilterTags.AddNew then
  1096.  
  1097.     term.setCursorPos(1,3)
  1098.     term.setBackgroundColor(colors.black)
  1099.     term.setTextColor(colours.dropMenuBottom)
  1100.     print("Right click to start making apps/folders")
  1101.     term.setTextColor(colors.white)
  1102.     -- Welcoming the user into the program and telling them how to get started
  1103.   end
  1104. end
  1105. -- Loads the entire page onto the screen using fillArea alot
  1106.  
  1107. function clickedApp(pageNumber,clickX,clickY)
  1108.   if appPages[1] then
  1109.     for i=1, #appPages[pageNumber] do
  1110.       -- Iterating for the number of apps in the page
  1111.  
  1112.       if appPages[pageNumber][i][1] <= clickX and appPages[pageNumber][i][3] >= clickX and appPages[pageNumber][i][2] <= clickY and appPages[pageNumber][i][4] >= clickY then
  1113.         -- Comparing the clicked x and y values with each of the app's x and y values
  1114.  
  1115.         return appPages[pageNumber][i]
  1116.         -- returning the original app name in the appPages table
  1117.       end
  1118.     end
  1119.   end
  1120.  
  1121.   return false
  1122.   -- Returning false if it hasn't already returned a value
  1123. end
  1124. -- Detecting what app the user has clicked (if they have clicked one that is)
  1125.  
  1126. function clickedOther(pageNumber,clickX,clickY)
  1127.   for key,val in pairs(otherArea(pageNumber)) do
  1128.     -- Iterating for the length of the table the otherArea() function returns
  1129.  
  1130.     if val[1] <= clickX and val[3] >= clickX and val[2] <= clickY and val[4] >= clickY then
  1131.       -- Comparing the clicked x and y values with each of the icon's x and y values
  1132.  
  1133.       return key
  1134.       -- Returning the key of the key/value pair in the otherArea table
  1135.     end
  1136.   end
  1137.  
  1138.   return false
  1139.   -- Returning false if the func hasn't already returned a value
  1140. end
  1141. -- Detecting if the user has clicked the page icons or the close icon
  1142.  
  1143. function clearScreen()
  1144.  
  1145.   term.setTextColor(colors.white)
  1146.   term.setBackgroundColor(colors.black)
  1147.   term.setCursorBlink(false)
  1148.   shell.run("clear")
  1149. end
  1150. -- Clearing the screen and resetting the taxt colour and the background colour
  1151.  
  1152. function loadDropMenu(dropMenuOptionsFuncs,name,x,y,filterBool,isCreate)
  1153.  
  1154.   local dropMenuOptions = {}
  1155.  
  1156.   for key,_ in pairs(dropMenuOptionsFuncs) do
  1157.  
  1158.     table.insert(dropMenuOptions,1,key)
  1159.   end
  1160.   -- Making the dropMenuOptions table from the functions's keys
  1161.  
  1162.   if y + #dropMenuOptions > maxY then
  1163.  
  1164.     y = y - (y+#dropMenuOptions-maxY)
  1165.   end
  1166.   -- Seeing if the drop menu will go off the screen and correcting it if it does
  1167.  
  1168.   if x+appMaxNameLength > maxX then
  1169.  
  1170.     x = x - (x+appMaxNameLength-maxX)
  1171.   end
  1172.   -- Seeing if the drop menu will go off the screen and correcting it if it does
  1173.  
  1174.   if name then
  1175.  
  1176.     term.setCursorPos(x,y)
  1177.     fillArea({x,y,x+appMaxNameLength,y,colours.dropMenuTop})
  1178.     term.setCursorPos(x,y)
  1179.  
  1180.     local shortenedName
  1181.  
  1182.     if not fs.isDir(appFolder .. "/" .. name) and not isCreate then
  1183.  
  1184.       shortenedName = name:sub(1,#name-#compressedFileExtension):sub(1,appMaxNameLength)
  1185.     else
  1186.  
  1187.       shortenedName = name:sub(1,appMaxNameLength)
  1188.     end
  1189.     -- Defining shortenedName differently depending on whether its a file or a folder
  1190.  
  1191.     term.write(shortenedName)
  1192.     -- Writing the app name in the right colour and at the right place
  1193.   end
  1194.   -- Seeing if the name argument has been given
  1195.  
  1196.   fillArea({x,y+1,x+appMaxNameLength,y+#dropMenuOptions,colours.dropMenuBottom})
  1197.   -- Filling the below area for the drop menu options
  1198.  
  1199.   for i=1,#dropMenuOptions do
  1200.     -- Iterating through the dropMenuOptions table
  1201.  
  1202.     if filterBool and activeFilterTags[dropMenuOptions[i]] then
  1203.       -- Seeing if filterBool is true and if the filter is active
  1204.  
  1205.       term.setTextColor(colours.filterOn)
  1206.       -- Setting the text colour to filterOn if the filter is on
  1207.  
  1208.     elseif filterBool then
  1209.       -- Seeing if filterBool is true but the filter is not active
  1210.  
  1211.       term.setTextColor(colours.filterOff)
  1212.       -- Setting the text colour to filterOff if the filter is off
  1213.     end
  1214.  
  1215.     term.setCursorPos(x,y+i)
  1216.     term.write(dropMenuOptions[i]:sub(1,appMaxNameLength))
  1217.     term.setTextColor(colors.white)
  1218.   end
  1219.   -- Writing the options in their places and making sure they don't go over the appMaxNameLength
  1220.  
  1221.   return dropMenuOptions,dropMenuOptionsFuncs,name,x,y
  1222.   -- Returning the changed coordinates of the drop menu
  1223. end
  1224. -- Loading the drop menu from where the user has clicked
  1225.  
  1226. function dropMenu(dropMenuOptions,dropMenuOptionsFuncs,name,x,y)
  1227.  
  1228.   local event, button, clickX, clickY = os.pullEvent("mouse_click")
  1229.   -- Getting a user mouse click input
  1230.  
  1231.   if button == 1 then
  1232.     -- Seeing if the user has left clicked
  1233.  
  1234.     for i=1,#dropMenuOptions do
  1235.       --Iterating for the amount of options in the drop menu
  1236.  
  1237.       if x <= clickX and x+appMaxNameLength >= clickX and y+i <= clickY and y+i >= clickY then
  1238.         -- Detecting whether the user has clicked an option
  1239.  
  1240.         dropMenuOptionsFuncs[dropMenuOptions[i]](name)
  1241.         -- Running the function in the drop menu
  1242.       end
  1243.     end
  1244.   end
  1245. end
  1246. -- Function for detecting if the user has clicked an option in the drop menu
  1247.  
  1248. appFolderNav = {folderDir}
  1249. -- Making the nav table so its easy to modify the directory navigation
  1250.  
  1251. local event = "mouse_click"
  1252. -- Giving the event var a value
  1253.  
  1254. local searchWord = ""
  1255. -- Defining searchWord as an empty string
  1256.  
  1257. while not terminate do
  1258.   -- Running while the terminate variable is false
  1259.  
  1260.   appFolder = ""
  1261.   -- Defining the appFolder as an empty string before adding strings to it
  1262.   for i=1,#appFolderNav do
  1263.  
  1264.     appFolder = appFolder .. "/" .. appFolderNav[i]
  1265.   end
  1266.   -- Remaking the appFolder directory navigation
  1267.  
  1268.   appPages = loadApps(appFolder,appFolderNav,searchWord)
  1269.   -- Loading the apps into a sorted table
  1270.  
  1271.   if event == "mouse_click" or event == "key" then
  1272.  
  1273.     clearScreen()
  1274.     loadPage(pageNumber,appFolderNav,searchWord)
  1275.   end
  1276.   -- First checking if the last event was a mouse click or a key press (to make it that little bit more efficient) before clearing and then loading the current page
  1277.  
  1278.   if not dropMenuOpts.paste then
  1279.  
  1280.     addPaste()
  1281.   end
  1282.   -- while the paste option is not in the dropMenuOpts table it tries to add paste to dropMenuOpts
  1283.  
  1284.   local event, button, x, y = os.pullEvent()
  1285.   -- Waiting for a mouse click event
  1286.  
  1287.   local currentFolder = fs.list(appFolder)
  1288.   -- Getting whatever is in the current folder for later use
  1289.  
  1290.   if event == "mouse_click" then
  1291.  
  1292.     local clickedAppResult = clickedApp(pageNumber,x,y)
  1293.     local clickedOtherResult = clickedOther(pageNumber,x,y)
  1294.     -- Getting the result of each of the click detection functions
  1295.  
  1296.     if button == 1 then
  1297.       if clickedAppResult and clickedAppResult[8] == "file" then
  1298.  
  1299.         local toRun = fs.open(runFile,"w")
  1300.         toRun.write(decompress(appFolder .. "/" .. clickedAppResult[7]))
  1301.         toRun.close()
  1302.         -- Making a temporary file with the decompressed version of the file's contents
  1303.  
  1304.         clearScreen()
  1305.         os.pullEvent = oldPullEvent
  1306.         shell.run(runFile .. " " .. appFolder)
  1307.         os.pullEvent = os.pullEventRaw
  1308.         clearScreen()
  1309.         fs.delete(runFile)
  1310.         -- If the user has clicked an app, it will first clear the screen and then run the app and then clear the screen yet again
  1311.  
  1312.       elseif clickedAppResult and clickedAppResult[8] == "folder" then
  1313.  
  1314.         table.insert(appFolderNav,#appFolderNav+1,clickedAppResult[7])
  1315.         -- When the user clicks a folder it will add the folder name to the appFolderNav table
  1316.  
  1317.       elseif clickedAppResult and clickedAppResult[8] == "addNew" then
  1318.  
  1319.         dropMenu(loadDropMenu(dropMenuOpts,nil,x,y-1))
  1320.         -- Loading the create drop menu when the user left clicks the + icon
  1321.  
  1322.       elseif appFolderNav[2] and clickedOtherResult == "back" then
  1323.  
  1324.         table.remove(appFolderNav,#appFolderNav)
  1325.         -- when the user clicks the back button inside a folder it will remove the last folder name the user clicked
  1326.  
  1327.       elseif appPages[pageNumber-1] and clickedOtherResult == "minus" then
  1328.  
  1329.         pageNumber = pageNumber - 1
  1330.         -- If the user has clicked the left page icon and if the appPages page exists it will minus the current pageNumber
  1331.  
  1332.       elseif appPages[pageNumber+1] and clickedOtherResult == "plus" then
  1333.  
  1334.         pageNumber = pageNumber + 1
  1335.         -- If the user has clicked the right page icon and if the appPages page exists it will plus the current pageNumber
  1336.  
  1337.       elseif clickedOtherResult == "searchFilter" then
  1338.  
  1339.         dropMenu(loadDropMenu(dropMenuFilterTags,nil,x,y-1-numFilterTags,true))
  1340.         -- Loading the filter's drop menu
  1341.  
  1342.       elseif clickedOtherResult == "power" then
  1343.  
  1344.         dropMenu(loadDropMenu(dropMenuPower,nil,x,y))
  1345.         -- If the user has clicked the power icon, it will load the power drop menu
  1346.  
  1347.         if terminate then
  1348.  
  1349.           clearScreen()
  1350.         end
  1351.         -- Clearing the screen when the user terminates the OS to go back to the normal CC OS
  1352.  
  1353.       end
  1354.  
  1355.       if clickedOtherResult ~= "minus" and clickedOtherResult ~= "plus" then
  1356.  
  1357.         searchWord = ""
  1358.       end
  1359.       -- making the searchWord = nothing after you search
  1360.  
  1361.     elseif button == 2 and clickedAppResult and clickedAppResult[8] == "file" then
  1362.  
  1363.       dropMenu(loadDropMenu(dropMenuApps,clickedAppResult[7],x,y))
  1364.       -- First loading the drop menu for apps and then detecting if the user has clicked on it
  1365.  
  1366.     elseif button == 2 and clickedAppResult and clickedAppResult[8] == "folder" then
  1367.  
  1368.       dropMenu(loadDropMenu(dropMenuFolders,clickedAppResult[7],x,y))
  1369.       -- First loading the drop menu for folders and then detecting if the user has clicked on it
  1370.  
  1371.     elseif button == 2 then
  1372.  
  1373.       dropMenu(loadDropMenu(dropMenuOpts,"Create",x,y,false,true))
  1374.       -- If the user hasn't right clicked on an app they get this drop down menu
  1375.     end
  1376.   elseif event == "key" and currentFolder[1] then
  1377.     -- Seeing if the event is a key press for searching
  1378.  
  1379.     pageNumber = 1
  1380.     -- Resetting the page number so that the program doesn't error
  1381.  
  1382.     local pressedKey = button
  1383.     local held = x
  1384.     -- Redefining button and x to make sense for the key event
  1385.  
  1386.     if pressedKey == 14 then
  1387.       -- Checking if the user has pressed backspace
  1388.  
  1389.       if #searchWord > 0 then
  1390.         -- Checking if theres any more characters to delete in the searchWord
  1391.  
  1392.         searchWord = searchWord:sub(1,#searchWord-1)
  1393.         -- Removing the last character from the searchWord string
  1394.       end
  1395.  
  1396.     elseif pressedKey <= 10 and pressedKey >= 2 then
  1397.       -- Catching if the user has entered 1-9
  1398.  
  1399.       searchWord = searchWord .. pressedKey - 1
  1400.       -- Adding the correct number to the searchWord
  1401.  
  1402.     elseif pressedKey == 11 then
  1403.       -- Catching if the user has pressed 0
  1404.  
  1405.       searchWord = searchWord .. 0
  1406.       -- Adding 0 to the searchWord
  1407.  
  1408.     elseif pressedKey == 203 and appPages[pageNumber-1] then
  1409.  
  1410.       pageNumber = pageNumber - 1
  1411.       -- If you press the left arrow key it will try to minus 1 from pageNumber
  1412.  
  1413.     elseif pressedKey == 205 and appPages[pageNumber+1] then
  1414.  
  1415.       pageNumber = pageNumber + 1
  1416.       -- If you press the right arrow key it will try to add 1 to pageNumber
  1417.  
  1418.     else
  1419.       for key,val in pairs(keys) do
  1420.         -- Iterating for the amount of keys and values the keys api has
  1421.  
  1422.         if val == pressedKey then
  1423.           -- Checking if what the user entered matched the current val
  1424.  
  1425.           if #key == 1 then
  1426.             -- Seeing if the val is a single character, essentially making this only pick up a-z
  1427.  
  1428.             searchWord = searchWord .. key
  1429.             -- Adding the key to the searchWord string
  1430.           end
  1431.  
  1432.           break
  1433.           -- Breaking the for loop to prevent further unecessary iteration
  1434.         end
  1435.       end
  1436.     end
  1437.   end
  1438. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement