blunty666

guiTiles

May 8th, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 42.33 KB | None | 0 0
  1. if not tiles then
  2.     error("this API requires tiles to work")
  3. end
  4.  
  5. --===== UTILS =====--
  6. local function makeMetatable(methodsTable)
  7.     return {
  8.         __index = function(t, k)
  9.             return methodsTable[k] or t.tile[k]
  10.         end,
  11.     }
  12. end
  13.  
  14. local function actualToRelative(object, xPos, yPos)
  15.     local rot = math.rad(-object:GetActualRotation())
  16.     local scale = object:GetTile():GetActualScale()
  17.     return (xPos*math.cos(rot) - yPos*math.sin(rot))/scale, (yPos*math.cos(rot) + xPos*math.sin(rot))/scale
  18. end
  19.  
  20. local function findObject(surfaceHandler, drawableID)
  21.     local drawable = surfaceHandler:GetSurface().getObjectById(drawableID)
  22.     if drawable then
  23.         objectID = drawable.getUserdata()
  24.         if objectID then
  25.             return surfaceHandler:GetObject(objectID)
  26.         end
  27.     end
  28.     return false
  29. end
  30.  
  31. local function isIntegerWithinBounds(value, minVal, maxVal)
  32.     return type(value) == "number" and value % 1 == 0 and value >= minVal and value <= maxVal
  33. end
  34.  
  35. function makeDraggable(mainTile, dragObject)
  36.     local function drag(obj, button, relX, relY, absX, absY)
  37.         mainTile:SetX(mainTile:GetX() + absX)
  38.         mainTile:SetY(mainTile:GetY() + absY)
  39.     end
  40.     dragObject:SetOnDrag(drag)
  41. end
  42.  
  43. --===== FANCY TEXT =====--
  44. do
  45.     local fancyTextMethods = {
  46.         GetTile = function(self)
  47.             return self.tile
  48.         end,
  49.         GetAlpha = function(self)
  50.             return self.main:GetAlpha()
  51.         end,
  52.         SetAlpha = function(self, alpha)
  53.             if tiles.checkProperty.alpha(alpha) then
  54.                 self.main:SetAlpha(alpha)
  55.                 self.shadow:SetAlpha(alpha/3)
  56.                 return true
  57.             end
  58.             return false
  59.         end,
  60.         GetColor = function(self)
  61.             return self.main:GetColor()
  62.         end,
  63.         SetColor = function(self, colour)
  64.             if tiles.checkProperty.colour(colour) then
  65.                 self.main:SetColor(colour)
  66.                 self.shadow:SetColor(colour/3)
  67.                 return true
  68.             end
  69.             return false
  70.         end,
  71.         GetText = function(self)
  72.             return self.main:GetText()
  73.         end,
  74.         SetText = function(self, text)
  75.             if type(text) == "string" or type(text) == "number" then
  76.                 text = tostring(text)
  77.                 self.main:SetText(text)
  78.                 self.shadow:SetText(text)
  79.                 return true
  80.             end
  81.             return false
  82.         end,
  83.     }
  84.     local fancyTextMetatable = makeMetatable(fancyTextMethods)
  85.  
  86.     local function addText(tile, xPos, yPos, zPos, text, colour, alpha)
  87.         local text = tile:AddText(xPos, yPos, text, colour)
  88.         text:SetZ(zPos)
  89.         text:SetAlpha(alpha)
  90.         text:SetClickable(false)
  91.         return text
  92.     end
  93.  
  94.     function addFancyText(tile, xPos, yPos, zPos, text, colour, alpha)
  95.         local subTile = tile:AddSubTile(xPos, yPos, zPos)
  96.         local fancyText = {
  97.             tile = subTile,
  98.             main = addText(subTile, 0, 0, 1, text, colour, alpha),
  99.             shadow = addText(subTile, 1, 1, 0, text, colour/3, alpha/3),
  100.         }
  101.         return setmetatable(fancyText, fancyTextMetatable)
  102.     end
  103. end
  104.  
  105. --===== BUTTON =====--
  106. do
  107.     local buttonToVariable = {
  108.         [0] = "leftClickEnabled",
  109.         [1] = "rightClickEnabled",
  110.         [2] = "middleClickEnabled",
  111.     }
  112.     local function buttonClick(button, clicked)
  113.         button = button:GetUserdata()
  114.         if not button.isPressed and button[buttonToVariable[clicked]] then
  115.             button.main:SetColor(button.activeMainColour)
  116.             button.text:SetColor(button.activeTextColour)
  117.             button.isPressed = true
  118.             if button.onClick then
  119.                 button.onClick(clicked)
  120.             end
  121.         end
  122.     end
  123.     local function buttonRelease(button, clicked)
  124.         button = button:GetUserdata()
  125.         if button.isPressed then
  126.             button.main:SetColor(button.inactiveMainColour)
  127.             button.text:SetColor(button.inactiveTextColour)
  128.             button.isPressed = false
  129.             if button[buttonToVariable[clicked]] and button.onRelease then
  130.                 button.onRelease(clicked)
  131.             end
  132.         end
  133.     end
  134.  
  135.     local buttonMethods = {
  136.         GetTile = function(self)
  137.             return self.tile
  138.         end,
  139.  
  140.         GetIsPressed = function(self)
  141.             return self.isPressed
  142.         end,
  143.         SetIsPressed = function(self, boolean)
  144.             if tiles.checkProperty.boolean(boolean) then
  145.                 if self.isPressed ~= boolean then
  146.                     if self.isPressed then
  147.                         self.main:SetColor(self.inactiveMainColour)
  148.                         self.text:SetColor(self.inactiveTextColour)
  149.                     else
  150.                         self.main:SetColor(self.activeMainColour)
  151.                         self.text:SetColor(self.activeTextColour)
  152.                     end
  153.                     self.isPressed = boolean
  154.                 end
  155.                 return true
  156.             end
  157.             return false
  158.         end,
  159.        
  160.         GetText = function(self)
  161.             return self.text:GetText()
  162.         end,
  163.         SetText = function(self, text)
  164.             if tiles.checkProperty.string(text) then
  165.                 self.text:SetText(text)
  166.                 return true
  167.             end
  168.         end,
  169.  
  170.         GetInactiveMainColour = function(self)
  171.             return self.inactiveMainColour
  172.         end,
  173.         SetInactiveMainColour = function(self, colour)
  174.             if tiles.checkProperty.colour(colour) then
  175.                 self.inactiveMainColour = colour
  176.                 if not self.isPressed then
  177.                     self.main:SetColor(colour)
  178.                 end
  179.                 return true
  180.             end
  181.             return false
  182.         end,
  183.         GetActiveMainColour = function(self)
  184.             return self.activeMainColour
  185.         end,
  186.         SetActiveMainColour = function(self, colour)
  187.             if tiles.checkProperty.colour(colour) then
  188.                 self.activeMainColour = colour
  189.                 if self.isPressed then
  190.                     self.main:SetColor(colour)
  191.                 end
  192.                 return true
  193.             end
  194.             return false
  195.         end,
  196.        
  197.         GetInactiveTextColour = function(self)
  198.             return self.inactiveTextColour
  199.         end,
  200.         SetInactiveTextColour = function(self, colour)
  201.             if tiles.checkProperty.colour(colour) then
  202.                 self.inactiveTextColour = colour
  203.                 if not self.isPressed then
  204.                     self.text:SetColor(colour)
  205.                 end
  206.                 return true
  207.             end
  208.             return false
  209.         end,
  210.         GetActiveTextColour = function(self)
  211.             return self.activeTextColour
  212.         end,
  213.         SetActiveTextColour = function(self, colour)
  214.             if tiles.checkProperty.colour(colour) then
  215.                 self.activeTextColour = colour
  216.                 if self.isPressed then
  217.                     self.text:SetColor(colour)
  218.                 end
  219.                 return true
  220.             end
  221.             return false
  222.         end,
  223.        
  224.         GetLeftClickEnabled = function(self)
  225.             return self.leftClickEnabled
  226.         end,
  227.         SetLeftClickEnabled = function(self, boolean)
  228.             if tiles.checkProperty.boolean(boolean) then
  229.                 self.leftClickEnabled = boolean
  230.                 return true
  231.             end
  232.             return false
  233.         end,
  234.         GetMiddleClickEnabled = function(self)
  235.             return self.middleClickEnabled
  236.         end,
  237.         SetMiddleClickEnabled = function(self, boolean)
  238.             if tiles.checkProperty.boolean(boolean) then
  239.                 self.middleClickEnabled = boolean
  240.                 return true
  241.             end
  242.             return false
  243.         end,
  244.         GetRightClickEnabled = function(self)
  245.             return self.rightClickEnabled
  246.         end,
  247.         SetRightClickEnabled = function(self, boolean)
  248.             if tiles.checkProperty.boolean(boolean) then
  249.                 self.rightClickEnabled = boolean
  250.                 return true
  251.             end
  252.             return false
  253.         end,
  254.        
  255.         GetOnClick = function(self)
  256.             return self.onClick
  257.         end,
  258.         SetOnClick = function(self, func)
  259.             if tiles.checkProperty.functionOrNil(func) then
  260.                 self.onClick = func
  261.                 return true
  262.             end
  263.             return false
  264.         end,
  265.         GetOnRelease = function(self)
  266.             return self.onRelease
  267.         end,
  268.         SetOnRelease = function(self, func)
  269.             if tiles.checkProperty.functionOrNil(func) then
  270.                 self.onRelease = func
  271.                 return true
  272.             end
  273.             return false
  274.         end,
  275.     }
  276.     local buttonMetatable = makeMetatable(buttonMethods)
  277.  
  278.     function addButton(tile, xPos, yPos, zPos, text, inactiveMainColour, inactiveTextColour, activeMainColour, activeTextColour, width, height)
  279.         local buttonTile = tile:AddSubTile(xPos, yPos, zPos)
  280.         local button = {
  281.             tile = buttonTile,
  282.            
  283.             inactiveMainColour = inactiveMainColour,
  284.             activeMainColour = activeMainColour,
  285.            
  286.             inactiveTextColour = inactiveTextColour,
  287.             activeTextColour = activeTextColour,
  288.            
  289.             leftClickEnabled = true,
  290.             middleClickEnabled = true,
  291.             rightClickEnabled = true,
  292.  
  293.             onClick = false,
  294.             onRelease = false,
  295.            
  296.             isPressed = false,
  297.         }
  298.        
  299.         local width = math.max(tiles.getStringWidth(text) + 2, (type(width) == "number" and width) or 0)
  300.         local height = math.max(10, (type(height) == "number" and height) or 0)
  301.        
  302.         local buttonMain = buttonTile:AddBox(0, 0, width, height, button.inactiveMainColour, 1)
  303.         buttonMain:SetOnClick(buttonClick)
  304.         buttonMain:SetOnRelease(buttonRelease)
  305.         buttonMain:SetUserdata(button)
  306.        
  307.         local buttonText = buttonTile:AddText(width/2, height/2, text, button.inactiveTextColour)
  308.         buttonText:SetObjectAnchor("MIDDLE", "MIDDLE")
  309.         buttonText:SetClickable(false)
  310.         buttonText:SetZ(1)
  311.        
  312.         button.main = buttonMain
  313.         button.text = buttonText
  314.        
  315.         return setmetatable(button, buttonMetatable)
  316.     end
  317. end
  318.  
  319. --===== SLIDER =====--
  320. do
  321.     local function sliderClick(object, button, clickX, clickY)
  322.         local slider = object:GetUserdata()
  323.         slider.currX = clickX
  324.         local handleX = math.max(3, math.min(slider.width - 3, clickX))
  325.         slider.handle:SetX(handleX)
  326.         if slider.onChanged then
  327.             slider.onChanged((handleX - 3)/(slider.width - 6))
  328.         end
  329.     end
  330.     local function sliderDrag(object, button, deltaX, deltaY)
  331.         local slider = object:GetUserdata()
  332.         slider.currX = slider.currX + deltaX
  333.         local handleX = math.max(3, math.min(slider.width - 3, slider.currX))
  334.         slider.handle:SetX(handleX)
  335.         if slider.onChanged then
  336.             slider.onChanged((handleX - 3)/(slider.width - 6))
  337.         end
  338.     end
  339.     local function sliderScroll(object, dir, xPos, yPos)
  340.         local slider = object:GetUserdata()
  341.         local handleX = math.max(3, math.min(slider.width - 3, slider.handle:GetX() + dir/math.abs(dir)))
  342.         slider.handle:SetX(handleX)
  343.         if slider.onChanged then
  344.             slider.onChanged((handleX - 3)/(slider.width - 6))
  345.         end
  346.     end
  347.  
  348.     local sliderMethods = {
  349.         GetPercent = function(self)
  350.             return self.percent
  351.         end,
  352.         SetPercent = function(self, percent)
  353.             if tiles.checkProperty.percent(percent) then
  354.                 self.percent = percent
  355.                 local width = self.background:GetWidth()
  356.                 local handleX = math.floor(percent*(width - 6)) + 3
  357.                 self.handle:SetX(handleX)
  358.                 return true
  359.             end
  360.             return false
  361.         end,
  362.  
  363.         GetOnChanged = function(self)
  364.             return self.onChanged
  365.         end,
  366.         SetOnChanged = function(self, func)
  367.             if tiles.checkProperty.functionOrNil(func) then
  368.                 self.onChanged = func
  369.                 return true
  370.             end
  371.             return false
  372.         end,
  373.     }
  374.     local sliderMetatable = makeMetatable(sliderMethods)
  375.  
  376.     function addSlider(tile, xPos, yPos, zPos, width, height)
  377.         local sliderTile = tile:AddSubTile(xPos, yPos, zPos)
  378.         local slider = {
  379.             tile = sliderTile,
  380.             onChanged = false,
  381.             width = width,
  382.             currX = 0,
  383.         }
  384.        
  385.         local background = sliderTile:AddBox(0, 0, width, height, 0xffffff, 1)
  386.         background:SetOnClick(sliderClick)
  387.         background:SetOnDrag(sliderDrag)
  388.         background:SetOnScroll(sliderScroll)
  389.         background:SetUserdata(slider)
  390.        
  391.         local runner = sliderTile:AddLine({x = 3, y = height/2},{x = width - 3, y = height/2}, 0x000000, 1)
  392.         runner:SetWidth(2)
  393.         runner:SetZ(1)
  394.         runner:SetClickable(false)
  395.        
  396.         local handle = sliderTile:AddBox(width - 3, height/2, 3, height - 2, 0x000000, 1)
  397.         handle:SetObjectAnchor("MIDDLE", "MIDDLE")
  398.         handle:SetZ(2)
  399.         handle:SetClickable(false)
  400.        
  401.         slider.runner = runner
  402.         slider.handle = handle
  403.         slider.background = background
  404.        
  405.         return setmetatable(slider, sliderMetatable)
  406.     end
  407. end
  408.  
  409. --===== LIST =====--
  410. do
  411.     local function redrawItemsTile(list, startIndex, noSliderUpdate)
  412.         local maxItems = math.floor(list.height/10)
  413.         local startIndex = math.max(0, math.min(#list.items - maxItems, startIndex))
  414.        
  415.         list.itemsTile:SetY(-(startIndex*10))
  416.         if not noSliderUpdate then
  417.             list.listSlider:SetPercent(1 - (startIndex/(#list.items - maxItems)))
  418.         end
  419.    
  420.         local isVisible
  421.         for index, itemTile in ipairs(list.itemTiles) do
  422.             isVisible = index > startIndex and index <= startIndex + maxItems
  423.             itemTile.tile:SetVisible(isVisible)
  424.             itemTile.tile:SetClickable(isVisible)
  425.         end
  426.        
  427.         list.startIndex = startIndex
  428.     end
  429.  
  430.     local function listTileOnKey(tile, object, keyCode)
  431.         local list = tile:GetUserdata()
  432.         if type(list) == "table" and list.highlighted then
  433.             if keyCode == keys.up then
  434.                 list:SetHighlighted(math.max(1, list.highlighted - 1))
  435.             elseif keyCode == keys.down then
  436.                 list:SetHighlighted(math.min(#list.items, list.highlighted + 1))
  437.             elseif keyCode == keys.enter then
  438.                 list:SetSelected(list.highlighted)
  439.             end
  440.         end
  441.     end
  442.  
  443.     local function itemObjectClick(object)
  444.         local list, index = unpack(object:GetUserdata())
  445.         list:SetHighlighted(index)
  446.     end
  447.  
  448.     local function itemObjectRelease(object)
  449.         local list, index = unpack(object:GetUserdata())
  450.         list:SetSelected(index)
  451.     end
  452.  
  453.     local function itemObjectScroll(object, dir)
  454.         local list = unpack(object:GetUserdata())
  455.         redrawItemsTile(list, list.startIndex - dir/math.abs(dir))
  456.     end
  457.    
  458.     local function updateItemTile(item, itemData, width)
  459.         item.background:SetWidth(width)
  460.         local itemText = itemData
  461.         if tiles.getMaxStringLength(itemText, width - 2, 1) < string.len(itemText) then
  462.             local textLen = tiles.getMaxStringLength(itemText, width - 8, 1)
  463.             itemText = string.sub(itemText, 1, textLen).."..."
  464.         end
  465.         item.text:SetText(itemText)
  466.     end
  467.    
  468.     local function updateItemTiles(list, startIndex, width)
  469.         for i = startIndex, #list.items do
  470.             local item, itemData = list.itemTiles[i], list.items[i][2]
  471.             updateItemTile(item, itemData, width)
  472.         end
  473.     end
  474.    
  475.     local function updateSlider(list, newSize)
  476.         local curSize, maxSize = #list.items, math.floor(list.height/10)
  477.         local widthChanged, itemWidth = false, list.width
  478.         if newSize > maxSize then
  479.             itemWidth = list.width - 10
  480.             if curSize <= maxSize then
  481.                 widthChanged = true
  482.                 -- make slider visible
  483.                 list.listSlider:SetVisible(true)
  484.                 list.listSlider:SetClickable(true)
  485.             end
  486.         else -- newSize <= maxSize
  487.             -- itemWidth = list.width
  488.             if curSize > maxSize then
  489.                 widthChanged = true
  490.                 -- make slider not visible
  491.                 list.listSlider:SetVisible(false)
  492.                 list.listSlider:SetClickable(false)
  493.             end
  494.         end
  495.         return widthChanged, itemWidth
  496.     end
  497.    
  498.     local function newItemTile(list, itemsTile, index, width, itemData)
  499.         local itemTile = itemsTile:AddSubTile(0, (index - 1)*10, 0)
  500.        
  501.         local backgroundColour = ((index % 2) == 0 and 0x4c4c4c) or 0x999999
  502.         local background = itemTile:AddBox(0, 0, width, 10, backgroundColour, 1)
  503.         background:SetOnClick(itemObjectClick)
  504.         background:SetOnRelease(itemObjectRelease)
  505.         background:SetOnScroll(itemObjectScroll)
  506.         background:SetUserdata({list, index})
  507.        
  508.         local itemText = itemData[2]
  509.         if tiles.getMaxStringLength(itemText, width - 2, 1) < string.len(itemText) then
  510.             local textLen = tiles.getMaxStringLength(itemText, width - 8, 1)
  511.             itemText = string.sub(itemText, 1, textLen).."..."
  512.         end
  513.         local text = itemTile:AddText(1, 1, itemText, 0x000000)
  514.         text:SetZ(1)
  515.         text:SetClickable(false)
  516.        
  517.         local item = {
  518.             tile = itemTile,
  519.             background = background,
  520.             text = text,
  521.         }
  522.        
  523.         return item
  524.     end
  525.  
  526.     local listMethods = {
  527.         GetHighlighted = function(self)
  528.             return self.highlighted
  529.         end,
  530.         SetHighlighted = function(self, index)
  531.             if isIntegerWithinBounds(index, 1, #self.items) or index == false then
  532.                 if self.highlighted then -- set color of current highlighted to normal
  533.                     local item = self.itemTiles[self.highlighted]
  534.                     if self.highlighted == self.selected then
  535.                         item.background:SetColor(0x008800)
  536.                     else
  537.                         item.background:SetColor(((self.highlighted % 2) == 0 and 0x4c4c4c) or 0x999999)
  538.                     end
  539.                 end
  540.                
  541.                 -- set color of new highlighted to highlighted color
  542.                 if index then
  543.                     local newItem = self.itemTiles[index]
  544.                     if index == self.selected then
  545.                         newItem.background:SetColor(0x008800)
  546.                     else
  547.                         newItem.background:SetColor(0x00ff00)
  548.                     end
  549.                    
  550.                     -- check if need to scroll
  551.                     local maxItems = math.floor(self.height/10)
  552.                     if index - 1 < self.startIndex then
  553.                         redrawItemsTile(self, index - 1)
  554.                     elseif index - maxItems > self.startIndex then
  555.                         redrawItemsTile(self, index - maxItems)
  556.                     end
  557.                 end
  558.                
  559.                 if not noUpdate and self.onHighlightedChanged then
  560.                     self.onHighlightedChanged(index, index and unpack(self.items[index]))
  561.                 end
  562.                
  563.                 -- update highlighted value
  564.                 self.highlighted = index
  565.                
  566.                 return true
  567.             end
  568.             return false
  569.         end,
  570.        
  571.         GetSelected = function(self)
  572.             return self.selected
  573.         end,
  574.         SetSelected = function(self, index, noUpdate)
  575.             if isIntegerWithinBounds(index, 1, #self.items) or index == false then
  576.                 if self.selected then -- set color of current selected to normal
  577.                     local item = self.itemTiles[self.selected]
  578.                     if self.selected == self.highlighted then
  579.                         item.background:SetColor(0x00ff00)
  580.                     else
  581.                         item.background:SetColor(((self.selected % 2) == 0 and 0x4c4c4c) or 0x999999)
  582.                     end
  583.                 end
  584.                
  585.                 -- set color of new selected to selected color
  586.                 if index then
  587.                     local newItem = self.itemTiles[index]
  588.                     newItem.background:SetColor(0x008800)
  589.                
  590.                     -- check if need to scroll
  591.                     local maxItems = math.floor(self.height/10)
  592.                     if index - 1 < self.startIndex then
  593.                         redrawItemsTile(self, index - 1)
  594.                     elseif index - maxItems > self.startIndex then
  595.                         redrawItemsTile(self, index - maxItems)
  596.                     end
  597.                 end
  598.                
  599.                 if not noUpdate and self.onSelectedChanged then
  600.                     self.onSelectedChanged(index, index and unpack(self.items[index]))
  601.                 end
  602.                
  603.                 -- update selected value
  604.                 self.selected = index
  605.                
  606.                 return true
  607.             end
  608.             return false
  609.         end,
  610.        
  611.         GetOnHighlightedChanged = function(self)
  612.             return self.onHighlightedChanged
  613.         end,
  614.         SetOnHighlightedChanged = function(self, func)
  615.             if tiles.checkProperty.functionOrNil(func) then
  616.                 self.onHighlightedChanged = func
  617.                 return true
  618.             end
  619.             return false
  620.         end,
  621.        
  622.         GetOnSelectedChanged = function(self)
  623.             return self.onSelectedChanged
  624.         end,
  625.         SetOnSelectedChanged = function(self, func)
  626.             if tiles.checkProperty.functionOrNil(func) then
  627.                 self.onSelectedChanged = func
  628.                 return true
  629.             end
  630.             return false
  631.         end,
  632.  
  633.         AddItem = function(self, index, itemData)
  634.             if isIntegerWithinBounds(index, 1, #self.items + 1) then
  635.            
  636.                 local widthChanged, itemWidth = updateSlider(self, #self.items + 1)
  637.  
  638.                 table.insert(self.items, index, itemData)
  639.                 table.insert(self.itemTiles, newItemTile(self, self.itemsTile, #self.itemTiles + 1, itemWidth, {"", ""}))
  640.                
  641.                 updateItemTiles(self, (widthChanged and 1) or index, itemWidth)
  642.                 redrawItemsTile(self, self.startIndex)
  643.                
  644.                 if index == self.highlighted then
  645.                     self:SetHighlighted(self.highlighted + 1)
  646.                 end
  647.                 if index == self.selected then
  648.                     self:SetSelected(self.selected + 1, true)
  649.                 end
  650.                
  651.                 return true
  652.             end
  653.             return false
  654.         end,
  655.         GetItem = function(self, index)
  656.             if isIntegerWithinBounds(index, 1, #self.items) then
  657.                 return self.items[index]
  658.             end
  659.         end,
  660.         SetItem = function(self, index, itemData)
  661.             if isIntegerWithinBounds(index, 1, #self.items) then
  662.                 local _, itemWidth = updateSlider(self, #self.items)
  663.                 self.items[index] = itemData
  664.                 updateItemTile(self.itemTiles[index], itemData[2], itemWidth)
  665.                 return true
  666.             end
  667.             return false
  668.         end,
  669.         RemoveItem = function(self, index)
  670.             if isIntegerWithinBounds(index, 1, #self.items) then
  671.                
  672.                 if index == self.highlighted then
  673.                     self:SetHighlighted(false)
  674.                 end
  675.                 if index == self.selected then
  676.                     self:SetSelected(false)
  677.                 end
  678.            
  679.                 local widthChanged, itemWidth = updateSlider(self, #self.items - 1)
  680.                
  681.                 table.remove(self.items, index)
  682.                 local itemTile = table.remove(self.itemTiles, #self.itemTiles)
  683.                 itemTile.tile:Delete()
  684.                
  685.                 updateItemTiles(self, (widthChanged and 1) or index, itemWidth)
  686.                 redrawItemsTile(self, self.startIndex)
  687.                
  688.                 return true
  689.             end
  690.             return false
  691.         end,
  692.     }
  693.     local listMetatable = makeMetatable(listMethods)
  694.  
  695.     function addList(tile, xPos, yPos, zPos, width, height, onSelectedChanged, items)
  696.         local listTile = tile:AddSubTile(xPos, yPos, zPos)
  697.         local itemsTile = listTile:AddSubTile(0, 0, 0)
  698.         local list = {
  699.             tile = listTile,
  700.             itemsTile = itemsTile,
  701.             onSelectedChanged = onSelectedChanged,
  702.             items = items or {},
  703.             itemTiles = {},
  704.             startIndex = 0,
  705.             selected = false,
  706.             highlighted = false,
  707.             width = width,
  708.             height = height,
  709.         }
  710.         setmetatable(list, listMetatable)
  711.        
  712.         listTile:SetUserdata(list)
  713.         listTile:SetOnKeyDown(listTileOnKey)
  714.  
  715.         local maxItems = math.floor(height/10)
  716.        
  717.         --local listSlider = addSlider(listTile, width, 0, 1, maxItems*10, 10)
  718.         local listSlider = addSlider(listTile, width - 10, height, 1, maxItems*10, 10)
  719.         local function listSliderOnChanged(percent)
  720.             local interval = 1/(#list.items - math.floor(list.height/10))
  721.             local index = (1 - percent)/interval
  722.             index = math.floor(index) + math.floor(2*(index%1))
  723.             redrawItemsTile(list, index, true)
  724.         end
  725.         listSlider:SetOnChanged(listSliderOnChanged)
  726.         listSlider:SetRotation(270)
  727.         listSlider:SetPercent(0)
  728.         list.listSlider = listSlider
  729.        
  730.         local itemWidth = width
  731.         if #items > maxItems then
  732.             itemWidth = itemWidth - 10
  733.         else
  734.             listSlider:SetVisible(false)
  735.             listSlider:SetClickable(false)
  736.         end
  737.         for index, itemData in ipairs(items) do
  738.             local itemTile = newItemTile(list, itemsTile, index, itemWidth, itemData)
  739.             if index > maxItems then
  740.                 itemTile.tile:SetVisible(false)
  741.                 itemTile.tile:SetClickable(false)
  742.             end
  743.             list.itemTiles[index] = itemTile
  744.         end
  745.  
  746.         return list
  747.     end
  748. end
  749.  
  750. --===== TEXT BOX =====--
  751. do
  752.     local function redrawTextBox(textBox)
  753.         local text
  754.         if textBox.mask then
  755.             text = string.rep(textBox.mask, string.len(textBox.currText))
  756.         else
  757.             text = textBox.currText
  758.         end
  759.         if textBox.cursorPos + 1 < textBox.startPos then
  760.             textBox.startPos = textBox.cursorPos + 1
  761.         elseif tiles.getStringWidth(string.sub(text, textBox.startPos, textBox.cursorPos)) > textBox.width - 2 then
  762.             repeat
  763.                 textBox.startPos = textBox.startPos + 1
  764.             until tiles.getStringWidth(string.sub(text, textBox.startPos, textBox.cursorPos)) <= textBox.width - 2
  765.         end
  766.         textBox.cursor:SetX(tiles.getStringWidth(string.sub(text, textBox.startPos, textBox.cursorPos)) + 1)
  767.         textBox.text:SetText(string.sub(text, textBox.startPos, tiles.getMaxStringLength(text, textBox.width - 2, textBox.startPos)))
  768.     end
  769.  
  770.     local function textBoxSelect(background)
  771.         local textBox = background:GetUserdata()
  772.         textBox.cursor:SetVisible(true)
  773.     end
  774.  
  775.     local function textBoxDeselect(background)
  776.         local textBox = background:GetUserdata()
  777.         textBox.cursor:SetVisible(false)
  778.     end
  779.  
  780.     local function textBoxKeyDown(background, keyCode, keyChar, isRepeat)
  781.         local textBox = background:GetUserdata()
  782.         if keyChar then
  783.             textBox.currText = string.sub(textBox.currText, 1, textBox.cursorPos)..keyChar..string.sub(textBox.currText, textBox.cursorPos + 1)
  784.             textBox.cursorPos = textBox.cursorPos + 1
  785.             redrawTextBox(textBox)
  786.         else
  787.             if keyCode == keys.enter then
  788.                 if textBox.onEnter then
  789.                     textBox.onEnter(textBox.currText)
  790.                 end
  791.                 if textBox.resetOnEnter then
  792.                     textBox:SetText("")
  793.                 end
  794.             elseif keyCode == keys.left then
  795.                 textBox.cursorPos = math.max(0, textBox.cursorPos - 1)
  796.                 redrawTextBox(textBox)
  797.             elseif keyCode == keys.right then
  798.                 textBox.cursorPos = math.min(string.len(textBox.currText), textBox.cursorPos + 1)
  799.                 redrawTextBox(textBox)
  800.             elseif keyCode == keys.backspace then
  801.                 if textBox.cursorPos > 0 then
  802.                     textBox.currText = string.sub(textBox.currText, 1, textBox.cursorPos - 1)..string.sub(textBox.currText, textBox.cursorPos + 1)
  803.                     textBox.cursorPos = textBox.cursorPos - 1
  804.                     redrawTextBox(textBox)
  805.                 end
  806.             elseif keyCode == keys.home then
  807.                 textBox.cursorPos = 0
  808.                 redrawTextBox(textBox)
  809.             elseif keyCode == keys.delete then
  810.                 if textBox.cursorPos < string.len(textBox.currText) then
  811.                     textBox.currText = string.sub(textBox.currText, 1, textBox.cursorPos)..string.sub(textBox.currText, textBox.cursorPos + 2)
  812.                     redrawTextBox(textBox)
  813.                 end
  814.             elseif keyCode == keys["end"] then
  815.                 textBox.cursorPos = string.len(textBox.currText)
  816.                 redrawTextBox(textBox)
  817.             end
  818.         end
  819.     end
  820.  
  821.     local function textBoxClick(background, button, xPos)
  822.         if button == 0 then
  823.             local textBox = background:GetUserdata()
  824.             local text
  825.             if textBox.mask then
  826.                 text = string.rep(textBox.mask, string.len(textBox.currText))
  827.             else
  828.                 text = textBox.currText
  829.             end
  830.             for i = textBox.startPos - 1, string.len(text) do
  831.                 local width = tiles.getStringWidth(string.sub(text, textBox.startPos, i))
  832.                 textBox.cursorPos = i
  833.                 if width + 2 > xPos then
  834.                     break
  835.                 end
  836.             end
  837.             textBox.cursor:SetX(tiles.getStringWidth(string.sub(text, textBox.startPos, textBox.cursorPos)) + 1)
  838.         end
  839.     end    
  840.  
  841.     local textBoxMethods = {
  842.         GetMask = function(self)
  843.             return self.mask
  844.         end,
  845.         SetMask = function(self, mask)
  846.             if tiles.checkProperty.string(mask) then
  847.                 self.mask = string.sub(mask, 1, 1)
  848.                 redrawTextBox(self)
  849.                 return true
  850.             elseif mask == nil then
  851.                 self.mask = nil
  852.                 redrawTextBox(self)
  853.                 return true
  854.             end
  855.             return false
  856.         end,
  857.        
  858.         GetText = function(self)
  859.             return self.currText
  860.         end,
  861.         SetText = function(self, text)
  862.             if tiles.checkProperty.string(text) then
  863.                 self.currText = text
  864.                 self.cursorPos = math.min(self.cursorPos, string.len(text))
  865.                 redrawTextBox(self)
  866.                 return true
  867.             end
  868.             return false
  869.         end,
  870.        
  871.         GetResetOnEnter = function(self)
  872.             return self.resetOnEnter
  873.         end,
  874.         SetResetOnEnter = function(self, boolean)
  875.             if tiles.checkProperty.boolean(boolean) then
  876.                 self.resetOnEnter = boolean
  877.                 return true
  878.             end
  879.             return false
  880.         end,
  881.        
  882.         GetWidth = function(self)
  883.             return self.width
  884.         end,
  885.         SetWidth = function(self, width)
  886.             if tiles.checkProperty.positive_number(width) then
  887.                 self.width = width
  888.                 self.background:SetWidth(width)
  889.                 redrawTextBox(self)
  890.                 return true
  891.             end
  892.             return false
  893.         end,
  894.        
  895.         GetOnEnter = function(self)
  896.             return self.onEnter
  897.         end,
  898.         SetOnEnter = function(self, func)
  899.             if tiles.checkProperty.functionOrNil(func) then
  900.                 self.onEnter = func
  901.                 return true
  902.             end
  903.             return false
  904.         end,
  905.     }
  906.     local textBoxMetatable = makeMetatable(textBoxMethods)
  907.  
  908.     function addTextBox(tile, xPos, yPos, zPos, width, onEnter, mask)
  909.         local textBoxTile = tile:AddSubTile(xPos, yPos, zPos)
  910.         local textBox = {
  911.             tile = textBoxTile,
  912.             onEnter = onEnter,
  913.             resetOnEnter = false,
  914.             width = width,
  915.             currText = "",
  916.             cursorPos = 0,
  917.             startPos = 1,
  918.             mask = mask,
  919.         }
  920.        
  921.         local text = textBoxTile:AddText(1, 1, "", 0x000000)
  922.         text:SetZ(1)
  923.         text:SetClickable(false)
  924.        
  925.         local cursor = textBoxTile:AddText(1, 1, "|", 0x000000)
  926.         cursor:SetAlpha(0.5)
  927.         cursor:SetZ(1)
  928.         cursor:SetClickable(false)
  929.         cursor:SetVisible(false)
  930.        
  931.         local background = textBoxTile:AddBox(0, 0, width, 10, 0xffffff, 1)
  932.         background:SetOnSelect(textBoxSelect)
  933.         background:SetOnKeyDown(textBoxKeyDown)
  934.         background:SetOnClick(textBoxClick)
  935.         background:SetOnDeselect(textBoxDeselect)
  936.         background:SetUserdata(textBox)
  937.        
  938.         textBox.text = text
  939.         textBox.cursor = cursor
  940.         textBox.background = background
  941.        
  942.         return setmetatable(textBox, textBoxMetatable)
  943.     end
  944. end
  945.  
  946. --===== ITEM SLOT =====--
  947. do
  948.     local slotWidth = 16
  949.     local function createSlotPoints(xPos, yPos)
  950.         return {
  951.             {x = xPos, y = yPos},
  952.             {x = xPos + slotWidth, y = yPos},
  953.             {x = xPos + slotWidth, y = yPos + slotWidth},
  954.             {x = xPos, y = yPos + slotWidth},
  955.             {x = xPos, y = yPos},
  956.         }
  957.     end
  958.    
  959.     local itemSlotMethods = {
  960.         GetAmount = function(self)
  961.             return self.amount
  962.         end,
  963.         SetAmount = function(self, amount)
  964.             if tiles.checkProperty.positive_number(amount) then
  965.                 self.amount = amount
  966.                 self.icon:SetVisible(true)
  967.                 self.icon:SetLabel((amount ~= 1 and tostring(amount)) or "")
  968.             elseif amount == false then
  969.                 self.amount = amount
  970.                 self.icon:SetVisible(false)
  971.             end
  972.         end,
  973.         GetItemId = function(self)
  974.             return self.icon:GetItemId()
  975.         end,
  976.         SetItemId = function(self, itemId)
  977.             return self.icon:SetItemId(itemId)
  978.         end,
  979.         GetMeta = function(self)
  980.             return self.icon:GetMeta()
  981.         end,
  982.         SetMeta = function(self, meta)
  983.             return self.icon:SetMeta(meta)
  984.         end,
  985.         GetDamageBar = function(self)
  986.             return self.icon:GetDamageBar()
  987.         end,
  988.         SetDamageBar = function(self, damage)
  989.             return self.icon:SetDamageBar(damage)
  990.         end,
  991.     }
  992.     local itemSlotMetatable = makeMetatable(itemSlotMethods)
  993.  
  994.     function addItemSlot(tile, xPos, yPos, zPos)
  995.         local itemSlotTile = tile:AddSubTile(xPos, yPos, zPos)
  996.  
  997.         local itemSlotBackground = itemSlotTile:AddBox(0, 0, slotWidth, slotWidth, 0x999999, 1)
  998.         itemSlotBackground:SetObjectAnchor("MIDDLE", "MIDDLE")
  999.  
  1000.         local itemSlotBorder = itemSlotTile:AddLineList(0x000000, 1, createSlotPoints(0, 0))
  1001.         itemSlotBorder:SetZ(1)
  1002.         itemSlotBorder:SetObjectAnchor("MIDDLE", "MIDDLE")
  1003.         itemSlotBorder:SetClickable(false)
  1004.  
  1005.         local itemSlotIcon = itemSlotTile:AddIcon(0, 0, "minecraft:stone")
  1006.         itemSlotIcon:SetZ(2)
  1007.         itemSlotIcon:SetObjectAnchor("MIDDLE", "MIDDLE")
  1008.         itemSlotIcon:SetVisible(false)
  1009.         itemSlotIcon:SetClickable(false)
  1010.        
  1011.         local itemSlot = {
  1012.             tile = itemSlotTile,
  1013.  
  1014.             amount = false,
  1015.  
  1016.             background = itemSlotBackground,
  1017.             border = itemSlotBorder,
  1018.             icon = itemSlotIcon,
  1019.         }
  1020.  
  1021.         return setmetatable(itemSlot, itemSlotMetatable)
  1022.     end
  1023. end
  1024.  
  1025. --===== BASIC WINDOW =====--
  1026. do
  1027.     local basicWindowMethods = {
  1028.         AddFancyText = addFancyText,
  1029.         AddButton = addButton,
  1030.         AddSlider = addSlider,
  1031.         AddList = addList,
  1032.         AddTextBox = addTextBox,
  1033.         AddItemSlot = addItemSlot,
  1034.  
  1035.         GetBackground = function(self)
  1036.             return self.background
  1037.         end,
  1038.         GetWidth = function(self)
  1039.             return self.width
  1040.         end,
  1041.         SetWidth = function(self, width)
  1042.             self.width = width
  1043.             self.background:SetWidth(self.width)
  1044.             self.border:SetPoints({{x = 0, y = 0}, {x = self.width, y = 0}, {x = self.width, y = self.height}, {x = 0, y = self.height}, {x = 0, y = 0}})
  1045.         end,
  1046.         GetHeight = function(self)
  1047.             return self.height
  1048.         end,
  1049.         SetHeight = function(self, height)
  1050.             self.height = height
  1051.             self.background:SetHeight(self.height)
  1052.             self.border:SetPoints({{x = 0, y = 0}, {x = self.width, y = 0}, {x = self.width, y = self.height}, {x = 0, y = self.height}, {x = 0, y = 0}})
  1053.         end,
  1054.         GetColor = function(self)
  1055.             return self.background:GetColor()
  1056.         end,
  1057.         SetColor = function(self, color)
  1058.             return self.background:SetColor(color)
  1059.         end,
  1060.     }
  1061.     local basicWindowMetatable = makeMetatable(basicWindowMethods)
  1062.  
  1063.     function newBasicWindow(tile, width, height, draggable)
  1064.         local basicWindow = {
  1065.             tile = tile,
  1066.             width = width,
  1067.             height = height,
  1068.             draggable = false,
  1069.             background = tile:AddBox(0, 0, width, height, 0xffffff, 1),
  1070.             border = tile:AddLineList(0x000000, 1, {{x = 0, y = 0}, {x = width, y = 0}, {x = width, y = height}, {x = 0, y = height}, {x = 0, y = 0}})
  1071.         }
  1072.         basicWindow.border:SetZ(1)
  1073.         basicWindow.border:SetClickable(false)
  1074.        
  1075.         setmetatable(basicWindow, basicWindowMetatable)
  1076.        
  1077.         if draggable == true then
  1078.             basicWindow.draggable = true
  1079.             makeDraggable(basicWindow, basicWindow:GetBackground())
  1080.         end
  1081.        
  1082.         return basicWindow
  1083.     end
  1084. end
  1085.  
  1086. --===== BASIC WINDOW HANDLER =====--
  1087. do
  1088.     local function onWindowSelectFunc(window)
  1089.         local handler, windowID = unpack(window:GetUserdata())
  1090.         handler:ToFront(windowID)
  1091.     end
  1092.    
  1093.     local function reorder(basicWindowHandler)
  1094.         for order, windowID in ipairs(basicWindowHandler.orderedList) do
  1095.             local window = basicWindowHandler.list[windowID]
  1096.             if window then
  1097.                 window:SetZ(basicWindowHandler.spacing*order)
  1098.             end
  1099.         end
  1100.     end
  1101.    
  1102.     local basicWindowHandlerMethods = {
  1103.         New = function(self, tile, width, height, draggable)
  1104.             local windowID
  1105.             repeat
  1106.                 windowID = math.random(0, 9999)
  1107.             until not self.list[windowID]
  1108.  
  1109.             local window = newBasicWindow(tile, width, height, draggable)
  1110.  
  1111.             self.list[windowID] = window
  1112.             table.insert(self.orderedList, windowID)
  1113.  
  1114.             window:SetZ(self.spacing*#self.orderedList)
  1115.             window:SetUserdata({self, windowID})
  1116.             window:SetOnSelect(onWindowSelectFunc)
  1117.  
  1118.             return window
  1119.         end,
  1120.         ToFront = function(self, windowID)
  1121.             for order, winID in ipairs(self.orderedList) do
  1122.                 if winID == windowID then
  1123.                     table.insert(self.orderedList, table.remove(self.orderedList, order))
  1124.                     reorder(self)
  1125.                     return true
  1126.                 end
  1127.             end
  1128.             return false
  1129.         end,
  1130.         ToBack = function(self, windowID)
  1131.             for order, winID in ipairs(self.orderedList) do
  1132.                 if winID == windowID then
  1133.                     table.insert(self.orderedList, 1, table.remove(self.orderedList, order))
  1134.                     reorder(self)
  1135.                     return true
  1136.                 end
  1137.             end
  1138.             return false
  1139.         end,
  1140.         Delete = function(self, windowID)
  1141.             local window = self.list[windowID]
  1142.             if window then
  1143.                 window:Delete()
  1144.                 self.list[windowID] = nil
  1145.                 for order, winID in ipairs(self.orderedList) do
  1146.                     if winID == windowID then
  1147.                         table.remove(self.orderedList, order)
  1148.                         reorder(self)
  1149.                         break
  1150.                     end
  1151.                 end
  1152.                 return true
  1153.             end
  1154.             return false
  1155.         end,
  1156.         GetWindow = function(self, windowID)
  1157.             return self.list[windowID]
  1158.         end,
  1159.         GetAllWindows = function(self)
  1160.             local windows = {}
  1161.             for windowID, window in pairs(self.list) do
  1162.                 windows[windowID] = window
  1163.             end
  1164.             return windows
  1165.         end,
  1166.         GetSpacing = function(self)
  1167.             return self.spacing
  1168.         end,
  1169.         SetSpacing = function(self, spacing)
  1170.             if tiles.checkProperty.positive_number(spacing) then
  1171.                 self.spacing = spacing
  1172.                 reorder(self)
  1173.                 return true
  1174.             end
  1175.             return false
  1176.         end,
  1177.     }
  1178.     local basicWindowHandlerMetatable = makeMetatable(basicWindowHandlerMethods)
  1179.  
  1180.     function newBasicWindowHandler()
  1181.         local basicWindowHandler = {
  1182.             spacing = 10,
  1183.             list = {},
  1184.             orderedList = {},
  1185.         }
  1186.         return setmetatable(basicWindowHandler, basicWindowHandlerMetatable)
  1187.     end
  1188. end
  1189.  
  1190. --===== GUI HANDLER =====--
  1191. do
  1192.     local function findChain(object)
  1193.         local chain = {}
  1194.         local tile = object:GetTile()
  1195.         chain[tile:GetID()] = tile
  1196.         while not tile:IsMasterTile() do
  1197.             tile = tile:GetParent()
  1198.             chain[tile:GetID()] = tile
  1199.         end
  1200.         return chain
  1201.     end
  1202.  
  1203.     local function passEventToObject(surfaceHandler, objectID, funcName, ...)
  1204.         local object = findObject(surfaceHandler, objectID)
  1205.         if object then
  1206.             local func = object[funcName](object)
  1207.             if func then
  1208.                 func(object, ...)
  1209.             end
  1210.         end
  1211.     end
  1212.  
  1213.     local function passEventUpChain(surfaceHandler, object, chain, funcName, ...)
  1214.         if not object then error("here", 2) end
  1215.         local func = object[funcName](object)
  1216.         if func then
  1217.             func(object, ...)
  1218.         end
  1219.         for _, tile in pairs(chain) do
  1220.             local selectFunc = tile[funcName](tile)
  1221.             if selectFunc then
  1222.                 selectFunc(tile, object, ...)
  1223.             end
  1224.         end
  1225.     end
  1226.  
  1227.     local surfaceEventHandlers = {
  1228.         --glasses_attach = function(handler, event)
  1229.         --end,
  1230.         glasses_detach = function(handler, event)
  1231.             if handler.lastClickedObjectID then
  1232.                 passEventToObject(handler.surfaceHandler, handler.lastClickedObjectID, "GetOnRelease", handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1233.             end
  1234.             handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = false, false, false, false
  1235.             handler.relativeX, handler.relativeY = false, false
  1236.         end,
  1237.         glasses_capture = function(handler, event)
  1238.             local capture = handler.surfaceHandler:GetCapture()
  1239.             if capture then
  1240.                 capture.setBackground(handler.captureBackground, handler.captureAlpha)
  1241.                 capture.toggleGuiElements(handler.captureGuiElements)
  1242.                 capture.setKeyRepeat(handler.captureKeyRepeat)
  1243.             end
  1244.         end,
  1245.         glasses_release = function(handler, event)
  1246.             if handler.lastClickedObjectID then
  1247.                 passEventToObject(handler.surfaceHandler, handler.lastClickedObjectID, "GetOnRelease", handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1248.             end
  1249.             handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = false, false, false, false
  1250.             handler.relativeX, handler.relativeY = false, false
  1251.         end,
  1252.         --glasses_chat_command = function(handler, event)
  1253.         --end,
  1254.         --glasses_chat_message = function(handler, event)
  1255.         --end,
  1256.         glasses_key_down = function(handler, event)
  1257.             if handler.lastObjectID then
  1258.                 local keyChar = event[6]:gsub("%c", "")
  1259.                 keyChar = (keyChar:len() > 0 and keyChar) or nil
  1260.                 local object = findObject(handler.surfaceHandler, handler.lastObjectID)
  1261.                 if object then
  1262.                     passEventUpChain(handler.surfaceHandler, object, findChain(object), "GetOnKeyDown", event[5], keyChar, event[7])
  1263.                 end
  1264.             end
  1265.         end,
  1266.         glasses_key_up = function(handler, event)
  1267.             if handler.lastObjectID then
  1268.                 local object = findObject(handler.surfaceHandler, handler.lastObjectID)
  1269.                 if object then
  1270.                     passEventUpChain(handler.surfaceHandler, object, findChain(object), "GetOnKeyUp", event[5])
  1271.                 end
  1272.             end
  1273.         end,
  1274.         --glasses_mouse_scroll = function(handler, event)
  1275.         --end,
  1276.         glasses_mouse_down = function(handler, event)
  1277.             if handler.lastObjectID then
  1278.                 local object = findObject(handler.surfaceHandler, handler.lastObjectID)
  1279.                 if object then
  1280.                     passEventUpChain(handler.surfaceHandler, object, findChain(object), "GetOnDeselect")
  1281.                 end
  1282.             end
  1283.             handler.lastObjectID = false
  1284.         end,
  1285.         glasses_mouse_up = function(handler, event)
  1286.             if handler.lastClickedObjectID then
  1287.                 passEventToObject(handler.surfaceHandler, handler.lastClickedObjectID, "GetOnRelease", handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1288.             end
  1289.             handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = false, false, false, false
  1290.             handler.relativeX, handler.relativeY = false, false
  1291.         end,
  1292.         glasses_mouse_drag = function(handler, event)
  1293.             if handler.lastClickedObjectID then
  1294.                 handler.actualX, handler.actualY = handler.actualX + event[5], handler.actualY + event[6]
  1295.                 local object = findObject(handler.surfaceHandler, handler.lastClickedObjectID)
  1296.                 if object then
  1297.                     local deltaX, deltaY = actualToRelative(object, event[5], event[6])
  1298.                     handler.relativeX, handler.relativeY = handler.relativeX + deltaX, handler.relativeY + deltaY
  1299.                     local func = object:GetOnDrag()
  1300.                     if func then
  1301.                         func(object, handler.button, deltaX, deltaY, event[5], event[6])
  1302.                     end
  1303.                 end
  1304.             end
  1305.         end,
  1306.         glasses_component_mouse_wheel = function(handler, event)
  1307.             local object = findObject(handler.surfaceHandler, event[5])
  1308.             if object then
  1309.                 local func = object:GetOnScroll()
  1310.                 if func then
  1311.                     local relX, relY = actualToRelative(object, event[7], event[8])
  1312.                     func(object, event[9], relX, relY, event[7], event[8])
  1313.                 end
  1314.             end
  1315.         end,
  1316.         glasses_component_mouse_down = function(handler, event)
  1317.             if handler.lastClickedObjectID then
  1318.                 passEventToObject(handler.surfaceHandler, handler.lastClickedObjectID, "GetOnRelease", handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1319.             end
  1320.             if not handler.lastObjectID or event[5] ~= handler.lastObjectID then
  1321.                 local newObject = findObject(handler.surfaceHandler, event[5])
  1322.                 local selectedChain = (newObject and findChain(newObject)) or {}
  1323.                 if handler.lastObjectID then
  1324.                     local object = findObject(handler.surfaceHandler, handler.lastObjectID)
  1325.                     if object then
  1326.                         local deselectedChain = findChain(object)
  1327.                         for tileID, _ in pairs(selectedChain) do
  1328.                             deselectedChain[tileID] = nil
  1329.                         end
  1330.                         passEventUpChain(handler.surfaceHandler, object, deselectedChain, "GetOnDeselect")
  1331.                     end
  1332.                 end
  1333.                 handler.lastObjectID = event[5]
  1334.                 if newObject then
  1335.                     passEventUpChain(handler.surfaceHandler, newObject, selectedChain, "GetOnSelect")
  1336.                 end
  1337.             end
  1338.             local object = findObject(handler.surfaceHandler, event[5])
  1339.             if object then
  1340.                 handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = event[5], event[7], event[8], event[9]
  1341.                 handler.lastObjectID = event[5]
  1342.                 local scale = object:GetTile():GetActualScale()
  1343.                 handler.relativeX, handler.relativeY = handler.actualX/scale, handler.actualY/scale
  1344.                 local clickFunc = object:GetOnClick()
  1345.                 if clickFunc then
  1346.                     clickFunc(object, handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1347.                 end
  1348.             else
  1349.                 handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = false, false, false, false
  1350.             end
  1351.         end,
  1352.         glasses_component_mouse_up = function(handler, event)
  1353.             if handler.lastClickedObjectID then
  1354.                 local object = findObject(handler.surfaceHandler, handler.lastClickedObjectID)
  1355.                 if object then
  1356.                     local func = object:GetOnRelease()
  1357.                     if func then
  1358.                         if handler.lastClickedObjectID == event[5] then
  1359.                             handler.actualX, handler.actualY = event[7], event[8]
  1360.                             local scale = object:GetTile():GetActualScale()
  1361.                             handler.relativeX, handler.relativeY = handler.actualX/scale, handler.actualY/scale
  1362.                         end
  1363.                         func(object, handler.button, handler.relativeX, handler.relativeY, handler.actualX, handler.actualY)
  1364.                     end
  1365.                 end
  1366.             end
  1367.             handler.lastClickedObjectID, handler.actualX, handler.actualY, handler.button = false, false, false, false
  1368.             handler.relativeX, handler.relativeY = false, false
  1369.         end,
  1370.     }
  1371.  
  1372.     local guiHandlerMethods = {
  1373.         GetCaptureBackground = function(self)
  1374.             return self.captureBackground
  1375.         end,
  1376.         SetCaptureBackground = function(self, colour)
  1377.             if tiles.checkProperty.colour(colour) then
  1378.                 self.captureBackground = colour
  1379.                 local capture = self.surfaceHandler:GetCapture()
  1380.                 if capture then
  1381.                     capture.setBackground(self.captureBackground, self.captureAlpha)
  1382.                 end
  1383.                 return true
  1384.             end
  1385.             return false
  1386.         end,
  1387.         GetCaptureAlpha = function(self)
  1388.             return self.captureAlpha
  1389.         end,
  1390.         SetCaptureAlpha = function(self, alpha)
  1391.             if tiles.checkProperty.alpha(alpha) then
  1392.                 self.captureAlpha = alpha
  1393.                 local capture = self.surfaceHandler:GetCapture()
  1394.                 if capture then
  1395.                     capture.setBackground(self.captureBackground, self.captureAlpha)
  1396.                 end
  1397.                 return true
  1398.             end
  1399.             return false
  1400.         end,
  1401.        
  1402.         HandleEvent = function(self, event)
  1403.             if type(event) == "table" then
  1404.                 local eventType = event[1]
  1405.                 local handler = surfaceEventHandlers[eventType]
  1406.                 if handler then
  1407.                     handler(self, event)
  1408.                     return true
  1409.                 end
  1410.             end
  1411.             return false
  1412.         end,
  1413.     }
  1414.     local guiHandlerMetatable = {__index = guiHandlerMethods}
  1415.  
  1416.     function newGuiHandler(surfaceHandler)
  1417.         local guiHandler = {
  1418.             surfaceHandler = surfaceHandler,
  1419.            
  1420.             captureBackground = 0xffffff,
  1421.             captureAlpha = 0,
  1422.             captureGuiElements = {},
  1423.             captureKeyRepeat = true,
  1424.            
  1425.             lastClickedObjectID = false,
  1426.             lastObjectID = false,
  1427.             button = false,
  1428.             actualX = false,
  1429.             actualY = false,
  1430.             relativeX = false,
  1431.             relativeY = false,
  1432.         }
  1433.         for i = 2, 13 do
  1434.             guiHandler.captureGuiElements[i] = false
  1435.         end
  1436.         setmetatable(guiHandler, guiHandlerMetatable)
  1437.         return guiHandler
  1438.     end
  1439. end
Add Comment
Please, Sign In to add comment