cleanup
This commit is contained in:
77
FlexLove.lua
77
FlexLove.lua
@@ -52,7 +52,6 @@ flexlove._LICENSE = [[
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
--- Initialize FlexLove with configuration
|
|
||||||
---@param config {baseScale?: {width?:number, height?:number}, theme?: string|ThemeDefinition, immediateMode?: boolean, stateRetentionFrames?: number, maxStateEntries?: number, autoFrameManagement?: boolean}
|
---@param config {baseScale?: {width?:number, height?:number}, theme?: string|ThemeDefinition, immediateMode?: boolean, stateRetentionFrames?: number, maxStateEntries?: number, autoFrameManagement?: boolean}
|
||||||
function flexlove.init(config)
|
function flexlove.init(config)
|
||||||
config = config or {}
|
config = config or {}
|
||||||
@@ -89,10 +88,8 @@ function flexlove.init(config)
|
|||||||
local immediateMode = config.immediateMode or false
|
local immediateMode = config.immediateMode or false
|
||||||
flexlove.setMode(immediateMode and "immediate" or "retained")
|
flexlove.setMode(immediateMode and "immediate" or "retained")
|
||||||
|
|
||||||
-- Configure auto frame management (defaults to false for manual control)
|
|
||||||
flexlove._autoFrameManagement = config.autoFrameManagement or false
|
flexlove._autoFrameManagement = config.autoFrameManagement or false
|
||||||
|
|
||||||
-- Configure state management
|
|
||||||
if config.stateRetentionFrames or config.maxStateEntries then
|
if config.stateRetentionFrames or config.maxStateEntries then
|
||||||
StateManager.configure({
|
StateManager.configure({
|
||||||
stateRetentionFrames = config.stateRetentionFrames,
|
stateRetentionFrames = config.stateRetentionFrames,
|
||||||
@@ -120,19 +117,16 @@ function flexlove.resize()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the rendering mode (immediate or retained)
|
---@param mode "immediate"|"retained"
|
||||||
---@param mode "immediate"|"retained" The rendering mode to use
|
|
||||||
function flexlove.setMode(mode)
|
function flexlove.setMode(mode)
|
||||||
if mode == "immediate" then
|
if mode == "immediate" then
|
||||||
flexlove._immediateMode = true
|
flexlove._immediateMode = true
|
||||||
flexlove._immediateModeState = StateManager
|
flexlove._immediateModeState = StateManager
|
||||||
-- Reset frame state
|
|
||||||
flexlove._frameStarted = false
|
flexlove._frameStarted = false
|
||||||
flexlove._autoBeganFrame = false
|
flexlove._autoBeganFrame = false
|
||||||
elseif mode == "retained" then
|
elseif mode == "retained" then
|
||||||
flexlove._immediateMode = false
|
flexlove._immediateMode = false
|
||||||
flexlove._immediateModeState = nil
|
flexlove._immediateModeState = nil
|
||||||
-- Clear immediate mode state
|
|
||||||
flexlove._frameStarted = false
|
flexlove._frameStarted = false
|
||||||
flexlove._autoBeganFrame = false
|
flexlove._autoBeganFrame = false
|
||||||
flexlove._currentFrameElements = {}
|
flexlove._currentFrameElements = {}
|
||||||
@@ -142,7 +136,6 @@ function flexlove.setMode(mode)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the current rendering mode
|
|
||||||
---@return "immediate"|"retained"
|
---@return "immediate"|"retained"
|
||||||
function flexlove.getMode()
|
function flexlove.getMode()
|
||||||
return flexlove._immediateMode and "immediate" or "retained"
|
return flexlove._immediateMode and "immediate" or "retained"
|
||||||
@@ -154,28 +147,20 @@ function flexlove.beginFrame()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Increment frame counter
|
|
||||||
flexlove._frameNumber = flexlove._frameNumber + 1
|
flexlove._frameNumber = flexlove._frameNumber + 1
|
||||||
StateManager.incrementFrame()
|
StateManager.incrementFrame()
|
||||||
|
|
||||||
-- Clear current frame elements
|
|
||||||
flexlove._currentFrameElements = {}
|
flexlove._currentFrameElements = {}
|
||||||
flexlove._frameStarted = true
|
flexlove._frameStarted = true
|
||||||
|
|
||||||
-- Clear top elements (they will be recreated this frame)
|
|
||||||
flexlove.topElements = {}
|
flexlove.topElements = {}
|
||||||
|
|
||||||
-- Clear z-index ordered elements from previous frame
|
|
||||||
GuiState.clearFrameElements()
|
GuiState.clearFrameElements()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- End the current immediate mode frame
|
|
||||||
function flexlove.endFrame()
|
function flexlove.endFrame()
|
||||||
if not flexlove._immediateMode then
|
if not flexlove._immediateMode then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sort elements by z-index for occlusion detection
|
|
||||||
GuiState.sortElementsByZIndex()
|
GuiState.sortElementsByZIndex()
|
||||||
|
|
||||||
-- Layout all top-level elements now that all children have been added
|
-- Layout all top-level elements now that all children have been added
|
||||||
@@ -189,8 +174,6 @@ function flexlove.endFrame()
|
|||||||
-- Auto-update all top-level elements (triggers additional state updates)
|
-- Auto-update all top-level elements (triggers additional state updates)
|
||||||
-- This must happen BEFORE saving state so that scroll positions and overflow are calculated
|
-- This must happen BEFORE saving state so that scroll positions and overflow are calculated
|
||||||
for _, element in ipairs(flexlove._currentFrameElements) do
|
for _, element in ipairs(flexlove._currentFrameElements) do
|
||||||
-- Only update top-level elements (those without parents in the current frame)
|
|
||||||
-- Element:update() will recursively update children
|
|
||||||
if not element.parent then
|
if not element.parent then
|
||||||
element:update(0) -- dt=0 since we're not doing animation updates here
|
element:update(0) -- dt=0 since we're not doing animation updates here
|
||||||
end
|
end
|
||||||
@@ -220,7 +203,6 @@ function flexlove.endFrame()
|
|||||||
state._scrollbarDragging = element._scrollbarDragging
|
state._scrollbarDragging = element._scrollbarDragging
|
||||||
state._hoveredScrollbar = element._hoveredScrollbar
|
state._hoveredScrollbar = element._hoveredScrollbar
|
||||||
state._scrollbarDragOffset = element._scrollbarDragOffset
|
state._scrollbarDragOffset = element._scrollbarDragOffset
|
||||||
-- Save cursor blink state
|
|
||||||
state._cursorBlinkTimer = element._cursorBlinkTimer
|
state._cursorBlinkTimer = element._cursorBlinkTimer
|
||||||
state._cursorVisible = element._cursorVisible
|
state._cursorVisible = element._cursorVisible
|
||||||
state._cursorBlinkPaused = element._cursorBlinkPaused
|
state._cursorBlinkPaused = element._cursorBlinkPaused
|
||||||
@@ -230,17 +212,11 @@ function flexlove.endFrame()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cleanup stale states
|
|
||||||
StateManager.cleanup()
|
StateManager.cleanup()
|
||||||
|
|
||||||
-- Force cleanup if we have too many states
|
|
||||||
StateManager.forceCleanupIfNeeded()
|
StateManager.forceCleanupIfNeeded()
|
||||||
|
|
||||||
-- Clear frame started flag
|
|
||||||
flexlove._frameStarted = false
|
flexlove._frameStarted = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Canvas cache for game rendering
|
|
||||||
flexlove._gameCanvas = nil
|
flexlove._gameCanvas = nil
|
||||||
flexlove._backdropCanvas = nil
|
flexlove._backdropCanvas = nil
|
||||||
flexlove._canvasDimensions = { width = 0, height = 0 }
|
flexlove._canvasDimensions = { width = 0, height = 0 }
|
||||||
@@ -248,7 +224,6 @@ flexlove._canvasDimensions = { width = 0, height = 0 }
|
|||||||
---@param gameDrawFunc function|nil
|
---@param gameDrawFunc function|nil
|
||||||
---@param postDrawFunc function|nil
|
---@param postDrawFunc function|nil
|
||||||
function flexlove.draw(gameDrawFunc, postDrawFunc)
|
function flexlove.draw(gameDrawFunc, postDrawFunc)
|
||||||
-- Auto-end frame if it was auto-started in immediate mode
|
|
||||||
if flexlove._immediateMode and flexlove._autoBeganFrame then
|
if flexlove._immediateMode and flexlove._autoBeganFrame then
|
||||||
flexlove.endFrame()
|
flexlove.endFrame()
|
||||||
flexlove._autoBeganFrame = false
|
flexlove._autoBeganFrame = false
|
||||||
@@ -346,7 +321,6 @@ function flexlove.draw(gameDrawFunc, postDrawFunc)
|
|||||||
love.graphics.setCanvas(outerCanvas)
|
love.graphics.setCanvas(outerCanvas)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if element is an ancestor of target
|
|
||||||
---@param element Element
|
---@param element Element
|
||||||
---@param target Element
|
---@param target Element
|
||||||
---@return boolean
|
---@return boolean
|
||||||
@@ -487,7 +461,6 @@ function flexlove.update(dt)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Forward text input to focused element
|
|
||||||
---@param text string
|
---@param text string
|
||||||
function flexlove.textinput(text)
|
function flexlove.textinput(text)
|
||||||
if flexlove._focusedElement then
|
if flexlove._focusedElement then
|
||||||
@@ -495,7 +468,6 @@ function flexlove.textinput(text)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Forward key press to focused element
|
|
||||||
---@param key string
|
---@param key string
|
||||||
---@param scancode string
|
---@param scancode string
|
||||||
---@param isrepeat boolean
|
---@param isrepeat boolean
|
||||||
@@ -505,7 +477,6 @@ function flexlove.keypressed(key, scancode, isrepeat)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Handle mouse wheel scrolling
|
|
||||||
function flexlove.wheelmoved(x, y)
|
function flexlove.wheelmoved(x, y)
|
||||||
local mx, my = love.mouse.getPosition()
|
local mx, my = love.mouse.getPosition()
|
||||||
|
|
||||||
@@ -537,7 +508,6 @@ function flexlove.wheelmoved(x, y)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- In immediate mode, use z-index ordered elements and respect occlusion
|
|
||||||
if flexlove._immediateMode then
|
if flexlove._immediateMode then
|
||||||
-- Find topmost scrollable element at mouse position using z-index ordering
|
-- Find topmost scrollable element at mouse position using z-index ordering
|
||||||
for i = #GuiState._zIndexOrderedElements, 1, -1 do
|
for i = #GuiState._zIndexOrderedElements, 1, -1 do
|
||||||
@@ -566,7 +536,6 @@ function flexlove.wheelmoved(x, y)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Destroy all elements and their children
|
|
||||||
function flexlove.destroy()
|
function flexlove.destroy()
|
||||||
for _, win in ipairs(flexlove.topElements) do
|
for _, win in ipairs(flexlove.topElements) do
|
||||||
win:destroy()
|
win:destroy()
|
||||||
@@ -581,7 +550,6 @@ function flexlove.destroy()
|
|||||||
flexlove._focusedElement = nil
|
flexlove._focusedElement = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a new element (supports both immediate and retained mode)
|
|
||||||
---@param props ElementProps
|
---@param props ElementProps
|
||||||
---@return Element
|
---@return Element
|
||||||
function flexlove.new(props)
|
function flexlove.new(props)
|
||||||
@@ -666,7 +634,6 @@ function flexlove.new(props)
|
|||||||
if element._scrollManager then
|
if element._scrollManager then
|
||||||
element._scrollManager._scrollbarHoveredVertical = element._scrollbarHoveredVertical or false
|
element._scrollManager._scrollbarHoveredVertical = element._scrollbarHoveredVertical or false
|
||||||
element._scrollManager._scrollbarHoveredHorizontal = element._scrollbarHoveredHorizontal or false
|
element._scrollManager._scrollbarHoveredHorizontal = element._scrollbarHoveredHorizontal or false
|
||||||
-- Note: drag state already synced earlier (lines 633-643)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set initial theme state based on StateManager state
|
-- Set initial theme state based on StateManager state
|
||||||
@@ -685,18 +652,11 @@ function flexlove.new(props)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Store element in current frame tracking
|
|
||||||
table.insert(flexlove._currentFrameElements, element)
|
table.insert(flexlove._currentFrameElements, element)
|
||||||
|
|
||||||
-- Save state back at end of frame (we'll do this in endFrame)
|
|
||||||
-- For now, we need to update the state when properties change
|
|
||||||
-- This is a simplified approach - a full implementation would use
|
|
||||||
-- a more sophisticated state synchronization mechanism
|
|
||||||
|
|
||||||
return element
|
return element
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get state count (for debugging)
|
|
||||||
---@return number
|
---@return number
|
||||||
function flexlove.getStateCount()
|
function flexlove.getStateCount()
|
||||||
if not flexlove._immediateMode then
|
if not flexlove._immediateMode then
|
||||||
@@ -731,41 +691,6 @@ function flexlove.getStateStats()
|
|||||||
return StateManager.getStats()
|
return StateManager.getStats()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Helper function: Create a button with default styling
|
|
||||||
---@param props table
|
|
||||||
---@return Element
|
|
||||||
function flexlove.button(props)
|
|
||||||
props = props or {}
|
|
||||||
props.themeComponent = props.themeComponent or "button"
|
|
||||||
return flexlove.new(props)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Helper function: Create a panel/container
|
|
||||||
---@param props table
|
|
||||||
---@return Element
|
|
||||||
function flexlove.panel(props)
|
|
||||||
props = props or {}
|
|
||||||
return flexlove.new(props)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Helper function: Create a text label
|
|
||||||
---@param props table
|
|
||||||
---@return Element
|
|
||||||
function flexlove.text(props)
|
|
||||||
props = props or {}
|
|
||||||
return flexlove.new(props)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Helper function: Create an input field
|
|
||||||
---@param props table
|
|
||||||
---@return Element
|
|
||||||
function flexlove.input(props)
|
|
||||||
props = props or {}
|
|
||||||
props.editable = true
|
|
||||||
return flexlove.new(props)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- only export what should be used externally
|
|
||||||
flexlove.Animation = Animation
|
flexlove.Animation = Animation
|
||||||
flexlove.Color = Color
|
flexlove.Color = Color
|
||||||
flexlove.Theme = Theme
|
flexlove.Theme = Theme
|
||||||
|
|||||||
Reference in New Issue
Block a user