Advertisement
PaymentOption

Dots OS

Nov 4th, 2012
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 37.53 KB | None | 0 0
  1. --[[
  2.         Dots shell by PaymentOption
  3.         3 November 2012
  4.  
  5.         This is a simple clickable desktop interface that allows
  6.         for a windows-like icon desktop system.
  7.  
  8.         Change Log:
  9.                 - 0.1: Initial Release
  10.  
  11.         Planned Features:
  12.                 - Ability to manipulate dots as you can in CraftOS.
  13.                 - Possibly a basic security system for logins and such.
  14. --]]
  15.  
  16. --[[
  17.         NOTES:
  18.                 - Read only files are red dots!
  19.                 - Dot properties are stored as: <dotName>_<dotName>
  20.                         * The color of the dot will be the first line. An example being: 'red'. NOT colors.red.
  21. --]]
  22.  
  23. --=VARIABLES=====================--
  24. local screenWidth, screenHeight = term.getSize() -- The x and y dimensions of the screen.
  25. local scrollOffset = 0 -- The amount of offsetting needed to be done in the screen buffer every update.
  26.  
  27. local BACKGROUND_COLOR = colors.cyan -- The color of the background used for the desktop.
  28. local DEFAULT_FILE_COLOR = colors.orange -- The color of a dot if it is a file and is using default settings.
  29. local DEFAULT_DIR_COLOR = colors.lime -- The color of a dot if it is a directory and is using default settings.
  30. local propertiesDirectory = ".dotProperties"
  31.  
  32. local tScreenBuffer = {}
  33. local tDots = {} -- The dots that are currently loaded.
  34. local tempDots = tDots -- A temporary buffer for scrolling the dots on screen.
  35. local tScrollBarPositions = {} -- The positions in which the scroll bar exists.
  36. local currentDirectory = "" -- The current directory that we are in.
  37. --=END VARIABLES=================--
  38.  
  39.  
  40.  
  41. --=FILE HANDLING FUNCTIONS============--
  42. -- Loads the property file for the given dot. Takes
  43. -- the path of the object represented by the dot.
  44. function loadDotProperty(dotPath, dotLabel)
  45.         -- Get the specific identifier for this dot's property file.
  46.         local dotIdentifier = string.gsub(dotPath, '/', '_')
  47.         local dotIsFile = not fs.isDir(dotPath)
  48.         -- Check if the object represented by the dot actually exists on this computer.
  49.         if fs.exists(dotPath) and fs.exists(propertiesDirectory .. '/' .. dotLabel .. '_' .. dotIdentifier) then
  50.                 -- Make sure that the file is not read only. If it is, however, then return red.
  51.                 if fs.isReadOnly(dotPath) then
  52.                         return colors.red
  53.                 end
  54.  
  55.                 -- Open the properties file related to this dot.
  56.                 local dotPropertyFileHandle = fs.open(propertiesDirectory .. '/' .. dotLabel .. '_' .. dotIdentifier, 'r')
  57.                 -- Make sure the file handle is valid.
  58.                 if dotPropertyFileHandle then
  59.                         -- Get the color stored in the file and close the file handle.
  60.                         local dotColor = getColorFromString(dotPropertyFileHandle.readAll()) -- This will be colors.someColor.
  61.                         dotPropertyFileHandle.close()
  62.  
  63.                         -- Make sure the color stored is valid.
  64.                         if dotColor then
  65.                                 return dotColor
  66.                         else
  67.                                 return getDefaultColor(dotIsFile, dotPath)
  68.                         end
  69.                 else
  70.                         return getDefaultColor(dotIsFile, dotPath)
  71.                 end
  72.                 return getDefaultColor(dotIsFile, dotPath)
  73.         end
  74. end
  75.  
  76. -- Returns the appropriate default color for the type given. Takes a boolean value
  77. -- representing whether or not the dot is a file.
  78. function getDefaultColor(dotIsFile, dotPath)
  79.         -- If the dot is a read only file, then return red.
  80.         if fs.isReadOnly(dotPath) then
  81.                 return colors.red
  82.         end
  83.  
  84.         -- If the dot is a file, then return the default file color for a dot.
  85.         if dotIsFile then
  86.                 return DEFAULT_FILE_COLOR
  87.         end
  88.         -- If the dot is a directory, then return the default directory color for a dot.
  89.         return DEFAULT_DIR_COLOR
  90. end
  91. --=END FILE HANDLING  FUNCTIONS=======--
  92.  
  93.  
  94.  
  95. --=SCREEN BUFFER FUNCTIONS============--
  96. -- Empties the screen buffer.
  97. function dumpBuffer()
  98.         tScreenBuffer = {}
  99. end
  100.  
  101. -- Writes text to the screen using the screen buffer.
  102. function writeToScreen(text, tempTextColor, tempBackgroundColor, tempPath)
  103.         -- Make sure the text color and backgrond color are valid.
  104.         tempTextColor = isColorValid(tempTextColor) or colors.white
  105.         tempBackgroundColor = isColorValid(tempBackgroundColor) or colors.black
  106.  
  107.         -- Get the x and y position of the text that will be written.
  108.         local xCursorPos, yCursorPos = term.getCursorPos()
  109.         -- Add the entry to the screen buffer.
  110.         local entry = {
  111.                 label = text,
  112.                 xPos = xCursorPos,
  113.                 yPos = yCursorPos,
  114.                 textColor = tempTextColor,
  115.                 backgroundColor = tempBackgroundColor,
  116.                 path = tempPath
  117.         }
  118.         table.insert(tScreenBuffer, entry)
  119.  
  120.         -- Write the text to the screen.
  121.         term.setTextColor(tempTextColor)
  122.         term.setBackgroundColor(tempBackgroundColor)
  123.  
  124.         term.write(text)
  125.  
  126.         term.setTextColor(colors.white)
  127.         term.setBackgroundColor(colors.black)
  128. end
  129.  
  130. -- Draws the screen buffer to the screen.
  131. function redrawBuffer()
  132.         for index, item in pairs(tScreenBuffer) do
  133.                 term.setTextColor(item.textColor)
  134.                 term.setBackgroundColor(item.backgroundColor)
  135.  
  136.                 term.setCursorPos(item.xPos, item.yPos)
  137.                 term.write(item.label)
  138.         end
  139.  
  140.         -- Reset the text and background colors to white on black.
  141.         term.setTextColor(colors.white)
  142.         term.setBackgroundColor(colors.black)
  143. end
  144. --=END SCREEN BUFFER FUNCTIONS========--
  145.  
  146. --=COLOR FUNCTIONS====================--
  147. -- Returns the proper color value from the colors table when given a string.
  148. function getColorFromString(colorString)
  149.         colorString = colorString
  150.         -- Use an 'if-else' ladder to retrieve the proper color from the colors table.
  151.         -- Leave red out of it since that is the custom color of read only files.
  152.         if colorString == "white" then
  153.                 return colors.white
  154.         elseif colorString == "orange" then
  155.                 return colors.orange
  156.         elseif colorString == "magenta" then
  157.                 return colors.magenta
  158.         elseif colorString == "lightBlue" then
  159.                 return colors.lightBlue
  160.         elseif colorString == "yellow" then
  161.                 return colors.yellow
  162.         elseif colorString == "lime" then
  163.                 return colors.lime
  164.         elseif colorString == "pink" then
  165.                 return colors.pink
  166.         elseif colorString == "gray" then
  167.                 return colors.gray
  168.         elseif colorString == "lightGray" then
  169.                 return colors.lightGray
  170.         elseif colorString == "purple" then
  171.                 return colors.purple
  172.         elseif colorString == "blue" then
  173.                 return colors.blue
  174.         elseif colorString == "brown" then
  175.                 return colors.brown
  176.         elseif colorString == "green" then
  177.                 return colors.green
  178.         elseif colorString == "black" then
  179.                 return colors.black
  180.         end
  181. end
  182.  
  183. -- Returns the color string value of the color given.
  184. function getColorFromValue(colorValue)
  185.         -- Use an 'if-else ladder' to retrieve the proper color string from the colors table.
  186.         -- Leave red out of it since that is the curstom color of read only files.
  187.         if colorValue == colors.white then
  188.                 return "white"
  189.         elseif colorValue == colors.orange then
  190.                 return "orange"
  191.         elseif colorValue == colors.magenta then
  192.                 return "magenta"
  193.         elseif colorValue == colors.lightBlue then
  194.                 return "lightBlue"
  195.         elseif colorValue == colors.yellow then
  196.                 return "yellow"
  197.         elseif colorValue == colors.lime then
  198.                 return "lime"
  199.         elseif colorValue == colors.pink then
  200.                 return "pink"
  201.         elseif colorValue == colors.gray then
  202.                 return "gray"
  203.         elseif colorValue == colors.lightGray then
  204.                 return "lightGray"
  205.         elseif colorValue == colors.purple then
  206.                 return "purple"
  207.         elseif colorValue == colors.blue then
  208.                 return "blue"
  209.         elseif colorValue == colors.brown then
  210.                 return "brown"
  211.         elseif colorValue == colors.green then
  212.                 return "green"
  213.         elseif colorValue == colors.black then
  214.                 return "black"
  215.         end
  216. end
  217.  
  218. -- Checks if the given color is valid. Returns the given color
  219. -- if it is valid; returns nil if it is invalid.
  220. function isColorValid(givenColor)
  221.         for index, color in pairs(colors) do
  222.                 if color == givenColor then
  223.                         return givenColor
  224.                 end
  225.         end
  226.  
  227.         -- If the loop completed without returning, then the color given is invalid;
  228.         -- return nil.
  229.         return nil
  230. end
  231.  
  232. -- Sets the background color for all screens.
  233. function setBackgroundColor(color)
  234.         if isColorValid(color) then
  235.                 BACKGROUND_COLOR = color
  236.         end
  237. end
  238. --=END COLOR FUNCTIONS================--
  239.  
  240.  
  241.  
  242. --=SCREEN UTILITES====================--
  243. -- Clears the screen of all text without dumping the screen buffer.
  244. function clearScreen()
  245.         term.setBackgroundColor(BACKGROUND_COLOR)
  246.  
  247.         term.clear()
  248.         term.setCursorPos(1, 1)
  249.  
  250.         term.setBackgroundColor(colors.black)
  251. end
  252.  
  253. -- Resets the screen in the case of a directory change.
  254. function resetScreen(path)
  255.         -- Reinitialize the dots and reset the scroll offset.
  256.         tDots = {}
  257.         initializeDots(path)
  258.         tempDots = tDots
  259.         scrollOffset = 0
  260. end
  261. --=END SCREEN UTILITES================--
  262.  
  263.  
  264.  
  265. --=DOT FUNCTIONS======================--
  266. -- Initializes the dot table with the directory given..
  267. function initializeDots(directory)
  268.         local contents = fs.list(directory)
  269.  
  270.         for index, item in ipairs(contents) do
  271.                 local dotColor = loadDotProperty(directory .. '/' .. item, item)
  272.  
  273.                 if fs.isReadOnly(item) then
  274.                         addDot(colors.red, directory .. '/' .. item, "Read only item.")
  275.                 else
  276.                         addDot(dotColor or DEFAULT_DOT_COLOR, directory .. '/' .. item, "Root content.")
  277.                 end
  278.         end
  279. end
  280.  
  281. -- Adds a dot to the list of current dots.
  282. -- NOTE: Generates a valid x position and y position for this new dot.
  283. function addDot(tempColor, path, tempDescription)
  284.         -- Make sure there is a description for this dot.
  285.         tempDescription = tempDescription or "No description provided"
  286.         -- Make sure that the color given is valid.
  287.         if not isColorValid(tempColor) then
  288.                 -- If the file/directory is read only, then set its default color to red.
  289.                 if fs.isReadOnly(path) then
  290.                         tempColor = colors.red
  291.                 else
  292.                         -- If the color isn't valid then use the default color for either a directory or a file.
  293.                         if fs.isDir(path) then
  294.                                 tempColor = DEFAULT_DIR_COLOR
  295.                         else
  296.                                 tempColor = DEFAULT_FILE_COLOR
  297.                         end
  298.                 end
  299.         end
  300.         -- Make sure that the path given is valid. If it is not valid, then
  301.         -- make the color a light gray.
  302.         if not fs.exists(path) then
  303.                 tempColor = colors.lightGray
  304.         end
  305.  
  306.         -- Add the dot to the dot table.
  307.         local dotEntry = {
  308.                 label = fs.getName(path),
  309.                 fullPath = path,
  310.                 color = tempColor,
  311.                 description = tempDescription
  312.         }
  313.         table.insert(tDots, dotEntry)
  314. end
  315.  
  316. -- Removes a dot from the list of current dots.
  317. -- NOTE: This function will use the next option provided to locate the dot in the table!
  318. -- Example: If you provide only the index, the loop will use that information to remove the dot.
  319. --          If you provide the index and the label, the loop will use the label.
  320. --          Etc.
  321. function removeDot(dotIndex, givenLabel, path)
  322.         for index, dot in pairs(tDots) do
  323.                 if path then
  324.                         if dot.fullPath == path then
  325.                                 table.remove(tDots, index)
  326.                         end
  327.                 elseif label then
  328.                         if dot.label == givenLabel then
  329.                                 table.remove(tDots, index)
  330.                         end
  331.                 elseif dotIndex then
  332.                         table.remove(tDots, dotIndex)
  333.                         break
  334.                 end
  335.         end
  336. end
  337.  
  338. -- Scrolls the dot table so that when it is drawn we see the scrolled values.
  339. -- Returns the modified table that only contains the values that should appear
  340. -- on screen after scrolling.
  341. function scrollDots(up)
  342.         -- If the screen should be scrolled up.
  343.         if up then
  344.                 -- Check if the screen can be scrolled up.
  345.                 if #tDots / 25 + scrollOffset > #tDots / 25 then
  346.                         scrollOffset = scrollOffset - 1
  347.                 end
  348.         -- If the screen should be scrolled down.
  349.         else
  350.                 -- Check if the screen can be scrolled down.
  351.                 if #tDots / 25 - scrollOffset - 1 >= 0 then
  352.                         scrollOffset = scrollOffset + 1
  353.                 end
  354.         end
  355.  
  356.         local scrolledTable = tDots
  357.  
  358.         if scrollOffset > 0 then
  359.                 scrolledTable = {}
  360.                 for index = scrollOffset * 25, #tDots do
  361.                         table.insert(scrolledTable, tDots[index])
  362.                 end
  363.         end
  364.  
  365.         return scrolledTable
  366. end
  367.  
  368. -- Draws the dots from the dot table to the screen.
  369. function drawDots(scrolledDots)
  370.         scrolledDots = scrolledDots or tDots
  371.  
  372.         -- Draw the dots in a linear fashion. 25 in one line, 9 lines per screen.
  373.         local pos = 2
  374.         local line = 2
  375.         -- Use a loop to go through the dot table and draw the dots by index.
  376.         for index, dot in pairs(scrolledDots) do
  377.                 if line > 18 then
  378.                         break
  379.                 end
  380.  
  381.                 -- Set the proper position and color for the current dot.
  382.                 term.setBackgroundColor(dot.color)
  383.                 term.setCursorPos(pos, line)
  384.                 term.write(' ')
  385.                 -- writeToScreen(' ', colors.white, dot.color, dot.path)
  386.                 -- Add the position drawn to the temp-dots table.
  387.                 tempDots[index] = {label = dot.label, fullPath = dot.fullPath, color = dot.color, descirption = dot.descirption, xPos = pos, yPos = line}
  388.  
  389.                 pos = pos + 2 -- Add 2 to the position for next dot so there will be a space between each dot.
  390.                 -- If the position is greater than 50 then go ahead
  391.                 -- and jump to the next line.
  392.                 if pos > 50 then
  393.                         pos = 2
  394.                         line = line + 2 -- Move the line down 2 so that there is a space between each line.
  395.                 end
  396.         end
  397.  
  398.         local scrollBarSize = calculateScrollBar() -- Get the size of the scroll bar.
  399.         -- If the scroll bar is greater than 18, meaning it can be scrolled, then draw the scroll bar.
  400.         if scrollBarSize then drawScrollBar(scrollBarSize) end
  401. end
  402.  
  403. -- Brings up a screen that provides information about the clicked dot.
  404. function drawDotScreen(dotIndex)
  405.         -- Draw a larger representation of the dot clicked.
  406.         clearScreen()
  407.         drawLargeDot(tempDots[dotIndex].color)
  408.  
  409.         -- List all information about the dot given.
  410.         local informationStartPos_X = 20
  411.         local informationStartPos_Y = 7
  412.  
  413.         local dotDescription = fs.isReadOnly(tempDots[dotIndex].fullPath) and "Read only content." or nil
  414.  
  415.         term.setCursorPos(informationStartPos_X, informationStartPos_Y)
  416.         writeToScreen("Name: " .. tempDots[dotIndex].label, colors.white, colors.cyan, nil)
  417.         term.setCursorPos(informationStartPos_X, informationStartPos_Y + 1)
  418.         writeToScreen("Path: " .. tempDots[dotIndex].fullPath, colors.white, colors.cyan, nil)
  419.  
  420.         term.setCursorPos(informationStartPos_X, informationStartPos_Y + 3)
  421.         writeToScreen(dotDescription, colors.white, colors.cyan, nil)
  422.  
  423.         -- Draw the back button on the right side of the screen.
  424.         term.setCursorPos(screenWidth - 1, screenHeight)
  425.         writeToScreen("->", colors.white, colors.lightBlue, nil)
  426.  
  427.         -- If this dot is a file, then offer to execute the file.
  428.         -- However, if this dot is a directory, then offer to enter the directory.
  429.         local clickableOption = (not fs.isDir(tempDots[dotIndex].fullPath) and "Execute" or "Enter")
  430.         local editOption = "Edit Description"
  431.         while true do
  432.                 term.setBackgroundColor(colors.lightBlue)
  433.                 term.setTextColor(colors.white)
  434.                 -- Draw the execute/enter option.
  435.                 term.setCursorPos(2, screenHeight)
  436.                 term.write(clickableOption)
  437.                 -- Draw the change color option underneath the larger dot.
  438.                 term.setCursorPos(5, 14)
  439.                 term.write("Change")
  440.  
  441.                 -- Check for a click on the 'execute' or 'enter' option.
  442.                 local event, p1, p2, p3 = os.pullEvent()
  443.  
  444.                 -- If the event was click, then check if it was on the option provided.
  445.                 if event == "mouse_click" then
  446.                         -- If the click was a left click then execute the command.
  447.                         if p1 == 1 then
  448.                                 if (p2 >= 2 and p2 <= 2 + clickableOption:len()) and p3 == screenHeight then
  449.                                         -- If the option was to execute the given file, then run it with the shell.
  450.                                         if clickableOption == "Execute" then
  451.                                                 clearScreen()
  452.                                                 term.setTextColor(colors.white)
  453.                                                 term.setBackgroundColor(colors.black)
  454.                                                 shell.run(tempDots[dotIndex].fullPath)
  455.  
  456.                                                 -- Dump the screen buffer and return from the screen.
  457.                                                 dumpBuffer()
  458.                                                 return
  459.                                         -- If the option was to enter the given directory, then enter the directory.
  460.                                         else
  461.                                                 -- Set the current directory to the appropriate path.
  462.                                                 currentDirectory = tempDots[dotIndex].fullPath
  463.                                                 -- Reinitialize the dots and reset the scroll offset.
  464.                                                 resetScreen(tempDots[dotIndex].fullPath)
  465.                                                
  466.                                                 -- Dump the screen buffer and return from the screen.
  467.                                                 dumpBuffer()
  468.                                                 return
  469.                                         end
  470.                                 -- If the click was on the back button, then leave the screen.
  471.                                 elseif (p2 >= screenWidth - 1 and p2 <= screenWidth) and p3 == screenHeight then
  472.                                         dumpBuffer()
  473.                                         return
  474.                                 -- If the click was on the change color button, then bring up the change color screen.
  475.                                 elseif (p2 >= 4 and p2 <= 4 + ("Change"):len()) and p3 == 14 then
  476.                                         -- Change the color.
  477.                                         dumpBuffer()
  478.                                         modifyDotColorPropertyFile(tempDots[dotIndex].label, tempDots[dotIndex].fullPath, changeDotColor(tempDots[dotIndex]) or tempDots[dotIndex].color)
  479.                                         resetScreen(currentDirectory)
  480.                                         return
  481.                                 end
  482.                         end
  483.                 end
  484.         end
  485. end
  486.  
  487. -- Presents a screen that allows the user to pick the color of the dot.
  488. function changeDotColor(dot)
  489.         -- Draw a screen that shows the current color of the dot,
  490.         -- the dot's name, path, and a list of colors we can change it to.
  491.         local dotCenterPos = screenWidth/2 - (dot.label:len() + 3)/2 - 5
  492.  
  493.         clearScreen()
  494.         term.setBackgroundColor(colors.cyan)
  495.         term.setTextColor(colors.white)
  496.         term.setCursorPos(dotCenterPos, 1)
  497.         term.write(dot.label .. " :")
  498.         term.setBackgroundColor(dot.color)
  499.         term.write(' ')
  500.         term.setBackgroundColor(BACKGROUND_COLOR)
  501.  
  502.         -- Draw the dot path.
  503.         term.setCursorPos(dotCenterPos, 2)
  504.         term.write("Path: " .. dot.fullPath)
  505.  
  506.         -- Draw the list of colors that we can change the color to.
  507.         local colorPositions = {}
  508.         local pos = dotCenterPos + 2
  509.         local line = 5
  510.         for index, color in pairs(colors) do
  511.                 if type(color) == "number" and color ~= colors.cyan and color ~= colors.red then
  512.                         term.setCursorPos(pos, line)
  513.                         term.setBackgroundColor(color)
  514.                         term.write(' ')
  515.  
  516.                         -- Add the color just written to the color positions table so we can click it.
  517.                         local entry = {pos, line, color}
  518.                         table.insert(colorPositions, entry)
  519.                         -- Increment the positions for the next color.
  520.                         pos = pos + 2
  521.                         if pos >= 28 then
  522.                                 pos = dotCenterPos + 2
  523.                                 line = line + 2
  524.                         end
  525.                 end
  526.         end
  527.  
  528.         -- Draw a back button that is clickable.
  529.         term.setCursorPos(1, screenHeight)
  530.         term.setBackgroundColor(colors.lightBlue)
  531.         term.setTextColor(colors.white)
  532.         term.write("<-")
  533.         -- Handle mouse clicks so we can change the color accordingly.
  534.         while true do
  535.                 local event, clickType, xClickPos, yClickPos = os.pullEvent("mouse_click")
  536.  
  537.                 -- Check if the click was on a color. If it was, then return the color clicked.
  538.                 for index = 1, #colorPositions do
  539.                         if xClickPos == math.floor(colorPositions[index][1]) and yClickPos == colorPositions[index][2] then
  540.                                 return colorPositions[index][3]
  541.                         end
  542.                 end
  543.                 -- Check if the click was on the back button. If it was, then return nil.
  544.                 if xClickPos <= 2 and yClickPos == screenHeight then
  545.                         return nil
  546.                 end
  547.         end
  548. end
  549.  
  550. -- Changes the dot property of the given dot.
  551. function modifyDotColorPropertyFile(dotLabel, dotPath, newColor)
  552.         newColor = getColorFromValue(newColor)
  553.         -- Get the specific identifier of the dot given.
  554.         local dotIdentifier = string.gsub(dotPath, '/', '_')
  555.         -- Open the dot property file for the given dot.
  556.         local propertyFileHandle = fs.open(propertiesDirectory .. '/' .. dotLabel .. '_' .. dotIdentifier, 'w')
  557.         propertyFileHandle.write(newColor)
  558.         propertyFileHandle.close()
  559. end
  560. --=END DOT FUNCTIONS==================--
  561.  
  562.  
  563.  
  564. --=CALCULATING FUNCTIONS==============--
  565. -- Calculates the size in spaces that the scroll bar should be depending
  566. -- on the amount of dots present on the screen.
  567. function calculateScrollBar()
  568.         if tDots then
  569.                 local size = math.floor(18 / (#tDots / 225))
  570.                 -- Make sure that the size is not an unusable number (inf).
  571.                 if 1/0 == size then
  572.                         return nil
  573.                 -- If the size is usable, then return it to the calling function.
  574.                 else
  575.                         return size
  576.                 end
  577.         end
  578.  
  579.         return nil
  580. end
  581. --=END CALCULATING FUNCTIONS==========--
  582.  
  583.  
  584.  
  585. --=DRAWING FUNCTIONS==================--
  586. -- Draws a larger representation of the given dot color.
  587. function drawLargeDot(dotColor)
  588.         term.setBackgroundColor(dotColor)
  589.  
  590.         for line = 5, 13 do
  591.                 for pos = 4, 12 do
  592.                         term.setCursorPos(pos, line)
  593.                         term.write(' ')
  594.                 end
  595.         end
  596.  
  597.         -- Reset the background color to the default background color.
  598.         term.setBackgroundColor(BACKGROUND_COLOR)
  599. end
  600.  
  601. -- Draws the scroll bar to the right of thes screen.
  602. function drawScrollBar(scrollBarSize)
  603.         -- Reset the sroll bar table.
  604.         tScrollBarPositions = {}
  605.  
  606.         -- Draw the area for the scroll bar.
  607.         term.setBackgroundColor(colors.white)
  608.         for line = 1, screenHeight do
  609.                 term.setCursorPos(screenWidth, line)
  610.                 term.write(' ')
  611.         end
  612.  
  613.         -- Draw the scroll bar.
  614.         term.setBackgroundColor(colors.lightGray)
  615.         for block = 1, scrollBarSize do
  616.                 -- Make sure that the position we're drawing is on screen.
  617.                 if scrollOffset + block <= screenHeight and scrollOffset + block >= 1 then
  618.                         term.setCursorPos(screenWidth, scrollOffset + block)
  619.                         table.insert(tScrollBarPositions, scrollOffset + block) -- Add the position drawn to the table
  620.                                                                                 -- so we may keep track of it.
  621.                         term.write(' ')
  622.                 end
  623.         end
  624.  
  625.         -- Reset the background color to black.
  626.         term.setBackgroundColor(colors.black)
  627. end
  628.  
  629. -- Draws the back button to the screen without the screen buffer.
  630. function drawBackButton()
  631.         term.setBackgroundColor(colors.lightBlue)
  632.         term.setTextColor(colors.white)
  633.  
  634.         term.setCursorPos(1, screenHeight)
  635.         term.write("<-")
  636. end
  637.  
  638. -- Draws the current directory that we are in.
  639. function drawPath()
  640.         term.setBackgroundColor(colors.lightBlue)
  641.         term.setTextColor(colors.white)
  642.  
  643.         -- Make sure that the directory to be drawn is less than or equal 25 characters in length.
  644.         if currentDirectory:len() <= 25 then
  645.                 term.setCursorPos(screenWidth - currentDirectory:len() - 1, screenHeight)
  646.                 term.write(currentDirectory)
  647.         else
  648.                 term.setCursorPos(screenWidth - 26, screenHeight)
  649.                 term.write(currentDirectory:sub(1, 22) .. "...")
  650.         end
  651. end
  652.  
  653. -- Draws the delete, move, and copy options for when in a dot profile screen.
  654. function drawDotCommands()
  655. end
  656. --=END DRAWING FUNCTIONS==============--
  657.  
  658.  
  659.  
  660. --=INPUT HANDLING FUNCTIONS===========--
  661. -- Handles limited amounts of character input. Returns the string that was typed.
  662. function limitRead( nLength, cReplaceChar )
  663.         term.setCursorBlink( true )
  664.        
  665.         nLength = nLength or -1 -- -1 is unlimited
  666.         sReturnString = ""
  667.        
  668.         xPos, yPos = term.getCursorPos()
  669.        
  670.         while true do
  671.                 event, char = os.pullEvent()
  672.                
  673.                 if nLength ~= -1 and string.len( sReturnString ) >= nLength then term.setCursorBlink( false ); return sReturnString end -- Length check
  674.                
  675.                 if event == "char" then sReturnString = sReturnString .. char
  676.                 elseif event == "key" and char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
  677.                 elseif event == "key" and char == 14 then -- Backspace
  678.                         term.setCursorPos( xPos, yPos )
  679.                         term.write( string.rep( " ", string.len( sReturnString ) ) )
  680.                         sReturnString = string.sub( sReturnString, 1, string.len( sReturnString )-1 )
  681.                         term.setCursorPos( xPos, yPos )
  682.                        
  683.                         if not cReplaceChar then term.write( sReturnString )
  684.                         else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  685.                 end
  686.                
  687.                 term.setCursorPos( xPos, yPos )
  688.                 term.write( string.rep( " ", string.len( sReturnString ) ) )
  689.                 term.setCursorPos( xPos, yPos )
  690.                 if not cReplaceChar then term.write( sReturnString )
  691.                 else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  692.         end
  693. end
  694.  
  695. -- Handles mouse-wheel events.
  696. function handleMouseScroll(direction)
  697.         -- Typically, the mouse wheel is used to scroll the screen.
  698.         -- The above is how we will go about treating such an event.
  699.         local scrollUp = (direction == - 1 and true or false)
  700.        
  701.         return scrollDots(scrollUp) -- Scroll the screen.
  702. end
  703. --=END INPUT HANDLING FUNCTIONS=======--
  704.  
  705.  
  706. --=VALIDATION FUNCTIONS===============--
  707. -- Checks if a mouse-drag was on the scroll bar. If the mouse was dragged
  708. -- on the scroll bar, then the function will handle the scrolling.
  709. function scrollWithDrag(xDragPos, yDragPos)
  710.         local wasDragged = false -- Whether or not the scroll bar was dragged.
  711.         local blockDragged = 0 -- The index of the black/position of the scroll bar dragged.
  712.  
  713.         -- Make sure that the drag was on a piece of the scroll bar.
  714.         for index, position in ipairs(tScrollBarPositions) do
  715.                 if xDragPos == screenWidth then
  716.                         if yDragPos == position then
  717.                                 wasDragged = true -- The scroll bar was dragged. Set the dragged flag to true.
  718.                                 blockDragged = position -- Set the block that was dragged by the scroll bar.
  719.                                 break
  720.                         end
  721.                 end
  722.         end
  723.  
  724.         -- If the scroll bar was dragged, then calculate the direction in which it was scrolled.
  725.         if wasDragged then
  726.                 -- Run a loop to handle the scrolling until any event other than a mouse drag is trhown.
  727.                 while true do
  728.                         local event, p1, p2, p3 = os.pullEvent()
  729.                        
  730.                         -- If the event pulled was a mouse drag, then scroll the screen.
  731.                         if event == "mouse_drag" then
  732.                                 -- If the yPosition of this drag was greater than that of the first drag,
  733.                                 -- then the scroll was down.
  734.                                 if p3 > yDragPos then
  735.                                         tempDots = scrollDots(false)
  736.                                 -- If the yPosition of this drag was less than that of the first drag,
  737.                                 -- then the scroll was up.
  738.                                 else
  739.                                         tempDots = scrollDots(true)
  740.                                 end
  741.                         -- If the event pulled was anything but a mouse drag, then return from this function.
  742.                         else
  743.                                 return
  744.                         end
  745.                         clearScreen()
  746.                         drawDots(tempDots) -- Redraw the dots that have now been scrolled.
  747.                 end
  748.         end
  749. end
  750.  
  751. -- Checks if the mouse clicked somewhere on the scroll bar.
  752. -- Returns false and nil if it didn't; true and the scrolled dots if it did.
  753. function didClickOnScrollBar(xClickPos, yClickPos)
  754.         -- Check if the xClickPos was on the sreenWidth.
  755.         if xClickPos == screenWidth then
  756.                 -- Make sure that the click was not on the scroll bar itself, but
  757.                 -- on the white part of it.
  758.                 for index, position in ipairs(tScrollBarPositions) do
  759.                         -- If the y position of the click was actually on one of the scroll bar blocks, then return
  760.                         -- false and nil.
  761.                         if yClickPos == position then
  762.                                 return false, nil
  763.                         end
  764.                 end
  765.  
  766.                 -- If the function did not return after the above loop, then place the top of the scroll bar at
  767.                 -- the y position of the click.
  768.                 scrollOffset = yClickPos -- Do not subtract one from the scroll offset after this line because that will be
  769.                                          -- done when we call 'scrollDots' for an upwards scroll.
  770.                 return true, scrollDots(true)
  771.         end
  772.  
  773.         -- If the function hasn't returned by now, then the click was not
  774.         -- on the scroll bar. Return false and nil.
  775.         return false, nil
  776. end
  777.  
  778. -- Checks if a dot was clicked. Returns the index in the dot table of the on-screen dots.
  779. -- Returns nil if no dot was clicked.
  780. function checkIfDotWasClicked(xClickPos, yClickPos)
  781.         -- Check if the click was on a dot. Remebering that once the dots are drawn, their positions are saved
  782.         -- in the tempDots table as the 5th and 6th index (xPos, yPos).
  783.         local dotIndex = nil -- The index of the dot (potentially) clicked.
  784.         for index, dot in pairs(tempDots) do
  785.                 if xClickPos == dot.xPos and yClickPos == dot.yPos then
  786.                         dotIndex = index
  787.                         break
  788.                 end
  789.         end
  790.  
  791.         return dotIndex
  792. end
  793.  
  794. -- Checks if the back button was clicked. Returns true if so; false if not.
  795. function checkIfClickedOnBackButton(xClickPos, yClickPos)
  796.         if xClickPos >=1 and xClickPos <= 2 and yClickPos == screenHeight then
  797.                 return true
  798.         end
  799.  
  800.         -- If the function has not returned by now, then the back button was not clickecd.
  801.         -- Return false.
  802.         return false
  803. end
  804. --=END VALIDATION FUNCTIONS===========--
  805.  
  806.  
  807. --=DIRECTORY HANDLING FUNCTIONS=======--
  808. -- Moves the directory given back one level. Returns the backed up directory.
  809. function moveBackDirectoryLevel(directory)
  810.         return directory:sub(1, directory:find(fs.getName(directory)) - 2)
  811. end
  812. --=END DIRECTORY HANDLING FUNCTIONS===--
  813.  
  814. initializeDots(currentDirectory) -- Add the contents of the root directory to the dots.
  815. tempDots = tDots
  816.  
  817. while true do
  818.         clearScreen()
  819.         drawDots(tempDots)
  820.         redrawBuffer() -- I know this seems kind of redundant, but it is necessary for drawing items that are not dots and are in
  821.                        -- the screen buffer.
  822.         if currentDirectory ~= "" then
  823.                 drawBackButton() -- Draws the back button if we are in a directory other than the root.
  824.                 drawPath() -- Draws the current directory that we are in.
  825.         end
  826.  
  827.         local event, param1, param2, param3 = os.pullEvent()
  828.        
  829.         -- If the event was a mouse wheel scroll, then scroll the screen accordingly.
  830.         if event == "mouse_scroll" then
  831.                 tempDots =  handleMouseScroll(param1) -- Param1 will be the direction of the scroll in this case.
  832.         -- If the event was a mouse drag, then handle the drag accordingly.
  833.         elseif event == "mouse_drag" then
  834.                 -- Attempt to scroll the dots with a mouse drag. This function will return after all scrolling
  835.                 -- has been handled.
  836.                 scrollWithDrag(param2, param3)
  837.         -- If the event was a mouse click, then handle the click accordingly.
  838.         elseif event == "mouse_click" then
  839.                 -- Check if the mouse click was on the scroll bar. If it was, then see if we can't
  840.                 -- jump the scroll bar to the position clicked.
  841.                 local didClick, scrolledDots = didClickOnScrollBar(param2, param3)
  842.                 if didClick then
  843.                         tempDots = scrolledDots -- Set the dots to be displayed as the scrolled dot table returned by the click
  844.                                                 -- scroll function.
  845.                 -- If the click was not on the scroll bar/was not meant to scroll the screen...
  846.                 else
  847.                         -- Check if the click was on a dot.
  848.                         local dotClickedIndex = checkIfDotWasClicked(param2, param3)
  849.                         if dotClickedIndex then
  850.                                 drawDotScreen(dotClickedIndex)
  851.                         -- If the click was not on a dot, then check if it was on the back button to return from a directory.
  852.                         else
  853.                                 -- Make sure that we are not in the root directory.
  854.                                 if currentDirectory ~= "" and checkIfClickedOnBackButton(param2, param3) then
  855.                                         -- If the click was on the back button, then move back one level.
  856.                                         currentDirectory = moveBackDirectoryLevel(currentDirectory)
  857.                                         -- Reset the screen now that the directory has changed.
  858.                                         resetScreen(currentDirectory)
  859.                                 end
  860.                         end
  861.                 end
  862.         end
  863. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement