GravityCube

MenuAPI

Oct 26th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.55 KB | None | 0 0
  1. --[[
  2.    
  3.             --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
  4.             --*               Menu API                  *--
  5.             --*     https://pastebin.com/feBVkdBU       *--
  6.             --*           by: GravityCube               *--
  7.             --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
  8.  
  9.     Dependency: GCAPI
  10.            
  11.     Changelog:
  12.         1.0.0 First release.
  13. --]]
  14. local currentWindow = nil
  15.  
  16. local ModificationWindow = {
  17.    
  18.     draw = function(self)
  19.         self:clearButtonsMap()
  20.        
  21.         local mon = self.mon
  22.         local max_x, max_y = mon.getSize()
  23.        
  24.         local data = self.data
  25.        
  26.         local width = math.floor(max_x*0.6)
  27.         local heigth = 4
  28.        
  29.         for i, item in pairs(data) do
  30.             if type(item.value) == "table" then
  31.                 for i, item2 in pairs(item.value) do
  32.                     if width < string.len(tostring(item2.name)) then width = string.len(tostring(item2.name)) end
  33.                     heigth = heigth + 1
  34.                 end    
  35.             else
  36.                 if width < string.len(tostring(item.value)) then width = string.len(tostring(item.value)) end
  37.                 heigth = heigth + 1
  38.             end
  39.         end
  40.        
  41.         width = width + 4
  42.        
  43.         local xi = gcapi.getCenter(max_x, width)
  44.         local yi = gcapi.getCenter(max_y, heigth)
  45.        
  46.         self.window = windowAPI.newWindow(mon, xi, yi, width, heigth)
  47.         local window = self.window
  48.        
  49.         window:setBackgroundColor(colors.white)
  50.         window:clear()
  51.        
  52.         --** Borders
  53.         window:setBackgroundColor(colors.cyan)
  54.         for y=1, heigth do
  55.             if y == 1 or y == heigth then
  56.                 window:setCursorPos(1,y)
  57.                 for x=1, width do
  58.                     window:write(" ")
  59.                 end
  60.             end
  61.         end
  62.        
  63.         for y=1, heigth do
  64.             window:setCursorPos(width,y)
  65.             window:write(" ")
  66.         end
  67.        
  68.         for y=1, heigth do
  69.             window:setCursorPos(1,y)
  70.             window:write(" ")
  71.         end
  72.        
  73.         --**Close button
  74.         window:setCursorPos(width-2,1)
  75.         self:newButton(" X ", function() self.active = false end)
  76.        
  77.        
  78.         local changeNumber = function(value, rate, minv, maxv)
  79.             local new_value = value + rate
  80.             if (maxv and new_value > maxv) or (minv and new_value < minv) then
  81.                 return value
  82.             end
  83.             return new_value
  84.         end
  85.        
  86.         --**Item data
  87.         for i, item in pairs(data) do
  88.             if type(item.value) == "table" then
  89.                 for i, item2 in pairs(item.value) do
  90.                 end
  91.             else
  92.                 window:setBackgroundColor(colors.white)
  93.                 window:setCursorPos(3,i+2)
  94.                 if item.type == "counter" then
  95.                     window:write(item.name .. ": ")
  96.                     self:newButton(" < ", function() item.value = changeNumber(item.value, -item.rate, item.min, item.max) end)
  97.                     window:setBackgroundColor(colors.white)
  98.                     window:write(" " .. tostring(item.value) .. " ")
  99.                     self:newButton(" > ", function() item.value = changeNumber(item.value, item.rate, item.min, item.max) end)
  100.                 elseif item.type == "boolean" then
  101.                     window:write(item.name .. ": ")
  102.                     self:newButton(tostring((item.value and "ON") or "OFF"), function(button)
  103.                         item.value = not item.value
  104.                     end, (item.value and colors.lime) or colors.red)
  105.                 else
  106.                     window:write(item.name .. ": " .. tostring(item.value))
  107.                 end
  108.             end
  109.         end
  110.         --** Back
  111.         window:setCursorPos(2,heigth)
  112.         self:newButton("Back", function() self.active = false end)
  113.        
  114.     end,
  115.    
  116.     displayMessage = function(self, text, background_color, text_color)
  117.         local background_color = background_color or colors.lightGray
  118.         local text_color = text_color or colors.black
  119.         local window = self.window
  120.         local text = " " .. text .. " "
  121.        
  122.         window:setBackgroundColor(background_color)
  123.         window:setTextColor(text_color)
  124.         window:setCursorPos(gcapi.getCenter(window.width+1, text), gcapi.getCenter(window.heigth+1))
  125.         window:write(text)
  126.         window:setTextColor(colors.black)
  127.     end,
  128.     buttonListener = function (self, tEvent)
  129.         if not self.window then
  130.             return false
  131.         end
  132.         if tEvent[1] == "monitor_touch" or tEvent[1] == "mouse_click" then
  133.             local x = tEvent[3]
  134.             local y = tEvent[4]
  135.            
  136.             local ix = self.window.init_x + 1
  137.             local iy = self.window.init_y + 1
  138.            
  139.             --if clic on the window
  140.             if gcapi.numberBetween(x, ix, self.window.width+ix) and gcapi.numberBetween(y, iy, self.window.heigth+iy) then
  141.                 local buttonFunc = self.buttons_map[x][y]
  142.                 if buttonFunc then
  143.                     buttonFunc()
  144.                 end
  145.                 return true
  146.             end
  147.         end
  148.         return false
  149.     end,
  150.    
  151.     closeWindow = function(self)
  152.         self.active = false
  153.         if self.close_function then self.close_function() end
  154.     end,
  155.    
  156.     newButton = function(self, text, func, color)
  157.         local xi, yi = self.window:getCursorPos()
  158.         local width = string.len(text)
  159.        
  160.         local button = {
  161.             text = text,
  162.             color = color or colors.cyan,
  163.             drawButton = function(text, color)
  164.                 self.window:setBackgroundColor(color)
  165.                 self.window:setCursorPos(xi + gcapi.getCenter(width, text), yi)
  166.                 self.window:write(text)
  167.             end,
  168.            
  169.         }
  170.         button.drawButton(button.text, button.color)
  171.         for x=xi, width+xi-1 do
  172.             self.buttons_map[x+self.window.init_x][yi+self.window.init_y] = function()
  173.                 button.drawButton(button.text, colors.orange)
  174.                 sleep(0.15)
  175.                 if func then
  176.                     return func()
  177.                 end
  178.             end
  179.         end
  180.     end,
  181.    
  182.     clearButtonsMap = function(self)
  183.         local max_x, max_y = self.mon.getSize()
  184.         for x=1, max_x do
  185.             self.buttons_map[x] = {}
  186.         end
  187.     end,
  188. }
  189.  
  190. function createModificationWindow(mon, element)
  191.     local max_x, max_y = mon.getSize()
  192.    
  193.     local data = element.elements
  194.    
  195.     local modificationWindow = {
  196.         data = data,
  197.         buttons_map = {},
  198.         active = true,
  199.         close_function = element.close_function
  200.     }
  201.     modificationWindow.mon = mon
  202.     for x=1, max_x do
  203.         modificationWindow.buttons_map[x] = {}
  204.     end
  205.     setmetatable(modificationWindow, {__index = ModificationWindow})
  206.     return modificationWindow
  207. end
  208. --------------------------------------
  209. -->             Instance           <--
  210. --------------------------------------
  211. local default_color = colors.white
  212. local default_button_color = colors.cyan
  213. local bars_color = colors.cyan
  214.  
  215. local MenuInstance = {
  216.     settings = {
  217.         ["title"] = "Menu",
  218.         ["active"] = true,
  219.         ["bottom_list"] = {
  220.             --[1] ={
  221.             --  ["name"] = nil
  222.             --  ["elements"] = {
  223.             --      --[1] = {["name"] = nil ["action"] = nil}
  224.             --  },
  225.             --  ["action"] = nil --function
  226.             --}
  227.         },
  228.     },
  229.     buttons_map = {},
  230.     size = {["x"] = 0, ["y"] = 0},
  231.    
  232.     resetButtonsMap = function (self)
  233.         local max_x, max_y = self.mon.getSize()
  234.         for x=1, max_x do
  235.             self.buttons_map[x] = {}
  236.         end
  237.     end,
  238.    
  239.     createBottomElement = function (self, name, action, elements)
  240.         local settings = self.settings
  241.        
  242.         local element = {}
  243.         element.name = name or "Null"
  244.         element.action = action
  245.         element.elements = elements
  246.        
  247.         table.insert(settings.bottom_list, element)
  248.     end,
  249.    
  250.     draw = function (self)
  251.         self:resetButtonsMap()
  252.         local mon = self.mon
  253.         local max_x, max_y = mon.getSize()
  254.        
  255.         mon.setBackgroundColor(colors.white)
  256.         mon.clear()
  257.         mon.setTextColor(colors.black)
  258.         mon.setBackgroundColor(bars_color)
  259.        
  260.         -- ** Bars **
  261.         mon.setCursorPos(1,1)
  262.         mon.write("                                                                                                 ")
  263.         mon.setCursorPos(1,max_y)
  264.         mon.write("                                                                                                 ")
  265.         -- ** Title **
  266.         mon.setCursorPos(gcapi.getCenter(max_x, self.settings.title),1)
  267.         mon.write(self.settings.title)
  268.        
  269.         local bottom_list = self.settings.bottom_list
  270.         local xo = 0
  271.         for i, element in pairs(bottom_list) do
  272.            
  273.             mon.setBackgroundColor(element.color or default_button_color)
  274.             mon.setCursorPos(xo,max_y)
  275.             mon.write(" " .. element.name .. " ")
  276.            
  277.             self:addButton(element.name, xo, max_y, element.action, element.color, element)
  278.            
  279.             xo = xo + string.len(element.name) + 2
  280.         end
  281.        
  282.         if self.drawContent then self.drawContent() end
  283.        
  284.         self:drawPops()
  285.         if currentWindow and currentWindow.active then
  286.             currentWindow:draw()
  287.         end
  288.     end,
  289.    
  290.     drawPops = function(self)
  291.         local mon = self.mon
  292.         local max_x, max_y = mon.getSize()
  293.        
  294.         local bottom_list = self.settings.bottom_list
  295.         local xo = 0
  296.         for i, element in pairs(bottom_list) do
  297.             if element.elements and element.active then
  298.                 for i2, element0 in pairs(element.elements) do
  299.                     mon.setBackgroundColor(element0.color or default_button_color)
  300.                     mon.setCursorPos(xo,max_y-i2)
  301.                     mon.write(" " .. element0.name .. " ")
  302.                    
  303.                     self:addButton(element0.name, xo, max_y-i2, element0.action, element0.color, element0)
  304.                 end
  305.             end
  306.             xo = xo + string.len(element.name) + 2
  307.         end
  308.     end,
  309.     disablePopups = function (self)
  310.         for i, element in pairs(self.settings.bottom_list) do
  311.             element.active = false
  312.         end
  313.     end,
  314.     eventListener = function(self, tEvent)
  315.         if tEvent[1] == "monitor_touch" or tEvent[1] == "mouse_click" then
  316.             local max_x, max_y = self.mon.getSize()
  317.        
  318.             local x = tEvent[3]
  319.             local y = tEvent[4]
  320.            
  321.             if currentWindow and currentWindow.active and currentWindow:buttonListener(tEvent) then
  322.                 self:draw()
  323.                 return
  324.             end
  325.            
  326.             local button = self.buttons_map[x][y]
  327.             if not button then self:disablePopups() return end
  328.            
  329.             local action_result = true
  330.             if button.action then
  331.                 action_result = not (button.action() == false)
  332.             end
  333.            
  334.             --Change color
  335.             local previous_color = button.color or default_button_color
  336.             local result_color = (action_result and colors.lime) or (action.red)
  337.             local text = " " .. button.name .. " "
  338.             self.mon.setBackgroundColor(result_color)
  339.             self.mon.setCursorPos(button.x, button.y)
  340.             self.mon.write(text)
  341.             sleep(0.1)
  342.            
  343.             self.mon.setBackgroundColor(previous_color)
  344.             self.mon.setCursorPos(button.x, button.y)
  345.             self.mon.write(text)
  346.            
  347.             self:draw()
  348.         end
  349.     end,
  350.    
  351.     addButton = function(self, name, x, y, action, color, element)
  352.         local max_x, max_y = self.mon.getSize()
  353.         local button = {
  354.             ["name"] = name,
  355.             ["action"] = action,
  356.             ["color"] = color,
  357.             ["x"] = x,
  358.             ["y"] = y,
  359.         }
  360.        
  361.         if element and element.elements then
  362.             if y == max_y then
  363.                 button.action = function ()
  364.                     if element.action then element.action() end
  365.                     local v = not element.active
  366.                     self:disablePopups()
  367.                     element.active = v
  368.                 end
  369.             else
  370.                 button.action = function ()
  371.                     if element.action then element.action() end
  372.                     currentWindow = createModificationWindow(self.mon, element)
  373.                 end
  374.             end
  375.         end
  376.        
  377.         --ADD TO BUTTON LIST
  378.         for c=1, string.len(element.name) + 2 do
  379.             self.buttons_map[c+x][y] = button
  380.         end
  381.     end
  382.    
  383. }
  384.  
  385. --------------------------------------
  386. -->         Public functions       <--
  387. --------------------------------------
  388. function create(mon, settings)
  389.     local instance = {}
  390.     instance.mon = mon
  391.     instance.settings = settings
  392.    
  393.     setmetatable(instance, {__index = MenuInstance})
  394.     instance:draw()
  395.     return instance
  396. end
Add Comment
Please, Sign In to add comment