134 lines
3.6 KiB
Lua
134 lines
3.6 KiB
Lua
local gui = require("gui")
|
|
local color = require("gui.core.color")
|
|
local multi, thread = require("multi"):init()
|
|
|
|
local function startTimer(opt)
|
|
local default = {
|
|
duration = 30,
|
|
autoText = true,
|
|
autoColor = true,
|
|
autoCleanup = false,
|
|
startColor = color.green,
|
|
textColor = color.black,
|
|
warnColor = color.yellow,
|
|
timeColor = color.red,
|
|
finegrained = false,
|
|
visibility = 1
|
|
}
|
|
|
|
if type(opt) == "number" then
|
|
local d = opt
|
|
opt = default
|
|
opt.duration = d
|
|
elseif type(opt) ~= "table" then
|
|
opt = default
|
|
else
|
|
for i, v in pairs(opt) do
|
|
default[i] = v
|
|
end
|
|
opt = default
|
|
end
|
|
|
|
local timeRemaining = opt.duration or 30
|
|
|
|
local tpie = gui:newFrame():makeArc("pie", -200, 0, 100, 1, 0, 0, 1.5*math.pi, 3.5*math.pi, 360)
|
|
local tlabel = tpie:newTextLabel("")
|
|
tlabel.textColor = opt.textColor
|
|
tlabel.align = gui.ALIGN_CENTER
|
|
tlabel:fullFrame()
|
|
tlabel.visibility = 0
|
|
tpie.color = opt.startColor
|
|
tpie.visibility = opt.visibility
|
|
|
|
local tm
|
|
local stopped = false
|
|
local onTimeConn = multi:newConnection()
|
|
local onStopConn = multi:newConnection()
|
|
|
|
local function cleanup()
|
|
if stopped then return end
|
|
stopped = true
|
|
if onTimeConn and not onTimeConn.destroyed then
|
|
onTimeConn:Destroy()
|
|
end
|
|
if not tpie.destroyed then
|
|
tpie:destroy()
|
|
end
|
|
end
|
|
|
|
local timerThread = thread:newThread("Pie Timer", function()
|
|
local startTime = love.timer.getTime()
|
|
local lastSecond = timeRemaining
|
|
|
|
while not stopped do
|
|
thread.sleep(1/60)
|
|
|
|
local now = love.timer.getTime()
|
|
local elapsed = now - startTime
|
|
local t = math.min(elapsed, timeRemaining)
|
|
local num = timeRemaining - math.floor(t)
|
|
local p = 3.5 - (t / timeRemaining) * 2
|
|
|
|
if opt.autoColor then
|
|
tpie.color = opt.startColor
|
|
if num <= timeRemaining / 3 then
|
|
tpie.color = opt.timeColor
|
|
elseif num <= timeRemaining / 2 then
|
|
tpie.color = opt.warnColor
|
|
end
|
|
end
|
|
|
|
tpie:makeArc("pie", -200, 0, 100, 1, 0, 0, 1.5*math.pi, p*math.pi, 360)
|
|
|
|
if opt.autoText then
|
|
tlabel.text = num
|
|
tlabel:fitFont(nil, nil, {scale=1/2})
|
|
tlabel:centerFont()
|
|
end
|
|
|
|
if opt.finegrained then
|
|
onTimeConn:Fire(tm, num, t)
|
|
elseif num < lastSecond then
|
|
-- crossed a second boundary
|
|
lastSecond = num
|
|
onTimeConn:Fire(tm, num, t)
|
|
end
|
|
|
|
if elapsed >= timeRemaining then
|
|
break
|
|
end
|
|
end
|
|
|
|
-- Timer finished
|
|
if stopped then return end
|
|
|
|
if opt.autoText then
|
|
tlabel.text = "Time"
|
|
tlabel:fitFont(nil, nil, {scale=1/2})
|
|
tlabel:centerFont()
|
|
end
|
|
tpie:makeArc("pie", -200, 0, 100, 1, 0, 0, 1.5*math.pi, 3.5*math.pi, 360)
|
|
|
|
local onStop = onStopConn
|
|
cleanup()
|
|
onStop:Fire(tm)
|
|
end)
|
|
|
|
tm = {
|
|
Duration = timeRemaining,
|
|
OnTime = onTimeConn,
|
|
OnStop = onStopConn,
|
|
SetText = function(str) tlabel.text = str end,
|
|
SetColor = function(c) tpie.color = c end,
|
|
Cleanup = function()
|
|
timerThread:Kill()
|
|
cleanup()
|
|
end,
|
|
}
|
|
|
|
return tm
|
|
end
|
|
|
|
return {
|
|
startTimer = startTimer
|
|
} |