A little timer app
Lua Carousel » Devlog

A friend was looking for a timer app, and I took the opportunity to also package up my little helper for managing GUI widgets that I've shown before (1, 2, 3). I also added support for long-press, which allows for a clean UI: tap on the timer to pause, long-press on the timer to stop.
Step 1: run the screen of abbreviations that comes with Lua Carousel:
-- Some abbreviations to reduce typing. g = love.graphics pt, line = g.points, g.line rect, poly = g.rectangle, g.polygon circle, arc, ellipse = g.circle, g.arc, g.ellipse color = g.setColor min, max = math.min, math.max floor, ceil = math.floor, math.ceil abs, rand = math.abs, math.random pi, cos, sin = math.pi, math.cos, math.sin touches = love.touch.getTouches touch = love.touch.getPosition audio = love.audio.newSource -- Hit 'run', Now they're available to other -- panes.
Step 2: Copy this into a screen and save it as 'widgets'
-- helper screen for creating UI widgets on screen
widgets = {}
long_press_duration = 1
function widgets.__draw()
for name,w in pairs(widgets) do
if name:find('__') == nil and w.draw then
w.draw()
end end end
function widgets.__mousepressed(x,y, b)
for name,w in pairs(widgets) do
if name:find('__') == nil then
if w.ispress(x,y) then
return w.press()
end end end end
function widgets.__update(dt)
local x, y = App.mouse_x(), App.mouse_y()
local mouse_down = App.mouse_down(1)
for name,w in pairs(widgets) do
if name:find('__') == nil then
if w.update then w.update(dt, x,y) end
if w.long_press then
if mouse_down and w.ispress(x,y) then
if w.press_time == nil then
w.press_time = 0
else
w.press_time = w.press_time+dt
if w.press_time > long_press_duration then
w.long_press()
w.press_time = nil
end
end
else
w.press_time = nil
end
end end end end
function widgets.__mousereleased(x,y, b)
for name,w in pairs(widgets) do
if name:find('__') == nil and w.release then
w.release()
end end end
Step 3: Create a third screen for the timer itself.
run_screen('widgets')
timer_x, timer_y = 60, 100
timer_font_height = min(Safe_width, Safe_height)/2
timer_font = g.newFont(timer_font_height)
timer_width = timer_font:getWidth('60')
button_font_height = timer_font_height/4
button_font = g.newFont(button_font_height)
time = 0
state = 'stop'
function main_button()
local x,y, w,h = timer_x, timer_y, timer_width, timer_font_height+4
local press_time = nil
local draw = function()
if state == 'paused' then
color(0.8,0.4,0)
else
color(0.4,0.4,0.4)
end
rect('fill', x,y, w,h, 2,2)
color(0.6,0.6,0.6)
rect('line', x,y, w,h, 2,2)
color(1,1,1)
local t = math.ceil(time)
g.setFont(timer_font)
g.print(t, x+(timer_width-timer_font:getWidth(tostring(t)))/2, y+2)
end
local ispress = function(x2,y2)
return x2 >= x and x2 <= x+w and y2 >= y and y2 <= y+h
end
local press = function()
if state == 'paused' then state = 'run'
else state = 'paused'
end
end
local long_press = function()
state = 'stop'
time = 0
end
local update = function(dt, x,y)
if state == 'run' then
if time > 0 then
time = time - dt
else
time = 0
end end end
return {draw=draw, update=update, ispress=ispress, press=press, long_press=long_press}
end
widgets.main = main_button()
function timer_button(offset, y, x, align)
local title = '+'..tostring(offset)
local w = button_font:getWidth(title)+4
if align == 'center' then x = x - w/2
elseif align == 'right' then x = x - w
end
local h = button_font:getHeight()
local draw = function()
color(0.4,0.7,1)
rect('fill', x,y, w,h, 2,2)
color(0,0,0)
g.setFont(button_font)
g.print(title, x+2, y+2)
end
local ispress = function(x2,y2)
return x2 >= x and x2 <= x+w and y2 >= y and y2 <= y+h
end
local press = function()
time = time + offset
state = 'run'
end
return {draw=draw, ispress=ispress, press=press}
end
local buttony = timer_y+timer_font_height+10
widgets.plus1 = timer_button(1, buttony, timer_x, 'left')
widgets.plus2 = timer_button(2, buttony, timer_x+timer_width/2, 'center')
widgets.plus5 = timer_button(5, buttony, timer_x+timer_width, 'right')
function car.draw()
widgets.__draw()
end
function car.mousepressed(x,y, b)
widgets.__mousepressed(x,y, b)
end
function car.update(dt)
widgets.__update(dt)
end
function car.mousereleased(x,y, b)
widgets.__mousereleased(x,y, b)
end
You need the last dozen or so lines to use the widget screen because each screen gets independent car.* handlers.
Get Lua Carousel
Lua Carousel
Write programs on desktop and mobile
| Status | In development |
| Category | Tool |
| Author | Kartik Agaram |
| Tags | LÖVE |
More posts
- Programming on your device with your preferred language73 days ago
- Lua Carousel: program on the device you have, with docs at your fingertipsMay 12, 2025
- Pong Wars, MMO editionFeb 16, 2025
- New version after 41 days, and stop-motion animationFeb 15, 2025
- Drawing with a pen on a pendulumJan 11, 2025
- New version after 16 daysJan 04, 2025
- New version after 9 daysDec 19, 2024
- New version after 3 daysNov 17, 2024
- New version after 40 daysNov 14, 2024
- Turn your phone or tablet into a chess clockNov 01, 2024
Leave a comment
Log in with itch.io to leave a comment.