diff --git a/libs/simple-button.lua b/libs/simple-button.lua
index a5766e6..8b969e2 100644
--- a/libs/simple-button.lua
+++ b/libs/simple-button.lua
@@ -1,51 +1,246 @@
-local defaultFont = love.graphics.newFont(20)
-local function defaultDrawingTextFunc(name, x, y, w, h)
- love.graphics.setFont(defaultFont)
- love.graphics.printf(name, x, y, w, "center")
-end
+local NULL = function () end
-local button = {}; button.__index = button
+---@class BUTTON.button
+---@field name string
+---@field x number
+---@field y number
+---@field w number
+---@field h number
+---
+---@field borderWidth? number
+---@field borderJoin? "bevel"|"milter"|"none"
+---@field borderStyle? "rough"|"smooth"
+---
+---@field font? love.Font
+---
+---@field codeWhenPressed? function
+---@field codeWhenReleased? function
+---@field drawingTextFunc? function
+---
+---@field _hovering? boolean
+---
+---@field draw? function
+---@field update? function
+local button = {
+ name = "NEW BUTTON",
+ x = 0, y = 0, w = 0, h = 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",
+
+ drawingBackgroundFunc = function(self)
+ love.graphics.setLineWidth(self.borderWidth)
+ love.graphics.setLineStyle(self.borderStyle)
+ love.graphics.setLineJoin(self.borderJoin)
+
+ love.graphics.setColor(unpack(self.backgroundColor))
+ love.graphics.rectangle('fill', self.x, self.y, self.w, self.h)
+
+ if self._hovering then
+ love.graphics.setColor(unpack(self.hoverColor))
+ love.graphics.rectangle('fill', self.x, self.y, self.w, self.h)
+ end
+
+ love.graphics.setColor(unpack(self.borderColor))
+ love.graphics.rectangle('line', self.x, self.y, self.w, self.h)
+ end,
+ drawingTextFunc = function(self)
+ love.graphics.setFont(self.font)
+ love.graphics.printf(self.name, self.x, self.y + (self.h * 0.25), self.w, "center")
+ end,
+ codeWhenPressed = NULL,
+ codeWhenReleased = NULL,
+
+ _hovering = false
+}; button.__index = button
function button:draw()
- love.graphics.setColor(1,1,1)
- love.graphics.setLineWidth(self.lineWidth)
- love.graphics.rectangle('line', self.x, self.y, self.w, self.h)
- self.drawingTextFunc(self.name, self.x, self.y, self.w, self.h)
+ self:drawingBackgroundFunc()
+ self:drawingTextFunc()
+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 name string @ Name of the button, will be shown
----@param x number
----@param y number
----@param w number
----@param h number
----@param drawingTextFunc? function
----@param lineWidth? number|1 @ Line width will be used to draw button
-function BUTTON.new(name, x, y, w, h, lineWidth, drawingTextFunc)
- assert(type(name) == "string", "[name] is missing or not valid")
- assert(type(x) == "number" and x > 0, "[x] must be a positive integer")
- assert(type(y) == "number" and y > 0, "[y] must be a positive integer")
- assert(type(w) == "number" and w > 0, "[w] must be a positive integer")
- assert(type(h) == "number" and h > 0, "[h] must be a positive integer")
- assert(type(drawingTextFunc) == "function" or type(drawingTextFunc) == "nil", "[drawingTextFunc] must be a function or nil")
- assert((type(lineWidth) == "number" and lineWidth > 0) or type(drawingTextFunc) == "nil", "[lineWidth] must be a postive integer")
+---@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" and D.x > 0, "[x] must be a positive integer")
+ assert(type(D.y) == "number" and D.y > 0, "[y] must be a positive 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.borderWidth) == "number" and D.borderWidth > 0) or D.drawingTextFunc == nil, "[borderWidth] must be a postive integer")
+ assert(table.contains({"bevel", "milter", "none"}, D.borderJoin) or D.borderJoin == nil, "[borderJoin] must be 'bevel', 'milter' 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")
+
+ local red_flag = false
+ if D.backgroundColor then
+ if type(D.backgroundColor) == "table" then
+ if #D.backgroundColor == 3 or #D.backgroundColor == 4 then
+ for _, v in pairs(D.backgroundColor) do
+ if type(v) ~= "number" or v<0 or v>1 then red_flag = true end
+ end
+ else
+ red_flag = true
+ end
+ else
+ red_flag = true
+ end
+ end
+ if red_flag then error("[backgroundColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") end
+
+ if D.hoverColor then
+ if type(D.hoverColor) == "table" then
+ if #D.hoverColor == 3 or #D.hoverColor == 4 then
+ for _, v in pairs(D.hoverColor) do
+ if type(v) ~= "number" or v<0 or v>1 then red_flag = true end
+ end
+ else
+ red_flag = true
+ end
+ else
+ red_flag = true
+ end
+ end
+ if red_flag then error("[hoverColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") end
+
+ if D.borderColor then
+ if type(D.borderColor) == "table" then
+ if #D.borderColor == 3 or #D.borderColor == 4 then
+ for _, v in pairs(D.borderColor) do
+ if type(v) ~= "number" or v<0 or v>1 then red_flag = true end
+ end
+ else
+ red_flag = true
+ end
+ else
+ red_flag = true
+ end
+ end
+ if red_flag then error("[borderColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") end
+
+ if D.textColor then
+ if type(D.textColor) == "table" then
+ if #D.textColor == 3 or #D.textColor == 4 then
+ for _, v in pairs(D.textColor) do
+ if type(v) ~= "number" or v<0 or v>1 then red_flag = true end
+ end
+ else
+ red_flag = true
+ end
+ else
+ red_flag = true
+ end
+ end
+ if red_flag then error("[textColor] must be a table with r, g, b (, a) values, all of them must be integers between 0 and 1") end
+
+ 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.drawingTextFunc) == "function" or D.drawingTextFunc == nil, "[drawingTextFunc] must be a function or nil")
+end
+
+
+---@class BUTTON.newData
+---@field name string # Name of the button, will be shown
+---@field x number
+---@field y number
+---@field w number
+---@field h number
+---
+---@field borderWidth? number|1 # Line width will be used to draw button
+---@field borderJoin? "bevel"|"milter"|"none"
+---@field borderStyle? "rough"|"smooth"
+---
+---@field font? love.Font
+---
+---@field backgroundColor? table<[r,g,b,a]>
+---@field hoverColor? table<[r,g,b,a]>
+---@field borderColor? table<[r,g,b,a]>
+---@field textColor? table<[r,g,b,a]>
+---
+---@field codeWhenPressed? function|nil # Code will be execute when pressed
+---@field codeWhenReleased? function|nil # Code will be execute when released
+---@field drawingTextFunc? function|defaultDrawingTextFunc
+
+---@param D BUTTON.newData
+---@return BUTTON.button
+---Create a new button, provide you a table with 2 functions inside: draw and update
+---You need to put them into intended callbacks :)
+function BUTTON.new(D)
+ BUTTON.checkDataValidation(D)
return setmetatable({
- name = name,
- x = x,
- y = y,
- w = w,
- h = h,
- drawingTextFunc = drawingTextFunc or defaultDrawingTextFunc,
- lineWidth = lineWidth or 1
+ name = D.name,
+ x = D.x,
+ y = D.y,
+ w = D.w,
+ h = D.h,
+
+ borderWidth = D.borderWidth,
+ borderJoin = D.borderJoin,
+ borderStyle = D.borderStyle,
+
+ backgroundColor = D.backgroundColor,
+ hoverColor = D.hoverColor,
+ borderColor = D.borderColor,
+ textColor = D.textColor,
+
+ codeWhenPressed = D.codeWhenPressed,
+ codeWhenReleased = D.codeWhenReleased,
+ drawingTextFunc = D.drawingTextFunc,
}, button)
end
--- Set the default funciton used to drawing text, will be passed name, x, y, w and h
function BUTTON.setDefaultDrawingTextFunction(f)
assert(type(f) == "function", "[f] must be a function!")
- defaultDrawingTextFunc = f
+ button.drawingTextFunc = f
+end
+
+---@param D BUTTON.newData
+function BUTTON.setDefaultOption(D)
+ BUTTON.checkDataValidation(D)
+ 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
\ No newline at end of file