scrolling fixed in immediate mode

This commit is contained in:
Michael Freno
2025-11-06 09:39:56 -05:00
parent f65d4b312b
commit 6a0fcfdfbd
2 changed files with 48 additions and 31 deletions

View File

@@ -178,7 +178,15 @@ function Gui.endFrame()
-- Sort elements by z-index for occlusion detection
GuiState.sortElementsByZIndex()
-- Auto-update all top-level elements (triggers layout calculation and overflow detection)
-- Layout all top-level elements now that all children have been added
-- This ensures overflow detection happens with complete child lists
for _, element in ipairs(Gui._currentFrameElements) do
if not element.parent then
element:layoutChildren() -- Layout with all children present
end
end
-- Auto-update all top-level elements (triggers additional state updates)
-- 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)
@@ -583,6 +591,11 @@ function Gui.new(props)
-- Mark state as used this frame
StateManager.markStateUsed(props.id)
-- Inject scroll state into props BEFORE creating element
-- This ensures scroll position is set before layoutChildren/detectOverflow is called
props._scrollX = state._scrollX or 0
props._scrollY = state._scrollY or 0
-- Create the element
local element = Element.new(props)
@@ -602,11 +615,11 @@ function Gui.new(props)
element._selectionStart = state._selectionStart
element._selectionEnd = state._selectionEnd
element._textBuffer = state._textBuffer or element.text or ""
element._scrollX = state._scrollX or element._scrollX or 0
element._scrollY = state._scrollY or element._scrollY or 0
element._scrollbarDragging = state._scrollbarDragging or false
-- 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 or 0
element._scrollbarDragOffset = state._scrollbarDragOffset ~= nil and state._scrollbarDragOffset or 0
-- Bind element to StateManager for interactive states
-- Use the same ID for StateManager so state persists across frames

View File

@@ -1165,9 +1165,9 @@ function Element.new(props)
self._contentWidth = 0
self._contentHeight = 0
-- Scroll state
self._scrollX = 0
self._scrollY = 0
-- Scroll state (can be restored from props in immediate mode)
self._scrollX = props._scrollX or 0
self._scrollY = props._scrollY or 0
self._maxScrollX = 0
self._maxScrollY = 0
@@ -1928,7 +1928,11 @@ function Element:addChild(child)
end
end
self:layoutChildren()
-- In immediate mode, defer layout until endFrame() when all elements are created
-- This prevents premature overflow detection with incomplete children
if not Gui._immediateMode then
self:layoutChildren()
end
end
--- Apply positioning offsets (top, right, bottom, left) to an element
@@ -3012,7 +3016,7 @@ function Element:update(dt)
-- and this is the topmost element at the mouse position (z-index ordering)
-- Exception: Allow drag continuation even if occluded (once drag starts, it continues)
local isDragging = false
for _, button in ipairs({1, 2, 3}) do
for _, button in ipairs({ 1, 2, 3 }) do
if self._pressed[button] and love.mouse.isDown(button) then
isDragging = true
break