FelixPBanan

Writer[GUI]

Nov 18th, 2017
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.66 KB | None | 0 0
  1. local component = require("component")
  2. local unicode = require("unicode")
  3. local fs = require("filesystem")
  4. local event = require("event")
  5. local gpu = component.gpu
  6. local internet = component.internet
  7.  
  8. ---------------------------------------------------------------------------------------------------------------------------------
  9.  
  10. local files = {
  11.   {
  12.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/advancedLua.lua",
  13.     path = "/lib/advancedLua.lua"
  14.   },
  15.   {
  16.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/color.lua",
  17.     path = "/lib/color.lua"
  18.   },
  19.   {
  20.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/ImageFormatModules/OCIF.lua",
  21.     path = "/lib/ImageFormatModules/OCIF.lua"
  22.   },
  23.   {
  24.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/ImageFormatModules/RAW.lua",
  25.     path = "/lib/ImageFormatModules/RAW.lua"
  26.   },
  27.   {
  28.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/image.lua",
  29.     path = "/lib/image.lua"
  30.   },
  31.   {
  32.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/doubleBuffering.lua",
  33.     path = "/lib/doubleBuffering.lua"
  34.   },
  35.   {
  36.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/syntax.lua",
  37.     path = "/lib/syntax.lua"
  38.   },
  39.   {
  40.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/palette.lua",
  41.     path = "/lib/palette.lua"
  42.   },
  43.   {
  44.     url = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/GUI.lua",
  45.     path = "/lib/GUI.lua"
  46.   },
  47.   {
  48.     url = "https://raw.githubusercontent.com/FelixBanan/OpenSecurity/master/Writer.lua",
  49.     path = "/Writer.lua"
  50.   },
  51. }
  52.  
  53. local properties = {
  54.     -- Comment any coordinate to calculate it automatically (will centerize window on screen by specified axis)
  55.     --windowX = 2,
  56.     --windowY = 2,
  57.     -- Set window width value lower than zero (0.5 for example) to calculate it dependent on screen width
  58.     windowWidth = 54,
  59.     -- Customize offset by X axis from window corners
  60.     GUIElementsOffset = 2,
  61.     -- Customize localization as you want to
  62.     localization = {
  63.         -- Specify title of your installer
  64.         title = "Writer[GUI] installer",
  65.         -- Use <currentProgress>, <totalProgress> and <currentFile> text insertions to automatically display their values
  66.         currentFile = "Downloading \"<currentFile>\"",
  67.         totalProgress = "Total progress: <totalProgress>%",
  68.         -- Comment this lines to automatically close installer window
  69.         finished1 = "Writer[GUI] has been successfully installed",
  70.         finished2 = "Press any key to quit"
  71.     },
  72.     -- Customize color scheme as you want to
  73.     colors = {
  74.         window = {
  75.             background = 0xEEEEEE,
  76.             text = 0x999999,
  77.             shadow = 0x3C3C3C
  78.         },
  79.         title = {
  80.             background = 0xCCCCCC,
  81.             text = 0x555555,
  82.         },
  83.         progressBar = {
  84.             active = 0x0092FF,
  85.             passive = 0xCCCCCC
  86.         }
  87.     }
  88. }
  89.  
  90. ---------------------------------------------------------------------------------------------------------------------------------
  91.  
  92. local screenWidth, screenHeight = gpu.getResolution()
  93. properties.windowHeight = 8
  94.  
  95. if properties.windowWidth < 1 then
  96.     properties.windowWidth = math.floor(screenWidth * properties.windowWidth)
  97. end
  98. progressBarWidth = properties.windowWidth - properties.GUIElementsOffset * 2
  99.  
  100. if not properties.windowX then
  101.     properties.windowX = math.floor(screenWidth / 2 - properties.windowWidth / 2)
  102. end
  103.  
  104. if not properties.windowY then
  105.     properties.windowY = math.floor(screenHeight / 2 - properties.windowHeight / 2)
  106. end
  107.  
  108. local currentBackground, currentForeground
  109.  
  110. ---------------------------------------------------------------------------------------------------------------------------------
  111.  
  112. local function setBackground(color)
  113.     if currentBackground ~= color then
  114.         gpu.setBackground(color)
  115.         currentBackground = color
  116.     end
  117. end
  118.  
  119. local function setForeground(color)
  120.     if currentForeground ~= color then
  121.         gpu.setForeground(color)
  122.         currentForeground = color
  123.     end
  124. end
  125.  
  126. local function rectangle(x, y, width, height, color)
  127.     setBackground(color)
  128.     gpu.fill(x, y, width, height, " ")
  129. end
  130.  
  131. local function centerizedText(y, color, text)
  132.     local textLength = unicode.len(text)
  133.     if textLength > progressBarWidth then
  134.         text = unicode.sub(text, 1, progressBarWidth)
  135.         textLength = progressBarWidth
  136.     end
  137.  
  138.     setForeground(color)
  139.     gpu.set(properties.windowX + properties.GUIElementsOffset, y, string.rep(" ", progressBarWidth))
  140.     gpu.set(math.floor(properties.windowX + properties.GUIElementsOffset + progressBarWidth / 2 - textLength / 2), y, text)
  141. end
  142.  
  143. local function progressBar(y, percent, text, totalProgress, currentProgress, currentFile)
  144.     setForeground(properties.colors.progressBar.passive)
  145.     gpu.set(properties.windowX + properties.GUIElementsOffset, y, string.rep("━", progressBarWidth))
  146.     setForeground(properties.colors.progressBar.active)
  147.     gpu.set(properties.windowX + properties.GUIElementsOffset, y, string.rep("━", math.ceil(progressBarWidth * percent)))
  148.  
  149.     text = text:gsub("<totalProgress>", totalProgress)
  150.     text = text:gsub("<currentProgress>", currentProgress)
  151.     text = text:gsub("<currentFile>", currentFile)
  152.  
  153.     centerizedText(y + 1, properties.colors.window.text, text)
  154. end
  155.  
  156. local function download(url, path, totalProgress)
  157.     fs.makeDirectory(fs.path(path))
  158.  
  159.     local file, fileReason = io.open(path, "w")
  160.     if file then
  161.         local pcallSuccess, requestHandle = pcall(internet.request, url)
  162.         if pcallSuccess then
  163.             if requestHandle then
  164.                 -- Drawing progressbar once with zero percentage
  165.                 local y = properties.windowY + 2
  166.                 progressBar(y, 0, properties.localization.currentFile, totalProgress, "0", path)
  167.                
  168.                 -- Waiting for any response code
  169.                 local responseCode, responseName, responseData
  170.                 repeat
  171.                     responseCode, responseName, responseData = requestHandle:response()
  172.                 until responseCode
  173.  
  174.                 -- Downloading file by chunks
  175.                 if responseData and responseData["Content-Length"] then
  176.                     local contentLength = tonumber(responseData["Content-Length"][1])
  177.                     local currentLength = 0
  178.                     while true do
  179.                         local data, reason = requestHandle.read(math.huge)
  180.                         if data then
  181.                             currentLength = currentLength + unicode.len(data)
  182.                             local percent = currentLength / contentLength
  183.                             progressBar(y, percent, properties.localization.currentFile, totalProgress, tostring(math.ceil(percent)), path)
  184.  
  185.                             file:write(data)
  186.                         else
  187.                             requestHandle:close()
  188.                             if reason then
  189.                                 error(reason)
  190.                             else
  191.                                 file:close()
  192.                                 return
  193.                             end
  194.                         end
  195.                     end
  196.                 else
  197.                     error("Response Content-Length header is missing: " .. tostring(responseCode) .. " " .. tostring(responseName))
  198.                 end
  199.             else
  200.                 error("Invalid URL-address: " .. tostring(url))
  201.             end
  202.         else
  203.             error("Usage: component.internet.request(string url)")
  204.         end
  205.  
  206.         file:close()
  207.     else
  208.         error("Failed to open file for writing: " .. tostring(fileReason))
  209.     end
  210. end
  211.  
  212. ---------------------------------------------------------------------------------------------------------------------------------
  213.  
  214. -- Copying current screen data
  215. local oldPixels = {}
  216. for y = properties.windowY, properties.windowY + properties.windowHeight do
  217.     oldPixels[y] = {}
  218.     for x = properties.windowX, properties.windowX + properties.windowWidth do
  219.         oldPixels[y][x] = { gpu.get(x, y) }
  220.     end
  221. end
  222.  
  223. local function shadowPixel(x, y, symbol)
  224.     setBackground(oldPixels[y][x][3])
  225.     gpu.set(x, y, symbol)
  226. end
  227.  
  228. -- Vertical shadow
  229. rectangle(properties.windowX + properties.windowWidth, properties.windowY + 1, 1, properties.windowHeight - 1, properties.colors.window.shadow)
  230. setForeground(properties.colors.window.shadow)
  231. shadowPixel(properties.windowX + properties.windowWidth, properties.windowY, "▄")
  232.  
  233. -- Horizontal shadow
  234. for i = properties.windowX + 1, properties.windowX + properties.windowWidth do
  235.     shadowPixel(i, properties.windowY + properties.windowHeight, "▀")
  236. end
  237.  
  238. -- Window background
  239. rectangle(properties.windowX, properties.windowY + 1, properties.windowWidth, properties.windowHeight - 1, properties.colors.window.background)
  240.  
  241. -- Title
  242. rectangle(properties.windowX, properties.windowY, properties.windowWidth, 1, properties.colors.title.background)
  243. centerizedText(properties.windowY, properties.colors.title.text, properties.localization.title)
  244. setBackground(properties.colors.window.background)
  245.  
  246. -- Downloading
  247. local y = properties.windowY + 5
  248. progressBar(y, 0, properties.localization.totalProgress, "0", "0", files[1].path)
  249. for i = 1, #files do
  250.     local percent = i / #files
  251.     local totalProgress = tostring(math.ceil(percent * 100))
  252.     download(files[i].url, files[i].path, totalProgress)
  253.     progressBar(y, percent, properties.localization.totalProgress, totalProgress, "0", files[i].path)
  254. end
  255.  
  256. -- On exit
  257. if properties.localization.finished1 then
  258.     rectangle(properties.windowX, properties.windowY + 1, properties.windowWidth, properties.windowHeight - 1, properties.colors.window.background)
  259.     centerizedText(properties.windowY + 3, properties.colors.window.text, properties.localization.finished1)
  260.     centerizedText(properties.windowY + 4, properties.colors.window.text, properties.localization.finished2)
  261.  
  262.     while true do
  263.         local eventType = event.pull()
  264.         if eventType == "key_down" or eventType == "touch" then
  265.             break
  266.         end
  267.     end
  268. end
  269.  
  270. -- Redraw old pixels
  271. for y = properties.windowY, properties.windowY + properties.windowHeight do
  272.     for x = properties.windowX, properties.windowX + properties.windowWidth do
  273.         setBackground(oldPixels[y][x][3])
  274.         setForeground(oldPixels[y][x][2])
  275.         gpu.set(x, y, oldPixels[y][x][1])
  276.     end
  277. end
Advertisement
Add Comment
Please, Sign In to add comment