immediate mode scroll regression fixed
This commit is contained in:
75
FlexLove.lua
75
FlexLove.lua
@@ -9,6 +9,7 @@ local utils = req("utils")
|
|||||||
local Units = req("Units")
|
local Units = req("Units")
|
||||||
local Context = req("Context")
|
local Context = req("Context")
|
||||||
local StateManager = req("StateManager")
|
local StateManager = req("StateManager")
|
||||||
|
local ErrorHandler = req("ErrorHandler")
|
||||||
---@type Element
|
---@type Element
|
||||||
local Element = req("Element")
|
local Element = req("Element")
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ local flexlove = Context
|
|||||||
|
|
||||||
-- Initialize Units module with Context dependency
|
-- Initialize Units module with Context dependency
|
||||||
Units.initialize(Context)
|
Units.initialize(Context)
|
||||||
|
Units.initializeErrorHandler(ErrorHandler)
|
||||||
|
|
||||||
-- Add version and metadata
|
-- Add version and metadata
|
||||||
flexlove._VERSION = "0.1.0"
|
flexlove._VERSION = "0.1.0"
|
||||||
@@ -480,10 +482,10 @@ function flexlove.keypressed(key, scancode, isrepeat)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function flexlove.wheelmoved(x, y)
|
function flexlove.wheelmoved(dx, dy)
|
||||||
local mx, my = love.mouse.getPosition()
|
local mx, my = love.mouse.getPosition()
|
||||||
|
|
||||||
local function findScrollableAtPosition(elements, mx, my)
|
local function findScrollableAtPosition(elements, x, y)
|
||||||
for i = #elements, 1, -1 do
|
for i = #elements, 1, -1 do
|
||||||
local element = elements[i]
|
local element = elements[i]
|
||||||
|
|
||||||
@@ -492,9 +494,9 @@ function flexlove.wheelmoved(x, y)
|
|||||||
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
||||||
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
||||||
|
|
||||||
if mx >= bx and mx <= bx + bw and my >= by and my <= by + bh then
|
if x >= bx and x <= bx + bw and y >= by and y <= by + bh then
|
||||||
if #element.children > 0 then
|
if #element.children > 0 then
|
||||||
local childResult = findScrollableAtPosition(element.children, mx, my)
|
local childResult = findScrollableAtPosition(element.children, x, y)
|
||||||
if childResult then
|
if childResult then
|
||||||
return childResult
|
return childResult
|
||||||
end
|
end
|
||||||
@@ -521,20 +523,79 @@ function flexlove.wheelmoved(x, y)
|
|||||||
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
||||||
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
||||||
|
|
||||||
if mx >= bx and mx <= bx + bw and my >= by and my <= by + bh then
|
-- Calculate scroll offset from parent chain
|
||||||
|
local scrollOffsetX = 0
|
||||||
|
local scrollOffsetY = 0
|
||||||
|
local current = element.parent
|
||||||
|
while current do
|
||||||
|
local overflowX = current.overflowX or current.overflow
|
||||||
|
local overflowY = current.overflowY or current.overflow
|
||||||
|
local hasScrollableOverflow = (
|
||||||
|
overflowX == "scroll"
|
||||||
|
or overflowX == "auto"
|
||||||
|
or overflowY == "scroll"
|
||||||
|
or overflowY == "auto"
|
||||||
|
or overflowX == "hidden"
|
||||||
|
or overflowY == "hidden"
|
||||||
|
)
|
||||||
|
if hasScrollableOverflow then
|
||||||
|
scrollOffsetX = scrollOffsetX + (current._scrollX or 0)
|
||||||
|
scrollOffsetY = scrollOffsetY + (current._scrollY or 0)
|
||||||
|
end
|
||||||
|
current = current.parent
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Adjust mouse position by scroll offset
|
||||||
|
local adjustedMx = mx + scrollOffsetX
|
||||||
|
local adjustedMy = my + scrollOffsetY
|
||||||
|
|
||||||
|
-- Check if mouse is within element bounds
|
||||||
|
if adjustedMx >= bx and adjustedMx <= bx + bw and adjustedMy >= by and adjustedMy <= by + bh then
|
||||||
|
-- Check if mouse position is clipped by any parent
|
||||||
|
local isClipped = false
|
||||||
|
local parentCheck = element.parent
|
||||||
|
while parentCheck do
|
||||||
|
local parentOverflowX = parentCheck.overflowX or parentCheck.overflow
|
||||||
|
local parentOverflowY = parentCheck.overflowY or parentCheck.overflow
|
||||||
|
|
||||||
|
if parentOverflowX == "hidden" or parentOverflowX == "scroll" or parentOverflowX == "auto" or
|
||||||
|
parentOverflowY == "hidden" or parentOverflowY == "scroll" or parentOverflowY == "auto" then
|
||||||
|
local parentX = parentCheck.x + parentCheck.padding.left
|
||||||
|
local parentY = parentCheck.y + parentCheck.padding.top
|
||||||
|
local parentW = parentCheck.width
|
||||||
|
local parentH = parentCheck.height
|
||||||
|
|
||||||
|
if mx < parentX or mx > parentX + parentW or my < parentY or my > parentY + parentH then
|
||||||
|
isClipped = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
parentCheck = parentCheck.parent
|
||||||
|
end
|
||||||
|
|
||||||
|
if not isClipped then
|
||||||
local overflowX = element.overflowX or element.overflow
|
local overflowX = element.overflowX or element.overflow
|
||||||
local overflowY = element.overflowY or element.overflow
|
local overflowY = element.overflowY or element.overflow
|
||||||
if (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") and (element._overflowX or element._overflowY) then
|
if (overflowX == "scroll" or overflowX == "auto" or overflowY == "scroll" or overflowY == "auto") and (element._overflowX or element._overflowY) then
|
||||||
element:_handleWheelScroll(x, y)
|
element:_handleWheelScroll(dx, dy)
|
||||||
|
|
||||||
|
-- Save scroll position to StateManager immediately in immediate mode
|
||||||
|
if element._stateId then
|
||||||
|
StateManager.updateState(element._stateId, {
|
||||||
|
_scrollX = element._scrollX,
|
||||||
|
_scrollY = element._scrollY,
|
||||||
|
})
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- In retained mode, use the old tree traversal method
|
-- In retained mode, use the old tree traversal method
|
||||||
local scrollableElement = findScrollableAtPosition(flexlove.topElements, mx, my)
|
local scrollableElement = findScrollableAtPosition(flexlove.topElements, mx, my)
|
||||||
if scrollableElement then
|
if scrollableElement then
|
||||||
scrollableElement:_handleWheelScroll(x, y)
|
scrollableElement:_handleWheelScroll(dx, dy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,215 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 01: Flex Positioning
|
|
||||||
|
|
||||||
This example demonstrates flexbox layouts in FlexLove:
|
|
||||||
- Flex direction (horizontal/vertical)
|
|
||||||
- Justify content (main axis alignment)
|
|
||||||
- Align items (cross axis alignment)
|
|
||||||
- Flex wrap behavior
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/01_flex_positioning.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Map Love to Lv to avoid duplicate definitions
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
-- Load FlexLove from parent directory
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
-- Initialize FlexLove with base scaling
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 01: Flex Positioning",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Horizontal Flex with Different JustifyContent Values
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
local yOffset = 10
|
|
||||||
|
|
||||||
-- Label for justify-content section
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Horizontal Flex - JustifyContent Options",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
yOffset = yOffset + 4
|
|
||||||
|
|
||||||
-- Demonstrate each justify-content option
|
|
||||||
local justifyOptions = {
|
|
||||||
{ name = "flex-start", value = enums.JustifyContent.FLEX_START },
|
|
||||||
{ name = "center", value = enums.JustifyContent.CENTER },
|
|
||||||
{ name = "flex-end", value = enums.JustifyContent.FLEX_END },
|
|
||||||
{ name = "space-between", value = enums.JustifyContent.SPACE_BETWEEN },
|
|
||||||
{ name = "space-around", value = enums.JustifyContent.SPACE_AROUND },
|
|
||||||
{ name = "space-evenly", value = enums.JustifyContent.SPACE_EVENLY },
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option in ipairs(justifyOptions) do
|
|
||||||
-- Label for this justify option
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = "15vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = option.name,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(0.8, 0.8, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.START,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Container demonstrating this justify-content value
|
|
||||||
local container = FlexLove.new({
|
|
||||||
x = "18vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = "78vw",
|
|
||||||
height = "8vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = option.value,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add child elements
|
|
||||||
local colors = {
|
|
||||||
Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
Color.new(0.8, 0.8, 0.3, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for j = 1, 4 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = container,
|
|
||||||
width = "8vw",
|
|
||||||
height = "5vh",
|
|
||||||
backgroundColor = colors[j],
|
|
||||||
text = tostring(j),
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
yOffset = yOffset + 9
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Vertical Flex with Different AlignItems Values
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
yOffset = yOffset + 2
|
|
||||||
|
|
||||||
-- Label for align-items section
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Vertical Flex - AlignItems Options",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
yOffset = yOffset + 4
|
|
||||||
|
|
||||||
-- Note: Due to space constraints, we'll show a subset in a horizontal layout
|
|
||||||
local alignOptions = {
|
|
||||||
{ name = "stretch", value = enums.AlignItems.STRETCH },
|
|
||||||
{ name = "flex-start", value = enums.AlignItems.FLEX_START },
|
|
||||||
{ name = "center", value = enums.AlignItems.CENTER },
|
|
||||||
{ name = "flex-end", value = enums.AlignItems.FLEX_END },
|
|
||||||
}
|
|
||||||
|
|
||||||
local xOffset = 2
|
|
||||||
local containerWidth = 22
|
|
||||||
|
|
||||||
for _, option in ipairs(alignOptions) do
|
|
||||||
-- Label for this align option
|
|
||||||
FlexLove.new({
|
|
||||||
x = xOffset .. "vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = containerWidth .. "vw",
|
|
||||||
height = "2.5vh",
|
|
||||||
text = option.name,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(0.8, 1, 0.8, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Container demonstrating this align-items value
|
|
||||||
local container = FlexLove.new({
|
|
||||||
x = xOffset .. "vw",
|
|
||||||
y = (yOffset + 3) .. "vh",
|
|
||||||
width = containerWidth .. "vw",
|
|
||||||
height = "20vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.FLEX_START,
|
|
||||||
alignItems = option.value,
|
|
||||||
gap = 5,
|
|
||||||
backgroundColor = Color.new(0.15, 0.2, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.4, 0.3, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add child elements with varying widths
|
|
||||||
local widths = { "8vw", "12vw", "6vw" }
|
|
||||||
local colors = {
|
|
||||||
Color.new(0.9, 0.4, 0.4, 1),
|
|
||||||
Color.new(0.4, 0.9, 0.4, 1),
|
|
||||||
Color.new(0.4, 0.4, 0.9, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for j = 1, 3 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = container,
|
|
||||||
width = option.value == enums.AlignItems.STRETCH and "auto" or widths[j],
|
|
||||||
height = "4vh",
|
|
||||||
backgroundColor = colors[j],
|
|
||||||
text = tostring(j),
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
xOffset = xOffset + containerWidth + 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,228 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 02: Grid Layout
|
|
||||||
|
|
||||||
This example demonstrates grid layouts in FlexLove:
|
|
||||||
- Different grid configurations (2x2, 3x3, 4x2)
|
|
||||||
- Row and column gaps
|
|
||||||
- AlignItems behavior in grid cells
|
|
||||||
- Automatic grid cell positioning
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/02_grid_layout.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 02: Grid Layout",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: 2x2 Grid with Gaps
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "2x2 Grid (rowGap: 10px, columnGap: 10px)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local grid2x2 = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "30vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 2,
|
|
||||||
gridColumns = 2,
|
|
||||||
rowGap = 10,
|
|
||||||
columnGap = 10,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add 4 cells to 2x2 grid
|
|
||||||
local colors2x2 = {
|
|
||||||
Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
Color.new(0.8, 0.8, 0.3, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for j = 1, 4 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = grid2x2,
|
|
||||||
backgroundColor = colors2x2[j],
|
|
||||||
text = "Cell " .. j,
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: 3x3 Grid with Different Gap Sizes
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "34vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "3x3 Grid (rowGap: 5px, columnGap: 15px)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local grid3x3 = FlexLove.new({
|
|
||||||
x = "34vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "30vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 3,
|
|
||||||
gridColumns = 3,
|
|
||||||
rowGap = 5,
|
|
||||||
columnGap = 15,
|
|
||||||
backgroundColor = Color.new(0.1, 0.15, 0.1, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.4, 0.3, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add 9 cells to 3x3 grid
|
|
||||||
for j = 1, 9 do
|
|
||||||
local hue = (j - 1) / 9
|
|
||||||
FlexLove.new({
|
|
||||||
parent = grid3x3,
|
|
||||||
backgroundColor = Color.new(0.3 + hue * 0.5, 0.5, 0.7 - hue * 0.4, 1),
|
|
||||||
text = tostring(j),
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: 4x2 Grid with AlignItems
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "66vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "32vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "4x2 Grid (alignItems: center)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local grid4x2 = FlexLove.new({
|
|
||||||
x = "66vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "32vw",
|
|
||||||
height = "30vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 4,
|
|
||||||
gridColumns = 2,
|
|
||||||
rowGap = 8,
|
|
||||||
columnGap = 8,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.15, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.4, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add 8 cells with varying content
|
|
||||||
for j = 1, 8 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = grid4x2,
|
|
||||||
backgroundColor = Color.new(0.6, 0.4 + j * 0.05, 0.7 - j * 0.05, 1),
|
|
||||||
text = "Item " .. j,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 4: Grid with Responsive Units (vw/vh gaps)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "46vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Grid with Responsive Gaps (rowGap: 2vh, columnGap: 2vw)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local gridResponsive = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "50vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "45vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 2,
|
|
||||||
gridColumns = 5,
|
|
||||||
rowGap = "2vh",
|
|
||||||
columnGap = "2vw",
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.25, 0.25, 0.35, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add 10 cells with gradient colors
|
|
||||||
for j = 1, 10 do
|
|
||||||
local progress = (j - 1) / 9
|
|
||||||
FlexLove.new({
|
|
||||||
parent = gridResponsive,
|
|
||||||
backgroundColor = Color.new(
|
|
||||||
0.2 + progress * 0.6,
|
|
||||||
0.4 + math.sin(progress * 3.14) * 0.4,
|
|
||||||
0.8 - progress * 0.4,
|
|
||||||
1
|
|
||||||
),
|
|
||||||
text = "Cell " .. j,
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 03: Theming System
|
|
||||||
|
|
||||||
This example demonstrates the theming system in FlexLove:
|
|
||||||
- Loading and applying themes
|
|
||||||
- Theme components (button, panel, card)
|
|
||||||
- Theme states (normal, hover, pressed, disabled, active)
|
|
||||||
- Theme colors and fonts
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/03_theming_system.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Load the space theme
|
|
||||||
FlexLove.loadTheme("space", "../themes/space")
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 03: Theming System",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Theme Components
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Theme Components - Space Theme",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Card component
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "20vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "card",
|
|
||||||
text = "Card Component",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Panel component
|
|
||||||
FlexLove.new({
|
|
||||||
x = "34vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "20vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "panel",
|
|
||||||
text = "Panel Component",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Panel red component
|
|
||||||
FlexLove.new({
|
|
||||||
x = "66vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "32vw",
|
|
||||||
height = "20vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "panelred",
|
|
||||||
text = "Panel Red Component",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 0.8, 0.8, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Button States
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "36vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Button States - Hover and Click to See State Changes",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Normal button (hover to see hover state, click to see pressed state)
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "8vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "button",
|
|
||||||
text = "Normal Button",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
print("Normal button clicked!")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Active button (simulating active state)
|
|
||||||
local activeButton = FlexLove.new({
|
|
||||||
x = "26vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "8vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "button",
|
|
||||||
text = "Active Button",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.3, 1, 0.3, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
active = true,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
element.active = not element.active
|
|
||||||
print("Active button toggled:", element.active)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Disabled button
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "8vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "button",
|
|
||||||
text = "Disabled Button",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.5, 0.5, 0.5, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
disabled = true,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
-- This won't be called because button is disabled
|
|
||||||
print("This shouldn't print!")
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Button with callback feedback
|
|
||||||
local clickCount = 0
|
|
||||||
local counterButton = FlexLove.new({
|
|
||||||
x = "74vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "24vw",
|
|
||||||
height = "8vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "button",
|
|
||||||
text = "Click Me! (0)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
clickCount = clickCount + 1
|
|
||||||
element.text = "Click Me! (" .. clickCount .. ")"
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Theme Colors and Fonts
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "50vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Theme Colors and Fonts",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Container showing theme colors
|
|
||||||
local colorContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "54vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "20vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Primary color swatch
|
|
||||||
FlexLove.new({
|
|
||||||
parent = colorContainer,
|
|
||||||
width = "20vw",
|
|
||||||
height = "15vh",
|
|
||||||
backgroundColor = Color.new(0.08, 0.75, 0.95, 1), -- Theme primary color
|
|
||||||
text = "Primary Color",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Secondary color swatch
|
|
||||||
FlexLove.new({
|
|
||||||
parent = colorContainer,
|
|
||||||
width = "20vw",
|
|
||||||
height = "15vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.20, 0.25, 1), -- Theme secondary color
|
|
||||||
text = "Secondary Color",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Text color swatch
|
|
||||||
FlexLove.new({
|
|
||||||
parent = colorContainer,
|
|
||||||
width = "20vw",
|
|
||||||
height = "15vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.25, 1),
|
|
||||||
text = "Text Color",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.80, 0.90, 1.00, 1), -- Theme text color
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Text dark color swatch
|
|
||||||
FlexLove.new({
|
|
||||||
parent = colorContainer,
|
|
||||||
width = "20vw",
|
|
||||||
height = "15vh",
|
|
||||||
backgroundColor = Color.new(0.25, 0.25, 0.3, 1),
|
|
||||||
text = "Text Dark Color",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.35, 0.40, 0.45, 1), -- Theme textDark color
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 4: Font Family from Theme
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "76vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "18vh",
|
|
||||||
theme = "space",
|
|
||||||
themeComponent = "card",
|
|
||||||
text = "This text uses the theme's default font (VT323)",
|
|
||||||
textSize = "3vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
fontFamily = "default", -- References theme font
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 04: Responsive Units
|
|
||||||
|
|
||||||
This example demonstrates responsive unit systems in FlexLove:
|
|
||||||
- Viewport units (vw, vh)
|
|
||||||
- Percentage units (%)
|
|
||||||
- Pixel units (px)
|
|
||||||
- How elements resize with the window
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/04_responsive_units.lua
|
|
||||||
Try resizing the window to see responsive behavior!
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 04: Responsive Units - Try Resizing!",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Viewport Width Units (vw)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Viewport Width (vw) - Scales with window width",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local vwContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "12vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Elements with vw widths
|
|
||||||
local vwWidths = { "10vw", "15vw", "20vw", "25vw" }
|
|
||||||
local colors = {
|
|
||||||
Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
Color.new(0.8, 0.8, 0.3, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, width in ipairs(vwWidths) do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = vwContainer,
|
|
||||||
width = width,
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = colors[i],
|
|
||||||
text = width,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Viewport Height Units (vh)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "28vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Viewport Height (vh) - Scales with window height",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local vhContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "32vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "30vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.FLEX_END,
|
|
||||||
backgroundColor = Color.new(0.1, 0.15, 0.1, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.4, 0.3, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Elements with vh heights
|
|
||||||
local vhHeights = { "8vh", "12vh", "16vh", "20vh", "24vh" }
|
|
||||||
|
|
||||||
for i, height in ipairs(vhHeights) do
|
|
||||||
local hue = (i - 1) / 4
|
|
||||||
FlexLove.new({
|
|
||||||
parent = vhContainer,
|
|
||||||
width = "16vw",
|
|
||||||
height = height,
|
|
||||||
backgroundColor = Color.new(0.3 + hue * 0.5, 0.5, 0.7 - hue * 0.4, 1),
|
|
||||||
text = height,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Percentage Units (%)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "64vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Percentage (%) - Relative to parent",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local percentContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "68vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "28vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.STRETCH,
|
|
||||||
backgroundColor = Color.new(0.15, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.4, 0.3, 0.4, 1),
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Child elements with percentage widths
|
|
||||||
local percentWidths = { "25%", "50%", "75%", "100%" }
|
|
||||||
|
|
||||||
for i, width in ipairs(percentWidths) do
|
|
||||||
local progress = (i - 1) / 3
|
|
||||||
FlexLove.new({
|
|
||||||
parent = percentContainer,
|
|
||||||
width = width,
|
|
||||||
height = "5vh",
|
|
||||||
backgroundColor = Color.new(0.6, 0.4 + progress * 0.4, 0.7 - progress * 0.4, 1),
|
|
||||||
text = width .. " of parent",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 4: Pixel Units (px) - Fixed Size
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "64vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Pixels (px) - Fixed size (doesn't resize)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local pxContainer = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "68vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "28vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = enums.JustifyContent.CENTER,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
gap = 10,
|
|
||||||
backgroundColor = Color.new(0.1, 0.12, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.35, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Fixed pixel size elements
|
|
||||||
local pxSizes = {
|
|
||||||
{ w = 80, h = 80 },
|
|
||||||
{ w = 100, h = 100 },
|
|
||||||
{ w = 120, h = 120 },
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, size in ipairs(pxSizes) do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = pxContainer,
|
|
||||||
width = size.w,
|
|
||||||
height = size.h,
|
|
||||||
backgroundColor = Color.new(0.8 - i * 0.2, 0.3 + i * 0.2, 0.5, 1),
|
|
||||||
text = size.w .. "px",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 05: Animations
|
|
||||||
|
|
||||||
This example demonstrates animation system in FlexLove:
|
|
||||||
- Fade animations
|
|
||||||
- Scale animations
|
|
||||||
- Custom animations with different easing functions
|
|
||||||
- Animation timing and interpolation
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/05_animations.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local Animation = FlexLove.Animation
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
-- Animation control variables
|
|
||||||
local fadeBox, scaleBox, easingBoxes
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 05: Animations",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Fade Animation
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Fade Animation - Click to trigger",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
fadeBox = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.6, 0.9, 1),
|
|
||||||
text = "Click me to fade out and back in",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
-- Fade out then fade in
|
|
||||||
local fadeOut = Animation.fade(1.0, 1.0, 0.0)
|
|
||||||
fadeOut.easing = function(t) return t * t end -- easeInQuad
|
|
||||||
element.animation = fadeOut
|
|
||||||
|
|
||||||
-- Queue fade in after fade out completes
|
|
||||||
local startTime = Lv.timer.getTime()
|
|
||||||
element._fadeCallback = function(el, dt)
|
|
||||||
if Lv.timer.getTime() - startTime >= 1.0 then
|
|
||||||
local fadeIn = Animation.fade(1.0, 0.0, 1.0)
|
|
||||||
fadeIn.easing = function(t) return t * (2 - t) end -- easeOutQuad
|
|
||||||
el.animation = fadeIn
|
|
||||||
el._fadeCallback = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Scale Animation
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Scale Animation - Click to trigger",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
scaleBox = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = 400,
|
|
||||||
height = 200,
|
|
||||||
backgroundColor = Color.new(0.9, 0.4, 0.4, 1),
|
|
||||||
text = "Click me to scale up",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
-- Scale up
|
|
||||||
local scaleUp = Animation.scale(
|
|
||||||
0.5,
|
|
||||||
{ width = element.width, height = element.height },
|
|
||||||
{ width = element.width * 1.5, height = element.height * 1.5 }
|
|
||||||
)
|
|
||||||
scaleUp.easing = function(t) return t < 0.5 and 2 * t * t or -1 + (4 - 2 * t) * t end -- easeInOutQuad
|
|
||||||
element.animation = scaleUp
|
|
||||||
|
|
||||||
-- Queue scale down
|
|
||||||
local startTime = Lv.timer.getTime()
|
|
||||||
element._scaleCallback = function(el, dt)
|
|
||||||
if Lv.timer.getTime() - startTime >= 0.5 then
|
|
||||||
local scaleDown = Animation.scale(
|
|
||||||
0.5,
|
|
||||||
{ width = el.width, height = el.height },
|
|
||||||
{ width = 400, height = 200 }
|
|
||||||
)
|
|
||||||
scaleDown.easing = function(t) return t < 0.5 and 2 * t * t or -1 + (4 - 2 * t) * t end
|
|
||||||
el.animation = scaleDown
|
|
||||||
el._scaleCallback = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Easing Functions Comparison
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "36vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Easing Functions - Click any box to see different easing",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local easingContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "56vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 3,
|
|
||||||
gridColumns = 3,
|
|
||||||
rowGap = "2vh",
|
|
||||||
columnGap = "2vw",
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.25, 0.25, 0.35, 1),
|
|
||||||
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Different easing functions
|
|
||||||
local easings = {
|
|
||||||
{ name = "Linear", func = function(t) return t end },
|
|
||||||
{ name = "EaseInQuad", func = function(t) return t * t end },
|
|
||||||
{ name = "EaseOutQuad", func = function(t) return t * (2 - t) end },
|
|
||||||
{ name = "EaseInOutQuad", func = function(t) return t < 0.5 and 2 * t * t or -1 + (4 - 2 * t) * t end },
|
|
||||||
{ name = "EaseInCubic", func = function(t) return t * t * t end },
|
|
||||||
{ name = "EaseOutCubic", func = function(t) local t1 = t - 1; return t1 * t1 * t1 + 1 end },
|
|
||||||
{ name = "EaseInQuart", func = function(t) return t * t * t * t end },
|
|
||||||
{ name = "EaseOutQuart", func = function(t) local t1 = t - 1; return 1 - t1 * t1 * t1 * t1 end },
|
|
||||||
{ name = "EaseInExpo", func = function(t) return t == 0 and 0 or math.pow(2, 10 * (t - 1)) end },
|
|
||||||
}
|
|
||||||
|
|
||||||
easingBoxes = {}
|
|
||||||
|
|
||||||
for i, easing in ipairs(easings) do
|
|
||||||
local hue = (i - 1) / 8
|
|
||||||
local box = FlexLove.new({
|
|
||||||
parent = easingContainer,
|
|
||||||
backgroundColor = Color.new(0.2 + hue * 0.6, 0.4 + math.sin(hue * 3.14) * 0.4, 0.8 - hue * 0.4, 1),
|
|
||||||
text = easing.name,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
-- Fade out and in with this easing
|
|
||||||
local fadeOut = Animation.fade(0.8, 1.0, 0.2)
|
|
||||||
fadeOut.easing = easing.func
|
|
||||||
element.animation = fadeOut
|
|
||||||
|
|
||||||
local startTime = Lv.timer.getTime()
|
|
||||||
element._easingCallback = function(el, dt)
|
|
||||||
if Lv.timer.getTime() - startTime >= 0.8 then
|
|
||||||
local fadeIn = Animation.fade(0.8, 0.2, 1.0)
|
|
||||||
fadeIn.easing = easing.func
|
|
||||||
el.animation = fadeIn
|
|
||||||
el._easingCallback = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
table.insert(easingBoxes, box)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
-- Handle fade callback
|
|
||||||
if fadeBox and fadeBox._fadeCallback then
|
|
||||||
fadeBox._fadeCallback(fadeBox, dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Handle scale callback
|
|
||||||
if scaleBox and scaleBox._scaleCallback then
|
|
||||||
scaleBox._scaleCallback(scaleBox, dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Handle easing callbacks
|
|
||||||
for _, box in ipairs(easingBoxes) do
|
|
||||||
if box._easingCallback then
|
|
||||||
box._easingCallback(box, dt)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,318 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 06: Event System
|
|
||||||
|
|
||||||
This example demonstrates the event system in FlexLove:
|
|
||||||
- Click events (left, right, middle mouse buttons)
|
|
||||||
- Press and release events
|
|
||||||
- Event properties (position, modifiers, click count)
|
|
||||||
- Double-click detection
|
|
||||||
- Keyboard modifiers (Shift, Ctrl, Alt)
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/06_event_system.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
-- Event log
|
|
||||||
local eventLog = {}
|
|
||||||
local maxLogEntries = 15
|
|
||||||
|
|
||||||
local function addLogEntry(text)
|
|
||||||
table.insert(eventLog, 1, text)
|
|
||||||
if #eventLog > maxLogEntries then
|
|
||||||
table.remove(eventLog)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 06: Event System",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Click Events
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Click Events - Try left, right, middle mouse buttons",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local clickBox = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.5, 0.7, 1),
|
|
||||||
text = "Click me with different mouse buttons!",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
local buttonName = event.button == 1 and "Left" or (event.button == 2 and "Right" or "Middle")
|
|
||||||
local eventTypeName = event.type:sub(1,1):upper() .. event.type:sub(2)
|
|
||||||
|
|
||||||
if event.type == "click" or event.type == "rightclick" or event.type == "middleclick" then
|
|
||||||
addLogEntry(string.format("%s Click at (%.0f, %.0f) - Count: %d",
|
|
||||||
buttonName, event.x, event.y, event.clickCount))
|
|
||||||
elseif event.type == "press" then
|
|
||||||
addLogEntry(string.format("%s Button Pressed at (%.0f, %.0f)",
|
|
||||||
buttonName, event.x, event.y))
|
|
||||||
elseif event.type == "release" then
|
|
||||||
addLogEntry(string.format("%s Button Released at (%.0f, %.0f)",
|
|
||||||
buttonName, event.x, event.y))
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Keyboard Modifiers
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Keyboard Modifiers - Hold Shift/Ctrl/Alt while clicking",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local modifierBox = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.7, 0.4, 0.5, 1),
|
|
||||||
text = "Click with modifiers!",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
onEvent = 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.super then table.insert(mods, "Super") end
|
|
||||||
|
|
||||||
local modText = #mods > 0 and table.concat(mods, "+") or "None"
|
|
||||||
addLogEntry(string.format("Click with modifiers: %s", modText))
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Double-Click Detection
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "36vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Double-Click Detection",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local doubleClickBox = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "15vh",
|
|
||||||
backgroundColor = Color.new(0.5, 0.7, 0.4, 1),
|
|
||||||
text = "Double-click me!",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
if event.clickCount == 1 then
|
|
||||||
addLogEntry("Single click detected")
|
|
||||||
elseif event.clickCount == 2 then
|
|
||||||
addLogEntry("DOUBLE CLICK detected!")
|
|
||||||
-- Visual feedback for double-click
|
|
||||||
element.backgroundColor = Color.new(0.9, 0.9, 0.3, 1)
|
|
||||||
elseif event.clickCount >= 3 then
|
|
||||||
addLogEntry(string.format("TRIPLE+ CLICK detected! (count: %d)", event.clickCount))
|
|
||||||
element.backgroundColor = Color.new(0.9, 0.3, 0.9, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Reset color after a delay (simulated in update)
|
|
||||||
element._resetTime = Lv.timer.getTime() + 0.3
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 4: Event Log Display
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "36vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Event Log (most recent first)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Event log container
|
|
||||||
local logContainer = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "40vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "56vh",
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.25, 0.25, 0.35, 1),
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 5: Interactive Buttons
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "57vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Interactive Buttons",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local buttonContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "61vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "35vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.STRETCH,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
gap = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Button 1: Press/Release events
|
|
||||||
FlexLove.new({
|
|
||||||
parent = buttonContainer,
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.4, 0.5, 0.8, 1),
|
|
||||||
text = "Press and Release Events",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "press" then
|
|
||||||
addLogEntry("Button 1: PRESSED")
|
|
||||||
element.backgroundColor = Color.new(0.2, 0.3, 0.6, 1)
|
|
||||||
elseif event.type == "release" then
|
|
||||||
addLogEntry("Button 1: RELEASED")
|
|
||||||
element.backgroundColor = Color.new(0.4, 0.5, 0.8, 1)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Button 2: Click counter
|
|
||||||
local clickCounter = 0
|
|
||||||
FlexLove.new({
|
|
||||||
parent = buttonContainer,
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.8, 0.5, 0.4, 1),
|
|
||||||
text = "Click Counter: 0",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
clickCounter = clickCounter + 1
|
|
||||||
element.text = "Click Counter: " .. clickCounter
|
|
||||||
addLogEntry("Button 2: Click #" .. clickCounter)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Button 3: Clear log
|
|
||||||
FlexLove.new({
|
|
||||||
parent = buttonContainer,
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.6, 0.4, 0.6, 1),
|
|
||||||
text = "Clear Event Log",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
onEvent = function(element, event)
|
|
||||||
if event.type == "click" then
|
|
||||||
eventLog = {}
|
|
||||||
addLogEntry("Log cleared!")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
-- Reset double-click box color
|
|
||||||
if doubleClickBox and doubleClickBox._resetTime and Lv.timer.getTime() >= doubleClickBox._resetTime then
|
|
||||||
doubleClickBox.backgroundColor = Color.new(0.5, 0.7, 0.4, 1)
|
|
||||||
doubleClickBox._resetTime = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
|
|
||||||
-- Draw event log
|
|
||||||
Lv.graphics.setColor(0.8, 0.9, 1, 1)
|
|
||||||
local logX = Lv.graphics.getWidth() * 0.50 + 10
|
|
||||||
local logY = Lv.graphics.getHeight() * 0.40 + 10
|
|
||||||
local lineHeight = 20
|
|
||||||
|
|
||||||
for i, entry in ipairs(eventLog) do
|
|
||||||
local alpha = 1.0 - (i - 1) / maxLogEntries * 0.5
|
|
||||||
Lv.graphics.setColor(0.8, 0.9, 1, alpha)
|
|
||||||
Lv.graphics.print(entry, logX, logY + (i - 1) * lineHeight)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 07: Text Rendering
|
|
||||||
|
|
||||||
This example demonstrates text rendering features in FlexLove:
|
|
||||||
- Text alignment (start, center, end, justify)
|
|
||||||
- Text size presets (xxs, xs, sm, md, lg, xl, xxl, 3xl, 4xl)
|
|
||||||
- Font rendering with custom fonts
|
|
||||||
- Text wrapping and positioning
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/07_text_rendering.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 07: Text Rendering",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Text Alignment
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Text Alignment Options",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local alignments = {
|
|
||||||
{ name = "START", value = enums.TextAlign.START },
|
|
||||||
{ name = "CENTER", value = enums.TextAlign.CENTER },
|
|
||||||
{ name = "END", value = enums.TextAlign.END },
|
|
||||||
}
|
|
||||||
|
|
||||||
local yOffset = 14
|
|
||||||
|
|
||||||
for _, align in ipairs(alignments) do
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = yOffset .. "vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
text = "Align: " .. align.name,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
textAlign = align.value,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
yOffset = yOffset + 9
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Text Size Presets
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "34vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "64vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Text Size Presets",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local textSizes = {
|
|
||||||
{ name = "XXS", value = "xxs" },
|
|
||||||
{ name = "XS", value = "xs" },
|
|
||||||
{ name = "SM", value = "sm" },
|
|
||||||
{ name = "MD", value = "md" },
|
|
||||||
{ name = "LG", value = "lg" },
|
|
||||||
{ name = "XL", value = "xl" },
|
|
||||||
{ name = "XXL", value = "xxl" },
|
|
||||||
{ name = "3XL", value = "3xl" },
|
|
||||||
{ name = "4XL", value = "4xl" },
|
|
||||||
}
|
|
||||||
|
|
||||||
local sizeContainer = FlexLove.new({
|
|
||||||
x = "34vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "64vw",
|
|
||||||
height = "76vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.FLEX_START,
|
|
||||||
alignItems = enums.AlignItems.STRETCH,
|
|
||||||
gap = 5,
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.25, 0.25, 0.35, 1),
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
for i, size in ipairs(textSizes) do
|
|
||||||
local hue = (i - 1) / 8
|
|
||||||
FlexLove.new({
|
|
||||||
parent = sizeContainer,
|
|
||||||
height = "7vh",
|
|
||||||
backgroundColor = Color.new(0.2 + hue * 0.3, 0.3 + hue * 0.2, 0.5 - hue * 0.2, 1),
|
|
||||||
text = size.name .. " - The quick brown fox jumps over the lazy dog",
|
|
||||||
textSize = size.value,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.START,
|
|
||||||
cornerRadius = 3,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Custom Font Sizes (vh units)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "41vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Custom Text Sizes (vh units)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local customSizes = { "1vh", "2vh", "3vh", "4vh", "5vh" }
|
|
||||||
|
|
||||||
local customContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "45vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "45vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_EVENLY,
|
|
||||||
alignItems = enums.AlignItems.STRETCH,
|
|
||||||
backgroundColor = Color.new(0.1, 0.12, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.35, 0.4, 1),
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
for i, size in ipairs(customSizes) do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = customContainer,
|
|
||||||
backgroundColor = Color.new(0.3, 0.4 + i * 0.08, 0.6 - i * 0.08, 1),
|
|
||||||
text = size .. " text",
|
|
||||||
textSize = size,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 3,
|
|
||||||
padding = { top = 5, right = 10, bottom = 5, left = 10 },
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,235 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 08: Absolute vs Relative Positioning
|
|
||||||
|
|
||||||
This example demonstrates positioning modes in FlexLove:
|
|
||||||
- Absolute positioning (fixed coordinates)
|
|
||||||
- Relative positioning (relative to siblings)
|
|
||||||
- Comparison between the two modes
|
|
||||||
- Practical use cases
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/08_absolute_relative_positioning.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 08: Absolute vs Relative Positioning",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Absolute Positioning
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Absolute Positioning - Fixed coordinates",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local absoluteContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "40vh",
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Absolute positioned children
|
|
||||||
FlexLove.new({
|
|
||||||
parent = absoluteContainer,
|
|
||||||
x = 20,
|
|
||||||
y = 20,
|
|
||||||
width = 150,
|
|
||||||
height = 80,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
text = "x:20, y:20",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = absoluteContainer,
|
|
||||||
x = 200,
|
|
||||||
y = 50,
|
|
||||||
width = 150,
|
|
||||||
height = 80,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
text = "x:200, y:50",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = absoluteContainer,
|
|
||||||
x = 100,
|
|
||||||
y = 150,
|
|
||||||
width = 150,
|
|
||||||
height = 80,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
text = "x:100, y:150",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = absoluteContainer,
|
|
||||||
x = 280,
|
|
||||||
y = 180,
|
|
||||||
width = 150,
|
|
||||||
height = 80,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.8, 0.8, 0.3, 1),
|
|
||||||
text = "x:280, y:180",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Relative Positioning
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Relative Positioning - Flows with siblings",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local relativeContainer = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "14vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "40vh",
|
|
||||||
positioning = enums.Positioning.RELATIVE,
|
|
||||||
backgroundColor = Color.new(0.1, 0.15, 0.1, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.4, 0.3, 1),
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Relative positioned children (flow naturally)
|
|
||||||
local relativeColors = {
|
|
||||||
Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
Color.new(0.8, 0.8, 0.3, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i = 1, 4 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = relativeContainer,
|
|
||||||
width = "45%",
|
|
||||||
height = "8vh",
|
|
||||||
positioning = enums.Positioning.RELATIVE,
|
|
||||||
backgroundColor = relativeColors[i],
|
|
||||||
text = "Element " .. i .. " (relative)",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
margin = { top = 5, right = 5, bottom = 5, left = 5 },
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Comparison with Overlapping
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "56vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Absolute Positioning Allows Overlapping",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local overlapContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "60vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "36vh",
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.25, 0.25, 0.35, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Create overlapping elements
|
|
||||||
local overlapColors = {
|
|
||||||
Color.new(0.9, 0.3, 0.3, 0.7),
|
|
||||||
Color.new(0.3, 0.9, 0.3, 0.7),
|
|
||||||
Color.new(0.3, 0.3, 0.9, 0.7),
|
|
||||||
Color.new(0.9, 0.9, 0.3, 0.7),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i = 1, 4 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = overlapContainer,
|
|
||||||
x = 50 + (i - 1) * 60,
|
|
||||||
y = 30 + (i - 1) * 40,
|
|
||||||
width = 300,
|
|
||||||
height = 150,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
backgroundColor = overlapColors[i],
|
|
||||||
text = "Layer " .. i,
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
z = i, -- Z-index for layering
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 09: Styling and Visual Effects
|
|
||||||
|
|
||||||
This example demonstrates styling and visual effects:
|
|
||||||
- Corner radius (uniform and individual corners)
|
|
||||||
- Borders (different sides)
|
|
||||||
- Opacity levels
|
|
||||||
- Background colors
|
|
||||||
- Blur effects (contentBlur and backdropBlur)
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/09_styling_visual_effects.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "5vh",
|
|
||||||
text = "FlexLove Example 09: Styling and Visual Effects",
|
|
||||||
textSize = "3.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 1: Corner Radius
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "9vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Corner Radius",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Uniform corner radius
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "14vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.6, 0.3, 0.7, 1),
|
|
||||||
cornerRadius = 5,
|
|
||||||
text = "radius: 5",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "17vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "14vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.6, 0.7, 1),
|
|
||||||
cornerRadius = 15,
|
|
||||||
text = "radius: 15",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Individual corner radius
|
|
||||||
FlexLove.new({
|
|
||||||
x = "32vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "16vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.7, 0.6, 0.3, 1),
|
|
||||||
cornerRadius = {
|
|
||||||
topLeft = 0,
|
|
||||||
topRight = 20,
|
|
||||||
bottomLeft = 20,
|
|
||||||
bottomRight = 0,
|
|
||||||
},
|
|
||||||
text = "Individual\ncorners",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 2: Borders
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "9vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Borders",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- All borders
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "14vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.8, 0.4, 0.4, 1),
|
|
||||||
text = "All sides",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Top and bottom borders
|
|
||||||
FlexLove.new({
|
|
||||||
x = "65vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "14vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.3, 0.2, 1),
|
|
||||||
border = { top = true, bottom = true },
|
|
||||||
borderColor = Color.new(0.4, 0.8, 0.4, 1),
|
|
||||||
text = "Top & Bottom",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Left border only
|
|
||||||
FlexLove.new({
|
|
||||||
x = "80vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "16vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
|
||||||
border = { left = true },
|
|
||||||
borderColor = Color.new(0.4, 0.4, 0.8, 1),
|
|
||||||
text = "Left only",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 3: Opacity
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "27vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Opacity Levels",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local opacityLevels = { 1.0, 0.75, 0.5, 0.25 }
|
|
||||||
|
|
||||||
for i, opacity in ipairs(opacityLevels) do
|
|
||||||
FlexLove.new({
|
|
||||||
x = (2 + (i - 1) * 24) .. "vw",
|
|
||||||
y = "31vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "12vh",
|
|
||||||
backgroundColor = Color.new(0.8, 0.3, 0.5, 1),
|
|
||||||
opacity = opacity,
|
|
||||||
text = "Opacity: " .. opacity,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 4: Background Colors
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "45vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Background Colors",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Gradient-like colors
|
|
||||||
for i = 1, 8 do
|
|
||||||
local hue = (i - 1) / 7
|
|
||||||
FlexLove.new({
|
|
||||||
x = (2 + (i - 1) * 12) .. "vw",
|
|
||||||
y = "49vh",
|
|
||||||
width = "11vw",
|
|
||||||
height = "18vh",
|
|
||||||
backgroundColor = Color.new(
|
|
||||||
0.3 + hue * 0.5,
|
|
||||||
0.5 + math.sin(hue * 3.14) * 0.3,
|
|
||||||
0.8 - hue * 0.5,
|
|
||||||
1
|
|
||||||
),
|
|
||||||
text = tostring(i),
|
|
||||||
textSize = "3vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ========================================
|
|
||||||
-- Section 5: Blur Effects (if supported)
|
|
||||||
-- ========================================
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "69vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Blur Effects (contentBlur & backdropBlur)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Content blur example
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "73vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "22vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.4, 0.6, 0.8),
|
|
||||||
contentBlur = { intensity = 5, quality = 3 },
|
|
||||||
text = "Content Blur\n(blurs this element)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Backdrop blur example
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "73vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "22vh",
|
|
||||||
backgroundColor = Color.new(0.6, 0.4, 0.3, 0.6),
|
|
||||||
backdropBlur = { intensity = 10, quality = 5 },
|
|
||||||
text = "Backdrop Blur\n(blurs background)",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 10: Padding and Margins
|
|
||||||
|
|
||||||
This example demonstrates padding and margin spacing:
|
|
||||||
- Uniform padding
|
|
||||||
- Individual padding sides
|
|
||||||
- Uniform margins
|
|
||||||
- Individual margin sides
|
|
||||||
- Visual indicators for spacing
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/10_padding_margins.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "5vh",
|
|
||||||
text = "FlexLove Example 10: Padding and Margins",
|
|
||||||
textSize = "3.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Section 1: Padding Examples
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "9vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Padding (internal spacing)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Uniform padding
|
|
||||||
local container1 = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "18vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.4, 0.6, 1),
|
|
||||||
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = container1,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
backgroundColor = Color.new(0.8, 0.6, 0.3, 1),
|
|
||||||
text = "Uniform\npadding: 20px",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Individual padding sides
|
|
||||||
local container2 = FlexLove.new({
|
|
||||||
x = "26vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "18vh",
|
|
||||||
backgroundColor = Color.new(0.4, 0.6, 0.3, 1),
|
|
||||||
padding = { top = 30, right = 10, bottom = 30, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = container2,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
backgroundColor = Color.new(0.8, 0.3, 0.6, 1),
|
|
||||||
text = "Individual\ntop/bottom: 30px\nleft/right: 10px",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Section 2: Margin Examples
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "9vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Margins (external spacing)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Container to show margins
|
|
||||||
local marginContainer = FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "13vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "38vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Elements with different margins
|
|
||||||
FlexLove.new({
|
|
||||||
parent = marginContainer,
|
|
||||||
width = "40vw",
|
|
||||||
height = "6vh",
|
|
||||||
backgroundColor = Color.new(0.7, 0.3, 0.3, 1),
|
|
||||||
margin = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
text = "Uniform margin: 10px",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = marginContainer,
|
|
||||||
width = "40vw",
|
|
||||||
height = "6vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.7, 0.3, 1),
|
|
||||||
margin = { top = 5, right = 30, bottom = 5, left = 30 },
|
|
||||||
text = "Horizontal margin: 30px",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = marginContainer,
|
|
||||||
width = "40vw",
|
|
||||||
height = "6vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.3, 0.7, 1),
|
|
||||||
margin = { top = 20, right = 10, bottom = 20, left = 10 },
|
|
||||||
text = "Vertical margin: 20px",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Section 3: Combined Padding and Margins
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "33vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Combined Padding & Margins",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local combinedContainer = FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "37vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "58vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
|
||||||
})
|
|
||||||
|
|
||||||
for i = 1, 3 do
|
|
||||||
local box = FlexLove.new({
|
|
||||||
parent = combinedContainer,
|
|
||||||
width = "auto",
|
|
||||||
height = "14vh",
|
|
||||||
backgroundColor = Color.new(0.5 + i * 0.1, 0.4, 0.6 - i * 0.1, 1),
|
|
||||||
margin = { top = 10, right = 0, bottom = 10, left = 0 },
|
|
||||||
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = box,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
|
||||||
text = "Box " .. i .. "\nPadding: 15px\nMargin: 10px",
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 11: Input Controls
|
|
||||||
|
|
||||||
This example demonstrates input controls (if available):
|
|
||||||
- Text input fields
|
|
||||||
- Keyboard input handling
|
|
||||||
- Focus management
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/11_input_controls.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 11: Input Controls",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Note: Input controls may require additional setup in FlexLove
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "4vh",
|
|
||||||
text = "Note: This example demonstrates basic input handling patterns",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.8, 0.8, 0.8, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Interactive buttons
|
|
||||||
local counter = 0
|
|
||||||
local counterDisplay = FlexLove.new({
|
|
||||||
x = "35vw",
|
|
||||||
y = "20vh",
|
|
||||||
width = "30vw",
|
|
||||||
height = "10vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
|
|
||||||
text = "Counter: 0",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Increment button
|
|
||||||
FlexLove.new({
|
|
||||||
x = "20vw",
|
|
||||||
y = "35vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.6, 0.3, 1),
|
|
||||||
text = "Increment (+)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
onEvent = function()
|
|
||||||
counter = counter + 1
|
|
||||||
counterDisplay.text = "Counter: " .. counter
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Decrement button
|
|
||||||
FlexLove.new({
|
|
||||||
x = "60vw",
|
|
||||||
y = "35vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.6, 0.3, 0.3, 1),
|
|
||||||
text = "Decrement (-)",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
onEvent = function()
|
|
||||||
counter = counter - 1
|
|
||||||
counterDisplay.text = "Counter: " .. counter
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Reset button
|
|
||||||
FlexLove.new({
|
|
||||||
x = "40vw",
|
|
||||||
y = "46vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "8vh",
|
|
||||||
backgroundColor = Color.new(0.4, 0.4, 0.6, 1),
|
|
||||||
text = "Reset",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
onEvent = function()
|
|
||||||
counter = 0
|
|
||||||
counterDisplay.text = "Counter: " .. counter
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Keyboard input info
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "60vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "30vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
text = "Keyboard Input:\n\nFlexLove supports keyboard input through Element properties:\n\n" ..
|
|
||||||
"- Use 'inputType' property for text input fields\n" ..
|
|
||||||
"- Handle onTextInput, onTextChange, onEnter callbacks\n" ..
|
|
||||||
"- Manage focus with onFocus and onBlur events\n\n" ..
|
|
||||||
"See FlexLove documentation for full input API",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.4, 0.4, 0.5, 1),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 12: Z-Index Layering
|
|
||||||
|
|
||||||
This example demonstrates z-index for element layering:
|
|
||||||
- Different z-index values
|
|
||||||
- Overlapping elements
|
|
||||||
- Layer ordering
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/12_z_index_layering.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 }
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 12: Z-Index Layering",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Description
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "10vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Elements with higher z-index values appear on top",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.8, 0.8, 0.8, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Section 1: Overlapping boxes with different z-index
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "15vh",
|
|
||||||
width = "46vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Overlapping Elements",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Box 1 (z-index: 1)
|
|
||||||
FlexLove.new({
|
|
||||||
x = "5vw",
|
|
||||||
y = "20vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "20vh",
|
|
||||||
z = 1,
|
|
||||||
backgroundColor = Color.new(0.8, 0.3, 0.3, 1),
|
|
||||||
text = "Z-Index: 1",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Box 2 (z-index: 2) - overlaps Box 1
|
|
||||||
FlexLove.new({
|
|
||||||
x = "12vw",
|
|
||||||
y = "25vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "20vh",
|
|
||||||
z = 2,
|
|
||||||
backgroundColor = Color.new(0.3, 0.8, 0.3, 1),
|
|
||||||
text = "Z-Index: 2",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Box 3 (z-index: 3) - overlaps Box 1 and 2
|
|
||||||
FlexLove.new({
|
|
||||||
x = "19vw",
|
|
||||||
y = "30vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "20vh",
|
|
||||||
z = 3,
|
|
||||||
backgroundColor = Color.new(0.3, 0.3, 0.8, 1),
|
|
||||||
text = "Z-Index: 3",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Section 2: Cards with different layers
|
|
||||||
FlexLove.new({
|
|
||||||
x = "50vw",
|
|
||||||
y = "15vh",
|
|
||||||
width = "48vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Layered Cards",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Create a stack of cards
|
|
||||||
for i = 1, 5 do
|
|
||||||
FlexLove.new({
|
|
||||||
x = (52 + i * 2) .. "vw",
|
|
||||||
y = (18 + i * 3) .. "vh",
|
|
||||||
width = "22vw",
|
|
||||||
height = "15vh",
|
|
||||||
z = i,
|
|
||||||
backgroundColor = Color.new(0.3 + i * 0.1, 0.4, 0.7 - i * 0.1, 1),
|
|
||||||
text = "Card " .. i .. "\nZ-Index: " .. i,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(1, 1, 1, 0.3),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Section 3: Interactive z-index demo
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "53vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Click to Bring to Front",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
local maxZ = 10
|
|
||||||
|
|
||||||
-- Create interactive boxes
|
|
||||||
for i = 1, 4 do
|
|
||||||
local box = FlexLove.new({
|
|
||||||
x = (5 + (i - 1) * 22) .. "vw",
|
|
||||||
y = "58vh",
|
|
||||||
width = "20vw",
|
|
||||||
height = "20vh",
|
|
||||||
z = i,
|
|
||||||
backgroundColor = Color.new(
|
|
||||||
0.4 + i * 0.1,
|
|
||||||
0.5 + math.sin(i) * 0.2,
|
|
||||||
0.7 - i * 0.1,
|
|
||||||
1
|
|
||||||
),
|
|
||||||
text = "Box " .. i .. "\nClick me!",
|
|
||||||
textSize = "2.2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add click handler to bring to front
|
|
||||||
box.onEvent = function(element)
|
|
||||||
maxZ = maxZ + 1
|
|
||||||
element.z = maxZ
|
|
||||||
element.text = "Box " .. i .. "\nZ: " .. element.z
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Info text
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "82vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "14vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
text = "Z-Index determines the stacking order of elements.\n" ..
|
|
||||||
"Higher values appear on top of lower values.\n" ..
|
|
||||||
"Click the boxes above to bring them to the front!",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 8,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 13: Comprehensive Demo
|
|
||||||
|
|
||||||
This example combines multiple FlexLove features into a polished demo:
|
|
||||||
- Flex and grid layouts
|
|
||||||
- Themed components
|
|
||||||
- Animations
|
|
||||||
- Event handling
|
|
||||||
- Responsive design
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/13_comprehensive_demo.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local Animation = FlexLove.Animation
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 },
|
|
||||||
theme = "space"
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Header
|
|
||||||
local header = FlexLove.new({
|
|
||||||
x = 0,
|
|
||||||
y = 0,
|
|
||||||
width = "100vw",
|
|
||||||
height = "12vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = enums.JustifyContent.SPACE_BETWEEN,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
padding = { top = 10, right = 20, bottom = 10, left = 20 },
|
|
||||||
border = { bottom = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Logo/Title
|
|
||||||
FlexLove.new({
|
|
||||||
parent = header,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = "FlexLove Demo",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(0.8, 0.9, 1, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Header buttons
|
|
||||||
local headerButtons = FlexLove.new({
|
|
||||||
parent = header,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
gap = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
local buttonNames = { "Home", "Features", "About" }
|
|
||||||
for _, name in ipairs(buttonNames) do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = headerButtons,
|
|
||||||
width = "8vw",
|
|
||||||
height = "6vh",
|
|
||||||
backgroundColor = Color.new(0.3, 0.4, 0.6, 1),
|
|
||||||
text = name,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
cornerRadius = 5,
|
|
||||||
themeComponent = "button",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Main content area
|
|
||||||
local mainContent = FlexLove.new({
|
|
||||||
x = 0,
|
|
||||||
y = "12vh",
|
|
||||||
width = "100vw",
|
|
||||||
height = "88vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
backgroundColor = Color.new(0.05, 0.05, 0.08, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Sidebar
|
|
||||||
local sidebar = FlexLove.new({
|
|
||||||
parent = mainContent,
|
|
||||||
width = "20vw",
|
|
||||||
height = "88vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
backgroundColor = Color.new(0.08, 0.08, 0.12, 1),
|
|
||||||
padding = { top = 20, right = 10, bottom = 20, left = 10 },
|
|
||||||
gap = 10,
|
|
||||||
border = { right = true },
|
|
||||||
borderColor = Color.new(0.2, 0.2, 0.3, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Sidebar menu items
|
|
||||||
local menuItems = {
|
|
||||||
{ icon = "◆", label = "Dashboard" },
|
|
||||||
{ icon = "◇", label = "Analytics" },
|
|
||||||
{ icon = "○", label = "Settings" },
|
|
||||||
{ icon = "□", label = "Profile" },
|
|
||||||
{ icon = "△", label = "Help" },
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item in ipairs(menuItems) do
|
|
||||||
local menuButton = FlexLove.new({
|
|
||||||
parent = sidebar,
|
|
||||||
width = "auto",
|
|
||||||
height = "7vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.HORIZONTAL,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
padding = { top = 10, right = 15, bottom = 10, left = 15 },
|
|
||||||
cornerRadius = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = menuButton,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = item.icon .. " " .. item.label,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Content panel
|
|
||||||
local contentPanel = FlexLove.new({
|
|
||||||
parent = mainContent,
|
|
||||||
width = "80vw",
|
|
||||||
height = "88vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
|
||||||
gap = 15,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Welcome section
|
|
||||||
FlexLove.new({
|
|
||||||
parent = contentPanel,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = "Welcome to FlexLove!",
|
|
||||||
textSize = "3.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Stats grid
|
|
||||||
local statsGrid = FlexLove.new({
|
|
||||||
parent = contentPanel,
|
|
||||||
width = "auto",
|
|
||||||
height = "20vh",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 1,
|
|
||||||
gridColumns = 4,
|
|
||||||
columnGap = 15,
|
|
||||||
})
|
|
||||||
|
|
||||||
local stats = {
|
|
||||||
{ label = "Projects", value = "24", color = Color.new(0.3, 0.6, 0.8, 1) },
|
|
||||||
{ label = "Users", value = "1.2K", color = Color.new(0.6, 0.3, 0.8, 1) },
|
|
||||||
{ label = "Revenue", value = "$45K", color = Color.new(0.8, 0.6, 0.3, 1) },
|
|
||||||
{ label = "Growth", value = "+12%", color = Color.new(0.3, 0.8, 0.6, 1) },
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, stat in ipairs(stats) do
|
|
||||||
local statCard = FlexLove.new({
|
|
||||||
parent = statsGrid,
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = enums.JustifyContent.CENTER,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = stat.color,
|
|
||||||
cornerRadius = 8,
|
|
||||||
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = statCard,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = stat.value,
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = statCard,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = stat.label,
|
|
||||||
textSize = "1.8vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Feature cards
|
|
||||||
local cardsContainer = FlexLove.new({
|
|
||||||
parent = contentPanel,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
positioning = enums.Positioning.GRID,
|
|
||||||
gridRows = 2,
|
|
||||||
gridColumns = 3,
|
|
||||||
rowGap = 15,
|
|
||||||
columnGap = 15,
|
|
||||||
})
|
|
||||||
|
|
||||||
local features = {
|
|
||||||
"Flexbox Layout",
|
|
||||||
"Grid System",
|
|
||||||
"Theming",
|
|
||||||
"Animations",
|
|
||||||
"Events",
|
|
||||||
"Responsive"
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, feature in ipairs(features) do
|
|
||||||
local card = FlexLove.new({
|
|
||||||
parent = cardsContainer,
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
justifyContent = enums.JustifyContent.CENTER,
|
|
||||||
alignItems = enums.AlignItems.CENTER,
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
cornerRadius = 10,
|
|
||||||
padding = { top = 20, right = 20, bottom = 20, left = 20 },
|
|
||||||
})
|
|
||||||
|
|
||||||
FlexLove.new({
|
|
||||||
parent = card,
|
|
||||||
width = "auto",
|
|
||||||
height = "auto",
|
|
||||||
text = feature,
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add hover animation
|
|
||||||
card.onEvent = function(element)
|
|
||||||
local anim = Animation.new({
|
|
||||||
duration = 0.2,
|
|
||||||
start = { opacity = 1 },
|
|
||||||
final = { opacity = 0.8 },
|
|
||||||
})
|
|
||||||
anim:apply(element)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
--[[
|
|
||||||
FlexLove Example 14: Drag Event - Slider Implementation
|
|
||||||
|
|
||||||
This example demonstrates how to use the new drag event to create
|
|
||||||
interactive sliders without any first-party slider component.
|
|
||||||
|
|
||||||
Features demonstrated:
|
|
||||||
- Using drag events for continuous mouse tracking
|
|
||||||
- Converting mouse coordinates to element-relative positions
|
|
||||||
- Updating UI elements based on drag position
|
|
||||||
- Creating reusable slider components
|
|
||||||
|
|
||||||
Run with: love /path/to/libs/examples/14_drag_slider.lua
|
|
||||||
]]
|
|
||||||
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
|
|
||||||
-- Slider state
|
|
||||||
local volume = 0.5 -- 0.0 to 1.0
|
|
||||||
local brightness = 0.75 -- 0.0 to 1.0
|
|
||||||
local temperature = 20 -- 0 to 40 (degrees)
|
|
||||||
|
|
||||||
-- UI elements
|
|
||||||
local volumeValueText
|
|
||||||
local brightnessValueText
|
|
||||||
local temperatureValueText
|
|
||||||
local volumeHandle
|
|
||||||
local brightnessHandle
|
|
||||||
local temperatureHandle
|
|
||||||
|
|
||||||
--- Helper function to create a slider
|
|
||||||
---@param x string|number
|
|
||||||
---@param y string|number
|
|
||||||
---@param width string|number
|
|
||||||
---@param label string
|
|
||||||
---@param min number
|
|
||||||
---@param max number
|
|
||||||
---@param initialValue number
|
|
||||||
---@param onValueChange function
|
|
||||||
---@return table -- Returns { bg, handle, valueText }
|
|
||||||
local function createSlider(x, y, width, label, min, max, initialValue, onValueChange)
|
|
||||||
-- Container for the slider
|
|
||||||
local container = FlexLove.new({
|
|
||||||
x = x,
|
|
||||||
y = y,
|
|
||||||
width = width,
|
|
||||||
height = "12vh",
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
gap = 5,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Label
|
|
||||||
FlexLove.new({
|
|
||||||
parent = container,
|
|
||||||
height = "3vh",
|
|
||||||
text = label,
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.9, 0.9, 0.9, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Slider track background
|
|
||||||
local sliderBg = FlexLove.new({
|
|
||||||
parent = container,
|
|
||||||
height = "4vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.25, 1),
|
|
||||||
cornerRadius = 5,
|
|
||||||
positioning = enums.Positioning.RELATIVE,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Slider handle
|
|
||||||
local normalized = (initialValue - min) / (max - min)
|
|
||||||
local handle = FlexLove.new({
|
|
||||||
parent = sliderBg,
|
|
||||||
x = (normalized * 95) .. "%",
|
|
||||||
y = "50%",
|
|
||||||
width = "5%",
|
|
||||||
height = "80%",
|
|
||||||
backgroundColor = Color.new(0.4, 0.6, 0.9, 1),
|
|
||||||
cornerRadius = 3,
|
|
||||||
positioning = enums.Positioning.ABSOLUTE,
|
|
||||||
-- Center the handle vertically
|
|
||||||
top = "10%",
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Value display
|
|
||||||
local valueText = FlexLove.new({
|
|
||||||
parent = container,
|
|
||||||
height = "3vh",
|
|
||||||
text = string.format("%.2f", initialValue),
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.7, 0.8, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Make the background track interactive
|
|
||||||
sliderBg.onEvent = function(element, event)
|
|
||||||
if event.type == "press" or event.type == "drag" then
|
|
||||||
-- Get element bounds
|
|
||||||
local bg_x = element.x
|
|
||||||
local bg_width = element.width
|
|
||||||
|
|
||||||
-- Calculate relative position (0 to 1)
|
|
||||||
local mouse_x = event.x
|
|
||||||
local relative_x = mouse_x - bg_x
|
|
||||||
local new_normalized = math.max(0, math.min(1, relative_x / bg_width))
|
|
||||||
|
|
||||||
-- Calculate actual value
|
|
||||||
local new_value = min + (new_normalized * (max - min))
|
|
||||||
|
|
||||||
-- Update handle position (use percentage for responsiveness)
|
|
||||||
handle.x = (new_normalized * 95) .. "%"
|
|
||||||
|
|
||||||
-- Update value text
|
|
||||||
if max - min > 10 then
|
|
||||||
-- For larger ranges (like temperature), show integers
|
|
||||||
valueText.text = string.format("%d", new_value)
|
|
||||||
else
|
|
||||||
-- For smaller ranges (like 0-1), show decimals
|
|
||||||
valueText.text = string.format("%.2f", new_value)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Call the value change callback
|
|
||||||
if onValueChange then
|
|
||||||
onValueChange(new_value)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Re-layout to apply position changes
|
|
||||||
element:recalculateUnits(Lv.graphics.getWidth(), Lv.graphics.getHeight())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
container = container,
|
|
||||||
bg = sliderBg,
|
|
||||||
handle = handle,
|
|
||||||
valueText = valueText,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 14: Drag Event - Slider Implementation",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Subtitle
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "9vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Drag the sliders to change values - built using only the drag event primitive!",
|
|
||||||
textSize = "2vh",
|
|
||||||
textColor = Color.new(0.7, 0.7, 0.7, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Volume Slider (0.0 - 1.0)
|
|
||||||
local volumeSlider = createSlider("10vw", "18vh", "80vw", "Volume (0.0 - 1.0)", 0.0, 1.0, volume, function(value)
|
|
||||||
volume = value
|
|
||||||
end)
|
|
||||||
volumeValueText = volumeSlider.valueText
|
|
||||||
volumeHandle = volumeSlider.handle
|
|
||||||
|
|
||||||
-- Brightness Slider (0.0 - 1.0)
|
|
||||||
local brightnessSlider = createSlider("10vw", "35vh", "80vw", "Brightness (0.0 - 1.0)", 0.0, 1.0, brightness, function(value)
|
|
||||||
brightness = value
|
|
||||||
end)
|
|
||||||
brightnessValueText = brightnessSlider.valueText
|
|
||||||
brightnessHandle = brightnessSlider.handle
|
|
||||||
|
|
||||||
-- Temperature Slider (0 - 40°C)
|
|
||||||
local temperatureSlider = createSlider("10vw", "52vh", "80vw", "Temperature (0 - 40°C)", 0, 40, temperature, function(value)
|
|
||||||
temperature = value
|
|
||||||
end)
|
|
||||||
temperatureValueText = temperatureSlider.valueText
|
|
||||||
temperatureHandle = temperatureSlider.handle
|
|
||||||
|
|
||||||
-- Visual feedback section
|
|
||||||
FlexLove.new({
|
|
||||||
x = "10vw",
|
|
||||||
y = "70vh",
|
|
||||||
width = "80vw",
|
|
||||||
height = "3vh",
|
|
||||||
text = "Visual Feedback:",
|
|
||||||
textSize = "2.5vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Volume visualization
|
|
||||||
FlexLove.new({
|
|
||||||
x = "10vw",
|
|
||||||
y = "75vh",
|
|
||||||
width = "25vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
cornerRadius = 10,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Brightness visualization
|
|
||||||
FlexLove.new({
|
|
||||||
x = "37.5vw",
|
|
||||||
y = "75vh",
|
|
||||||
width = "25vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
cornerRadius = 10,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Temperature visualization
|
|
||||||
FlexLove.new({
|
|
||||||
x = "65vw",
|
|
||||||
y = "75vh",
|
|
||||||
width = "25vw",
|
|
||||||
height = "20vh",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
cornerRadius = 10,
|
|
||||||
border = { top = true, right = true, bottom = true, left = true },
|
|
||||||
borderColor = Color.new(0.3, 0.3, 0.4, 1),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
Lv.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
|
|
||||||
-- Draw volume visualization (speaker icon with bars)
|
|
||||||
local volumeX = Lv.graphics.getWidth() * 0.10 + 20
|
|
||||||
local volumeY = Lv.graphics.getHeight() * 0.75 + 30
|
|
||||||
Lv.graphics.setColor(0.4, 0.6, 0.9, 1)
|
|
||||||
Lv.graphics.print("Volume:", volumeX, volumeY, 0, 2, 2)
|
|
||||||
|
|
||||||
-- Volume bars
|
|
||||||
local barCount = 10
|
|
||||||
for i = 1, barCount do
|
|
||||||
if i / barCount <= volume then
|
|
||||||
Lv.graphics.setColor(0.4, 0.8, 0.4, 1)
|
|
||||||
else
|
|
||||||
Lv.graphics.setColor(0.2, 0.2, 0.25, 1)
|
|
||||||
end
|
|
||||||
local barX = volumeX + 20 + (i - 1) * 30
|
|
||||||
local barHeight = 20 + i * 5
|
|
||||||
Lv.graphics.rectangle("fill", barX, volumeY + 60 - barHeight, 20, barHeight, 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Draw brightness visualization (sun icon)
|
|
||||||
local brightnessX = Lv.graphics.getWidth() * 0.375 + 20
|
|
||||||
local brightnessY = Lv.graphics.getHeight() * 0.75 + 30
|
|
||||||
Lv.graphics.setColor(0.4, 0.6, 0.9, 1)
|
|
||||||
Lv.graphics.print("Brightness:", brightnessX, brightnessY, 0, 2, 2)
|
|
||||||
|
|
||||||
-- Sun circle
|
|
||||||
Lv.graphics.setColor(1, 0.9, 0.3, brightness)
|
|
||||||
Lv.graphics.circle("fill", brightnessX + 150, brightnessY + 80, 30 * brightness + 10)
|
|
||||||
|
|
||||||
-- Draw temperature visualization (thermometer)
|
|
||||||
local tempX = Lv.graphics.getWidth() * 0.65 + 20
|
|
||||||
local tempY = Lv.graphics.getHeight() * 0.75 + 30
|
|
||||||
Lv.graphics.setColor(0.4, 0.6, 0.9, 1)
|
|
||||||
Lv.graphics.print("Temperature:", tempX, tempY, 0, 2, 2)
|
|
||||||
|
|
||||||
-- Thermometer
|
|
||||||
local tempNormalized = temperature / 40
|
|
||||||
local tempColor = {
|
|
||||||
1 - tempNormalized * 0.5, -- Red increases with temp
|
|
||||||
0.3,
|
|
||||||
1 - tempNormalized, -- Blue decreases with temp
|
|
||||||
}
|
|
||||||
Lv.graphics.setColor(tempColor[1], tempColor[2], tempColor[3], 1)
|
|
||||||
Lv.graphics.rectangle("fill", tempX + 100, tempY + 50, 40, 100 * tempNormalized, 5)
|
|
||||||
Lv.graphics.setColor(0.3, 0.3, 0.4, 1)
|
|
||||||
Lv.graphics.rectangle("line", tempX + 100, tempY + 50, 40, 100, 5)
|
|
||||||
|
|
||||||
-- Temperature text
|
|
||||||
Lv.graphics.setColor(1, 1, 1, 1)
|
|
||||||
Lv.graphics.print(string.format("%.0f°C", temperature), tempX + 160, tempY + 90, 0, 2, 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
-- Example 15: Scrollable Elements
|
|
||||||
-- Demonstrates scrollable containers with overflow detection and visual scrollbars
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
local enums = FlexLove.enums
|
|
||||||
local Lv = love
|
|
||||||
|
|
||||||
function Lv.load()
|
|
||||||
FlexLove.init({
|
|
||||||
baseScale = { width = 1920, height = 1080 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
FlexLove.new({
|
|
||||||
x = "2vw",
|
|
||||||
y = "2vh",
|
|
||||||
width = "96vw",
|
|
||||||
height = "6vh",
|
|
||||||
text = "FlexLove Example 15: Scrollable Elements",
|
|
||||||
textSize = "4vh",
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Example 1: Vertical scroll with auto scrollbars
|
|
||||||
local verticalScroll = FlexLove.new({
|
|
||||||
x = "5vw",
|
|
||||||
y = "12vh",
|
|
||||||
width = "25vw",
|
|
||||||
height = "35vh",
|
|
||||||
overflow = "auto",
|
|
||||||
backgroundColor = Color.new(0.15, 0.15, 0.2, 1),
|
|
||||||
cornerRadius = 8,
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
gap = 5,
|
|
||||||
padding = { top = 10, right = 10, bottom = 10, left = 10 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add many items to create overflow
|
|
||||||
for i = 1, 20 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = verticalScroll,
|
|
||||||
height = "5vh",
|
|
||||||
backgroundColor = Color.new(0.3 + (i % 3) * 0.1, 0.4, 0.6, 1),
|
|
||||||
cornerRadius = 4,
|
|
||||||
text = "Item " .. i,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
textAlign = enums.TextAlign.CENTER,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Example 2: Custom styled scrollbar
|
|
||||||
local customScroll = FlexLove.new({
|
|
||||||
x = "35vw",
|
|
||||||
y = "12vh",
|
|
||||||
width = "60vw",
|
|
||||||
height = "35vh",
|
|
||||||
overflow = "auto",
|
|
||||||
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
|
|
||||||
cornerRadius = 8,
|
|
||||||
scrollbarWidth = 16,
|
|
||||||
scrollbarColor = Color.new(0.3, 0.6, 0.9, 1),
|
|
||||||
scrollbarTrackColor = Color.new(0.15, 0.15, 0.2, 0.8),
|
|
||||||
scrollbarRadius = 8,
|
|
||||||
positioning = enums.Positioning.FLEX,
|
|
||||||
flexDirection = enums.FlexDirection.VERTICAL,
|
|
||||||
gap = 10,
|
|
||||||
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Add content
|
|
||||||
for i = 1, 25 do
|
|
||||||
FlexLove.new({
|
|
||||||
parent = customScroll,
|
|
||||||
height = "6vh",
|
|
||||||
backgroundColor = Color.new(0.2, 0.25, 0.3, 1),
|
|
||||||
cornerRadius = 6,
|
|
||||||
text = "Custom Scrollbar Item " .. i,
|
|
||||||
textColor = Color.new(0.9, 0.9, 1, 1),
|
|
||||||
textSize = "2vh",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Instructions
|
|
||||||
FlexLove.new({
|
|
||||||
x = "5vw",
|
|
||||||
y = "52vh",
|
|
||||||
width = "90vw",
|
|
||||||
height = "40vh",
|
|
||||||
backgroundColor = Color.new(0.1, 0.15, 0.2, 0.9),
|
|
||||||
cornerRadius = 8,
|
|
||||||
padding = { top = 15, right = 15, bottom = 15, left = 15 },
|
|
||||||
text = [[Instructions:
|
|
||||||
• Use mouse wheel to scroll elements under cursor
|
|
||||||
• Click and drag scrollbar thumb to scroll
|
|
||||||
• Click on scrollbar track to jump to position
|
|
||||||
• Scrollbars automatically appear when content overflows
|
|
||||||
• overflow="auto" shows scrollbars only when needed
|
|
||||||
• overflow="scroll" always shows scrollbars
|
|
||||||
• overflow="hidden" clips without scrollbars
|
|
||||||
• overflow="visible" shows all content (default)
|
|
||||||
|
|
||||||
Scrollbar colors change on hover and when dragging!]],
|
|
||||||
textColor = Color.new(0.9, 0.9, 1, 1),
|
|
||||||
textSize = "2vh",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.update(dt)
|
|
||||||
FlexLove.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.draw()
|
|
||||||
love.graphics.clear(0.05, 0.05, 0.08, 1)
|
|
||||||
FlexLove.draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.resize(w, h)
|
|
||||||
FlexLove.resize(w, h)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Lv.wheelmoved(x, y)
|
|
||||||
FlexLove.wheelmoved(x, y)
|
|
||||||
end
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
--[[
|
|
||||||
InputFieldsDemo.lua
|
|
||||||
Simple input field demo - multiple fields to test all features
|
|
||||||
Uses retained mode - elements are created once and reused
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local FlexLove = require("../FlexLove")
|
|
||||||
local Element = FlexLove.Element
|
|
||||||
local Color = FlexLove.Color
|
|
||||||
|
|
||||||
local InputFieldsDemo = {}
|
|
||||||
|
|
||||||
-- Elements (created once)
|
|
||||||
local elements = {}
|
|
||||||
local initialized = false
|
|
||||||
|
|
||||||
-- Initialize elements once
|
|
||||||
local function initialize()
|
|
||||||
if initialized then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
initialized = true
|
|
||||||
elements.container = Element.new({
|
|
||||||
x = 0,
|
|
||||||
y = 0,
|
|
||||||
padding = { horizontal = "5%", vertical = "5%" },
|
|
||||||
width = love.graphics.getWidth(),
|
|
||||||
height = love.graphics.getHeight(),
|
|
||||||
flexDirection = "vertical",
|
|
||||||
positioning = "flex",
|
|
||||||
gap = 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Title
|
|
||||||
elements.title = Element.new({
|
|
||||||
parent = elements.container,
|
|
||||||
width = 700,
|
|
||||||
height = 40,
|
|
||||||
text = "FlexLove Input Field Demo",
|
|
||||||
textSize = 28,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
z = 1000,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Input field 1 - Empty with placeholder
|
|
||||||
elements.inputField1 = Element.new({
|
|
||||||
parent = elements.container,
|
|
||||||
width = 600,
|
|
||||||
height = 50,
|
|
||||||
editable = true,
|
|
||||||
text = "",
|
|
||||||
textSize = 18,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
backgroundColor = Color.new(0.2, 0.2, 0.3, 0.9),
|
|
||||||
cornerRadius = 8,
|
|
||||||
padding = { horizontal = 15, vertical = 12 },
|
|
||||||
placeholder = "Type here... (empty field with placeholder)",
|
|
||||||
selectOnFocus = false,
|
|
||||||
multiline = true,
|
|
||||||
autoGrow = true,
|
|
||||||
z = 1000,
|
|
||||||
onTextChange = function(element, newText)
|
|
||||||
print("Field 1 changed:", newText)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Input field 2 - Pre-filled with selectOnFocus
|
|
||||||
elements.inputField2 = Element.new({
|
|
||||||
parent = elements.container,
|
|
||||||
width = 600,
|
|
||||||
height = 50,
|
|
||||||
editable = true,
|
|
||||||
text = "Pre-filled text",
|
|
||||||
textSize = 18,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
backgroundColor = Color.new(0.2, 0.3, 0.2, 0.9),
|
|
||||||
cornerRadius = 8,
|
|
||||||
padding = { horizontal = 15, vertical = 12 },
|
|
||||||
placeholder = "This shouldn't show",
|
|
||||||
selectOnFocus = true,
|
|
||||||
z = 1000,
|
|
||||||
onTextChange = function(_, newText)
|
|
||||||
print("Field 2 changed:", newText)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
elements.inputField3 = Element.new({
|
|
||||||
parent = elements.container,
|
|
||||||
width = 600,
|
|
||||||
height = 50,
|
|
||||||
editable = true,
|
|
||||||
text = "",
|
|
||||||
textSize = 18,
|
|
||||||
textColor = Color.new(1, 1, 1, 1),
|
|
||||||
backgroundColor = Color.new(0.3, 0.2, 0.2, 0.9),
|
|
||||||
cornerRadius = 8,
|
|
||||||
padding = { horizontal = 15, vertical = 12 },
|
|
||||||
placeholder = "Max 20 characters",
|
|
||||||
maxLength = 20,
|
|
||||||
selectOnFocus = false,
|
|
||||||
z = 1000,
|
|
||||||
onTextChange = function(element, newText)
|
|
||||||
print("Field 3 changed:", newText)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
elements.instructions = Element.new({
|
|
||||||
parent = elements.container,
|
|
||||||
width = 700,
|
|
||||||
height = 200,
|
|
||||||
text = "Instructions:\n• Click on a field to focus it\n• Type to enter text\n• Field 1: Empty with placeholder\n• Field 2: Pre-filled, selects all on focus\n• Field 3: Max 20 characters\n• Press ESC to unfocus\n• Use arrow keys to move cursor",
|
|
||||||
textSize = 14,
|
|
||||||
textColor = Color.new(0.8, 0.8, 0.8, 1),
|
|
||||||
z = 1000,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Render function (just initializes if needed)
|
|
||||||
function InputFieldsDemo.render()
|
|
||||||
initialize()
|
|
||||||
end
|
|
||||||
|
|
||||||
return InputFieldsDemo
|
|
||||||
@@ -85,7 +85,11 @@ local function isPointInElement(element, x, y)
|
|||||||
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
local bw = element._borderBoxWidth or (element.width + element.padding.left + element.padding.right)
|
||||||
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
local bh = element._borderBoxHeight or (element.height + element.padding.top + element.padding.bottom)
|
||||||
|
|
||||||
-- Walk up parent chain to check clipping and apply scroll offsets
|
-- Calculate scroll offset from parent chain
|
||||||
|
local scrollOffsetX = 0
|
||||||
|
local scrollOffsetY = 0
|
||||||
|
|
||||||
|
-- Walk up parent chain to check clipping and accumulate scroll offsets
|
||||||
local current = element.parent
|
local current = element.parent
|
||||||
while current do
|
while current do
|
||||||
local overflowX = current.overflowX or current.overflow
|
local overflowX = current.overflowX or current.overflow
|
||||||
@@ -101,12 +105,20 @@ local function isPointInElement(element, x, y)
|
|||||||
if x < parentX or x > parentX + parentW or y < parentY or y > parentY + parentH then
|
if x < parentX or x > parentX + parentW or y < parentY or y > parentY + parentH then
|
||||||
return false -- Point is clipped by parent
|
return false -- Point is clipped by parent
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Accumulate scroll offset
|
||||||
|
scrollOffsetX = scrollOffsetX + (current._scrollX or 0)
|
||||||
|
scrollOffsetY = scrollOffsetY + (current._scrollY or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
current = current.parent
|
current = current.parent
|
||||||
end
|
end
|
||||||
|
|
||||||
return x >= bx and x <= bx + bw and y >= by and y <= by + bh
|
-- Adjust mouse position by scroll offset for hit testing
|
||||||
|
local adjustedX = x + scrollOffsetX
|
||||||
|
local adjustedY = y + scrollOffsetY
|
||||||
|
|
||||||
|
return adjustedX >= bx and adjustedX <= bx + bw and adjustedY >= by and adjustedY <= by + bh
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the topmost element at a screen position
|
--- Get the topmost element at a screen position
|
||||||
|
|||||||
@@ -540,6 +540,7 @@ function Element.new(props)
|
|||||||
Grid = Grid,
|
Grid = Grid,
|
||||||
Units = Units,
|
Units = Units,
|
||||||
Context = Context,
|
Context = Context,
|
||||||
|
ErrorHandler = ErrorHandler,
|
||||||
})
|
})
|
||||||
self._layoutEngine:initialize(self)
|
self._layoutEngine:initialize(self)
|
||||||
|
|
||||||
@@ -633,7 +634,10 @@ function Element.new(props)
|
|||||||
-- Pixel units
|
-- Pixel units
|
||||||
self.textSize = value
|
self.textSize = value
|
||||||
else
|
else
|
||||||
ErrorHandler.error("Element", "Unknown textSize unit: " .. unit)
|
ErrorHandler.error(
|
||||||
|
"Element",
|
||||||
|
string.format("Unknown textSize unit '%s'. Valid units: px, %%, vw, vh, ew, eh. Or use presets: xs, sm, md, lg, xl, xxl, 2xl, 3xl, 4xl", unit)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Validate pixel textSize value
|
-- Validate pixel textSize value
|
||||||
@@ -835,6 +839,10 @@ function Element.new(props)
|
|||||||
|
|
||||||
-- Re-resolve ew/eh textSize units now that width/height are set
|
-- Re-resolve ew/eh textSize units now that width/height are set
|
||||||
if props.textSize and type(props.textSize) == "string" then
|
if props.textSize and type(props.textSize) == "string" then
|
||||||
|
-- Check if it's a preset first (presets don't need re-resolution)
|
||||||
|
local presetValue, presetUnit = resolveTextSizePreset(props.textSize)
|
||||||
|
if not presetValue then
|
||||||
|
-- Not a preset, parse and check for ew/eh units
|
||||||
local value, unit = Units.parse(props.textSize)
|
local value, unit = Units.parse(props.textSize)
|
||||||
if unit == "ew" then
|
if unit == "ew" then
|
||||||
-- Element width relative (now that width is set)
|
-- Element width relative (now that width is set)
|
||||||
@@ -844,6 +852,7 @@ function Element.new(props)
|
|||||||
self.textSize = (value / 100) * self.height
|
self.textSize = (value / 100) * self.height
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Apply min/max constraints (also scaled)
|
-- Apply min/max constraints (also scaled)
|
||||||
local minSize = self.minTextSize and (Context.baseScale and (self.minTextSize * scaleY) or self.minTextSize)
|
local minSize = self.minTextSize and (Context.baseScale and (self.minTextSize * scaleY) or self.minTextSize)
|
||||||
@@ -1253,16 +1262,36 @@ function Element.new(props)
|
|||||||
-- Update the LayoutEngine with actual layout properties
|
-- Update the LayoutEngine with actual layout properties
|
||||||
-- (it was initialized early with defaults for auto-sizing calculations)
|
-- (it was initialized early with defaults for auto-sizing calculations)
|
||||||
self._layoutEngine.positioning = self.positioning
|
self._layoutEngine.positioning = self.positioning
|
||||||
if self.flexDirection then self._layoutEngine.flexDirection = self.flexDirection end
|
if self.flexDirection then
|
||||||
if self.flexWrap then self._layoutEngine.flexWrap = self.flexWrap end
|
self._layoutEngine.flexDirection = self.flexDirection
|
||||||
if self.justifyContent then self._layoutEngine.justifyContent = self.justifyContent end
|
end
|
||||||
if self.alignItems then self._layoutEngine.alignItems = self.alignItems end
|
if self.flexWrap then
|
||||||
if self.alignContent then self._layoutEngine.alignContent = self.alignContent end
|
self._layoutEngine.flexWrap = self.flexWrap
|
||||||
if self.gap then self._layoutEngine.gap = self.gap end
|
end
|
||||||
if self.gridRows then self._layoutEngine.gridRows = self.gridRows end
|
if self.justifyContent then
|
||||||
if self.gridColumns then self._layoutEngine.gridColumns = self.gridColumns end
|
self._layoutEngine.justifyContent = self.justifyContent
|
||||||
if self.columnGap then self._layoutEngine.columnGap = self.columnGap end
|
end
|
||||||
if self.rowGap then self._layoutEngine.rowGap = self.rowGap end
|
if self.alignItems then
|
||||||
|
self._layoutEngine.alignItems = self.alignItems
|
||||||
|
end
|
||||||
|
if self.alignContent then
|
||||||
|
self._layoutEngine.alignContent = self.alignContent
|
||||||
|
end
|
||||||
|
if self.gap then
|
||||||
|
self._layoutEngine.gap = self.gap
|
||||||
|
end
|
||||||
|
if self.gridRows then
|
||||||
|
self._layoutEngine.gridRows = self.gridRows
|
||||||
|
end
|
||||||
|
if self.gridColumns then
|
||||||
|
self._layoutEngine.gridColumns = self.gridColumns
|
||||||
|
end
|
||||||
|
if self.columnGap then
|
||||||
|
self._layoutEngine.columnGap = self.columnGap
|
||||||
|
end
|
||||||
|
if self.rowGap then
|
||||||
|
self._layoutEngine.rowGap = self.rowGap
|
||||||
|
end
|
||||||
|
|
||||||
---animation
|
---animation
|
||||||
self.transform = props.transform or {}
|
self.transform = props.transform or {}
|
||||||
@@ -1285,6 +1314,7 @@ function Element.new(props)
|
|||||||
_scrollY = props._scrollY,
|
_scrollY = props._scrollY,
|
||||||
}, {
|
}, {
|
||||||
utils = utils,
|
utils = utils,
|
||||||
|
Color = Color,
|
||||||
})
|
})
|
||||||
self._scrollManager:initialize(self)
|
self._scrollManager:initialize(self)
|
||||||
|
|
||||||
@@ -1464,15 +1494,6 @@ function Element:_handleScrollbarRelease(button)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Scroll to track click position (internal method used by ScrollManager)
|
|
||||||
---@param mouseX number
|
|
||||||
---@param mouseY number
|
|
||||||
---@param component string -- "vertical" or "horizontal"
|
|
||||||
function Element:_scrollToTrackPosition(mouseX, mouseY, component)
|
|
||||||
-- This method is now handled internally by ScrollManager
|
|
||||||
-- Keeping empty stub for backward compatibility
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Handle mouse wheel scrolling (delegates to ScrollManager)
|
--- Handle mouse wheel scrolling (delegates to ScrollManager)
|
||||||
---@param x number -- Horizontal scroll amount
|
---@param x number -- Horizontal scroll amount
|
||||||
---@param y number -- Vertical scroll amount
|
---@param y number -- Vertical scroll amount
|
||||||
@@ -1794,10 +1815,11 @@ function Element:draw(backdropCanvas)
|
|||||||
self._renderer:drawText(self)
|
self._renderer:drawText(self)
|
||||||
|
|
||||||
-- Draw visual feedback when element is pressed (if it has an onEvent handler and highlight is not disabled)
|
-- Draw visual feedback when element is pressed (if it has an onEvent handler and highlight is not disabled)
|
||||||
if self.onEvent and not self.disableHighlight then
|
if self.onEvent and not self.disableHighlight and self._eventHandler then
|
||||||
-- Check if any button is pressed
|
-- Check if any button is pressed
|
||||||
local anyPressed = false
|
local anyPressed = false
|
||||||
for _, pressed in pairs(self._pressed) do
|
local pressedState = self._eventHandler:getState()._pressed or {}
|
||||||
|
for _, pressed in pairs(pressedState) do
|
||||||
if pressed then
|
if pressed then
|
||||||
anyPressed = true
|
anyPressed = true
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ function LayoutEngine.new(props, deps)
|
|||||||
self._Grid = deps.Grid
|
self._Grid = deps.Grid
|
||||||
self._Units = deps.Units
|
self._Units = deps.Units
|
||||||
self._Context = deps.Context
|
self._Context = deps.Context
|
||||||
|
self._ErrorHandler = deps.ErrorHandler
|
||||||
self._Positioning = Positioning
|
self._Positioning = Positioning
|
||||||
self._FlexDirection = FlexDirection
|
self._FlexDirection = FlexDirection
|
||||||
self._JustifyContent = JustifyContent
|
self._JustifyContent = JustifyContent
|
||||||
@@ -174,6 +175,22 @@ function LayoutEngine:layoutChildren()
|
|||||||
local isFlexChild = not (child.positioning == self._Positioning.ABSOLUTE and child._explicitlyAbsolute)
|
local isFlexChild = not (child.positioning == self._Positioning.ABSOLUTE and child._explicitlyAbsolute)
|
||||||
if isFlexChild then
|
if isFlexChild then
|
||||||
table.insert(flexChildren, child)
|
table.insert(flexChildren, child)
|
||||||
|
|
||||||
|
-- Warn if child uses percentage sizing but parent has autosizing
|
||||||
|
if self._ErrorHandler then
|
||||||
|
if child.units and child.units.width then
|
||||||
|
if child.units.width.unit == "%" and self.element.autosizing and self.element.autosizing.width then
|
||||||
|
self._ErrorHandler.warn("LayoutEngine",
|
||||||
|
string.format("Child '%s' uses percentage width but parent has auto-sizing enabled. This may cause unexpected results", child.id or "unnamed"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if child.units and child.units.height then
|
||||||
|
if child.units.height.unit == "%" and self.element.autosizing and self.element.autosizing.height then
|
||||||
|
self._ErrorHandler.warn("LayoutEngine",
|
||||||
|
string.format("Child '%s' uses percentage height but parent has auto-sizing enabled. This may cause unexpected results", child.id or "unnamed"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local Units = {}
|
local Units = {}
|
||||||
|
|
||||||
local Context = nil
|
local Context = nil
|
||||||
|
local ErrorHandler = nil
|
||||||
|
|
||||||
--- Initialize Units module with Context dependency
|
--- Initialize Units module with Context dependency
|
||||||
---@param context table The Context module
|
---@param context table The Context module
|
||||||
@@ -8,6 +9,12 @@ function Units.initialize(context)
|
|||||||
Context = context
|
Context = context
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Initialize ErrorHandler dependency
|
||||||
|
---@param errorHandler table The ErrorHandler module
|
||||||
|
function Units.initializeErrorHandler(errorHandler)
|
||||||
|
ErrorHandler = errorHandler
|
||||||
|
end
|
||||||
|
|
||||||
---@param value string|number
|
---@param value string|number
|
||||||
---@return number, string -- Returns numeric value and unit type ("px", "%", "vw", "vh")
|
---@return number, string -- Returns numeric value and unit type ("px", "%", "vw", "vh")
|
||||||
function Units.parse(value)
|
function Units.parse(value)
|
||||||
@@ -16,20 +23,34 @@ function Units.parse(value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if type(value) ~= "string" then
|
if type(value) ~= "string" then
|
||||||
-- Fallback to 0px for invalid types
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Invalid unit value type. Expected string or number, got %s", type(value)))
|
||||||
|
end
|
||||||
|
return 0, "px"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check for invalid format (space between number and unit)
|
||||||
|
if value:match("%d%s+%a") then
|
||||||
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Invalid unit string '%s' (contains space). Use format like '50px' or '50%%'", value))
|
||||||
|
end
|
||||||
return 0, "px"
|
return 0, "px"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Match number followed by optional unit
|
-- Match number followed by optional unit
|
||||||
local numStr, unit = value:match("^([%-]?[%d%.]+)(.*)$")
|
local numStr, unit = value:match("^([%-]?[%d%.]+)(.*)$")
|
||||||
if not numStr then
|
if not numStr then
|
||||||
-- Fallback to 0px for invalid format
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Invalid unit format '%s'. Expected format: number + unit (e.g., '50px', '10%%', '2vw')", value))
|
||||||
|
end
|
||||||
return 0, "px"
|
return 0, "px"
|
||||||
end
|
end
|
||||||
|
|
||||||
local num = tonumber(numStr)
|
local num = tonumber(numStr)
|
||||||
if not num then
|
if not num then
|
||||||
-- Fallback to 0px for invalid numeric value
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Invalid numeric value in '%s'", value))
|
||||||
|
end
|
||||||
return 0, "px"
|
return 0, "px"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,6 +61,9 @@ function Units.parse(value)
|
|||||||
|
|
||||||
local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true }
|
local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true }
|
||||||
if not validUnits[unit] then
|
if not validUnits[unit] then
|
||||||
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Unknown unit '%s' in '%s'. Valid units: px, %%, vw, vh, ew, eh", unit, value))
|
||||||
|
end
|
||||||
return num, "px"
|
return num, "px"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -59,7 +83,11 @@ function Units.resolve(value, unit, viewportWidth, viewportHeight, parentSize)
|
|||||||
return value
|
return value
|
||||||
elseif unit == "%" then
|
elseif unit == "%" then
|
||||||
if not parentSize then
|
if not parentSize then
|
||||||
error(formatError("Units", "Percentage units require parent dimension"))
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", "Percentage units require parent dimension. Element has no parent or parent dimension not available")
|
||||||
|
else
|
||||||
|
error("Percentage units require parent dimension")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return (value / 100) * parentSize
|
return (value / 100) * parentSize
|
||||||
elseif unit == "vw" then
|
elseif unit == "vw" then
|
||||||
@@ -67,7 +95,11 @@ function Units.resolve(value, unit, viewportWidth, viewportHeight, parentSize)
|
|||||||
elseif unit == "vh" then
|
elseif unit == "vh" then
|
||||||
return (value / 100) * viewportHeight
|
return (value / 100) * viewportHeight
|
||||||
else
|
else
|
||||||
error(formatError("Units", string.format("Unknown unit type: '%s'. Valid units: px, %%, vw, vh, ew, eh", unit)))
|
if ErrorHandler then
|
||||||
|
ErrorHandler.error("Units", string.format("Unknown unit '%s'. Valid units: px, %%, vw, vh, ew, eh", unit))
|
||||||
|
else
|
||||||
|
error(string.format("Unknown unit type: '%s'", unit))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user