fixed layout manager so that we know if size got manually changed

fixed scrollframe not sending scroll events to its children
fixed scrollframe scrolling even if mouse is not hovering over the element
improved the behaviour of the flow layout
This commit is contained in:
Robert Jelic
2025-11-03 13:29:11 +01:00
parent 250ce886ca
commit c723c66004
5 changed files with 221 additions and 31 deletions

View File

@@ -39,8 +39,24 @@ function flow.calculate(instance)
for i, child in ipairs(children) do
local childWidth = child.get("width")
local childHeight = child.get("height")
local layoutConfig = child.get("layoutConfig") or {}
if currentX + childWidth - 1 > containerWidth - padding and currentX > padding + 1 then
if child._userModified then
child._originalWidth = childWidth
child._originalHeight = childHeight
end
local basis = layoutConfig.basis
if not basis then
if not child._originalWidth then
child._originalWidth = childWidth
end
basis = child._originalWidth
end
local hasFlexConfig = layoutConfig.grow or layoutConfig.shrink or layoutConfig.basis
if currentX + basis - 1 > containerWidth - padding and currentX > padding + 1 then
table.insert(rows, {
children = currentRow,
@@ -57,10 +73,14 @@ function flow.calculate(instance)
table.insert(currentRow, {
child = child,
width = childWidth,
height = childHeight
height = childHeight,
basis = basis,
grow = layoutConfig.grow or 0,
shrink = layoutConfig.shrink or 1,
hasFlexConfig = hasFlexConfig
})
currentX = currentX + childWidth + spacing
currentX = currentX + basis + spacing
maxHeightInRow = math.max(maxHeightInRow, childHeight)
end
@@ -73,9 +93,39 @@ function flow.calculate(instance)
end
for _, row in ipairs(rows) do
local totalBasis = 0
local totalSpacing = (#row.children - 1) * spacing
local totalGrow = 0
local totalShrink = 0
for _, item in ipairs(row.children) do
totalBasis = totalBasis + item.basis
totalGrow = totalGrow + item.grow
totalShrink = totalShrink + item.shrink
end
local availableWidth = containerWidth - 2 * padding
local remainingSpace = availableWidth - totalBasis - totalSpacing
for _, item in ipairs(row.children) do
if remainingSpace > 0 and totalGrow > 0 then
local extraSpace = (remainingSpace * item.grow) / totalGrow
item.finalWidth = item.basis + extraSpace
elseif remainingSpace < 0 and totalShrink > 0 then
local reduceSpace = (-remainingSpace * item.shrink) / totalShrink
item.finalWidth = math.max(1, item.basis - reduceSpace)
else
item.finalWidth = item.basis
end
if not item.hasFlexConfig then
item.finalWidth = item.basis
end
end
local rowWidth = 0
for j, item in ipairs(row.children) do
rowWidth = rowWidth + item.width
rowWidth = rowWidth + item.finalWidth
if j < #row.children then
rowWidth = rowWidth + spacing
end
@@ -100,11 +150,11 @@ function flow.calculate(instance)
positions[item.child] = {
x = x,
y = y,
width = item.width,
width = math.floor(item.finalWidth),
height = item.height
}
x = x + item.width + spacing
x = x + math.floor(item.finalWidth) + spacing
end
end
@@ -118,8 +168,25 @@ function flow.calculate(instance)
for i, child in ipairs(children) do
local childWidth = child.get("width")
local childHeight = child.get("height")
local layoutConfig = child.get("layoutConfig") or {}
if currentY + childHeight - 1 > containerHeight - padding and currentY > padding + 1 then
-- If user modified the element, update the original size
if child._userModified then
child._originalWidth = childWidth
child._originalHeight = childHeight
end
local basis = layoutConfig.basis
if not basis then
if not child._originalHeight then
child._originalHeight = childHeight
end
basis = child._originalHeight
end
local hasFlexConfig = layoutConfig.grow or layoutConfig.shrink or layoutConfig.basis
if currentY + basis - 1 > containerHeight - padding and currentY > padding + 1 then
table.insert(columns, {
children = currentColumn,
x = currentX,
@@ -135,10 +202,14 @@ function flow.calculate(instance)
table.insert(currentColumn, {
child = child,
width = childWidth,
height = childHeight
height = childHeight,
basis = basis,
grow = layoutConfig.grow or 0,
shrink = layoutConfig.shrink or 1,
hasFlexConfig = hasFlexConfig
})
currentY = currentY + childHeight + spacing
currentY = currentY + basis + spacing
maxWidthInColumn = math.max(maxWidthInColumn, childWidth)
end
@@ -151,9 +222,39 @@ function flow.calculate(instance)
end
for _, column in ipairs(columns) do
local totalBasis = 0
local totalSpacing = (#column.children - 1) * spacing
local totalGrow = 0
local totalShrink = 0
for _, item in ipairs(column.children) do
totalBasis = totalBasis + item.basis
totalGrow = totalGrow + item.grow
totalShrink = totalShrink + item.shrink
end
local availableHeight = containerHeight - 2 * padding
local remainingSpace = availableHeight - totalBasis - totalSpacing
for _, item in ipairs(column.children) do
if remainingSpace > 0 and totalGrow > 0 then
local extraSpace = (remainingSpace * item.grow) / totalGrow
item.finalHeight = item.basis + extraSpace
elseif remainingSpace < 0 and totalShrink > 0 then
local reduceSpace = (-remainingSpace * item.shrink) / totalShrink
item.finalHeight = math.max(1, item.basis - reduceSpace)
else
item.finalHeight = item.basis
end
if not item.hasFlexConfig then
item.finalHeight = item.basis
end
end
local columnHeight = 0
for j, item in ipairs(column.children) do
columnHeight = columnHeight + item.height
columnHeight = columnHeight + item.finalHeight
if j < #column.children then
columnHeight = columnHeight + spacing
end
@@ -179,10 +280,10 @@ function flow.calculate(instance)
x = x,
y = y,
width = item.width,
height = item.height
height = math.floor(item.finalHeight)
}
y = y + item.height + spacing
y = y + math.floor(item.finalHeight) + spacing
end
end
end