· 4 years ago · Jul 20, 2021, 09:22 PM
1local pullEvent = os.pullEvent
2os.pullEvent = os.pullEventRaw
3repeat
4 term.clear()
5 term.setCursorPos(1, 1)
6 term.setTextColor(colors.red)
7 print("Dlux Security V2\n")
8 term.setTextColor(colors.blue)
9 write("Username: Joozie\nPassword: ")
10 local pw = read("*")
11 if pw ~= "JuicyWasHere" then
12 term.setTextColor(colors.red)
13 print("Access denied")
14 sleep(1)
15 end
16until pw == "JuicyWasHere"
17term.setTextColor(colors.green)
18print("Access Granted. Welcome back, Joozie.")
19sleep(1)
20term.clear()
21term.setCursorPos(1, 1)
22os.pullEvent = pullEvent
23-- Password Protection
24
25local folderDir = "DluxOSApps"
26local osVersion = "2.0"
27-- Defining folderDir as the folder you keep your apps in and the osVersion is the version of the os you are using
28
29local appMaxHeight = 3
30local appMaxNameLength = 11
31-- 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
32
33local pageNumber = 1
34-- Setting the page number that the program loads with
35
36local colours = {
37 app = colors.blue,
38 folder = colors.lightBlue,
39 addNew = colors.cyan,
40 page = colors.green,
41 dropMenuTop = colors.gray,
42 dropMenuBottom = colors.lightGray,
43 infoText = colors.lightBlue,
44 decoText = colors.yellow,
45 searchBackground = colors.cyan,
46 filterBackground = colors.purple,
47 filterOn = colors.lime,
48 filterOff = colors.red
49}
50-- Colour theme for the apps and the page icons
51
52-- ============================== End Of User Config ==============================
53
54if fs.exists(folderDir) and not fs.isDir(folderDir) then
55
56 error("folderDir variable is assigned to an already existing file.")
57end
58-- Seeing if the folderDir is a file already on the local computer
59
60if not fs.exists(folderDir) then
61
62 fs.makeDir(folderDir)
63end
64-- Making the folderDir if its not already made
65
66shell.run("clear")
67term.setTextColor(colours.infoText)
68print("Setting things up...")
69-- The boot up message
70
71local maxX,maxY = term.getSize()
72-- Getting the max dimensions of the screen
73
74local searchFilterName = "Filter"
75-- The word that is displayed where the filter is
76
77local activeFilterTags = {}
78-- Defining a table that i will be keeping the active filter tags in
79
80local terminate = false
81-- Defining the terminate variable as false to use later on
82
83local clipboard = nil
84-- Defining the clipBoard variable as nil for use later on
85
86local addNewVisible = true
87-- Setting the AddNew icon to visible
88
89local oldPullEvent = os.pullEvent
90os.pullEvent = os.pullEventRaw
91-- Defining os.pullEvent as os.pullEventRaw so that the read() function will use raw instead of the normal os.pullEvent
92
93local dropMenuPower = {
94 Terminate = function() terminate = true end,
95 Restart = function() os.reboot() end,
96 Shutdown = function() os.shutdown() end
97}
98-- Functions that are called when the user left clicks the power button on the top right
99
100local dropMenuFilterTags = {
101 Folders = function() checkFilterTags("Folders") end,
102 Files = function() checkFilterTags("Files") end,
103 Hidden = function() checkFilterTags("Hidden") end,
104 AddNew = function() checkAddNew() end
105}
106-- Tag Filters that will be displayed visually
107
108local dropMenuFolders = {
109 Delete = function(name) fs.delete(appFolder .. "/" .. name) end,
110 Copy = function(name) clipboard = {appFolder, name} end
111}
112-- Functions that are called when the user right clicks an option for a folder in the drop menu
113
114local dropMenuApps = {
115 Edit = function(name) shell.run("edit " .. appFolder .. "/" .. name) end,
116 Delete = function(name) fs.delete(appFolder .. "/" .. name) end,
117 Copy = function(name) clipboard = {appFolder, name} end,
118 Rename = function(name)
119
120 clearScreen()
121 term.setTextColor(colours.infoText)
122 print("Enter the new name of the app below or press enter again to not rename:")
123 -- Prompting the user for an input
124
125 term.setTextColor(colors.white)
126 local newName = read()
127 -- Getting user input
128
129 term.setTextColor(colours.infoText)
130 -- Setting the text colour so i don't have to set it in the if statements
131
132 if not fs.exists(appFolder .. "/" .. newName) then
133 -- Checking if the name doesn't already exist in the current directory
134
135 fs.move(appFolder .. "/" .. name, appFolder .. "/" .. newName)
136 print("File successfully renamed")
137 sleep(1)
138 -- If the directory already doesn't have an app/folder of that name then it will rename the app
139
140 elseif newName == "" then
141 -- Checking if they have put anything in the read()
142
143 print("New name not set")
144 sleep(1)
145 -- If they haven't put anything in the read() then it won't try to set a new name
146 else
147
148 print("Name already exists in current directory")
149 sleep(1)
150 -- Informing the user that the name they chose already exists
151 end
152 end
153}
154-- Functions that are called when the user right clicks an option for an app in the drop menu
155
156local dropMenuOpts = {
157 App = function()
158
159 clearScreen()
160 DluxOS()
161 -- Loading the OS version
162
163 term.setCursorPos(1,2)
164 term.setTextColor(colours.infoText)
165 print("Enter name of new app below or leave blank to not create:")
166 term.setTextColor(colors.white)
167 -- Prompting the user to enter the new app name
168
169 local appName = wordSplit(read())
170 -- Immediately splitting the user input at the spaces
171
172 if appName[1] and not fs.exists(appName[1]) then
173 -- Checking if the user inputted a app name and seeing if it exists already or not
174
175 shell.run("edit " .. appFolder .. "/" .. appName[1])
176 -- Edit the new file
177 elseif appName[1] and fs.exists(appName[1]) then
178
179 term.setTextColor(colours.infoText)
180 print("Name already exists")
181 sleep(1)
182 -- Notifying the user that the name already exists
183 else
184
185 term.setTextColor(colours.infoText)
186 print("No new file created")
187 sleep(1)
188 -- 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
189 end
190 end,
191
192 Folder = function()
193
194 clearScreen()
195 DluxOS()
196 -- Loading the OS version
197
198 term.setCursorPos(1,2)
199 term.setTextColor(colours.infoText)
200 print("Enter the name of the new folder below or leave blank to not create:")
201 term.setTextColor(colors.white)
202 -- Prompting the user for the new folder name
203
204 local folderName = wordSplit(read())
205 -- Immediately splitting the user input into a table
206
207 if folderName[1] and not fs.exists(folderName[1]) then
208 -- Checking if the user inputted a app name and seeing if it exists already or not
209
210 fs.makeDir(appFolder .. "/" .. folderName[1])
211 -- Makes the new folder
212
213 elseif folderName[1] and fs.exists(folderName[1]) then
214 -- Catches if the user has inputted an folder name that already exists
215
216 term.setTextColor(colours.infoText)
217 print("Name already exists")
218 sleep(1)
219 -- Notifying the user that the name they have inputted already exists
220 else
221
222 term.setTextColor(colours.infoText)
223 print("No new folder created")
224 sleep(1)
225 -- 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
226 end
227 end
228}
229-- The drop menu you see if you don't right click on an app
230
231if http then
232 -- First seeing if you have the http api enabled before doing anything
233
234 local testFile = http.get("http://pastebin.com/raw.php?i=DSMHN2iF")
235
236 if testFile then
237
238 testPaste = testFile.readAll()
239 testFile.close()
240 -- Reading a test file that i have made just to make sure you can access pastebin.com
241 end
242
243 if testPaste == "test" then
244 -- Seeing if the test paste has "test" in it's contents (should always return test)
245
246 dropMenuOpts.Pastebin = function()
247 -- Adding the Pastebin option to the dropMenuOpts
248
249 clearScreen()
250 DluxOS()
251 -- Loading the OS version
252
253 term.setCursorPos(1,2)
254 term.setTextColor(colours.infoText)
255 print("Enter the pastebin url after http://pastebin.com/ below or leave blank to not create:")
256 term.setTextColor(colors.white)
257 -- Prompting the user for the pastebin url
258
259 local pasteURL = wordSplit(read())
260 -- Immediately splitting the user input into a table
261
262 if pasteURL[1] then
263 -- Seeing if the user has entered anything
264
265 local pasteFile = http.get("http://pastebin.com/raw.php?i=" .. textutils.urlEncode(pasteURL[1]))
266 local pasteContents = pasteFile.readAll()
267 pasteFile.close()
268 -- Getting the user's file from pastebin
269
270 if pasteContents then
271 -- Checking if the pastebin url is valid and is actually a file
272
273 term.setTextColor(colours.infoText)
274 print("Enter the file name you want to download as:")
275 term.setTextColor(colors.white)
276 -- Prompting the user for the file name to download as
277
278 local pasteFile = wordSplit(read())
279 -- Getting the file name and splitting the user input into a table
280
281 if pasteFile[1] and not fs.exists(appFolder .. "/" .. pasteFile[1]) then
282 -- Checking if the user has entered anything and also checking if the file already exists or not
283
284 local file = fs.open(appFolder .. "/" .. pasteFile[1], "w")
285 file.write(pasteContents)
286 file.close()
287 -- If everything goes well it will make the file
288
289 term.setTextColor(colours.infoText)
290 print("Successfully made file")
291 sleep(1)
292 -- Letting the user know it was successful
293
294 elseif pasteFile[1] and fs.exists(appFolder .. pasteFile[1]) then
295 -- Catching if the use has entered a file name but it already exists
296
297 term.setTextColor(colours.infoText)
298 print("File already exists. Press Y to force or enter another key to not force:")
299 local event, key, held = os.pullEvent("key")
300 -- Seeing if the user wants to force make the file
301
302 if key == 21 then
303 -- In this case 21 is the key Y
304
305 local file = fs.open(appFolder .. "/" .. pasteFile[1], "w")
306 file.write(pasteContents)
307 file.close()
308 -- Writing over the old file with the newly downloaded file
309
310 term.setTextColor(colours.infoText)
311 print("Successfully force made file")
312 sleep(1)
313 -- Letting the use know that the file was replaced
314 else
315
316 term.setTextColor(colours.infoText)
317 print("Aborted making the file")
318 sleep(1)
319 -- If the user hasn't entered a valid name e.g either spaces or nothing
320 end
321 end
322 else
323
324 term.setTextColor(infoText)
325 print("Invalid paste URL")
326 sleep(1)
327 -- Letting the user know that the pastebin url's contents aren't there e.g invalid url
328 end
329 else
330
331 term.setTextColor(colours.infoText)
332 print("No url specified")
333 sleep(1)
334 -- If no input was given it returns to the app page
335 end
336 end
337 end
338end
339-- First checking if the user can access pastebin.com and if they can then will add the pastebin option to dropMenuOpts
340
341local filterTags = {
342
343 Folders = function (tab)
344
345 local out = {}
346 -- Defining the out table to be later returned
347
348 for i=1, #tab do
349 -- Iterating for the amount of values the tab table has
350
351 if not fs.isDir(appFolder .. "/" .. tab[i]) then
352
353 table.insert(out,#out+1,tab[i])
354 end
355 -- Removing the folders from the table
356 end
357
358 return out
359 -- Returning the filtered table
360 end,
361
362 Files = function (tab)
363
364 local out = {}
365 -- Defining the out table to be later returned
366
367 for i=1,#tab do
368 -- Iterating for the amount of values the tab table has
369
370 if fs.isDir(appFolder .. "/" .. tab[i]) then
371
372 table.insert(out,#out+1,tab[i])
373 end
374 -- Removing the files from the table
375 end
376
377 return out
378 -- Returning the filtered table
379 end,
380
381 Hidden = function (tab)
382
383 local out = {}
384 -- Defining the out table to be later returned
385
386 for i=1,#tab do
387 -- Iterating for the amount of values the tab table has
388
389 if tab[i]:sub(1,1) ~= "." then
390
391 table.insert(out,#out+1,tab[i])
392 end
393 -- Adding the Filtered Files to the out table
394 end
395
396 return out
397 -- Returning the filtered table
398 end,
399
400 AddNew = function(tab) return tab end
401}
402-- The tags that the directory can be filtered for
403
404local numFilterTags = 0
405
406for key,val in pairs(dropMenuFilterTags) do
407
408 numFilterTags = numFilterTags + 1
409end
410-- Getting the number of filter tags for later use
411
412for key,val in pairs(dropMenuFilterTags) do
413 -- Iterating for the number of key/value pairs in dropMenuFilterTags
414
415 if key == "Hidden" then
416 -- Seeing if the key is "Hidden"
417
418 activeFilterTags[key] = true
419 -- Setting the key to activated
420 else
421
422 activeFilterTags[key] = false
423 -- Setting the key to deactivated
424 end
425end
426-- Making the activeFilterTags table
427
428local directoryBeforeSearch
429-- Declaring directoryBeforeSearch variable here so i can compare with it later on
430
431function checkFilterTags(name)
432 if activeFilterTags[name] then
433 -- Seeing what the status of the filter was before
434
435 activeFilterTags[name] = false
436 -- Removing the filter from the active tags list
437 else
438
439 activeFilterTags[name] = true
440 pageNumber = 1
441 -- Adding the filter to the tags list aswell as resetting the page number so it won't error
442 end
443end
444
445function checkAddNew()
446 if activeFilterTags.AddNew then
447 -- Seeing what the status of AddNew was before
448
449 activeFilterTags.AddNew = false
450 addNewVisible = true
451 -- Removing AddNew from the active tags list and setting it's visibility to true
452 else
453
454 activeFilterTags.AddNew = true
455 pageNumber = 1
456 addNewVisible = false
457 -- Adding AddNew to the tags list aswell as resetting the page number so it won't error and setting it's visibility to false
458 end
459end
460
461
462function fileSort(fileTab,appFolder,searchWord)
463
464 local out = {}
465 local files = {}
466
467 for key,val in pairs(activeFilterTags) do
468 -- iterating over the activeFilterTags table
469
470 if val then
471
472 fileTab = filterTags[key](fileTab)
473 -- Assigning fileTab to the new table that the filterTags tag will return
474 end
475 end
476 -- Applying any filters that the user has put on
477
478 directoryBeforeSearch = fileTab
479 -- Defining directoryBeforeSearch as fileTab before it has been filtered with the search word
480
481 for i=1,#fileTab do
482 if fs.isDir(appFolder .. "/" .. fileTab[i]) and fileTab[i]:lower():find(searchWord) then
483 -- 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
484
485 table.insert(out,#out+1,fileTab[i])
486 elseif fileTab[i]:lower():find(searchWord) then
487
488 table.insert(files,#files+1,fileTab[i])
489 end
490 end
491 -- Sorting the fileTab table into the files and out table
492
493 for i=1,#files do
494
495 table.insert(out,#out+1,files[i])
496 end
497 -- merging the files table with the out table
498
499 if addNewVisible then
500 -- Checking if the visible var is true
501
502 out[#out+1] = "+"
503 -- Making the addNew icon
504 end
505
506 return out
507 -- Returning the sorted table
508end
509-- Function for sorting files and folders so that the folders will appear first
510
511function wordSplit(string)
512
513 local out = {}
514
515 for word in string:gmatch("%S+") do
516 -- Splitting the string at the spaces
517
518 table.insert(out, word)
519 -- Inserting the value into a table
520 end
521
522 return out
523 -- Returning the table
524end
525-- Receives a string and returns a table that's the string split at the spaces
526
527function fillArea(tab)
528
529 term.setBackgroundColor(tab[5])
530 -- Setting the right background colour
531
532 for i=0,tab[4]-tab[2] do
533 -- Running for how many rows there are (indexes 2,4 == y values and indexes 1,3 == x values in the table)
534
535 local j = 0
536
537 while j <= tab[3]-tab[1] do
538 -- I use a while loop here because i iterate up with variable amounts
539
540 term.setCursorPos(tab[1]+j,tab[2]+i)
541 -- Positioning the cursor for the next string whether it be a space or the word
542
543 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
544 -- If statement seeing whether the iterators have hit the place where it should be writing the word out
545
546 term.write(tab[6])
547 j = j + #tab[6]
548 -- Only runs when the above if statement has found the place where the word will be centered
549 else
550
551 j = j + 1
552 term.write(" ")
553 -- Writing " " so the background text colour is visible
554 end
555 end
556 end
557end
558-- Defining the function for filling an area of the screen with a word centered in it
559
560function loadApps(appFolder,appFolderNav,searchWord)
561
562 local pages = {}
563 local apps = fileSort(fs.list(appFolder),appFolder,searchWord)
564 -- Getting the app names from the appFolder
565
566 local numberXApps = math.floor(maxX/(appMaxNameLength+1))
567 -- Seeing how many apps it can fit on one line
568
569 if appFolderNav[2] then
570
571 negY = 5
572 else
573
574 negY = 3
575 end
576 -- Seeing whether or not there needs to be more space for other icons on the page or not
577
578 local appsPerPage = math.floor((maxY-negY)/(appMaxHeight+1))*numberXApps
579 -- Seeing the total number of apps per page it can fit
580
581 for i=1,math.ceil(#apps/appsPerPage) do
582 -- Running for the number of pages it has to create
583
584 pages[i] = {}
585
586 for j=0,appsPerPage-1 do
587 -- Running for the number of apps per page
588
589 if not apps[1] then break end
590 -- Seeing if it has done all the apps in the table
591
592 if fs.isDir(appFolder .. "/" .. apps[1]) then
593
594 iconType = "folder"
595 colour = colours.folder
596 -- Setting the iconType var to folder and setting the colour
597
598 elseif fs.exists(appFolder .. "/" .. apps[1]) and not fs.isDir(appFolder .. "/" .. apps[1]) then
599
600 iconType = "file"
601 colour = colours.app
602 -- Setting the iconType var to file and setting the colour
603
604 elseif apps[1] == "+" then
605
606 iconType = "addNew"
607 colour = colours.addNew
608 -- Setting the iconType var to addNew and setting the colour
609 end
610 -- Seeing what icon colour to display for apps[1]
611
612 local indent = (j%numberXApps)*appMaxNameLength+(j%numberXApps)+2
613 -- Finding what the indent of the X value is
614
615 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,apps[1]:sub(1,appMaxNameLength),apps[1],iconType}
616 -- 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}
617
618 table.remove(apps,1)
619 -- Removing the last value from the table
620 end
621
622 if not apps[1] then break end
623 -- Seeing if it has done all the apps in the table
624 end
625
626 return pages
627 -- Returning the pages table after making it
628end
629-- Making a function to load the apps from the appFolder into a table thats split up into pages
630
631function DluxOS()
632
633 term.setCursorPos(1,1)
634 term.setTextColor(colours.decoText)
635 term.write("DluxOS Version: " .. osVersion)
636 term.setTextColor(colors.white)
637end
638-- Displaying the version number at the top left of the screen
639
640function otherArea(pageNumber)
641 return {
642 plus = {maxX-math.ceil((maxX)/2)+1,maxY-1,maxX,maxY-1,colours.page,"page "..pageNumber+1},
643 minus = {1,maxY-1,math.floor((maxX)/2)-1,maxY-1,colours.page,"page "..pageNumber-1},
644 power = {maxX-2,1,maxX,1,colors.red,"O"},
645 back = {1,3,2,3,colours.page,"<"},
646 searchBar = {1,maxY,maxX-#searchFilterName-1,maxY,colours.searchBackground},
647 searchFilter = {maxX-#searchFilterName-1,maxY,maxX,maxY,colours.filterBackground,searchFilterName}
648 }
649end
650-- Getting the updated pageNumber for the pages aswell as setting the power button at the top right of the screen
651
652function addPaste(tab)
653 if clipboard then
654
655 dropMenuOpts.paste = function() paste() end
656 end
657end
658-- Function to add the paste option once you have a clipboard from using copy
659
660function paste()
661 if appFolder ~= clipboard[1] then
662
663 fs.copy(clipboard[1] .. "/" .. clipboard[2], appFolder .. "/" .. clipboard[2])
664 end
665end
666-- Function for pasting a file
667
668function loadPage(pageNumber,appFolderNav,searchWord)
669
670 local otherAreaTab = otherArea(pageNumber)
671 -- Getting the otherArea table with the updated pageNumber
672
673 local topFolder = fs.list(folderDir)
674 -- Defining topFolder as the folders/files in the upper folder to be used later on
675
676 DluxOS()
677 -- displaying the OS Version
678
679 if appFolderNav[2] then
680
681 term.setBackgroundColor(colors.black)
682 term.setTextColor(colours.infoText)
683 -- Getting the colours ready
684
685 local dirLink = "CC:" .. appFolderNav[2]
686 -- Defining the dirLink variable so it won't concatenate with what it was before
687
688 for i=1,#appFolderNav-2 do
689
690 dirLink = dirLink .. "/" .. appFolderNav[i+2]
691 end
692 -- Making the dirLink by conatenation without what folderDir is
693
694 if #dirLink > maxX-4 then
695
696 dirLink = dirLink:sub(#dirLink-maxX+4,#dirLink)
697 end
698
699 term.setCursorPos(4,3)
700 term.write(dirLink)
701 term.setTextColor(colors.white)
702 -- Seeing if dirLink is longer than the page and making a sub string if it is when writing it out
703 end
704 -- Seeing if the user is in a folder and then displaying the back button and the directory link
705
706 if appPages[1] then
707 for i=1,#appPages[pageNumber] do
708
709 fillArea(appPages[pageNumber][i])
710 end
711 end
712 -- Displaying the app icons on the screen
713
714 for key,val in pairs(otherAreaTab) do
715 -- Iterating for all of the values in the otherAreaTab table
716
717 local fillCatch = true
718 -- Defining a variable so i can use it later on
719
720 if key == "searchBar"then
721 if directoryBeforeSearch[1] then
722
723 fillArea(val)
724 end
725
726 fillCatch = false
727 end
728 -- Seeing if there are appPages then it will display the search bar
729
730 if key == "minus" then
731 if appPages[pageNumber-1] then
732
733 fillArea(val)
734 end
735
736 fillCatch = false
737 end
738 -- Seeing if theres a table before displaying the previous page icon
739
740 if key == "plus" then
741 if appPages[pageNumber+1] then
742
743 fillArea(val)
744 end
745
746 fillCatch = false
747 end
748 -- Seeing if theres a table before displaying the next page icon
749
750 if key == "back" then
751 if appFolderNav[2] then
752
753 fillArea(val)
754 end
755
756 fillCatch = false
757 end
758 -- Seeing if the user is in a folder to see if it should display the back icon
759
760 if fillCatch then
761
762 fillArea(val)
763 end
764 -- Catching if the other if statements haven't returned true
765 end
766
767 if #searchWord > 0 then
768 -- Checking if the searchWord has characters in it
769
770 term.setTextColor(colors.white)
771 term.setBackgroundColor(colours.searchBackground)
772 term.setCursorPos(2,maxY)
773 -- Getting ready for the text to be written
774
775 local searchWordWrite = searchWord
776 -- Defining another variable as searchWord so that it won't substring searchWord
777
778 if #searchWord > maxX-5-#searchFilterName then
779 -- Seeing if the searchWord string is longer than the screen
780
781 searchWordWrite = searchWord:sub(#searchWord-maxX+5+#searchFilterName,#searchWord)
782 -- Making a substring of searchWord so that it will fit on the string
783 end
784
785 term.write(searchWordWrite)
786 term.setCursorBlink(true)
787 term.setTextColor(colors.white)
788 -- Writing searchWordWrite to the screen and then resetting the text colour
789
790 elseif directoryBeforeSearch[1] then
791
792 term.setCursorPos(2,maxY)
793 term.setBackgroundColor(colours.searchBackground)
794 term.setTextColor(colors.white)
795 term.write("Type to search")
796 -- Making place holder text for the search bar
797
798 elseif not topFolder[1] then
799
800 term.setCursorPos(1,3)
801 term.setBackgroundColor(colors.black)
802 term.setTextColor(colours.dropMenuBottom)
803 print("Right click to start making apps/folders")
804 term.setTextColor(colors.white)
805 -- Welcoming the user into the program and telling them how to get started
806 end
807end
808-- Loads the entire page onto the screen using fillArea alot
809
810function clickedApp(pageNumber,clickX,clickY)
811 if appPages[1] then
812 for i=1, #appPages[pageNumber] do
813 -- Iterating for the number of apps in the page
814
815 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
816 -- Comparing the clicked x and y values with each of the app's x and y values
817
818 return appPages[pageNumber][i]
819 -- returning the original app name in the appPages table
820 end
821 end
822 end
823
824 return false
825 -- Returning false if it hasn't already returned a value
826end
827-- Detecting what app the user has clicked (if they have clicked one that is)
828
829function clickedOther(pageNumber,clickX,clickY)
830 for key,val in pairs(otherArea(pageNumber)) do
831 -- Iterating for the length of the table the otherArea() function returns
832
833 if val[1] <= clickX and val[3] >= clickX and val[2] <= clickY and val[4] >= clickY then
834 -- Comparing the clicked x and y values with each of the icon's x and y values
835
836 return key
837 -- Returning the key of the key/value pair in the otherArea table
838 end
839 end
840
841 return false
842 -- Returning false if the func hasn't already returned a value
843end
844-- Detecting if the user has clicked the page icons or the close icon
845
846function clearScreen()
847
848 term.setTextColor(colors.white)
849 term.setBackgroundColor(colors.black)
850 term.setCursorBlink(false)
851 shell.run("clear")
852end
853-- Clearing the screen and resetting the taxt colour and the background colour
854
855function loadDropMenu(dropMenuOptionsFuncs,name,x,y,filterBool)
856
857 local dropMenuOptions = {}
858
859 for key,_ in pairs(dropMenuOptionsFuncs) do
860
861 table.insert(dropMenuOptions,1,key)
862 end
863 -- Making the dropMenuOptions table from the functions's keys
864
865 if y + #dropMenuOptions > maxY then
866
867 y = y - (y+#dropMenuOptions-maxY)
868 end
869 -- Seeing if the drop menu will go off the screen and correcting it if it does
870
871 if x+appMaxNameLength > maxX then
872
873 x = x - (x+appMaxNameLength-maxX)
874 end
875 -- Seeing if the drop menu will go off the screen and correcting it if it does
876
877 if name then
878
879 term.setCursorPos(x,y)
880 fillArea({x,y,x+appMaxNameLength,y,colours.dropMenuTop})
881 term.setCursorPos(x,y)
882 term.write(name:sub(1,appMaxNameLength))
883 -- Writing the app name in the right colour and at the right place
884 end
885 -- Seeing if the name argument has been given
886
887 fillArea({x,y+1,x+appMaxNameLength,y+#dropMenuOptions,colours.dropMenuBottom})
888 -- Filling the below area for the drop menu options
889
890 for i=1,#dropMenuOptions do
891 -- Iterating through the dropMenuOptions table
892
893 if filterBool and activeFilterTags[dropMenuOptions[i]] then
894 -- Seeing if filterBool is true and if the filter is active
895
896 term.setTextColor(colours.filterOn)
897 -- Setting the text colour to filterOn if the filter is on
898
899 elseif filterBool then
900 -- Seeing if filterBool is true but the filter is not active
901
902 term.setTextColor(colours.filterOff)
903 -- Setting the text colour to filterOff if the filter is off
904 end
905
906 term.setCursorPos(x,y+i)
907 term.write(dropMenuOptions[i]:sub(1,appMaxNameLength))
908 term.setTextColor(colors.white)
909 end
910 -- Writing the options in their places and making sure they don't go over the appMaxNameLength
911
912 return dropMenuOptions,dropMenuOptionsFuncs,name,x,y
913 -- Returning the changed coordinates of the drop menu
914end
915-- Loading the drop menu from where the user has clicked
916
917function dropMenu(dropMenuOptions,dropMenuOptionsFuncs,name,x,y)
918
919 local event, button, clickX, clickY = os.pullEvent("mouse_click")
920 -- Getting a user mouse click input
921
922 if button == 1 then
923 -- Seeing if the user has left clicked
924
925 for i=1,#dropMenuOptions do
926 --Iterating for the amount of options in the drop menu
927
928 if x <= clickX and x+appMaxNameLength >= clickX and y+i <= clickY and y+i >= clickY then
929 -- Detecting whether the user has clicked an option
930
931 dropMenuOptionsFuncs[dropMenuOptions[i]](name)
932 -- Running the function in the drop menu
933 end
934 end
935 end
936end
937-- Function for detecting if the user has clicked an option in the drop menu
938
939appFolderNav = {folderDir}
940-- Making the nav table so its easy to modify the directory navigation
941
942local event = "mouse_click"
943-- Giving the event var a value
944
945local searchWord = ""
946-- Defining searchWord as an empty string
947
948while not terminate do
949 -- Running while the terminate variable is false
950
951 appFolder = ""
952 -- Defining the appFolder as an empty string before adding strings to it
953 for i=1,#appFolderNav do
954
955 appFolder = appFolder .. "/" .. appFolderNav[i]
956 end
957 -- Remaking the appFolder directory navigation
958
959 appPages = loadApps(appFolder,appFolderNav,searchWord)
960 -- Loading the apps into a sorted table
961
962 if event == "mouse_click" or event == "key" then
963
964 clearScreen()
965 loadPage(pageNumber,appFolderNav,searchWord)
966 end
967 -- 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
968
969 if not dropMenuOpts.paste then
970
971 addPaste()
972 end
973 -- while the paste option is not in the dropMenuOpts table it tries to add paste to dropMenuOpts
974
975 local event, button, x, y = os.pullEvent()
976 -- Waiting for a mouse click event
977
978 local currentFolder = fs.list(appFolder)
979 -- Getting whatever is in the current folder for later use
980
981 if event == "mouse_click" then
982
983 local clickedAppResult = clickedApp(pageNumber,x,y)
984 local clickedOtherResult = clickedOther(pageNumber,x,y)
985 -- Getting the result of each of the click detection functions
986
987 if button == 1 then
988 if clickedAppResult and clickedAppResult[8] == "file" then
989
990 clearScreen()
991 os.pullEvent = oldPullEvent
992 shell.run(appFolder .. "/" .. clickedAppResult[7] .. " " .. appFolder)
993 clearScreen()
994 os.pullEvent = os.pullEventRaw
995 -- 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
996
997 elseif clickedAppResult and clickedAppResult[8] == "folder" then
998
999 table.insert(appFolderNav,#appFolderNav+1,clickedAppResult[7])
1000 -- When the user clicks a folder it will add the folder name to the appFolderNav table
1001
1002 elseif clickedAppResult and clickedAppResult[8] == "addNew" then
1003
1004 dropMenu(loadDropMenu(dropMenuOpts,nil,x,y-1))
1005 -- Loading the create drop menu when the user left clicks the + icon
1006
1007 elseif appFolderNav[2] and clickedOtherResult == "back" then
1008
1009 table.remove(appFolderNav,#appFolderNav)
1010 -- when the user clicks the back button inside a folder it will remove the last folder name the user clicked
1011
1012 elseif appPages[pageNumber-1] and clickedOtherResult == "minus" then
1013
1014 pageNumber = pageNumber - 1
1015 -- If the user has clicked the left page icon and if the appPages page exists it will minus the current pageNumber
1016
1017 elseif appPages[pageNumber+1] and clickedOtherResult == "plus" then
1018
1019 pageNumber = pageNumber + 1
1020 -- If the user has clicked the right page icon and if the appPages page exists it will plus the current pageNumber
1021
1022 elseif clickedOtherResult == "searchFilter" then
1023
1024 dropMenu(loadDropMenu(dropMenuFilterTags,nil,x,y-1-numFilterTags,true))
1025 -- Loading the filter's drop menu
1026
1027 elseif clickedOtherResult == "power" then
1028
1029 dropMenu(loadDropMenu(dropMenuPower,nil,x,y))
1030 -- If the user has clicked the power icon, it will load the power drop menu
1031
1032 if terminate then
1033
1034 clearScreen()
1035 end
1036 -- Clearing the screen when the user terminates the OS to go back to the normal CC OS
1037
1038 end
1039
1040 if clickedOtherResult ~= "minus" and clickedOtherResult ~= "plus" then
1041
1042 searchWord = ""
1043 end
1044 -- making the searchWord = nothing after you search
1045
1046 elseif button == 2 and clickedAppResult and clickedAppResult[8] == "file" then
1047
1048 dropMenu(loadDropMenu(dropMenuApps,clickedAppResult[7],x,y))
1049 -- First loading the drop menu for apps and then detecting if the user has clicked on it
1050
1051 elseif button == 2 and clickedAppResult and clickedAppResult[8] == "folder" then
1052
1053 dropMenu(loadDropMenu(dropMenuFolders,clickedAppResult[7],x,y))
1054 -- First loading the drop menu for folders and then detecting if the user has clicked on it
1055
1056 elseif button == 2 then
1057
1058 dropMenu(loadDropMenu(dropMenuOpts,"Create",x,y))
1059 -- If the user hasn't right clicked on an app they get this drop down menu
1060 end
1061 elseif event == "key" and currentFolder[1] then
1062 -- Seeing if the event is a key press for searching
1063
1064 pageNumber = 1
1065 -- Resetting the page number so that the program doesn't error
1066
1067 local pressedKey = button
1068 local held = x
1069 -- Redefining button and x to make sense for the key event
1070
1071 if pressedKey == 14 then
1072 -- Checking if the user has pressed backspace
1073
1074 if #searchWord > 0 then
1075 -- Checking if theres any more characters to delete in the searchWord
1076
1077 searchWord = searchWord:sub(1,#searchWord-1)
1078 -- Removing the last character from the searchWord string
1079 end
1080
1081 elseif pressedKey <= 10 and pressedKey >= 2 then
1082 -- Catching if the user has entered 1-9
1083
1084 searchWord = searchWord .. pressedKey - 1
1085 -- Adding the correct number to the searchWord
1086
1087 elseif pressedKey == 11 then
1088 -- Catching if the user has pressed 0
1089
1090 searchWord = searchWord .. 0
1091 -- Adding 0 to the searchWord
1092
1093 elseif pressedKey == 203 and appPages[pageNumber-1] then
1094
1095 pageNumber = pageNumber - 1
1096 -- If you press the left arrow key it will try to minus 1 from pageNumber
1097
1098 elseif pressedKey == 205 and appPages[pageNumber+1] then
1099
1100 pageNumber = pageNumber + 1
1101 -- If you press the right arrow key it will try to add 1 to pageNumber
1102
1103 else
1104 for key,val in pairs(keys) do
1105 -- Iterating for the amount of keys and values the keys api has
1106
1107 if val == pressedKey then
1108 -- Checking if what the user entered matched the current val
1109
1110 if #key == 1 then
1111 -- Seeing if the val is a single character, essentially making this only pick up a-z
1112
1113 searchWord = searchWord .. key
1114 -- Adding the key to the searchWord string
1115 end
1116
1117 break
1118 -- Breaking the for loop to prevent further unecessary iteration
1119 end
1120 end
1121 end
1122 end
1123end