local NULL = function() end local function checkColorTableValidation(C) if C then if type(C) == "table" then if #C == 3 or #C == 4 then for _, v in pairs(C) do if type(v) ~= "number" or v<0 or v>1 then return false end end else return false end else return false end end return true end ---@class BUTTON.button ---@field name string ---@field x number ---@field y number ---@field w number ---@field h number ---@field r number # Round corner --- ---@field borderWidth number ---@field borderJoin "bevel"|"miter"|"none" ---@field borderStyle "rough"|"smooth" --- ---@field font love.Font --- ---@field codeWhenPressed function ---@field codeWhenReleased function --- ---@field _hovering? boolean --- ---@field draw function ---@field update function local button = { name = "NEW BUTTON", x = 0, y = 0, w = 1, h = 1, r = 0, backgroundColor = {0,0,0,0}, hoverColor = {1,1,1,0.5}, borderColor = {1,1,1}, textColor = {1,1,1}, font = love.graphics.newFont(15), borderWidth = 1, borderJoin = "none", borderStyle = "smooth", codeWhenPressed = NULL, codeWhenReleased = NULL, _hovering = false }; button.__index = button function button:draw() love.graphics.setLineWidth(self.borderWidth) love.graphics.setLineStyle(self.borderStyle) love.graphics.setLineJoin(self.borderJoin) love.graphics.setColor(self.backgroundColor) love.graphics.rectangle('fill', self.x, self.y, self.w, self.h, self.r) if self._hovering then love.graphics.setColor(self.hoverColor) love.graphics.rectangle('fill', self.x, self.y, self.w, self.h, self.r) end love.graphics.setColor(self.textColor) love.graphics.setFont(self.font) love.graphics.printf(self.name, self.x, self.y + (self.h * 0.25), self.w, "center") love.graphics.setColor(self.borderColor) love.graphics.rectangle('line', self.x, self.y, self.w, self.h, self.r) end function button:isHovering(x,y) if x >= self.x and y >= self.y and x <= self.x + self.w and y <= self.y + self.h then self._hovering = true else self._hovering = false end end ---@param touch? boolean @ If the button is touched, remember to pass true into touch param function button:press(touch) if touch or self._hovering then self.codeWhenPressed() end end ---@param touch? boolean @ If the button is touched, remember to pass true into touch param function button:release(touch) if touch or self._hovering then self.codeWhenReleased() end end local BUTTON = {} ---@param D BUTTON.newData ---Validate the provided data, will be called by ``BUTTON.new`` and ``BUTTON.setDefaultOption``
---***WARNING! THIS FUNCTION WILL RAISE EXCEPTION IF DATA IS INVALID!*** function BUTTON.checkDataValidation(D) assert(type(D.name) == "string", "[name] is missing or not valid") assert(type(D.x) == "number", "[x] must be a integer") assert(type(D.y) == "number", "[y] must be a integer") assert(type(D.w) == "number" and D.w > 0, "[w] must be a positive integer") assert(type(D.h) == "number" and D.h > 0, "[h] must be a positive integer") assert((type(D.r) == "number" and D.r >= 0 and D.r <= D.w * 0.5 and D.r <= D.h * 0.5) or D.r == nil, "[r] must be a positive integer and cannot larger than half of button's width and half of button's height") assert((type(D.borderWidth) == "number" and D.borderWidth > 0) or D.borderWidth == nil, "[borderWidth] must be a postive integer") assert(table.contains({"bevel", "miter", "none"}, D.borderJoin) or D.borderJoin == nil, "[borderJoin] must be 'bevel', 'miter' or 'none") assert(table.contains({"rough", "smooth"}, D.borderStyle) or D.borderStyle == nil, "[borderStyle] must be 'rough' or 'smooth'") assert((D.font and D.font.typeOf and D.font:typeOf("Font")) or D.font == nil, "[font] must be love.Font") assert(checkColorTableValidation(D.backgroundColor), "[backgroundColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") assert(checkColorTableValidation(D.hoverColor), "[hoverColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") assert(checkColorTableValidation(D.borderColor), "[borderColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") assert(checkColorTableValidation(D.textColor), "[textColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") assert(type(D.codeWhenPressed) == "function" or D.codeWhenPressed == nil, "[codeWhenPressed] must be a function or nil") assert(type(D.codeWhenReleased) == "function" or D.codeWhenReleased == nil, "[codeWhenReleased] must be a function or nil") assert(type(D.drawingButtonFunc) == "function" or D.drawingButtonFunc == nil, "[drawingButtonFunc] must be a function or nil") end ---@class BUTTON.newData ---@field name? string # Name of the button, will be used to show ---@field x? number # Position of the button (x, y, w, h) ---@field y? number # Position of the button (x, y, w, h) ---@field w? number # Position of the button (x, y, w, h) ---@field h? number # Position of the button (x, y, w, h) ---@field r? number # Radius corner, cannot larger than half of button's width and half of button's height --- ---@field borderWidth? number|1 # Line width will be used to draw button ---@field borderJoin? "bevel"|"miter"|"none" ---@field borderStyle? "rough"|"smooth" --- ---@field font? love.Font --- ---@field backgroundColor? table<[r,g,b,a]> ---@field textColor? table<[r,g,b,a]> ---@field borderColor? table<[r,g,b,a]> ---@field hoverColor? table<[r,g,b,a]> --- ---@field codeWhenPressed? function| # Code will be execute when pressed ---@field codeWhenReleased? function| # Code will be execute when released ---@field drawingButtonFunc? function| # The function is used to draw text
You can override the default one if you feel the default text drawing function is not suitable for you ---@param D BUTTON.newData ---@return BUTTON.button ---Create a new button, provide you a table with 4 functions inside: draw and update, press and release
---You need to put them into intended callbacks :) function BUTTON.new(D) BUTTON.checkDataValidation(D) return setmetatable({ name = D.name, x = D.x, y = D.y, w = D.w, h = D.h, r = D.r, borderWidth = D.borderWidth, borderJoin = D.borderJoin, borderStyle = D.borderStyle, backgroundColor = D.backgroundColor, hoverColor = D.hoverColor, textColor = D.textColor, borderColor = D.borderColor, codeWhenPressed = D.codeWhenPressed, codeWhenReleased = D.codeWhenReleased, drawingButtonFunc = D.drawingButtonFunc, }, button) end ---@param D BUTTON.newData function BUTTON.setDefaultOption(D) ---@diagnostic disable-next-line: param-type-mismatch BUTTON.checkDataValidation(setmetatable(D, button)) for k, v in pairs(D) do if button[k] ~= nil then button[k] = v else error("There is no "..k.." parameter in BUTTON!") end end end return BUTTON