Advertisement
blunty666

glassWindow

Sep 4th, 2015
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.23 KB | None | 0 0
  1. local colourToRGB = {
  2.     [colours.white] = 0xf0f0f0,
  3.     [colours.orange] = 0xf2b233,
  4.     [colours.magenta] = 0xe57fd8,
  5.     [colours.lightBlue] = 0x99b2f2,
  6.     [colours.yellow] = 0xdede6c,
  7.     [colours.lime] = 0x7fcc19,
  8.     [colours.pink] = 0xf2b2cc,
  9.     [colours.grey] = 0x4c4c4c,
  10.     [colours.lightGrey] = 0x999999,
  11.     [colours.cyan] = 0x4c99b2,
  12.     [colours.purple] = 0xb266e5,
  13.     [colours.blue] = 0x3366cc,
  14.     [colours.brown] = 0x7f664c,
  15.     [colours.green] = 0x57a64e,
  16.     [colours.red] = 0xcc4c4c,
  17.     [colours.black] = 0x000000,
  18. }
  19.  
  20. local rgbToColour = {}
  21. for ccColour, glassesHex in pairs(colourToRGB) do
  22.     rgbToColour[glassesHex] = ccColour
  23. end
  24.  
  25. local hexValues = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}
  26. local hexToColour = {}
  27. for i = 1, 16 do
  28.     hexToColour[hexValues[i]] = colourToRGB[2^(i-1)]
  29. end
  30.  
  31. local charOffset = {
  32.     ["!"] = 2, ["'"] = 2, ["("] = 1, [")"] = 1, ["*"] = 1, [","] = 2, ["."] = 2, [":"] = 2,
  33.     [";"] = 2,  ["<"] = 1, [">"] = 1, ["I"] = 1, ["["] = 1, ["["] = 1, ["`"] = 2, ["f"] = 1,
  34.     ["i"] = 2, ["k"] = 1, ["l"] = 2, ["t"] = 1, ["{"] = 1, ["|"] = 2, ["}"] = 1,
  35. }
  36.  
  37. function new(surface, width, height, xOffset, yOffset, zOffset, opacity)
  38.     local surface = surface
  39.    
  40.     local width, height = width or 51, height or 19
  41.     local xOffset, yOffset, zOffset = xOffset or -(math.floor(width*6/2)), yOffset or -(math.floor(height*9/2)), zOffset or 1
  42.    
  43.     local map = {}
  44.    
  45.     local clickCatcherID = false
  46.     local clickCatcherObject = false
  47.    
  48.     local cursorX, cursorY = 1, 1
  49.     local cursorBlink = false
  50.     local cursorObject = false
  51.    
  52.     local currentTextColour = colourToRGB[colours.white]
  53.     local currentBackgroundColour = colourToRGB[colours.black]
  54.    
  55.     local isDrawn = false
  56.     local isVisible = true
  57.     local opacity = opacity or 1
  58.     local hasChanged = false
  59.     local horizontalAlign, verticalAlign = "MIDDLE", "MIDDLE"
  60.    
  61.     local bezelDrawn = false
  62.     local topBezel, bottomBezel, leftBezel, rightBezel = false, false, false, false
  63.    
  64.     local function drawBezel()
  65.         topBezel = surface.addBox(xOffset - 6, yOffset - 9, (width + 2)*6, 9, 0xdcd56c, opacity)
  66.         topBezel.setScreenAnchor(horizontalAlign, verticalAlign)
  67.         topBezel.setVisible(isVisible)
  68.         topBezel.setZ(zOffset)
  69.         bottomBezel = surface.addBox(xOffset - 6, yOffset + height*9, (width + 2)*6, 9, 0xdcd56c, opacity)
  70.         bottomBezel.setScreenAnchor(horizontalAlign, verticalAlign)
  71.         bottomBezel.setVisible(isVisible)
  72.         bottomBezel.setZ(zOffset)
  73.         leftBezel = surface.addBox(xOffset - 6, yOffset, 6, height*9, 0xdcd56c, opacity)
  74.         leftBezel.setScreenAnchor(horizontalAlign, verticalAlign)
  75.         leftBezel.setVisible(isVisible)
  76.         leftBezel.setZ(zOffset)
  77.         rightBezel = surface.addBox(xOffset + (width*6), yOffset, 6, height*9, 0xdcd56c, opacity)
  78.         rightBezel.setScreenAnchor(horizontalAlign, verticalAlign)
  79.         rightBezel.setVisible(isVisible)
  80.         rightBezel.setZ(zOffset)
  81.     end
  82.    
  83.     local function eraseBezel()
  84.         if topBezel then
  85.             topBezel.delete()
  86.             topBezel = false
  87.         end
  88.         if bottomBezel then
  89.             bottomBezel.delete()
  90.             bottomBezel = false
  91.         end
  92.         if leftBezel then
  93.             leftBezel.delete()
  94.             leftBezel = false
  95.         end
  96.         if rightBezel then
  97.             rightBezel.delete()
  98.             rightBezel = false
  99.         end
  100.     end
  101.    
  102.     local function drawClickCatcher()
  103.         clickCatcherObject = surface.addBox(xOffset, yOffset, width*6, height*9, 0x000000, 0)
  104.         clickCatcherObject.setScreenAnchor(horizontalAlign, verticalAlign)
  105.         clickCatcherObject.setVisible(isVisible)
  106.         clickCatcherObject.setZ(zOffset + 3)
  107.         clickCatcherID = clickCatcherObject.getId()
  108.     end
  109.    
  110.     local function eraseClickCatcher()
  111.         if clickCatcherObject then
  112.             clickCatcherObject.delete()
  113.             clickCatcherObject = false
  114.         end
  115.         clickCatcherID = false
  116.     end
  117.    
  118.     local function drawText(xPos, yPos, text, textColour)
  119.         local textObject = surface.addText((xPos-1)*6 + xOffset + (charOffset[text] or 0), (yPos-1)*9 + yOffset, text, textColour)
  120.         textObject.setScreenAnchor(horizontalAlign, verticalAlign)
  121.         textObject.setVisible(isVisible)
  122.         textObject.setZ(zOffset + 1)
  123.         return textObject
  124.     end
  125.    
  126.     local function drawBackground(xPos, yPos, backgroundColour)
  127.         local backgroundObject = surface.addBox((xPos-1)*6 + xOffset, (yPos-1)*9 + yOffset, 6, 9, backgroundColour, opacity)
  128.         backgroundObject.setScreenAnchor(horizontalAlign, verticalAlign)
  129.         backgroundObject.setVisible(isVisible)
  130.         backgroundObject.setZ(zOffset)
  131.         return backgroundObject
  132.     end
  133.    
  134.     local function drawCursor()
  135.         cursorObject = surface.addText((cursorX-1)*6 + xOffset, (cursorY-1)*9 + yOffset, "_", currentTextColour)
  136.         cursorObject.setScreenAnchor(horizontalAlign, verticalAlign)
  137.         cursorObject.setVisible((isVisible and cursorBlink and (map[cursorY] and map[cursorY][cursorX]) and true) or false)
  138.         cursorObject.setZ(zOffset + 2)
  139.     end
  140.    
  141.     local function createCoord(xPos, yPos, text, textColour, backgroundColour)
  142.         local coord = {
  143.             text = text,
  144.             textCol = textColour,
  145.             backCol = backgroundColour,
  146.             textObj = false,
  147.             backObj = false,
  148.         }
  149.         if isDrawn then
  150.             coord.textObj = drawText(xPos, yPos, text, textColour)
  151.             coord.backObj = drawBackground(xPos, yPos, backgroundColour)
  152.         end
  153.         return coord
  154.     end
  155.    
  156.     local updateTextObj
  157.     local function updateCoord(xPos, yPos, text, textColour, backgroundColour)
  158.         local coord = map[yPos] and map[yPos][xPos]
  159.         if coord then
  160.             if coord.text ~= text or coord.textCol ~= textColour or coord.backCol ~= backgroundColour then
  161.                 coord.text = text
  162.                 coord.textCol = textColour
  163.                 coord.backCol = backgroundColour
  164.            
  165.                 if isDrawn then
  166.                     updateTextObj = coord.textObj
  167.                     updateTextObj.setText(text)
  168.                     updateTextObj.setColor(textColour)
  169.                     updateTextObj.setX((xPos-1)*6 + xOffset + (charOffset[text] or 0))
  170.            
  171.                     coord.backObj.setColor(backgroundColour)
  172.                 end
  173.            
  174.                 hasChanged = true
  175.             end
  176.         end
  177.     end
  178.    
  179.     local function updateCursor()
  180.         if isDrawn and cursorObject then
  181.             cursorObject.setX((cursorX-1)*6 + xOffset)
  182.             cursorObject.setY((cursorY-1)*9 + yOffset)
  183.             cursorObject.setZ(zOffset + 2)
  184.             cursorObject.setVisible((isVisible and cursorBlink and (map[cursorY] and map[cursorY][cursorX]) and true) or false)
  185.             cursorObject.setColor(currentTextColour)
  186.         end
  187.     end
  188.    
  189.     local glassWindow = {}
  190.    
  191.     glassWindow.getDrawn = function()
  192.         return isDrawn
  193.     end
  194.     glassWindow.setDrawn = function(setDrawn)
  195.         if type(setDrawn) == "boolean" and isDrawn ~= setDrawn then
  196.             if setDrawn == true then
  197.                 local coord
  198.                 for yPos = 1, height do
  199.                     for xPos = 1,width do
  200.                         coord = map[yPos][xPos]
  201.                         coord.textObj = drawText(xPos, yPos, coord.text, coord.textCol)
  202.                         coord.backObj = drawBackground(xPos, yPos, coord.backCol)
  203.                     end
  204.                 end
  205.                 if bezelDrawn then
  206.                     drawBezel()
  207.                 end
  208.                 drawClickCatcher()
  209.                 drawCursor()
  210.             else
  211.                 local coord
  212.                 for yPos = 1, height do
  213.                     for xPos = 1,width do
  214.                         coord = map[yPos][xPos]
  215.                         coord.textObj.delete()
  216.                         coord.backObj.delete()
  217.                         coord.textObj = false
  218.                         coord.backObj = false
  219.                     end
  220.                 end
  221.                 cursorObject.delete()
  222.                 cursorObject = false
  223.                 eraseClickCatcher()
  224.                 eraseBezel()
  225.             end
  226.             isDrawn = setDrawn
  227.             hasChanged = true
  228.             return true
  229.         end
  230.         return false
  231.     end
  232.    
  233.     glassWindow.getAlignment = function()
  234.         return horizontalAlign, verticalAlign
  235.     end
  236.     glassWindow.setAlignment = function(horizontal, vertical)
  237.         --if check args then
  238.             if isDrawn then
  239.                 local coord
  240.                 for yPos = 1, height do
  241.                     for xPos = 1,width do
  242.                         coord = map[yPos][xPos]
  243.                         coord.textObj.setScreenAnchor(horizontal, vertical)
  244.                         coord.backObj.setScreenAnchor(horizontal, vertical)
  245.                     end
  246.                 end
  247.                 if bezelDrawn then
  248.                     topBezel.setScreenAnchor(horizontal, vertical)
  249.                     bottomBezel.setScreenAnchor(horizontal, vertical)
  250.                     leftBezel.setScreenAnchor(horizontal, vertical)
  251.                     rightBezel.setScreenAnchor(horizontal, vertical)
  252.                 end
  253.                 clickCatcherObject.setScreenAnchor(horizontal, vertical)
  254.                 cursorObject.setScreenAnchor(horizontal, vertical)
  255.                 hasChanged = true
  256.             end
  257.             horizontalAlign, verticalAlign = horizontal, vertical
  258.             return true
  259.         --end
  260.         --return false
  261.     end
  262.    
  263.     glassWindow.getVisible = function()
  264.         return isVisible
  265.     end
  266.     glassWindow.setVisible = function(setVisible)
  267.         if type(setVisible) == "boolean" and isVisible ~= setVisible then
  268.             if isDrawn then
  269.                 local coord
  270.                 for yPos = 1, height do
  271.                     for xPos = 1,width do
  272.                         coord = map[yPos][xPos]
  273.                         coord.textObj.setVisible(setVisible)
  274.                         coord.backObj.setVisible(setVisible)
  275.                     end
  276.                 end
  277.                 if bezelDrawn then
  278.                     topBezel.setVisible(setVisible)
  279.                     bottomBezel.setVisible(setVisible)
  280.                     leftBezel.setVisible(setVisible)
  281.                     rightBezel.setVisible(setVisible)
  282.                 end
  283.                 clickCatcherObject.setVisible(setVisible)
  284.                 cursorObject.setVisible(setVisible and cursorBlink)
  285.                 hasChanged = true
  286.             end
  287.             isVisible = setVisible
  288.             return true
  289.         end
  290.         return false
  291.     end
  292.    
  293.     glassWindow.getOpacity = function()
  294.         return opacity
  295.     end
  296.     glassWindow.setOpacity = function(newOpacity)
  297.         if type(newOpacity) == "number" and newOpacity >= 0 and newOpacity <= 1 then
  298.             if isDrawn then
  299.                 local coord
  300.                 for yPos = 1, height do
  301.                     for xPos = 1,width do
  302.                         coord = map[yPos][xPos]
  303.                         coord.backObj.setOpacity(newOpacity)
  304.                     end
  305.                 end
  306.                 if bezelDrawn then
  307.                     topBezel.setOpacity(newOpacity)
  308.                     bottomBezel.setOpacity(newOpacity)
  309.                     leftBezel.setOpacity(newOpacity)
  310.                     rightBezel.setOpacity(newOpacity)
  311.                 end
  312.                 hasChanged = true
  313.             end
  314.             opacity = newOpacity
  315.             return true
  316.         end
  317.         return false
  318.     end
  319.    
  320.     glassWindow.getSurface = function()
  321.         return surface
  322.     end
  323.     glassWindow.setSurface = function(newSurface, redraw)
  324.         surface = newSurface
  325.         if redraw == true and isDrawn then
  326.             glassWindow.setDrawn(false)
  327.             glassWindow.setDrawn(true)
  328.         end
  329.     end
  330.    
  331.     glassWindow.getOffset = function()
  332.         return xOffset, yOffset, zOffset
  333.     end
  334.     glassWindow.setOffset = function(xOffsetNew, yOffsetNew, zOffsetNew)
  335.         xOffset = math.floor(tonumber(xOffsetNew) or xOffset)
  336.         yOffset = math.floor(tonumber(yOffsetNew) or yOffset)
  337.         zOffset = math.min(250, math.max(1, math.floor(tonumber(zOffsetNew) or zOffset)))
  338.         if isDrawn then
  339.             for yPos, line in ipairs(map) do
  340.                 for xPos, coord in ipairs(line) do
  341.                     coord.textObj.setX((xPos-1)*6 + xOffset + (charOffset[coord.curText] or 0))
  342.                     coord.textObj.setY((yPos-1)*9 + yOffset)
  343.                     coord.textObj.setZ(zOffset + 1)
  344.  
  345.                     coord.backObj.setX((xPos-1)*6 + xOffset)
  346.                     coord.backObj.setY((yPos-1)*9 + yOffset)
  347.                     coord.backObj.setZ(zOffset)
  348.                 end
  349.             end
  350.             clickCatcherObject.setX(xOffset)
  351.             clickCatcherObject.setY(yOffset)
  352.             clickCatcherObject.setZ(zOffset + 3)
  353.             if bezelDrawn then
  354.                 eraseBezel()
  355.                 drawBezel()
  356.             end
  357.             updateCursor()
  358.             hasChanged = true
  359.         end
  360.         return true
  361.     end
  362.    
  363.     glassWindow.getSize = function()
  364.         return width, height
  365.     end
  366.     glassWindow.setSize = function(newWidth, newHeight)
  367.         for yPos = 1, math.max(newHeight, height) do
  368.             if yPos <= newHeight then
  369.                 map[yPos] = map[yPos] or {}
  370.                 for xPos = 1, math.max(newWidth, width) do
  371.                     if xPos <= newWidth then
  372.                         if not map[yPos][xPos] then
  373.                             map[yPos][xPos] = createCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
  374.                         end
  375.                     elseif map[yPos][xPos] then
  376.                         local coord = map[yPos][xPos]
  377.                         if coord.textObj then
  378.                             coord.textObj.delete()
  379.                         end
  380.                         if coord.backObj then
  381.                             coord.backObj.delete()
  382.                         end
  383.                         map[yPos][xPos] = nil
  384.                     end
  385.                 end
  386.             elseif map[yPos] then
  387.                 for xPos = 1, math.max(newWidth, width) do
  388.                     if map[yPos][xPos] then
  389.                         local coord = map[yPos][xPos]
  390.                         if coord.textObj then
  391.                             coord.textObj.delete()
  392.                         end
  393.                         if coord.backObj then
  394.                             coord.backObj.delete()
  395.                         end
  396.                         map[yPos][xPos] = nil
  397.                     end
  398.                 end
  399.                 map[yPos] = nil
  400.             end
  401.         end
  402.         width, height = newWidth, newHeight
  403.         if isDrawn then
  404.             clickCatcherObject.delete()
  405.             drawClickCatcher()
  406.             if bezelDrawn then
  407.                 eraseBezel()
  408.                 drawBezel()
  409.             end
  410.         end
  411.         updateCursor()
  412.         hasChanged = true
  413.     end
  414.    
  415.     glassWindow.getClick = function(objectID, xPos, yPos)
  416.         if objectID == clickCatcherID then
  417.             return math.ceil((xPos+1)/6), math.ceil((yPos+1)/9)
  418.         else
  419.             return false, false
  420.         end
  421.     end
  422.    
  423.     glassWindow.getBezelDrawn = function()
  424.         return bezelDrawn
  425.     end
  426.     glassWindow.setBezelDrawn = function(isBezelDrawn)
  427.         if type(isBezelDrawn) == "boolean" and bezelDrawn ~= isBezelDrawn then
  428.             bezelDrawn = isBezelDrawn
  429.             if isDrawn then
  430.                 if isBezelDrawn then
  431.                     drawBezel()
  432.                 else
  433.                     eraseBezel()
  434.                 end
  435.                 hasChanged = true
  436.             end
  437.             return true
  438.         end
  439.         return false
  440.     end
  441.    
  442.     glassWindow.hasChanged = function()
  443.         return hasChanged
  444.     end
  445.     glassWindow.reset = function()
  446.         hasChanged = false
  447.     end
  448.        
  449.     local newTerm = {
  450.         write = function(text)
  451.             local textType = type(text)
  452.             if textType == "string" or textType == "number" then
  453.                 local text = string.gsub(text, "%c", " ")
  454.                 local length = string.len(text)
  455.                 if length > 0 then
  456.                     if map[cursorY] then
  457.                         for xPos = 1, length do
  458.                             updateCoord(xPos - 1 + cursorX, cursorY, string.sub(text, xPos, xPos), currentTextColour, currentBackgroundColour)
  459.                         end
  460.                     end
  461.                     cursorX = cursorX + length
  462.                     updateCursor()
  463.                 end
  464.             end
  465.         end,
  466.         blit = function(text, textColour, backgroundColour)
  467.             if type(text) ~= "string" or type(textColour) ~= "string" or type(backgroundColour) ~= "string" then
  468.                 error("Expected string, string, string", 2)
  469.             end
  470.             if #text ~= #textColour or #text ~= #backgroundColour then
  471.                 error("Arguments must be the same length", 2)
  472.             end
  473.             local text = string.gsub(text, "%c", " ")
  474.             local length = string.len(text)
  475.             if length > 0 then
  476.                 if map[cursorY] then
  477.                     for xPos = 1, length do
  478.                         updateCoord(xPos - 1 + cursorX, cursorY, string.sub(text, xPos, xPos), hexToColour[string.sub(textColour, xPos, xPos)] or currentTextColour, hexToColour[string.sub(backgroundColour, xPos, xPos)] or currentBackgroundColour)
  479.                     end
  480.                 end
  481.                 cursorX = cursorX + length
  482.                 updateCursor()
  483.             end
  484.         end,
  485.         clear = function()
  486.             for yPos = 1, height do
  487.                 for xPos = 1, width do
  488.                     updateCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
  489.                 end
  490.             end
  491.         end,
  492.         clearLine = function()
  493.             if map[cursorY] then
  494.                 for xPos = 1, width do
  495.                     updateCoord(xPos, cursorY, " ", currentTextColour, currentBackgroundColour)
  496.                 end
  497.             end
  498.         end,
  499.         getCursorPos = function()
  500.             return cursorX, cursorY
  501.         end,
  502.         setCursorPos = function(xPos, yPos)
  503.             cursorX = math.floor(tonumber(xPos) or cursorX)
  504.             cursorY = math.floor(tonumber(yPos) or cursorY)
  505.             updateCursor()
  506.         end,
  507.         setCursorBlink = function(blink)
  508.             if type(blink) == "boolean" then
  509.                 cursorBlink = blink
  510.                 updateCursor()
  511.             end
  512.         end,
  513.         isColour = function()
  514.             return true
  515.         end,
  516.         getSize = function()
  517.             return width, height
  518.         end,
  519.         scroll = function(noOfLines)
  520.             local n = math.floor(tonumber(noOfLines) or 0)
  521.             if n ~= 0 and height > 0 then
  522.                 for yPos = (n > 0 and 1) or height, (n < 0 and 1) or height, n/math.abs(n) do
  523.                     for xPos = 1, width do
  524.                         if map[yPos + n] then
  525.                             local coord = map[yPos + n][xPos].data
  526.                             updateCoord(xPos, yPos, coord.text, coord.textColour, coord.backgroundColour)
  527.                         else
  528.                             updateCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
  529.                         end
  530.                     end
  531.                 end
  532.             end
  533.         end,
  534.         setTextColour = function(colour)
  535.             local newColour = colourToRGB[tonumber(colour)]
  536.             if newColour then
  537.                 currentTextColour = newColour
  538.                 updateCursor()
  539.             end
  540.         end,
  541.         getTextColour = function()
  542.             return rgbToColour[currentTextColour]
  543.         end,
  544.         setBackgroundColour = function(colour)
  545.             local newColour = colourToRGB[tonumber(colour)]
  546.             if newColour then
  547.                 currentBackgroundColour = newColour
  548.             end
  549.         end,
  550.         getBackgroundColour = function()
  551.             return rgbToColour[currentBackgroundColour]
  552.         end,
  553.     }
  554.     newTerm.isColor = newTerm.isColour
  555.     newTerm.setTextColor = newTerm.setTextColour
  556.     newTerm.getTextColor = newTerm.getTextColour
  557.     newTerm.setBackgroundColor = newTerm.setBackgroundColour
  558.     newTerm.getBackgroundColor = newTerm.getBackgroundColour
  559.    
  560.     glassWindow.term = newTerm
  561.    
  562.     glassWindow.setSize(width, height)
  563.    
  564.     return glassWindow
  565. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement