Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
- --* Menu API *--
- --* https://pastebin.com/feBVkdBU *--
- --* by: GravityCube *--
- --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
- Dependency: GCAPI
- Changelog:
- 1.0.0 First release.
- --]]
- local currentWindow = nil
- local ModificationWindow = {
- draw = function(self)
- self:clearButtonsMap()
- local mon = self.mon
- local max_x, max_y = mon.getSize()
- local data = self.data
- local width = math.floor(max_x*0.6)
- local heigth = 4
- for i, item in pairs(data) do
- if type(item.value) == "table" then
- for i, item2 in pairs(item.value) do
- if width < string.len(tostring(item2.name)) then width = string.len(tostring(item2.name)) end
- heigth = heigth + 1
- end
- else
- if width < string.len(tostring(item.value)) then width = string.len(tostring(item.value)) end
- heigth = heigth + 1
- end
- end
- width = width + 4
- local xi = gcapi.getCenter(max_x, width)
- local yi = gcapi.getCenter(max_y, heigth)
- self.window = windowAPI.newWindow(mon, xi, yi, width, heigth)
- local window = self.window
- window:setBackgroundColor(colors.white)
- window:clear()
- --** Borders
- window:setBackgroundColor(colors.cyan)
- for y=1, heigth do
- if y == 1 or y == heigth then
- window:setCursorPos(1,y)
- for x=1, width do
- window:write(" ")
- end
- end
- end
- for y=1, heigth do
- window:setCursorPos(width,y)
- window:write(" ")
- end
- for y=1, heigth do
- window:setCursorPos(1,y)
- window:write(" ")
- end
- --**Close button
- window:setCursorPos(width-2,1)
- self:newButton(" X ", function() self.active = false end)
- local changeNumber = function(value, rate, minv, maxv)
- local new_value = value + rate
- if (maxv and new_value > maxv) or (minv and new_value < minv) then
- return value
- end
- return new_value
- end
- --**Item data
- for i, item in pairs(data) do
- if type(item.value) == "table" then
- for i, item2 in pairs(item.value) do
- end
- else
- window:setBackgroundColor(colors.white)
- window:setCursorPos(3,i+2)
- if item.type == "counter" then
- window:write(item.name .. ": ")
- self:newButton(" < ", function() item.value = changeNumber(item.value, -item.rate, item.min, item.max) end)
- window:setBackgroundColor(colors.white)
- window:write(" " .. tostring(item.value) .. " ")
- self:newButton(" > ", function() item.value = changeNumber(item.value, item.rate, item.min, item.max) end)
- elseif item.type == "boolean" then
- window:write(item.name .. ": ")
- self:newButton(tostring((item.value and "ON") or "OFF"), function(button)
- item.value = not item.value
- end, (item.value and colors.lime) or colors.red)
- else
- window:write(item.name .. ": " .. tostring(item.value))
- end
- end
- end
- --** Back
- window:setCursorPos(2,heigth)
- self:newButton("Back", function() self.active = false end)
- end,
- displayMessage = function(self, text, background_color, text_color)
- local background_color = background_color or colors.lightGray
- local text_color = text_color or colors.black
- local window = self.window
- local text = " " .. text .. " "
- window:setBackgroundColor(background_color)
- window:setTextColor(text_color)
- window:setCursorPos(gcapi.getCenter(window.width+1, text), gcapi.getCenter(window.heigth+1))
- window:write(text)
- window:setTextColor(colors.black)
- end,
- buttonListener = function (self, tEvent)
- if not self.window then
- return false
- end
- if tEvent[1] == "monitor_touch" or tEvent[1] == "mouse_click" then
- local x = tEvent[3]
- local y = tEvent[4]
- local ix = self.window.init_x + 1
- local iy = self.window.init_y + 1
- --if clic on the window
- if gcapi.numberBetween(x, ix, self.window.width+ix) and gcapi.numberBetween(y, iy, self.window.heigth+iy) then
- local buttonFunc = self.buttons_map[x][y]
- if buttonFunc then
- buttonFunc()
- end
- return true
- end
- end
- return false
- end,
- closeWindow = function(self)
- self.active = false
- if self.close_function then self.close_function() end
- end,
- newButton = function(self, text, func, color)
- local xi, yi = self.window:getCursorPos()
- local width = string.len(text)
- local button = {
- text = text,
- color = color or colors.cyan,
- drawButton = function(text, color)
- self.window:setBackgroundColor(color)
- self.window:setCursorPos(xi + gcapi.getCenter(width, text), yi)
- self.window:write(text)
- end,
- }
- button.drawButton(button.text, button.color)
- for x=xi, width+xi-1 do
- self.buttons_map[x+self.window.init_x][yi+self.window.init_y] = function()
- button.drawButton(button.text, colors.orange)
- sleep(0.15)
- if func then
- return func()
- end
- end
- end
- end,
- clearButtonsMap = function(self)
- local max_x, max_y = self.mon.getSize()
- for x=1, max_x do
- self.buttons_map[x] = {}
- end
- end,
- }
- function createModificationWindow(mon, element)
- local max_x, max_y = mon.getSize()
- local data = element.elements
- local modificationWindow = {
- data = data,
- buttons_map = {},
- active = true,
- close_function = element.close_function
- }
- modificationWindow.mon = mon
- for x=1, max_x do
- modificationWindow.buttons_map[x] = {}
- end
- setmetatable(modificationWindow, {__index = ModificationWindow})
- return modificationWindow
- end
- --------------------------------------
- --> Instance <--
- --------------------------------------
- local default_color = colors.white
- local default_button_color = colors.cyan
- local bars_color = colors.cyan
- local MenuInstance = {
- settings = {
- ["title"] = "Menu",
- ["active"] = true,
- ["bottom_list"] = {
- --[1] ={
- -- ["name"] = nil
- -- ["elements"] = {
- -- --[1] = {["name"] = nil ["action"] = nil}
- -- },
- -- ["action"] = nil --function
- --}
- },
- },
- buttons_map = {},
- size = {["x"] = 0, ["y"] = 0},
- resetButtonsMap = function (self)
- local max_x, max_y = self.mon.getSize()
- for x=1, max_x do
- self.buttons_map[x] = {}
- end
- end,
- createBottomElement = function (self, name, action, elements)
- local settings = self.settings
- local element = {}
- element.name = name or "Null"
- element.action = action
- element.elements = elements
- table.insert(settings.bottom_list, element)
- end,
- draw = function (self)
- self:resetButtonsMap()
- local mon = self.mon
- local max_x, max_y = mon.getSize()
- mon.setBackgroundColor(colors.white)
- mon.clear()
- mon.setTextColor(colors.black)
- mon.setBackgroundColor(bars_color)
- -- ** Bars **
- mon.setCursorPos(1,1)
- mon.write(" ")
- mon.setCursorPos(1,max_y)
- mon.write(" ")
- -- ** Title **
- mon.setCursorPos(gcapi.getCenter(max_x, self.settings.title),1)
- mon.write(self.settings.title)
- local bottom_list = self.settings.bottom_list
- local xo = 0
- for i, element in pairs(bottom_list) do
- mon.setBackgroundColor(element.color or default_button_color)
- mon.setCursorPos(xo,max_y)
- mon.write(" " .. element.name .. " ")
- self:addButton(element.name, xo, max_y, element.action, element.color, element)
- xo = xo + string.len(element.name) + 2
- end
- if self.drawContent then self.drawContent() end
- self:drawPops()
- if currentWindow and currentWindow.active then
- currentWindow:draw()
- end
- end,
- drawPops = function(self)
- local mon = self.mon
- local max_x, max_y = mon.getSize()
- local bottom_list = self.settings.bottom_list
- local xo = 0
- for i, element in pairs(bottom_list) do
- if element.elements and element.active then
- for i2, element0 in pairs(element.elements) do
- mon.setBackgroundColor(element0.color or default_button_color)
- mon.setCursorPos(xo,max_y-i2)
- mon.write(" " .. element0.name .. " ")
- self:addButton(element0.name, xo, max_y-i2, element0.action, element0.color, element0)
- end
- end
- xo = xo + string.len(element.name) + 2
- end
- end,
- disablePopups = function (self)
- for i, element in pairs(self.settings.bottom_list) do
- element.active = false
- end
- end,
- eventListener = function(self, tEvent)
- if tEvent[1] == "monitor_touch" or tEvent[1] == "mouse_click" then
- local max_x, max_y = self.mon.getSize()
- local x = tEvent[3]
- local y = tEvent[4]
- if currentWindow and currentWindow.active and currentWindow:buttonListener(tEvent) then
- self:draw()
- return
- end
- local button = self.buttons_map[x][y]
- if not button then self:disablePopups() return end
- local action_result = true
- if button.action then
- action_result = not (button.action() == false)
- end
- --Change color
- local previous_color = button.color or default_button_color
- local result_color = (action_result and colors.lime) or (action.red)
- local text = " " .. button.name .. " "
- self.mon.setBackgroundColor(result_color)
- self.mon.setCursorPos(button.x, button.y)
- self.mon.write(text)
- sleep(0.1)
- self.mon.setBackgroundColor(previous_color)
- self.mon.setCursorPos(button.x, button.y)
- self.mon.write(text)
- self:draw()
- end
- end,
- addButton = function(self, name, x, y, action, color, element)
- local max_x, max_y = self.mon.getSize()
- local button = {
- ["name"] = name,
- ["action"] = action,
- ["color"] = color,
- ["x"] = x,
- ["y"] = y,
- }
- if element and element.elements then
- if y == max_y then
- button.action = function ()
- if element.action then element.action() end
- local v = not element.active
- self:disablePopups()
- element.active = v
- end
- else
- button.action = function ()
- if element.action then element.action() end
- currentWindow = createModificationWindow(self.mon, element)
- end
- end
- end
- --ADD TO BUTTON LIST
- for c=1, string.len(element.name) + 2 do
- self.buttons_map[c+x][y] = button
- end
- end
- }
- --------------------------------------
- --> Public functions <--
- --------------------------------------
- function create(mon, settings)
- local instance = {}
- instance.mon = mon
- instance.settings = settings
- setmetatable(instance, {__index = MenuInstance})
- instance:draw()
- return instance
- end
Add Comment
Please, Sign In to add comment