Convert the main menu screen to lua lol
@@ -0,0 +1,13 @@
|
||||
local analogTime = lvgl.AnalogTime(nil, {
|
||||
border_width = 0,
|
||||
x = lvgl.HOR_RES() // 2,
|
||||
y = lvgl.VER_RES() // 2,
|
||||
hands = {
|
||||
hour = SCRIPT_PATH .. "/assets/hand-hour.png",
|
||||
minute = SCRIPT_PATH .. "/assets/hand-minute.png",
|
||||
second = SCRIPT_PATH .. "/assets/hand-second.png",
|
||||
},
|
||||
period = 33,
|
||||
})
|
||||
|
||||
print("analogTime: ", analogTime)
|
||||
@@ -0,0 +1,61 @@
|
||||
local root = lvgl.Object()
|
||||
root:set { w = lvgl.HOR_RES(), h = lvgl.VER_RES() }
|
||||
|
||||
-- create image on root and set position/img src/etc. properties.
|
||||
root:Object():Image {
|
||||
src = SCRIPT_PATH .. "/assets/lvgl-logo.png",
|
||||
x = 0,
|
||||
y = 0,
|
||||
bg_color = 0x004400,
|
||||
pad_all = 0,
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
}:Anim {
|
||||
run = true,
|
||||
start_value = 0,
|
||||
end_value = 3600,
|
||||
duration = 2000,
|
||||
repeat_count = 2,
|
||||
path = "bounce",
|
||||
exec_cb = function(obj, value)
|
||||
obj:set {
|
||||
angle = value
|
||||
}
|
||||
end,
|
||||
done_cb = function (anim, obj)
|
||||
print("anim done.: ", anim, "obj:", obj)
|
||||
anim:delete()
|
||||
end
|
||||
}
|
||||
|
||||
-- second anim example with playback
|
||||
local obj = root:Object {
|
||||
bg_color = "#F00000",
|
||||
radius = lvgl.RADIUS_CIRCLE,
|
||||
align = lvgl.ALIGN.LEFT_MID,
|
||||
}
|
||||
obj:clear_flag(lvgl.FLAG.SCROLLABLE)
|
||||
|
||||
--- @type AnimPara
|
||||
local animPara = {
|
||||
run = true,
|
||||
start_value = 10,
|
||||
end_value = 50,
|
||||
duration = 1000,
|
||||
playback_delay = 100,
|
||||
playback_time = 500,
|
||||
repeat_count = lvgl.ANIM_REPEAT_INFINITE,
|
||||
path = "ease_in_out",
|
||||
}
|
||||
|
||||
animPara.exec_cb = function(obj, value)
|
||||
obj:set { size = value }
|
||||
end
|
||||
|
||||
obj:Anim(animPara)
|
||||
|
||||
animPara.end_value = 240
|
||||
animPara.exec_cb = function(obj, value)
|
||||
obj:set { x = value }
|
||||
end
|
||||
|
||||
obj:Anim(animPara)
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,74 @@
|
||||
-- a dropdown on top left
|
||||
local dd = lvgl.Dropdown(nil, {
|
||||
-- note there are two "Orange"
|
||||
options = "Apple\nBanana\nOrange\nCherry\nGrape\nRaspberry\nMelon\nOrange\nLemon\nNuts",
|
||||
symbol = "\xEF\x81\x94",
|
||||
dir = lvgl.DIR.RIGHT,
|
||||
highlight = false,
|
||||
text = nil,
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_LEFT,
|
||||
x_ofs = 20,
|
||||
y_ofs = 20,
|
||||
}
|
||||
})
|
||||
local list = dd:get("list")
|
||||
print("get dropdown list: ", list)
|
||||
list:set { text_font = lvgl.BUILTIN_FONT.MONTSERRAT_20 }
|
||||
|
||||
print("available options:", dd:get("options"))
|
||||
|
||||
local cnt = 0
|
||||
dd:onevent(lvgl.EVENT.VALUE_CHANGED,
|
||||
---comment
|
||||
---@param obj Dropdown
|
||||
---@param code ObjEventCode
|
||||
function(obj, code)
|
||||
obj:add_option(string.format("Option:%d", cnt), dd:get("option_cnt"))
|
||||
cnt = cnt + 1
|
||||
print(obj:get("selected_str"), "option_cnt" .. obj:get("option_cnt"))
|
||||
end
|
||||
)
|
||||
|
||||
-- another dropdown on top left
|
||||
local dd = lvgl.Dropdown(nil, {
|
||||
options = "Apple\nBanana\nOrange\nCherry\nGrape\nRaspberry\nMelon\nOrange\nLemon\nNuts",
|
||||
symbol = "\xEF\x81\xB7",
|
||||
dir = lvgl.DIR.BOTTOM,
|
||||
text = "SetText",
|
||||
selected = 5,
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_20,
|
||||
align = {
|
||||
type = lvgl.ALIGN.BOTTOM_MID,
|
||||
x_ofs = 0,
|
||||
y_ofs = -20,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
dd:get("list"):set { text_font = lvgl.Font("montserrat", 24) }
|
||||
dd:onevent(lvgl.EVENT.VALUE_CHANGED, function(obj, code)
|
||||
print(obj:get("selected_str") .. ":" .. obj:get("selected"),
|
||||
"dir:" .. obj:get("dir"),
|
||||
"option_index" .. dd:get("option_index", obj:get("selected_str")))
|
||||
end)
|
||||
|
||||
|
||||
|
||||
lvgl.Timer {
|
||||
period = 1000,
|
||||
cb = function(t)
|
||||
t:delete()
|
||||
dd:open()
|
||||
print("now dd should be opened: " .. (dd:is_open() and "open" or "closed"))
|
||||
end
|
||||
}
|
||||
|
||||
lvgl.Timer {
|
||||
period = 2000,
|
||||
cb = function(t)
|
||||
t:delete()
|
||||
dd:close()
|
||||
print("now dd should be closed: " .. (dd:is_open() and "open" or "closed"))
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
local container = lvgl.Object(nil, {
|
||||
w = lvgl.HOR_RES(),
|
||||
h = lvgl.VER_RES(),
|
||||
bg_color = "#888",
|
||||
bg_opa = lvgl.OPA(100),
|
||||
border_width = 0,
|
||||
radius = 0,
|
||||
flex = {
|
||||
flex_direction = "row",
|
||||
flex_wrap = "wrap"
|
||||
}
|
||||
})
|
||||
|
||||
print("created container", container)
|
||||
|
||||
local function createBtn(parent, name)
|
||||
local root = parent:Object {
|
||||
w = lvgl.SIZE_CONTENT,
|
||||
h = lvgl.SIZE_CONTENT,
|
||||
bg_color = "#ccc",
|
||||
bg_opa = lvgl.OPA(100),
|
||||
border_width = 0,
|
||||
radius = 10,
|
||||
pad_all = 20,
|
||||
}
|
||||
|
||||
root:onClicked(function()
|
||||
container:delete()
|
||||
require(name)
|
||||
end)
|
||||
|
||||
root:Label {
|
||||
text = name,
|
||||
text_color = "#333",
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
}
|
||||
end
|
||||
|
||||
createBtn(container, "keyboard")
|
||||
createBtn(container, "animation")
|
||||
createBtn(container, "pointer")
|
||||
createBtn(container, "analogTime")
|
||||
createBtn(container, "flappyBird/flappyBird")
|
||||
createBtn(container, "tests")
|
||||
@@ -0,0 +1,14 @@
|
||||
-- demo of external widget added to lvgl. See simulator/extension.c
|
||||
|
||||
local extension = lvgl.Extension(nil, {
|
||||
border_width = 1,
|
||||
w = lvgl.PCT(20),
|
||||
h = lvgl.PCT(20),
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
})
|
||||
|
||||
extension:onClicked(function ()
|
||||
print("clicked")
|
||||
end)
|
||||
|
||||
print("extension: ", extension)
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,765 @@
|
||||
local lvgl = require("lvgl")
|
||||
|
||||
local MOVE_SPEED = 480 / 8000 -- 8s for 480 pixel, pixel per ms
|
||||
local PIXEL_PER_METER = 80
|
||||
local TOP_Y = 20
|
||||
local BOTTOM_Y = 480 - 112
|
||||
local PIPE_COUNT = 5
|
||||
local PIPE_GAP = 100
|
||||
local PIPE_SPACE = 120
|
||||
|
||||
-- SCRIPT_PATH is set in simulator/main.c, used to get the abs path of first
|
||||
-- lua script lua get called. In this example, SCRIPT_PATH is set to
|
||||
-- path of `examples.lua`, flappyBird.lua is called when button is clicked.
|
||||
|
||||
local IMAGE_PATH = SCRIPT_PATH
|
||||
if not IMAGE_PATH then
|
||||
IMAGE_PATH = "/"
|
||||
print("Note image root path is set to: ", IMAGE_PATH)
|
||||
end
|
||||
|
||||
IMAGE_PATH = IMAGE_PATH .. "/flappyBird/"
|
||||
print("IMAGE_PATH:", IMAGE_PATH)
|
||||
|
||||
local function randomY()
|
||||
return math.random(TOP_Y + 30, BOTTOM_Y - 50 - 50)
|
||||
end
|
||||
|
||||
local function screenCreate(parent)
|
||||
local property = {
|
||||
w = 480,
|
||||
h = 480,
|
||||
bg_opa = 0,
|
||||
border_width = 0,
|
||||
pad_all = 0
|
||||
}
|
||||
|
||||
local scr
|
||||
if parent then
|
||||
scr = parent:Object{
|
||||
w = 480,
|
||||
h = 480,
|
||||
bg_opa = 0,
|
||||
border_width = 0,
|
||||
pad_all = 0
|
||||
}
|
||||
else
|
||||
scr = lvgl.Object(nil, property)
|
||||
end
|
||||
scr:clear_flag(lvgl.FLAG.SCROLLABLE)
|
||||
scr:clear_flag(lvgl.FLAG.CLICKABLE)
|
||||
return scr
|
||||
end
|
||||
|
||||
local function Image(parent, src)
|
||||
local img = {}
|
||||
img.widget = parent:Image{
|
||||
src = src
|
||||
}
|
||||
|
||||
img.w, img.h = img.widget:get_img_size()
|
||||
if not img.w or not img.h then
|
||||
error("failed to load image: " .. src)
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function ImageScroll(root, src, animSpeed, y)
|
||||
-- image on right
|
||||
local right = Image(root, src).widget
|
||||
right:set{
|
||||
src = src,
|
||||
x = 480,
|
||||
y = y,
|
||||
pad_all = 0
|
||||
}
|
||||
|
||||
local img = Image(root, src).widget
|
||||
img:set{
|
||||
x = 0,
|
||||
y = y,
|
||||
src = src,
|
||||
pad_all = 0
|
||||
}
|
||||
|
||||
img:Anim{
|
||||
run = true,
|
||||
start_value = 0,
|
||||
end_value = -480,
|
||||
time = 480 / animSpeed,
|
||||
repeat_count = lvgl.ANIM_REPEAT_INFINITE,
|
||||
path = "linear",
|
||||
exec_cb = function(obj, value)
|
||||
img:set{
|
||||
x = value
|
||||
}
|
||||
|
||||
right:set{
|
||||
x = value + 480
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
img:clear_flag(lvgl.FLAG.CLICKABLE)
|
||||
|
||||
return img
|
||||
end
|
||||
|
||||
local function Frames(parent, src, fps)
|
||||
local frame = Image(parent, src[1])
|
||||
fps = fps ~= 0 and fps or 25
|
||||
|
||||
frame.src = src
|
||||
frame.len = #src
|
||||
frame.i = 0
|
||||
|
||||
frame.timer = lvgl.Timer {
|
||||
period = 1000 / fps,
|
||||
cb = function(t)
|
||||
frame.widget:set{
|
||||
src = frame.src[frame.i]
|
||||
}
|
||||
|
||||
frame.i = frame.i + 1
|
||||
if frame.i == frame.len then
|
||||
frame.i = 1
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
frame.start = function(self)
|
||||
self.timer:resume()
|
||||
end
|
||||
|
||||
frame.pause = function(self)
|
||||
self.timer:pause()
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
local function Pipe(parent)
|
||||
local up = Image(parent, IMAGE_PATH .. "pipe_up.png")
|
||||
local down = Image(parent, IMAGE_PATH .. "pipe_down.png")
|
||||
local pipe = {
|
||||
up = up.widget,
|
||||
down = down.widget,
|
||||
w = up.w,
|
||||
h = up.h,
|
||||
x = 0,
|
||||
y = 0
|
||||
}
|
||||
|
||||
function pipe:updatePipePos()
|
||||
self.up:set{
|
||||
x = self.x,
|
||||
y = self.y - up.h
|
||||
}
|
||||
|
||||
self.down:set{
|
||||
x = self.x,
|
||||
y = self.y + PIPE_GAP
|
||||
}
|
||||
end
|
||||
|
||||
pipe:updatePipePos()
|
||||
return pipe
|
||||
end
|
||||
|
||||
local function ObjInfo(x, y, w, h)
|
||||
return {
|
||||
x = x,
|
||||
y = y,
|
||||
w = w,
|
||||
h = h
|
||||
}
|
||||
end
|
||||
|
||||
local function Pipes(parent)
|
||||
local pipes = {}
|
||||
|
||||
-- add initial pipe
|
||||
for i = 1, PIPE_COUNT do
|
||||
pipes[i] = Pipe(parent)
|
||||
if i == 1 then
|
||||
pipes.w = pipes[i].w -- record pipe size
|
||||
pipes.h = pipes[i].h
|
||||
end
|
||||
end
|
||||
|
||||
local function pipesPosinit()
|
||||
local x = 480;
|
||||
local y = randomY()
|
||||
|
||||
for i = 1, PIPE_COUNT do
|
||||
local pipe = pipes[i]
|
||||
pipe.x = x
|
||||
pipe.y = y
|
||||
pipe:updatePipePos()
|
||||
pipes[i] = pipe
|
||||
x = x + PIPE_SPACE + pipe.w
|
||||
y = randomY()
|
||||
end
|
||||
end
|
||||
|
||||
pipesPosinit()
|
||||
|
||||
pipes.score = 0
|
||||
pipes.last = PIPE_COUNT -- first pipe index in pipes.pipes
|
||||
pipes.totalWidth = (PIPE_COUNT) * (PIPE_SPACE + pipes.w)
|
||||
pipes.birdInfo = ObjInfo(0, 0, 0, 0)
|
||||
pipes.gapInfo = ObjInfo(0, 0, 0, 0)
|
||||
|
||||
function pipes:setObjInfo(x, y, w, h)
|
||||
self.birdInfo.x = x
|
||||
self.birdInfo.y = y
|
||||
if w then
|
||||
self.birdInfo.w = w
|
||||
end
|
||||
if h then
|
||||
self.birdInfo.h = h
|
||||
end
|
||||
end
|
||||
|
||||
local function setGapInfo(x, y, w, h)
|
||||
pipes.gapInfo.x = x
|
||||
pipes.gapInfo.y = y
|
||||
pipes.gapInfo.w = w
|
||||
pipes.gapInfo.h = h
|
||||
end
|
||||
|
||||
pipes.objPassing = -1
|
||||
|
||||
local function isBirdCollision()
|
||||
local bird = pipes.birdInfo
|
||||
local gap = pipes.gapInfo
|
||||
|
||||
-- far left
|
||||
if bird.x + bird.w < gap.x then
|
||||
return false
|
||||
end
|
||||
|
||||
-- far right
|
||||
if bird.x > gap.x + gap.w then
|
||||
return false
|
||||
end
|
||||
|
||||
-- in middle
|
||||
|
||||
if (bird.y > gap.y) and (bird.y + bird.h < gap.y + gap.h) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function moveVirtualX(dx)
|
||||
for i = 1, PIPE_COUNT do
|
||||
local pipe = pipes[i]
|
||||
local newX = pipe.x + dx
|
||||
|
||||
if newX + pipes.w < 0 then
|
||||
newX = newX + pipes.totalWidth
|
||||
pipe.y = randomY()
|
||||
pipes.last = i
|
||||
end
|
||||
|
||||
pipe.x = newX
|
||||
pipe.updatePipePos(pipe)
|
||||
end
|
||||
end
|
||||
|
||||
local function checkScore(i)
|
||||
local pipe = pipes[i]
|
||||
|
||||
local bird = pipes.birdInfo
|
||||
local gap = pipes.gapInfo
|
||||
local passing = pipes.objPassing
|
||||
|
||||
-- far left or right
|
||||
if bird.x + bird.w < gap.x or bird.x > gap.x + gap.w then
|
||||
if passing > 0 and i == passing then
|
||||
pipes.score = pipes.score + 1
|
||||
passing = -1
|
||||
pipes.scoreUpdateCB(pipes.score)
|
||||
end
|
||||
else
|
||||
if passing < 0 then
|
||||
passing = i
|
||||
end
|
||||
end
|
||||
|
||||
pipes.objPassing = passing
|
||||
end
|
||||
|
||||
--- Detect if obj has collision with pipes
|
||||
local function collisionDetect()
|
||||
local first = (pipes.last % PIPE_COUNT) + 1
|
||||
for idx = 0, PIPE_COUNT - 1 do
|
||||
local i = (first + idx - 1) % PIPE_COUNT + 1
|
||||
local pipe = pipes[i]
|
||||
setGapInfo(pipe.x, pipe.y, pipe.w, PIPE_GAP)
|
||||
|
||||
if isBirdCollision() then
|
||||
local bird = pipes.birdInfo
|
||||
if pipes.collisionCB then
|
||||
pipes.collisionCB()
|
||||
end
|
||||
end
|
||||
|
||||
checkScore(i)
|
||||
end
|
||||
end
|
||||
|
||||
pipes.preValue = 0
|
||||
pipes.anim = pipes[1].up:Anim{
|
||||
run = false,
|
||||
start_value = 0,
|
||||
end_value = 480,
|
||||
time = 480 / MOVE_SPEED, -- MOVE_SPEED
|
||||
repeat_count = lvgl.ANIM_REPEAT_INFINITE,
|
||||
path = "linear",
|
||||
exec_cb = function(obj, value)
|
||||
local x = pipes.preValue
|
||||
local d
|
||||
if value < x then
|
||||
d = value + 480 - x
|
||||
else
|
||||
d = value - x
|
||||
end
|
||||
pipes.preValue = value
|
||||
moveVirtualX(-d)
|
||||
collisionDetect()
|
||||
end
|
||||
}
|
||||
|
||||
function pipes:start()
|
||||
self.anim:start()
|
||||
end
|
||||
|
||||
function pipes:stop()
|
||||
self.anim:stop()
|
||||
end
|
||||
|
||||
function pipes:reset()
|
||||
pipesPosinit()
|
||||
pipes.score = 0
|
||||
pipes.preValue = 0
|
||||
pipes.objPassing = -1
|
||||
end
|
||||
|
||||
function pipes:setCollisionCB(collisionCB)
|
||||
self.collisionCB = collisionCB
|
||||
end
|
||||
|
||||
function pipes:setScoreUpdateCB(cb)
|
||||
self.scoreUpdateCB = cb
|
||||
end
|
||||
|
||||
return pipes
|
||||
end
|
||||
|
||||
local function Bird(parent, birdMovedCB)
|
||||
-- create bird Frame(sprite) in 5FPS
|
||||
local bird = Frames(parent,
|
||||
{IMAGE_PATH .. "bird1.png", IMAGE_PATH .. "bird2.png", IMAGE_PATH .. "bird3.png"}, 5)
|
||||
|
||||
local function birdVarInit()
|
||||
bird.x = 240 - bird.w / 2
|
||||
bird.y = 240 - bird.h / 2
|
||||
bird.widget:set{
|
||||
x = bird.x,
|
||||
y = bird.y
|
||||
}
|
||||
|
||||
bird.head = 0
|
||||
bird.force = 0 -- in unit of m/s^2 rather than N
|
||||
bird.velocity = 0 -- vertical verlocity
|
||||
bird.time = 0 -- time stamp when it updates
|
||||
bird.moving = false
|
||||
end
|
||||
|
||||
birdVarInit()
|
||||
|
||||
bird.setY = function(self)
|
||||
bird.widget:set{
|
||||
y = bird.y
|
||||
}
|
||||
end
|
||||
|
||||
bird.setHead = function(self)
|
||||
bird.widget:set{
|
||||
angle = self.head
|
||||
}
|
||||
end
|
||||
|
||||
bird.applyForce = function(self, force)
|
||||
self.force = force
|
||||
if bird.moving then
|
||||
return
|
||||
end
|
||||
|
||||
bird.moving = true
|
||||
self.y_anim:start()
|
||||
end
|
||||
|
||||
bird.pressed = function(self)
|
||||
bird:applyForce(-13)
|
||||
bird.velocity = 0
|
||||
end
|
||||
|
||||
bird.released = function(self)
|
||||
bird:applyForce(9.8)
|
||||
bird.velocity = 0
|
||||
end
|
||||
|
||||
local function velocity2HeadAngle(v)
|
||||
-- -9.8 ~ 9.8:90 ~ -90
|
||||
return v * 60
|
||||
end
|
||||
|
||||
-- y moving anim, in time.
|
||||
bird.y_anim = bird.widget:Anim{
|
||||
run = false,
|
||||
start_value = 0,
|
||||
end_value = 1000,
|
||||
time = 1000, -- 1000 ms
|
||||
repeat_count = lvgl.ANIM_REPEAT_INFINITE,
|
||||
path = "linear",
|
||||
exec_cb = function(obj, tNow)
|
||||
-- we use anim to get current time, can calculate position based on force/velocity
|
||||
if tNow < bird.time then
|
||||
tNow = tNow + 1000
|
||||
end
|
||||
local y = bird.y
|
||||
local preT = bird.time
|
||||
local v = bird.velocity
|
||||
local t = tNow < preT and tNow + 1000 - preT or tNow - preT
|
||||
t = t * 0.001 -- ms to s
|
||||
|
||||
v = bird.force * t + v
|
||||
if v > 10 then
|
||||
v = 10
|
||||
end
|
||||
|
||||
if v < -10 then
|
||||
v = -10
|
||||
end
|
||||
|
||||
y = y + v * t * PIXEL_PER_METER
|
||||
if y > BOTTOM_Y - 30 then
|
||||
y = BOTTOM_Y - 30
|
||||
v = 0
|
||||
end
|
||||
if y < TOP_Y then
|
||||
y = TOP_Y
|
||||
v = 0
|
||||
end
|
||||
|
||||
bird.y = y
|
||||
bird.time = tNow
|
||||
bird.velocity = v
|
||||
bird.head = velocity2HeadAngle(v)
|
||||
|
||||
birdMovedCB(bird.x, bird.y)
|
||||
-- set y
|
||||
bird:setY()
|
||||
bird:setHead()
|
||||
end
|
||||
}
|
||||
|
||||
function bird:stop()
|
||||
bird.y_anim:stop()
|
||||
end
|
||||
|
||||
function bird:gameOver()
|
||||
-- like it's released forever
|
||||
bird.released()
|
||||
end
|
||||
|
||||
function bird:start()
|
||||
bird.y_anim:start()
|
||||
end
|
||||
|
||||
function bird:reset()
|
||||
bird.stop()
|
||||
birdVarInit()
|
||||
end
|
||||
|
||||
return bird;
|
||||
end
|
||||
|
||||
local function Background(root, bgEventCB)
|
||||
local bgLayer = screenCreate(root) -- background layer
|
||||
bgLayer:add_flag(lvgl.FLAG.CLICKABLE) -- we accept event here
|
||||
|
||||
local bg = ImageScroll(bgLayer, IMAGE_PATH .. "bg_day.png", MOVE_SPEED * 0.4, 0)
|
||||
local pipes = Pipes(bgLayer)
|
||||
local land = ImageScroll(bgLayer, IMAGE_PATH .. "land.png", MOVE_SPEED, BOTTOM_Y)
|
||||
|
||||
bgLayer:onevent(lvgl.EVENT.PRESSED, function(obj, code)
|
||||
bgEventCB(lvgl.EVENT.PRESSED)
|
||||
end)
|
||||
|
||||
bgLayer:onevent(lvgl.EVENT.RELEASED, function(obj, code)
|
||||
bgEventCB(lvgl.EVENT.RELEASED)
|
||||
end)
|
||||
|
||||
return {
|
||||
pipes = pipes
|
||||
}
|
||||
end
|
||||
|
||||
local function SysLayer(root)
|
||||
local sysLayer = screenCreate(root) -- upper layer
|
||||
return sysLayer
|
||||
end
|
||||
|
||||
local function createPlayBtn(sysLayer, onEvent)
|
||||
local playBtn = Image(sysLayer, IMAGE_PATH .. "button_play.png").widget
|
||||
playBtn:add_flag(lvgl.FLAG.CLICKABLE)
|
||||
playBtn:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.CENTER,
|
||||
y_ofs = 80
|
||||
}
|
||||
}
|
||||
|
||||
playBtn:onevent(lvgl.EVENT.PRESSED, onEvent)
|
||||
|
||||
return playBtn
|
||||
end
|
||||
|
||||
local function entry()
|
||||
local scr = screenCreate()
|
||||
local bgLayer
|
||||
local mainLayer
|
||||
local sysLayer
|
||||
local bird
|
||||
local pipes
|
||||
local bgEventCB -- background layer pressed/released event
|
||||
local birdMovedCB -- callback when bird position updates
|
||||
local collisionCB -- callback when collision happends
|
||||
local flagRunning = false
|
||||
local gameStart -- API to start game
|
||||
local gameOver -- API to stop game
|
||||
local scoreLabel
|
||||
local scoreBest = 0
|
||||
local scoreNow = 0
|
||||
local debouncing = false
|
||||
-- global event process
|
||||
|
||||
local scoreUpdateCB = function(score)
|
||||
scoreLabel:set{
|
||||
text = string.format("%03d", score)
|
||||
}
|
||||
scoreNow = score
|
||||
end
|
||||
|
||||
print("font:", lvgl.BUILTIN_FONT.MONTSERRAT_26)
|
||||
gameStart = function()
|
||||
if flagRunning then
|
||||
return
|
||||
end
|
||||
|
||||
bird:reset()
|
||||
pipes:reset()
|
||||
pipes:start()
|
||||
bird:start()
|
||||
flagRunning = true
|
||||
scoreNow = 0
|
||||
if scoreLabel then
|
||||
scoreLabel:set{
|
||||
text = string.format("%03d", 0)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
gameOver = function()
|
||||
if not flagRunning then
|
||||
return
|
||||
end
|
||||
|
||||
debouncing = true
|
||||
flagRunning = false
|
||||
|
||||
pipes:stop()
|
||||
bird:gameOver()
|
||||
if scoreNow > scoreBest then
|
||||
scoreBest = scoreNow
|
||||
end
|
||||
|
||||
local gameoverImg = Image(sysLayer, IMAGE_PATH .. "text_game_over.png").widget
|
||||
gameoverImg:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_MID,
|
||||
y_ofs = 100
|
||||
}
|
||||
}
|
||||
|
||||
gameoverImg:Anim{
|
||||
run = true,
|
||||
start_value = 0,
|
||||
end_value = 3600,
|
||||
time = 2000,
|
||||
repeat_count = 2,
|
||||
path = "bounce",
|
||||
exec_cb = function(obj, value)
|
||||
obj:set{
|
||||
angle = value
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
local scoreImg = Image(sysLayer, IMAGE_PATH .. "score.png").widget
|
||||
scoreImg:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.CENTER,
|
||||
y_ofs = -20,
|
||||
x_ofs = 0
|
||||
}
|
||||
}
|
||||
scoreImg:Anim{
|
||||
run = true,
|
||||
start_value = 480,
|
||||
end_value = 0,
|
||||
time = 1000,
|
||||
repeat_count = 1,
|
||||
path = "ease_in",
|
||||
exec_cb = function(obj, value)
|
||||
obj:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.CENTER,
|
||||
x_ofs = value,
|
||||
y_ofs = -20
|
||||
}
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
local scoreResultLabel = scoreImg:Label{
|
||||
text = string.format("%03d", scoreNow),
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_22,
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_MID,
|
||||
x_ofs = 0,
|
||||
y_ofs = 25
|
||||
}
|
||||
}
|
||||
|
||||
local scoreBestLabel = scoreImg:Label{
|
||||
text = string.format("%03d", scoreBest),
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_22,
|
||||
align = {
|
||||
type = lvgl.ALIGN.BOTTOM_MID,
|
||||
x_ofs = 0,
|
||||
y_ofs = -5
|
||||
}
|
||||
}
|
||||
scoreNow = 0
|
||||
|
||||
local playBtn;
|
||||
playBtn = createPlayBtn(sysLayer, function(obj, code)
|
||||
if debouncing then
|
||||
return
|
||||
end
|
||||
|
||||
gameStart()
|
||||
playBtn:delete()
|
||||
playBtn = nil
|
||||
gameoverImg:delete()
|
||||
gameoverImg = nil
|
||||
scoreImg:delete()
|
||||
scoreImg = nil
|
||||
end)
|
||||
|
||||
lvgl.Timer {
|
||||
period = 1000,
|
||||
cb = function(t)
|
||||
t:delete()
|
||||
debouncing = false
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
bgEventCB = function(event)
|
||||
if not flagRunning then
|
||||
return
|
||||
end
|
||||
|
||||
if event == lvgl.EVENT.PRESSED then
|
||||
bird:pressed()
|
||||
else
|
||||
bird:released()
|
||||
end
|
||||
end
|
||||
|
||||
local birdMovedCB = function(x, y)
|
||||
pipes:setObjInfo(bird.x, bird.y) -- set intial bird position.
|
||||
end
|
||||
|
||||
local collisionCB = function()
|
||||
print("bird collision, stop game")
|
||||
-- call later
|
||||
lvgl.Timer {
|
||||
period = 10,
|
||||
cb = function(t)
|
||||
t:delete()
|
||||
gameOver()
|
||||
end
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
-- background layer, including sky, then pipes and land above
|
||||
bgLayer = Background(scr, bgEventCB) -- background layer
|
||||
pipes = bgLayer.pipes -- get pipes from bg layer for set bird info etc.
|
||||
pipes:setCollisionCB(collisionCB)
|
||||
pipes:setScoreUpdateCB(scoreUpdateCB)
|
||||
|
||||
-- main layer, the bird
|
||||
mainLayer = screenCreate(scr) -- main layer
|
||||
bird = Bird(mainLayer, birdMovedCB)
|
||||
pipes:setObjInfo(bird.x, bird.y, bird.w, bird.h)
|
||||
-- system layer, score etc.
|
||||
sysLayer = SysLayer(scr)
|
||||
|
||||
local title = Image(sysLayer, IMAGE_PATH .. "title.png").widget
|
||||
title:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_MID,
|
||||
y_ofs = 80
|
||||
}
|
||||
}
|
||||
|
||||
local playBtn;
|
||||
playBtn = createPlayBtn(sysLayer, function()
|
||||
print("pressed")
|
||||
gameStart()
|
||||
playBtn:delete()
|
||||
playBtn = nil
|
||||
title:delete()
|
||||
title = nil
|
||||
|
||||
local medal = Image(sysLayer, IMAGE_PATH .. "medals.png").widget
|
||||
medal:set{
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_MID,
|
||||
y_ofs = 10,
|
||||
x_ofs = -50
|
||||
}
|
||||
}
|
||||
scoreLabel = sysLayer:Label{
|
||||
text = " 000",
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_28,
|
||||
align = {
|
||||
type = lvgl.ALIGN.TOP_MID,
|
||||
x_ofs = 10,
|
||||
y_ofs = 20
|
||||
}
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
entry()
|
||||
|
||||
-- bird = Bird(, nil)
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 536 B |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,27 @@
|
||||
local lvgl = require("lvgl")
|
||||
|
||||
local root = lvgl.Object(nil, {
|
||||
flex = {
|
||||
flex_direction = "row",
|
||||
flex_wrap = "wrap",
|
||||
justify_content = "center",
|
||||
align_items = "center",
|
||||
align_content = "center",
|
||||
},
|
||||
w = lvgl.HOR_RES(),
|
||||
h = lvgl.VER_RES(),
|
||||
align = lvgl.ALIGN.CENTER
|
||||
})
|
||||
|
||||
for i = 1, 10 do
|
||||
local item = root:Object {
|
||||
w = 100,
|
||||
h = lvgl.PCT(100),
|
||||
}
|
||||
item:clear_flag(lvgl.FLAG.SCROLLABLE)
|
||||
|
||||
local label = item:Label {
|
||||
text = string.format("label %d", i)
|
||||
}
|
||||
label:center()
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
local label1 = lvgl.Label(nil, {
|
||||
x = 0, y = 0,
|
||||
text_font = lvgl.Font("montserrat", 32, "normal"),
|
||||
text = "Hello Font",
|
||||
align = lvgl.ALIGN.CENTER
|
||||
})
|
||||
|
||||
print("label1: ", label1)
|
||||
|
||||
lvgl.Label(nil, {
|
||||
-- x= 0, y = 0,
|
||||
-- text_font = lvgl.Font("MiSansW medium, montserrat", 24),
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_22,
|
||||
text = "Hello Font2",
|
||||
}):align_to({
|
||||
type = lvgl.ALIGN.OUT_BOTTOM_LEFT,
|
||||
base = label1,
|
||||
})
|
||||
@@ -0,0 +1,59 @@
|
||||
local function fs_example()
|
||||
-- local f <close>, msg, code = lvgl.open_file(SCRIPT_PATH .. "/tmp.txt") -- for lua 5.4
|
||||
local f, msg, code = lvgl.fs.open_file(SCRIPT_PATH .. "/tmp.txt", "rw")
|
||||
if not f then
|
||||
print("failed: ", msg, code)
|
||||
return
|
||||
end
|
||||
|
||||
print("f: ", f)
|
||||
|
||||
f:write("0123456789", 123, "\n", "the remaining text")
|
||||
f:seek("set", 0) -- go back
|
||||
local header, remaining = f:read(10, "*a")
|
||||
f:close()
|
||||
if not header then
|
||||
print("read failed or EOF")
|
||||
return
|
||||
end
|
||||
|
||||
print("header len:", #header, ": ", header)
|
||||
print("remaining: ", remaining)
|
||||
|
||||
lvgl.Label(nil, {
|
||||
x = 0,
|
||||
y = 0,
|
||||
text_font = lvgl.Font("montserrat", 20, "normal"),
|
||||
text = header .. remaining,
|
||||
align = lvgl.ALIGN.TOP_LEFT
|
||||
})
|
||||
|
||||
local list = lvgl.List(nil, {
|
||||
align = lvgl.ALIGN.TOP_RIGHT,
|
||||
pad_all = 10,
|
||||
text_font = lvgl.BUILTIN_FONT.MONTSERRAT_12
|
||||
})
|
||||
list:add_text("Directory list:")
|
||||
|
||||
-- local dir <close>, msg, code = lvgl.fs.open_dir(SCRIPT_PATH .. "/")
|
||||
local dir, msg, code = lvgl.fs.open_dir(SCRIPT_PATH .. "/")
|
||||
if not dir then
|
||||
print("open dir failed: ", msg, code)
|
||||
return
|
||||
end
|
||||
|
||||
while true do
|
||||
local d = dir:read()
|
||||
if not d then break end
|
||||
local is_dir = string.byte(d, 1) == string.byte("/", 1)
|
||||
local str = (is_dir and "dir: " or "file: ") .. d
|
||||
print(str)
|
||||
|
||||
list:add_text(str):set{
|
||||
border_width = 1,
|
||||
}
|
||||
end
|
||||
dir:close()
|
||||
end
|
||||
|
||||
fs_example()
|
||||
@@ -0,0 +1,61 @@
|
||||
local function group_example()
|
||||
local g = lvgl.group.create()
|
||||
g:set_default()
|
||||
|
||||
-- for demo purpose, set all indev to use this group
|
||||
local indev = nil
|
||||
while true do
|
||||
indev = lvgl.indev.get_next(indev)
|
||||
if not indev then break end
|
||||
|
||||
local t = indev:get_type()
|
||||
if t == 2 or t == 4 then
|
||||
indev:set_group(g)
|
||||
end
|
||||
end
|
||||
|
||||
local style = lvgl.Style({
|
||||
border_width = 5,
|
||||
border_color = "#a00",
|
||||
})
|
||||
|
||||
local root = lvgl.Object(nil, {
|
||||
w = lvgl.PCT(100),
|
||||
h = lvgl.PCT(100),
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
bg_color = "#aaa",
|
||||
flex = {
|
||||
flex_direction = "row",
|
||||
flex_wrap = "wrap"
|
||||
}
|
||||
})
|
||||
|
||||
root:add_style(style, lvgl.STATE.FOCUSED)
|
||||
|
||||
for _ = 1, 5 do
|
||||
local obj = root:Object({
|
||||
w = lvgl.PCT(50),
|
||||
h = lvgl.PCT(50),
|
||||
bg_color = "#555",
|
||||
})
|
||||
|
||||
obj:add_style(style, lvgl.STATE.FOCUSED)
|
||||
|
||||
obj:onClicked(function(obj, code)
|
||||
print("clicked: ", obj)
|
||||
end)
|
||||
|
||||
obj:onevent(lvgl.EVENT.FOCUSED, function(obj, code)
|
||||
print("focused: ", obj)
|
||||
obj:scroll_to_view(true)
|
||||
end)
|
||||
|
||||
obj:onevent(lvgl.EVENT.DEFOCUSED, function(obj, code)
|
||||
print("defocused: ", obj)
|
||||
end)
|
||||
|
||||
g:add_obj(obj)
|
||||
end
|
||||
end
|
||||
|
||||
group_example()
|
||||
@@ -0,0 +1,61 @@
|
||||
local function indev_example()
|
||||
local indev = lvgl.indev.get_act()
|
||||
print("act indev: ", indev)
|
||||
|
||||
|
||||
indev:on_event(lvgl.EVENT.SHORT_CLICKED, function ()
|
||||
print("indev pressed")
|
||||
end)
|
||||
local obj_act = lvgl.indev.get_obj_act()
|
||||
print("obj_act: ", obj_act)
|
||||
|
||||
local root = lvgl.Object(nil, {
|
||||
w = lvgl.PCT(30),
|
||||
h = lvgl.PCT(30),
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
bg_color = "#aaa",
|
||||
})
|
||||
|
||||
root:Object({
|
||||
w = 1000,
|
||||
h = 1000,
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
bg_color = "#555",
|
||||
}):onevent(lvgl.EVENT.ALL, function(obj, code)
|
||||
local indev = lvgl.indev.get_act()
|
||||
|
||||
if not indev then return end
|
||||
|
||||
if code == lvgl.EVENT.PRESSED then
|
||||
local x, y = indev:get_point()
|
||||
print("pressed: ", x, y)
|
||||
end
|
||||
|
||||
if code == lvgl.EVENT.PRESSING then
|
||||
local x, y = indev:get_vect()
|
||||
print("vect: ", x, y)
|
||||
end
|
||||
|
||||
if code == lvgl.EVENT.GESTURE then
|
||||
local gesture_dir = indev:get_gesture_dir()
|
||||
print("gesture_dir: ", gesture_dir)
|
||||
end
|
||||
|
||||
if code == lvgl.EVENT.RELEASED then
|
||||
local scroll_dir = indev:get_scroll_dir()
|
||||
print("scroll_dir: ", scroll_dir)
|
||||
|
||||
local scroll_obj = indev:get_scroll_obj()
|
||||
print("scroll_obj: ", scroll_obj)
|
||||
|
||||
local x, y = indev:get_vect()
|
||||
local obj_search = obj:indev_search(x, y)
|
||||
print("indev search obj: ", obj_search)
|
||||
|
||||
local obj_search = obj:indev_search({x, y})
|
||||
print("indev search obj2: ", obj_search)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
indev_example()
|
||||
@@ -0,0 +1,46 @@
|
||||
local root = lvgl.Object(nil, {
|
||||
w = lvgl.HOR_RES(),
|
||||
h = lvgl.VER_RES(),
|
||||
pad_all = 0,
|
||||
bg_color = "#333",
|
||||
bg_opa = lvgl.OPA(50),
|
||||
})
|
||||
root:add_flag(lvgl.FLAG.CLICKABLE)
|
||||
|
||||
local ta = root:Textarea {
|
||||
password_mode = false,
|
||||
one_line = true,
|
||||
text_font = lvgl.Font("montserrat", 22),
|
||||
text_color = "#FFF",
|
||||
text = "Input text here",
|
||||
w = lvgl.SIZE_CONTENT,
|
||||
h = lvgl.SIZE_CONTENT,
|
||||
bg_opa = 0,
|
||||
border_width = 2,
|
||||
pad_all = 2,
|
||||
align = lvgl.ALIGN.TOP_MID,
|
||||
}
|
||||
|
||||
print("created textarea: ", ta)
|
||||
|
||||
local keyboard = root:Keyboard {
|
||||
textarea = ta,
|
||||
align = lvgl.ALIGN.BOTTOM_MID,
|
||||
}
|
||||
print("created keyboard: ", keyboard)
|
||||
|
||||
ta:onevent(lvgl.EVENT.PRESSED, function(obj, code)
|
||||
keyboard:clear_flag(lvgl.FLAG.HIDDEN)
|
||||
end)
|
||||
|
||||
ta:onevent(lvgl.EVENT.READY, function()
|
||||
keyboard:add_flag(lvgl.FLAG.HIDDEN)
|
||||
end)
|
||||
|
||||
ta:onevent(lvgl.EVENT.CANCEL, function(obj, code)
|
||||
keyboard:add_flag(lvgl.FLAG.HIDDEN)
|
||||
end)
|
||||
|
||||
root:onClicked(function (obj, code)
|
||||
keyboard:add_flag(lvgl.FLAG.HIDDEN)
|
||||
end)
|
||||
@@ -0,0 +1,46 @@
|
||||
local root = lvgl.Object(nil, {
|
||||
w = 0,
|
||||
h = 0,
|
||||
pad_all = 0,
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
border_width = 1,
|
||||
border_color = "#F00",
|
||||
})
|
||||
|
||||
local pointer = root:Pointer {
|
||||
src = SCRIPT_PATH .. "/assets/second.png",
|
||||
x = -20,
|
||||
y = -233,
|
||||
border_width = 1,
|
||||
border_color = "#0F0",
|
||||
range = {
|
||||
valueStart = 0,
|
||||
valueRange = 60000,
|
||||
angleStart = 0,
|
||||
angleRange = -3600
|
||||
},
|
||||
}
|
||||
|
||||
-- lvgl requires src set firstly, since lua cannot guarantee table order,
|
||||
-- we set pivot after image src is set.
|
||||
pointer:set {
|
||||
pivot = { x = 20, y = 233 },
|
||||
}
|
||||
|
||||
print("img w,h: ", pointer:get_img_size())
|
||||
|
||||
pointer:Anim{
|
||||
run = true,
|
||||
start_value = 0,
|
||||
end_value = 60000,
|
||||
duration = 60000,
|
||||
path = "linear",
|
||||
repeat_count = lvgl.ANIM_REPEAT_INFINITE,
|
||||
exec_cb = function(obj, value)
|
||||
obj:set {
|
||||
value = value
|
||||
}
|
||||
end,
|
||||
}
|
||||
|
||||
print("created pointer: ", pointer)
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
local function testCrash()
|
||||
print(nil .. "")
|
||||
end
|
||||
|
||||
local function testCrash2()
|
||||
testCrash()
|
||||
end
|
||||
local function testCrash3()
|
||||
testCrash2()
|
||||
end
|
||||
local function testCrash4()
|
||||
testCrash3()
|
||||
end
|
||||
|
||||
local function testCrash5()
|
||||
testCrash4()
|
||||
end
|
||||
|
||||
local function testCrash6()
|
||||
testCrash5()
|
||||
end
|
||||
|
||||
lvgl.Label(nil, {
|
||||
text = "crash in 1 second.",
|
||||
align = lvgl.ALIGN.CENTER
|
||||
})
|
||||
|
||||
lvgl.Timer {
|
||||
period = 1000,
|
||||
cb = function(t)
|
||||
t:delete()
|
||||
-- crash in callback function is protected.
|
||||
testCrash6()
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
local roller = lvgl.Roller(nil, {
|
||||
options = {
|
||||
options = "January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember",
|
||||
mode = lvgl.ROLLER_MODE.INFINITE,
|
||||
},
|
||||
visible_cnt = 4,
|
||||
align = lvgl.ALIGN.CENTER
|
||||
})
|
||||
|
||||
print("create roller:", roller)
|
||||
roller:onevent(lvgl.EVENT.VALUE_CHANGED, function (obj, code)
|
||||
print(obj:get_selected_str())
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
local container = lvgl.Object(nil, {
|
||||
w = lvgl.HOR_RES(),
|
||||
h = lvgl.VER_RES(),
|
||||
bg_color = "#888",
|
||||
bg_opa = lvgl.OPA(100),
|
||||
border_width = 0,
|
||||
radius = 0,
|
||||
flex = {
|
||||
flex_direction = "row",
|
||||
flex_wrap = "wrap"
|
||||
}
|
||||
})
|
||||
|
||||
local function createBtn(parent, name)
|
||||
local root = parent:Object {
|
||||
w = lvgl.SIZE_CONTENT,
|
||||
h = lvgl.SIZE_CONTENT,
|
||||
bg_color = "#ccc",
|
||||
bg_opa = lvgl.OPA(100),
|
||||
border_width = 0,
|
||||
radius = 10,
|
||||
pad_all = 20,
|
||||
}
|
||||
|
||||
root:onClicked(function()
|
||||
container:delete()
|
||||
require(name)
|
||||
end)
|
||||
|
||||
root:Label {
|
||||
text = name,
|
||||
text_color = "#333",
|
||||
align = lvgl.ALIGN.CENTER,
|
||||
}
|
||||
end
|
||||
|
||||
createBtn(container, "font")
|
||||
createBtn(container, "uservalue")
|
||||
createBtn(container, "roller")
|
||||
createBtn(container, "dropdown")
|
||||
createBtn(container, "extension")
|
||||
createBtn(container, "fs")
|
||||
createBtn(container, "indev")
|
||||
createBtn(container, "group")
|
||||
createBtn(container, "protectedcall")
|
||||
@@ -0,0 +1,34 @@
|
||||
collectgarbage("collect")
|
||||
print("initial: ", collectgarbage("count"))
|
||||
|
||||
local str_t = {}
|
||||
for i = 1, 1024 * 1024 do
|
||||
str_t[#str_t + 1] = 'a'
|
||||
end
|
||||
|
||||
local str = table.concat(str_t)
|
||||
str_t = nil
|
||||
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
print("after string collect: ", collectgarbage("count"))
|
||||
|
||||
for i = 1, 10 do
|
||||
local label = lvgl.Label(nil)
|
||||
label:set_text_static(str)
|
||||
label:delete()
|
||||
end
|
||||
str = nil
|
||||
|
||||
print("after set text: ", collectgarbage("count"))
|
||||
collectgarbage("collect")
|
||||
print("after collect: ", collectgarbage("count"))
|
||||
print("again: ", collectgarbage("count"))
|
||||
collectgarbage("collect")
|
||||
print("again2: ", collectgarbage("count"))
|
||||
collectgarbage("collect")
|
||||
print("again3: ", collectgarbage("count"))
|
||||
|
||||
local label = lvgl.Label(nil)
|
||||
label:set({ text = "Test Done" })
|
||||
label:center()
|
||||