some example
This commit is contained in:
212
examples/advanced_layout.lua
Normal file
212
examples/advanced_layout.lua
Normal 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
232
examples/input_handling.lua
Normal 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
|
||||||
98
examples/scrollable_content.lua
Normal file
98
examples/scrollable_content.lua
Normal 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
159
examples/slider_example.lua
Normal 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
247
examples/stateful_ui.lua
Normal 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
|
||||||
|
|
||||||
144
examples/theme_custom_components.lua
Normal file
144
examples/theme_custom_components.lua
Normal 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
|
||||||
|
|
||||||
Reference in New Issue
Block a user