checking logic

This commit is contained in:
Michael Freno
2025-10-31 12:18:39 -04:00
parent 9f215e252e
commit 747382614b

View File

@@ -814,7 +814,7 @@ function ImageCache.load(imagePath, loadImageData)
end end
local normalizedPath = normalizePath(imagePath) local normalizedPath = normalizePath(imagePath)
-- Check if already cached -- Check if already cached
if ImageCache._cache[normalizedPath] then if ImageCache._cache[normalizedPath] then
return ImageCache._cache[normalizedPath].image, nil return ImageCache._cache[normalizedPath].image, nil
@@ -840,7 +840,7 @@ function ImageCache.load(imagePath, loadImageData)
-- Cache the image -- Cache the image
ImageCache._cache[normalizedPath] = { ImageCache._cache[normalizedPath] = {
image = image, image = image,
imageData = imgData imageData = imgData,
} }
return image, nil return image, nil
@@ -927,7 +927,7 @@ function ImageCache.getStats()
return { return {
count = count, count = count,
memoryEstimate = memoryEstimate memoryEstimate = memoryEstimate,
} }
end end
@@ -957,16 +957,16 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
end end
local result = { local result = {
sx = 0, -- Source X sx = 0, -- Source X
sy = 0, -- Source Y sy = 0, -- Source Y
sw = imageWidth, -- Source width sw = imageWidth, -- Source width
sh = imageHeight, -- Source height sh = imageHeight, -- Source height
dx = 0, -- Destination X dx = 0, -- Destination X
dy = 0, -- Destination Y dy = 0, -- Destination Y
dw = boundsWidth, -- Destination width dw = boundsWidth, -- Destination width
dh = boundsHeight, -- Destination height dh = boundsHeight, -- Destination height
scaleX = 1, -- Scale factor X scaleX = 1, -- Scale factor X
scaleY = 1 -- Scale factor Y scaleY = 1, -- Scale factor Y
} }
-- Calculate based on fit mode -- Calculate based on fit mode
@@ -976,7 +976,6 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
result.scaleY = boundsHeight / imageHeight result.scaleY = boundsHeight / imageHeight
result.dw = boundsWidth result.dw = boundsWidth
result.dh = boundsHeight result.dh = boundsHeight
elseif fitMode == "contain" then elseif fitMode == "contain" then
-- Scale to fit within bounds (preserves aspect ratio) -- Scale to fit within bounds (preserves aspect ratio)
local scale = math.min(boundsWidth / imageWidth, boundsHeight / imageHeight) local scale = math.min(boundsWidth / imageWidth, boundsHeight / imageHeight)
@@ -989,19 +988,18 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
local posX, posY = ImageRenderer._parsePosition(objectPosition) local posX, posY = ImageRenderer._parsePosition(objectPosition)
result.dx = (boundsWidth - result.dw) * posX result.dx = (boundsWidth - result.dw) * posX
result.dy = (boundsHeight - result.dh) * posY result.dy = (boundsHeight - result.dh) * posY
elseif fitMode == "cover" then elseif fitMode == "cover" then
-- Scale to cover bounds (preserves aspect ratio, may crop) -- Scale to cover bounds (preserves aspect ratio, may crop)
local scale = math.max(boundsWidth / imageWidth, boundsHeight / imageHeight) local scale = math.max(boundsWidth / imageWidth, boundsHeight / imageHeight)
result.scaleX = scale result.scaleX = scale
result.scaleY = scale result.scaleY = scale
local scaledWidth = imageWidth * scale local scaledWidth = imageWidth * scale
local scaledHeight = imageHeight * scale local scaledHeight = imageHeight * scale
-- Apply object-position for crop alignment -- Apply object-position for crop alignment
local posX, posY = ImageRenderer._parsePosition(objectPosition) local posX, posY = ImageRenderer._parsePosition(objectPosition)
-- Calculate which part of the scaled image to show -- Calculate which part of the scaled image to show
local cropX = (scaledWidth - boundsWidth) * posX local cropX = (scaledWidth - boundsWidth) * posX
local cropY = (scaledHeight - boundsHeight) * posY local cropY = (scaledHeight - boundsHeight) * posY
@@ -1011,12 +1009,11 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
result.sy = cropY / scale result.sy = cropY / scale
result.sw = boundsWidth / scale result.sw = boundsWidth / scale
result.sh = boundsHeight / scale result.sh = boundsHeight / scale
result.dx = 0 result.dx = 0
result.dy = 0 result.dy = 0
result.dw = boundsWidth result.dw = boundsWidth
result.dh = boundsHeight result.dh = boundsHeight
elseif fitMode == "none" then elseif fitMode == "none" then
-- Use natural size (no scaling) -- Use natural size (no scaling)
result.scaleX = 1 result.scaleX = 1
@@ -1028,7 +1025,6 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
local posX, posY = ImageRenderer._parsePosition(objectPosition) local posX, posY = ImageRenderer._parsePosition(objectPosition)
result.dx = (boundsWidth - imageWidth) * posX result.dx = (boundsWidth - imageWidth) * posX
result.dy = (boundsHeight - imageHeight) * posY result.dy = (boundsHeight - imageHeight) * posY
elseif fitMode == "scale-down" then elseif fitMode == "scale-down" then
-- Use none or contain, whichever is smaller -- Use none or contain, whichever is smaller
if imageWidth <= boundsWidth and imageHeight <= boundsHeight then if imageWidth <= boundsWidth and imageHeight <= boundsHeight then
@@ -1038,7 +1034,6 @@ function ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, bounds
-- Image too large, use "contain" -- Image too large, use "contain"
return ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, boundsHeight, "contain", objectPosition) return ImageRenderer.calculateFit(imageWidth, imageHeight, boundsWidth, boundsHeight, "contain", objectPosition)
end end
else else
error(formatError("ImageRenderer", string.format("Invalid fit mode: '%s'. Must be one of: fill, contain, cover, scale-down, none", tostring(fitMode)))) error(formatError("ImageRenderer", string.format("Invalid fit mode: '%s'. Must be one of: fill, contain, cover, scale-down, none", tostring(fitMode))))
end end
@@ -1065,11 +1060,11 @@ function ImageRenderer._parsePosition(position)
if #parts == 1 then if #parts == 1 then
local val = parts[1] local val = parts[1]
if val == "left" or val == "right" then if val == "left" or val == "right" then
parts = {val, "center"} parts = { val, "center" }
elseif val == "top" or val == "bottom" then elseif val == "top" or val == "bottom" then
parts = {"center", val} parts = { "center", val }
else else
parts = {val, val} parts = { val, val }
end end
elseif #parts == 0 then elseif #parts == 0 then
return 0.5, 0.5 -- Default to center return 0.5, 0.5 -- Default to center
@@ -1077,9 +1072,12 @@ function ImageRenderer._parsePosition(position)
local function parseValue(val) local function parseValue(val)
-- Handle keywords -- Handle keywords
if val == "center" then return 0.5 if val == "center" then
elseif val == "left" or val == "top" then return 0 return 0.5
elseif val == "right" or val == "bottom" then return 1 elseif val == "left" or val == "top" then
return 0
elseif val == "right" or val == "bottom" then
return 1
end end
-- Handle percentages -- Handle percentages
@@ -2340,6 +2338,29 @@ function Gui.init(config)
end end
end end
--- Check for Z-index coverage (occlusion)
---@param elem Element
---@param clickX number
---@param clickY number
---@return boolean
function Gui.isOccluded(elem, clickX, clickY)
for _, element in ipairs(Gui.topElements) do
if element.z > elem.z and element:contains(clickX, clickY) then
return true
end
--TODO: check if walking the children tree is necessary here - might only need to check for absolute positioned
--children
for _, child in ipairs(element.children) do
if child.positioning == "absolute" then
if child.z > elem.z and child:contains(clickX, clickY) then
return true
end
end
end
end
return false
end
--- Get current scale factors --- Get current scale factors
---@return number, number -- scaleX, scaleY ---@return number, number -- scaleX, scaleY
function Gui.getScaleFactors() function Gui.getScaleFactors()
@@ -2398,7 +2419,7 @@ Gui._canvasDimensions = { width = 0, height = 0 }
function Gui.draw(gameDrawFunc, postDrawFunc) function Gui.draw(gameDrawFunc, postDrawFunc)
-- Save the current canvas state to support nested rendering -- Save the current canvas state to support nested rendering
local outerCanvas = love.graphics.getCanvas() local outerCanvas = love.graphics.getCanvas()
local gameCanvas = nil local gameCanvas = nil
-- Render game content to a canvas if function provided -- Render game content to a canvas if function provided
@@ -2414,7 +2435,7 @@ function Gui.draw(gameDrawFunc, postDrawFunc)
end end
gameCanvas = Gui._gameCanvas gameCanvas = Gui._gameCanvas
love.graphics.setCanvas(gameCanvas) love.graphics.setCanvas(gameCanvas)
love.graphics.clear() love.graphics.clear()
gameDrawFunc() -- Call the drawing function gameDrawFunc() -- Call the drawing function
@@ -2574,39 +2595,40 @@ end
function Gui.wheelmoved(x, y) function Gui.wheelmoved(x, y)
-- Get mouse position -- Get mouse position
local mx, my = love.mouse.getPosition() local mx, my = love.mouse.getPosition()
-- Find the deepest scrollable element at mouse position -- Find the deepest scrollable element at mouse position
local function findScrollableAtPosition(elements, mx, my) local function findScrollableAtPosition(elements, mx, my)
-- Check in reverse z-order (top to bottom) -- Check in reverse z-order (top to bottom)
for i = #elements, 1, -1 do for i = #elements, 1, -1 do
local element = elements[i] local element = elements[i]
-- Check if mouse is over element -- Check if mouse is over element
local bx = element.x local bx = element.x
local by = element.y local by = element.y
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right) local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom) local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
if mx >= bx and mx <= bx + bw and my >= by and my <= by + bh then if mx >= bx and mx <= bx + bw and my >= by and my <= by + bh then
-- Check children first (depth-first) -- Check children first (depth-first)
if #element.children > 0 then if #element.children > 0 then
local childResult = findScrollableAtPosition(element.children, mx, my) local childResult = findScrollableAtPosition(element.children, mx, my)
if childResult then return childResult end if childResult then
return childResult
end
end end
-- Check if this element is scrollable -- Check if this element is scrollable
local overflowX = element.overflowX or element.overflow local overflowX = element.overflowX or element.overflow
local overflowY = element.overflowY or element.overflow local overflowY = element.overflowY or element.overflow
if (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") and if (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") and (element._overflowX or element._overflowY) then
(element._overflowX or element._overflowY) then
return element return element
end end
end end
end end
return nil return nil
end end
local scrollableElement = findScrollableAtPosition(Gui.topElements, mx, my) local scrollableElement = findScrollableAtPosition(Gui.topElements, mx, my)
if scrollableElement then if scrollableElement then
scrollableElement:_handleWheelScroll(x, y) scrollableElement:_handleWheelScroll(x, y)
@@ -3195,7 +3217,7 @@ function Element.new(props)
self._lastClickButton = nil self._lastClickButton = nil
self._clickCount = 0 self._clickCount = 0
self._touchPressed = {} self._touchPressed = {}
-- Initialize drag tracking for event system -- Initialize drag tracking for event system
self._dragStartX = {} -- Track drag start X position per mouse button self._dragStartX = {} -- Track drag start X position per mouse button
self._dragStartY = {} -- Track drag start Y position per mouse button self._dragStartY = {} -- Track drag start Y position per mouse button
@@ -3378,7 +3400,7 @@ function Element.new(props)
self.objectFit = props.objectFit or "fill" self.objectFit = props.objectFit or "fill"
self.objectPosition = props.objectPosition or "center center" self.objectPosition = props.objectPosition or "center center"
self.imageOpacity = props.imageOpacity or 1 self.imageOpacity = props.imageOpacity or 1
-- Auto-load image if imagePath is provided -- Auto-load image if imagePath is provided
if self.imagePath and not self.image then if self.imagePath and not self.image then
local loadedImage, err = ImageCache.load(self.imagePath) local loadedImage, err = ImageCache.load(self.imagePath)
@@ -4118,7 +4140,7 @@ function Element.new(props)
self.overflow = props.overflow or "visible" self.overflow = props.overflow or "visible"
self.overflowX = props.overflowX self.overflowX = props.overflowX
self.overflowY = props.overflowY self.overflowY = props.overflowY
-- Scrollbar configuration -- Scrollbar configuration
self.scrollbarWidth = props.scrollbarWidth or 12 self.scrollbarWidth = props.scrollbarWidth or 12
self.scrollbarColor = props.scrollbarColor or Color.new(0.5, 0.5, 0.5, 0.8) self.scrollbarColor = props.scrollbarColor or Color.new(0.5, 0.5, 0.5, 0.8)
@@ -4126,24 +4148,24 @@ function Element.new(props)
self.scrollbarRadius = props.scrollbarRadius or 6 self.scrollbarRadius = props.scrollbarRadius or 6
self.scrollbarPadding = props.scrollbarPadding or 2 self.scrollbarPadding = props.scrollbarPadding or 2
self.scrollSpeed = props.scrollSpeed or 20 self.scrollSpeed = props.scrollSpeed or 20
-- Internal overflow state -- Internal overflow state
self._overflowX = false self._overflowX = false
self._overflowY = false self._overflowY = false
self._contentWidth = 0 self._contentWidth = 0
self._contentHeight = 0 self._contentHeight = 0
-- Scroll state -- Scroll state
self._scrollX = 0 self._scrollX = 0
self._scrollY = 0 self._scrollY = 0
self._maxScrollX = 0 self._maxScrollX = 0
self._maxScrollY = 0 self._maxScrollY = 0
-- Scrollbar interaction state -- Scrollbar interaction state
self._scrollbarHovered = false self._scrollbarHovered = false
self._scrollbarDragging = false self._scrollbarDragging = false
self._hoveredScrollbar = nil -- "vertical" or "horizontal" self._hoveredScrollbar = nil -- "vertical" or "horizontal"
self._scrollbarDragOffset = 0 -- Offset from thumb top when drag started self._scrollbarDragOffset = 0 -- Offset from thumb top when drag started
return self return self
end end
@@ -4154,6 +4176,15 @@ function Element:getBounds()
return { x = self.x, y = self.y, width = self:getBorderBoxWidth(), height = self:getBorderBoxHeight() } return { x = self.x, y = self.y, width = self:getBorderBoxWidth(), height = self:getBorderBoxHeight() }
end end
--- Check if point is inside element bounds
--- @param x number
--- @param y number
--- @return boolean
function Element:contains(x, y)
local bounds = self:getBounds()
return bounds.x <= x and bounds.y <= y and bounds.x + bounds.width >= x and bounds.y + bounds.height >= y
end
--- Get border-box width (including padding) --- Get border-box width (including padding)
---@return number ---@return number
function Element:getBorderBoxWidth() function Element:getBorderBoxWidth()
@@ -4173,22 +4204,22 @@ function Element:_detectOverflow()
self._overflowY = false self._overflowY = false
self._contentWidth = self.width self._contentWidth = self.width
self._contentHeight = self.height self._contentHeight = self.height
-- Skip detection if overflow is visible (no clipping needed) -- Skip detection if overflow is visible (no clipping needed)
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
if overflowX == "visible" and overflowY == "visible" then if overflowX == "visible" and overflowY == "visible" then
return return
end end
-- Calculate content bounds based on children -- Calculate content bounds based on children
if #self.children == 0 then if #self.children == 0 then
return -- No children, no overflow return -- No children, no overflow
end end
local minX, minY = math.huge, math.huge local minX, minY = math.huge, math.huge
local maxX, maxY = -math.huge, -math.huge local maxX, maxY = -math.huge, -math.huge
for _, child in ipairs(self.children) do for _, child in ipairs(self.children) do
-- Skip absolutely positioned children (they don't contribute to overflow) -- Skip absolutely positioned children (they don't contribute to overflow)
if not child._explicitlyAbsolute then if not child._explicitlyAbsolute then
@@ -4196,34 +4227,34 @@ function Element:_detectOverflow()
local childTop = child.y - self.y local childTop = child.y - self.y
local childRight = childLeft + child:getBorderBoxWidth() + child.margin.left + child.margin.right local childRight = childLeft + child:getBorderBoxWidth() + child.margin.left + child.margin.right
local childBottom = childTop + child:getBorderBoxHeight() + child.margin.top + child.margin.bottom local childBottom = childTop + child:getBorderBoxHeight() + child.margin.top + child.margin.bottom
minX = math.min(minX, childLeft) minX = math.min(minX, childLeft)
minY = math.min(minY, childTop) minY = math.min(minY, childTop)
maxX = math.max(maxX, childRight) maxX = math.max(maxX, childRight)
maxY = math.max(maxY, childBottom) maxY = math.max(maxY, childBottom)
end end
end end
-- If no non-absolute children, no overflow -- If no non-absolute children, no overflow
if minX == math.huge then if minX == math.huge then
return return
end end
-- Calculate content dimensions -- Calculate content dimensions
self._contentWidth = math.max(0, maxX - minX) self._contentWidth = math.max(0, maxX - minX)
self._contentHeight = math.max(0, maxY - minY) self._contentHeight = math.max(0, maxY - minY)
-- Detect overflow -- Detect overflow
local containerWidth = self.width local containerWidth = self.width
local containerHeight = self.height local containerHeight = self.height
self._overflowX = self._contentWidth > containerWidth self._overflowX = self._contentWidth > containerWidth
self._overflowY = self._contentHeight > containerHeight self._overflowY = self._contentHeight > containerHeight
-- Calculate maximum scroll bounds -- Calculate maximum scroll bounds
self._maxScrollX = math.max(0, self._contentWidth - containerWidth) self._maxScrollX = math.max(0, self._contentWidth - containerWidth)
self._maxScrollY = math.max(0, self._contentHeight - containerHeight) self._maxScrollY = math.max(0, self._contentHeight - containerHeight)
-- Clamp current scroll position to new bounds -- Clamp current scroll position to new bounds
self._scrollX = math.max(0, math.min(self._scrollX, self._maxScrollX)) self._scrollX = math.max(0, math.min(self._scrollX, self._maxScrollX))
self._scrollY = math.max(0, math.min(self._scrollY, self._maxScrollY)) self._scrollY = math.max(0, math.min(self._scrollY, self._maxScrollY))
@@ -4246,21 +4277,21 @@ end
function Element:_calculateScrollbarDimensions() function Element:_calculateScrollbarDimensions()
local result = { local result = {
vertical = { visible = false, trackHeight = 0, thumbHeight = 0, thumbY = 0 }, vertical = { visible = false, trackHeight = 0, thumbHeight = 0, thumbY = 0 },
horizontal = { visible = false, trackWidth = 0, thumbWidth = 0, thumbX = 0 } horizontal = { visible = false, trackWidth = 0, thumbWidth = 0, thumbX = 0 },
} }
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
-- Vertical scrollbar -- Vertical scrollbar
if self._overflowY and (overflowY == "scroll" or overflowY == "auto") then if self._overflowY and (overflowY == "scroll" or overflowY == "auto") then
result.vertical.visible = true result.vertical.visible = true
result.vertical.trackHeight = self.height - (self.scrollbarPadding * 2) result.vertical.trackHeight = self.height - (self.scrollbarPadding * 2)
-- Calculate thumb height based on content ratio -- Calculate thumb height based on content ratio
local contentRatio = self.height / math.max(self._contentHeight, self.height) local contentRatio = self.height / math.max(self._contentHeight, self.height)
result.vertical.thumbHeight = math.max(20, result.vertical.trackHeight * contentRatio) result.vertical.thumbHeight = math.max(20, result.vertical.trackHeight * contentRatio)
-- Calculate thumb position based on scroll ratio -- Calculate thumb position based on scroll ratio
local scrollRatio = self._maxScrollY > 0 and (self._scrollY / self._maxScrollY) or 0 local scrollRatio = self._maxScrollY > 0 and (self._scrollY / self._maxScrollY) or 0
local maxThumbY = result.vertical.trackHeight - result.vertical.thumbHeight local maxThumbY = result.vertical.trackHeight - result.vertical.thumbHeight
@@ -4272,16 +4303,16 @@ function Element:_calculateScrollbarDimensions()
result.vertical.thumbHeight = result.vertical.trackHeight result.vertical.thumbHeight = result.vertical.trackHeight
result.vertical.thumbY = 0 result.vertical.thumbY = 0
end end
-- Horizontal scrollbar -- Horizontal scrollbar
if self._overflowX and (overflowX == "scroll" or overflowX == "auto") then if self._overflowX and (overflowX == "scroll" or overflowX == "auto") then
result.horizontal.visible = true result.horizontal.visible = true
result.horizontal.trackWidth = self.width - (self.scrollbarPadding * 2) result.horizontal.trackWidth = self.width - (self.scrollbarPadding * 2)
-- Calculate thumb width based on content ratio -- Calculate thumb width based on content ratio
local contentRatio = self.width / math.max(self._contentWidth, self.width) local contentRatio = self.width / math.max(self._contentWidth, self.width)
result.horizontal.thumbWidth = math.max(20, result.horizontal.trackWidth * contentRatio) result.horizontal.thumbWidth = math.max(20, result.horizontal.trackWidth * contentRatio)
-- Calculate thumb position based on scroll ratio -- Calculate thumb position based on scroll ratio
local scrollRatio = self._maxScrollX > 0 and (self._scrollX / self._maxScrollX) or 0 local scrollRatio = self._maxScrollX > 0 and (self._scrollX / self._maxScrollX) or 0
local maxThumbX = result.horizontal.trackWidth - result.horizontal.thumbWidth local maxThumbX = result.horizontal.trackWidth - result.horizontal.thumbWidth
@@ -4293,7 +4324,7 @@ function Element:_calculateScrollbarDimensions()
result.horizontal.thumbWidth = result.horizontal.trackWidth result.horizontal.thumbWidth = result.horizontal.trackWidth
result.horizontal.thumbX = 0 result.horizontal.thumbX = 0
end end
return result return result
end end
@@ -4302,59 +4333,45 @@ end
function Element:_drawScrollbars(dims) function Element:_drawScrollbars(dims)
local x, y = self.x, self.y local x, y = self.x, self.y
local w, h = self.width, self.height local w, h = self.width, self.height
-- Determine thumb color based on state -- Determine thumb color based on state
local thumbColor = self.scrollbarColor local thumbColor = self.scrollbarColor
if self._scrollbarDragging then if self._scrollbarDragging then
-- Active state: brighter -- Active state: brighter
thumbColor = Color.new( thumbColor = Color.new(math.min(1, thumbColor.r * 1.4), math.min(1, thumbColor.g * 1.4), math.min(1, thumbColor.b * 1.4), thumbColor.a)
math.min(1, thumbColor.r * 1.4),
math.min(1, thumbColor.g * 1.4),
math.min(1, thumbColor.b * 1.4),
thumbColor.a
)
elseif self._scrollbarHovered then elseif self._scrollbarHovered then
-- Hover state: slightly brighter -- Hover state: slightly brighter
thumbColor = Color.new( thumbColor = Color.new(math.min(1, thumbColor.r * 1.2), math.min(1, thumbColor.g * 1.2), math.min(1, thumbColor.b * 1.2), thumbColor.a)
math.min(1, thumbColor.r * 1.2),
math.min(1, thumbColor.g * 1.2),
math.min(1, thumbColor.b * 1.2),
thumbColor.a
)
end end
-- Vertical scrollbar -- Vertical scrollbar
if dims.vertical.visible then if dims.vertical.visible then
local trackX = x + w - self.scrollbarWidth - self.scrollbarPadding + self.padding.left local trackX = x + w - self.scrollbarWidth - self.scrollbarPadding + self.padding.left
local trackY = y + self.scrollbarPadding + self.padding.top local trackY = y + self.scrollbarPadding + self.padding.top
-- Draw track -- Draw track
love.graphics.setColor(self.scrollbarTrackColor:toRGBA()) love.graphics.setColor(self.scrollbarTrackColor:toRGBA())
love.graphics.rectangle("fill", trackX, trackY, love.graphics.rectangle("fill", trackX, trackY, self.scrollbarWidth, dims.vertical.trackHeight, self.scrollbarRadius)
self.scrollbarWidth, dims.vertical.trackHeight, self.scrollbarRadius)
-- Draw thumb with state-based color -- Draw thumb with state-based color
love.graphics.setColor(thumbColor:toRGBA()) love.graphics.setColor(thumbColor:toRGBA())
love.graphics.rectangle("fill", trackX, trackY + dims.vertical.thumbY, love.graphics.rectangle("fill", trackX, trackY + dims.vertical.thumbY, self.scrollbarWidth, dims.vertical.thumbHeight, self.scrollbarRadius)
self.scrollbarWidth, dims.vertical.thumbHeight, self.scrollbarRadius)
end end
-- Horizontal scrollbar -- Horizontal scrollbar
if dims.horizontal.visible then if dims.horizontal.visible then
local trackX = x + self.scrollbarPadding + self.padding.left local trackX = x + self.scrollbarPadding + self.padding.left
local trackY = y + h - self.scrollbarWidth - self.scrollbarPadding + self.padding.top local trackY = y + h - self.scrollbarWidth - self.scrollbarPadding + self.padding.top
-- Draw track -- Draw track
love.graphics.setColor(self.scrollbarTrackColor:toRGBA()) love.graphics.setColor(self.scrollbarTrackColor:toRGBA())
love.graphics.rectangle("fill", trackX, trackY, love.graphics.rectangle("fill", trackX, trackY, dims.horizontal.trackWidth, self.scrollbarWidth, self.scrollbarRadius)
dims.horizontal.trackWidth, self.scrollbarWidth, self.scrollbarRadius)
-- Draw thumb with state-based color -- Draw thumb with state-based color
love.graphics.setColor(thumbColor:toRGBA()) love.graphics.setColor(thumbColor:toRGBA())
love.graphics.rectangle("fill", trackX + dims.horizontal.thumbX, trackY, love.graphics.rectangle("fill", trackX + dims.horizontal.thumbX, trackY, dims.horizontal.thumbWidth, self.scrollbarWidth, self.scrollbarRadius)
dims.horizontal.thumbWidth, self.scrollbarWidth, self.scrollbarRadius)
end end
-- Reset color -- Reset color
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
end end
@@ -4366,24 +4383,23 @@ end
function Element:_getScrollbarAtPosition(mouseX, mouseY) function Element:_getScrollbarAtPosition(mouseX, mouseY)
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
if not (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") then if not (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") then
return nil return nil
end end
local dims = self:_calculateScrollbarDimensions() local dims = self:_calculateScrollbarDimensions()
local x, y = self.x, self.y local x, y = self.x, self.y
local w, h = self.width, self.height local w, h = self.width, self.height
-- Check vertical scrollbar -- Check vertical scrollbar
if dims.vertical.visible then if dims.vertical.visible then
local trackX = x + w - self.scrollbarWidth - self.scrollbarPadding + self.padding.left local trackX = x + w - self.scrollbarWidth - self.scrollbarPadding + self.padding.left
local trackY = y + self.scrollbarPadding + self.padding.top local trackY = y + self.scrollbarPadding + self.padding.top
local trackW = self.scrollbarWidth local trackW = self.scrollbarWidth
local trackH = dims.vertical.trackHeight local trackH = dims.vertical.trackHeight
if mouseX >= trackX and mouseX <= trackX + trackW and if mouseX >= trackX and mouseX <= trackX + trackW and mouseY >= trackY and mouseY <= trackY + trackH then
mouseY >= trackY and mouseY <= trackY + trackH then
-- Check if over thumb -- Check if over thumb
local thumbY = trackY + dims.vertical.thumbY local thumbY = trackY + dims.vertical.thumbY
local thumbH = dims.vertical.thumbHeight local thumbH = dims.vertical.thumbHeight
@@ -4394,16 +4410,15 @@ function Element:_getScrollbarAtPosition(mouseX, mouseY)
end end
end end
end end
-- Check horizontal scrollbar -- Check horizontal scrollbar
if dims.horizontal.visible then if dims.horizontal.visible then
local trackX = x + self.scrollbarPadding + self.padding.left local trackX = x + self.scrollbarPadding + self.padding.left
local trackY = y + h - self.scrollbarWidth - self.scrollbarPadding + self.padding.top local trackY = y + h - self.scrollbarWidth - self.scrollbarPadding + self.padding.top
local trackW = dims.horizontal.trackWidth local trackW = dims.horizontal.trackWidth
local trackH = self.scrollbarWidth local trackH = self.scrollbarWidth
if mouseX >= trackX and mouseX <= trackX + trackW and if mouseX >= trackX and mouseX <= trackX + trackW and mouseY >= trackY and mouseY <= trackY + trackH then
mouseY >= trackY and mouseY <= trackY + trackH then
-- Check if over thumb -- Check if over thumb
local thumbX = trackX + dims.horizontal.thumbX local thumbX = trackX + dims.horizontal.thumbX
local thumbW = dims.horizontal.thumbWidth local thumbW = dims.horizontal.thumbWidth
@@ -4414,7 +4429,7 @@ function Element:_getScrollbarAtPosition(mouseX, mouseY)
end end
end end
end end
return nil return nil
end end
@@ -4424,17 +4439,21 @@ end
---@param button number ---@param button number
---@return boolean -- True if event was consumed ---@return boolean -- True if event was consumed
function Element:_handleScrollbarPress(mouseX, mouseY, button) function Element:_handleScrollbarPress(mouseX, mouseY, button)
if button ~= 1 then return false end -- Only left click if button ~= 1 then
return false
end -- Only left click
local scrollbar = self:_getScrollbarAtPosition(mouseX, mouseY) local scrollbar = self:_getScrollbarAtPosition(mouseX, mouseY)
if not scrollbar then return false end if not scrollbar then
return false
end
if scrollbar.region == "thumb" then if scrollbar.region == "thumb" then
-- Start dragging thumb -- Start dragging thumb
self._scrollbarDragging = true self._scrollbarDragging = true
self._hoveredScrollbar = scrollbar.component self._hoveredScrollbar = scrollbar.component
local dims = self:_calculateScrollbarDimensions() local dims = self:_calculateScrollbarDimensions()
if scrollbar.component == "vertical" then if scrollbar.component == "vertical" then
local trackY = self.y + self.scrollbarPadding + self.padding.top local trackY = self.y + self.scrollbarPadding + self.padding.top
local thumbY = trackY + dims.vertical.thumbY local thumbY = trackY + dims.vertical.thumbY
@@ -4444,15 +4463,14 @@ function Element:_handleScrollbarPress(mouseX, mouseY, button)
local thumbX = trackX + dims.horizontal.thumbX local thumbX = trackX + dims.horizontal.thumbX
self._scrollbarDragOffset = mouseX - thumbX self._scrollbarDragOffset = mouseX - thumbX
end end
return true -- Event consumed return true -- Event consumed
elseif scrollbar.region == "track" then elseif scrollbar.region == "track" then
-- Click on track - jump to position -- Click on track - jump to position
self:_scrollToTrackPosition(mouseX, mouseY, scrollbar.component) self:_scrollToTrackPosition(mouseX, mouseY, scrollbar.component)
return true return true
end end
return false return false
end end
@@ -4461,43 +4479,44 @@ end
---@param mouseY number ---@param mouseY number
---@return boolean -- True if event was consumed ---@return boolean -- True if event was consumed
function Element:_handleScrollbarDrag(mouseX, mouseY) function Element:_handleScrollbarDrag(mouseX, mouseY)
if not self._scrollbarDragging then return false end if not self._scrollbarDragging then
return false
end
local dims = self:_calculateScrollbarDimensions() local dims = self:_calculateScrollbarDimensions()
if self._hoveredScrollbar == "vertical" then if self._hoveredScrollbar == "vertical" then
local trackY = self.y + self.scrollbarPadding + self.padding.top local trackY = self.y + self.scrollbarPadding + self.padding.top
local trackH = dims.vertical.trackHeight local trackH = dims.vertical.trackHeight
local thumbH = dims.vertical.thumbHeight local thumbH = dims.vertical.thumbHeight
-- Calculate new thumb position -- Calculate new thumb position
local newThumbY = mouseY - self._scrollbarDragOffset - trackY local newThumbY = mouseY - self._scrollbarDragOffset - trackY
newThumbY = math.max(0, math.min(newThumbY, trackH - thumbH)) newThumbY = math.max(0, math.min(newThumbY, trackH - thumbH))
-- Convert thumb position to scroll position -- Convert thumb position to scroll position
local scrollRatio = (trackH - thumbH) > 0 and (newThumbY / (trackH - thumbH)) or 0 local scrollRatio = (trackH - thumbH) > 0 and (newThumbY / (trackH - thumbH)) or 0
local newScrollY = scrollRatio * self._maxScrollY local newScrollY = scrollRatio * self._maxScrollY
self:setScrollPosition(nil, newScrollY) self:setScrollPosition(nil, newScrollY)
return true return true
elseif self._hoveredScrollbar == "horizontal" then elseif self._hoveredScrollbar == "horizontal" then
local trackX = self.x + self.scrollbarPadding + self.padding.left local trackX = self.x + self.scrollbarPadding + self.padding.left
local trackW = dims.horizontal.trackWidth local trackW = dims.horizontal.trackWidth
local thumbW = dims.horizontal.thumbWidth local thumbW = dims.horizontal.thumbWidth
-- Calculate new thumb position -- Calculate new thumb position
local newThumbX = mouseX - self._scrollbarDragOffset - trackX local newThumbX = mouseX - self._scrollbarDragOffset - trackX
newThumbX = math.max(0, math.min(newThumbX, trackW - thumbW)) newThumbX = math.max(0, math.min(newThumbX, trackW - thumbW))
-- Convert thumb position to scroll position -- Convert thumb position to scroll position
local scrollRatio = (trackW - thumbW) > 0 and (newThumbX / (trackW - thumbW)) or 0 local scrollRatio = (trackW - thumbW) > 0 and (newThumbX / (trackW - thumbW)) or 0
local newScrollX = scrollRatio * self._maxScrollX local newScrollX = scrollRatio * self._maxScrollX
self:setScrollPosition(newScrollX, nil) self:setScrollPosition(newScrollX, nil)
return true return true
end end
return false return false
end end
@@ -4505,13 +4524,15 @@ end
---@param button number ---@param button number
---@return boolean -- True if event was consumed ---@return boolean -- True if event was consumed
function Element:_handleScrollbarRelease(button) function Element:_handleScrollbarRelease(button)
if button ~= 1 then return false end if button ~= 1 then
return false
end
if self._scrollbarDragging then if self._scrollbarDragging then
self._scrollbarDragging = false self._scrollbarDragging = false
return true return true
end end
return false return false
end end
@@ -4521,35 +4542,34 @@ end
---@param component string -- "vertical" or "horizontal" ---@param component string -- "vertical" or "horizontal"
function Element:_scrollToTrackPosition(mouseX, mouseY, component) function Element:_scrollToTrackPosition(mouseX, mouseY, component)
local dims = self:_calculateScrollbarDimensions() local dims = self:_calculateScrollbarDimensions()
if component == "vertical" then if component == "vertical" then
local trackY = self.y + self.scrollbarPadding + self.padding.top local trackY = self.y + self.scrollbarPadding + self.padding.top
local trackH = dims.vertical.trackHeight local trackH = dims.vertical.trackHeight
local thumbH = dims.vertical.thumbHeight local thumbH = dims.vertical.thumbHeight
-- Calculate target thumb position (centered on click) -- Calculate target thumb position (centered on click)
local targetThumbY = mouseY - trackY - (thumbH / 2) local targetThumbY = mouseY - trackY - (thumbH / 2)
targetThumbY = math.max(0, math.min(targetThumbY, trackH - thumbH)) targetThumbY = math.max(0, math.min(targetThumbY, trackH - thumbH))
-- Convert to scroll position -- Convert to scroll position
local scrollRatio = (trackH - thumbH) > 0 and (targetThumbY / (trackH - thumbH)) or 0 local scrollRatio = (trackH - thumbH) > 0 and (targetThumbY / (trackH - thumbH)) or 0
local newScrollY = scrollRatio * self._maxScrollY local newScrollY = scrollRatio * self._maxScrollY
self:setScrollPosition(nil, newScrollY) self:setScrollPosition(nil, newScrollY)
elseif component == "horizontal" then elseif component == "horizontal" then
local trackX = self.x + self.scrollbarPadding + self.padding.left local trackX = self.x + self.scrollbarPadding + self.padding.left
local trackW = dims.horizontal.trackWidth local trackW = dims.horizontal.trackWidth
local thumbW = dims.horizontal.thumbWidth local thumbW = dims.horizontal.thumbWidth
-- Calculate target thumb position (centered on click) -- Calculate target thumb position (centered on click)
local targetThumbX = mouseX - trackX - (thumbW / 2) local targetThumbX = mouseX - trackX - (thumbW / 2)
targetThumbX = math.max(0, math.min(targetThumbX, trackW - thumbW)) targetThumbX = math.max(0, math.min(targetThumbX, trackW - thumbW))
-- Convert to scroll position -- Convert to scroll position
local scrollRatio = (trackW - thumbW) > 0 and (targetThumbX / (trackW - thumbW)) or 0 local scrollRatio = (trackW - thumbW) > 0 and (targetThumbX / (trackW - thumbW)) or 0
local newScrollX = scrollRatio * self._maxScrollX local newScrollX = scrollRatio * self._maxScrollX
self:setScrollPosition(newScrollX, nil) self:setScrollPosition(newScrollX, nil)
end end
end end
@@ -4561,24 +4581,24 @@ end
function Element:_handleWheelScroll(x, y) function Element:_handleWheelScroll(x, y)
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
if not (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") then if not (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") then
return false return false
end end
local hasVerticalOverflow = self._overflowY and self._maxScrollY > 0 local hasVerticalOverflow = self._overflowY and self._maxScrollY > 0
local hasHorizontalOverflow = self._overflowX and self._maxScrollX > 0 local hasHorizontalOverflow = self._overflowX and self._maxScrollX > 0
local scrolled = false local scrolled = false
-- Vertical scrolling -- Vertical scrolling
if y ~= 0 and hasVerticalOverflow then if y ~= 0 and hasVerticalOverflow then
local delta = -y * self.scrollSpeed -- Negative because wheel up = scroll up local delta = -y * self.scrollSpeed -- Negative because wheel up = scroll up
local newScrollY = self._scrollY + delta local newScrollY = self._scrollY + delta
self:setScrollPosition(nil, newScrollY) self:setScrollPosition(nil, newScrollY)
scrolled = true scrolled = true
end end
-- Horizontal scrolling -- Horizontal scrolling
if x ~= 0 and hasHorizontalOverflow then if x ~= 0 and hasHorizontalOverflow then
local delta = -x * self.scrollSpeed local delta = -x * self.scrollSpeed
@@ -4586,7 +4606,7 @@ function Element:_handleWheelScroll(x, y)
self:setScrollPosition(newScrollX, nil) self:setScrollPosition(newScrollX, nil)
scrolled = true scrolled = true
end end
return scrolled return scrolled
end end
@@ -5251,7 +5271,7 @@ function Element:layoutChildren()
end end
end end
end end
-- Detect overflow after children are laid out -- Detect overflow after children are laid out
self:_detectOverflow() self:_detectOverflow()
end end
@@ -5339,14 +5359,16 @@ function Element:draw(backdropCanvas)
local imageY = self.y + self.padding.top local imageY = self.y + self.padding.top
local imageWidth = self.width local imageWidth = self.width
local imageHeight = self.height local imageHeight = self.height
-- Combine element opacity with imageOpacity -- Combine element opacity with imageOpacity
local finalOpacity = self.opacity * self.imageOpacity local finalOpacity = self.opacity * self.imageOpacity
-- Apply cornerRadius clipping if set -- Apply cornerRadius clipping if set
local hasCornerRadius = self.cornerRadius.topLeft > 0 or self.cornerRadius.topRight > 0 local hasCornerRadius = self.cornerRadius.topLeft > 0
or self.cornerRadius.bottomLeft > 0 or self.cornerRadius.bottomRight > 0 or self.cornerRadius.topRight > 0
or self.cornerRadius.bottomLeft > 0
or self.cornerRadius.bottomRight > 0
if hasCornerRadius then if hasCornerRadius then
-- Use stencil to clip image to rounded corners -- Use stencil to clip image to rounded corners
love.graphics.stencil(function() love.graphics.stencil(function()
@@ -5354,19 +5376,10 @@ function Element:draw(backdropCanvas)
end, "replace", 1) end, "replace", 1)
love.graphics.setStencilTest("greater", 0) love.graphics.setStencilTest("greater", 0)
end end
-- Draw the image -- Draw the image
ImageRenderer.draw( ImageRenderer.draw(self._loadedImage, imageX, imageY, imageWidth, imageHeight, self.objectFit, self.objectPosition, finalOpacity)
self._loadedImage,
imageX,
imageY,
imageWidth,
imageHeight,
self.objectFit,
self.objectPosition,
finalOpacity
)
-- Clear stencil if it was used -- Clear stencil if it was used
if hasCornerRadius then if hasCornerRadius then
love.graphics.setStencilTest() love.graphics.setStencilTest()
@@ -5529,10 +5542,10 @@ function Element:draw(backdropCanvas)
elseif self.textAlign == TextAlign.JUSTIFY then elseif self.textAlign == TextAlign.JUSTIFY then
align = "justify" align = "justify"
end end
tx = contentX tx = contentX
ty = contentY ty = contentY
-- Use printf with the available width for wrapping -- Use printf with the available width for wrapping
love.graphics.printf(self.text, tx, ty, textAreaWidth, align) love.graphics.printf(self.text, tx, ty, textAreaWidth, align)
else else
@@ -5598,15 +5611,15 @@ function Element:draw(backdropCanvas)
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
local needsOverflowClipping = (overflowX ~= "visible" or overflowY ~= "visible") and (overflowX ~= nil or overflowY ~= nil) local needsOverflowClipping = (overflowX ~= "visible" or overflowY ~= "visible") and (overflowX ~= nil or overflowY ~= nil)
-- Apply scroll offset if overflow is not visible -- Apply scroll offset if overflow is not visible
local hasScrollOffset = needsOverflowClipping and (self._scrollX ~= 0 or self._scrollY ~= 0) local hasScrollOffset = needsOverflowClipping and (self._scrollX ~= 0 or self._scrollY ~= 0)
if hasScrollOffset then if hasScrollOffset then
love.graphics.push() love.graphics.push()
love.graphics.translate(-self._scrollX, -self._scrollY) love.graphics.translate(-self._scrollX, -self._scrollY)
end end
if hasRoundedCorners and #sortedChildren > 0 then if hasRoundedCorners and #sortedChildren > 0 then
-- Use stencil to clip children to rounded rectangle -- Use stencil to clip children to rounded rectangle
-- BORDER-BOX MODEL: Use stored border-box dimensions for clipping -- BORDER-BOX MODEL: Use stored border-box dimensions for clipping
@@ -5628,13 +5641,13 @@ function Element:draw(backdropCanvas)
local contentY = self.y + self.padding.top local contentY = self.y + self.padding.top
local contentWidth = self.width local contentWidth = self.width
local contentHeight = self.height local contentHeight = self.height
love.graphics.setScissor(contentX, contentY, contentWidth, contentHeight) love.graphics.setScissor(contentX, contentY, contentWidth, contentHeight)
for _, child in ipairs(sortedChildren) do for _, child in ipairs(sortedChildren) do
child:draw(backdropCanvas) child:draw(backdropCanvas)
end end
love.graphics.setScissor() love.graphics.setScissor()
else else
-- No clipping needed -- No clipping needed
@@ -5642,7 +5655,7 @@ function Element:draw(backdropCanvas)
child:draw(backdropCanvas) child:draw(backdropCanvas)
end end
end end
if hasScrollOffset then if hasScrollOffset then
love.graphics.pop() love.graphics.pop()
end end
@@ -5659,7 +5672,7 @@ function Element:draw(backdropCanvas)
else else
drawChildren() drawChildren()
end end
-- Draw scrollbars if overflow is scroll or auto -- Draw scrollbars if overflow is scroll or auto
local overflowX = self.overflowX or self.overflow local overflowX = self.overflowX or self.overflow
local overflowY = self.overflowY or self.overflow local overflowY = self.overflowY or self.overflow
@@ -5718,7 +5731,7 @@ function Element:update(dt)
self._hoveredScrollbar = nil self._hoveredScrollbar = nil
end end
end end
-- Handle scrollbar dragging -- Handle scrollbar dragging
if self._scrollbarDragging and love.mouse.isDown(1) then if self._scrollbarDragging and love.mouse.isDown(1) then
self:_handleScrollbarDrag(mx, my) self:_handleScrollbarDrag(mx, my)
@@ -5795,7 +5808,7 @@ function Element:update(dt)
self.callback(self, pressEvent) self.callback(self, pressEvent)
self._pressed[button] = true self._pressed[button] = true
end end
-- Record drag start position per button -- Record drag start position per button
self._dragStartX[button] = mx self._dragStartX[button] = mx
self._dragStartY[button] = my self._dragStartY[button] = my
@@ -5805,13 +5818,13 @@ function Element:update(dt)
-- Button is still pressed - check for mouse movement (drag) -- Button is still pressed - check for mouse movement (drag)
local lastX = self._lastMouseX[button] or mx local lastX = self._lastMouseX[button] or mx
local lastY = self._lastMouseY[button] or my local lastY = self._lastMouseY[button] or my
if lastX ~= mx or lastY ~= my then if lastX ~= mx or lastY ~= my then
-- Mouse has moved - fire drag event -- Mouse has moved - fire drag event
local modifiers = getModifiers() local modifiers = getModifiers()
local dx = mx - self._dragStartX[button] local dx = mx - self._dragStartX[button]
local dy = my - self._dragStartY[button] local dy = my - self._dragStartY[button]
local dragEvent = InputEvent.new({ local dragEvent = InputEvent.new({
type = "drag", type = "drag",
button = button, button = button,
@@ -5823,7 +5836,7 @@ function Element:update(dt)
clickCount = 1, clickCount = 1,
}) })
self.callback(self, dragEvent) self.callback(self, dragEvent)
-- Update last known position for this button -- Update last known position for this button
self._lastMouseX[button] = mx self._lastMouseX[button] = mx
self._lastMouseY[button] = my self._lastMouseY[button] = my
@@ -5867,7 +5880,7 @@ function Element:update(dt)
self.callback(self, clickEvent) self.callback(self, clickEvent)
self._pressed[button] = false self._pressed[button] = false
-- Clean up drag tracking -- Clean up drag tracking
self._dragStartX[button] = nil self._dragStartX[button] = nil
self._dragStartY[button] = nil self._dragStartY[button] = nil
@@ -6174,7 +6187,7 @@ function Element:recalculateUnits(newViewportWidth, newViewportHeight)
self._borderBoxHeight = self.height + self.padding.top + self.padding.bottom self._borderBoxHeight = self.height + self.padding.top + self.padding.bottom
end end
-- For pixel units, height stays as-is (may have been manually modified) -- For pixel units, height stays as-is (may have been manually modified)
-- Detect overflow after layout calculations -- Detect overflow after layout calculations
self:_detectOverflow() self:_detectOverflow()
end end
@@ -6348,7 +6361,7 @@ function Element:calculateTextHeight()
if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.height then if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.height then
height = height * self.contentAutoSizingMultiplier.height height = height * self.contentAutoSizingMultiplier.height
end end
return height return height
end end