-- local gui = require("gui") -- local color = require("gui.core.color") -- local transition = require("gui.core.transitions") -- local multi = require("multi"):init() -- local timer = transition.glide(3.5,1.5,5) -- local function startTimer(opt) -- local default = { -- duration = 30, -- autoText = true, -- autoColor = true, -- autoCleanup = true, -- 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 -- elseif type(opt) == "table" then -- for i,v in pairs(opt) do -- default[i] = v -- end -- opt = default -- end -- local timeRemaining = opt.duration or 30 -- transition.glide:SetFPS(60) -- local handle = timer(3.5, 1.5, timeRemaining) -- 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, num -- local func = function(p,t) -- if num ~= timeRemaining-math.floor(t) then -- num = timeRemaining-math.floor(t) -- end -- 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 num == 0 then -- thread:newThread("Pie Timer",function() -- thread.yield() -- 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) -- tm.OnStop:Fire(tm) -- if opt.autoCleanup then -- tm:Cleanup() -- end -- tm.OnTime:Destroy() -- tm.OnStop:Destroy() -- end) -- end -- return tm, num, t -- end -- tm = { -- Duration = timeRemaining, -- Cleanup = function() handle:Kill() tpie:destroy() tm.Cleanup = function() end end, -- SetText = function(str) tlabel.text = str end, -- SetColor = function(c) tpie.color = c end, -- OnStop = multi:newConnection() -- } -- if opt.finegrained then -- tm.OnTime = func % handle.OnStep -- else -- tm.OnTime = function(self, sec, t) return math.floor(t) == t, self, sec end / (func % handle.OnStep) -- end -- return tm -- end -- return { -- startTimer = startTimer -- } 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 }