theme update

This commit is contained in:
Michael Freno
2025-10-14 20:22:58 -04:00
parent bde22c7ffa
commit 120e69bfdb
3 changed files with 293 additions and 116 deletions

View File

@@ -329,6 +329,7 @@ end
---@field regions {topLeft:ThemeRegion, topCenter:ThemeRegion, topRight:ThemeRegion, middleLeft:ThemeRegion, middleCenter:ThemeRegion, middleRight:ThemeRegion, bottomLeft:ThemeRegion, bottomCenter:ThemeRegion, bottomRight:ThemeRegion} ---@field regions {topLeft:ThemeRegion, topCenter:ThemeRegion, topRight:ThemeRegion, middleLeft:ThemeRegion, middleCenter:ThemeRegion, middleRight:ThemeRegion, bottomLeft:ThemeRegion, bottomCenter:ThemeRegion, bottomRight:ThemeRegion}
---@field stretch {horizontal:table<integer, string>, vertical:table<integer, string>} ---@field stretch {horizontal:table<integer, string>, vertical:table<integer, string>}
---@field states table<string, ThemeComponent>? ---@field states table<string, ThemeComponent>?
---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Optional: multiplier for auto-sized content dimensions
---@field _loadedAtlas love.Image? -- Internal: cached loaded atlas image ---@field _loadedAtlas love.Image? -- Internal: cached loaded atlas image
---@class FontFamily ---@class FontFamily
@@ -341,6 +342,7 @@ end
---@field components table<string, ThemeComponent> ---@field components table<string, ThemeComponent>
---@field colors table<string, Color>? ---@field colors table<string, Color>?
---@field fonts table<string, string>? -- Optional: font family definitions (name -> path) ---@field fonts table<string, string>? -- Optional: font family definitions (name -> path)
---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Optional: default multiplier for auto-sized content dimensions
---@class Theme ---@class Theme
---@field name string ---@field name string
@@ -348,6 +350,7 @@ end
---@field components table<string, ThemeComponent> ---@field components table<string, ThemeComponent>
---@field colors table<string, Color> ---@field colors table<string, Color>
---@field fonts table<string, string> -- Font family definitions ---@field fonts table<string, string> -- Font family definitions
---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Optional: default multiplier for auto-sized content dimensions
local Theme = {} local Theme = {}
Theme.__index = Theme Theme.__index = Theme
@@ -483,6 +486,7 @@ function Theme.new(definition)
self.components = definition.components or {} self.components = definition.components or {}
self.colors = definition.colors or {} self.colors = definition.colors or {}
self.fonts = definition.fonts or {} self.fonts = definition.fonts or {}
self.contentAutoSizingMultiplier = definition.contentAutoSizingMultiplier or nil
-- Load component-specific atlases -- Load component-specific atlases
for componentName, component in pairs(self.components) do for componentName, component in pairs(self.components) do
@@ -1865,6 +1869,7 @@ Public API methods to access internal state:
---@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) ---@field disableHighlight boolean? -- Whether to disable the pressed state highlight overlay (default: false)
---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Multiplier for auto-sized content dimensions
local Element = {} local Element = {}
Element.__index = Element Element.__index = Element
@@ -1915,6 +1920,7 @@ Element.__index = Element
---@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) ---@field disableHighlight boolean? -- Whether to disable the pressed state highlight overlay (default: false)
---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Multiplier for auto-sized content dimensions (default: sourced from theme)
local ElementProps = {} local ElementProps = {}
---@param props ElementProps ---@param props ElementProps
@@ -1954,6 +1960,37 @@ function Element.new(props)
self.disableHighlight = self.themeComponent ~= nil self.disableHighlight = self.themeComponent ~= nil
end end
-- Initialize contentAutoSizingMultiplier after theme is set
-- Priority: element props > theme component > theme default
if props.contentAutoSizingMultiplier then
-- Explicitly set on element
self.contentAutoSizingMultiplier = props.contentAutoSizingMultiplier
else
-- Try to source from theme
local themeToUse = self.theme and themes[self.theme] or Theme.getActive()
if themeToUse then
-- First check if themeComponent has a multiplier
if self.themeComponent then
local component = themeToUse.components[self.themeComponent]
if component and component.contentAutoSizingMultiplier then
self.contentAutoSizingMultiplier = component.contentAutoSizingMultiplier
elseif themeToUse.contentAutoSizingMultiplier then
-- Fall back to theme default
self.contentAutoSizingMultiplier = themeToUse.contentAutoSizingMultiplier
else
self.contentAutoSizingMultiplier = nil
end
elseif themeToUse.contentAutoSizingMultiplier then
-- No themeComponent, use theme default
self.contentAutoSizingMultiplier = themeToUse.contentAutoSizingMultiplier
else
self.contentAutoSizingMultiplier = nil
end
else
self.contentAutoSizingMultiplier = nil
end
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
@@ -3945,11 +3982,19 @@ function Element:calculateTextWidth()
local tempFont = FONT_CACHE.get(self.textSize, fontPath) local tempFont = FONT_CACHE.get(self.textSize, fontPath)
local width = tempFont:getWidth(self.text) local width = tempFont:getWidth(self.text)
-- Apply contentAutoSizingMultiplier if set
if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.width then
width = width * self.contentAutoSizingMultiplier.width
end
return width return width
end end
local font = love.graphics.getFont() local font = love.graphics.getFont()
local width = font:getWidth(self.text) local width = font:getWidth(self.text)
-- Apply contentAutoSizingMultiplier if set
if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.width then
width = width * self.contentAutoSizingMultiplier.width
end
return width return width
end end
@@ -3978,11 +4023,19 @@ function Element:calculateTextHeight()
local tempFont = FONT_CACHE.get(self.textSize, fontPath) local tempFont = FONT_CACHE.get(self.textSize, fontPath)
local height = tempFont:getHeight() local height = tempFont:getHeight()
-- Apply contentAutoSizingMultiplier if set
if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.height then
height = height * self.contentAutoSizingMultiplier.height
end
return height return height
end end
local font = love.graphics.getFont() local font = love.graphics.getFont()
local height = font:getHeight() local height = font:getHeight()
-- Apply contentAutoSizingMultiplier if set
if self.contentAutoSizingMultiplier and self.contentAutoSizingMultiplier.height then
height = height * self.contentAutoSizingMultiplier.height
end
return height return height
end end

View File

@@ -0,0 +1,115 @@
-- ContentAutoSizingMultiplier Demo
-- Demonstrates how to use contentAutoSizingMultiplier to add padding/spacing
-- to auto-sized text elements without using explicit padding
local FlexLove = require("libs.FlexLove")
function love.load()
-- Initialize with space theme (has contentAutoSizingMultiplier: width=1.05, height=1.1)
FlexLove.Gui.init({
baseScale = { width = 1920, height = 1080 },
theme = "space",
})
-- Example 1: Text element with theme's default multiplier
-- The space theme has width=1.05 (5% wider) and height=1.1 (10% taller)
FlexLove.Element.new({
x = "10vw",
y = "10vh",
text = "Theme Default Multiplier",
textSize = "lg",
textColor = FlexLove.Color.new(1, 1, 1, 1),
backgroundColor = FlexLove.Color.new(0.2, 0.2, 0.8, 0.8),
themeComponent = "button", -- Uses theme's contentAutoSizingMultiplier
})
-- Example 2: Text element with custom multiplier (override theme)
-- This will be 20% wider and 30% taller than the actual text
FlexLove.Element.new({
x = "10vw",
y = "25vh",
text = "Custom Multiplier (1.2x, 1.3x)",
textSize = "lg",
textColor = FlexLove.Color.new(1, 1, 1, 1),
backgroundColor = FlexLove.Color.new(0.8, 0.2, 0.2, 0.8),
themeComponent = "button",
contentAutoSizingMultiplier = { width = 1.2, height = 1.3 },
})
-- Example 3: Text element with no multiplier
-- This will be exactly the size of the text (no extra space)
FlexLove.Element.new({
x = "10vw",
y = "40vh",
text = "No Multiplier (exact fit)",
textSize = "lg",
textColor = FlexLove.Color.new(1, 1, 1, 1),
backgroundColor = FlexLove.Color.new(0.2, 0.8, 0.2, 0.8),
contentAutoSizingMultiplier = { width = 1.0, height = 1.0 },
})
-- Example 4: Container with multiple text elements
-- Shows how multiplier affects layout in flex containers
local container = FlexLove.Element.new({
x = "10vw",
y = "55vh",
positioning = FlexLove.Positioning.FLEX,
flexDirection = FlexLove.FlexDirection.HORIZONTAL,
gap = 10,
backgroundColor = FlexLove.Color.new(0.1, 0.1, 0.1, 0.8),
padding = { horizontal = 20, vertical = 10 },
})
for i = 1, 3 do
FlexLove.Element.new({
parent = container,
text = "Item " .. i,
textSize = "md",
textColor = FlexLove.Color.new(1, 1, 1, 1),
backgroundColor = FlexLove.Color.new(0.3, 0.3, 0.6, 0.8),
themeComponent = "button", -- Uses theme's multiplier
})
end
-- Example 5: Width-only multiplier
-- Useful for creating horizontal padding without vertical padding
FlexLove.Element.new({
x = "10vw",
y = "75vh",
text = "Wide Button (1.5x width, 1.0x height)",
textSize = "lg",
textColor = FlexLove.Color.new(1, 1, 1, 1),
backgroundColor = FlexLove.Color.new(0.6, 0.3, 0.6, 0.8),
contentAutoSizingMultiplier = { width = 1.5, height = 1.0 },
})
-- Info text
FlexLove.Element.new({
x = "50vw",
y = "10vh",
text = "contentAutoSizingMultiplier Demo\n\n"
.. "This feature multiplies auto-sized dimensions:\n"
.. "- Theme default: width=1.05, height=1.1\n"
.. "- Can be overridden per element\n"
.. "- Useful for adding visual breathing room\n"
.. "- Works with text and child-based sizing",
textSize = "sm",
textColor = FlexLove.Color.new(0.9, 0.9, 0.9, 1),
backgroundColor = FlexLove.Color.new(0.15, 0.15, 0.15, 0.9),
padding = { horizontal = 20, vertical = 15 },
})
end
function love.update(dt)
FlexLove.Gui.update(dt)
end
function love.draw()
-- Dark background
love.graphics.clear(0.05, 0.05, 0.1, 1)
FlexLove.Gui.draw()
end
function love.resize()
FlexLove.Gui.resize()
end

View File

@@ -17,43 +17,110 @@ end
return { return {
name = "Space Theme", name = "Space Theme",
contentAutoSizingMultiplier = { height = 1.1, width = 1.05 },
components = { components = {
-- Panel component (882x687 with 110px border) card = {
panel = { atlas = "themes/space/card.png",
atlas = "themes/space/panel.png",
regions = { regions = {
-- 9-slice regions for 882x687 image (110-662-110 split) topLeft = { x = 0, y = 0, width = 100, height = 100 },
-- Top row topCenter = { x = 100, y = 0, width = 205, height = 100 },
topLeft = { x = 0, y = 0, w = 110, h = 110 }, topRight = { x = 305, y = 0, width = 100, height = 100 },
topCenter = { x = 110, y = 0, w = 662, h = 110 }, middleLeft = { x = 0, y = 100, width = 100, height = 178 },
topRight = { x = 772, y = 0, w = 110, h = 110 }, middleCenter = { x = 100, y = 100, width = 205, height = 178 },
-- Middle row (stretchable) middleRight = { x = 305, y = 100, width = 100, height = 178 },
middleLeft = { x = 0, y = 110, w = 110, h = 467 }, bottomLeft = { x = 0, y = 278, width = 100, height = 100 },
middleCenter = { x = 110, y = 110, w = 662, h = 467 }, bottomCenter = { x = 100, y = 278, width = 205, height = 100 },
middleRight = { x = 772, y = 110, w = 110, h = 467 }, bottomRight = { x = 305, y = 278, width = 100, height = 100 },
-- Bottom row
bottomLeft = { x = 0, y = 577, w = 110, h = 110 },
bottomCenter = { x = 110, y = 577, w = 662, h = 110 },
bottomRight = { x = 772, y = 577, w = 110, h = 110 },
}, },
stretch = { stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" }, horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" }, vertical = { "middleLeft", "middleCenter", "middleRight" },
}, },
}, },
cardv2 = {
button = { atlas = "themes/space/card-v2.png",
atlas = "themes/space/interactive.png",
regions = { regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 }, topLeft = { x = 0, y = 0, width = 100, height = 100 },
topCenter = { x = 31, y = 0, w = 127, h = 31 }, topCenter = { x = 100, y = 0, width = 205, height = 100 },
topRight = { x = 158, y = 0, w = 31, h = 31 }, topRight = { x = 305, y = 0, width = 100, height = 100 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 }, middleLeft = { x = 0, y = 100, width = 100, height = 178 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 }, middleCenter = { x = 100, y = 100, width = 205, height = 178 },
middleRight = { x = 158, y = 31, w = 31, h = 127 }, middleRight = { x = 305, y = 100, width = 100, height = 178 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 }, bottomLeft = { x = 0, y = 278, width = 100, height = 100 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 }, bottomCenter = { x = 100, y = 278, width = 205, height = 100 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 }, bottomRight = { x = 305, y = 278, width = 100, height = 100 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
panel = {
atlas = "themes/space/panel.png",
regions = {
topLeft = { x = 0, y = 0, width = 38, height = 30 },
topCenter = { x = 38, y = 0, width = 53, height = 30 },
topRight = { x = 91, y = 0, width = 22, height = 30 },
middleLeft = { x = 0, y = 30, width = 38, height = 5 },
middleCenter = { x = 38, y = 30, width = 53, height = 5 },
middleRight = { x = 91, y = 30, width = 22, height = 5 },
bottomLeft = { x = 0, y = 35, width = 38, height = 30 },
bottomCenter = { x = 38, y = 35, width = 53, height = 30 },
bottomRight = { x = 91, y = 35, width = 22, height = 30 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
panelred = {
atlas = "themes/space/panel-red.png",
regions = {
topLeft = { x = 0, y = 0, width = 38, height = 30 },
topCenter = { x = 38, y = 0, width = 53, height = 30 },
topRight = { x = 91, y = 0, width = 22, height = 30 },
middleLeft = { x = 0, y = 30, width = 38, height = 5 },
middleCenter = { x = 38, y = 30, width = 53, height = 5 },
middleRight = { x = 91, y = 30, width = 22, height = 5 },
bottomLeft = { x = 0, y = 35, width = 38, height = 30 },
bottomCenter = { x = 38, y = 35, width = 53, height = 30 },
bottomRight = { x = 91, y = 35, width = 22, height = 30 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
panelgreen = {
atlas = "themes/space/panel-green.png",
regions = {
topLeft = { x = 0, y = 0, width = 38, height = 30 },
topCenter = { x = 38, y = 0, width = 53, height = 30 },
topRight = { x = 91, y = 0, width = 22, height = 30 },
middleLeft = { x = 0, y = 30, width = 38, height = 5 },
middleCenter = { x = 38, y = 30, width = 53, height = 5 },
middleRight = { x = 91, y = 30, width = 22, height = 5 },
bottomLeft = { x = 0, y = 35, width = 38, height = 30 },
bottomCenter = { x = 38, y = 35, width = 53, height = 30 },
bottomRight = { x = 91, y = 35, width = 22, height = 30 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
button = {
atlas = "themes/space/button.png",
regions = {
topLeft = { x = 0, y = 0, width = 14, height = 14 },
topCenter = { x = 14, y = 0, width = 86, height = 14 },
topRight = { x = 100, y = 0, width = 14, height = 14 },
middleLeft = { x = 0, y = 14, width = 14, height = 10 },
middleCenter = { x = 14, y = 14, width = 86, height = 10 },
middleRight = { x = 100, y = 14, width = 14, height = 10 },
bottomLeft = { x = 0, y = 24, width = 14, height = 14 },
bottomCenter = { x = 14, y = 24, width = 86, height = 14 },
bottomRight = { x = 100, y = 24, width = 14, height = 14 },
}, },
stretch = { stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" }, horizontal = { "topCenter", "middleCenter", "bottomCenter" },
@@ -61,17 +128,17 @@ return {
}, },
states = { states = {
hover = { hover = {
atlas = "themes/space/interactive-hover.png", atlas = "themes/space/button-hover.png",
regions = { regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 }, topLeft = { x = 0, y = 0, width = 14, height = 14 },
topCenter = { x = 31, y = 0, w = 127, h = 31 }, topCenter = { x = 14, y = 0, width = 86, height = 14 },
topRight = { x = 158, y = 0, w = 31, h = 31 }, topRight = { x = 100, y = 0, width = 14, height = 14 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 }, middleLeft = { x = 0, y = 14, width = 14, height = 10 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 }, middleCenter = { x = 14, y = 14, width = 86, height = 10 },
middleRight = { x = 158, y = 31, w = 31, h = 127 }, middleRight = { x = 100, y = 14, width = 14, height = 10 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 }, bottomLeft = { x = 0, y = 24, width = 14, height = 14 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 }, bottomCenter = { x = 14, y = 24, width = 86, height = 14 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 }, bottomRight = { x = 100, y = 24, width = 14, height = 14 },
}, },
stretch = { stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" }, horizontal = { "topCenter", "middleCenter", "bottomCenter" },
@@ -79,17 +146,17 @@ return {
}, },
}, },
pressed = { pressed = {
atlas = "themes/space/interactive-pressed.png", atlas = "themes/space/button-pressed.png",
regions = { regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 }, topLeft = { x = 0, y = 0, width = 14, height = 14 },
topCenter = { x = 31, y = 0, w = 127, h = 31 }, topCenter = { x = 14, y = 0, width = 86, height = 14 },
topRight = { x = 158, y = 0, w = 31, h = 31 }, topRight = { x = 100, y = 0, width = 14, height = 14 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 }, middleLeft = { x = 0, y = 14, width = 14, height = 10 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 }, middleCenter = { x = 14, y = 14, width = 86, height = 10 },
middleRight = { x = 158, y = 31, w = 31, h = 127 }, middleRight = { x = 100, y = 14, width = 14, height = 10 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 }, bottomLeft = { x = 0, y = 24, width = 14, height = 14 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 }, bottomCenter = { x = 14, y = 24, width = 86, height = 14 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 }, bottomRight = { x = 100, y = 24, width = 14, height = 14 },
}, },
stretch = { stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" }, horizontal = { "topCenter", "middleCenter", "bottomCenter" },
@@ -97,75 +164,17 @@ return {
}, },
}, },
disabled = { disabled = {
atlas = "themes/space/interactive-disabled.png", atlas = "themes/space/button-disabled.png",
regions = { regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 }, topLeft = { x = 0, y = 0, width = 14, height = 14 },
topCenter = { x = 31, y = 0, w = 127, h = 31 }, topCenter = { x = 14, y = 0, width = 86, height = 14 },
topRight = { x = 158, y = 0, w = 31, h = 31 }, topRight = { x = 100, y = 0, width = 14, height = 14 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 }, middleLeft = { x = 0, y = 14, width = 14, height = 10 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 }, middleCenter = { x = 14, y = 14, width = 86, height = 10 },
middleRight = { x = 158, y = 31, w = 31, h = 127 }, middleRight = { x = 100, y = 14, width = 14, height = 10 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 }, bottomLeft = { x = 0, y = 24, width = 14, height = 14 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 }, bottomCenter = { x = 14, y = 24, width = 86, height = 14 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 }, bottomRight = { x = 100, y = 24, width = 14, height = 14 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
},
},
-- Input component with active and disabled states
input = {
atlas = "themes/space/interactive.png",
regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 },
topCenter = { x = 31, y = 0, w = 127, h = 31 },
topRight = { x = 158, y = 0, w = 31, h = 31 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 },
middleRight = { x = 158, y = 31, w = 31, h = 127 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
states = {
active = {
atlas = "themes/space/interactive-hover.png",
regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 },
topCenter = { x = 31, y = 0, w = 127, h = 31 },
topRight = { x = 158, y = 0, w = 31, h = 31 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 },
middleRight = { x = 158, y = 31, w = 31, h = 127 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 },
},
stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" },
vertical = { "middleLeft", "middleCenter", "middleRight" },
},
},
disabled = {
atlas = "themes/space/interactive-disabled.png",
regions = {
topLeft = { x = 0, y = 0, w = 31, h = 31 },
topCenter = { x = 31, y = 0, w = 127, h = 31 },
topRight = { x = 158, y = 0, w = 31, h = 31 },
middleLeft = { x = 0, y = 31, w = 31, h = 127 },
middleCenter = { x = 31, y = 31, w = 127, h = 127 },
middleRight = { x = 158, y = 31, w = 31, h = 127 },
bottomLeft = { x = 0, y = 158, w = 31, h = 31 },
bottomCenter = { x = 31, y = 158, w = 127, h = 31 },
bottomRight = { x = 158, y = 158, w = 31, h = 31 },
}, },
stretch = { stretch = {
horizontal = { "topCenter", "middleCenter", "bottomCenter" }, horizontal = { "topCenter", "middleCenter", "bottomCenter" },