corner radius, control highlight
This commit is contained in:
285
FlexLove.lua
285
FlexLove.lua
@@ -104,10 +104,10 @@ local function getFlexLoveBasePath()
|
|||||||
fsPath = fsPath:gsub("^%./", "")
|
fsPath = fsPath:gsub("^%./", "")
|
||||||
-- Remove trailing /
|
-- Remove trailing /
|
||||||
fsPath = fsPath:gsub("/$", "")
|
fsPath = fsPath:gsub("/$", "")
|
||||||
|
|
||||||
-- Convert filesystem path to Lua module path
|
-- Convert filesystem path to Lua module path
|
||||||
local modulePath = fsPath:gsub("/", ".")
|
local modulePath = fsPath:gsub("/", ".")
|
||||||
|
|
||||||
return modulePath, fsPath
|
return modulePath, fsPath
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -127,7 +127,7 @@ local function resolveImagePath(imagePath)
|
|||||||
if imagePath:match("^/") or imagePath:match("^[A-Z]:") then
|
if imagePath:match("^/") or imagePath:match("^[A-Z]:") then
|
||||||
return imagePath
|
return imagePath
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Otherwise, make it relative to FlexLove's location
|
-- Otherwise, make it relative to FlexLove's location
|
||||||
return FLEXLOVE_FILESYSTEM_PATH .. "/" .. imagePath
|
return FLEXLOVE_FILESYSTEM_PATH .. "/" .. imagePath
|
||||||
end
|
end
|
||||||
@@ -263,6 +263,102 @@ function Theme.getComponent(componentName, state)
|
|||||||
return component
|
return component
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- ====================
|
||||||
|
-- Rounded Rectangle Helper
|
||||||
|
-- ====================
|
||||||
|
|
||||||
|
local RoundedRect = {}
|
||||||
|
|
||||||
|
--- Generate points for a rounded rectangle
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param width number
|
||||||
|
---@param height number
|
||||||
|
---@param cornerRadius {topLeft:number, topRight:number, bottomLeft:number, bottomRight:number}
|
||||||
|
---@param segments number? -- Number of segments per corner arc (default: 10)
|
||||||
|
---@return table -- Array of vertices for love.graphics.polygon
|
||||||
|
function RoundedRect.getPoints(x, y, width, height, cornerRadius, segments)
|
||||||
|
segments = segments or 10
|
||||||
|
local points = {}
|
||||||
|
|
||||||
|
-- Helper to add arc points
|
||||||
|
local function addArc(cx, cy, radius, startAngle, endAngle)
|
||||||
|
if radius <= 0 then
|
||||||
|
table.insert(points, cx)
|
||||||
|
table.insert(points, cy)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 0, segments do
|
||||||
|
local angle = startAngle + (endAngle - startAngle) * (i / segments)
|
||||||
|
table.insert(points, cx + math.cos(angle) * radius)
|
||||||
|
table.insert(points, cy + math.sin(angle) * radius)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local r1 = math.min(cornerRadius.topLeft, width / 2, height / 2)
|
||||||
|
local r2 = math.min(cornerRadius.topRight, width / 2, height / 2)
|
||||||
|
local r3 = math.min(cornerRadius.bottomRight, width / 2, height / 2)
|
||||||
|
local r4 = math.min(cornerRadius.bottomLeft, width / 2, height / 2)
|
||||||
|
|
||||||
|
-- Top-right corner
|
||||||
|
addArc(x + width - r2, y + r2, r2, -math.pi / 2, 0)
|
||||||
|
|
||||||
|
-- Bottom-right corner
|
||||||
|
addArc(x + width - r3, y + height - r3, r3, 0, math.pi / 2)
|
||||||
|
|
||||||
|
-- Bottom-left corner
|
||||||
|
addArc(x + r4, y + height - r4, r4, math.pi / 2, math.pi)
|
||||||
|
|
||||||
|
-- Top-left corner
|
||||||
|
addArc(x + r1, y + r1, r1, math.pi, math.pi * 1.5)
|
||||||
|
|
||||||
|
return points
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Draw a filled rounded rectangle
|
||||||
|
---@param mode string -- "fill" or "line"
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param width number
|
||||||
|
---@param height number
|
||||||
|
---@param cornerRadius {topLeft:number, topRight:number, bottomLeft:number, bottomRight:number}
|
||||||
|
function RoundedRect.draw(mode, x, y, width, height, cornerRadius)
|
||||||
|
-- Check if any corners are rounded
|
||||||
|
local hasRoundedCorners = cornerRadius.topLeft > 0
|
||||||
|
or cornerRadius.topRight > 0
|
||||||
|
or cornerRadius.bottomLeft > 0
|
||||||
|
or cornerRadius.bottomRight > 0
|
||||||
|
|
||||||
|
if not hasRoundedCorners then
|
||||||
|
-- No rounded corners, use regular rectangle
|
||||||
|
love.graphics.rectangle(mode, x, y, width, height)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local points = RoundedRect.getPoints(x, y, width, height, cornerRadius)
|
||||||
|
|
||||||
|
if mode == "fill" then
|
||||||
|
love.graphics.polygon("fill", points)
|
||||||
|
else
|
||||||
|
-- For line mode, draw the outline
|
||||||
|
love.graphics.polygon("line", points)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a stencil function for rounded rectangle clipping
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param width number
|
||||||
|
---@param height number
|
||||||
|
---@param cornerRadius {topLeft:number, topRight:number, bottomLeft:number, bottomRight:number}
|
||||||
|
---@return function
|
||||||
|
function RoundedRect.stencilFunction(x, y, width, height, cornerRadius)
|
||||||
|
return function()
|
||||||
|
RoundedRect.draw("fill", x, y, width, height, cornerRadius)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- ====================
|
-- ====================
|
||||||
-- NineSlice Renderer
|
-- NineSlice Renderer
|
||||||
-- ====================
|
-- ====================
|
||||||
@@ -312,11 +408,11 @@ function NineSlice.draw(component, atlas, x, y, width, height, opacity)
|
|||||||
-- Check if element is too small and needs proportional scaling
|
-- Check if element is too small and needs proportional scaling
|
||||||
local scaleDownX = 1
|
local scaleDownX = 1
|
||||||
local scaleDownY = 1
|
local scaleDownY = 1
|
||||||
|
|
||||||
if width < minWidth then
|
if width < minWidth then
|
||||||
scaleDownX = width / minWidth
|
scaleDownX = width / minWidth
|
||||||
end
|
end
|
||||||
|
|
||||||
if height < minHeight then
|
if height < minHeight then
|
||||||
scaleDownY = height / minHeight
|
scaleDownY = height / minHeight
|
||||||
end
|
end
|
||||||
@@ -336,13 +432,37 @@ function NineSlice.draw(component, atlas, x, y, width, height, opacity)
|
|||||||
love.graphics.draw(atlas, makeQuad(regions.topLeft), x, y, 0, scaleDownX, scaleDownY)
|
love.graphics.draw(atlas, makeQuad(regions.topLeft), x, y, 0, scaleDownX, scaleDownY)
|
||||||
|
|
||||||
-- Top-right corner
|
-- Top-right corner
|
||||||
love.graphics.draw(atlas, makeQuad(regions.topRight), x + width - scaledRightCornerWidth, y, 0, scaleDownX, scaleDownY)
|
love.graphics.draw(
|
||||||
|
atlas,
|
||||||
|
makeQuad(regions.topRight),
|
||||||
|
x + width - scaledRightCornerWidth,
|
||||||
|
y,
|
||||||
|
0,
|
||||||
|
scaleDownX,
|
||||||
|
scaleDownY
|
||||||
|
)
|
||||||
|
|
||||||
-- Bottom-left corner
|
-- Bottom-left corner
|
||||||
love.graphics.draw(atlas, makeQuad(regions.bottomLeft), x, y + height - scaledBottomLeftHeight, 0, scaleDownX, scaleDownY)
|
love.graphics.draw(
|
||||||
|
atlas,
|
||||||
|
makeQuad(regions.bottomLeft),
|
||||||
|
x,
|
||||||
|
y + height - scaledBottomLeftHeight,
|
||||||
|
0,
|
||||||
|
scaleDownX,
|
||||||
|
scaleDownY
|
||||||
|
)
|
||||||
|
|
||||||
-- Bottom-right corner
|
-- Bottom-right corner
|
||||||
love.graphics.draw(atlas, makeQuad(regions.bottomRight), x + width - scaledRightCornerWidth, y + height - scaledBottomRightHeight, 0, scaleDownX, scaleDownY)
|
love.graphics.draw(
|
||||||
|
atlas,
|
||||||
|
makeQuad(regions.bottomRight),
|
||||||
|
x + width - scaledRightCornerWidth,
|
||||||
|
y + height - scaledBottomRightHeight,
|
||||||
|
0,
|
||||||
|
scaleDownX,
|
||||||
|
scaleDownY
|
||||||
|
)
|
||||||
|
|
||||||
-- Top edge (stretched)
|
-- Top edge (stretched)
|
||||||
if centerWidth > 0 then
|
if centerWidth > 0 then
|
||||||
@@ -388,7 +508,15 @@ function NineSlice.draw(component, atlas, x, y, width, height, opacity)
|
|||||||
if centerWidth > 0 and centerHeight > 0 then
|
if centerWidth > 0 and centerHeight > 0 then
|
||||||
local scaleX = centerWidth / regions.middleCenter.w
|
local scaleX = centerWidth / regions.middleCenter.w
|
||||||
local scaleY = centerHeight / regions.middleCenter.h
|
local scaleY = centerHeight / regions.middleCenter.h
|
||||||
love.graphics.draw(atlas, makeQuad(regions.middleCenter), x + scaledCornerWidth, y + scaledCornerHeight, 0, scaleX, scaleY)
|
love.graphics.draw(
|
||||||
|
atlas,
|
||||||
|
makeQuad(regions.middleCenter),
|
||||||
|
x + scaledCornerWidth,
|
||||||
|
y + scaledCornerHeight,
|
||||||
|
0,
|
||||||
|
scaleX,
|
||||||
|
scaleY
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reset color
|
-- Reset color
|
||||||
@@ -1083,6 +1211,7 @@ end
|
|||||||
---@field opacity number
|
---@field opacity number
|
||||||
---@field borderColor Color -- Color of the border
|
---@field borderColor Color -- Color of the border
|
||||||
---@field backgroundColor Color -- Background color of the element
|
---@field backgroundColor Color -- Background color of the element
|
||||||
|
---@field cornerRadius number|{topLeft:number?, topRight:number?, bottomLeft:number?, bottomRight:number?}? -- Corner radius for rounded corners (default: 0)
|
||||||
---@field prevGameSize {width:number, height:number} -- Previous game size for resize calculations
|
---@field prevGameSize {width:number, height:number} -- Previous game size for resize calculations
|
||||||
---@field text string? -- Text content to display in the element
|
---@field text string? -- Text content to display in the element
|
||||||
---@field textColor Color -- Color of the text content
|
---@field textColor Color -- Color of the text content
|
||||||
@@ -1117,6 +1246,7 @@ end
|
|||||||
---@field _themeState string? -- Current theme state (normal, hover, pressed, active, disabled)
|
---@field _themeState string? -- Current theme state (normal, hover, pressed, active, disabled)
|
||||||
---@field disabled boolean? -- Whether the element is disabled (default: false)
|
---@field disabled boolean? -- Whether the element is disabled (default: false)
|
||||||
---@field active boolean? -- Whether the element is active/focused (for inputs, default: false)
|
---@field active boolean? -- Whether the element is active/focused (for inputs, default: false)
|
||||||
|
---@field disableHighlight boolean? -- Whether to disable the pressed state highlight overlay (default: false)
|
||||||
local Element = {}
|
local Element = {}
|
||||||
Element.__index = Element
|
Element.__index = Element
|
||||||
|
|
||||||
@@ -1136,6 +1266,7 @@ Element.__index = Element
|
|||||||
---@field borderColor Color? -- Color of the border (default: black)
|
---@field borderColor Color? -- Color of the border (default: black)
|
||||||
---@field opacity number?
|
---@field opacity number?
|
||||||
---@field backgroundColor Color? -- Background color (default: transparent)
|
---@field backgroundColor Color? -- Background color (default: transparent)
|
||||||
|
---@field cornerRadius number|{topLeft:number?, topRight:number?, bottomLeft:number?, bottomRight:number?}? -- Corner radius: number (all corners) or table for individual corners (default: 0)
|
||||||
---@field gap number|string? -- Space between children elements (default: 10)
|
---@field gap number|string? -- Space between children elements (default: 10)
|
||||||
---@field padding {top:number|string?, right:number|string?, bottom:number|string?, left:number|string?, horizontal: number|string?, vertical:number|string?}? -- Padding around children (default: {top=0, right=0, bottom=0, left=0})
|
---@field padding {top:number|string?, right:number|string?, bottom:number|string?, left:number|string?, horizontal: number|string?, vertical:number|string?}? -- Padding around children (default: {top=0, right=0, bottom=0, left=0})
|
||||||
---@field margin {top:number|string?, right:number|string?, bottom:number|string?, left:number|string?, horizontal: number|string?, vertical:number|string?}? -- Margin around children (default: {top=0, right=0, bottom=0, left=0})
|
---@field margin {top:number|string?, right:number|string?, bottom:number|string?, left:number|string?, horizontal: number|string?, vertical:number|string?}? -- Margin around children (default: {top=0, right=0, bottom=0, left=0})
|
||||||
@@ -1164,6 +1295,7 @@ Element.__index = Element
|
|||||||
---@field themeComponent string? -- Theme component to use (e.g., "panel", "button", "input"). If nil, no theme is applied
|
---@field themeComponent string? -- Theme component to use (e.g., "panel", "button", "input"). If nil, no theme is applied
|
||||||
---@field disabled boolean? -- Whether the element is disabled (default: false)
|
---@field disabled boolean? -- Whether the element is disabled (default: false)
|
||||||
---@field active boolean? -- Whether the element is active/focused (for inputs, default: false)
|
---@field active boolean? -- Whether the element is active/focused (for inputs, default: false)
|
||||||
|
---@field disableHighlight boolean? -- Whether to disable the pressed state highlight overlay (default: false)
|
||||||
local ElementProps = {}
|
local ElementProps = {}
|
||||||
|
|
||||||
---@param props ElementProps
|
---@param props ElementProps
|
||||||
@@ -1195,6 +1327,14 @@ function Element.new(props)
|
|||||||
self.disabled = props.disabled or false
|
self.disabled = props.disabled or false
|
||||||
self.active = props.active or false
|
self.active = props.active or false
|
||||||
|
|
||||||
|
-- disableHighlight defaults to true when using themeComponent (themes handle their own visual feedback)
|
||||||
|
-- Can be explicitly overridden by setting props.disableHighlight
|
||||||
|
if props.disableHighlight ~= nil then
|
||||||
|
self.disableHighlight = props.disableHighlight
|
||||||
|
else
|
||||||
|
self.disableHighlight = self.themeComponent ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Set parent first so it's available for size calculations
|
-- Set parent first so it's available for size calculations
|
||||||
self.parent = props.parent
|
self.parent = props.parent
|
||||||
|
|
||||||
@@ -1217,6 +1357,32 @@ function Element.new(props)
|
|||||||
self.backgroundColor = props.backgroundColor or Color.new(0, 0, 0, 0)
|
self.backgroundColor = props.backgroundColor or Color.new(0, 0, 0, 0)
|
||||||
self.opacity = props.opacity or 1
|
self.opacity = props.opacity or 1
|
||||||
|
|
||||||
|
-- Handle cornerRadius (can be number or table)
|
||||||
|
if props.cornerRadius then
|
||||||
|
if type(props.cornerRadius) == "number" then
|
||||||
|
self.cornerRadius = {
|
||||||
|
topLeft = props.cornerRadius,
|
||||||
|
topRight = props.cornerRadius,
|
||||||
|
bottomLeft = props.cornerRadius,
|
||||||
|
bottomRight = props.cornerRadius,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
self.cornerRadius = {
|
||||||
|
topLeft = props.cornerRadius.topLeft or 0,
|
||||||
|
topRight = props.cornerRadius.topRight or 0,
|
||||||
|
bottomLeft = props.cornerRadius.bottomLeft or 0,
|
||||||
|
bottomRight = props.cornerRadius.bottomRight or 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.cornerRadius = {
|
||||||
|
topLeft = 0,
|
||||||
|
topRight = 0,
|
||||||
|
bottomLeft = 0,
|
||||||
|
bottomRight = 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
self.text = props.text
|
self.text = props.text
|
||||||
self.textAlign = props.textAlign or TextAlign.START
|
self.textAlign = props.textAlign or TextAlign.START
|
||||||
|
|
||||||
@@ -2156,7 +2322,8 @@ function Element:draw()
|
|||||||
if self.animation then
|
if self.animation then
|
||||||
local anim = self.animation:interpolate()
|
local anim = self.animation:interpolate()
|
||||||
if anim.opacity then
|
if anim.opacity then
|
||||||
drawBackgroundColor = Color.new(self.backgroundColor.r, self.backgroundColor.g, self.backgroundColor.b, anim.opacity)
|
drawBackgroundColor =
|
||||||
|
Color.new(self.backgroundColor.r, self.backgroundColor.g, self.backgroundColor.b, anim.opacity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2166,12 +2333,13 @@ function Element:draw()
|
|||||||
local backgroundWithOpacity =
|
local backgroundWithOpacity =
|
||||||
Color.new(drawBackgroundColor.r, drawBackgroundColor.g, drawBackgroundColor.b, drawBackgroundColor.a * self.opacity)
|
Color.new(drawBackgroundColor.r, drawBackgroundColor.g, drawBackgroundColor.b, drawBackgroundColor.a * self.opacity)
|
||||||
love.graphics.setColor(backgroundWithOpacity:toRGBA())
|
love.graphics.setColor(backgroundWithOpacity:toRGBA())
|
||||||
love.graphics.rectangle(
|
RoundedRect.draw(
|
||||||
"fill",
|
"fill",
|
||||||
self.x,
|
self.x,
|
||||||
self.y,
|
self.y,
|
||||||
self.width + self.padding.left + self.padding.right,
|
self.width + self.padding.left + self.padding.right,
|
||||||
self.height + self.padding.top + self.padding.bottom
|
self.height + self.padding.top + self.padding.bottom,
|
||||||
|
self.cornerRadius
|
||||||
)
|
)
|
||||||
|
|
||||||
-- LAYER 2: Draw theme on top of backgroundColor (if theme exists)
|
-- LAYER 2: Draw theme on top of backgroundColor (if theme exists)
|
||||||
@@ -2232,27 +2400,44 @@ function Element:draw()
|
|||||||
local borderColorWithOpacity =
|
local borderColorWithOpacity =
|
||||||
Color.new(self.borderColor.r, self.borderColor.g, self.borderColor.b, self.borderColor.a * self.opacity)
|
Color.new(self.borderColor.r, self.borderColor.g, self.borderColor.b, self.borderColor.a * self.opacity)
|
||||||
love.graphics.setColor(borderColorWithOpacity:toRGBA())
|
love.graphics.setColor(borderColorWithOpacity:toRGBA())
|
||||||
if self.border.top then
|
|
||||||
love.graphics.line(self.x, self.y, self.x + self.width + self.padding.left + self.padding.right, self.y)
|
-- Check if all borders are enabled
|
||||||
end
|
local allBorders = self.border.top and self.border.bottom and self.border.left and self.border.right
|
||||||
if self.border.bottom then
|
|
||||||
love.graphics.line(
|
if allBorders then
|
||||||
|
-- Draw complete rounded rectangle border
|
||||||
|
RoundedRect.draw(
|
||||||
|
"line",
|
||||||
self.x,
|
self.x,
|
||||||
self.y + self.height + self.padding.top + self.padding.bottom,
|
|
||||||
self.x + self.width + self.padding.left + self.padding.right,
|
|
||||||
self.y + self.height + self.padding.top + self.padding.bottom
|
|
||||||
)
|
|
||||||
end
|
|
||||||
if self.border.left then
|
|
||||||
love.graphics.line(self.x, self.y, self.x, self.y + self.height + self.padding.top + self.padding.bottom)
|
|
||||||
end
|
|
||||||
if self.border.right then
|
|
||||||
love.graphics.line(
|
|
||||||
self.x + self.width + self.padding.left + self.padding.right,
|
|
||||||
self.y,
|
self.y,
|
||||||
self.x + self.width + self.padding.left + self.padding.right,
|
self.width + self.padding.left + self.padding.right,
|
||||||
self.y + self.height + self.padding.top + self.padding.bottom
|
self.height + self.padding.top + self.padding.bottom,
|
||||||
|
self.cornerRadius
|
||||||
)
|
)
|
||||||
|
else
|
||||||
|
-- Draw individual borders (without rounded corners for partial borders)
|
||||||
|
if self.border.top then
|
||||||
|
love.graphics.line(self.x, self.y, self.x + self.width + self.padding.left + self.padding.right, self.y)
|
||||||
|
end
|
||||||
|
if self.border.bottom then
|
||||||
|
love.graphics.line(
|
||||||
|
self.x,
|
||||||
|
self.y + self.height + self.padding.top + self.padding.bottom,
|
||||||
|
self.x + self.width + self.padding.left + self.padding.right,
|
||||||
|
self.y + self.height + self.padding.top + self.padding.bottom
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if self.border.left then
|
||||||
|
love.graphics.line(self.x, self.y, self.x, self.y + self.height + self.padding.top + self.padding.bottom)
|
||||||
|
end
|
||||||
|
if self.border.right then
|
||||||
|
love.graphics.line(
|
||||||
|
self.x + self.width + self.padding.left + self.padding.right,
|
||||||
|
self.y,
|
||||||
|
self.x + self.width + self.padding.left + self.padding.right,
|
||||||
|
self.y + self.height + self.padding.top + self.padding.bottom
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Draw element text if present
|
-- Draw element text if present
|
||||||
@@ -2294,8 +2479,8 @@ function Element:draw()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Draw visual feedback when element is pressed (if it has a callback)
|
-- Draw visual feedback when element is pressed (if it has a callback and highlight is not disabled)
|
||||||
if self.callback then
|
if self.callback and not self.disableHighlight then
|
||||||
-- Check if any button is pressed
|
-- Check if any button is pressed
|
||||||
local anyPressed = false
|
local anyPressed = false
|
||||||
for _, pressed in pairs(self._pressed) do
|
for _, pressed in pairs(self._pressed) do
|
||||||
@@ -2306,12 +2491,13 @@ function Element:draw()
|
|||||||
end
|
end
|
||||||
if anyPressed then
|
if anyPressed then
|
||||||
love.graphics.setColor(0.5, 0.5, 0.5, 0.3 * self.opacity) -- Semi-transparent gray for pressed state with opacity
|
love.graphics.setColor(0.5, 0.5, 0.5, 0.3 * self.opacity) -- Semi-transparent gray for pressed state with opacity
|
||||||
love.graphics.rectangle(
|
RoundedRect.draw(
|
||||||
"fill",
|
"fill",
|
||||||
self.x,
|
self.x,
|
||||||
self.y,
|
self.y,
|
||||||
self.width + self.padding.left + self.padding.right,
|
self.width + self.padding.left + self.padding.right,
|
||||||
self.height + self.padding.top + self.padding.bottom
|
self.height + self.padding.top + self.padding.bottom,
|
||||||
|
self.cornerRadius
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2325,8 +2511,35 @@ function Element:draw()
|
|||||||
return a.z < b.z
|
return a.z < b.z
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for _, child in ipairs(sortedChildren) do
|
-- Check if we need to clip children to rounded corners
|
||||||
child:draw()
|
local hasRoundedCorners = self.cornerRadius.topLeft > 0
|
||||||
|
or self.cornerRadius.topRight > 0
|
||||||
|
or self.cornerRadius.bottomLeft > 0
|
||||||
|
or self.cornerRadius.bottomRight > 0
|
||||||
|
|
||||||
|
if hasRoundedCorners and #sortedChildren > 0 then
|
||||||
|
-- Use stencil to clip children to rounded rectangle
|
||||||
|
local stencilFunc = RoundedRect.stencilFunction(
|
||||||
|
self.x,
|
||||||
|
self.y,
|
||||||
|
self.width + self.padding.left + self.padding.right,
|
||||||
|
self.height + self.padding.top + self.padding.bottom,
|
||||||
|
self.cornerRadius
|
||||||
|
)
|
||||||
|
|
||||||
|
love.graphics.stencil(stencilFunc, "replace", 1)
|
||||||
|
love.graphics.setStencilTest("greater", 0)
|
||||||
|
|
||||||
|
for _, child in ipairs(sortedChildren) do
|
||||||
|
child:draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setStencilTest()
|
||||||
|
else
|
||||||
|
-- No clipping needed
|
||||||
|
for _, child in ipairs(sortedChildren) do
|
||||||
|
child:draw()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
312
examples/CornerRadiusDemo.lua
Normal file
312
examples/CornerRadiusDemo.lua
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
-- Demo showing corner radius functionality
|
||||||
|
|
||||||
|
local FlexLove = require("FlexLove")
|
||||||
|
local Gui = FlexLove.GUI
|
||||||
|
local Color = FlexLove.Color
|
||||||
|
|
||||||
|
function love.load()
|
||||||
|
Gui.init({
|
||||||
|
baseScale = { width = 1920, height = 1080 }
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Create main container
|
||||||
|
local container = Gui.new({
|
||||||
|
x = 50,
|
||||||
|
y = 50,
|
||||||
|
width = 1100,
|
||||||
|
height = 600,
|
||||||
|
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
||||||
|
cornerRadius = 20,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(0.5, 0.5, 0.6, 1),
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 20,
|
||||||
|
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Title
|
||||||
|
Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 50,
|
||||||
|
text = "Corner Radius Demo",
|
||||||
|
textSize = 28,
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
||||||
|
cornerRadius = 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Row 1: Uniform corner radius
|
||||||
|
local row1 = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 150,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "horizontal",
|
||||||
|
gap = 20,
|
||||||
|
backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "radius: 0",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.8, 0.2, 0.2, 1),
|
||||||
|
cornerRadius = 0,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "radius: 10",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.8, 0.2, 1),
|
||||||
|
cornerRadius = 10,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "radius: 25",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.2, 0.8, 1),
|
||||||
|
cornerRadius = 25,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "radius: 50\n(pill)",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.8, 0.2, 0.8, 1),
|
||||||
|
cornerRadius = 50,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Row 2: Individual corner radii
|
||||||
|
local row2 = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 150,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "horizontal",
|
||||||
|
gap = 20,
|
||||||
|
backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "Top-Left\nOnly",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.9, 0.5, 0.2, 1),
|
||||||
|
cornerRadius = { topLeft = 30, topRight = 0, bottomLeft = 0, bottomRight = 0 },
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "Top\nCorners",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.9, 0.5, 1),
|
||||||
|
cornerRadius = { topLeft = 25, topRight = 25, bottomLeft = 0, bottomRight = 0 },
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "Diagonal\nCorners",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.5, 0.2, 0.9, 1),
|
||||||
|
cornerRadius = { topLeft = 30, topRight = 0, bottomLeft = 0, bottomRight = 30 },
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
width = 150,
|
||||||
|
height = 100,
|
||||||
|
text = "Mixed\nRadii",
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.9, 0.9, 0.2, 1),
|
||||||
|
cornerRadius = { topLeft = 5, topRight = 15, bottomLeft = 25, bottomRight = 35 },
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.5),
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Row 3: Interactive buttons with corner radius
|
||||||
|
local row3 = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 180,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 15,
|
||||||
|
backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row3,
|
||||||
|
height = 25,
|
||||||
|
text = "Interactive Buttons with Corner Radius:",
|
||||||
|
textSize = 16,
|
||||||
|
textColor = Color.new(0.8, 0.9, 1, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
local buttonRow = Gui.new({
|
||||||
|
parent = row3,
|
||||||
|
height = 80,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "horizontal",
|
||||||
|
gap = 15,
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = buttonRow,
|
||||||
|
width = 180,
|
||||||
|
height = 60,
|
||||||
|
text = "Click Me!",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 18,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.6, 0.9, 1),
|
||||||
|
cornerRadius = 15,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.3),
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Button 1 clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = buttonRow,
|
||||||
|
width = 180,
|
||||||
|
height = 60,
|
||||||
|
text = "Pill Button",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 18,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.9, 0.3, 0.4, 1),
|
||||||
|
cornerRadius = 30,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.3),
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Button 2 clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = buttonRow,
|
||||||
|
width = 180,
|
||||||
|
height = 60,
|
||||||
|
text = "Sharp Top",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 18,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.3, 0.8, 0.4, 1),
|
||||||
|
cornerRadius = { topLeft = 0, topRight = 0, bottomLeft = 20, bottomRight = 20 },
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(1, 1, 1, 0.3),
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Button 3 clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Clipping demo
|
||||||
|
local clippingDemo = Gui.new({
|
||||||
|
x = 50,
|
||||||
|
y = 670,
|
||||||
|
width = 500,
|
||||||
|
height = 150,
|
||||||
|
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
||||||
|
cornerRadius = 20,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(0.8, 0.8, 0.9, 1),
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 10,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = clippingDemo,
|
||||||
|
height = 25,
|
||||||
|
text = "Clipping Demo: Children clipped to parent's rounded corners",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Child that extends beyond parent (will be clipped)
|
||||||
|
Gui.new({
|
||||||
|
parent = clippingDemo,
|
||||||
|
x = -10,
|
||||||
|
y = 40,
|
||||||
|
width = 520,
|
||||||
|
height = 80,
|
||||||
|
backgroundColor = Color.new(0.9, 0.5, 0.2, 0.8),
|
||||||
|
text = "This element extends beyond parent but is clipped!",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
positioning = "absolute",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.update(dt)
|
||||||
|
Gui.update(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
love.graphics.clear(0.05, 0.05, 0.1, 1)
|
||||||
|
Gui.draw()
|
||||||
|
|
||||||
|
-- Draw instructions
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.print("Corner Radius System", 10, 10)
|
||||||
|
love.graphics.print("Supports uniform radius (number) or individual corners (table)", 10, 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.resize(w, h)
|
||||||
|
Gui.resize()
|
||||||
|
end
|
||||||
239
examples/DisableHighlightDemo.lua
Normal file
239
examples/DisableHighlightDemo.lua
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
-- Demo showing disableHighlight property
|
||||||
|
|
||||||
|
local FlexLove = require("FlexLove")
|
||||||
|
local Gui = FlexLove.GUI
|
||||||
|
local Theme = FlexLove.Theme
|
||||||
|
local Color = FlexLove.Color
|
||||||
|
|
||||||
|
function love.load()
|
||||||
|
Gui.init({
|
||||||
|
baseScale = { width = 1920, height = 1080 }
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Try to load space theme (optional)
|
||||||
|
pcall(function()
|
||||||
|
Theme.load("space")
|
||||||
|
Theme.setActive("space")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Create main container
|
||||||
|
local container = Gui.new({
|
||||||
|
x = 50,
|
||||||
|
y = 50,
|
||||||
|
width = 900,
|
||||||
|
height = 550,
|
||||||
|
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
||||||
|
cornerRadius = 20,
|
||||||
|
border = { top = true, bottom = true, left = true, right = true },
|
||||||
|
borderColor = Color.new(0.5, 0.5, 0.6, 1),
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 20,
|
||||||
|
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Title
|
||||||
|
Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 50,
|
||||||
|
text = "disableHighlight Property Demo",
|
||||||
|
textSize = 24,
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
||||||
|
cornerRadius = 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Description
|
||||||
|
Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 70,
|
||||||
|
text = "Click buttons to see the difference.\nButtons with themeComponent automatically disable highlight (can be overridden).\nRegular buttons show highlight by default.",
|
||||||
|
textSize = 13,
|
||||||
|
textAlign = "center",
|
||||||
|
textColor = Color.new(0.8, 0.9, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.15, 0.15, 0.2, 0.8),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Row 1: Regular buttons
|
||||||
|
local row1 = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 130,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 10,
|
||||||
|
backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
height = 20,
|
||||||
|
text = "Regular Buttons (no theme):",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(0.8, 0.9, 1, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
local regularRow = Gui.new({
|
||||||
|
parent = row1,
|
||||||
|
height = 80,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "horizontal",
|
||||||
|
gap = 15,
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = regularRow,
|
||||||
|
width = 250,
|
||||||
|
height = 70,
|
||||||
|
text = "Default\n(shows highlight)",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.6, 0.9, 1),
|
||||||
|
cornerRadius = 12,
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Regular button with highlight clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = regularRow,
|
||||||
|
width = 250,
|
||||||
|
height = 70,
|
||||||
|
text = "disableHighlight = true\n(no highlight)",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.9, 0.3, 0.4, 1),
|
||||||
|
cornerRadius = 12,
|
||||||
|
disableHighlight = true,
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Regular button without highlight clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Row 2: Themed buttons
|
||||||
|
local row2 = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 150,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 10,
|
||||||
|
backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
height = 20,
|
||||||
|
text = "Themed Buttons (with themeComponent):",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(0.8, 0.9, 1, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
local themedRow = Gui.new({
|
||||||
|
parent = row2,
|
||||||
|
height = 100,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "horizontal",
|
||||||
|
gap = 15,
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = themedRow,
|
||||||
|
width = 250,
|
||||||
|
height = 80,
|
||||||
|
text = "Default\n(auto-disables highlight)",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.2, 0.6, 0.9, 0.3),
|
||||||
|
cornerRadius = 12,
|
||||||
|
themeComponent = "button",
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Themed button (auto-disabled highlight) clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = themedRow,
|
||||||
|
width = 250,
|
||||||
|
height = 80,
|
||||||
|
text = "disableHighlight = false\n(forced highlight)",
|
||||||
|
textAlign = "center",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(1, 1, 1, 1),
|
||||||
|
backgroundColor = Color.new(0.9, 0.3, 0.4, 0.3),
|
||||||
|
cornerRadius = 12,
|
||||||
|
themeComponent = "button",
|
||||||
|
disableHighlight = false,
|
||||||
|
callback = function(element, event)
|
||||||
|
if event.type == "click" then
|
||||||
|
print("Themed button (forced highlight) clicked!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Summary
|
||||||
|
local summary = Gui.new({
|
||||||
|
parent = container,
|
||||||
|
height = 70,
|
||||||
|
positioning = "flex",
|
||||||
|
flexDirection = "vertical",
|
||||||
|
gap = 5,
|
||||||
|
backgroundColor = Color.new(0.15, 0.2, 0.15, 0.8),
|
||||||
|
cornerRadius = 8,
|
||||||
|
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = summary,
|
||||||
|
height = 18,
|
||||||
|
text = "Summary:",
|
||||||
|
textSize = 14,
|
||||||
|
textColor = Color.new(0.8, 1, 0.8, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
Gui.new({
|
||||||
|
parent = summary,
|
||||||
|
height = 40,
|
||||||
|
text = "• Regular buttons: highlight enabled by default\n• Themed buttons: highlight disabled by default (themes provide their own feedback)\n• Both can be explicitly overridden with disableHighlight property",
|
||||||
|
textSize = 11,
|
||||||
|
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
||||||
|
backgroundColor = Color.new(0, 0, 0, 0),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.update(dt)
|
||||||
|
Gui.update(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
love.graphics.clear(0.05, 0.05, 0.1, 1)
|
||||||
|
Gui.draw()
|
||||||
|
|
||||||
|
-- Draw instructions
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.print("disableHighlight Property Demo", 10, 10)
|
||||||
|
love.graphics.print("Press and hold buttons to see the difference", 10, 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.resize(w, h)
|
||||||
|
Gui.resize()
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user