broken restrained mode - will revert
This commit is contained in:
84
FlexLove.lua
84
FlexLove.lua
@@ -54,8 +54,10 @@ local Positioning, FlexDirection, JustifyContent, AlignContent, AlignItems, Text
|
|||||||
local Gui = GuiState
|
local Gui = GuiState
|
||||||
|
|
||||||
--- Initialize FlexLove with configuration
|
--- Initialize FlexLove with configuration
|
||||||
---@param config {baseScale?: {width?:number, height?:number}, theme?: string|ThemeDefinition, immediateMode?: boolean, stateRetentionFrames?: number, maxStateEntries?: number}
|
---@param config {baseScale?: {width?:number, height?:number}, theme?: string|ThemeDefinition, immediateMode?: boolean, stateRetentionFrames?: number, maxStateEntries?: number, autoFrameManagement?: boolean}
|
||||||
function Gui.init(config)
|
function Gui.init(config)
|
||||||
|
config = config or {}
|
||||||
|
|
||||||
if config.baseScale then
|
if config.baseScale then
|
||||||
Gui.baseScale = {
|
Gui.baseScale = {
|
||||||
width = config.baseScale.width or 1920,
|
width = config.baseScale.width or 1920,
|
||||||
@@ -85,22 +87,18 @@ function Gui.init(config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Initialize immediate mode if requested
|
local immediateMode = config.immediateMode or false
|
||||||
if config.immediateMode then
|
Gui.setMode(immediateMode and "immediate" or "retained")
|
||||||
Gui._immediateMode = true
|
|
||||||
Gui._immediateModeState = ImmediateModeState
|
|
||||||
|
|
||||||
-- Configure state management
|
-- Configure auto frame management (defaults to false for manual control)
|
||||||
if config.stateRetentionFrames or config.maxStateEntries then
|
Gui._autoFrameManagement = config.autoFrameManagement or false
|
||||||
ImmediateModeState.configure({
|
|
||||||
stateRetentionFrames = config.stateRetentionFrames,
|
-- Configure state management
|
||||||
maxStateEntries = config.maxStateEntries,
|
if config.stateRetentionFrames or config.maxStateEntries then
|
||||||
})
|
ImmediateModeState.configure({
|
||||||
end
|
stateRetentionFrames = config.stateRetentionFrames,
|
||||||
else
|
maxStateEntries = config.maxStateEntries,
|
||||||
-- Explicitly disable immediate mode if not requested
|
})
|
||||||
Gui._immediateMode = false
|
|
||||||
Gui._immediateModeState = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -123,6 +121,34 @@ function Gui.resize()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set the rendering mode (immediate or retained)
|
||||||
|
---@param mode "immediate"|"retained" The rendering mode to use
|
||||||
|
function Gui.setMode(mode)
|
||||||
|
if mode == "immediate" then
|
||||||
|
Gui._immediateMode = true
|
||||||
|
Gui._immediateModeState = ImmediateModeState
|
||||||
|
-- Reset frame state
|
||||||
|
Gui._frameStarted = false
|
||||||
|
Gui._autoBeganFrame = false
|
||||||
|
elseif mode == "retained" then
|
||||||
|
Gui._immediateMode = false
|
||||||
|
Gui._immediateModeState = nil
|
||||||
|
-- Clear immediate mode state
|
||||||
|
Gui._frameStarted = false
|
||||||
|
Gui._autoBeganFrame = false
|
||||||
|
Gui._currentFrameElements = {}
|
||||||
|
Gui._frameNumber = 0
|
||||||
|
else
|
||||||
|
error("[FlexLove] Invalid mode: " .. tostring(mode) .. ". Expected 'immediate' or 'retained'")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the current rendering mode
|
||||||
|
---@return "immediate"|"retained"
|
||||||
|
function Gui.getMode()
|
||||||
|
return Gui._immediateMode and "immediate" or "retained"
|
||||||
|
end
|
||||||
|
|
||||||
--- Begin a new immediate mode frame
|
--- Begin a new immediate mode frame
|
||||||
function Gui.beginFrame()
|
function Gui.beginFrame()
|
||||||
if not Gui._immediateMode then
|
if not Gui._immediateMode then
|
||||||
@@ -136,6 +162,7 @@ function Gui.beginFrame()
|
|||||||
|
|
||||||
-- Clear current frame elements
|
-- Clear current frame elements
|
||||||
Gui._currentFrameElements = {}
|
Gui._currentFrameElements = {}
|
||||||
|
Gui._frameStarted = true
|
||||||
|
|
||||||
-- Clear top elements (they will be recreated this frame)
|
-- Clear top elements (they will be recreated this frame)
|
||||||
Gui.topElements = {}
|
Gui.topElements = {}
|
||||||
@@ -147,6 +174,16 @@ function Gui.endFrame()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Auto-update all top-level elements (triggers layout calculation and overflow detection)
|
||||||
|
-- This must happen BEFORE saving state so that scroll positions and overflow are calculated
|
||||||
|
for _, element in ipairs(Gui._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
|
||||||
|
element:update(0) -- dt=0 since we're not doing animation updates here
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Save state back for all elements created this frame
|
-- Save state back for all elements created this frame
|
||||||
for _, element in ipairs(Gui._currentFrameElements) do
|
for _, element in ipairs(Gui._currentFrameElements) do
|
||||||
if element.id and element.id ~= "" then
|
if element.id and element.id ~= "" then
|
||||||
@@ -184,6 +221,9 @@ function Gui.endFrame()
|
|||||||
-- Force cleanup if we have too many states
|
-- Force cleanup if we have too many states
|
||||||
ImmediateModeState.forceCleanupIfNeeded()
|
ImmediateModeState.forceCleanupIfNeeded()
|
||||||
StateManager.forceCleanupIfNeeded()
|
StateManager.forceCleanupIfNeeded()
|
||||||
|
|
||||||
|
-- Clear frame started flag
|
||||||
|
Gui._frameStarted = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Canvas cache for game rendering
|
-- Canvas cache for game rendering
|
||||||
@@ -194,6 +234,12 @@ Gui._canvasDimensions = { width = 0, height = 0 }
|
|||||||
---@param gameDrawFunc function|nil
|
---@param gameDrawFunc function|nil
|
||||||
---@param postDrawFunc function|nil
|
---@param postDrawFunc function|nil
|
||||||
function Gui.draw(gameDrawFunc, postDrawFunc)
|
function Gui.draw(gameDrawFunc, postDrawFunc)
|
||||||
|
-- Auto-end frame if it was auto-started in immediate mode
|
||||||
|
if Gui._immediateMode and Gui._autoBeganFrame then
|
||||||
|
Gui.endFrame()
|
||||||
|
Gui._autoBeganFrame = false
|
||||||
|
end
|
||||||
|
|
||||||
local outerCanvas = love.graphics.getCanvas()
|
local outerCanvas = love.graphics.getCanvas()
|
||||||
local gameCanvas = nil
|
local gameCanvas = nil
|
||||||
|
|
||||||
@@ -487,6 +533,12 @@ function Gui.new(props)
|
|||||||
return Element.new(props)
|
return Element.new(props)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Auto-begin frame if not manually started (convenience feature)
|
||||||
|
if not Gui._frameStarted then
|
||||||
|
Gui.beginFrame()
|
||||||
|
Gui._autoBeganFrame = true
|
||||||
|
end
|
||||||
|
|
||||||
-- Immediate mode: generate ID if not provided
|
-- Immediate mode: generate ID if not provided
|
||||||
if not props.id then
|
if not props.id then
|
||||||
props.id = ImmediateModeState.generateID(props)
|
props.id = ImmediateModeState.generateID(props)
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ local GuiState = {
|
|||||||
_frameNumber = 0,
|
_frameNumber = 0,
|
||||||
_currentFrameElements = {},
|
_currentFrameElements = {},
|
||||||
_immediateModeState = nil, -- Will be initialized if immediate mode is enabled
|
_immediateModeState = nil, -- Will be initialized if immediate mode is enabled
|
||||||
|
_frameStarted = false,
|
||||||
|
_autoBeganFrame = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Get current scale factors
|
--- Get current scale factors
|
||||||
|
|||||||
Reference in New Issue
Block a user