This commit is contained in:
Michael Freno
2025-10-13 09:44:33 -04:00
parent 2d724bf120
commit a0cea8081b
12 changed files with 313 additions and 123 deletions

View File

@@ -1082,7 +1082,7 @@ end
---@field border Border -- Border configuration for the element ---@field border Border -- Border configuration for the element
---@field opacity number ---@field opacity number
---@field borderColor Color -- Color of the border ---@field borderColor Color -- Color of the border
---@field background Color -- Background color of the element ---@field backgroundColor Color -- Background color of the element
---@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
@@ -1135,7 +1135,7 @@ Element.__index = Element
---@field border Border? -- Border configuration for the element ---@field border Border? -- Border configuration for the 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 background Color? -- Background color (default: transparent) ---@field backgroundColor Color? -- Background color (default: transparent)
---@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})
@@ -1214,7 +1214,7 @@ function Element.new(props)
left = false, left = false,
} }
self.borderColor = props.borderColor or Color.new(0, 0, 0, 1) self.borderColor = props.borderColor or Color.new(0, 0, 0, 1)
self.background = props.background 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
self.text = props.text self.text = props.text
@@ -2152,16 +2152,29 @@ end
--- Draw element and its children --- Draw element and its children
function Element:draw() function Element:draw()
-- Handle opacity during animation -- Handle opacity during animation
local drawBackground = self.background local drawBackgroundColor = self.backgroundColor
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
drawBackground = Color.new(self.background.r, self.background.g, self.background.b, anim.opacity) drawBackgroundColor = Color.new(self.backgroundColor.r, self.backgroundColor.g, self.backgroundColor.b, anim.opacity)
end end
end end
-- Check if element has a theme component -- LAYER 1: Draw backgroundColor first (behind everything)
local hasTheme = false -- Apply opacity to all drawing operations
-- (x, y) represents border box, so draw background from (x, y)
local backgroundWithOpacity =
Color.new(drawBackgroundColor.r, drawBackgroundColor.g, drawBackgroundColor.b, drawBackgroundColor.a * self.opacity)
love.graphics.setColor(backgroundWithOpacity:toRGBA())
love.graphics.rectangle(
"fill",
self.x,
self.y,
self.width + self.padding.left + self.padding.right,
self.height + self.padding.top + self.padding.bottom
)
-- LAYER 2: Draw theme on top of backgroundColor (if theme exists)
if self.themeComponent then if self.themeComponent then
-- Get the theme to use -- Get the theme to use
local themeToUse = nil local themeToUse = nil
@@ -2204,7 +2217,6 @@ function Element:draw()
self.height + self.padding.top + self.padding.bottom, self.height + self.padding.top + self.padding.bottom,
self.opacity self.opacity
) )
hasTheme = true
else else
print("[FlexLove] No atlas for component: " .. self.themeComponent) print("[FlexLove] No atlas for component: " .. self.themeComponent)
end end
@@ -2216,24 +2228,7 @@ function Element:draw()
end end
end end
-- Draw background if no theme is used -- LAYER 3: Draw borders on top of theme (always render if specified)
if not hasTheme then
-- Apply opacity to all drawing operations
-- (x, y) represents border box, so draw background from (x, y)
local backgroundWithOpacity =
Color.new(drawBackground.r, drawBackground.g, drawBackground.b, drawBackground.a * self.opacity)
love.graphics.setColor(backgroundWithOpacity:toRGBA())
love.graphics.rectangle(
"fill",
self.x,
self.y,
self.width + self.padding.left + self.padding.right,
self.height + self.padding.top + self.padding.bottom
)
end
-- Draw borders based on border property (skip if using theme)
if not hasTheme then
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())
@@ -2259,7 +2254,6 @@ function Element:draw()
self.y + self.height + self.padding.top + self.padding.bottom self.y + self.height + self.padding.top + self.padding.bottom
) )
end end
end
-- Draw element text if present -- Draw element text if present
if self.text then if self.text then
@@ -2356,7 +2350,7 @@ function Element:update(dt)
self.opacity = anim.opacity or self.opacity self.opacity = anim.opacity or self.opacity
-- Update background color with interpolated opacity -- Update background color with interpolated opacity
if anim.opacity then if anim.opacity then
self.background.a = anim.opacity self.backgroundColor.a = anim.opacity
end end
end end
end end

View File

@@ -70,7 +70,7 @@ local pauseMenu = Gui.new({
flexDirection = "vertical", flexDirection = "vertical",
justifyContent = "center", justifyContent = "center",
alignItems = "center", alignItems = "center",
background = Color.new(0.1, 0.1, 0.1, 0.9), backgroundColor = Color.new(0.1, 0.1, 0.1, 0.9),
}) })
local title = Gui.new({ local title = Gui.new({

View File

@@ -19,7 +19,7 @@ function EventSystemDemo.init()
y = 50, y = 50,
width = 700, width = 700,
height = 500, height = 500,
background = Color.new(0.15, 0.15, 0.2, 0.95), backgroundColor = Color.new(0.15, 0.15, 0.2, 0.95),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.8, 0.8, 0.8, 1), borderColor = Color.new(0.8, 0.8, 0.8, 1),
positioning = "flex", positioning = "flex",
@@ -36,7 +36,7 @@ function EventSystemDemo.init()
textSize = 18, textSize = 18,
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.2, 0.2, 0.3, 1), backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
}) })
-- Button container -- Button container
@@ -46,7 +46,7 @@ function EventSystemDemo.init()
positioning = "flex", positioning = "flex",
flexDirection = "horizontal", flexDirection = "horizontal",
gap = 15, gap = 15,
background = Color.new(0.1, 0.1, 0.15, 0.5), backgroundColor = Color.new(0.1, 0.1, 0.15, 0.5),
padding = { top = 15, right = 15, bottom = 15, left = 15 }, padding = { top = 15, right = 15, bottom = 15, left = 15 },
}) })
@@ -67,7 +67,7 @@ function EventSystemDemo.init()
text = "Left Click Me", text = "Left Click Me",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.2, 0.6, 0.9, 0.8), backgroundColor = Color.new(0.2, 0.6, 0.9, 0.8),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.4, 0.8, 1, 1), borderColor = Color.new(0.4, 0.8, 1, 1),
callback = function(element, event) callback = function(element, event)
@@ -85,7 +85,7 @@ function EventSystemDemo.init()
text = "Right Click Me", text = "Right Click Me",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.9, 0.4, 0.4, 0.8), backgroundColor = Color.new(0.9, 0.4, 0.4, 0.8),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(1, 0.6, 0.6, 1), borderColor = Color.new(1, 0.6, 0.6, 1),
callback = function(element, event) callback = function(element, event)
@@ -105,7 +105,7 @@ function EventSystemDemo.init()
text = "Try Shift/Ctrl", text = "Try Shift/Ctrl",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.6, 0.9, 0.4, 0.8), backgroundColor = Color.new(0.6, 0.9, 0.4, 0.8),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.8, 1, 0.6, 1), borderColor = Color.new(0.8, 1, 0.6, 1),
callback = function(element, event) callback = function(element, event)
@@ -133,7 +133,7 @@ function EventSystemDemo.init()
text = "All Events", text = "All Events",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.9, 0.7, 0.3, 0.8), backgroundColor = Color.new(0.9, 0.7, 0.3, 0.8),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(1, 0.9, 0.5, 1), borderColor = Color.new(1, 0.9, 0.5, 1),
callback = function(element, event) callback = function(element, event)
@@ -151,7 +151,7 @@ function EventSystemDemo.init()
textSize = 14, textSize = 14,
textAlign = "start", textAlign = "start",
textColor = Color.new(0.9, 0.9, 1, 1), textColor = Color.new(0.9, 0.9, 1, 1),
background = Color.new(0.05, 0.05, 0.1, 1), backgroundColor = Color.new(0.05, 0.05, 0.1, 1),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.3, 0.3, 0.4, 1), borderColor = Color.new(0.3, 0.3, 0.4, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },

View File

@@ -20,7 +20,7 @@ function OnClickAnimDemo.init()
z = 10, z = 10,
w = 300, w = 300,
h = 200, h = 200,
background = Color.new(0.1, 0.1, 0.3, 0.8), backgroundColor = Color.new(0.1, 0.1, 0.3, 0.8),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.7, 0.7, 0.7, 1), borderColor = Color.new(0.7, 0.7, 0.7, 1),
}) })
@@ -33,7 +33,7 @@ function OnClickAnimDemo.init()
w = 100, w = 100,
h = 40, h = 40,
text = "Fade", text = "Fade",
background = Color.new(0.2, 0.9, 0.6, 0.8), backgroundColor = Color.new(0.2, 0.9, 0.6, 0.8),
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
borderColor = Color.new(0.4, 1, 0.8, 1), borderColor = Color.new(0.4, 1, 0.8, 1),
callback = function() callback = function()
@@ -51,7 +51,7 @@ function OnClickAnimDemo.init()
w = 100, w = 100,
h = 40, h = 40,
text = "Scale", text = "Scale",
background = Color.new(0.9, 0.6, 0.2, 0.8), backgroundColor = Color.new(0.9, 0.6, 0.2, 0.8),
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
borderColor = Color.new(1, 0.8, 0.4, 1), borderColor = Color.new(1, 0.8, 0.4, 1),
callback = function() callback = function()

View File

@@ -24,7 +24,7 @@ local grid1 = Gui.new({
gridColumns = 3, gridColumns = 3,
columnGap = 10, columnGap = 10,
rowGap = 10, rowGap = 10,
background = Color.new(0.9, 0.9, 0.9, 1), backgroundColor = Color.new(0.9, 0.9, 0.9, 1),
padding = { horizontal = 20, vertical = 20 }, padding = { horizontal = 20, vertical = 20 },
}) })
@@ -32,7 +32,7 @@ local grid1 = Gui.new({
for i = 1, 6 do for i = 1, 6 do
Gui.new({ Gui.new({
parent = grid1, parent = grid1,
background = Color.new(0.2, 0.5, 0.8, 1), backgroundColor = Color.new(0.2, 0.5, 0.8, 1),
text = "Item " .. i, text = "Item " .. i,
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -58,14 +58,14 @@ local grid2 = Gui.new({
gridColumns = 4, gridColumns = 4,
columnGap = 5, columnGap = 5,
rowGap = 5, rowGap = 5,
background = Color.new(0.9, 0.9, 0.9, 1), backgroundColor = Color.new(0.9, 0.9, 0.9, 1),
padding = { horizontal = 10, vertical = 10 }, padding = { horizontal = 10, vertical = 10 },
}) })
for i = 1, 16 do for i = 1, 16 do
Gui.new({ Gui.new({
parent = grid2, parent = grid2,
background = Color.new(0.3, 0.6, 0.3, 1), backgroundColor = Color.new(0.3, 0.6, 0.3, 1),
text = tostring(i), text = tostring(i),
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -90,7 +90,7 @@ local grid3 = Gui.new({
gridColumns = 5, gridColumns = 5,
columnGap = 10, columnGap = 10,
rowGap = 0, rowGap = 0,
background = Color.new(0.9, 0.9, 0.9, 1), backgroundColor = Color.new(0.9, 0.9, 0.9, 1),
padding = { horizontal = 10, vertical = 10 }, padding = { horizontal = 10, vertical = 10 },
}) })
@@ -98,7 +98,7 @@ local labels = { "Home", "Products", "About", "Contact", "Login" }
for i = 1, 5 do for i = 1, 5 do
Gui.new({ Gui.new({
parent = grid3, parent = grid3,
background = Color.new(0.3, 0.3, 0.8, 1), backgroundColor = Color.new(0.3, 0.3, 0.8, 1),
text = labels[i], text = labels[i],
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -122,14 +122,14 @@ local grid4 = Gui.new({
gridColumns = 1, gridColumns = 1,
columnGap = 0, columnGap = 0,
rowGap = 10, rowGap = 10,
background = Color.new(0.9, 0.9, 0.9, 1), backgroundColor = Color.new(0.9, 0.9, 0.9, 1),
padding = { horizontal = 10, vertical = 10 }, padding = { horizontal = 10, vertical = 10 },
}) })
for i = 1, 5 do for i = 1, 5 do
Gui.new({ Gui.new({
parent = grid4, parent = grid4,
background = Color.new(0.5, 0.3, 0.7, 1), backgroundColor = Color.new(0.5, 0.3, 0.7, 1),
text = "Option " .. i, text = "Option " .. i,
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -153,14 +153,14 @@ local outerGrid = Gui.new({
gridColumns = 2, gridColumns = 2,
columnGap = 10, columnGap = 10,
rowGap = 10, rowGap = 10,
background = Color.new(0.85, 0.85, 0.85, 1), backgroundColor = Color.new(0.85, 0.85, 0.85, 1),
padding = { horizontal = 10, vertical = 10 }, padding = { horizontal = 10, vertical = 10 },
}) })
-- Top-left: Simple item -- Top-left: Simple item
Gui.new({ Gui.new({
parent = outerGrid, parent = outerGrid,
background = Color.new(0.5, 0.3, 0.7, 1), backgroundColor = Color.new(0.5, 0.3, 0.7, 1),
text = "Single Item", text = "Single Item",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -174,14 +174,14 @@ local nestedGrid1 = Gui.new({
gridColumns = 2, gridColumns = 2,
columnGap = 5, columnGap = 5,
rowGap = 5, rowGap = 5,
background = Color.new(0.7, 0.7, 0.7, 1), backgroundColor = Color.new(0.7, 0.7, 0.7, 1),
padding = { horizontal = 5, vertical = 5 }, padding = { horizontal = 5, vertical = 5 },
}) })
for i = 1, 4 do for i = 1, 4 do
Gui.new({ Gui.new({
parent = nestedGrid1, parent = nestedGrid1,
background = Color.new(0.3, 0.6, 0.9, 1), backgroundColor = Color.new(0.3, 0.6, 0.9, 1),
text = "A" .. i, text = "A" .. i,
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -196,14 +196,14 @@ local nestedGrid2 = Gui.new({
gridColumns = 3, gridColumns = 3,
columnGap = 5, columnGap = 5,
rowGap = 5, rowGap = 5,
background = Color.new(0.7, 0.7, 0.7, 1), backgroundColor = Color.new(0.7, 0.7, 0.7, 1),
padding = { horizontal = 5, vertical = 5 }, padding = { horizontal = 5, vertical = 5 },
}) })
for i = 1, 3 do for i = 1, 3 do
Gui.new({ Gui.new({
parent = nestedGrid2, parent = nestedGrid2,
background = Color.new(0.9, 0.6, 0.3, 1), backgroundColor = Color.new(0.9, 0.6, 0.3, 1),
text = "B" .. i, text = "B" .. i,
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,
@@ -213,7 +213,7 @@ end
-- Bottom-right: Another simple item -- Bottom-right: Another simple item
Gui.new({ Gui.new({
parent = outerGrid, parent = outerGrid,
background = Color.new(0.3, 0.7, 0.5, 1), backgroundColor = Color.new(0.3, 0.7, 0.5, 1),
text = "Another Item", text = "Another Item",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
textAlign = enums.TextAlign.CENTER, textAlign = enums.TextAlign.CENTER,

View File

@@ -95,7 +95,7 @@ local box = Gui.new({
text = "Responsive Box", text = "Responsive Box",
textSize = "10ew", textSize = "10ew",
textAlign = "center", textAlign = "center",
background = Color.new(0.2, 0.2, 0.2), backgroundColor = Color.new(0.2, 0.2, 0.2),
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
print(" Initial (width=200): textSize = " .. box.textSize .. "px") print(" Initial (width=200): textSize = " .. box.textSize .. "px")

View File

@@ -73,7 +73,7 @@ local container = Gui.new({
flexDirection = "vertical", flexDirection = "vertical",
gap = 10, gap = 10,
padding = { horizontal = 20, vertical = 20 }, padding = { horizontal = 20, vertical = 20 },
background = Color.new(0.1, 0.1, 0.1), backgroundColor = Color.new(0.1, 0.1, 0.1),
}) })
local title = Gui.new({ local title = Gui.new({

View File

@@ -0,0 +1,196 @@
-- Demo showing the new layering system:
-- backgroundColor -> theme -> borders -> text
local FlexLove = require("FlexLove")
local Gui = FlexLove.GUI
local Theme = FlexLove.Theme
local Color = FlexLove.Color
function love.load()
-- Initialize FlexLove with the space theme
Gui.init({
baseScale = { width = 1920, height = 1080 },
theme = "space"
})
-- Create main container
local container = Gui.new({
x = 50,
y = 50,
width = 700,
height = 500,
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
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 = 40,
text = "Theme Layering Demo",
textSize = 24,
textAlign = "center",
textColor = Color.new(1, 1, 1, 1),
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
})
-- Description
Gui.new({
parent = container,
height = 60,
text = "Layering order: backgroundColor -> theme -> borders -> text\nAll layers are always rendered when specified",
textSize = 14,
textAlign = "center",
textColor = Color.new(0.8, 0.9, 1, 1),
backgroundColor = Color.new(0.15, 0.15, 0.2, 0.8),
padding = { top = 10, right = 10, bottom = 10, left = 10 },
})
-- Example 1: Theme with backgroundColor
local example1 = Gui.new({
parent = container,
height = 100,
positioning = "flex",
flexDirection = "vertical",
gap = 10,
backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 },
})
Gui.new({
parent = example1,
height = 20,
text = "Example 1: Theme with backgroundColor (red tint behind)",
textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1),
backgroundColor = Color.new(0, 0, 0, 0),
})
Gui.new({
parent = example1,
width = 200,
height = 50,
text = "Themed Button",
textAlign = "center",
textColor = Color.new(1, 1, 1, 1),
backgroundColor = Color.new(0.8, 0.2, 0.2, 0.5), -- Red tint behind theme
themeComponent = "button",
callback = function(element, event)
if event.type == "click" then
print("Button with backgroundColor clicked!")
end
end
})
-- Example 2: Theme with borders
local example2 = Gui.new({
parent = container,
height = 100,
positioning = "flex",
flexDirection = "vertical",
gap = 10,
backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 },
})
Gui.new({
parent = example2,
height = 20,
text = "Example 2: Theme with borders (yellow borders on top)",
textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1),
backgroundColor = Color.new(0, 0, 0, 0),
})
Gui.new({
parent = example2,
width = 200,
height = 50,
text = "Bordered Button",
textAlign = "center",
textColor = Color.new(1, 1, 1, 1),
backgroundColor = Color.new(0.2, 0.2, 0.3, 0.5),
border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(1, 1, 0, 1), -- Yellow border on top of theme
themeComponent = "button",
callback = function(element, event)
if event.type == "click" then
print("Button with borders clicked!")
end
end
})
-- Example 3: Theme with both backgroundColor and borders
local example3 = Gui.new({
parent = container,
height = 120,
positioning = "flex",
flexDirection = "vertical",
gap = 10,
backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 },
})
Gui.new({
parent = example3,
height = 20,
text = "Example 3: Theme with backgroundColor AND borders",
textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1),
backgroundColor = Color.new(0, 0, 0, 0),
})
Gui.new({
parent = example3,
width = 250,
height = 60,
text = "Full Layering",
textAlign = "center",
textColor = Color.new(1, 1, 1, 1),
backgroundColor = Color.new(0.2, 0.6, 0.8, 0.3), -- Blue tint behind
border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0, 1, 0, 1), -- Green border on top
themeComponent = "button",
callback = function(element, event)
if event.type == "click" then
print("Full layering button clicked!")
end
end
})
-- Example 4: Panel with backgroundColor
Gui.new({
x = 800,
y = 50,
width = 300,
height = 200,
backgroundColor = Color.new(0.3, 0.1, 0.3, 0.5), -- Purple tint
border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(1, 0.5, 0, 1), -- Orange border
themeComponent = "panel",
padding = { top = 20, right = 20, bottom = 20, left = 20 }
})
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("Theme Layering System", 10, 10)
love.graphics.print("Hover over buttons to see state changes", 10, 30)
end
function love.resize(w, h)
Gui.resize()
end

View File

@@ -30,7 +30,7 @@ function ThemeDemo.init()
y = 50, y = 50,
width = 700, width = 700,
height = 550, height = 550,
background = Color.new(0.15, 0.15, 0.2, 0.95), backgroundColor = Color.new(0.15, 0.15, 0.2, 0.95),
border = { top = true, bottom = true, left = true, right = true }, border = { top = true, bottom = true, left = true, right = true },
borderColor = Color.new(0.8, 0.8, 0.8, 1), borderColor = Color.new(0.8, 0.8, 0.8, 1),
positioning = "flex", positioning = "flex",
@@ -47,7 +47,7 @@ function ThemeDemo.init()
textSize = 20, textSize = 20,
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.2, 0.2, 0.3, 1), backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
}) })
-- Status message -- Status message
@@ -59,7 +59,7 @@ function ThemeDemo.init()
textSize = 14, textSize = 14,
textAlign = "center", textAlign = "center",
textColor = themeLoaded and Color.new(0.3, 0.9, 0.3, 1) or Color.new(0.9, 0.7, 0.3, 1), textColor = themeLoaded and Color.new(0.3, 0.9, 0.3, 1) or Color.new(0.9, 0.7, 0.3, 1),
background = Color.new(0.1, 0.1, 0.15, 0.8), backgroundColor = Color.new(0.1, 0.1, 0.15, 0.8),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -70,7 +70,7 @@ function ThemeDemo.init()
positioning = "flex", positioning = "flex",
flexDirection = "vertical", flexDirection = "vertical",
gap = 15, gap = 15,
background = Color.new(0.1, 0.1, 0.15, 0.5), backgroundColor = Color.new(0.1, 0.1, 0.15, 0.5),
padding = { top = 15, right = 15, bottom = 15, left = 15 }, padding = { top = 15, right = 15, bottom = 15, left = 15 },
}) })
@@ -81,7 +81,7 @@ function ThemeDemo.init()
positioning = "flex", positioning = "flex",
flexDirection = "vertical", flexDirection = "vertical",
gap = 10, gap = 10,
background = Color.new(0.12, 0.12, 0.17, 1), backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -91,7 +91,7 @@ function ThemeDemo.init()
text = "Example 1: Basic Themed Button", text = "Example 1: Basic Themed Button",
textSize = 14, textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1), textColor = Color.new(0.8, 0.9, 1, 1),
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
-- This button would use theme if loaded -- This button would use theme if loaded
@@ -102,7 +102,7 @@ function ThemeDemo.init()
text = "Themed Button", text = "Themed Button",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.2, 0.6, 0.9, 0.8), backgroundColor = Color.new(0.2, 0.6, 0.9, 0.8),
-- theme = "button", -- Uncomment when theme atlas exists -- theme = "button", -- Uncomment when theme atlas exists
callback = function(element, event) callback = function(element, event)
if event.type == "click" then if event.type == "click" then
@@ -118,7 +118,7 @@ function ThemeDemo.init()
positioning = "flex", positioning = "flex",
flexDirection = "vertical", flexDirection = "vertical",
gap = 10, gap = 10,
background = Color.new(0.12, 0.12, 0.17, 1), backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -128,7 +128,7 @@ function ThemeDemo.init()
text = "Example 2: Button with Hover/Pressed States", text = "Example 2: Button with Hover/Pressed States",
textSize = 14, textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1), textColor = Color.new(0.8, 0.9, 1, 1),
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
Gui.new({ Gui.new({
@@ -137,7 +137,7 @@ function ThemeDemo.init()
text = "Hover over or click the button to see state changes (when theme is loaded)", text = "Hover over or click the button to see state changes (when theme is loaded)",
textSize = 11, textSize = 11,
textColor = Color.new(0.6, 0.7, 0.8, 1), textColor = Color.new(0.6, 0.7, 0.8, 1),
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
local stateButton = Gui.new({ local stateButton = Gui.new({
@@ -147,7 +147,7 @@ function ThemeDemo.init()
text = "Interactive Button", text = "Interactive Button",
textAlign = "center", textAlign = "center",
textColor = Color.new(1, 1, 1, 1), textColor = Color.new(1, 1, 1, 1),
background = Color.new(0.3, 0.7, 0.4, 0.8), backgroundColor = Color.new(0.3, 0.7, 0.4, 0.8),
-- theme = "button", -- Will automatically handle hover/pressed states -- theme = "button", -- Will automatically handle hover/pressed states
callback = function(element, event) callback = function(element, event)
if event.type == "click" then if event.type == "click" then
@@ -163,7 +163,7 @@ function ThemeDemo.init()
positioning = "flex", positioning = "flex",
flexDirection = "vertical", flexDirection = "vertical",
gap = 10, gap = 10,
background = Color.new(0.12, 0.12, 0.17, 1), backgroundColor = Color.new(0.12, 0.12, 0.17, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -173,14 +173,14 @@ function ThemeDemo.init()
text = "Example 3: Themed Panel/Container", text = "Example 3: Themed Panel/Container",
textSize = 14, textSize = 14,
textColor = Color.new(0.8, 0.9, 1, 1), textColor = Color.new(0.8, 0.9, 1, 1),
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
local themedPanel = Gui.new({ local themedPanel = Gui.new({
parent = example3, parent = example3,
width = 300, width = 300,
height = 80, height = 80,
background = Color.new(0.25, 0.25, 0.35, 0.9), backgroundColor = Color.new(0.25, 0.25, 0.35, 0.9),
-- theme = "panel", -- Would use panel theme component -- theme = "panel", -- Would use panel theme component
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -191,14 +191,14 @@ function ThemeDemo.init()
textSize = 12, textSize = 12,
textColor = Color.new(0.9, 0.9, 1, 1), textColor = Color.new(0.9, 0.9, 1, 1),
textAlign = "center", textAlign = "center",
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
-- Code example section -- Code example section
local codeSection = Gui.new({ local codeSection = Gui.new({
parent = self.window, parent = self.window,
height = 40, height = 40,
background = Color.new(0.08, 0.08, 0.12, 1), backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
padding = { top = 10, right = 10, bottom = 10, left = 10 }, padding = { top = 10, right = 10, bottom = 10, left = 10 },
}) })
@@ -207,7 +207,7 @@ function ThemeDemo.init()
text = 'Usage: element = Gui.new({ theme = "button", ... })', text = 'Usage: element = Gui.new({ theme = "button", ... })',
textSize = 12, textSize = 12,
textColor = Color.new(0.5, 0.9, 0.5, 1), textColor = Color.new(0.5, 0.9, 0.5, 1),
background = Color.new(0, 0, 0, 0), backgroundColor = Color.new(0, 0, 0, 0),
}) })
return self return self

View File

@@ -20,7 +20,7 @@ local back = Gui.new({
width = 100, width = 100,
height = 100, height = 100,
z = 1, z = 1,
background = Color.new(1, 0, 0, 0.8), backgroundColor = Color.new(1, 0, 0, 0.8),
text = "Z=1 (Back)", text = "Z=1 (Back)",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -32,7 +32,7 @@ local middle = Gui.new({
width = 100, width = 100,
height = 100, height = 100,
z = 2, z = 2,
background = Color.new(0, 1, 0, 0.8), backgroundColor = Color.new(0, 1, 0, 0.8),
text = "Z=2 (Middle)", text = "Z=2 (Middle)",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -44,7 +44,7 @@ local front = Gui.new({
width = 100, width = 100,
height = 100, height = 100,
z = 3, z = 3,
background = Color.new(0, 0, 1, 0.8), backgroundColor = Color.new(0, 0, 1, 0.8),
text = "Z=3 (Front)", text = "Z=3 (Front)",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -75,7 +75,7 @@ local parent = Gui.new({
y = 0, y = 0,
width = 300, width = 300,
height = 300, height = 300,
background = Color.new(0.1, 0.1, 0.1, 1), backgroundColor = Color.new(0.1, 0.1, 0.1, 1),
}) })
-- Create children in random z-order -- Create children in random z-order
@@ -87,7 +87,7 @@ local child3 = Gui.new({
width = 80, width = 80,
height = 80, height = 80,
z = 3, z = 3,
background = Color.new(0, 0, 1, 0.8), backgroundColor = Color.new(0, 0, 1, 0.8),
text = "Z=3", text = "Z=3",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -100,7 +100,7 @@ local child1 = Gui.new({
width = 80, width = 80,
height = 80, height = 80,
z = 1, z = 1,
background = Color.new(1, 0, 0, 0.8), backgroundColor = Color.new(1, 0, 0, 0.8),
text = "Z=1", text = "Z=1",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -113,7 +113,7 @@ local child2 = Gui.new({
width = 80, width = 80,
height = 80, height = 80,
z = 2, z = 2,
background = Color.new(0, 1, 0, 0.8), backgroundColor = Color.new(0, 1, 0, 0.8),
text = "Z=2", text = "Z=2",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -131,14 +131,14 @@ print(" Z-index can be negative for background elements\n")
Gui.destroy() Gui.destroy()
local background = Gui.new({ local backgroundColor = Gui.new({
id = "background", id = "background",
x = 0, x = 0,
y = 0, y = 0,
width = 200, width = 200,
height = 200, height = 200,
z = -1, z = -1,
background = Color.new(0.2, 0.2, 0.2, 1), backgroundColor = Color.new(0.2, 0.2, 0.2, 1),
text = "Background (z=-1)", text = "Background (z=-1)",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -150,7 +150,7 @@ local normal = Gui.new({
width = 100, width = 100,
height = 100, height = 100,
z = 0, z = 0,
background = Color.new(0.5, 0.5, 0.5, 1), backgroundColor = Color.new(0.5, 0.5, 0.5, 1),
text = "Normal (z=0)", text = "Normal (z=0)",
textColor = Color.new(1, 1, 1), textColor = Color.new(1, 1, 1),
}) })
@@ -175,7 +175,7 @@ local default1 = Gui.new({
y = 10, y = 10,
width = 50, width = 50,
height = 50, height = 50,
background = Color.new(1, 0, 0, 1), backgroundColor = Color.new(1, 0, 0, 1),
}) })
local explicit = Gui.new({ local explicit = Gui.new({
@@ -185,7 +185,7 @@ local explicit = Gui.new({
width = 50, width = 50,
height = 50, height = 50,
z = 1, z = 1,
background = Color.new(0, 1, 0, 1), backgroundColor = Color.new(0, 1, 0, 1),
}) })
local default2 = Gui.new({ local default2 = Gui.new({
@@ -194,7 +194,7 @@ local default2 = Gui.new({
y = 50, y = 50,
width = 50, width = 50,
height = 50, height = 50,
background = Color.new(0, 0, 1, 1), backgroundColor = Color.new(0, 0, 1, 1),
}) })
print("default1.z =", default1.z, "(default)") print("default1.z =", default1.z, "(default)")

View File

@@ -595,7 +595,7 @@ function TestAbsolutePositioningBasic:testMultiBranchZIndexStacking()
}) })
-- Background layer (z=1) -- Background layer (z=1)
local background = Gui.new({ local backgroundColor = Gui.new({
parent = container, parent = container,
id = "background", id = "background",
x = 100, x = 100,

View File

@@ -18,7 +18,7 @@ function TestRelativePositioning.testBasicRelativePositioning()
width = 200, width = 200,
height = 150, height = 150,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.2, 0.2, 1.0),
}) })
local child = Gui.new({ local child = Gui.new({
@@ -28,7 +28,7 @@ function TestRelativePositioning.testBasicRelativePositioning()
width = 50, width = 50,
height = 40, height = 40,
positioning = "relative", positioning = "relative",
background = Color.new(0.8, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.8, 0.2, 0.2, 1.0),
}) })
-- Child should be positioned relative to parent -- Child should be positioned relative to parent
@@ -45,7 +45,7 @@ function TestRelativePositioning.testRelativePositioningPercentages()
width = 200, width = 200,
height = 100, height = 100,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.2, 0.2, 1.0),
}) })
local child = Gui.new({ local child = Gui.new({
@@ -55,7 +55,7 @@ function TestRelativePositioning.testRelativePositioningPercentages()
width = 30, width = 30,
height = 20, height = 20,
positioning = "relative", positioning = "relative",
background = Color.new(0.8, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.8, 0.2, 0.2, 1.0),
}) })
-- Child should be positioned relative to parent with percentage offsets -- Child should be positioned relative to parent with percentage offsets
@@ -72,7 +72,7 @@ function TestRelativePositioning.testRelativePositioningNoOffset()
width = 150, width = 150,
height = 200, height = 200,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.2, 0.2, 1.0),
}) })
local child = Gui.new({ local child = Gui.new({
@@ -80,7 +80,7 @@ function TestRelativePositioning.testRelativePositioningNoOffset()
width = 40, width = 40,
height = 30, height = 30,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.8, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.8, 0.2, 1.0),
}) })
-- Child should be positioned at parent's position with no offset -- Child should be positioned at parent's position with no offset
@@ -97,7 +97,7 @@ function TestRelativePositioning.testMultipleRelativeChildren()
width = 100, width = 100,
height = 100, height = 100,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.2, 0.2, 1.0),
}) })
local child1 = Gui.new({ local child1 = Gui.new({
@@ -107,7 +107,7 @@ function TestRelativePositioning.testMultipleRelativeChildren()
width = 20, width = 20,
height = 20, height = 20,
positioning = "relative", positioning = "relative",
background = Color.new(0.8, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.8, 0.2, 0.2, 1.0),
}) })
local child2 = Gui.new({ local child2 = Gui.new({
@@ -117,7 +117,7 @@ function TestRelativePositioning.testMultipleRelativeChildren()
width = 25, width = 25,
height = 25, height = 25,
positioning = "relative", positioning = "relative",
background = Color.new(0.2, 0.8, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.8, 0.2, 1.0),
}) })
-- Both children should be positioned relative to parent -- Both children should be positioned relative to parent
@@ -136,7 +136,7 @@ function TestRelativePositioning.testNestedRelativePositioning()
width = 300, width = 300,
height = 250, height = 250,
positioning = "relative", positioning = "relative",
background = Color.new(0.1, 0.1, 0.1, 1.0), backgroundColor = Color.new(0.1, 0.1, 0.1, 1.0),
}) })
local parent = Gui.new({ local parent = Gui.new({
@@ -146,7 +146,7 @@ function TestRelativePositioning.testNestedRelativePositioning()
width = 200, width = 200,
height = 150, height = 150,
positioning = "relative", positioning = "relative",
background = Color.new(0.3, 0.3, 0.3, 1.0), backgroundColor = Color.new(0.3, 0.3, 0.3, 1.0),
}) })
local child = Gui.new({ local child = Gui.new({
@@ -156,7 +156,7 @@ function TestRelativePositioning.testNestedRelativePositioning()
width = 50, width = 50,
height = 40, height = 40,
positioning = "relative", positioning = "relative",
background = Color.new(0.8, 0.8, 0.8, 1.0), backgroundColor = Color.new(0.8, 0.8, 0.8, 1.0),
}) })
-- Each level should be positioned relative to its parent -- Each level should be positioned relative to its parent
@@ -175,7 +175,7 @@ function TestRelativePositioning.testMixedPositioning()
width = 180, width = 180,
height = 120, height = 120,
positioning = "absolute", positioning = "absolute",
background = Color.new(0.2, 0.2, 0.2, 1.0), backgroundColor = Color.new(0.2, 0.2, 0.2, 1.0),
}) })
local child = Gui.new({ local child = Gui.new({
@@ -185,7 +185,7 @@ function TestRelativePositioning.testMixedPositioning()
width = 60, width = 60,
height = 35, height = 35,
positioning = "relative", positioning = "relative",
background = Color.new(0.8, 0.8, 0.2, 1.0), backgroundColor = Color.new(0.8, 0.8, 0.2, 1.0),
}) })
-- Relative child should still be positioned relative to absolute parent -- Relative child should still be positioned relative to absolute parent