state persistance consolidation
This commit is contained in:
134
FlexLove.lua
134
FlexLove.lua
@@ -430,54 +430,14 @@ function flexlove.endFrame()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Save state back for all elements created this frame (with diffing optimization)
|
-- Save state for all elements created this frame
|
||||||
|
-- State is collected from element and all sub-modules via element:saveState()
|
||||||
|
-- This is the ONLY place state is saved in immediate mode
|
||||||
for _, element in ipairs(flexlove._currentFrameElements) do
|
for _, element in ipairs(flexlove._currentFrameElements) do
|
||||||
if element.id and element.id ~= "" then
|
if element.id and element.id ~= "" then
|
||||||
-- Build state update object
|
-- Collect state from element and all sub-modules
|
||||||
local stateUpdate = {}
|
local stateUpdate = element:saveState()
|
||||||
|
|
||||||
-- Get event handler state
|
|
||||||
if element._eventHandler then
|
|
||||||
local eventState = element._eventHandler:getState()
|
|
||||||
for k, v in pairs(eventState) do
|
|
||||||
stateUpdate[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
stateUpdate._focused = element._focused
|
|
||||||
stateUpdate._cursorPosition = element._cursorPosition
|
|
||||||
stateUpdate._selectionStart = element._selectionStart
|
|
||||||
stateUpdate._selectionEnd = element._selectionEnd
|
|
||||||
stateUpdate._textBuffer = element._textBuffer
|
|
||||||
stateUpdate._scrollX = element._scrollX
|
|
||||||
stateUpdate._scrollY = element._scrollY
|
|
||||||
stateUpdate._scrollbarDragging = element._scrollbarDragging
|
|
||||||
stateUpdate._hoveredScrollbar = element._hoveredScrollbar
|
|
||||||
stateUpdate._scrollbarDragOffset = element._scrollbarDragOffset
|
|
||||||
-- Cursor blink state is stored in TextEditor instance
|
|
||||||
if element._textEditor then
|
|
||||||
stateUpdate._cursorBlinkTimer = element._textEditor._cursorBlinkTimer
|
|
||||||
stateUpdate._cursorVisible = element._textEditor._cursorVisible
|
|
||||||
stateUpdate._cursorBlinkPaused = element._textEditor._cursorBlinkPaused
|
|
||||||
stateUpdate._cursorBlinkPauseTimer = element._textEditor._cursorBlinkPauseTimer
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Track blur-related properties for cache invalidation
|
|
||||||
if element.backdropBlur or element.contentBlur then
|
|
||||||
stateUpdate._blurX = element.x
|
|
||||||
stateUpdate._blurY = element.y
|
|
||||||
stateUpdate._blurWidth = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
|
||||||
stateUpdate._blurHeight = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
|
||||||
if element.backdropBlur then
|
|
||||||
stateUpdate._backdropBlurIntensity = element.backdropBlur.intensity
|
|
||||||
stateUpdate._backdropBlurQuality = element.backdropBlur.quality
|
|
||||||
end
|
|
||||||
if element.contentBlur then
|
|
||||||
stateUpdate._contentBlurIntensity = element.contentBlur.intensity
|
|
||||||
stateUpdate._contentBlurQuality = element.contentBlur.quality
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Use optimized update that only changes modified values
|
-- Use optimized update that only changes modified values
|
||||||
-- Returns true if state was changed (meaning blur cache needs invalidation)
|
-- Returns true if state was changed (meaning blur cache needs invalidation)
|
||||||
local stateChanged = StateManager.updateStateIfChanged(element.id, stateUpdate)
|
local stateChanged = StateManager.updateStateIfChanged(element.id, stateUpdate)
|
||||||
@@ -757,22 +717,8 @@ function flexlove.update(dt)
|
|||||||
|
|
||||||
flexlove._activeEventElement = nil
|
flexlove._activeEventElement = nil
|
||||||
|
|
||||||
-- In immediate mode, save state after update so that cursor blink timer changes persist
|
-- Note: State saving happens in endFrame() after element:update() is called
|
||||||
if flexlove._immediateMode and flexlove._currentFrameElements then
|
-- This ensures all state changes (including cursor blink) are captured once per frame
|
||||||
for _, element in ipairs(flexlove._currentFrameElements) do
|
|
||||||
if element.id and element.id ~= "" and element.editable and element._focused and element._textEditor then
|
|
||||||
local state = StateManager.getState(element.id, {})
|
|
||||||
|
|
||||||
-- Save cursor blink state (updated during element:update())
|
|
||||||
state._cursorBlinkTimer = element._textEditor._cursorBlinkTimer
|
|
||||||
state._cursorVisible = element._textEditor._cursorVisible
|
|
||||||
state._cursorBlinkPaused = element._textEditor._cursorBlinkPaused
|
|
||||||
state._cursorBlinkPauseTimer = element._textEditor._cursorBlinkPauseTimer
|
|
||||||
|
|
||||||
StateManager.setState(element.id, state)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Internal GC management function (called from update)
|
--- Internal GC management function (called from update)
|
||||||
@@ -1065,69 +1011,35 @@ function flexlove.new(props)
|
|||||||
|
|
||||||
-- Inject scroll state into props BEFORE creating element
|
-- Inject scroll state into props BEFORE creating element
|
||||||
-- This ensures scroll position is set before layoutChildren/detectOverflow is called
|
-- This ensures scroll position is set before layoutChildren/detectOverflow is called
|
||||||
props._scrollX = state._scrollX or 0
|
-- ScrollManager state uses _scrollX/_scrollY with underscore prefix
|
||||||
props._scrollY = state._scrollY or 0
|
if state.scrollManager then
|
||||||
|
props._scrollX = state.scrollManager._scrollX or 0
|
||||||
|
props._scrollY = state.scrollManager._scrollY or 0
|
||||||
|
else
|
||||||
|
-- Fallback to old state structure for backward compatibility
|
||||||
|
props._scrollX = state._scrollX or 0
|
||||||
|
props._scrollY = state._scrollY or 0
|
||||||
|
end
|
||||||
|
|
||||||
local element = Element.new(props)
|
local element = Element.new(props)
|
||||||
|
|
||||||
-- Bind persistent state to element (ImmediateModeState)
|
-- Restore all state from StateManager (delegates to sub-modules)
|
||||||
-- Restore event handler state
|
element:restoreState(state)
|
||||||
if element._eventHandler then
|
|
||||||
element._eventHandler:setState(state)
|
|
||||||
end
|
|
||||||
element._focused = state._focused
|
|
||||||
element._focused = state._focused
|
|
||||||
element._cursorPosition = state._cursorPosition
|
|
||||||
element._selectionStart = state._selectionStart
|
|
||||||
element._selectionEnd = state._selectionEnd
|
|
||||||
element._textBuffer = state._textBuffer or element.text or ""
|
|
||||||
-- Note: scroll position already set from props during Element.new()
|
|
||||||
-- element._scrollX and element._scrollY already restored
|
|
||||||
element._scrollbarDragging = state._scrollbarDragging ~= nil and state._scrollbarDragging or false
|
|
||||||
element._hoveredScrollbar = state._hoveredScrollbar
|
|
||||||
element._scrollbarDragOffset = state._scrollbarDragOffset ~= nil and state._scrollbarDragOffset or 0
|
|
||||||
|
|
||||||
-- Sync scrollbar drag state to ScrollManager if it exists
|
|
||||||
if element._scrollManager then
|
|
||||||
element._scrollManager._scrollbarDragging = element._scrollbarDragging
|
|
||||||
element._scrollManager._hoveredScrollbar = element._hoveredScrollbar
|
|
||||||
element._scrollManager._scrollbarDragOffset = element._scrollbarDragOffset
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Restore cursor blink state (will be restored by TextEditor:restoreState() if element has _textEditor)
|
|
||||||
-- These are kept for backward compatibility but are no longer used directly on element
|
|
||||||
element._cursorBlinkTimer = state._cursorBlinkTimer or 0
|
|
||||||
element._cursorVisible = state._cursorVisible
|
|
||||||
element._cursorBlinkPaused = state._cursorBlinkPaused or false
|
|
||||||
element._cursorBlinkPauseTimer = state._cursorBlinkPauseTimer or 0
|
|
||||||
|
|
||||||
-- Bind element to StateManager for interactive states
|
-- Bind element to StateManager for interactive states
|
||||||
-- Use the same ID for StateManager so state persists across frames
|
|
||||||
element._stateId = props.id
|
element._stateId = props.id
|
||||||
|
|
||||||
-- Load interactive state from StateManager (already loaded in 'state' variable above)
|
|
||||||
element._scrollbarHoveredVertical = state.scrollbarHoveredVertical
|
|
||||||
element._scrollbarHoveredHorizontal = state.scrollbarHoveredHorizontal
|
|
||||||
element._scrollbarDragging = state.scrollbarDragging
|
|
||||||
element._hoveredScrollbar = state.hoveredScrollbar
|
|
||||||
element._scrollbarDragOffset = state.scrollbarDragOffset or 0
|
|
||||||
|
|
||||||
-- Sync interactive scroll state to ScrollManager if it exists
|
|
||||||
if element._scrollManager then
|
|
||||||
element._scrollManager._scrollbarHoveredVertical = element._scrollbarHoveredVertical or false
|
|
||||||
element._scrollManager._scrollbarHoveredHorizontal = element._scrollbarHoveredHorizontal or false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set initial theme state based on StateManager state
|
-- Set initial theme state based on StateManager state
|
||||||
-- This will be updated in Element:update() but we need an initial value
|
-- This will be updated in Element:update() but we need an initial value
|
||||||
if element.themeComponent then
|
if element.themeComponent then
|
||||||
if element.disabled or state.disabled then
|
local eventState = state.eventHandler or {}
|
||||||
|
if element.disabled or eventState.disabled then
|
||||||
element._themeState = "disabled"
|
element._themeState = "disabled"
|
||||||
elseif element.active or state.active then
|
elseif element.active or eventState.active then
|
||||||
element._themeState = "active"
|
element._themeState = "active"
|
||||||
elseif state.pressed then
|
elseif eventState._pressed and next(eventState._pressed) then
|
||||||
element._themeState = "pressed"
|
element._themeState = "pressed"
|
||||||
elseif state.hover then
|
elseif eventState._hovered then
|
||||||
element._themeState = "hover"
|
element._themeState = "hover"
|
||||||
else
|
else
|
||||||
element._themeState = "normal"
|
element._themeState = "normal"
|
||||||
|
|||||||
@@ -3160,6 +3160,110 @@ function Element:setProperty(property, value)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- ====================
|
||||||
|
-- State Persistence
|
||||||
|
-- ====================
|
||||||
|
|
||||||
|
--- Save all element state for immediate mode persistence
|
||||||
|
--- Collects state from all sub-modules and returns consolidated state
|
||||||
|
---@return ElementStateData state Complete state snapshot
|
||||||
|
function Element:saveState()
|
||||||
|
local state = {}
|
||||||
|
|
||||||
|
-- Element-owned state
|
||||||
|
state._focused = self._focused
|
||||||
|
|
||||||
|
-- EventHandler state (if exists)
|
||||||
|
if self._eventHandler then
|
||||||
|
state.eventHandler = self._eventHandler:getState()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TextEditor state (if exists)
|
||||||
|
if self._textEditor then
|
||||||
|
state.textEditor = self._textEditor:getState()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ScrollManager state (if exists)
|
||||||
|
if self._scrollManager then
|
||||||
|
state.scrollManager = self._scrollManager:getState()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Blur cache data (for cache invalidation)
|
||||||
|
if self.backdropBlur or self.contentBlur then
|
||||||
|
state.blur = {
|
||||||
|
_blurX = self.x,
|
||||||
|
_blurY = self.y,
|
||||||
|
_blurWidth = self._borderBoxWidth or (self.width + self.padding.left + self.padding.right),
|
||||||
|
_blurHeight = self._borderBoxHeight or (self.height + self.padding.top + self.padding.bottom),
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.backdropBlur then
|
||||||
|
state.blur._backdropBlurIntensity = self.backdropBlur.intensity
|
||||||
|
state.blur._backdropBlurQuality = self.backdropBlur.quality
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.contentBlur then
|
||||||
|
state.blur._contentBlurIntensity = self.contentBlur.intensity
|
||||||
|
state.blur._contentBlurQuality = self.contentBlur.quality
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return state
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Restore all element state from StateManager
|
||||||
|
--- Distributes state to all sub-modules
|
||||||
|
---@param state ElementStateData State to restore
|
||||||
|
function Element:restoreState(state)
|
||||||
|
if not state then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore element-owned state
|
||||||
|
if state._focused ~= nil then
|
||||||
|
self._focused = state._focused
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore EventHandler state (if exists)
|
||||||
|
if self._eventHandler and state.eventHandler then
|
||||||
|
self._eventHandler:setState(state.eventHandler)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore TextEditor state (if exists)
|
||||||
|
if self._textEditor and state.textEditor then
|
||||||
|
self._textEditor:setState(state.textEditor)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore ScrollManager state (if exists)
|
||||||
|
if self._scrollManager and state.scrollManager then
|
||||||
|
self._scrollManager:setState(state.scrollManager)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Note: Blur cache data is used for invalidation, not restoration
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if blur cache should be invalidated based on state changes
|
||||||
|
---@param oldState ElementStateData? Previous state
|
||||||
|
---@param newState ElementStateData Current state
|
||||||
|
---@return boolean shouldInvalidate True if blur cache should be cleared
|
||||||
|
function Element:shouldInvalidateBlurCache(oldState, newState)
|
||||||
|
if not oldState or not oldState.blur or not newState.blur then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local old = oldState.blur
|
||||||
|
local new = newState.blur
|
||||||
|
|
||||||
|
-- Check if any blur-related property changed
|
||||||
|
return old._blurX ~= new._blurX
|
||||||
|
or old._blurY ~= new._blurY
|
||||||
|
or old._blurWidth ~= new._blurWidth
|
||||||
|
or old._blurHeight ~= new._blurHeight
|
||||||
|
or old._backdropBlurIntensity ~= new._backdropBlurIntensity
|
||||||
|
or old._backdropBlurQuality ~= new._backdropBlurQuality
|
||||||
|
or old._contentBlurIntensity ~= new._contentBlurIntensity
|
||||||
|
or old._contentBlurQuality ~= new._contentBlurQuality
|
||||||
|
end
|
||||||
|
|
||||||
--- Cleanup method to break circular references (for immediate mode)
|
--- Cleanup method to break circular references (for immediate mode)
|
||||||
--- Note: Cleans internal module state but keeps structure for inspection
|
--- Note: Cleans internal module state but keeps structure for inspection
|
||||||
|
|||||||
@@ -617,11 +617,13 @@ end
|
|||||||
---@return table State data
|
---@return table State data
|
||||||
function ScrollManager:getState()
|
function ScrollManager:getState()
|
||||||
return {
|
return {
|
||||||
scrollX = self._scrollX,
|
_scrollX = self._scrollX or 0,
|
||||||
scrollY = self._scrollY,
|
_scrollY = self._scrollY or 0,
|
||||||
scrollbarDragging = self._scrollbarDragging,
|
_scrollbarDragging = self._scrollbarDragging or false,
|
||||||
hoveredScrollbar = self._hoveredScrollbar,
|
_hoveredScrollbar = self._hoveredScrollbar,
|
||||||
scrollbarDragOffset = self._scrollbarDragOffset,
|
_scrollbarDragOffset = self._scrollbarDragOffset or 0,
|
||||||
|
_scrollbarHoveredVertical = self._scrollbarHoveredVertical or false,
|
||||||
|
_scrollbarHoveredHorizontal = self._scrollbarHoveredHorizontal or false,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -632,21 +634,44 @@ function ScrollManager:setState(state)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if state.scrollX then
|
-- Support both old (scrollX) and new (_scrollX) field names for backward compatibility
|
||||||
|
if state._scrollX ~= nil then
|
||||||
|
self._scrollX = state._scrollX
|
||||||
|
elseif state.scrollX ~= nil then
|
||||||
self._scrollX = state.scrollX
|
self._scrollX = state.scrollX
|
||||||
end
|
end
|
||||||
if state.scrollY then
|
|
||||||
|
if state._scrollY ~= nil then
|
||||||
|
self._scrollY = state._scrollY
|
||||||
|
elseif state.scrollY ~= nil then
|
||||||
self._scrollY = state.scrollY
|
self._scrollY = state.scrollY
|
||||||
end
|
end
|
||||||
if state.scrollbarDragging ~= nil then
|
|
||||||
|
if state._scrollbarDragging ~= nil then
|
||||||
|
self._scrollbarDragging = state._scrollbarDragging
|
||||||
|
elseif state.scrollbarDragging ~= nil then
|
||||||
self._scrollbarDragging = state.scrollbarDragging
|
self._scrollbarDragging = state.scrollbarDragging
|
||||||
end
|
end
|
||||||
if state.hoveredScrollbar then
|
|
||||||
|
if state._hoveredScrollbar ~= nil then
|
||||||
|
self._hoveredScrollbar = state._hoveredScrollbar
|
||||||
|
elseif state.hoveredScrollbar ~= nil then
|
||||||
self._hoveredScrollbar = state.hoveredScrollbar
|
self._hoveredScrollbar = state.hoveredScrollbar
|
||||||
end
|
end
|
||||||
if state.scrollbarDragOffset then
|
|
||||||
|
if state._scrollbarDragOffset ~= nil then
|
||||||
|
self._scrollbarDragOffset = state._scrollbarDragOffset
|
||||||
|
elseif state.scrollbarDragOffset ~= nil then
|
||||||
self._scrollbarDragOffset = state.scrollbarDragOffset
|
self._scrollbarDragOffset = state.scrollbarDragOffset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if state._scrollbarHoveredVertical ~= nil then
|
||||||
|
self._scrollbarHoveredVertical = state._scrollbarHoveredVertical
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._scrollbarHoveredHorizontal ~= nil then
|
||||||
|
self._scrollbarHoveredHorizontal = state._scrollbarHoveredHorizontal
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Handle touch press for scrolling
|
--- Handle touch press for scrolling
|
||||||
|
|||||||
@@ -1681,6 +1681,66 @@ function TextEditor:_getFont(element)
|
|||||||
return element._renderer:getFont(element)
|
return element._renderer:getFont(element)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get current state for persistence
|
||||||
|
---@return table state TextEditor state snapshot
|
||||||
|
function TextEditor:getState()
|
||||||
|
return {
|
||||||
|
_cursorPosition = self._cursorPosition,
|
||||||
|
_selectionStart = self._selectionStart,
|
||||||
|
_selectionEnd = self._selectionEnd,
|
||||||
|
_textBuffer = self._textBuffer,
|
||||||
|
_cursorBlinkTimer = self._cursorBlinkTimer,
|
||||||
|
_cursorVisible = self._cursorVisible,
|
||||||
|
_cursorBlinkPaused = self._cursorBlinkPaused,
|
||||||
|
_cursorBlinkPauseTimer = self._cursorBlinkPauseTimer,
|
||||||
|
_focused = self._focused,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Restore state from persistence
|
||||||
|
---@param state table State to restore
|
||||||
|
function TextEditor:setState(state)
|
||||||
|
if not state then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._cursorPosition ~= nil then
|
||||||
|
self._cursorPosition = state._cursorPosition
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._selectionStart ~= nil then
|
||||||
|
self._selectionStart = state._selectionStart
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._selectionEnd ~= nil then
|
||||||
|
self._selectionEnd = state._selectionEnd
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._textBuffer ~= nil then
|
||||||
|
self._textBuffer = state._textBuffer
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._cursorBlinkTimer ~= nil then
|
||||||
|
self._cursorBlinkTimer = state._cursorBlinkTimer
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._cursorVisible ~= nil then
|
||||||
|
self._cursorVisible = state._cursorVisible
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._cursorBlinkPaused ~= nil then
|
||||||
|
self._cursorBlinkPaused = state._cursorBlinkPaused
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._cursorBlinkPauseTimer ~= nil then
|
||||||
|
self._cursorBlinkPauseTimer = state._cursorBlinkPauseTimer
|
||||||
|
end
|
||||||
|
|
||||||
|
if state._focused ~= nil then
|
||||||
|
self._focused = state._focused
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---Save state to StateManager (for immediate mode)
|
---Save state to StateManager (for immediate mode)
|
||||||
---@param element Element? The parent element
|
---@param element Element? The parent element
|
||||||
function TextEditor:_saveState(element)
|
function TextEditor:_saveState(element)
|
||||||
|
|||||||
@@ -187,3 +187,23 @@ local TransformProps
|
|||||||
---@field gcStepSize number? -- Work units per GC step, higher = more aggressive (default: 200)
|
---@field gcStepSize number? -- Work units per GC step, higher = more aggressive (default: 200)
|
||||||
---@field immediateModeBlurOptimizations boolean? -- Cache blur canvases in immediate mode to avoid re-rendering each frame (default: true)
|
---@field immediateModeBlurOptimizations boolean? -- Cache blur canvases in immediate mode to avoid re-rendering each frame (default: true)
|
||||||
local FlexLoveConfig = {}
|
local FlexLoveConfig = {}
|
||||||
|
|
||||||
|
--=====================================--
|
||||||
|
-- For State Persistence
|
||||||
|
--=====================================--
|
||||||
|
---@class ElementStateData
|
||||||
|
---@field _focused boolean?
|
||||||
|
---@field eventHandler table? -- EventHandler state
|
||||||
|
---@field textEditor table? -- TextEditor state
|
||||||
|
---@field scrollManager table? -- ScrollManager state
|
||||||
|
---@field blur BlurCacheData? -- Blur cache invalidation data
|
||||||
|
|
||||||
|
---@class BlurCacheData
|
||||||
|
---@field _blurX number
|
||||||
|
---@field _blurY number
|
||||||
|
---@field _blurWidth number
|
||||||
|
---@field _blurHeight number
|
||||||
|
---@field _backdropBlurIntensity number?
|
||||||
|
---@field _backdropBlurQuality string?
|
||||||
|
---@field _contentBlurIntensity number?
|
||||||
|
---@field _contentBlurQuality string?
|
||||||
|
|||||||
@@ -915,11 +915,11 @@ function TestScrollManagerEdgeCases:testGetState()
|
|||||||
sm._scrollbarDragOffset = 10
|
sm._scrollbarDragOffset = 10
|
||||||
|
|
||||||
local state = sm:getState()
|
local state = sm:getState()
|
||||||
luaunit.assertEquals(state.scrollX, 50)
|
luaunit.assertEquals(state._scrollX, 50)
|
||||||
luaunit.assertEquals(state.scrollY, 75)
|
luaunit.assertEquals(state._scrollY, 75)
|
||||||
luaunit.assertTrue(state.scrollbarDragging)
|
luaunit.assertTrue(state._scrollbarDragging)
|
||||||
luaunit.assertEquals(state.hoveredScrollbar, "vertical")
|
luaunit.assertEquals(state._hoveredScrollbar, "vertical")
|
||||||
luaunit.assertEquals(state.scrollbarDragOffset, 10)
|
luaunit.assertEquals(state._scrollbarDragOffset, 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
function TestScrollManagerEdgeCases:testSetStateWithNil()
|
function TestScrollManagerEdgeCases:testSetStateWithNil()
|
||||||
|
|||||||
Reference in New Issue
Block a user