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:
@@ -1,6 +1,7 @@
|
||||
local elementManager = require("elementManager")
|
||||
local errorManager = require("errorManager")
|
||||
local VisualElement = elementManager.getElement("VisualElement")
|
||||
local LayoutManager = require("layoutManager")
|
||||
local expect = require("libraries/expect")
|
||||
local split = require("libraries/utils").split
|
||||
---@configDescription The container class. It is a visual element that can contain other elements. It is the base class for all containers
|
||||
@@ -697,7 +698,6 @@ end
|
||||
--- @param options? table Optional layout-specific options
|
||||
--- @return Container self For method chaining
|
||||
function Container:applyLayout(layoutPath, options)
|
||||
local LayoutManager = require("layoutManager")
|
||||
|
||||
if self._layoutInstance then
|
||||
LayoutManager.destroy(self._layoutInstance)
|
||||
@@ -716,7 +716,6 @@ end
|
||||
--- @return Container self For method chaining
|
||||
function Container:updateLayout()
|
||||
if self._layoutInstance then
|
||||
local LayoutManager = require("layoutManager")
|
||||
LayoutManager.update(self._layoutInstance)
|
||||
end
|
||||
return self
|
||||
|
||||
@@ -320,20 +320,40 @@ end
|
||||
--- @return boolean Whether the event was handled
|
||||
--- @protected
|
||||
function ScrollFrame:mouse_scroll(direction, x, y)
|
||||
local height = self.get("height")
|
||||
local width = self.get("width")
|
||||
local offsetY = self.get("offsetY")
|
||||
local contentWidth = self.get("contentWidth")
|
||||
local contentHeight = self.get("contentHeight")
|
||||
if self:isInBounds(x, y) then
|
||||
local xOffset, yOffset = self.get("offsetX"), self.get("offsetY")
|
||||
local relX, relY = self:getRelativePosition(x + xOffset, y + yOffset)
|
||||
|
||||
local needsHorizontalScrollBar = self.get("showScrollBar") and contentWidth > width
|
||||
local viewportHeight = needsHorizontalScrollBar and height - 1 or height
|
||||
local maxScroll = math.max(0, contentHeight - viewportHeight)
|
||||
local success, child = self:callChildrenEvent(true, "mouse_scroll", direction, relX, relY)
|
||||
if success then
|
||||
return true
|
||||
end
|
||||
|
||||
local newScroll = math.min(maxScroll, math.max(0, offsetY + direction))
|
||||
self.set("offsetY", newScroll)
|
||||
local height = self.get("height")
|
||||
local width = self.get("width")
|
||||
local offsetY = self.get("offsetY")
|
||||
local offsetX = self.get("offsetX")
|
||||
local contentWidth = self.get("contentWidth")
|
||||
local contentHeight = self.get("contentHeight")
|
||||
|
||||
return true
|
||||
local needsHorizontalScrollBar = self.get("showScrollBar") and contentWidth > width
|
||||
local viewportHeight = needsHorizontalScrollBar and height - 1 or height
|
||||
local needsVerticalScrollBar = self.get("showScrollBar") and contentHeight > viewportHeight
|
||||
local viewportWidth = needsVerticalScrollBar and width - 1 or width
|
||||
|
||||
if needsVerticalScrollBar then
|
||||
local maxScroll = math.max(0, contentHeight - viewportHeight)
|
||||
local newScroll = math.min(maxScroll, math.max(0, offsetY + direction))
|
||||
self.set("offsetY", newScroll)
|
||||
elseif needsHorizontalScrollBar then
|
||||
local maxScroll = math.max(0, contentWidth - viewportWidth)
|
||||
local newScroll = math.min(maxScroll, math.max(0, offsetX + direction))
|
||||
self.set("offsetX", newScroll)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Renders the ScrollFrame and its scrollbars
|
||||
|
||||
@@ -64,6 +64,9 @@ end})
|
||||
---@property ignoreOffset boolean false Whether to ignore the parent's offset
|
||||
VisualElement.defineProperty(VisualElement, "ignoreOffset", {default = false, type = "boolean"})
|
||||
|
||||
---@property layoutConfig table {} Configuration for layout systems (grow, shrink, alignSelf, etc.)
|
||||
VisualElement.defineProperty(VisualElement, "layoutConfig", {default = {}, type = "table"})
|
||||
|
||||
---@combinedProperty position {x number, y number} Combined x, y position
|
||||
VisualElement.combineProperties(VisualElement, "position", "x", "y")
|
||||
---@combinedProperty size {width number, height number} Combined width, height
|
||||
@@ -178,6 +181,27 @@ function VisualElement:setConstraint(property, targetElement, targetProperty, of
|
||||
return self
|
||||
end
|
||||
|
||||
--- Updates a single property in the layoutConfig table
|
||||
--- @shortDescription Updates a single layout config property without replacing the entire table
|
||||
--- @param key string The layout config property to update (grow, shrink, basis, alignSelf, order, etc.)
|
||||
--- @param value any The value to set for the property
|
||||
--- @return VisualElement self The element instance
|
||||
function VisualElement:setLayoutConfigProperty(key, value)
|
||||
local layoutConfig = self.get("layoutConfig")
|
||||
layoutConfig[key] = value
|
||||
self.set("layoutConfig", layoutConfig)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets a single property from the layoutConfig table
|
||||
--- @shortDescription Gets a single layout config property
|
||||
--- @param key string The layout config property to get
|
||||
--- @return any value The value of the property, or nil if not set
|
||||
function VisualElement:getLayoutConfigProperty(key)
|
||||
local layoutConfig = self.get("layoutConfig")
|
||||
return layoutConfig[key]
|
||||
end
|
||||
|
||||
--- Resolves all constraints for the element
|
||||
--- @shortDescription Resolves all constraints for the element
|
||||
--- @return VisualElement self The element instance
|
||||
@@ -191,7 +215,7 @@ function VisualElement:resolveAllConstraints()
|
||||
for _, property in ipairs(order) do
|
||||
if constraints[property] then
|
||||
local value = self:_resolveConstraint(property, constraints[property])
|
||||
self:_applyConstraintValue(property, value)
|
||||
self:_applyConstraintValue(property, value, constraints)
|
||||
end
|
||||
end
|
||||
self._constraintsDirty = false
|
||||
@@ -200,17 +224,31 @@ end
|
||||
|
||||
--- Applies a resolved constraint value to the appropriate property
|
||||
--- @private
|
||||
function VisualElement:_applyConstraintValue(property, value)
|
||||
function VisualElement:_applyConstraintValue(property, value, constraints)
|
||||
if property == "x" or property == "left" then
|
||||
self.set("x", value)
|
||||
elseif property == "y" or property == "top" then
|
||||
self.set("y", value)
|
||||
elseif property == "right" then
|
||||
local width = self.get("width")
|
||||
self.set("x", value - width + 1)
|
||||
if constraints.left then
|
||||
local leftValue = self:_resolveConstraint("left", constraints.left)
|
||||
local width = value - leftValue + 1
|
||||
self.set("width", width)
|
||||
self.set("x", leftValue)
|
||||
else
|
||||
local width = self.get("width")
|
||||
self.set("x", value - width + 1)
|
||||
end
|
||||
elseif property == "bottom" then
|
||||
local height = self.get("height")
|
||||
self.set("y", value - height + 1)
|
||||
if constraints.top then
|
||||
local topValue = self:_resolveConstraint("top", constraints.top)
|
||||
local height = value - topValue + 1
|
||||
self.set("height", height)
|
||||
self.set("y", topValue)
|
||||
else
|
||||
local height = self.get("height")
|
||||
self.set("y", value - height + 1)
|
||||
end
|
||||
elseif property == "centerX" then
|
||||
local width = self.get("width")
|
||||
self.set("x", value - math.floor(width / 2))
|
||||
|
||||
@@ -58,14 +58,46 @@ function LayoutManager._applyPositions(instance)
|
||||
child.set("y", pos.y)
|
||||
child.set("width", pos.width)
|
||||
child.set("height", pos.height)
|
||||
child._layoutValues = {
|
||||
x = pos.x,
|
||||
y = pos.y,
|
||||
width = pos.width,
|
||||
height = pos.height
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Checks if a child's properties were changed by the user since last layout
|
||||
--- @param child BaseElement The child element to check
|
||||
--- @return boolean changed Whether the user changed x, y, width, or height
|
||||
--- @private
|
||||
function LayoutManager._wasChangedByUser(child)
|
||||
if not child._layoutValues then return false end
|
||||
|
||||
local currentX = child.get("x")
|
||||
local currentY = child.get("y")
|
||||
local currentWidth = child.get("width")
|
||||
local currentHeight = child.get("height")
|
||||
|
||||
return currentX ~= child._layoutValues.x or
|
||||
currentY ~= child._layoutValues.y or
|
||||
currentWidth ~= child._layoutValues.width or
|
||||
currentHeight ~= child._layoutValues.height
|
||||
end
|
||||
|
||||
--- Updates a layout instance (recalculates positions)
|
||||
--- @param instance table The layout instance
|
||||
function LayoutManager.update(instance)
|
||||
if instance and instance.layout and instance.layout.calculate then
|
||||
if instance._positions then
|
||||
for child, pos in pairs(instance._positions) do
|
||||
if not child._destroyed then
|
||||
child._userModified = LayoutManager._wasChangedByUser(child)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
instance.layout.calculate(instance)
|
||||
LayoutManager._applyPositions(instance)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user