From ae1c44673f75e1e55ab99c80f6b71bfca5d85f40 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Wed, 15 Oct 2025 22:01:05 -0400 Subject: [PATCH] removing examples for a min --- FlexLove.lua | 190 ++++------- README.md | 2 +- examples/AutoScalingWithExplicitSize.lua | 107 ------ examples/BaseScaling.lua | 151 --------- examples/BaseScalingSimple.lua | 102 ------ examples/ContentAutoSizingMultiplierDemo.lua | 115 ------- examples/CornerRadiusDemo.lua | 312 ------------------ examples/DisableHighlightDemo.lua | 239 -------------- examples/EventSystemDemo.lua | 171 ---------- examples/FontFamilyDemo.lua | 214 ------------ examples/NineSliceCornerScalingDemo.lua | 243 -------------- examples/OnClickAnimations.lua | 67 ---- examples/ProportionalScalingDemo.lua | 284 ---------------- examples/SimpleGrid.lua | 236 ------------- examples/TextAutoScaling.lua | 131 -------- examples/TextSizePresets.lua | 167 ---------- examples/ThemeColorAccessDemo.lua | 170 ---------- examples/ThemeInitDemo.lua | 104 ------ examples/ThemeLayeringDemo.lua | 196 ----------- examples/ThemeSystemDemo.lua | 216 ------------ examples/ZIndexDemo.lua | 218 ------------ .../01_absolute_positioning_basic_tests.lua | 2 +- ...bsolute_positioning_child_layout_tests.lua | 4 +- .../03_flex_direction_horizontal_tests.lua | 4 +- .../04_flex_direction_vertical_tests.lua | 4 +- .../__tests__/05_justify_content_tests.lua | 4 +- testing/__tests__/06_align_items_tests.lua | 12 +- testing/__tests__/07_flex_wrap_tests.lua | 2 - .../__tests__/08_comprehensive_flex_tests.lua | 2 - .../__tests__/09_layout_validation_tests.lua | 4 +- testing/__tests__/10_performance_tests.lua | 4 +- .../11_auxiliary_functions_tests.lua | 14 +- testing/__tests__/12_units_system_tests.lua | 6 +- .../13_relative_positioning_tests.lua | 4 +- .../__tests__/14_text_scaling_basic_tests.lua | 10 +- testing/__tests__/15_grid_layout_tests.lua | 5 +- testing/__tests__/16_event_system_tests.lua | 2 - .../17_sibling_space_reservation_tests.lua | 2 +- .../18_font_family_inheritance_tests.lua | 10 +- .../__tests__/19_negative_margin_tests.lua | 22 +- testing/__tests__/20_padding_resize_tests.lua | 4 +- ...lua => 22_image_scaler_bilinear_tests.lua} | 13 +- testing/runAll.lua | 1 + 43 files changed, 140 insertions(+), 3630 deletions(-) delete mode 100644 examples/AutoScalingWithExplicitSize.lua delete mode 100644 examples/BaseScaling.lua delete mode 100644 examples/BaseScalingSimple.lua delete mode 100644 examples/ContentAutoSizingMultiplierDemo.lua delete mode 100644 examples/CornerRadiusDemo.lua delete mode 100644 examples/DisableHighlightDemo.lua delete mode 100644 examples/EventSystemDemo.lua delete mode 100644 examples/FontFamilyDemo.lua delete mode 100644 examples/NineSliceCornerScalingDemo.lua delete mode 100644 examples/OnClickAnimations.lua delete mode 100644 examples/ProportionalScalingDemo.lua delete mode 100644 examples/SimpleGrid.lua delete mode 100644 examples/TextAutoScaling.lua delete mode 100644 examples/TextSizePresets.lua delete mode 100644 examples/ThemeColorAccessDemo.lua delete mode 100644 examples/ThemeInitDemo.lua delete mode 100644 examples/ThemeLayeringDemo.lua delete mode 100644 examples/ThemeSystemDemo.lua delete mode 100644 examples/ZIndexDemo.lua rename testing/__tests__/{23_image_scaler_bilinear_tests.lua => 22_image_scaler_bilinear_tests.lua} (97%) diff --git a/FlexLove.lua b/FlexLove.lua index 6d54368..46aa951 100644 --- a/FlexLove.lua +++ b/FlexLove.lua @@ -477,7 +477,7 @@ end ---@field contentAutoSizingMultiplier {width:number?, height:number?}? -- Optional: multiplier for auto-sized content dimensions ---@field scaleCorners boolean? -- Optional: scale non-stretched regions (corners/edges) with window size. Default: false ---@field scalingAlgorithm "nearest"|"bilinear"? -- Optional: scaling algorithm for non-stretched regions. Default: "bilinear" ----@field _loadedAtlas love.Image? -- Internal: cached loaded atlas image +---@field _loadedAtlas string|love.Image? -- Internal: cached loaded atlas image ---@field _ninePatchData {insets:table, stretchX:table, stretchY:table}? -- Internal: parsed 9-patch data with multiple stretch regions ---@field _scaledRegionCache table? -- Internal: cache for scaled corner/edge images @@ -618,11 +618,18 @@ function Theme.new(definition) if definition.atlas then if type(definition.atlas) == "string" then local resolvedPath = resolveImagePath(definition.atlas) - local image, err = safeLoadImage(resolvedPath) + local image, loaderr = safeLoadImage(resolvedPath) if image then self.atlas = image else - print("[FlexLove] Warning: Failed to load global atlas for theme '" .. definition.name .. "'") + print( + "[FlexLove] Warning: Failed to load global atlas for theme '" + .. definition.name + .. "'" + .. "(" + .. loaderr + .. ")" + ) end else self.atlas = definition.atlas @@ -634,142 +641,91 @@ function Theme.new(definition) self.fonts = definition.fonts or {} self.contentAutoSizingMultiplier = definition.contentAutoSizingMultiplier or nil + -- Helper function to load atlas with 9-patch support + local function loadAtlasWithNinePatch(comp, atlasPath, errorContext) + ---@diagnostic disable-next-line + local resolvedPath = resolveImagePath(atlasPath) + ---@diagnostic disable-next-line + local is9Patch = not comp.insets and atlasPath:match("%.9%.png$") + + if is9Patch then + local parseResult, parseErr = NinePatchParser.parse(resolvedPath) + if parseResult then + comp.insets = parseResult.insets + comp._ninePatchData = parseResult + else + print("[FlexLove] Warning: Failed to parse 9-patch " .. errorContext .. ": " .. tostring(parseErr)) + end + end + + local image, loaderr = safeLoadImage(resolvedPath) + if image then + comp._loadedAtlas = image + else + print("[FlexLove] Warning: Failed to load atlas " .. errorContext .. ": " .. tostring(loaderr)) + end + end + + -- Helper function to create regions from insets + local function createRegionsFromInsets(comp, fallbackAtlas) + local atlasImage = comp._loadedAtlas or fallbackAtlas + if not atlasImage or type(atlasImage) == "string" then + return + end + + local imgWidth, imgHeight = atlasImage:getDimensions() + local left = comp.insets.left or 0 + local top = comp.insets.top or 0 + local right = comp.insets.right or 0 + local bottom = comp.insets.bottom or 0 + + local is9Patch = comp._ninePatchData ~= nil + local offsetX = is9Patch and 1 or 0 + local offsetY = is9Patch and 1 or 0 + local borderSize = is9Patch and 2 or 0 + + local centerWidth = imgWidth - left - right - borderSize + local centerHeight = imgHeight - top - bottom - borderSize + + comp.regions = { + topLeft = { x = offsetX, y = offsetY, w = left, h = top }, + topCenter = { x = left + offsetX, y = offsetY, w = centerWidth, h = top }, + topRight = { x = left + centerWidth + offsetX, y = offsetY, w = right, h = top }, + middleLeft = { x = offsetX, y = top + offsetY, w = left, h = centerHeight }, + middleCenter = { x = left + offsetX, y = top + offsetY, w = centerWidth, h = centerHeight }, + middleRight = { x = left + centerWidth + offsetX, y = top + offsetY, w = right, h = centerHeight }, + bottomLeft = { x = offsetX, y = top + centerHeight + offsetY, w = left, h = bottom }, + bottomCenter = { x = left + offsetX, y = top + centerHeight + offsetY, w = centerWidth, h = bottom }, + bottomRight = { x = left + centerWidth + offsetX, y = top + centerHeight + offsetY, w = right, h = bottom }, + } + end + -- Load component-specific atlases and process 9-patch definitions for componentName, component in pairs(self.components) do if component.atlas then if type(component.atlas) == "string" then - local resolvedPath = resolveImagePath(component.atlas) - - -- Check if this is a 9-patch file that needs parsing - local is9Patch = not component.insets and component.atlas:match("%.9%.png$") - - -- Parse 9-patch BEFORE loading the image - if is9Patch then - local parseResult, parseErr = NinePatchParser.parse(resolvedPath) - if parseResult then - component.insets = parseResult.insets - component._ninePatchData = parseResult -- Store full data including stretch regions - else - print("[FlexLove] Warning: Failed to parse 9-patch '" .. component.atlas .. "': " .. tostring(parseErr)) - end - end - - -- Now load the image normally - local image, err = safeLoadImage(resolvedPath) - if image then - component._loadedAtlas = image - else - print("[FlexLove] Warning: Failed to load atlas for component '" .. componentName .. "'") - end + loadAtlasWithNinePatch(component, component.atlas, "for component '" .. componentName .. "'") else component._loadedAtlas = component.atlas end end - -- Process 9-patch insets into regions (new format) if component.insets then - local atlasImage = component._loadedAtlas or self.atlas - if atlasImage then - local imgWidth, imgHeight = atlasImage:getDimensions() - local left = component.insets.left or 0 - local top = component.insets.top or 0 - local right = component.insets.right or 0 - local bottom = component.insets.bottom or 0 - - -- Check if this is a 9-patch image (has border pixels to skip) - local is9Patch = component._ninePatchData ~= nil - local offsetX = is9Patch and 1 or 0 - local offsetY = is9Patch and 1 or 0 - local borderSize = is9Patch and 2 or 0 -- 1 pixel on each side - - -- Calculate center dimensions (accounting for 9-patch borders) - local centerWidth = imgWidth - left - right - borderSize - local centerHeight = imgHeight - top - bottom - borderSize - - -- Generate regions from insets (offset by 1 pixel for 9-patch to skip border) - component.regions = { - topLeft = { x = offsetX, y = offsetY, w = left, h = top }, - topCenter = { x = left + offsetX, y = offsetY, w = centerWidth, h = top }, - topRight = { x = left + centerWidth + offsetX, y = offsetY, w = right, h = top }, - middleLeft = { x = offsetX, y = top + offsetY, w = left, h = centerHeight }, - middleCenter = { x = left + offsetX, y = top + offsetY, w = centerWidth, h = centerHeight }, - middleRight = { x = left + centerWidth + offsetX, y = top + offsetY, w = right, h = centerHeight }, - bottomLeft = { x = offsetX, y = top + centerHeight + offsetY, w = left, h = bottom }, - bottomCenter = { x = left + offsetX, y = top + centerHeight + offsetY, w = centerWidth, h = bottom }, - bottomRight = { x = left + centerWidth + offsetX, y = top + centerHeight + offsetY, w = right, h = bottom }, - } - end + createRegionsFromInsets(component, self.atlas) end - -- Also load atlases for component states and process their 9-patch definitions if component.states then for stateName, stateComponent in pairs(component.states) do if stateComponent.atlas then if type(stateComponent.atlas) == "string" then - local resolvedPath = resolveImagePath(stateComponent.atlas) - - -- Check if this is a 9-patch file that needs parsing - local is9Patch = not stateComponent.insets and stateComponent.atlas:match("%.9%.png$") - - -- Parse 9-patch BEFORE loading the image - if is9Patch then - local parseResult, parseErr = NinePatchParser.parse(resolvedPath) - if parseResult then - stateComponent.insets = parseResult.insets - stateComponent._ninePatchData = parseResult - else - print("[FlexLove] Warning: Failed to parse 9-patch state '" .. stateName .. "': " .. tostring(parseErr)) - end - end - - -- Now load the image normally - local image, imgErr = safeLoadImage(resolvedPath) - if image then - stateComponent._loadedAtlas = image - else - print("[FlexLove] Warning: Failed to load state atlas '" .. stateName .. "': " .. tostring(imgErr)) - end + loadAtlasWithNinePatch(stateComponent, stateComponent.atlas, "for state '" .. stateName .. "'") else stateComponent._loadedAtlas = stateComponent.atlas end end - -- Process 9-patch insets for state components if stateComponent.insets then - local atlasImage = stateComponent._loadedAtlas or component._loadedAtlas or self.atlas - if atlasImage then - local imgWidth, imgHeight = atlasImage:getDimensions() - local left = stateComponent.insets.left or 0 - local top = stateComponent.insets.top or 0 - local right = stateComponent.insets.right or 0 - local bottom = stateComponent.insets.bottom or 0 - - -- Check if this is a 9-patch image (has border pixels to skip) - local is9Patch = stateComponent._ninePatchData ~= nil - local offsetX = is9Patch and 1 or 0 - local offsetY = is9Patch and 1 or 0 - local borderSize = is9Patch and 2 or 0 - - local centerWidth = imgWidth - left - right - borderSize - local centerHeight = imgHeight - top - bottom - borderSize - - stateComponent.regions = { - topLeft = { x = offsetX, y = offsetY, w = left, h = top }, - topCenter = { x = left + offsetX, y = offsetY, w = centerWidth, h = top }, - topRight = { x = left + centerWidth + offsetX, y = offsetY, w = right, h = top }, - middleLeft = { x = offsetX, y = top + offsetY, w = left, h = centerHeight }, - middleCenter = { x = left + offsetX, y = top + offsetY, w = centerWidth, h = centerHeight }, - middleRight = { x = left + centerWidth + offsetX, y = top + offsetY, w = right, h = centerHeight }, - bottomLeft = { x = offsetX, y = top + centerHeight + offsetY, w = left, h = bottom }, - bottomCenter = { x = left + offsetX, y = top + centerHeight + offsetY, w = centerWidth, h = bottom }, - bottomRight = { - x = left + centerWidth + offsetX, - y = top + centerHeight + offsetY, - w = right, - h = bottom, - }, - } - end + createRegionsFromInsets(stateComponent, component._loadedAtlas or self.atlas) end end end diff --git a/README.md b/README.md index 061cb4e..c31d282 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ This library is under active development. While many features are functional, so - **Element Management**: Hierarchical element structures with automatic sizing - **Interactive Elements**: Buttons with click detection, event system, and callbacks - **Theme System**: 9-slice/9-patch theming with state support (normal, hover, pressed, disabled) - - **Android 9-Patch Auto-Parsing**: Automatic parsing of *.9.png files with multi-region support +- **Android 9-Patch Auto-Parsing**: Automatic parsing of *.9.png files with multi-region support - **Animations**: Built-in animation support for transitions and effects - **Responsive Design**: Automatic resizing with viewport units (vw, vh, %) - **Color Handling**: Utility classes for managing colors in various formats diff --git a/examples/AutoScalingWithExplicitSize.lua b/examples/AutoScalingWithExplicitSize.lua deleted file mode 100644 index 0872230..0000000 --- a/examples/AutoScalingWithExplicitSize.lua +++ /dev/null @@ -1,107 +0,0 @@ --- Example: Auto-scaling with explicit textSize values --- By default, even explicit pixel sizes will auto-scale with window - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Auto-Scaling with Explicit textSize ===\n") - --- Example 1: Default behavior - auto-scales even with explicit pixel size -print("1. Default: textSize=40 auto-scales") -local elem1 = Gui.new({ - text = "Pause Menu", - textSize = 40, -- Explicit pixel size - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600: textSize = " .. elem1.textSize) -print(" (Converted to " .. string.format("%.2f", elem1.units.textSize.value) .. "vh internally)") - -love.window.setMode(1600, 1200) -Gui.resize() -print(" At 1600x1200: textSize = " .. elem1.textSize) -print(" (Scales proportionally!)\n") - --- Example 2: Disable auto-scaling for truly fixed size -print("2. Fixed: textSize=40 with autoScaleText=false") -Gui.destroy() -love.window.setMode(800, 600) -local elem2 = Gui.new({ - text = "Fixed Size", - textSize = 40, - autoScaleText = false, -- Disable auto-scaling - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600: textSize = " .. elem2.textSize) - -love.window.setMode(1600, 1200) -Gui.resize() -print(" At 1600x1200: textSize = " .. elem2.textSize) -print(" (Stays fixed)\n") - --- Example 3: Use viewport units explicitly -print("3. Explicit viewport units: textSize='5vh'") -Gui.destroy() -love.window.setMode(800, 600) -local elem3 = Gui.new({ - text = "Large Title", - textSize = "5vh", -- 5% of viewport height - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600: textSize = " .. elem3.textSize .. " (5% of 600)") - -love.window.setMode(1600, 1200) -Gui.resize() -print(" At 1600x1200: textSize = " .. elem3.textSize .. " (5% of 1200)\n") - --- Example 4: Your Pause Menu use case -print("4. Pause Menu Example") -Gui.destroy() -love.window.setMode(800, 600) - -local pauseMenu = Gui.new({ - x = "25%", - y = "25%", - width = "50%", - height = "50%", - positioning = "flex", - flexDirection = "vertical", - justifyContent = "center", - alignItems = "center", - backgroundColor = Color.new(0.1, 0.1, 0.1, 0.9), -}) - -local title = Gui.new({ - parent = pauseMenu, - text = "Pause Menu", - textSize = 40, -- Auto-scales by default! - textColor = Color.new(1, 1, 1), -}) - -local closeButton = Gui.new({ - parent = pauseMenu, - text = "X", - textSize = 40, -- Auto-scales by default! - padding = { horizontal = 8 }, - textColor = Color.new(1, 1, 1), -}) - -print(" At 800x600:") -print(" Title textSize: " .. title.textSize) -print(" Button textSize: " .. closeButton.textSize) - -love.window.setMode(1600, 1200) -Gui.resize() -print(" At 1600x1200:") -print(" Title textSize: " .. title.textSize .. " (scaled 2x!)") -print(" Button textSize: " .. closeButton.textSize .. " (scaled 2x!)") -print() - -print("=== Summary ===") -print("• textSize with pixel values NOW AUTO-SCALES by default") -print("• To disable: set autoScaleText = false") -print("• Pixel values are converted to viewport units (vh) internally") -print("• This makes text responsive without any extra configuration!") -print("• Your Pause Menu will now scale perfectly at any resolution") diff --git a/examples/BaseScaling.lua b/examples/BaseScaling.lua deleted file mode 100644 index 97a41c3..0000000 --- a/examples/BaseScaling.lua +++ /dev/null @@ -1,151 +0,0 @@ --- Example demonstrating base scaling feature --- Design your UI at a base resolution and it scales proportionally - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Base Scaling Examples ===\n") - --- Example 1: Without base scaling (default behavior) -print("1. Without Base Scaling") -print(" Elements use actual pixel values") -local elem1 = Gui.new({ - x = 100, - y = 50, - width = 200, - height = 100, - text = "No Scaling", - textSize = 16, - autoScaleText = false, - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600:") -print(" x=" .. elem1.x .. ", y=" .. elem1.y .. ", width=" .. elem1.width .. ", height=" .. elem1.height .. ", textSize=" .. elem1.textSize) -love.window.setMode(1600, 1200) -elem1:resize(1600, 1200) -print(" After resize to 1600x1200:") -print(" x=" .. elem1.x .. ", y=" .. elem1.y .. ", width=" .. elem1.width .. ", height=" .. elem1.height .. ", textSize=" .. elem1.textSize) -print(" (No scaling applied)\n") - --- Example 2: With base scaling -print("2. With Base Scaling (baseScale = {width=800, height=600})") -print(" Design at 800x600, scales to any resolution") -love.window.setMode(800, 600) -Gui.destroy() -Gui.init({ - baseScale = { width = 800, height = 600 } -}) - -local scaleX, scaleY = Gui.getScaleFactors() -print(" Initial scale factors: x=" .. scaleX .. ", y=" .. scaleY) - -local elem2 = Gui.new({ - x = 100, -- Designed for 800x600 - y = 50, - width = 200, - height = 100, - text = "Scaled UI", - textSize = 16, - autoScaleText = false, - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600 (base resolution):") -print(" x=" .. elem2.x .. ", y=" .. elem2.y .. ", width=" .. elem2.width .. ", height=" .. elem2.height .. ", textSize=" .. elem2.textSize) - -love.window.setMode(1600, 1200) -elem2:resize(1600, 1200) -scaleX, scaleY = Gui.getScaleFactors() -print(" After resize to 1600x1200:") -print(" Scale factors: x=" .. scaleX .. ", y=" .. scaleY) -print(" x=" .. elem2.x .. ", y=" .. elem2.y .. ", width=" .. elem2.width .. ", height=" .. elem2.height .. ", textSize=" .. elem2.textSize) -print(" (Everything scaled 2x!)\n") - --- Example 3: Padding and margins are NOT scaled -print("3. Padding/Margins NOT Scaled") -love.window.setMode(800, 600) -Gui.destroy() -Gui.init({ - baseScale = { width = 800, height = 600 } -}) - -local elem3 = Gui.new({ - x = 100, - y = 50, - width = 200, - height = 100, - padding = { horizontal = 10, vertical = 5 }, - text = "Padding Test", - autoScaleText = false, - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600:") -print(" width=" .. elem3.width .. ", padding.left=" .. elem3.padding.left .. ", padding.top=" .. elem3.padding.top) - -love.window.setMode(1600, 1200) -elem3:resize(1600, 1200) -print(" After resize to 1600x1200:") -print(" width=" .. elem3.width .. " (scaled 2x), padding.left=" .. elem3.padding.left .. ", padding.top=" .. elem3.padding.top .. " (NOT scaled)") -print() - --- Example 4: Percentage units still work -print("4. Percentage Units with Base Scaling") -love.window.setMode(800, 600) -Gui.destroy() -Gui.init({ - baseScale = { width = 800, height = 600 } -}) - -local elem4 = Gui.new({ - x = "10%", -- Percentage of viewport - y = "10%", - width = "50%", - height = "20%", - text = "Percentage", - autoScaleText = false, - textColor = Color.new(1, 1, 1), -}) -print(" At 800x600:") -print(" x=" .. elem4.x .. ", y=" .. elem4.y .. ", width=" .. elem4.width .. ", height=" .. elem4.height) - -love.window.setMode(1600, 1200) -elem4:resize(1600, 1200) -print(" After resize to 1600x1200:") -print(" x=" .. elem4.x .. ", y=" .. elem4.y .. ", width=" .. elem4.width .. ", height=" .. elem4.height) -print(" (Percentage units scale with viewport, not base scale)\n") - --- Example 5: Designing for 1920x1080 and scaling down -print("5. Design for 1920x1080, Scale to 800x600") -love.window.setMode(800, 600) -Gui.destroy() -Gui.init({ - baseScale = { width = 1920, height = 1080 } -}) - -scaleX, scaleY = Gui.getScaleFactors() -print(" Scale factors at 800x600: x=" .. string.format("%.3f", scaleX) .. ", y=" .. string.format("%.3f", scaleY)) - -local elem5 = Gui.new({ - x = 960, -- Center of 1920x1080 - y = 540, - width = 400, - height = 200, - text = "HD Design", - textSize = 24, - autoScaleText = false, - textColor = Color.new(1, 1, 1), -}) -print(" Designed for 1920x1080 (x=960, y=540, width=400, textSize=24)") -print(" At 800x600:") -print(" x=" .. string.format("%.1f", elem5.x) .. ", y=" .. string.format("%.1f", elem5.y) .. ", width=" .. string.format("%.1f", elem5.width) .. ", textSize=" .. string.format("%.1f", elem5.textSize)) -print(" (Scaled down proportionally)\n") - -print("=== Summary ===") -print("• Call Gui.init({baseScale = {width=W, height=H}}) in love.load()") -print("• Design your UI at the base resolution") -print("• All pixel values (x, y, width, height, textSize) scale proportionally") -print("• Padding and margins do NOT scale (stay at designed pixel values)") -print("• Percentage/viewport units work independently of base scaling") -print("• Perfect for responsive UIs that maintain proportions") diff --git a/examples/BaseScalingSimple.lua b/examples/BaseScalingSimple.lua deleted file mode 100644 index 21443ec..0000000 --- a/examples/BaseScalingSimple.lua +++ /dev/null @@ -1,102 +0,0 @@ --- Simple example demonstrating base scaling - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Base Scaling Demo ===\n") - --- Initialize with base scale (call this in love.load()) -Gui.init({ - baseScale = { width = 800, height = 600 }, -}) - -print("Designing UI for 800x600 base resolution\n") - --- Create UI elements using base resolution coordinates -local button = Gui.new({ - x = 100, - y = 50, - width = 200, - height = 60, - text = "Click Me!", - textSize = 20, - autoScaleText = false, - padding = { horizontal = 16, vertical = 8 }, - textAlign = "center", - border = { top = true, right = true, bottom = true, left = true }, - borderColor = Color.new(1, 1, 1), - textColor = Color.new(1, 1, 1), -}) - -print("At 800x600 (base resolution):") -print( - string.format( - " Button: x=%d, y=%d, width=%d, height=%d, textSize=%d", - button.x, - button.y, - button.width, - button.height, - button.textSize - ) -) -print(string.format(" Padding: left=%d, top=%d (NOT scaled)", button.padding.left, button.padding.top)) - --- Simulate window resize to 1600x1200 (2x scale) -print("\nResizing window to 1600x1200...") -love.window.setMode(1600, 1200) -Gui.resize() -- This updates all elements - -local sx, sy = Gui.getScaleFactors() -print(string.format("Scale factors: x=%.1f, y=%.1f", sx, sy)) -print( - string.format( - " Button: x=%d, y=%d, width=%d, height=%d, textSize=%d", - button.x, - button.y, - button.width, - button.height, - button.textSize - ) -) -print(string.format(" Padding: left=%d, top=%d (NOT scaled)", button.padding.left, button.padding.top)) - --- Simulate window resize to 400x300 (0.5x scale) -print("\nResizing window to 400x300...") -love.window.setMode(400, 300) -Gui.resize() - -sx, sy = Gui.getScaleFactors() -print(string.format("Scale factors: x=%.1f, y=%.1f", sx, sy)) -print( - string.format( - " Button: x=%d, y=%d, width=%d, height=%d, textSize=%d", - button.x, - button.y, - button.width, - button.height, - button.textSize - ) -) -print(string.format(" Padding: left=%d, top=%d (NOT scaled)", button.padding.left, button.padding.top)) - -print("\n=== Usage ===") -print("In your main.lua:") -print([[ -function love.load() - local FlexLove = require("libs.FlexLove") - local Gui = FlexLove.GUI - - -- Initialize with your design resolution - Gui.init({ baseScale = { width = 800, height = 600 } }) - - -- Create UI using base resolution coordinates - -- Everything will scale automatically! -end - -function love.resize(w, h) - Gui.resize() -- Update all elements for new window size -end -]]) diff --git a/examples/ContentAutoSizingMultiplierDemo.lua b/examples/ContentAutoSizingMultiplierDemo.lua deleted file mode 100644 index 37c8c0c..0000000 --- a/examples/ContentAutoSizingMultiplierDemo.lua +++ /dev/null @@ -1,115 +0,0 @@ --- 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 diff --git a/examples/CornerRadiusDemo.lua b/examples/CornerRadiusDemo.lua deleted file mode 100644 index acc1b1b..0000000 --- a/examples/CornerRadiusDemo.lua +++ /dev/null @@ -1,312 +0,0 @@ --- 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 diff --git a/examples/DisableHighlightDemo.lua b/examples/DisableHighlightDemo.lua deleted file mode 100644 index 3544166..0000000 --- a/examples/DisableHighlightDemo.lua +++ /dev/null @@ -1,239 +0,0 @@ --- 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 diff --git a/examples/EventSystemDemo.lua b/examples/EventSystemDemo.lua deleted file mode 100644 index f934143..0000000 --- a/examples/EventSystemDemo.lua +++ /dev/null @@ -1,171 +0,0 @@ -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - ----@class EventSystemDemo ----@field window Element ----@field eventLog table ----@field logDisplay Element -local EventSystemDemo = {} -EventSystemDemo.__index = EventSystemDemo - -function EventSystemDemo.init() - local self = setmetatable({}, EventSystemDemo) - self.eventLog = {} - - -- Create main demo window - self.window = Gui.new({ - x = 50, - y = 50, - width = 700, - height = 500, - backgroundColor = Color.new(0.15, 0.15, 0.2, 0.95), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.8, 0.8, 0.8, 1), - positioning = "flex", - flexDirection = "vertical", - gap = 20, - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - }) - - -- Title - local title = Gui.new({ - parent = self.window, - height = 40, - text = "Event System Demo - Try different clicks and modifiers!", - textSize = 18, - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.2, 0.2, 0.3, 1), - }) - - -- Button container - local buttonContainer = Gui.new({ - parent = self.window, - height = 200, - positioning = "flex", - flexDirection = "horizontal", - gap = 15, - backgroundColor = Color.new(0.1, 0.1, 0.15, 0.5), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - -- Helper function to add event to log - local function logEvent(message) - table.insert(self.eventLog, 1, message) -- Add to beginning - if #self.eventLog > 10 then - table.remove(self.eventLog) -- Keep only last 10 events - end - self:updateLogDisplay() - end - - -- Left Click Button - local leftClickBtn = Gui.new({ - parent = buttonContainer, - width = 150, - height = 80, - text = "Left Click Me", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.2, 0.6, 0.9, 0.8), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.4, 0.8, 1, 1), - callback = function(element, event) - local msg = string.format("[%s] Button: %d, Clicks: %d", - event.type, event.button, event.clickCount) - logEvent(msg) - end, - }) - - -- Right Click Button - local rightClickBtn = Gui.new({ - parent = buttonContainer, - width = 150, - height = 80, - text = "Right Click Me", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.9, 0.4, 0.4, 0.8), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(1, 0.6, 0.6, 1), - callback = function(element, event) - if event.type == "rightclick" then - logEvent("RIGHT CLICK detected!") - elseif event.type == "click" then - logEvent("Left click (try right click!)") - end - end, - }) - - -- Modifier Button - local modifierBtn = Gui.new({ - parent = buttonContainer, - width = 150, - height = 80, - text = "Try Shift/Ctrl", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.6, 0.9, 0.4, 0.8), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.8, 1, 0.6, 1), - callback = function(element, event) - if event.type == "click" then - local mods = {} - if event.modifiers.shift then table.insert(mods, "SHIFT") end - if event.modifiers.ctrl then table.insert(mods, "CTRL") end - if event.modifiers.alt then table.insert(mods, "ALT") end - if event.modifiers.cmd then table.insert(mods, "CMD") end - - if #mods > 0 then - logEvent("Modifiers: " .. table.concat(mods, "+")) - else - logEvent("No modifiers (try holding Shift/Ctrl)") - end - end - end, - }) - - -- Multi-Event Button (shows all event types) - local multiEventBtn = Gui.new({ - parent = buttonContainer, - width = 150, - height = 80, - text = "All Events", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.9, 0.7, 0.3, 0.8), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(1, 0.9, 0.5, 1), - callback = function(element, event) - local msg = string.format("[%s] Btn:%d at (%d,%d)", - event.type, event.button, math.floor(event.x), math.floor(event.y)) - logEvent(msg) - end, - }) - - -- Event log display area - self.logDisplay = Gui.new({ - parent = self.window, - height = 200, - text = "Event log will appear here...", - textSize = 14, - textAlign = "start", - textColor = Color.new(0.9, 0.9, 1, 1), - backgroundColor = Color.new(0.05, 0.05, 0.1, 1), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.3, 0.3, 0.4, 1), - padding = { top = 10, right = 10, bottom = 10, left = 10 }, - }) - - return self -end - -function EventSystemDemo:updateLogDisplay() - if #self.eventLog == 0 then - self.logDisplay.text = "Event log will appear here..." - else - self.logDisplay.text = table.concat(self.eventLog, "\n") - end -end - -return EventSystemDemo.init() diff --git a/examples/FontFamilyDemo.lua b/examples/FontFamilyDemo.lua deleted file mode 100644 index 20dc3b9..0000000 --- a/examples/FontFamilyDemo.lua +++ /dev/null @@ -1,214 +0,0 @@ --- Font Family Demo --- Demonstrates how to use custom fonts with FlexLove theme system - -local FlexLove = require("libs.FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color -local Theme = FlexLove.Theme - --- Initialize FlexLove with base scaling and theme -Gui.init({ - baseScale = { width = 1920, height = 1080 }, - theme = "space", -}) - --- Create a simple theme with custom fonts -local customTheme = Theme.new({ - name = "Custom Font Theme", - - -- Define font families - -- Note: These paths are examples - replace with your actual font files - fonts = { - -- You can reference fonts by name in your elements - -- default = "path/to/your/font.ttf", - -- heading = "path/to/your/heading-font.ttf", - -- mono = "path/to/your/monospace-font.ttf", - }, - - colors = { - background = Color.new(0.1, 0.1, 0.15, 1), - text = Color.new(0.9, 0.9, 0.95, 1), - }, -}) - --- Set the custom theme as active --- Theme.setActive(customTheme) - --- Create main container -local container = Gui.new({ - x = 100, - y = 100, - width = 1720, - height = 880, - backgroundColor = Color.new(0.1, 0.1, 0.15, 1), - cornerRadius = 10, - positioning = "flex", - flexDirection = "vertical", - padding = { top = 40, horizontal = 40, bottom = 40 }, - gap = 30, -}) - --- Title -Gui.new({ - parent = container, - text = "Font Family Demo", - textSize = "3xl", - textColor = Color.new(1, 1, 1, 1), - textAlign = "center", - -- fontFamily = "heading", -- Uncomment to use custom heading font from theme -}) - --- Description -Gui.new({ - parent = container, - text = "FlexLove supports custom font families through the theme system", - textSize = "md", - textColor = Color.new(0.8, 0.8, 0.9, 1), - textAlign = "center", - -- fontFamily = "default", -- Uncomment to use custom default font from theme -}) - --- Example 1: Default System Font -local example1 = Gui.new({ - parent = container, - width = "100%", - backgroundColor = Color.new(0.15, 0.15, 0.2, 1), - cornerRadius = 8, - padding = { top = 20, horizontal = 20, bottom = 20 }, - positioning = "flex", - flexDirection = "vertical", - gap = 10, -}) - -Gui.new({ - parent = example1, - text = "1. Default System Font", - textSize = "lg", - textColor = Color.new(0.3, 0.7, 1, 1), -}) - -Gui.new({ - parent = example1, - text = "This text uses the default system font (no fontFamily specified)", - textSize = "md", - textColor = Color.new(0.9, 0.9, 0.95, 1), -}) - --- Example 2: Font from Theme -local example2 = Gui.new({ - parent = container, - width = "100%", - backgroundColor = Color.new(0.15, 0.15, 0.2, 1), - cornerRadius = 8, - padding = { top = 20, horizontal = 20, bottom = 20 }, - positioning = "flex", - flexDirection = "vertical", - gap = 10, -}) - -Gui.new({ - parent = example2, - text = "2. Font from Theme", - textSize = "lg", - textColor = Color.new(0.3, 0.7, 1, 1), -}) - -Gui.new({ - parent = example2, - text = "Use fontFamily='default' to reference fonts defined in your theme", - textSize = "md", - textColor = Color.new(0.9, 0.9, 0.95, 1), - -- fontFamily = "default", -- Uncomment when you have fonts defined in theme -}) - --- Example 3: Direct Font Path -local example3 = Gui.new({ - parent = container, - width = "100%", - backgroundColor = Color.new(0.15, 0.15, 0.2, 1), - cornerRadius = 8, - padding = { top = 20, horizontal = 20, bottom = 20 }, - positioning = "flex", - flexDirection = "vertical", - gap = 10, -}) - -Gui.new({ - parent = example3, - text = "3. Direct Font Path", - textSize = "lg", - textColor = Color.new(0.3, 0.7, 1, 1), -}) - -Gui.new({ - parent = example3, - text = "You can also specify a direct path: fontFamily='path/to/font.ttf'", - textSize = "md", - textColor = Color.new(0.9, 0.9, 0.95, 1), - -- fontFamily = "path/to/your/font.ttf", -- Uncomment with actual font path -}) - --- Example 4: Different Sizes with Same Font -local example4 = Gui.new({ - parent = container, - width = "100%", - backgroundColor = Color.new(0.15, 0.15, 0.2, 1), - cornerRadius = 8, - padding = { top = 20, horizontal = 20, bottom = 20 }, - positioning = "flex", - flexDirection = "vertical", - gap = 10, -}) - -Gui.new({ - parent = example4, - text = "4. Multiple Sizes", - textSize = "lg", - textColor = Color.new(0.3, 0.7, 1, 1), -}) - -local sizeContainer = Gui.new({ - parent = example4, - positioning = "flex", - flexDirection = "vertical", - gap = 5, -}) - -local sizes = { "xs", "sm", "md", "lg", "xl", "xxl" } -for _, size in ipairs(sizes) do - Gui.new({ - parent = sizeContainer, - text = "Text size: " .. size, - textSize = size, - textColor = Color.new(0.9, 0.9, 0.95, 1), - -- fontFamily = "default", -- Same font, different sizes - }) -end - --- Instructions -Gui.new({ - parent = container, - text = "To use custom fonts: 1) Add font files to your project, 2) Define them in theme.fonts, 3) Reference by name in elements", - textSize = "sm", - textColor = Color.new(0.6, 0.6, 0.7, 1), - textAlign = "center", -}) - --- LÖVE callbacks -function love.load() - print("Font Family Demo loaded") - print("Add your custom font files and update the theme definition to see custom fonts in action") -end - -function love.update(dt) - Gui.update(dt) -end - -function love.draw() - love.graphics.clear(0.05, 0.05, 0.08, 1) - Gui.draw() -end - -function love.resize(w, h) - Gui.resize() -end diff --git a/examples/NineSliceCornerScalingDemo.lua b/examples/NineSliceCornerScalingDemo.lua deleted file mode 100644 index 9b78685..0000000 --- a/examples/NineSliceCornerScalingDemo.lua +++ /dev/null @@ -1,243 +0,0 @@ -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Theme = FlexLove.Theme -local Color = FlexLove.Color - ----@class CornerScalingDemo ----@field window Element ----@field currentMode string ----@field modeButtons table -local CornerScalingDemo = {} -CornerScalingDemo.__index = CornerScalingDemo - -function CornerScalingDemo.init() - local self = setmetatable({}, CornerScalingDemo) - - self.currentMode = "none" - self.modeButtons = {} - - -- Try to load theme - local themeLoaded = pcall(function() - Theme.load("space") - Theme.setActive("space") - end) - - -- Create main window - self.window = Gui.new({ - x = 50, - y = 50, - width = 900, - height = 650, - backgroundColor = Color.new(0.1, 0.1, 0.15, 0.95), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.6, 0.6, 0.7, 1), - positioning = "flex", - flexDirection = "vertical", - gap = 20, - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - }) - - -- Title - Gui.new({ - parent = self.window, - height = 40, - text = "NineSlice Corner Scaling Demo", - textSize = 24, - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.15, 0.15, 0.25, 1), - }) - - -- Status - Gui.new({ - parent = self.window, - height = 30, - text = themeLoaded and "✓ Theme loaded - Scaling demonstration active" - or "⚠ Theme not loaded - Please ensure theme assets exist", - textSize = 14, - textAlign = "center", - textColor = themeLoaded and Color.new(0.3, 0.9, 0.3, 1) or Color.new(0.9, 0.6, 0.3, 1), - backgroundColor = Color.new(0.08, 0.08, 0.12, 0.8), - }) - - -- Mode selector section - local modeSection = Gui.new({ - parent = self.window, - height = 80, - backgroundColor = Color.new(0.12, 0.12, 0.18, 1), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - positioning = "flex", - flexDirection = "vertical", - gap = 10, - }) - - Gui.new({ - parent = modeSection, - height = 20, - text = "Select Scaling Mode:", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- Button container - local buttonContainer = Gui.new({ - parent = modeSection, - height = 40, - positioning = "flex", - flexDirection = "horizontal", - gap = 15, - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- Helper to create mode button - local function createModeButton(mode, label) - local button = Gui.new({ - parent = buttonContainer, - width = 180, - height = 40, - text = label, - textAlign = "center", - textSize = 14, - textColor = Color.new(1, 1, 1, 1), - backgroundColor = self.currentMode == mode and Color.new(0.3, 0.6, 0.9, 1) or Color.new(0.25, 0.25, 0.35, 1), - callback = function(element, event) - if event.type == "click" then - self:setMode(mode) - end - end, - }) - self.modeButtons[mode] = button - return button - end - - createModeButton("none", "No Scaling (Default)") - createModeButton("nearest", "Nearest Neighbor") - createModeButton("bilinear", "Bilinear Interpolation") - - -- Comparison section - local comparisonSection = Gui.new({ - parent = self.window, - height = 420, - backgroundColor = Color.new(0.08, 0.08, 0.12, 1), - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - positioning = "flex", - flexDirection = "vertical", - gap = 15, - }) - - -- Description - Gui.new({ - parent = comparisonSection, - height = 60, - text = "The panels below demonstrate different scaling modes.\n" .. - "• No Scaling: Corners remain at original size (may appear small at high DPI)\n" .. - "• Nearest Neighbor: Sharp, pixelated scaling (ideal for pixel art)\n" .. - "• Bilinear: Smooth, filtered scaling (ideal for high-quality graphics)", - textSize = 12, - textColor = Color.new(0.7, 0.8, 0.9, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- Demo panels container - local panelsContainer = Gui.new({ - parent = comparisonSection, - positioning = "flex", - flexDirection = "horizontal", - gap = 20, - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- Helper to create demo panel - local function createDemoPanel(size, label) - local container = Gui.new({ - parent = panelsContainer, - width = (900 - 80 - 40) / 3, -- Divide available space - positioning = "flex", - flexDirection = "vertical", - gap = 10, - backgroundColor = Color.new(0, 0, 0, 0), - }) - - Gui.new({ - parent = container, - height = 20, - text = label, - textSize = 12, - textAlign = "center", - textColor = Color.new(0.8, 0.9, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - local panel = Gui.new({ - parent = container, - width = size, - height = size, - backgroundColor = Color.new(0.2, 0.3, 0.4, 0.5), - theme = themeLoaded and "panel" or nil, - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - Gui.new({ - parent = panel, - text = "Themed\nPanel", - textSize = 14, - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - return panel - end - - createDemoPanel(120, "Small (120x120)") - createDemoPanel(160, "Medium (160x160)") - createDemoPanel(200, "Large (200x200)") - - -- Info footer - Gui.new({ - parent = self.window, - height = 30, - text = "Resize the window to see how scaling adapts to different DPI settings", - textSize = 11, - textAlign = "center", - textColor = Color.new(0.5, 0.6, 0.7, 1), - backgroundColor = Color.new(0.08, 0.08, 0.12, 1), - }) - - return self -end - -function CornerScalingDemo:setMode(mode) - self.currentMode = mode - - -- Update button colors - for modeName, button in pairs(self.modeButtons) do - button.backgroundColor = modeName == mode and Color.new(0.3, 0.6, 0.9, 1) or Color.new(0.25, 0.25, 0.35, 1) - end - - -- Update theme components based on mode - local activeTheme = Theme.getActive() - if activeTheme and activeTheme.components then - for componentName, component in pairs(activeTheme.components) do - if mode == "none" then - component.scaleCorners = false - elseif mode == "nearest" then - component.scaleCorners = true - component.scalingAlgorithm = "nearest" - elseif mode == "bilinear" then - component.scaleCorners = true - component.scalingAlgorithm = "bilinear" - end - - -- Clear cache to force re-rendering - if component._scaledRegionCache then - component._scaledRegionCache = {} - end - end - end - - print("Scaling mode changed to: " .. mode) -end - -return CornerScalingDemo.init() diff --git a/examples/OnClickAnimations.lua b/examples/OnClickAnimations.lua deleted file mode 100644 index f0ae5b0..0000000 --- a/examples/OnClickAnimations.lua +++ /dev/null @@ -1,67 +0,0 @@ -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - ----@class AnimDemo ----@field window Element ----@field button Element ----@field fadeButton Element ----@field scaleButton Element -local OnClickAnimDemo = {} -OnClickAnimDemo.__index = OnClickAnimDemo - -function OnClickAnimDemo.init() - local self = setmetatable({}, OnClickAnimDemo) - - -- Create a demo window - self.window = Gui.new({ - x = 100, - y = 100, - z = 10, - w = 300, - h = 200, - backgroundColor = Color.new(0.1, 0.1, 0.3, 0.8), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.7, 0.7, 0.7, 1), - }) - - -- Create a fade button - self.fadeButton = Gui.new({ - parent = self.window, - x = 20, - y = 80, - w = 100, - h = 40, - text = "Fade", - backgroundColor = Color.new(0.2, 0.9, 0.6, 0.8), - textColor = Color.new(1, 1, 1), - borderColor = Color.new(0.4, 1, 0.8, 1), - callback = function() - -- Create a fade animation - local fadeAnim = Gui.Animation.fade(1, 0.8, 0.2) - fadeAnim:apply(self.window) - end, - }) - - -- Create a scale button - self.scaleButton = Gui.new({ - parent = self.window, - x = 20, - y = 140, - w = 100, - h = 40, - text = "Scale", - backgroundColor = Color.new(0.9, 0.6, 0.2, 0.8), - textColor = Color.new(1, 1, 1), - borderColor = Color.new(1, 0.8, 0.4, 1), - callback = function() - -- Create a scale animation - local scaleAnim = Gui.Animation.scale(1.5, { width = 100, height = 40 }, { width = 200, height = 80 }) - scaleAnim:apply(self.button) - end, - }) - - return self -end - -return OnClickAnimDemo.init() diff --git a/examples/ProportionalScalingDemo.lua b/examples/ProportionalScalingDemo.lua deleted file mode 100644 index e648b68..0000000 --- a/examples/ProportionalScalingDemo.lua +++ /dev/null @@ -1,284 +0,0 @@ -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Theme = FlexLove.Theme -local Color = FlexLove.Color - ----@class ProportionalScalingDemo ----@field window Element -local ProportionalScalingDemo = {} -ProportionalScalingDemo.__index = ProportionalScalingDemo - -function ProportionalScalingDemo.init() - local self = setmetatable({}, ProportionalScalingDemo) - - -- Load space theme - Theme.load("space") - Theme.setActive("space") - - -- Create main demo window - self.window = Gui.new({ - x = 50, - y = 50, - width = 900, - height = 700, - backgroundColor = Color.new(0.1, 0.1, 0.15, 0.95), - positioning = "flex", - flexDirection = "vertical", - gap = 20, - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - }) - - -- Title - Gui.new({ - parent = self.window, - height = 40, - text = "Proportional 9-Slice Scaling 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 = self.window, - height = 80, - text = "Theme borders render ONLY in the padding area!\nwidth/height = content area, padding = border thickness\nBorders scale to fit padding dimensions.", - 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 }, - }) - - -- Small buttons section - local smallSection = Gui.new({ - parent = self.window, - height = 160, - positioning = "flex", - flexDirection = "vertical", - gap = 10, - backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - Gui.new({ - parent = smallSection, - height = 20, - text = "Different Padding Sizes (borders scale to padding)", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - }) - - local smallButtonRow = Gui.new({ - parent = smallSection, - positioning = "flex", - flexDirection = "horizontal", - gap = 15, - justifyContent = "center", - alignItems = "center", - }) - - -- Buttons with different padding - borders scale to fit - Gui.new({ - parent = smallButtonRow, - text = "Thin Border", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - padding = { horizontal = 8, vertical = 4 }, - themeComponent = "button", - callback = function() - print("Thin border button clicked!") - end, - }) - - Gui.new({ - parent = smallButtonRow, - text = "Medium Border", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - padding = { horizontal = 16, vertical = 8 }, - themeComponent = "button", - callback = function() - print("Medium border button clicked!") - end, - }) - - Gui.new({ - parent = smallButtonRow, - text = "Thick Border", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - padding = { horizontal = 24, vertical = 12 }, - themeComponent = "button", - callback = function() - print("Thick border button clicked!") - end, - }) - - Gui.new({ - parent = smallButtonRow, - text = "Extra Thick", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - padding = { horizontal = 32, vertical = 16 }, - themeComponent = "button", - callback = function() - print("Extra thick border button clicked!") - end, - }) - - -- Content area demonstration - local contentSection = Gui.new({ - parent = self.window, - height = 180, - positioning = "flex", - flexDirection = "vertical", - gap = 10, - backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - Gui.new({ - parent = contentSection, - height = 20, - text = "Content Area = width x height (padding adds border space)", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - }) - - local contentRow = Gui.new({ - parent = contentSection, - positioning = "flex", - flexDirection = "horizontal", - gap = 15, - justifyContent = "center", - alignItems = "center", - }) - - -- Same content size, different padding - Gui.new({ - parent = contentRow, - width = 100, - height = 40, - text = "100x40\n+5px pad", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - textSize = 10, - padding = { horizontal = 5, vertical = 5 }, - themeComponent = "button", - callback = function() - print("Small padding clicked!") - end, - }) - - Gui.new({ - parent = contentRow, - width = 100, - height = 40, - text = "100x40\n+15px pad", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - textSize = 10, - padding = { horizontal = 15, vertical = 15 }, - themeComponent = "button", - callback = function() - print("Large padding clicked!") - end, - }) - - Gui.new({ - parent = contentRow, - width = 100, - height = 40, - text = "100x40\n+25px pad", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - textSize = 10, - padding = { horizontal = 25, vertical = 25 }, - themeComponent = "button", - callback = function() - print("Extra large padding clicked!") - end, - }) - - -- Panel section - local panelSection = Gui.new({ - parent = self.window, - height = 250, - positioning = "flex", - flexDirection = "vertical", - gap = 10, - backgroundColor = Color.new(0.12, 0.12, 0.17, 0.5), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - Gui.new({ - parent = panelSection, - height = 20, - text = "Themed Panels (different sizes)", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - }) - - local panelRow = Gui.new({ - parent = panelSection, - positioning = "flex", - flexDirection = "horizontal", - gap = 15, - justifyContent = "center", - alignItems = "flex-start", - }) - - -- Small panel - local smallPanel = Gui.new({ - parent = panelRow, - width = 150, - height = 100, - themeComponent = "panel", - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - Gui.new({ - parent = smallPanel, - text = "Small\nPanel", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - }) - - -- Medium panel - local mediumPanel = Gui.new({ - parent = panelRow, - width = 200, - height = 150, - themeComponent = "panel", - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - }) - - Gui.new({ - parent = mediumPanel, - text = "Medium Panel\nwith more content", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - }) - - -- Large panel - local largePanel = Gui.new({ - parent = panelRow, - width = 250, - height = 180, - themeComponent = "panel", - padding = { top = 25, right = 25, bottom = 25, left = 25 }, - }) - - Gui.new({ - parent = largePanel, - text = "Large Panel\nScales proportionally\nBorders maintain aspect", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - }) - - return self -end - -return ProportionalScalingDemo.init() diff --git a/examples/SimpleGrid.lua b/examples/SimpleGrid.lua deleted file mode 100644 index 74ff22a..0000000 --- a/examples/SimpleGrid.lua +++ /dev/null @@ -1,236 +0,0 @@ --- Example demonstrating the simplified grid layout system --- Shows how to create grids with simple row/column counts - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color -local enums = FlexLove.enums - -print("=== Simplified Grid Layout Examples ===\n") - --- Example 1: Simple 3x2 grid -print("1. Simple 3x2 Grid") -print(" Grid with 3 columns and 2 rows") - -local grid1 = Gui.new({ - x = 50, - y = 50, - width = 600, - height = 400, - positioning = enums.Positioning.GRID, - gridRows = 2, - gridColumns = 3, - columnGap = 10, - rowGap = 10, - backgroundColor = Color.new(0.9, 0.9, 0.9, 1), - padding = { horizontal = 20, vertical = 20 }, -}) - --- Add grid items - they auto-tile in order -for i = 1, 6 do - Gui.new({ - parent = grid1, - backgroundColor = Color.new(0.2, 0.5, 0.8, 1), - text = "Item " .. i, - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - -print(" Grid container: 600x400, 3 columns, 2 rows") -print(" Column gap: 10px, Row gap: 10px") -print(" Items: 6 items auto-tiled in order\n") - --- Example 2: Square grid (4x4) -print("2. Square Grid (4x4)") -print(" Perfect for icon grids or game boards") - -Gui.destroy() -local grid2 = Gui.new({ - x = 50, - y = 50, - width = 400, - height = 400, - positioning = enums.Positioning.GRID, - gridRows = 4, - gridColumns = 4, - columnGap = 5, - rowGap = 5, - backgroundColor = Color.new(0.9, 0.9, 0.9, 1), - padding = { horizontal = 10, vertical = 10 }, -}) - -for i = 1, 16 do - Gui.new({ - parent = grid2, - backgroundColor = Color.new(0.3, 0.6, 0.3, 1), - text = tostring(i), - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - -print(" 16 items in a 4x4 grid") -print(" Each cell is equal size\n") - --- Example 3: Horizontal strip (1 row, multiple columns) -print("3. Horizontal Strip") -print(" Single row with multiple columns") - -Gui.destroy() -local grid3 = Gui.new({ - x = 50, - y = 50, - width = 800, - height = 100, - positioning = enums.Positioning.GRID, - gridRows = 1, - gridColumns = 5, - columnGap = 10, - rowGap = 0, - backgroundColor = Color.new(0.9, 0.9, 0.9, 1), - padding = { horizontal = 10, vertical = 10 }, -}) - -local labels = { "Home", "Products", "About", "Contact", "Login" } -for i = 1, 5 do - Gui.new({ - parent = grid3, - backgroundColor = Color.new(0.3, 0.3, 0.8, 1), - text = labels[i], - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - -print(" Perfect for navigation bars\n") - --- Example 4: Vertical strip (multiple rows, 1 column) -print("4. Vertical Strip") -print(" Single column with multiple rows") - -Gui.destroy() -local grid4 = Gui.new({ - x = 50, - y = 50, - width = 200, - height = 500, - positioning = enums.Positioning.GRID, - gridRows = 5, - gridColumns = 1, - columnGap = 0, - rowGap = 10, - backgroundColor = Color.new(0.9, 0.9, 0.9, 1), - padding = { horizontal = 10, vertical = 10 }, -}) - -for i = 1, 5 do - Gui.new({ - parent = grid4, - backgroundColor = Color.new(0.5, 0.3, 0.7, 1), - text = "Option " .. i, - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - -print(" Perfect for sidebar menus\n") - --- Example 5: Nested grids -print("5. Nested Grids") -print(" Grid containers within grid cells") - -Gui.destroy() -local outerGrid = Gui.new({ - x = 50, - y = 50, - width = 600, - height = 400, - positioning = enums.Positioning.GRID, - gridRows = 2, - gridColumns = 2, - columnGap = 10, - rowGap = 10, - backgroundColor = Color.new(0.85, 0.85, 0.85, 1), - padding = { horizontal = 10, vertical = 10 }, -}) - --- Top-left: Simple item -Gui.new({ - parent = outerGrid, - backgroundColor = Color.new(0.5, 0.3, 0.7, 1), - text = "Single Item", - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, -}) - --- Top-right: Nested 2x2 grid -local nestedGrid1 = Gui.new({ - parent = outerGrid, - positioning = enums.Positioning.GRID, - gridRows = 2, - gridColumns = 2, - columnGap = 5, - rowGap = 5, - backgroundColor = Color.new(0.7, 0.7, 0.7, 1), - padding = { horizontal = 5, vertical = 5 }, -}) - -for i = 1, 4 do - Gui.new({ - parent = nestedGrid1, - backgroundColor = Color.new(0.3, 0.6, 0.9, 1), - text = "A" .. i, - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - --- Bottom-left: Nested 1x3 grid -local nestedGrid2 = Gui.new({ - parent = outerGrid, - positioning = enums.Positioning.GRID, - gridRows = 1, - gridColumns = 3, - columnGap = 5, - rowGap = 5, - backgroundColor = Color.new(0.7, 0.7, 0.7, 1), - padding = { horizontal = 5, vertical = 5 }, -}) - -for i = 1, 3 do - Gui.new({ - parent = nestedGrid2, - backgroundColor = Color.new(0.9, 0.6, 0.3, 1), - text = "B" .. i, - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, - }) -end - --- Bottom-right: Another simple item -Gui.new({ - parent = outerGrid, - backgroundColor = Color.new(0.3, 0.7, 0.5, 1), - text = "Another Item", - textColor = Color.new(1, 1, 1, 1), - textAlign = enums.TextAlign.CENTER, -}) - -print(" Outer grid: 2x2 layout") -print(" Top-right: 2x2 nested grid") -print(" Bottom-left: 1x3 nested grid\n") - -print("=== Summary ===") -print("The simplified grid system provides:") -print("• Simple API: Just set gridRows and gridColumns") -print("• Auto-tiling: Children are placed in order automatically") -print("• Equal sizing: All cells are equal size") -print("• Gaps: Use columnGap and rowGap for spacing") -print("• Stretch: Children stretch to fill cells by default") -print("• Nesting: Grids can contain other grids") -print("\nNo need for complex track definitions, explicit placement, or spans!") - -Gui.destroy() diff --git a/examples/TextAutoScaling.lua b/examples/TextAutoScaling.lua deleted file mode 100644 index 453e069..0000000 --- a/examples/TextAutoScaling.lua +++ /dev/null @@ -1,131 +0,0 @@ --- Example demonstrating text auto-scaling feature --- Text automatically scales proportionally with window size by default - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Text Auto-Scaling Examples ===\n") - --- Example 1: Default auto-scaling (enabled by default) -print("1. Default Auto-Scaling (no textSize specified)") -print(" Text will scale proportionally with window size") -local button1 = Gui.new({ - x = 10, - y = 10, - padding = { horizontal = 16, vertical = 8 }, - text = "Auto-Scaled Button", - textAlign = "center", - border = { top = true, right = true, bottom = true, left = true }, - borderColor = Color.new(1, 1, 1), - textColor = Color.new(1, 1, 1), -}) -print(" Initial size (800x600): textSize = " .. button1.textSize .. "px") -button1:resize(1600, 1200) -print(" After resize (1600x1200): textSize = " .. button1.textSize .. "px") -print(" Scaling factor: " .. (button1.textSize / 9.0) .. "x\n") - --- Example 2: Disable auto-scaling for fixed text size -print("2. Auto-Scaling Disabled (autoScaleText = false)") -print(" Text remains fixed at 12px regardless of window size") -Gui.destroy() -local button2 = Gui.new({ - x = 10, - y = 60, - padding = { horizontal = 16, vertical = 8 }, - text = "Fixed Size Button", - textAlign = "center", - autoScaleText = false, - border = { top = true, right = true, bottom = true, left = true }, - borderColor = Color.new(1, 1, 1), - textColor = Color.new(1, 1, 1), -}) -print(" Initial size (800x600): textSize = " .. button2.textSize .. "px") -button2:resize(1600, 1200) -print(" After resize (1600x1200): textSize = " .. button2.textSize .. "px") -print(" No scaling applied\n") - --- Example 3: Custom auto-scaling with viewport units -print("3. Custom Auto-Scaling (textSize = '2vh')") -print(" Text scales at 2% of viewport height") -Gui.destroy() -local title = Gui.new({ - x = 10, - y = 110, - text = "Large Title", - textSize = "2vh", - textColor = Color.new(1, 1, 1), -}) -print(" Initial size (800x600): textSize = " .. title.textSize .. "px") -title:resize(1600, 1200) -print(" After resize (1600x1200): textSize = " .. title.textSize .. "px") -print(" Scaling factor: " .. (title.textSize / 12.0) .. "x\n") - --- Example 4: Fixed pixel size (still auto-scales if using viewport units) -print("4. Fixed Pixel Size (textSize = 20)") -print(" Explicit pixel values don't scale") -Gui.destroy() -local button3 = Gui.new({ - x = 10, - y = 160, - padding = { horizontal = 16, vertical = 8 }, - text = "20px Button", - textSize = 20, - textAlign = "center", - border = { top = true, right = true, bottom = true, left = true }, - borderColor = Color.new(1, 1, 1), - textColor = Color.new(1, 1, 1), -}) -print(" Initial size (800x600): textSize = " .. button3.textSize .. "px") -button3:resize(1600, 1200) -print(" After resize (1600x1200): textSize = " .. button3.textSize .. "px") -print(" Fixed at 20px\n") - --- Example 5: Element-relative scaling -print("5. Element-Relative Scaling (textSize = '10ew')") -print(" Text scales at 10% of element width") -Gui.destroy() -local box = Gui.new({ - x = 10, - y = 210, - width = 200, - height = 100, - text = "Responsive Box", - textSize = "10ew", - textAlign = "center", - backgroundColor = Color.new(0.2, 0.2, 0.2), - textColor = Color.new(1, 1, 1), -}) -print(" Initial (width=200): textSize = " .. box.textSize .. "px") -box.width = 400 -box:resize(800, 600) -print(" After width change (width=400): textSize = " .. box.textSize .. "px") -print(" Scales with element size\n") - --- Example 6: Combining auto-scaling with min/max constraints -print("6. Auto-Scaling with Constraints") -print(" Text scales between 10px and 24px") -Gui.destroy() -local constrained = Gui.new({ - x = 10, - y = 260, - text = "Constrained Text", - textSize = "3vh", - minTextSize = 10, - maxTextSize = 24, - textColor = Color.new(1, 1, 1), -}) -print(" Initial (3vh of 600): textSize = " .. constrained.textSize .. "px") -constrained:resize(1600, 1200) -print(" After resize (3vh of 1200 = 36px, clamped): textSize = " .. constrained.textSize .. "px") -print(" Clamped to maxTextSize = 24px\n") - -print("=== Summary ===") -print("• Auto-scaling is ENABLED by default") -print("• Default scaling: 1.5vh (1.5% of viewport height)") -print("• Disable with: autoScaleText = false") -print("• Custom scaling: use vh, vw, %, ew, or eh units") -print("• Fixed sizes: use pixel values (e.g., textSize = 16)") -print("• Constraints: use minTextSize and maxTextSize") diff --git a/examples/TextSizePresets.lua b/examples/TextSizePresets.lua deleted file mode 100644 index 67f4736..0000000 --- a/examples/TextSizePresets.lua +++ /dev/null @@ -1,167 +0,0 @@ --- Example demonstrating text size presets --- FlexLove provides convenient size presets that automatically scale with viewport - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Text Size Presets Examples ===\n") - --- Example 1: All size presets -print("1. All Text Size Presets") -print(" Demonstrating all available size presets\n") - -local presets = { - { name = "xxs", vh = 0.75 }, - { name = "xs", vh = 1.0 }, - { name = "sm", vh = 1.25 }, - { name = "md", vh = 1.5 }, - { name = "lg", vh = 2.0 }, - { name = "xl", vh = 2.5 }, - { name = "xxl", vh = 3.0 }, - { name = "3xl", vh = 4.0 }, - { name = "4xl", vh = 5.0 }, -} - -print("At viewport height 600px:") -for _, preset in ipairs(presets) do - local element = Gui.new({ - text = "Sample Text (" .. preset.name .. ")", - textSize = preset.name, - textColor = Color.new(1, 1, 1), - }) - - local expectedSize = (preset.vh / 100) * 600 - print(string.format(" %4s: textSize = %.2fpx (expected: %.2fpx = %.2fvh)", - preset.name, element.textSize, expectedSize, preset.vh)) - - -- Verify it matches expected size - assert(math.abs(element.textSize - expectedSize) < 0.01, - string.format("Size mismatch for %s: got %.2f, expected %.2f", preset.name, element.textSize, expectedSize)) - - element:destroy() -end - -print("\n2. Auto-Scaling Behavior") -print(" Text size presets automatically scale with viewport\n") - -Gui.destroy() -local mdElement = Gui.new({ - text = "Medium Text", - textSize = "md", - textColor = Color.new(1, 1, 1), -}) - -print(" 'md' preset at 600px viewport: " .. mdElement.textSize .. "px") -mdElement:resize(1200, 1200) -print(" 'md' preset at 1200px viewport: " .. mdElement.textSize .. "px") -print(" Scaling factor: " .. (mdElement.textSize / 9.0) .. "x\n") - --- Example 3: Combining presets with other properties -print("3. Presets with Flex Layout") -print(" Using presets in a practical layout\n") - -Gui.destroy() -local container = Gui.new({ - x = 10, - y = 10, - width = 400, - height = 300, - positioning = "flex", - flexDirection = "vertical", - gap = 10, - padding = { horizontal = 20, vertical = 20 }, - backgroundColor = Color.new(0.1, 0.1, 0.1), -}) - -local title = Gui.new({ - parent = container, - text = "Title (xl)", - textSize = "xl", - textColor = Color.new(1, 1, 1), -}) - -local subtitle = Gui.new({ - parent = container, - text = "Subtitle (lg)", - textSize = "lg", - textColor = Color.new(0.8, 0.8, 0.8), -}) - -local body = Gui.new({ - parent = container, - text = "Body text (md)", - textSize = "md", - textColor = Color.new(0.7, 0.7, 0.7), -}) - -local caption = Gui.new({ - parent = container, - text = "Caption (sm)", - textSize = "sm", - textColor = Color.new(0.5, 0.5, 0.5), -}) - -print(" Title: " .. title.textSize .. "px") -print(" Subtitle: " .. subtitle.textSize .. "px") -print(" Body: " .. body.textSize .. "px") -print(" Caption: " .. caption.textSize .. "px\n") - --- Example 4: Presets vs Custom Units -print("4. Presets vs Custom Units") -print(" Comparing preset convenience with custom units\n") - -Gui.destroy() -local preset = Gui.new({ - text = "Using preset 'lg'", - textSize = "lg", - textColor = Color.new(1, 1, 1), -}) - -local custom = Gui.new({ - text = "Using custom '2vh'", - textSize = "2vh", - textColor = Color.new(1, 1, 1), -}) - -print(" Preset 'lg': " .. preset.textSize .. "px (2vh)") -print(" Custom '2vh': " .. custom.textSize .. "px") -print(" Both are equivalent!\n") - --- Example 5: Responsive Typography -print("5. Responsive Typography Scale") -print(" Building a complete type scale with presets\n") - -Gui.destroy() -local typeScale = { - { label = "Display", preset = "4xl" }, - { label = "Heading 1", preset = "3xl" }, - { label = "Heading 2", preset = "xxl" }, - { label = "Heading 3", preset = "xl" }, - { label = "Heading 4", preset = "lg" }, - { label = "Body Large", preset = "md" }, - { label = "Body", preset = "sm" }, - { label = "Caption", preset = "xs" }, - { label = "Fine Print", preset = "xxs" }, -} - -print(" Typography Scale at 600px viewport:") -for _, item in ipairs(typeScale) do - local element = Gui.new({ - text = item.label, - textSize = item.preset, - textColor = Color.new(1, 1, 1), - }) - print(string.format(" %-15s (%4s): %.2fpx", item.label, item.preset, element.textSize)) - element:destroy() -end - -print("\n=== Summary ===") -print("• Text size presets: xxs, xs, sm, md, lg, xl, xxl, 3xl, 4xl") -print("• All presets use viewport-relative units (vh)") -print("• Automatically scale with window size") -print("• Provide consistent typography scales") -print("• Can be mixed with custom units (px, vh, vw, %, ew, eh)") -print("• Default preset when no textSize specified: md (1.5vh)") diff --git a/examples/ThemeColorAccessDemo.lua b/examples/ThemeColorAccessDemo.lua deleted file mode 100644 index 022f532..0000000 --- a/examples/ThemeColorAccessDemo.lua +++ /dev/null @@ -1,170 +0,0 @@ --- Theme Color Access Demo --- Demonstrates various ways to access and use theme colors - -package.path = package.path .. ";./?.lua;../?.lua" - -local FlexLove = require("FlexLove") -local Theme = FlexLove.Theme -local Gui = FlexLove.Gui -local Color = FlexLove.Color - --- Initialize love stubs for testing -love = { - graphics = { - newFont = function(size) return { getHeight = function() return size end } end, - getFont = function() return { getHeight = function() return 12 end } end, - getWidth = function() return 1920 end, - getHeight = function() return 1080 end, - newImage = function() return {} end, - newQuad = function() return {} end, - }, -} - -print("=== Theme Color Access Demo ===\n") - --- Load and activate the space theme -Theme.load("space") -Theme.setActive("space") - -print("1. Basic Color Access") -print("---------------------") - --- Method 1: Using Theme.getColor() (Recommended) -local primaryColor = Theme.getColor("primary") -local secondaryColor = Theme.getColor("secondary") -local textColor = Theme.getColor("text") -local textDarkColor = Theme.getColor("textDark") - -print(string.format("Primary: r=%.2f, g=%.2f, b=%.2f", primaryColor.r, primaryColor.g, primaryColor.b)) -print(string.format("Secondary: r=%.2f, g=%.2f, b=%.2f", secondaryColor.r, secondaryColor.g, secondaryColor.b)) -print(string.format("Text: r=%.2f, g=%.2f, b=%.2f", textColor.r, textColor.g, textColor.b)) -print(string.format("Text Dark: r=%.2f, g=%.2f, b=%.2f", textDarkColor.r, textDarkColor.g, textDarkColor.b)) - -print("\n2. Get All Available Colors") -print("----------------------------") - --- Method 2: Get all color names -local colorNames = Theme.getColorNames() -if colorNames then - print("Available colors in theme:") - for _, name in ipairs(colorNames) do - print(" - " .. name) - end -end - -print("\n3. Get All Colors at Once") -print("-------------------------") - --- Method 3: Get all colors as a table -local allColors = Theme.getAllColors() -if allColors then - print("All colors:") - for name, color in pairs(allColors) do - print(string.format(" %s: r=%.2f, g=%.2f, b=%.2f, a=%.2f", name, color.r, color.g, color.b, color.a)) - end -end - -print("\n4. Safe Color Access with Fallback") -print("-----------------------------------") - --- Method 4: Get color with fallback -local accentColor = Theme.getColorOrDefault("accent", Color.new(1, 0, 0, 1)) -- Falls back to red -local primaryColor2 = Theme.getColorOrDefault("primary", Color.new(1, 0, 0, 1)) -- Uses theme color - -print(string.format("Accent (fallback): r=%.2f, g=%.2f, b=%.2f", accentColor.r, accentColor.g, accentColor.b)) -print(string.format("Primary (theme): r=%.2f, g=%.2f, b=%.2f", primaryColor2.r, primaryColor2.g, primaryColor2.b)) - -print("\n5. Using Colors in GUI Elements") -print("--------------------------------") - --- Create a container with theme colors -local container = Gui.new({ - width = 400, - height = 300, - backgroundColor = Theme.getColor("secondary"), - positioning = FlexLove.enums.Positioning.FLEX, - flexDirection = FlexLove.enums.FlexDirection.VERTICAL, - gap = 10, - padding = { top = 20, right = 20, bottom = 20, left = 20 }, -}) - --- Create a button with primary color -local button = Gui.new({ - parent = container, - width = 360, - height = 50, - backgroundColor = Theme.getColor("primary"), - textColor = Theme.getColor("text"), - text = "Click Me!", - textSize = 18, -}) - --- Create a text label with dark text -local label = Gui.new({ - parent = container, - width = 360, - height = 30, - backgroundColor = Theme.getColorOrDefault("background", Color.new(0.2, 0.2, 0.2, 1)), - textColor = Theme.getColor("textDark"), - text = "This is a label with dark text", - textSize = 14, -}) - -print("Created GUI elements with theme colors:") -print(string.format(" Container: %d children", #container.children)) -print(string.format(" Button background: r=%.2f, g=%.2f, b=%.2f", button.backgroundColor.r, button.backgroundColor.g, button.backgroundColor.b)) -print(string.format(" Label text color: r=%.2f, g=%.2f, b=%.2f", label.textColor.r, label.textColor.g, label.textColor.b)) - -print("\n6. Creating Color Variations") -print("-----------------------------") - --- Create variations of theme colors -local primaryDark = Color.new( - primaryColor.r * 0.7, - primaryColor.g * 0.7, - primaryColor.b * 0.7, - primaryColor.a -) - -local primaryLight = Color.new( - math.min(1, primaryColor.r * 1.3), - math.min(1, primaryColor.g * 1.3), - math.min(1, primaryColor.b * 1.3), - primaryColor.a -) - -local primaryTransparent = Color.new( - primaryColor.r, - primaryColor.g, - primaryColor.b, - 0.5 -) - -print(string.format("Primary (original): r=%.2f, g=%.2f, b=%.2f, a=%.2f", primaryColor.r, primaryColor.g, primaryColor.b, primaryColor.a)) -print(string.format("Primary (dark): r=%.2f, g=%.2f, b=%.2f, a=%.2f", primaryDark.r, primaryDark.g, primaryDark.b, primaryDark.a)) -print(string.format("Primary (light): r=%.2f, g=%.2f, b=%.2f, a=%.2f", primaryLight.r, primaryLight.g, primaryLight.b, primaryLight.a)) -print(string.format("Primary (50%% alpha): r=%.2f, g=%.2f, b=%.2f, a=%.2f", primaryTransparent.r, primaryTransparent.g, primaryTransparent.b, primaryTransparent.a)) - -print("\n7. Quick Reference") -print("------------------") -print([[ -// Basic usage: -local color = Theme.getColor("primary") - -// With fallback: -local color = Theme.getColorOrDefault("accent", Color.new(1, 0, 0, 1)) - -// Get all colors: -local colors = Theme.getAllColors() - -// Get color names: -local names = Theme.getColorNames() - -// Use in elements: -local button = Gui.new({ - backgroundColor = Theme.getColor("primary"), - textColor = Theme.getColor("text"), -}) -]]) - -print("\n=== Demo Complete ===") diff --git a/examples/ThemeInitDemo.lua b/examples/ThemeInitDemo.lua deleted file mode 100644 index 272a3d2..0000000 --- a/examples/ThemeInitDemo.lua +++ /dev/null @@ -1,104 +0,0 @@ --- Example: Setting theme in Gui.init() --- NOTE: This should be called in love.load() after LÖVE graphics is initialized -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color -local Theme = FlexLove.Theme - --- In love.load(): --- Initialize GUI with theme -Gui.init({ - baseScale = { width = 1920, height = 1080 }, - theme = "space" -- Load and activate the space theme -}) - --- Alternative: Load theme manually if Gui.init() is called before love.load() --- Theme.load("space") --- Theme.setActive("space") - --- Now all elements can use the theme -local panel = Gui.new({ - x = 100, - y = 100, - width = 400, - height = 300, - themeComponent = "panel", - padding = { top = 20, right = 20, bottom = 20, left = 20 }, -}) - -local button1 = Gui.new({ - parent = panel, - x = 20, - y = 20, - width = 150, - height = 50, - text = "Normal Button", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - themeComponent = "button", - callback = function(element, event) - if event.type == "click" then - print("Button clicked!") - end - end -}) - -local button2 = Gui.new({ - parent = panel, - x = 20, - y = 80, - width = 150, - height = 50, - text = "Disabled", - textAlign = "center", - textColor = Color.new(0.6, 0.6, 0.6, 1), - themeComponent = "button", - disabled = true, -- Shows disabled state - callback = function(element, event) - print("This won't fire!") - end -}) - -local input1 = Gui.new({ - parent = panel, - x = 20, - y = 140, - width = 200, - height = 40, - text = "Type here...", - textColor = Color.new(1, 1, 1, 1), - themeComponent = "input", -}) - -local input2 = Gui.new({ - parent = panel, - x = 20, - y = 190, - width = 200, - height = 40, - text = "Active input", - textColor = Color.new(1, 1, 1, 1), - themeComponent = "input", - active = true, -- Shows active/focused state -}) - -local input3 = Gui.new({ - parent = panel, - x = 20, - y = 240, - width = 200, - height = 40, - text = "Disabled input", - textColor = Color.new(0.6, 0.6, 0.6, 1), - themeComponent = "input", - disabled = true, -- Shows disabled state -}) - -return { - panel = panel, - button1 = button1, - button2 = button2, - input1 = input1, - input2 = input2, - input3 = input3, -} diff --git a/examples/ThemeLayeringDemo.lua b/examples/ThemeLayeringDemo.lua deleted file mode 100644 index 0e0ac78..0000000 --- a/examples/ThemeLayeringDemo.lua +++ /dev/null @@ -1,196 +0,0 @@ --- 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 diff --git a/examples/ThemeSystemDemo.lua b/examples/ThemeSystemDemo.lua deleted file mode 100644 index 19ef47c..0000000 --- a/examples/ThemeSystemDemo.lua +++ /dev/null @@ -1,216 +0,0 @@ -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Theme = FlexLove.Theme -local Color = FlexLove.Color - ----@class ThemeDemo ----@field window Element ----@field statusText Element -local ThemeDemo = {} -ThemeDemo.__index = ThemeDemo - -function ThemeDemo.init() - local self = setmetatable({}, ThemeDemo) - - -- Try to load and set the default theme - -- Note: This will fail if the atlas image doesn't exist yet - -- For now, we'll demonstrate the API without actually loading a theme - local themeLoaded = false - local themeError = nil - - pcall(function() - Theme.load("default") - Theme.setActive("default") - themeLoaded = true - end) - - -- Create main demo window (without theme for now) - self.window = Gui.new({ - x = 50, - y = 50, - width = 700, - height = 550, - backgroundColor = Color.new(0.15, 0.15, 0.2, 0.95), - border = { top = true, bottom = true, left = true, right = true }, - borderColor = Color.new(0.8, 0.8, 0.8, 1), - positioning = "flex", - flexDirection = "vertical", - gap = 20, - padding = { top = 20, right = 20, bottom = 20, left = 20 }, - }) - - -- Title - local title = Gui.new({ - parent = self.window, - height = 40, - text = "Theme System Demo", - textSize = 20, - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.2, 0.2, 0.3, 1), - }) - - -- Status message - self.statusText = Gui.new({ - parent = self.window, - height = 60, - text = themeLoaded and "✓ Theme loaded successfully!\nTheme system is ready to use." - or "⚠ Theme not loaded (atlas image missing)\nShowing API demonstration without actual theme rendering.", - textSize = 14, - textAlign = "center", - textColor = themeLoaded and Color.new(0.3, 0.9, 0.3, 1) or Color.new(0.9, 0.7, 0.3, 1), - backgroundColor = Color.new(0.1, 0.1, 0.15, 0.8), - padding = { top = 10, right = 10, bottom = 10, left = 10 }, - }) - - -- Info section - local infoSection = Gui.new({ - parent = self.window, - height = 350, - positioning = "flex", - flexDirection = "vertical", - gap = 15, - backgroundColor = Color.new(0.1, 0.1, 0.15, 0.5), - padding = { top = 15, right = 15, bottom = 15, left = 15 }, - }) - - -- Example 1: Basic themed button - local example1 = Gui.new({ - parent = infoSection, - height = 80, - 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: Basic Themed Button", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- This button would use theme if loaded - local themedButton = Gui.new({ - parent = example1, - width = 150, - height = 40, - text = "Themed Button", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.2, 0.6, 0.9, 0.8), - -- theme = "button", -- Uncomment when theme atlas exists - callback = function(element, event) - if event.type == "click" then - print("Themed button clicked!") - end - end, - }) - - -- Example 2: Button with states - local example2 = Gui.new({ - parent = infoSection, - 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: Button with Hover/Pressed States", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - Gui.new({ - parent = example2, - height = 15, - text = "Hover over or click the button to see state changes (when theme is loaded)", - textSize = 11, - textColor = Color.new(0.6, 0.7, 0.8, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - local stateButton = Gui.new({ - parent = example2, - width = 200, - height = 40, - text = "Interactive Button", - textAlign = "center", - textColor = Color.new(1, 1, 1, 1), - backgroundColor = Color.new(0.3, 0.7, 0.4, 0.8), - -- theme = "button", -- Will automatically handle hover/pressed states - callback = function(element, event) - if event.type == "click" then - print("State button clicked! State was:", element._themeState) - end - end, - }) - - -- Example 3: Themed panel - local example3 = Gui.new({ - parent = infoSection, - 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: Themed Panel/Container", - textSize = 14, - textColor = Color.new(0.8, 0.9, 1, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - local themedPanel = Gui.new({ - parent = example3, - width = 300, - height = 80, - backgroundColor = Color.new(0.25, 0.25, 0.35, 0.9), - -- theme = "panel", -- Would use panel theme component - padding = { top = 10, right = 10, bottom = 10, left = 10 }, - }) - - Gui.new({ - parent = themedPanel, - text = "This is a themed panel container.\nIt would have a 9-slice border when theme is loaded.", - textSize = 12, - textColor = Color.new(0.9, 0.9, 1, 1), - textAlign = "center", - backgroundColor = Color.new(0, 0, 0, 0), - }) - - -- Code example section - local codeSection = Gui.new({ - parent = self.window, - height = 40, - backgroundColor = Color.new(0.08, 0.08, 0.12, 1), - padding = { top = 10, right = 10, bottom = 10, left = 10 }, - }) - - Gui.new({ - parent = codeSection, - text = 'Usage: element = Gui.new({ theme = "button", ... })', - textSize = 12, - textColor = Color.new(0.5, 0.9, 0.5, 1), - backgroundColor = Color.new(0, 0, 0, 0), - }) - - return self -end - -return ThemeDemo.init() diff --git a/examples/ZIndexDemo.lua b/examples/ZIndexDemo.lua deleted file mode 100644 index 20aaa33..0000000 --- a/examples/ZIndexDemo.lua +++ /dev/null @@ -1,218 +0,0 @@ --- Example demonstrating z-index functionality --- Elements with higher z-index appear on top (drawn last) - -package.path = package.path .. ";?.lua" -require("testing/loveStub") -local FlexLove = require("FlexLove") -local Gui = FlexLove.GUI -local Color = FlexLove.Color - -print("=== Z-Index Demo ===\n") - --- Example 1: Top-level elements with different z-indices -print("1. Top-Level Elements") -print(" Creating 3 overlapping elements with different z-indices\n") - -local back = Gui.new({ - id = "back", - x = 10, - y = 10, - width = 100, - height = 100, - z = 1, - backgroundColor = Color.new(1, 0, 0, 0.8), - text = "Z=1 (Back)", - textColor = Color.new(1, 1, 1), -}) - -local middle = Gui.new({ - id = "middle", - x = 50, - y = 50, - width = 100, - height = 100, - z = 2, - backgroundColor = Color.new(0, 1, 0, 0.8), - text = "Z=2 (Middle)", - textColor = Color.new(1, 1, 1), -}) - -local front = Gui.new({ - id = "front", - x = 90, - y = 90, - width = 100, - height = 100, - z = 3, - backgroundColor = Color.new(0, 0, 1, 0.8), - text = "Z=3 (Front)", - textColor = Color.new(1, 1, 1), -}) - -print("Before draw:") -for i, elem in ipairs(Gui.topElements) do - print(string.format(" %d. %s (z=%d)", i, elem.id, elem.z)) -end - --- Trigger sorting by calling draw -Gui.draw() - -print("\nAfter draw (sorted by z-index):") -for i, elem in ipairs(Gui.topElements) do - print(string.format(" %d. %s (z=%d)", i, elem.id, elem.z)) -end -print(" Draw order: back → middle → front ✓") - --- Example 2: Children with z-indices -print("\n2. Children with Z-Indices") -print(" Children are also sorted by z-index within parent\n") - -Gui.destroy() - -local parent = Gui.new({ - id = "parent", - x = 0, - y = 0, - width = 300, - height = 300, - backgroundColor = Color.new(0.1, 0.1, 0.1, 1), -}) - --- Create children in random z-order -local child3 = Gui.new({ - parent = parent, - id = "child3", - x = 150, - y = 150, - width = 80, - height = 80, - z = 3, - backgroundColor = Color.new(0, 0, 1, 0.8), - text = "Z=3", - textColor = Color.new(1, 1, 1), -}) - -local child1 = Gui.new({ - parent = parent, - id = "child1", - x = 50, - y = 50, - width = 80, - height = 80, - z = 1, - backgroundColor = Color.new(1, 0, 0, 0.8), - text = "Z=1", - textColor = Color.new(1, 1, 1), -}) - -local child2 = Gui.new({ - parent = parent, - id = "child2", - x = 100, - y = 100, - width = 80, - height = 80, - z = 2, - backgroundColor = Color.new(0, 1, 0, 0.8), - text = "Z=2", - textColor = Color.new(1, 1, 1), -}) - -print("Children added in order: child3, child1, child2") -print("Children z-indices: child3.z=3, child1.z=1, child2.z=2") -print("\nDuring draw, children will be sorted and drawn:") -print(" 1. child1 (z=1) - drawn first (back)") -print(" 2. child2 (z=2) - drawn second (middle)") -print(" 3. child3 (z=3) - drawn last (front) ✓") - --- Example 3: Negative z-indices -print("\n3. Negative Z-Indices") -print(" Z-index can be negative for background elements\n") - -Gui.destroy() - -local backgroundColor = Gui.new({ - id = "background", - x = 0, - y = 0, - width = 200, - height = 200, - z = -1, - backgroundColor = Color.new(0.2, 0.2, 0.2, 1), - text = "Background (z=-1)", - textColor = Color.new(1, 1, 1), -}) - -local normal = Gui.new({ - id = "normal", - x = 50, - y = 50, - width = 100, - height = 100, - z = 0, - backgroundColor = Color.new(0.5, 0.5, 0.5, 1), - text = "Normal (z=0)", - textColor = Color.new(1, 1, 1), -}) - -Gui.draw() - -print("Elements sorted by z-index:") -for i, elem in ipairs(Gui.topElements) do - print(string.format(" %d. %s (z=%d)", i, elem.id, elem.z)) -end -print(" Background element drawn first ✓") - --- Example 4: Default z-index -print("\n4. Default Z-Index") -print(" Elements without explicit z-index default to 0\n") - -Gui.destroy() - -local default1 = Gui.new({ - id = "default1", - x = 10, - y = 10, - width = 50, - height = 50, - backgroundColor = Color.new(1, 0, 0, 1), -}) - -local explicit = Gui.new({ - id = "explicit", - x = 30, - y = 30, - width = 50, - height = 50, - z = 1, - backgroundColor = Color.new(0, 1, 0, 1), -}) - -local default2 = Gui.new({ - id = "default2", - x = 50, - y = 50, - width = 50, - height = 50, - backgroundColor = Color.new(0, 0, 1, 1), -}) - -print("default1.z =", default1.z, "(default)") -print("explicit.z =", explicit.z, "(explicit)") -print("default2.z =", default2.z, "(default)") - -Gui.draw() - -print("\nAfter sorting:") -for i, elem in ipairs(Gui.topElements) do - print(string.format(" %d. %s (z=%d)", i, elem.id, elem.z)) -end -print(" Elements with z=0 drawn first, then z=1 ✓") - -print("\n=== Summary ===") -print("• Z-index controls draw order (lower z drawn first, appears behind)") -print("• Top-level elements are sorted by z-index in Gui.draw()") -print("• Children are sorted by z-index within parent.draw()") -print("• Default z-index is 0") -print("• Negative z-indices are supported") -print("• Higher z-index = drawn later = appears on top") diff --git a/testing/__tests__/01_absolute_positioning_basic_tests.lua b/testing/__tests__/01_absolute_positioning_basic_tests.lua index ee62a5e..f331748 100644 --- a/testing/__tests__/01_absolute_positioning_basic_tests.lua +++ b/testing/__tests__/01_absolute_positioning_basic_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";./?.lua;./game/?.lua;./game/utils/?.lua;./game/components/?.lua;./game/systems/?.lua" local luaunit = require("testing.luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/02_absolute_positioning_child_layout_tests.lua b/testing/__tests__/02_absolute_positioning_child_layout_tests.lua index 644f93a..66366d1 100644 --- a/testing/__tests__/02_absolute_positioning_child_layout_tests.lua +++ b/testing/__tests__/02_absolute_positioning_child_layout_tests.lua @@ -4,8 +4,8 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/03_flex_direction_horizontal_tests.lua b/testing/__tests__/03_flex_direction_horizontal_tests.lua index c78ded4..7dd8e10 100644 --- a/testing/__tests__/03_flex_direction_horizontal_tests.lua +++ b/testing/__tests__/03_flex_direction_horizontal_tests.lua @@ -3,8 +3,8 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/04_flex_direction_vertical_tests.lua b/testing/__tests__/04_flex_direction_vertical_tests.lua index 8343f5c..1936162 100644 --- a/testing/__tests__/04_flex_direction_vertical_tests.lua +++ b/testing/__tests__/04_flex_direction_vertical_tests.lua @@ -3,8 +3,8 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/05_justify_content_tests.lua b/testing/__tests__/05_justify_content_tests.lua index 3d89ae5..5783646 100644 --- a/testing/__tests__/05_justify_content_tests.lua +++ b/testing/__tests__/05_justify_content_tests.lua @@ -4,8 +4,8 @@ -- Load test framework and dependencies package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/06_align_items_tests.lua b/testing/__tests__/06_align_items_tests.lua index 3f6d11e..4cb25e6 100644 --- a/testing/__tests__/06_align_items_tests.lua +++ b/testing/__tests__/06_align_items_tests.lua @@ -4,8 +4,8 @@ -- Load test framework and dependencies package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums @@ -192,8 +192,8 @@ function TestAlignItems:testHorizontalFlexAlignItemsStretch() -- Children with explicit heights should NOT be stretched (CSS flexbox behavior) luaunit.assertEquals(child1.y, 0) luaunit.assertEquals(child2.y, 0) - luaunit.assertEquals(child1.height, 30) -- Keeps explicit height - luaunit.assertEquals(child2.height, 40) -- Keeps explicit height + luaunit.assertEquals(child1.height, 30) -- Keeps explicit height + luaunit.assertEquals(child2.height, 40) -- Keeps explicit height end -- Test 5: Vertical Flex with AlignItems.FLEX_START @@ -360,8 +360,8 @@ function TestAlignItems:testVerticalFlexAlignItemsStretch() -- Children with explicit widths should NOT be stretched (CSS flexbox behavior) luaunit.assertEquals(child1.x, 0) luaunit.assertEquals(child2.x, 0) - luaunit.assertEquals(child1.width, 50) -- Keeps explicit width - luaunit.assertEquals(child2.width, 80) -- Keeps explicit width + luaunit.assertEquals(child1.width, 50) -- Keeps explicit width + luaunit.assertEquals(child2.width, 80) -- Keeps explicit width end -- Test 9: Default AlignItems value (should be STRETCH) diff --git a/testing/__tests__/07_flex_wrap_tests.lua b/testing/__tests__/07_flex_wrap_tests.lua index d0ff319..7a95f18 100644 --- a/testing/__tests__/07_flex_wrap_tests.lua +++ b/testing/__tests__/07_flex_wrap_tests.lua @@ -1,8 +1,6 @@ package.path = package.path .. ";./?.lua;./game/?.lua;./game/utils/?.lua;./game/components/?.lua;./game/systems/?.lua" local luaunit = require("testing.luaunit") - --- Import the love stub and FlexLove require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/08_comprehensive_flex_tests.lua b/testing/__tests__/08_comprehensive_flex_tests.lua index 9cd08cf..00a310c 100644 --- a/testing/__tests__/08_comprehensive_flex_tests.lua +++ b/testing/__tests__/08_comprehensive_flex_tests.lua @@ -1,8 +1,6 @@ package.path = package.path .. ";./?.lua;./game/?.lua;./game/utils/?.lua;./game/components/?.lua;./game/systems/?.lua" local luaunit = require("testing.luaunit") - --- Import the love stub and FlexLove require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums diff --git a/testing/__tests__/09_layout_validation_tests.lua b/testing/__tests__/09_layout_validation_tests.lua index 78ede29..cf25a26 100644 --- a/testing/__tests__/09_layout_validation_tests.lua +++ b/testing/__tests__/09_layout_validation_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums local Color = FlexLove.Color diff --git a/testing/__tests__/10_performance_tests.lua b/testing/__tests__/10_performance_tests.lua index 5df3ed4..4263e5a 100644 --- a/testing/__tests__/10_performance_tests.lua +++ b/testing/__tests__/10_performance_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums local Positioning = enums.Positioning diff --git a/testing/__tests__/11_auxiliary_functions_tests.lua b/testing/__tests__/11_auxiliary_functions_tests.lua index f78a48f..3c3e600 100644 --- a/testing/__tests__/11_auxiliary_functions_tests.lua +++ b/testing/__tests__/11_auxiliary_functions_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, Color, enums = FlexLove.GUI, FlexLove.Color, FlexLove.enums @@ -493,21 +493,21 @@ function TestAuxiliaryFunctions:testAnimationInterpolationAtBoundaries() -- At start (elapsed = 0) scaleAnim.elapsed = 0 - scaleAnim._resultDirty = true -- Mark dirty after changing elapsed + scaleAnim._resultDirty = true -- Mark dirty after changing elapsed local result = scaleAnim:interpolate() luaunit.assertEquals(result.width, 100) luaunit.assertEquals(result.height, 50) -- At end (elapsed = duration) scaleAnim.elapsed = 1.0 - scaleAnim._resultDirty = true -- Mark dirty after changing elapsed + scaleAnim._resultDirty = true -- Mark dirty after changing elapsed result = scaleAnim:interpolate() luaunit.assertEquals(result.width, 200) luaunit.assertEquals(result.height, 100) -- Beyond end (elapsed > duration) - should clamp to end values scaleAnim.elapsed = 1.5 - scaleAnim._resultDirty = true -- Mark dirty after changing elapsed + scaleAnim._resultDirty = true -- Mark dirty after changing elapsed result = scaleAnim:interpolate() luaunit.assertEquals(result.width, 200) luaunit.assertEquals(result.height, 100) @@ -683,7 +683,7 @@ function TestAuxiliaryFunctions:testComplexColorManagementSystem() ui_container:layoutChildren() luaunit.assertEquals(#ui_container.children, 5, "Should have 5 themed components") - + -- Count theme_colors (it's a table with string keys, not an array) local theme_color_count = 0 for _ in pairs(theme_colors) do @@ -952,7 +952,7 @@ function TestAuxiliaryFunctions:testAdvancedTextAndAutoSizingSystem() #text_scenarios + 1, "Should have scenario containers plus nested container" ) - + -- Count text_metrics (it's a table with string keys, not an array) local metrics_count = 0 for _ in pairs(content_manager.text_metrics) do diff --git a/testing/__tests__/12_units_system_tests.lua b/testing/__tests__/12_units_system_tests.lua index 0ed8533..558f2b2 100644 --- a/testing/__tests__/12_units_system_tests.lua +++ b/testing/__tests__/12_units_system_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") local FlexLove = require("FlexLove") local Gui, enums = FlexLove.GUI, FlexLove.enums @@ -152,7 +152,7 @@ function TestUnitsSystem:testResizeViewportUnits() luaunit.assertEquals(container.width, 800) -- 50% of 1600 luaunit.assertEquals(container.height, 250) -- 25% of 1000 - + -- Restore viewport love.window.setMode(1200, 800) end diff --git a/testing/__tests__/13_relative_positioning_tests.lua b/testing/__tests__/13_relative_positioning_tests.lua index fa8440f..c1ce4e1 100644 --- a/testing/__tests__/13_relative_positioning_tests.lua +++ b/testing/__tests__/13_relative_positioning_tests.lua @@ -1,8 +1,8 @@ -- Test relative positioning functionality package.path = package.path .. ";?.lua" -require("testing/loveStub") +require("testing.loveStub") local FlexLove = require("FlexLove") -local luaunit = require("testing/luaunit") +local luaunit = require("testing.luaunit") local Gui, enums = FlexLove.GUI, FlexLove.enums local Color = FlexLove.Color diff --git a/testing/__tests__/14_text_scaling_basic_tests.lua b/testing/__tests__/14_text_scaling_basic_tests.lua index 83d0f15..f17f0d8 100644 --- a/testing/__tests__/14_text_scaling_basic_tests.lua +++ b/testing/__tests__/14_text_scaling_basic_tests.lua @@ -3,8 +3,8 @@ package.path = package.path .. ";?.lua" -local luaunit = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local luaunit = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui = FlexLove.GUI @@ -135,7 +135,7 @@ function TestTextScaling.testNoTextSize() -- Resize should scale the text element:resize(1600, 1200) luaunit.assertEquals(element.textSize, 18.0) -- 1.5% of 1200px - + -- Test with auto-scaling disabled local elementNoScale = Gui.new({ id = "testElementNoScale", @@ -144,11 +144,11 @@ function TestTextScaling.testNoTextSize() text = "Hello World", autoScaleText = false, }) - + luaunit.assertEquals(elementNoScale.autoScaleText, false) luaunit.assertEquals(elementNoScale.units.textSize.value, nil) luaunit.assertEquals(elementNoScale.textSize, 12) -- Fixed 12px - + -- Resize should not affect textSize when auto-scaling is disabled elementNoScale:resize(1600, 1200) luaunit.assertEquals(elementNoScale.textSize, 12) diff --git a/testing/__tests__/15_grid_layout_tests.lua b/testing/__tests__/15_grid_layout_tests.lua index 1d18719..83044bb 100644 --- a/testing/__tests__/15_grid_layout_tests.lua +++ b/testing/__tests__/15_grid_layout_tests.lua @@ -3,11 +3,10 @@ package.path = package.path .. ";?.lua" -local lu = require("testing/luaunit") -require("testing/loveStub") -- Required to mock LOVE functions +local lu = require("testing.luaunit") +require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") local Gui = FlexLove.GUI -local Color = FlexLove.Color local enums = FlexLove.enums TestGridLayout = {} diff --git a/testing/__tests__/16_event_system_tests.lua b/testing/__tests__/16_event_system_tests.lua index 51bf2bb..9ed4141 100644 --- a/testing/__tests__/16_event_system_tests.lua +++ b/testing/__tests__/16_event_system_tests.lua @@ -6,9 +6,7 @@ package.path = package.path .. ";?.lua" local lu = require("testing.luaunit") require("testing.loveStub") -- Required to mock LOVE functions local FlexLove = require("FlexLove") - local Gui = FlexLove.GUI -local Color = FlexLove.Color TestEventSystem = {} diff --git a/testing/__tests__/17_sibling_space_reservation_tests.lua b/testing/__tests__/17_sibling_space_reservation_tests.lua index 7388300..04efd67 100644 --- a/testing/__tests__/17_sibling_space_reservation_tests.lua +++ b/testing/__tests__/17_sibling_space_reservation_tests.lua @@ -4,7 +4,7 @@ package.path = package.path .. ";?.lua" local lu = require("testing.luaunit") -require("testing.loveStub") -- Required to mock LOVE functions +require("testing.loveStub") local FlexLove = require("FlexLove") local Gui = FlexLove.GUI local Color = FlexLove.Color diff --git a/testing/__tests__/18_font_family_inheritance_tests.lua b/testing/__tests__/18_font_family_inheritance_tests.lua index 44adeeb..0ec9845 100644 --- a/testing/__tests__/18_font_family_inheritance_tests.lua +++ b/testing/__tests__/18_font_family_inheritance_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" local lu = require("testing.luaunit") -require("testing.loveStub") -- Required to mock LOVE functions +require("testing.loveStub") local FlexLove = require("FlexLove") TestFontFamilyInheritance = {} @@ -94,8 +94,8 @@ function TestFontFamilyInheritance:testInheritanceInFlexContainer() local flexParent = FlexLove.Element.new({ width = 300, height = 300, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.HORIZONTAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.HORIZONTAL, fontFamily = "Courier", }) @@ -121,7 +121,7 @@ function TestFontFamilyInheritance:testInheritanceInGridContainer() local gridParent = FlexLove.Element.new({ width = 300, height = 300, - positioning = FlexLove.Positioning.GRID, + positioning = FlexLove.enums.Positioning.GRID, gridRows = 2, gridColumns = 2, fontFamily = "Verdana", @@ -183,7 +183,7 @@ function TestFontFamilyInheritance:testInheritanceWithAbsolutePositioning() local child = FlexLove.Element.new({ parent = parent, - positioning = FlexLove.Positioning.ABSOLUTE, + positioning = FlexLove.enums.Positioning.ABSOLUTE, x = 50, y = 50, width = 100, diff --git a/testing/__tests__/19_negative_margin_tests.lua b/testing/__tests__/19_negative_margin_tests.lua index f3d4987..9d0855e 100644 --- a/testing/__tests__/19_negative_margin_tests.lua +++ b/testing/__tests__/19_negative_margin_tests.lua @@ -1,7 +1,7 @@ package.path = package.path .. ";?.lua" local lu = require("testing.luaunit") -require("testing.loveStub") -- Required to mock LOVE functions +require("testing.loveStub") local FlexLove = require("FlexLove") TestNegativeMargin = {} @@ -19,8 +19,8 @@ function TestNegativeMargin:testBasicNegativeMarginTop() local parent = FlexLove.Element.new({ width = 200, height = 200, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.VERTICAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.VERTICAL, }) local child1 = FlexLove.Element.new({ @@ -46,8 +46,8 @@ function TestNegativeMargin:testNegativeMarginLeft() local parent = FlexLove.Element.new({ width = 300, height = 100, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.HORIZONTAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.HORIZONTAL, }) local child1 = FlexLove.Element.new({ @@ -72,8 +72,8 @@ function TestNegativeMargin:testNegativeMarginRight() local parent = FlexLove.Element.new({ width = 300, height = 100, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.HORIZONTAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.HORIZONTAL, }) local child = FlexLove.Element.new({ @@ -92,8 +92,8 @@ function TestNegativeMargin:testNegativeMarginBottom() local parent = FlexLove.Element.new({ width = 200, height = 200, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.VERTICAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.VERTICAL, }) local child = FlexLove.Element.new({ @@ -181,7 +181,7 @@ function TestNegativeMargin:testNegativeMarginInGridLayout() local gridParent = FlexLove.Element.new({ width = 300, height = 300, - positioning = FlexLove.Positioning.GRID, + positioning = FlexLove.enums.Positioning.GRID, gridRows = 2, gridColumns = 2, }) @@ -258,7 +258,7 @@ function TestNegativeMargin:testNegativeMarginWithAbsolutePositioning() local child = FlexLove.Element.new({ parent = parent, - positioning = FlexLove.Positioning.ABSOLUTE, + positioning = FlexLove.enums.Positioning.ABSOLUTE, x = 50, y = 50, width = 100, diff --git a/testing/__tests__/20_padding_resize_tests.lua b/testing/__tests__/20_padding_resize_tests.lua index 5bcc4e8..fee44f7 100644 --- a/testing/__tests__/20_padding_resize_tests.lua +++ b/testing/__tests__/20_padding_resize_tests.lua @@ -102,8 +102,8 @@ function TestPaddingResize:testNestedPercentagePadding() width = "100%", height = "100%", padding = { horizontal = "10%", vertical = "10%" }, - positioning = FlexLove.Positioning.FLEX, - flexDirection = FlexLove.FlexDirection.VERTICAL, + positioning = FlexLove.enums.Positioning.FLEX, + flexDirection = FlexLove.enums.FlexDirection.VERTICAL, }) -- Create child with percentage padding (relative to parent's content area) diff --git a/testing/__tests__/23_image_scaler_bilinear_tests.lua b/testing/__tests__/22_image_scaler_bilinear_tests.lua similarity index 97% rename from testing/__tests__/23_image_scaler_bilinear_tests.lua rename to testing/__tests__/22_image_scaler_bilinear_tests.lua index f19e393..713b5ed 100644 --- a/testing/__tests__/23_image_scaler_bilinear_tests.lua +++ b/testing/__tests__/22_image_scaler_bilinear_tests.lua @@ -275,14 +275,17 @@ function TestImageScalerBilinear:testComparison_SmootherThanNearest() end local bilinearCount = 0 - for _ in pairs(bilinearValues) do bilinearCount = bilinearCount + 1 end - + for _ in pairs(bilinearValues) do + bilinearCount = bilinearCount + 1 + end + local nearestCount = 0 - for _ in pairs(nearestValues) do nearestCount = nearestCount + 1 end + for _ in pairs(nearestValues) do + nearestCount = nearestCount + 1 + end -- Bilinear should have more unique values (smoother gradient) - luaunit.assertTrue(bilinearCount >= nearestCount, - "Bilinear should produce smoother gradient with more unique values") + luaunit.assertTrue(bilinearCount >= nearestCount, "Bilinear should produce smoother gradient with more unique values") end luaunit.LuaUnit.run() diff --git a/testing/runAll.lua b/testing/runAll.lua index 397e465..ddf87d7 100644 --- a/testing/runAll.lua +++ b/testing/runAll.lua @@ -25,6 +25,7 @@ local testFiles = { "testing/__tests__/19_negative_margin_tests.lua", "testing/__tests__/20_padding_resize_tests.lua", "testing/__tests__/21_image_scaler_nearest_tests.lua", + "testing/__tests__/22_image_scaler_bilinear_tests.lua", } local success = true