some example

This commit is contained in:
Michael Freno
2025-11-14 17:16:09 -05:00
parent 36010381c2
commit 42ab82381d
6 changed files with 1092 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
--[[
Example: Advanced Layout with Flexbox and Grid
This example demonstrates advanced layout techniques using both flexbox and grid layouts
]]
local FlexLove = require("libs.FlexLove")
-- Create the main window
local window = FlexLove.new({
x = "10%",
y = "10%",
width = "80%",
height = "80%",
themeComponent = "framev3",
positioning = "flex",
flexDirection = "vertical",
gap = 20,
padding = { horizontal = 20, vertical = 20 },
})
-- Title
FlexLove.new({
parent = window,
text = "Advanced Layout Example",
textAlign = "center",
textSize = "3xl",
width = "100%",
})
-- Flex container with complex layout
local flexContainer = FlexLove.new({
parent = window,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "stretch",
gap = 15,
height = "70%",
})
-- Left panel - Grid layout
local leftPanel = FlexLove.new({
parent = flexContainer,
width = "40%",
positioning = "flex",
flexDirection = "vertical",
gap = 10,
padding = { horizontal = 10, vertical = 10 },
})
FlexLove.new({
parent = leftPanel,
text = "Grid Layout Example",
textAlign = "center",
textSize = "lg",
width = "100%",
})
-- Grid container
local gridContainer = FlexLove.new({
parent = leftPanel,
positioning = "flex",
flexDirection = "horizontal",
flexWrap = "wrap",
justifyContent = "space-between",
alignItems = "flex-start",
gap = 10,
height = "80%",
})
-- Grid items
for i = 1, 6 do
FlexLove.new({
parent = gridContainer,
width = "45%",
height = "40%",
themeComponent = "buttonv2",
text = "Item " .. i,
textAlign = "center",
textSize = "md",
onEvent = function(_, event)
if event.type == "release" then
print("Grid item " .. i .. " clicked")
end
end,
})
end
-- Right panel - Flex layout with nested flex containers
local rightPanel = FlexLove.new({
parent = flexContainer,
width = "55%",
positioning = "flex",
flexDirection = "vertical",
gap = 10,
})
FlexLove.new({
parent = rightPanel,
text = "Nested Flex Containers",
textAlign = "center",
textSize = "lg",
width = "100%",
})
-- First nested flex container
local nestedFlex1 = FlexLove.new({
parent = rightPanel,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-around",
alignItems = "center",
gap = 10,
height = "40%",
})
FlexLove.new({
parent = nestedFlex1,
text = "Button A",
themeComponent = "buttonv1",
width = "25%",
textAlign = "center",
onEvent = function(_, event)
if event.type == "release" then
print("Button A clicked")
end
end,
})
FlexLove.new({
parent = nestedFlex1,
text = "Button B",
themeComponent = "buttonv2",
width = "25%",
textAlign = "center",
onEvent = function(_, event)
if event.type == "release" then
print("Button B clicked")
end
end,
})
-- Second nested flex container
local nestedFlex2 = FlexLove.new({
parent = rightPanel,
positioning = "flex",
flexDirection = "vertical",
justifyContent = "space-around",
alignItems = "stretch",
gap = 10,
height = "50%",
})
FlexLove.new({
parent = nestedFlex2,
text = "Vertical Flex Item 1",
themeComponent = "framev3",
textAlign = "center",
padding = { vertical = 10 },
})
FlexLove.new({
parent = nestedFlex2,
text = "Vertical Flex Item 2",
themeComponent = "framev3",
textAlign = "center",
padding = { vertical = 10 },
})
-- Footer with progress bar
local footer = FlexLove.new({
parent = window,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
gap = 15,
height = "20%",
})
FlexLove.new({
parent = footer,
text = "Progress:",
textAlign = "start",
textSize = "md",
})
local progressContainer = FlexLove.new({
parent = footer,
width = "60%",
height = "30%",
themeComponent = "framev3",
positioning = "flex",
flexDirection = "horizontal",
alignItems = "center",
gap = 5,
})
-- Progress bar fill
local progressFill = FlexLove.new({
parent = progressContainer,
width = "70%",
height = "100%",
themeComponent = "buttonv1",
})
FlexLove.new({
parent = footer,
text = "70%",
textAlign = "end",
textSize = "md",
})

232
examples/input_handling.lua Normal file
View File

@@ -0,0 +1,232 @@
-- Example: Input Handling System
-- This demonstrates how to handle various input events in FlexLove
local FlexLove = require("libs.FlexLove")
local InputExample = {}
function InputExample:new()
local obj = {
-- State variables for input handling example
mousePosition = { x = 0, y = 0 },
keyPressed = "",
touchPosition = { x = 0, y = 0 },
isMouseOver = false,
hoverCount = 0
}
setmetatable(obj, {__index = self})
return obj
end
function InputExample:render()
local flex = FlexLove.new({
x = "10%",
y = "10%",
width = "80%",
height = "80%",
positioning = "flex",
flexDirection = "vertical",
gap = 10,
padding = { horizontal = 10, vertical = 10 },
})
-- Title
FlexLove.new({
parent = flex,
text = "Input Handling System Example",
textAlign = "center",
textSize = "2xl",
width = "100%",
height = "10%",
})
-- Mouse interaction section
local mouseSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = mouseSection,
text = "Mouse Position: (" .. self.mousePosition.x .. ", " .. self.mousePosition.y .. ")",
textAlign = "left",
textSize = "md",
width = "60%",
})
-- Hoverable area
local hoverArea = FlexLove.new({
parent = mouseSection,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
width = "30%",
height = "100%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 10 },
onEvent = function(_, event)
if event.type == "mousemoved" then
self.mousePosition.x = event.x
self.mousePosition.y = event.y
elseif event.type == "mouseenter" then
self.isMouseOver = true
self.hoverCount = self.hoverCount + 1
elseif event.type == "mouseleave" then
self.isMouseOver = false
end
end,
})
FlexLove.new({
parent = hoverArea,
text = "Hover over me!",
textAlign = "center",
textSize = "md",
width = "100%",
height = "100%",
color = self.isMouseOver and "#48bb78" or "#a0aec0", -- Green when hovered
})
-- Keyboard input section
local keyboardSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = keyboardSection,
text = "Last Key Pressed: " .. (self.keyPressed or "None"),
textAlign = "left",
textSize = "md",
width = "60%",
})
-- Input field for typing
local inputField = FlexLove.new({
parent = keyboardSection,
themeComponent = "inputv2",
text = "",
textAlign = "left",
textSize = "md",
width = "30%",
onEvent = function(_, event)
if event.type == "textinput" then
self.keyPressed = event.text
elseif event.type == "keypressed" then
self.keyPressed = event.key
end
end,
})
-- Touch input section
local touchSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = touchSection,
text = "Touch Position: (" .. self.touchPosition.x .. ", " .. self.touchPosition.y .. ")",
textAlign = "left",
textSize = "md",
width = "60%",
})
-- Touchable area
local touchArea = FlexLove.new({
parent = touchSection,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
width = "30%",
height = "100%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 10 },
onEvent = function(_, event)
if event.type == "touch" then
self.touchPosition.x = event.x
self.touchPosition.y = event.y
end
end,
})
FlexLove.new({
parent = touchArea,
text = "Touch me!",
textAlign = "center",
textSize = "md",
width = "100%",
height = "100%",
})
-- Status section showing interaction counts
local statusSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = statusSection,
text = "Hover Count: " .. self.hoverCount,
textAlign = "left",
textSize = "md",
width = "30%",
})
-- Reset button
FlexLove.new({
parent = statusSection,
themeComponent = "buttonv2",
text = "Reset All",
textAlign = "center",
width = "30%",
onEvent = function(_, event)
if event.type == "release" then
self.mousePosition = { x = 0, y = 0 }
self.keyPressed = ""
self.touchPosition = { x = 0, y = 0 }
self.hoverCount = 0
self.isMouseOver = false
print("All input states reset")
end
end,
})
return flex
end
return InputExample

View File

@@ -0,0 +1,98 @@
local FlexLove = require("libs.FlexLove")
local Color = FlexLove.Color
---@class ScrollableContentExample
---@field window Element
---@field container Element
---@field scrollContainer Element
local ScrollableContentExample = {}
ScrollableContentExample.__index = ScrollableContentExample
function ScrollableContentExample.new()
local self = setmetatable({}, ScrollableContentExample)
-- Create main window with backdrop blur
self.window = FlexLove.new({
x = "25%",
y = "10%",
z = 1000,
width = "50vw",
height = "80vh",
themeComponent = "framev3",
scaleCorners = 3,
positioning = "flex",
flexDirection = "vertical",
justifyContent = "center",
alignItems = "center",
gap = 10,
backdropBlur = { intensity = 50, quality = 10 },
backgroundColor = Color.new(0.1, 0.1, 0.1, 0.8),
})
-- Header
FlexLove.new({
parent = self.window,
text = "Scrollable Content Example",
textAlign = "center",
textSize = "2xl",
width = "100%",
textColor = Color.new(1, 1, 1, 1),
margin = { bottom = 10 },
})
-- Create scroll container with overflow handling
self.scrollContainer = FlexLove.new({
parent = self.window,
width = "90%",
height = "70%",
positioning = "flex",
flexDirection = "vertical",
overflowY = "scroll",
gap = 5,
padding = { horizontal = 10, vertical = 5 },
themeComponent = "framev3",
backgroundColor = Color.new(0.2, 0.2, 0.2, 0.5),
})
-- Add multiple scrollable elements to demonstrate scrolling
for i = 1, 30 do
local text = string.format(
"Item %d - This is a long line of content that should wrap and show how scrolling works in FlexLove when content exceeds the container bounds",
i
)
FlexLove.new({
parent = self.scrollContainer,
text = text,
textAlign = "start",
textSize = "md",
width = "100%",
textColor = Color.new(0.9, 0.9, 0.9, 1),
padding = { vertical = 5 },
themeComponent = i % 3 == 0 and "panel" or "cardv2",
backgroundColor = i % 3 == 0 and Color.new(0.3, 0.3, 0.3, 0.7) or Color.new(0.4, 0.4, 0.4, 0.5),
})
end
-- Footer with instructions
FlexLove.new({
parent = self.window,
text = "Scroll using the mouse wheel or drag the scrollbar",
textAlign = "center",
textSize = "sm",
width = "100%",
textColor = Color.new(0.7, 0.7, 0.7, 1),
margin = { top = 10 },
})
return self
end
function ScrollableContentExample:destroy()
if self.window then
self.window:destroy()
self.window = nil
end
end
return ScrollableContentExample

159
examples/slider_example.lua Normal file
View File

@@ -0,0 +1,159 @@
--- Example demonstrating how to create sliders using FlexLove
-- This example shows the implementation pattern used in SettingsMenu.lua
local FlexLove = require("libs.FlexLove")
local Theme = FlexLove.Theme
local Color = FlexLove.Color
local helpers = require("utils.helperFunctions")
local round = helpers.round
---@class SliderExample
local SliderExample = {}
SliderExample.__index = SliderExample
local instance
---@return SliderExample
function SliderExample.init()
if instance == nil then
local self = setmetatable({}, SliderExample)
instance = self
end
return instance
end
--- Create a slider control like in SettingsMenu
---@param parent Element The parent element
---@param label string The control label
---@param min number Minimum value
---@param max number Maximum value
---@param initial_value number? Initial value (defaults to min)
---@param display_multiplier number? Multiplier for display (e.g., 100 for percentage)
function SliderExample:create_slider(parent, label, min, max, initial_value, display_multiplier)
display_multiplier = display_multiplier or 1
initial_value = initial_value or min
local row = FlexLove.new({
parent = parent,
width = "100%",
height = "5vh",
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
gap = 10,
})
-- Label
FlexLove.new({
parent = row,
text = label,
textAlign = "start",
textSize = "md",
width = "30%",
})
local slider_container = FlexLove.new({
parent = row,
width = "50%",
height = "100%",
positioning = "flex",
flexDirection = "horizontal",
alignItems = "center",
gap = 5,
})
local value = initial_value
local normalized = (value - min) / (max - min)
local function convert_x_to_percentage(mx, parentX, parentWidth)
local val = (mx - parentX) / parentWidth
if val < 0.01 then
val = 0
elseif val > 0.99 then
val = 1
else
val = round(val, 2)
end
-- In a real app, you'd update the actual setting here
value = min + (val * (max - min))
-- Update the display value
value_display.text = string.format("%d", value * display_multiplier)
end
local slider_track = FlexLove.new({
parent = slider_container,
width = "80%",
height = "75%",
positioning = "flex",
flexDirection = "horizontal",
themeComponent = "framev3",
onEvent = function(elem, event)
convert_x_to_percentage(event.x, elem.x, elem.width)
end,
})
local fill_bar = FlexLove.new({
parent = slider_track,
width = (normalized * 100) .. "%",
height = "100%",
themeComponent = "buttonv1",
onEvent = function(_, event)
convert_x_to_percentage(event.x, slider_track.x, slider_track.width)
end,
})
local value_display = FlexLove.new({
parent = slider_container,
text = string.format("%d", value * display_multiplier),
textAlign = "center",
textSize = "md",
width = "15%",
})
end
--- Create an example UI with multiple sliders
function SliderExample:render_example()
-- Create a window for our example
local window = FlexLove.new({
x = "10%",
y = "10%",
width = "80%",
height = "80%",
themeComponent = "framev3",
positioning = "flex",
flexDirection = "vertical",
justifySelf = "center",
justifyContent = "flex-start",
alignItems = "center",
scaleCorners = 3,
padding = { horizontal = "5%", vertical = "3%" },
gap = 20,
})
FlexLove.new({
parent = window,
text = "Slider Example",
textAlign = "center",
textSize = "3xl",
width = "100%",
margin = { top = "-4%", bottom = "4%" },
})
-- Content container
local content = FlexLove.new({
parent = window,
width = "100%",
height = "100%",
positioning = "flex",
flexDirection = "vertical",
padding = { top = "4%" },
gap = 20,
})
-- Create a few example sliders
self:create_slider(content, "Volume", 0, 100, 75, 1)
self:create_slider(content, "Brightness", 0, 100, 50, 1)
self:create_slider(content, "Sensitivity", 0.1, 2.0, 1.0, 100)
end
return SliderExample.init()

247
examples/stateful_ui.lua Normal file
View File

@@ -0,0 +1,247 @@
-- Example: Stateful Interactive UI
-- This demonstrates how to create interactive UI elements with state management
local FlexLove = require("libs.FlexLove")
local StatefulUIExample = {}
function StatefulUIExample:new()
local obj = {
-- State variables for the example
counter = 0,
isToggled = false,
inputValue = "",
selectedOption = "option1",
}
setmetatable(obj, { __index = self })
return obj
end
function StatefulUIExample:render()
local flex = FlexLove.new({
x = "10%",
y = "10%",
width = "80%",
height = "80%",
positioning = "flex",
flexDirection = "vertical",
gap = 10,
padding = { horizontal = 10, vertical = 10 },
})
-- Title
FlexLove.new({
parent = flex,
text = "Stateful Interactive UI Example",
textAlign = "center",
textSize = "2xl",
width = "100%",
height = "10%",
})
-- Counter section
local counterSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = counterSection,
text = "Counter: " .. self.counter,
textAlign = "left",
textSize = "lg",
width = "40%",
})
-- Increment button
FlexLove.new({
parent = counterSection,
themeComponent = "buttonv2",
text = "Increment",
textAlign = "center",
width = "25%",
onEvent = function(_, event)
if event.type == "release" then
self.counter = self.counter + 1
print("Counter incremented to: " .. self.counter)
end
end,
})
-- Reset button
FlexLove.new({
parent = counterSection,
themeComponent = "buttonv2",
text = "Reset",
textAlign = "center",
width = "25%",
onEvent = function(_, event)
if event.type == "release" then
self.counter = 0
print("Counter reset to: " .. self.counter)
end
end,
})
-- Toggle switch section
local toggleSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = toggleSection,
text = "Toggle Switch: " .. tostring(self.isToggled),
textAlign = "left",
textSize = "lg",
width = "40%",
})
-- Toggle button
local toggleButton = FlexLove.new({
parent = toggleSection,
positioning = "flex",
width = 60,
height = 30,
backgroundColor = self.isToggled and "#48bb78" or "#a0aec0", -- Green when on, gray when off
borderRadius = 15,
padding = { horizontal = 5 },
})
FlexLove.new({
parent = toggleButton,
text = self.isToggled and "ON" or "OFF",
textAlign = "center",
textSize = "sm",
width = "100%",
height = "100%",
color = "#ffffff", -- White text
})
-- Toggle event handler
toggleButton.onEvent = function(_, event)
if event.type == "release" then
self.isToggled = not self.isToggled
print("Toggle switched to: " .. tostring(self.isToggled))
-- This would normally update the visual state, but we'll do it manually for this example
end
end
-- Input section
local inputSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = inputSection,
text = "Input Value:",
textAlign = "left",
textSize = "lg",
width = "30%",
})
FlexLove.new({
parent = inputSection,
themeComponent = "inputv2",
text = self.inputValue,
textAlign = "left",
textSize = "md",
width = "50%",
onEvent = function(_, event)
if event.type == "textinput" then
self.inputValue = event.text
print("Input value changed to: " .. self.inputValue)
end
end,
})
-- Dropdown section
local dropdownSection = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = dropdownSection,
text = "Selected Option:",
textAlign = "left",
textSize = "lg",
width = "30%",
})
FlexLove.new({
parent = dropdownSection,
themeComponent = "dropdownv2",
text = self.selectedOption,
textAlign = "left",
textSize = "md",
width = "50%",
options = { "option1", "option2", "option3" },
onEvent = function(_, event)
if event.type == "select" then
self.selectedOption = event.value
print("Selected option changed to: " .. self.selectedOption)
end
end,
})
-- Status indicator at the bottom
local statusIndicator = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "10%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = statusIndicator,
text = "Current State - Counter: " .. self.counter .. ", Toggle: " .. tostring(self.isToggled),
textAlign = "left",
textSize = "sm",
width = "70%",
})
return flex
end
return StatefulUIExample

View File

@@ -0,0 +1,144 @@
-- Example: Theming and Custom Components
-- This demonstrates how to use themes and create custom components
local FlexLove = require("libs.FlexLove")
local ThemeExample = {}
function ThemeExample:new()
local obj = {
themeIndex = 1,
themes = { "space", "metal" },
}
setmetatable(obj, { __index = self })
return obj
end
function ThemeExample:render()
local flex = FlexLove.new({
x = "10%",
y = "10%",
width = "80%",
height = "80%",
positioning = "flex",
flexDirection = "vertical",
gap = 10,
padding = { horizontal = 10, vertical = 10 },
})
-- Title
FlexLove.new({
parent = flex,
text = "Theming and Custom Components Example",
textAlign = "center",
textSize = "2xl",
width = "100%",
height = "10%",
})
-- Theme selector
local themeSelector = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "10%",
backgroundColor = "#2d3748",
borderRadius = 8,
padding = { horizontal = 10 },
})
FlexLove.new({
parent = themeSelector,
text = "Current Theme: " .. self.themes[self.themeIndex],
textAlign = "left",
textSize = "md",
width = "50%",
})
FlexLove.new({
parent = themeSelector,
themeComponent = "buttonv2",
text = "Switch Theme",
textAlign = "center",
width = "30%",
onEvent = function(_, event)
if event.type == "release" then
self.themeIndex = (self.themeIndex % #self.themes) + 1
-- In a real app, you'd update the theme here
print("Theme switched to: " .. self.themes[self.themeIndex])
end
end,
})
-- Custom component example - A styled card
local customCard = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "vertical",
justifyContent = "center",
alignItems = "center",
width = "100%",
height = "40%",
themeComponent = "cardv2", -- Uses theme styling
padding = { horizontal = 20, vertical = 20 },
margin = { top = 10 },
})
FlexLove.new({
parent = customCard,
text = "Custom Card Component",
textAlign = "center",
textSize = "lg",
width = "100%",
height = "30%",
})
FlexLove.new({
parent = customCard,
text = "This demonstrates how to create reusable components with theme support",
textAlign = "center",
textSize = "sm",
width = "100%",
height = "50%",
color = "#a0aec0", -- Light gray text
})
-- Another custom component - Status indicator
local statusIndicator = FlexLove.new({
parent = flex,
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
width = "100%",
height = "20%",
backgroundColor = "#4a5568",
borderRadius = 8,
padding = { horizontal = 15 },
})
FlexLove.new({
parent = statusIndicator,
text = "Status: Active",
textAlign = "left",
textSize = "md",
width = "50%",
})
local statusDot = FlexLove.new({
parent = statusIndicator,
positioning = "flex",
width = 20,
height = 20,
backgroundColor = "#48bb78", -- Green dot
borderRadius = 10, -- Circle
})
return flex
end
return ThemeExample