fix dupe and typing issues
This commit is contained in:
293
FlexLove.lua
293
FlexLove.lua
@@ -4,66 +4,9 @@
|
|||||||
---@field g number -- Green component (0-1)
|
---@field g number -- Green component (0-1)
|
||||||
---@field b number -- Blue component (0-1)
|
---@field b number -- Blue component (0-1)
|
||||||
---@field a number -- Alpha component (0-1)
|
---@field a number -- Alpha component (0-1)
|
||||||
---@field toHex fun(self:Color): string -- Converts color to hex string
|
|
||||||
---@field toRGBA fun(self:Color): number, number, number, number -- Returns RGBA components as numbers
|
|
||||||
local Color = {}
|
local Color = {}
|
||||||
Color.__index = Color
|
Color.__index = Color
|
||||||
|
|
||||||
--- Create a new color instance
|
|
||||||
---@param r number -- Red component (0-1)
|
|
||||||
---@param g number -- Green component (0-1)
|
|
||||||
---@param b number -- Blue component (0-1)
|
|
||||||
---@param a number? -- Alpha component (0-1), default 1
|
|
||||||
---@return Color
|
|
||||||
function Color.new(r, g, b, a)
|
|
||||||
local self = setmetatable({}, Color)
|
|
||||||
self.r = r or 0
|
|
||||||
self.g = g or 0
|
|
||||||
self.b = b or 0
|
|
||||||
self.a = a or 1
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Convert hex string to color
|
|
||||||
---@param hex string -- e.g. "#RRGGBB" or "#RRGGBBAA"
|
|
||||||
---@return Color
|
|
||||||
function Color.fromHex(hex)
|
|
||||||
local hex = hex:gsub("#", "")
|
|
||||||
if #hex == 6 then
|
|
||||||
local r = tonumber("0x" .. hex:sub(1, 2))
|
|
||||||
local g = tonumber("0x" .. hex:sub(3, 4))
|
|
||||||
local b = tonumber("0x" .. hex:sub(5, 6))
|
|
||||||
return Color.new(r, g, b, 1)
|
|
||||||
elseif #hex == 8 then
|
|
||||||
local r = tonumber("0x" .. hex:sub(1, 2))
|
|
||||||
local g = tonumber("0x" .. hex:sub(3, 4))
|
|
||||||
local b = tonumber("0x" .. hex:sub(5, 6))
|
|
||||||
local a = tonumber("0x" .. hex:sub(7, 8)) / 255
|
|
||||||
return Color.new(r, g, b, a)
|
|
||||||
else
|
|
||||||
error("Invalid hex string")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Convert color to hex string
|
|
||||||
---@return string -- Hex color string in format "#RRGGBB" or "#RRGGBBAA"
|
|
||||||
function Color:toHex()
|
|
||||||
local r = math.floor(self.r * 255)
|
|
||||||
local g = math.floor(self.g * 255)
|
|
||||||
local b = math.floor(self.b * 255)
|
|
||||||
local a = math.floor(self.a * 255)
|
|
||||||
if self.a ~= 1 then
|
|
||||||
return string.format("#%02X%02X%02X%02X", r, g, b, a)
|
|
||||||
else
|
|
||||||
return string.format("#%02X%02X%02X", r, g, b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return number r, number g, number b, number a
|
|
||||||
function Color:toRGBA()
|
|
||||||
return self.r, self.g, self.b, self.a
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Create a new color instance
|
--- Create a new color instance
|
||||||
---@param r number
|
---@param r number
|
||||||
---@param g number
|
---@param g number
|
||||||
@@ -204,10 +147,10 @@ local Positioning, FlexDirection, JustifyContent, AlignContent, AlignItems, Text
|
|||||||
--- Top level GUI manager
|
--- Top level GUI manager
|
||||||
---@class Gui
|
---@class Gui
|
||||||
---@field topWindows table<integer, Window>
|
---@field topWindows table<integer, Window>
|
||||||
---@field resize fun(): void
|
---@field resize fun(): nil
|
||||||
---@field draw fun(): void
|
---@field draw fun(): nil
|
||||||
---@field update fun(dt:number): void
|
---@field update fun(dt:number): nil
|
||||||
---@field destroy fun(): void
|
---@field destroy fun(): nil
|
||||||
local Gui = { topWindows = {} }
|
local Gui = { topWindows = {} }
|
||||||
|
|
||||||
function Gui.resize()
|
function Gui.resize()
|
||||||
@@ -252,9 +195,6 @@ end
|
|||||||
---@field elapsed number
|
---@field elapsed number
|
||||||
---@field transform table?
|
---@field transform table?
|
||||||
---@field transition table?
|
---@field transition table?
|
||||||
---@field update fun(self:Animation, dt:number): boolean
|
|
||||||
---@field interpolate fun(self:Animation): table
|
|
||||||
---@field apply fun(self:Animation, element:Window|Button): void
|
|
||||||
local Animation = {}
|
local Animation = {}
|
||||||
Animation.__index = Animation
|
Animation.__index = Animation
|
||||||
|
|
||||||
@@ -279,6 +219,8 @@ function Animation.new(props)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param dt number
|
||||||
|
---@return boolean
|
||||||
function Animation:update(dt)
|
function Animation:update(dt)
|
||||||
self.elapsed = self.elapsed + dt
|
self.elapsed = self.elapsed + dt
|
||||||
if self.elapsed >= self.duration then
|
if self.elapsed >= self.duration then
|
||||||
@@ -288,6 +230,7 @@ function Animation:update(dt)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return table
|
||||||
function Animation:interpolate()
|
function Animation:interpolate()
|
||||||
local t = math.min(self.elapsed / self.duration, 1)
|
local t = math.min(self.elapsed / self.duration, 1)
|
||||||
local result = {}
|
local result = {}
|
||||||
@@ -418,16 +361,6 @@ end
|
|||||||
---@field textSize number? -- Font size for text content
|
---@field textSize number? -- Font size for text content
|
||||||
---@field transform table -- Transform properties for animations and styling
|
---@field transform table -- Transform properties for animations and styling
|
||||||
---@field transition table -- Transition settings for animations
|
---@field transition table -- Transition settings for animations
|
||||||
---@field getBounds fun(self:Window): {x:number, y:number, width:number, height:number} -- Returns window bounds
|
|
||||||
---@field addChild fun(self:Window, child:Button|Window): void -- Adds a child to this window
|
|
||||||
---@field layoutChildren fun(self:Window): void -- Layouts all children based on current settings
|
|
||||||
---@field destroy fun(self:Window): void -- Destroys the window and its children
|
|
||||||
---@field draw fun(self:Window): void -- Draws the window and its children
|
|
||||||
---@field update fun(self:Window, dt:number): void -- Updates the window and its children
|
|
||||||
---@field resize fun(self:Window, newGameWidth:number, newGameHeight:number): void -- Resizes the window based on game size change
|
|
||||||
---@field calculateAutoWidth fun(self:Window): void -- Calculates auto width based on children
|
|
||||||
---@field calculateAutoHeight fun(self:Window): void -- Calculates auto height based on children
|
|
||||||
---@field updateAutoSize fun(self:Window): void -- Updates the window size to fit its children automatically
|
|
||||||
local Window = {}
|
local Window = {}
|
||||||
Window.__index = Window
|
Window.__index = Window
|
||||||
|
|
||||||
@@ -456,6 +389,8 @@ Window.__index = Window
|
|||||||
---@field alignContent AlignContent? -- Alignment of lines in multi-line flex containers (default: STRETCH)
|
---@field alignContent AlignContent? -- Alignment of lines in multi-line flex containers (default: STRETCH)
|
||||||
---@field justifySelf JustifySelf? -- Alignment of the item itself along main axis (default: AUTO)
|
---@field justifySelf JustifySelf? -- Alignment of the item itself along main axis (default: AUTO)
|
||||||
---@field alignSelf AlignSelf? -- Alignment of the item itself along cross axis (default: AUTO)
|
---@field alignSelf AlignSelf? -- Alignment of the item itself along cross axis (default: AUTO)
|
||||||
|
---@field transform table? -- Transform properties for animations and styling
|
||||||
|
---@field transition table? -- Transition settings for animations
|
||||||
local WindowProps = {}
|
local WindowProps = {}
|
||||||
|
|
||||||
---@param props WindowProps
|
---@param props WindowProps
|
||||||
@@ -910,10 +845,10 @@ function Window:updateAutoSize()
|
|||||||
-- Store current dimensions for comparison
|
-- Store current dimensions for comparison
|
||||||
local oldWidth, oldHeight = self.width, self.height
|
local oldWidth, oldHeight = self.width, self.height
|
||||||
if self.width == 0 then
|
if self.width == 0 then
|
||||||
self.width = self:calculateAutoWidth()
|
self.width = self:calculateAutoWidth() or 0
|
||||||
end
|
end
|
||||||
if self.height == 0 then
|
if self.height == 0 then
|
||||||
self.height = self:calculateAutoHeight()
|
self.height = self:calculateAutoHeight() or 0
|
||||||
end
|
end
|
||||||
-- Only re-layout children if dimensions changed
|
-- Only re-layout children if dimensions changed
|
||||||
if oldWidth ~= self.width or oldHeight ~= self.height then
|
if oldWidth ~= self.width or oldHeight ~= self.height then
|
||||||
@@ -921,6 +856,103 @@ function Window:updateAutoSize()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Find a child element by name or id (if applicable)
|
||||||
|
---@param name string -- Name or id to search for
|
||||||
|
---@return Button|Window|nil
|
||||||
|
function Window:findChild(name)
|
||||||
|
for _, child in ipairs(self.children) do
|
||||||
|
if child.name == name or child.id == name then
|
||||||
|
return child
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get all children of a specific type
|
||||||
|
---@param type string -- "Button" or "Window"
|
||||||
|
---@return table<integer, Button|Window>
|
||||||
|
function Window:getChildrenOfType(type)
|
||||||
|
local result = {}
|
||||||
|
for _, child in ipairs(self.children) do
|
||||||
|
if getmetatable(child).__name == type then
|
||||||
|
table.insert(result, child)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the visibility of this window and its children
|
||||||
|
---@param visible boolean -- Whether to show or hide the window
|
||||||
|
function Window:setVisible(visible)
|
||||||
|
self.visible = visible
|
||||||
|
for _, child in ipairs(self.children) do
|
||||||
|
if child.setVisible then
|
||||||
|
child:setVisible(visible)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the absolute position of this window relative to screen
|
||||||
|
---@return number x, number y
|
||||||
|
function Window:getAbsolutePosition()
|
||||||
|
local x, y = self.x, self.y
|
||||||
|
local parent = self.parent
|
||||||
|
while parent do
|
||||||
|
x = x + parent.x
|
||||||
|
y = y + parent.y
|
||||||
|
parent = parent.parent
|
||||||
|
end
|
||||||
|
return x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the absolute bounds of this window
|
||||||
|
---@return {x:number, y:number, width:number, height:number}
|
||||||
|
function Window:getAbsoluteBounds()
|
||||||
|
local x, y = self:getAbsolutePosition()
|
||||||
|
return {
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
width = self.width,
|
||||||
|
height = self.height,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the size of this window and all its children proportionally
|
||||||
|
---@param width number -- New width
|
||||||
|
---@param height number -- New height
|
||||||
|
function Window:setSize(width, height)
|
||||||
|
local oldWidth = self.width
|
||||||
|
local oldHeight = self.height
|
||||||
|
if oldWidth > 0 and oldHeight > 0 then
|
||||||
|
local ratioW = width / oldWidth
|
||||||
|
local ratioH = height / oldHeight
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
-- Resize children proportionally
|
||||||
|
for _, child in ipairs(self.children) do
|
||||||
|
if child.resize then
|
||||||
|
child:resize(ratioW, ratioH)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Center this window within its parent or screen
|
||||||
|
---@param parent Window? -- Parent window to center within (optional)
|
||||||
|
function Window:center(parent)
|
||||||
|
local parentWidth, parentHeight = love.window.getMode()
|
||||||
|
if parent then
|
||||||
|
parentWidth = parent.width
|
||||||
|
parentHeight = parent.height
|
||||||
|
end
|
||||||
|
|
||||||
|
self.x = (parentWidth - self.width) / 2
|
||||||
|
self.y = (parentHeight - self.height) / 2
|
||||||
|
end
|
||||||
|
|
||||||
---@class Button
|
---@class Button
|
||||||
---@field x number
|
---@field x number
|
||||||
---@field y number
|
---@field y number
|
||||||
@@ -943,14 +975,6 @@ end
|
|||||||
---@field alignSelf AlignSelf -- default: auto
|
---@field alignSelf AlignSelf -- default: auto
|
||||||
---@field transform table
|
---@field transform table
|
||||||
---@field transition table
|
---@field transition table
|
||||||
---@field bounds fun(self:Button): {x:number, y:number, width:number, height:number}
|
|
||||||
---@field resize fun(self:Button, ratioW?:number, ratioH?:number): void
|
|
||||||
---@field updateText fun(self:Button, newText:string, autoresize?:boolean): void
|
|
||||||
---@field draw fun(self:Button): void
|
|
||||||
---@field calculateTextWidth fun(self:Button): number
|
|
||||||
---@field calculateTextHeight fun(self:Button): number
|
|
||||||
---@field update fun(self:Button, dt:number): void
|
|
||||||
---@field destroy fun(self:Button): void
|
|
||||||
local Button = {}
|
local Button = {}
|
||||||
Button.__index = Button
|
Button.__index = Button
|
||||||
|
|
||||||
@@ -973,6 +997,8 @@ Button.__index = Button
|
|||||||
---@field positioning Positioning? --default: ABSOLUTE (checks parent first)
|
---@field positioning Positioning? --default: ABSOLUTE (checks parent first)
|
||||||
---@field justifySelf JustifySelf? -- default: AUTO
|
---@field justifySelf JustifySelf? -- default: AUTO
|
||||||
---@field alignSelf AlignSelf? -- default: AUTO
|
---@field alignSelf AlignSelf? -- default: AUTO
|
||||||
|
---@field transform table?
|
||||||
|
---@field transition table?
|
||||||
local ButtonProps = {}
|
local ButtonProps = {}
|
||||||
|
|
||||||
---@param props ButtonProps
|
---@param props ButtonProps
|
||||||
@@ -1013,7 +1039,7 @@ function Button.new(props)
|
|||||||
|
|
||||||
self.callback = props.callback or function() end
|
self.callback = props.callback or function() end
|
||||||
self._pressed = false
|
self._pressed = false
|
||||||
self._touchPressed = false
|
self._touchPressed = {}
|
||||||
|
|
||||||
-- Add transform and transition properties
|
-- Add transform and transition properties
|
||||||
self.transform = props.transform or {}
|
self.transform = props.transform or {}
|
||||||
@@ -1203,103 +1229,6 @@ function Button:destroy()
|
|||||||
self._touchPressed = nil
|
self._touchPressed = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Find a child element by name or id (if applicable)
|
|
||||||
---@param name string -- Name or id to search for
|
|
||||||
---@return Button|Window|nil
|
|
||||||
function Window:findChild(name)
|
|
||||||
for _, child in ipairs(self.children) do
|
|
||||||
if child.name == name or child.id == name then
|
|
||||||
return child
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get all children of a specific type
|
|
||||||
---@param type string -- "Button" or "Window"
|
|
||||||
---@return table<integer, Button|Window>
|
|
||||||
function Window:getChildrenOfType(type)
|
|
||||||
local result = {}
|
|
||||||
for _, child in ipairs(self.children) do
|
|
||||||
if getmetatable(child).__name == type then
|
|
||||||
table.insert(result, child)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the visibility of this window and its children
|
|
||||||
---@param visible boolean -- Whether to show or hide the window
|
|
||||||
function Window:setVisible(visible)
|
|
||||||
self.visible = visible
|
|
||||||
for _, child in ipairs(self.children) do
|
|
||||||
if child.setVisible then
|
|
||||||
child:setVisible(visible)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get the absolute position of this window relative to screen
|
|
||||||
---@return number x, number y
|
|
||||||
function Window:getAbsolutePosition()
|
|
||||||
local x, y = self.x, self.y
|
|
||||||
local parent = self.parent
|
|
||||||
while parent do
|
|
||||||
x = x + parent.x
|
|
||||||
y = y + parent.y
|
|
||||||
parent = parent.parent
|
|
||||||
end
|
|
||||||
return x, y
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get the absolute bounds of this window
|
|
||||||
---@return {x:number, y:number, width:number, height:number}
|
|
||||||
function Window:getAbsoluteBounds()
|
|
||||||
local x, y = self:getAbsolutePosition()
|
|
||||||
return {
|
|
||||||
x = x,
|
|
||||||
y = y,
|
|
||||||
width = self.width,
|
|
||||||
height = self.height,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the size of this window and all its children proportionally
|
|
||||||
---@param width number -- New width
|
|
||||||
---@param height number -- New height
|
|
||||||
function Window:setSize(width, height)
|
|
||||||
local oldWidth = self.width
|
|
||||||
local oldHeight = self.height
|
|
||||||
if oldWidth > 0 and oldHeight > 0 then
|
|
||||||
local ratioW = width / oldWidth
|
|
||||||
local ratioH = height / oldHeight
|
|
||||||
self.width = width
|
|
||||||
self.height = height
|
|
||||||
-- Resize children proportionally
|
|
||||||
for _, child in ipairs(self.children) do
|
|
||||||
if child.resize then
|
|
||||||
child:resize(ratioW, ratioH)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self.width = width
|
|
||||||
self.height = height
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Center this window within its parent or screen
|
|
||||||
---@param parent Window? -- Parent window to center within (optional)
|
|
||||||
function Window:center(parent)
|
|
||||||
local parentWidth, parentHeight = love.window.getMode()
|
|
||||||
if parent then
|
|
||||||
parentWidth = parent.width
|
|
||||||
parentHeight = parent.height
|
|
||||||
end
|
|
||||||
|
|
||||||
self.x = (parentWidth - self.width) / 2
|
|
||||||
self.y = (parentHeight - self.height) / 2
|
|
||||||
end
|
|
||||||
|
|
||||||
Gui.Button = Button
|
Gui.Button = Button
|
||||||
Gui.Window = Window
|
Gui.Window = Window
|
||||||
Gui.Animation = Animation
|
Gui.Animation = Animation
|
||||||
|
|||||||
Reference in New Issue
Block a user