removing unnecessary methods and comments
This commit is contained in:
@@ -35,37 +35,28 @@ function EventHandler.new(config, deps)
|
||||
|
||||
local self = setmetatable({}, EventHandler)
|
||||
|
||||
-- Store dependencies
|
||||
self._InputEvent = deps.InputEvent
|
||||
self._GuiState = deps.GuiState
|
||||
|
||||
-- Event callback
|
||||
self.onEvent = config.onEvent
|
||||
|
||||
-- Mouse button state tracking {button -> boolean}
|
||||
self._pressed = config._pressed or {}
|
||||
|
||||
-- Click detection state
|
||||
self._lastClickTime = config._lastClickTime
|
||||
self._lastClickButton = config._lastClickButton
|
||||
self._clickCount = config._clickCount or 0
|
||||
|
||||
-- Drag tracking per button {button -> position}
|
||||
self._dragStartX = config._dragStartX or {}
|
||||
self._dragStartY = config._dragStartY or {}
|
||||
self._lastMouseX = config._lastMouseX or {}
|
||||
self._lastMouseY = config._lastMouseY or {}
|
||||
|
||||
-- Touch state tracking {touchId -> boolean}
|
||||
self._touchPressed = config._touchPressed or {}
|
||||
|
||||
-- Hover state
|
||||
self._hovered = config._hovered or false
|
||||
|
||||
-- Reference to parent element (set via initialize)
|
||||
self._element = nil
|
||||
|
||||
-- Scrollbar press tracking flag
|
||||
self._scrollbarPressHandled = false
|
||||
|
||||
return self
|
||||
|
||||
@@ -57,7 +57,6 @@ function Grid.layoutGridItems(element)
|
||||
local cellWidth = (availableWidth - totalColumnGaps) / columns
|
||||
local cellHeight = (availableHeight - totalRowGaps) / rows
|
||||
|
||||
-- Get children that participate in grid layout
|
||||
local gridChildren = {}
|
||||
for _, child in ipairs(element.children) do
|
||||
if not (child.positioning == Positioning.ABSOLUTE and child._explicitlyAbsolute) then
|
||||
@@ -65,14 +64,12 @@ function Grid.layoutGridItems(element)
|
||||
end
|
||||
end
|
||||
|
||||
-- Place children in grid cells
|
||||
for i, child in ipairs(gridChildren) do
|
||||
-- Calculate row and column (0-indexed for calculation)
|
||||
local index = i - 1
|
||||
local col = index % columns
|
||||
local row = math.floor(index / columns)
|
||||
|
||||
-- Skip if we've exceeded the grid
|
||||
if row >= rows then
|
||||
break
|
||||
end
|
||||
@@ -84,7 +81,6 @@ function Grid.layoutGridItems(element)
|
||||
-- Apply alignment within grid cell (default to stretch)
|
||||
local effectiveAlignItems = element.alignItems or AlignItems.STRETCH
|
||||
|
||||
-- Stretch child to fill cell by default
|
||||
-- BORDER-BOX MODEL: Set border-box dimensions, content area adjusts automatically
|
||||
if effectiveAlignItems == AlignItems.STRETCH or effectiveAlignItems == "stretch" then
|
||||
child.x = cellX
|
||||
@@ -110,7 +106,6 @@ function Grid.layoutGridItems(element)
|
||||
child.x = cellX + cellWidth - childBorderBoxWidth
|
||||
child.y = cellY + cellHeight - childBorderBoxHeight
|
||||
else
|
||||
-- Default to stretch
|
||||
child.x = cellX
|
||||
child.y = cellY
|
||||
child._borderBoxWidth = cellWidth
|
||||
@@ -122,7 +117,6 @@ function Grid.layoutGridItems(element)
|
||||
child.autosizing.height = false
|
||||
end
|
||||
|
||||
-- Layout child's children if it has any
|
||||
if #child.children > 0 then
|
||||
child:layoutChildren()
|
||||
end
|
||||
|
||||
@@ -46,7 +46,6 @@ function GuiState.registerElement(element)
|
||||
return
|
||||
end
|
||||
|
||||
-- Add element to the z-index ordered list
|
||||
table.insert(GuiState._zIndexOrderedElements, element)
|
||||
end
|
||||
|
||||
@@ -81,7 +80,6 @@ end
|
||||
---@param y number Screen Y coordinate
|
||||
---@return boolean True if point is inside element bounds
|
||||
local function isPointInElement(element, x, y)
|
||||
-- Get element bounds
|
||||
local bx = element.x
|
||||
local by = element.y
|
||||
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
||||
@@ -95,7 +93,6 @@ local function isPointInElement(element, x, y)
|
||||
|
||||
-- Check if parent clips content (overflow: hidden, scroll, auto)
|
||||
if overflowX == "hidden" or overflowX == "scroll" or overflowX == "auto" or overflowY == "hidden" or overflowY == "scroll" or overflowY == "auto" then
|
||||
-- Check if point is outside parent's clipping region
|
||||
local parentX = current.x + current.padding.left
|
||||
local parentY = current.y + current.padding.top
|
||||
local parentW = current.width
|
||||
@@ -109,7 +106,6 @@ local function isPointInElement(element, x, y)
|
||||
current = current.parent
|
||||
end
|
||||
|
||||
-- Check if point is inside element bounds
|
||||
return x >= bx and x <= bx + bw and y >= by and y <= by + bh
|
||||
end
|
||||
|
||||
@@ -139,14 +135,11 @@ function GuiState.getTopElementAt(x, y)
|
||||
for i = #GuiState._zIndexOrderedElements, 1, -1 do
|
||||
local element = GuiState._zIndexOrderedElements[i]
|
||||
|
||||
-- Check if point is inside this element
|
||||
if isPointInElement(element, x, y) then
|
||||
-- Return the first interactive ancestor (or the element itself if interactive)
|
||||
local interactive = findInteractiveAncestor(element)
|
||||
if interactive then
|
||||
return interactive
|
||||
end
|
||||
-- If no interactive ancestor, return the element itself
|
||||
-- This preserves backward compatibility for non-interactive overlays
|
||||
return element
|
||||
end
|
||||
|
||||
@@ -7,11 +7,8 @@ ImageCache._cache = {}
|
||||
---@param path string -- File path to normalize
|
||||
---@return string -- Normalized path
|
||||
local function normalizePath(path)
|
||||
-- Remove leading/trailing whitespace
|
||||
path = path:match("^%s*(.-)%s*$")
|
||||
-- Convert backslashes to forward slashes
|
||||
path = path:gsub("\\", "/")
|
||||
-- Remove redundant slashes
|
||||
path = path:gsub("/+", "/")
|
||||
return path
|
||||
end
|
||||
@@ -29,12 +26,10 @@ function ImageCache.load(imagePath, loadImageData)
|
||||
|
||||
local normalizedPath = normalizePath(imagePath)
|
||||
|
||||
-- Check if already cached
|
||||
if ImageCache._cache[normalizedPath] then
|
||||
return ImageCache._cache[normalizedPath].image, nil
|
||||
end
|
||||
|
||||
-- Try to load the image
|
||||
local success, imageOrError = pcall(love.graphics.newImage, normalizedPath)
|
||||
if not success then
|
||||
return nil, string.format("Failed to load image '%s': %s", imagePath, tostring(imageOrError))
|
||||
@@ -43,7 +38,6 @@ function ImageCache.load(imagePath, loadImageData)
|
||||
local image = imageOrError
|
||||
local imgData = nil
|
||||
|
||||
-- Load ImageData if requested
|
||||
if loadImageData then
|
||||
local dataSuccess, dataOrError = pcall(love.image.newImageData, normalizedPath)
|
||||
if dataSuccess then
|
||||
@@ -51,7 +45,6 @@ function ImageCache.load(imagePath, loadImageData)
|
||||
end
|
||||
end
|
||||
|
||||
-- Cache the image
|
||||
ImageCache._cache[normalizedPath] = {
|
||||
image = image,
|
||||
imageData = imgData,
|
||||
@@ -96,7 +89,6 @@ function ImageCache.remove(imagePath)
|
||||
|
||||
local normalizedPath = normalizePath(imagePath)
|
||||
if ImageCache._cache[normalizedPath] then
|
||||
-- Release the image
|
||||
local cached = ImageCache._cache[normalizedPath]
|
||||
if cached.image then
|
||||
cached.image:release()
|
||||
@@ -112,7 +104,6 @@ end
|
||||
|
||||
--- Clear all cached images
|
||||
function ImageCache.clear()
|
||||
-- Release all images
|
||||
for path, cached in pairs(ImageCache._cache) do
|
||||
if cached.image then
|
||||
cached.image:release()
|
||||
|
||||
@@ -6,13 +6,8 @@ local function formatError(module, message)
|
||||
return string.format("[FlexLove.%s] %s", module, message)
|
||||
end
|
||||
|
||||
-- ====================
|
||||
-- ImageDataReader
|
||||
-- ====================
|
||||
|
||||
local ImageDataReader = {}
|
||||
|
||||
--- Load ImageData from a file path
|
||||
---@param imagePath string
|
||||
---@return love.ImageData
|
||||
function ImageDataReader.loadImageData(imagePath)
|
||||
|
||||
@@ -6,10 +6,6 @@ local function formatError(module, message)
|
||||
return string.format("[FlexLove.%s] %s", module, message)
|
||||
end
|
||||
|
||||
-- ====================
|
||||
-- ImageRenderer
|
||||
-- ====================
|
||||
|
||||
---@class ImageRenderer
|
||||
local ImageRenderer = {}
|
||||
|
||||
@@ -26,7 +22,6 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
|
||||
fitMode = fitMode or "fill"
|
||||
objectPosition = objectPosition or "center center"
|
||||
|
||||
-- Validate inputs
|
||||
if imageWidth <= 0 or imageHeight <= 0 or boundsWidth <= 0 or boundsHeight <= 0 then
|
||||
error(formatError("ImageRenderer", "Dimensions must be positive"))
|
||||
end
|
||||
@@ -44,7 +39,6 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
|
||||
scaleY = 1, -- Scale factor Y
|
||||
}
|
||||
|
||||
-- Calculate based on fit mode
|
||||
if fitMode == "fill" then
|
||||
-- Stretch to fill bounds (may distort)
|
||||
result.scaleX = boundsWidth / imageWidth
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---@class ThemeManager
|
||||
---@field theme string? -- Theme name to use
|
||||
---@field themeComponent string? -- Component name from theme (e.g., "button", "panel")
|
||||
---@field theme string?
|
||||
---@field themeComponent string?
|
||||
---@field _themeState string -- Current theme state (normal, hover, pressed, active, disabled)
|
||||
---@field disabled boolean -- If true, element is disabled
|
||||
---@field active boolean -- If true, element is in active state (e.g., focused input)
|
||||
---@field disabled boolean
|
||||
---@field active boolean
|
||||
---@field disableHighlight boolean -- If true, disable pressed highlight overlay
|
||||
---@field scaleCorners number? -- Scale multiplier for 9-patch corners/edges
|
||||
---@field scalingAlgorithm string? -- "nearest" or "bilinear" scaling for 9-patch
|
||||
@@ -12,7 +12,6 @@
|
||||
local ThemeManager = {}
|
||||
ThemeManager.__index = ThemeManager
|
||||
|
||||
--- Create new ThemeManager instance
|
||||
---@param config table Configuration options
|
||||
---@param deps table Dependencies {Theme: Theme module}
|
||||
---@return ThemeManager
|
||||
@@ -20,10 +19,8 @@ function ThemeManager.new(config, deps)
|
||||
local Theme = deps.Theme
|
||||
local self = setmetatable({}, ThemeManager)
|
||||
|
||||
-- Store dependency for instance methods
|
||||
self._Theme = Theme
|
||||
|
||||
-- Theme configuration
|
||||
self.theme = config.theme
|
||||
self.themeComponent = config.themeComponent
|
||||
self.disabled = config.disabled or false
|
||||
@@ -32,20 +29,17 @@ function ThemeManager.new(config, deps)
|
||||
self.scaleCorners = config.scaleCorners
|
||||
self.scalingAlgorithm = config.scalingAlgorithm
|
||||
|
||||
-- Internal state
|
||||
self._themeState = "normal"
|
||||
self._element = nil
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Initialize ThemeManager with parent element reference
|
||||
---@param element table The parent Element
|
||||
function ThemeManager:initialize(element)
|
||||
self._element = element
|
||||
end
|
||||
|
||||
--- Update theme state based on interaction state
|
||||
---@param isHovered boolean Whether element is hovered
|
||||
---@param isPressed boolean Whether element is pressed
|
||||
---@param isFocused boolean Whether element is focused
|
||||
@@ -54,7 +48,6 @@ end
|
||||
function ThemeManager:updateState(isHovered, isPressed, isFocused, isDisabled)
|
||||
local newState = "normal"
|
||||
|
||||
-- State priority: disabled > active > pressed > hover > normal
|
||||
if isDisabled or self.disabled then
|
||||
newState = "disabled"
|
||||
elseif self.active then
|
||||
@@ -69,31 +62,21 @@ function ThemeManager:updateState(isHovered, isPressed, isFocused, isDisabled)
|
||||
return newState
|
||||
end
|
||||
|
||||
--- Get current theme state
|
||||
---@return string The current theme state
|
||||
function ThemeManager:getState()
|
||||
return self._themeState
|
||||
end
|
||||
|
||||
--- Set theme state directly
|
||||
---@param state string The theme state to set
|
||||
function ThemeManager:setState(state)
|
||||
self._themeState = state
|
||||
end
|
||||
|
||||
--- Check if this ThemeManager has a theme component
|
||||
---@return boolean
|
||||
function ThemeManager:hasThemeComponent()
|
||||
return self.themeComponent ~= nil
|
||||
end
|
||||
|
||||
--- Get the theme component name
|
||||
---@return string?
|
||||
function ThemeManager:getThemeComponent()
|
||||
return self.themeComponent
|
||||
end
|
||||
|
||||
--- Get the theme to use (element-specific or active theme)
|
||||
---@return table? The theme object or nil
|
||||
function ThemeManager:getTheme()
|
||||
if self.theme then
|
||||
@@ -102,7 +85,6 @@ function ThemeManager:getTheme()
|
||||
return self._Theme.getActive()
|
||||
end
|
||||
|
||||
--- Get the component definition from the theme
|
||||
---@return table? The component definition or nil
|
||||
function ThemeManager:getComponent()
|
||||
if not self.themeComponent then
|
||||
@@ -117,7 +99,6 @@ function ThemeManager:getComponent()
|
||||
return themeToUse.components[self.themeComponent]
|
||||
end
|
||||
|
||||
--- Get the current state's component definition (including state-specific overrides)
|
||||
---@return table? The component definition for current state or nil
|
||||
function ThemeManager:getStateComponent()
|
||||
local component = self:getComponent()
|
||||
@@ -125,7 +106,6 @@ function ThemeManager:getStateComponent()
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Check for state-specific override
|
||||
local state = self._themeState
|
||||
if state and state ~= "normal" and component.states and component.states[state] then
|
||||
return component.states[state]
|
||||
@@ -134,7 +114,6 @@ function ThemeManager:getStateComponent()
|
||||
return component
|
||||
end
|
||||
|
||||
--- Get property value from theme for current state
|
||||
---@param property string The property name
|
||||
---@return any? The property value or nil
|
||||
function ThemeManager:getStyle(property)
|
||||
@@ -146,9 +125,8 @@ function ThemeManager:getStyle(property)
|
||||
return stateComponent[property]
|
||||
end
|
||||
|
||||
--- Get the scaled content padding for current theme state
|
||||
---@param borderBoxWidth number The element's border box width
|
||||
---@param borderBoxHeight number The element's border box height
|
||||
---@param borderBoxWidth number
|
||||
---@param borderBoxHeight number
|
||||
---@return table? {left, top, right, bottom} or nil if no contentPadding
|
||||
function ThemeManager:getScaledContentPadding(borderBoxWidth, borderBoxHeight)
|
||||
if not self.themeComponent then
|
||||
@@ -162,7 +140,6 @@ function ThemeManager:getScaledContentPadding(borderBoxWidth, borderBoxHeight)
|
||||
|
||||
local component = themeToUse.components[self.themeComponent]
|
||||
|
||||
-- Check for state-specific override
|
||||
local state = self._themeState or "normal"
|
||||
if state and state ~= "normal" and component.states and component.states[state] then
|
||||
component = component.states[state]
|
||||
@@ -174,7 +151,6 @@ function ThemeManager:getScaledContentPadding(borderBoxWidth, borderBoxHeight)
|
||||
|
||||
local contentPadding = component._ninePatchData.contentPadding
|
||||
|
||||
-- Scale contentPadding to match the actual rendered size
|
||||
local atlasImage = component._loadedAtlas or themeToUse.atlas
|
||||
if atlasImage and type(atlasImage) ~= "string" then
|
||||
local originalWidth, originalHeight = atlasImage:getDimensions()
|
||||
@@ -192,7 +168,6 @@ function ThemeManager:getScaledContentPadding(borderBoxWidth, borderBoxHeight)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get contentAutoSizingMultiplier from theme
|
||||
---@return number? The multiplier or nil
|
||||
function ThemeManager:getContentAutoSizingMultiplier()
|
||||
if not self.themeComponent then
|
||||
@@ -204,7 +179,6 @@ function ThemeManager:getContentAutoSizingMultiplier()
|
||||
return nil
|
||||
end
|
||||
|
||||
-- First check if themeComponent has a multiplier
|
||||
if self.themeComponent then
|
||||
local component = themeToUse.components[self.themeComponent]
|
||||
if component and component.contentAutoSizingMultiplier then
|
||||
@@ -233,7 +207,6 @@ function ThemeManager:getDefaultFontFamily()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Set theme and component
|
||||
---@param themeName string? The theme name
|
||||
---@param componentName string? The component name
|
||||
function ThemeManager:setTheme(themeName, componentName)
|
||||
@@ -241,16 +214,4 @@ function ThemeManager:setTheme(themeName, componentName)
|
||||
self.themeComponent = componentName
|
||||
end
|
||||
|
||||
--- Get scale corners multiplier
|
||||
---@return number?
|
||||
function ThemeManager:getScaleCorners()
|
||||
return self.scaleCorners
|
||||
end
|
||||
|
||||
--- Get scaling algorithm
|
||||
---@return string?
|
||||
function ThemeManager:getScalingAlgorithm()
|
||||
return self.scalingAlgorithm
|
||||
end
|
||||
|
||||
return ThemeManager
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
local Units = {}
|
||||
|
||||
--- Parse a unit value (string or number) into value and unit type
|
||||
---@param value string|number
|
||||
---@return number, string -- Returns numeric value and unit type ("px", "%", "vw", "vh")
|
||||
function Units.parse(value)
|
||||
@@ -71,7 +70,6 @@ function Units.getViewport()
|
||||
return Gui._cachedViewport.width, Gui._cachedViewport.height
|
||||
end
|
||||
|
||||
-- Query viewport dimensions normally
|
||||
if love.graphics and love.graphics.getDimensions then
|
||||
return love.graphics.getDimensions()
|
||||
else
|
||||
@@ -80,9 +78,8 @@ function Units.getViewport()
|
||||
end
|
||||
end
|
||||
|
||||
--- Apply base scaling to a value
|
||||
---@param value number
|
||||
---@param axis "x"|"y" -- Which axis to scale on
|
||||
---@param axis "x"|"y"
|
||||
---@param scaleFactors {x:number, y:number}
|
||||
---@return number
|
||||
function Units.applyBaseScale(value, axis, scaleFactors)
|
||||
@@ -93,7 +90,6 @@ function Units.applyBaseScale(value, axis, scaleFactors)
|
||||
end
|
||||
end
|
||||
|
||||
--- Resolve units for spacing properties (padding, margin)
|
||||
---@param spacingProps table?
|
||||
---@param parentWidth number
|
||||
---@param parentHeight number
|
||||
@@ -106,7 +102,6 @@ function Units.resolveSpacing(spacingProps, parentWidth, parentHeight)
|
||||
local viewportWidth, viewportHeight = Units.getViewport()
|
||||
local result = {}
|
||||
|
||||
-- Handle shorthand properties first
|
||||
local vertical = spacingProps.vertical
|
||||
local horizontal = spacingProps.horizontal
|
||||
|
||||
@@ -124,7 +119,6 @@ function Units.resolveSpacing(spacingProps, parentWidth, parentHeight)
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle individual sides
|
||||
for _, side in ipairs({ "top", "right", "bottom", "left" }) do
|
||||
local value = spacingProps[side]
|
||||
if value then
|
||||
@@ -136,7 +130,6 @@ function Units.resolveSpacing(spacingProps, parentWidth, parentHeight)
|
||||
result[side] = value
|
||||
end
|
||||
else
|
||||
-- Use fallbacks
|
||||
if side == "top" or side == "bottom" then
|
||||
result[side] = vertical or 0
|
||||
else
|
||||
@@ -148,9 +141,8 @@ function Units.resolveSpacing(spacingProps, parentWidth, parentHeight)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Check if a unit string is valid
|
||||
---@param unitStr string -- Unit string to validate (e.g., "10px", "50%", "20vw")
|
||||
---@return boolean -- Returns true if unit string is valid
|
||||
---@param unitStr string
|
||||
---@return boolean
|
||||
function Units.isValid(unitStr)
|
||||
if type(unitStr) ~= "string" then
|
||||
return false
|
||||
@@ -161,7 +153,6 @@ function Units.isValid(unitStr)
|
||||
return validUnits[unit] == true
|
||||
end
|
||||
|
||||
--- Parse and resolve a unit value in one call
|
||||
---@param value string|number -- Value to parse and resolve
|
||||
---@param viewportWidth number -- Current viewport width
|
||||
---@param viewportHeight number -- Current viewport height
|
||||
|
||||
Reference in New Issue
Block a user