update type defs

This commit is contained in:
Michael Freno
2025-11-18 10:55:37 -05:00
parent 9f147c1d84
commit 6f3fa0e473
2 changed files with 125 additions and 44 deletions

View File

@@ -111,6 +111,10 @@
---@field imageOpacity number? -- Image opacity 0-1 (default: 1, combines with element opacity) ---@field imageOpacity number? -- Image opacity 0-1 (default: 1, combines with element opacity)
---@field imageRepeat "no-repeat"|"repeat"|"repeat-x"|"repeat-y"|"space"|"round"? -- Image repeat/tiling mode (default: "no-repeat") ---@field imageRepeat "no-repeat"|"repeat"|"repeat-x"|"repeat-y"|"space"|"round"? -- Image repeat/tiling mode (default: "no-repeat")
---@field imageTint Color? -- Color to tint the image (default: nil/white, no tint) ---@field imageTint Color? -- Color to tint the image (default: nil/white, no tint)
---@field onImageLoad fun(element:Element, image:love.Image)? -- Callback when image loads successfully
---@field onImageLoadDeferred boolean? -- Whether onImageLoad callback should be deferred (default: false)
---@field onImageError fun(element:Element, error:string)? -- Callback when image fails to load
---@field onImageErrorDeferred boolean? -- Whether onImageError callback should be deferred (default: false)
---@field _loadedImage love.Image? -- Internal: cached loaded image ---@field _loadedImage love.Image? -- Internal: cached loaded image
---@field hideScrollbars boolean|{vertical:boolean, horizontal:boolean}? -- Hide scrollbars (boolean for both, or table for individual control) ---@field hideScrollbars boolean|{vertical:boolean, horizontal:boolean}? -- Hide scrollbars (boolean for both, or table for individual control)
---@field userdata table? ---@field userdata table?
@@ -215,10 +219,15 @@ function Element.new(props, deps)
self.userdata = props.userdata self.userdata = props.userdata
self.onFocus = props.onFocus self.onFocus = props.onFocus
self.onFocusDeferred = props.onFocusDeferred or false
self.onBlur = props.onBlur self.onBlur = props.onBlur
self.onBlurDeferred = props.onBlurDeferred or false
self.onTextInput = props.onTextInput self.onTextInput = props.onTextInput
self.onTextInputDeferred = props.onTextInputDeferred or false
self.onTextChange = props.onTextChange self.onTextChange = props.onTextChange
self.onTextChangeDeferred = props.onTextChangeDeferred or false
self.onEnter = props.onEnter self.onEnter = props.onEnter
self.onEnterDeferred = props.onEnterDeferred or false
-- Initialize state manager ID for immediate mode (use self.id which may be auto-generated) -- Initialize state manager ID for immediate mode (use self.id which may be auto-generated)
self._stateId = self.id self._stateId = self.id
@@ -226,7 +235,7 @@ function Element.new(props, deps)
-- In immediate mode, restore EventHandler state from StateManager -- In immediate mode, restore EventHandler state from StateManager
local eventHandlerConfig = { local eventHandlerConfig = {
onEvent = self.onEvent, onEvent = self.onEvent,
onEventDeferred = props.onEventDeferred onEventDeferred = props.onEventDeferred,
} }
if self._deps.Context._immediateMode and self._stateId and self._stateId ~= "" then if self._deps.Context._immediateMode and self._stateId and self._stateId ~= "" then
local state = self._deps.StateManager.getState(self._stateId) local state = self._deps.StateManager.getState(self._stateId)
@@ -465,7 +474,7 @@ function Element.new(props, deps)
["repeat-x"] = "repeat-x", ["repeat-x"] = "repeat-x",
["repeat-y"] = "repeat-y", ["repeat-y"] = "repeat-y",
space = "space", space = "space",
round = "round" round = "round",
} }
self._deps.utils.validateEnum(props.imageRepeat, validImageRepeat, "imageRepeat") self._deps.utils.validateEnum(props.imageRepeat, validImageRepeat, "imageRepeat")
end end
@@ -474,17 +483,71 @@ function Element.new(props, deps)
-- Set imageTint -- Set imageTint
self.imageTint = props.imageTint self.imageTint = props.imageTint
-- Image callbacks
self.onImageLoad = props.onImageLoad
self.onImageLoadDeferred = props.onImageLoadDeferred or false
self.onImageError = props.onImageError
self.onImageErrorDeferred = props.onImageErrorDeferred or false
-- Auto-load image if imagePath is provided -- Auto-load image if imagePath is provided
if self.imagePath and not self.image then if self.imagePath and not self.image then
local loadedImage, err = self._deps.ImageCache.load(self.imagePath) local loadedImage, err = self._deps.ImageCache.load(self.imagePath)
if loadedImage then if loadedImage then
self._loadedImage = loadedImage self._loadedImage = loadedImage
-- Call onImageLoad callback if provided
if self.onImageLoad and type(self.onImageLoad) == "function" then
if self.onImageLoadDeferred then
self._deps.Context.deferCallback(function()
local success, callbackErr = pcall(self.onImageLoad, self, loadedImage)
if not success then
print(string.format("[Element] onImageLoad error: %s", tostring(callbackErr)))
end
end)
else
local success, callbackErr = pcall(self.onImageLoad, self, loadedImage)
if not success then
print(string.format("[Element] onImageLoad error: %s", tostring(callbackErr)))
end
end
end
else else
-- Silently fail - image will just not render -- Image failed to load
self._loadedImage = nil self._loadedImage = nil
-- Call onImageError callback if provided
if self.onImageError and type(self.onImageError) == "function" then
if self.onImageErrorDeferred then
self._deps.Context.deferCallback(function()
local success, callbackErr = pcall(self.onImageError, self, err or "Unknown error")
if not success then
print(string.format("[Element] onImageError error: %s", tostring(callbackErr)))
end
end)
else
local success, callbackErr = pcall(self.onImageError, self, err or "Unknown error")
if not success then
print(string.format("[Element] onImageError error: %s", tostring(callbackErr)))
end
end
end
end end
elseif self.image then elseif self.image then
self._loadedImage = self.image self._loadedImage = self.image
-- Call onImageLoad for directly provided images
if self.onImageLoad and type(self.onImageLoad) == "function" then
if self.onImageLoadDeferred then
self._deps.Context.deferCallback(function()
local success, callbackErr = pcall(self.onImageLoad, self, self.image)
if not success then
print(string.format("[Element] onImageLoad error: %s", tostring(callbackErr)))
end
end)
else
local success, callbackErr = pcall(self.onImageLoad, self, self.image)
if not success then
print(string.format("[Element] onImageLoad error: %s", tostring(callbackErr)))
end
end
end
else else
self._loadedImage = nil self._loadedImage = nil
end end
@@ -2854,7 +2917,7 @@ function Element:setImageRepeat(repeatMode)
["repeat-x"] = "repeat-x", ["repeat-x"] = "repeat-x",
["repeat-y"] = "repeat-y", ["repeat-y"] = "repeat-y",
space = "space", space = "space",
round = "round" round = "round",
} }
self._deps.utils.validateEnum(repeatMode, validImageRepeat, "imageRepeat") self._deps.utils.validateEnum(repeatMode, validImageRepeat, "imageRepeat")
self.imageRepeat = repeatMode self.imageRepeat = repeatMode

View File

@@ -6,11 +6,16 @@
-- For Animation.lua -- For Animation.lua
--=====================================-- --=====================================--
---@class AnimationProps ---@class AnimationProps
---@field duration number ---@field duration number -- Duration in seconds
---@field start {width?:number, height?:number, opacity?:number} ---@field start table -- Starting values (can contain: width, height, opacity, x, y, gap, imageOpacity, backgroundColor, borderColor, textColor, padding, margin, cornerRadius, transform, etc.)
---@field final {width?:number, height?:number, opacity?:number} ---@field final table -- Final values (same properties as start)
---@field transform table? ---@field easing string? -- Easing function name: "linear", "easeInQuad", "easeOutQuad", "easeInOutQuad", "easeInCubic", "easeOutCubic", "easeInOutCubic", "easeInQuart", "easeOutQuart", "easeInExpo", "easeOutExpo" (default: "linear")
---@field transition table? ---@field onStart fun(animation:Animation, element:Element?)? -- Called when animation starts
---@field onUpdate fun(animation:Animation, element:Element?, progress:number)? -- Called each frame with progress (0-1)
---@field onComplete fun(animation:Animation, element:Element?)? -- Called when animation completes
---@field onCancel fun(animation:Animation, element:Element?)? -- Called when animation is cancelled
---@field transform table? -- Additional transform properties (legacy support)
---@field transition table? -- Transition properties (legacy support)
local AnimationProps = {} local AnimationProps = {}
---@class TransformProps ---@class TransformProps
@@ -41,6 +46,7 @@ local AnimationProps = {}
---@field border Border? -- Border configuration for the element ---@field border Border? -- Border configuration for the element
---@field borderColor Color? -- Color of the border (default: black) ---@field borderColor Color? -- Color of the border (default: black)
---@field opacity number? -- Element opacity 0-1 (default: 1) ---@field opacity number? -- Element opacity 0-1 (default: 1)
---@field visibility "visible"|"hidden"? -- Element visibility (default: "visible")
---@field backgroundColor Color? -- Background color (default: transparent) ---@field backgroundColor Color? -- Background color (default: transparent)
---@field cornerRadius number|{topLeft:number?, topRight:number?, bottomLeft:number?, bottomRight:number?}? -- Corner radius: number (all corners) or table for individual corners (default: 0) ---@field cornerRadius number|{topLeft:number?, topRight:number?, bottomLeft:number?, bottomRight:number?}? -- Corner radius: number (all corners) or table for individual corners (default: 0)
---@field gap number|string? -- Space between children elements (default: 0) ---@field gap number|string? -- Space between children elements (default: 0)
@@ -63,11 +69,17 @@ local AnimationProps = {}
---@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 onEvent fun(element:Element, event:InputEvent)? -- Callback function for interaction events ---@field onEvent fun(element:Element, event:InputEvent)? -- Callback function for interaction events
---@field onFocus fun(element:Element, event:InputEvent)? -- Callback when element receives focus ---@field onEventDeferred boolean? -- Whether onEvent callback should be deferred until after canvases are released (default: false)
---@field onBlur fun(element:Element, event:InputEvent)? -- Callback when element loses focus ---@field onFocus fun(element:Element)? -- Callback when element receives focus
---@field onFocusDeferred boolean? -- Whether onFocus callback should be deferred (default: false)
---@field onBlur fun(element:Element)? -- Callback when element loses focus
---@field onBlurDeferred boolean? -- Whether onBlur callback should be deferred (default: false)
---@field onTextInput fun(element:Element, text:string)? -- Callback when text is input ---@field onTextInput fun(element:Element, text:string)? -- Callback when text is input
---@field onTextInputDeferred boolean? -- Whether onTextInput callback should be deferred (default: false)
---@field onTextChange fun(element:Element, text:string)? -- Callback when text content changes ---@field onTextChange fun(element:Element, text:string)? -- Callback when text content changes
---@field onTextChangeDeferred boolean? -- Whether onTextChange callback should be deferred (default: false)
---@field onEnter fun(element:Element)? -- Callback when Enter key is pressed ---@field onEnter fun(element:Element)? -- Callback when Enter key is pressed
---@field onEnterDeferred boolean? -- Whether onEnter callback should be deferred (default: false)
---@field transform TransformProps? -- Transform properties for animations and styling ---@field transform TransformProps? -- Transform properties for animations and styling
---@field transition TransitionProps? -- Transition settings for animations ---@field transition TransitionProps? -- Transition settings for animations
---@field gridRows number? -- Number of rows in the grid (default: 1) ---@field gridRows number? -- Number of rows in the grid (default: 1)
@@ -114,6 +126,12 @@ local AnimationProps = {}
---@field objectFit "fill"|"contain"|"cover"|"scale-down"|"none"? -- Image fit mode (default: "fill") ---@field objectFit "fill"|"contain"|"cover"|"scale-down"|"none"? -- Image fit mode (default: "fill")
---@field objectPosition string? -- Image position like "center center", "top left", "50% 50%" (default: "center center") ---@field objectPosition string? -- Image position like "center center", "top left", "50% 50%" (default: "center center")
---@field imageOpacity number? -- Image opacity 0-1 (default: 1, combines with element opacity) ---@field imageOpacity number? -- Image opacity 0-1 (default: 1, combines with element opacity)
---@field imageRepeat "no-repeat"|"repeat"|"repeat-x"|"repeat-y"|"space"|"round"? -- Image repeat/tiling mode (default: "no-repeat")
---@field imageTint Color? -- Color to tint the image (default: nil/white, no tint)
---@field onImageLoad fun(element:Element, image:love.Image)? -- Callback when image loads successfully
---@field onImageLoadDeferred boolean? -- Whether onImageLoad callback should be deferred (default: false)
---@field onImageError fun(element:Element, error:string)? -- Callback when image fails to load
---@field onImageErrorDeferred boolean? -- Whether onImageError callback should be deferred (default: false)
---@field _scrollX number? -- Internal: scroll X position (restored in immediate mode) ---@field _scrollX number? -- Internal: scroll X position (restored in immediate mode)
---@field _scrollY number? -- Internal: scroll Y position (restored in immediate mode) ---@field _scrollY number? -- Internal: scroll Y position (restored in immediate mode)
---@field userdata table? -- User-defined data storage for custom properties ---@field userdata table? -- User-defined data storage for custom properties