my personal dotfiles managed by dotbot, zinit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
3.7 KiB

--- === CountDown ===
---
--- Tiny countdown with visual indicator
---
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/CountDown.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/CountDown.spoon.zip)
local obj = {}
obj.__index = obj
-- Metadata
obj.name = "CountDown"
obj.version = "1.0"
obj.author = "ashfinal <[email protected]>"
obj.homepage = "https://github.com/Hammerspoon/Spoons"
obj.license = "MIT - https://opensource.org/licenses/MIT"
obj.canvas = nil
obj.timer = nil
function obj:init()
self.canvas = hs.canvas.new({x=0, y=0, w=0, h=0}):show()
self.canvas:behavior(hs.canvas.windowBehaviors.canJoinAllSpaces)
self.canvas:level(hs.canvas.windowLevels.status)
self.canvas:alpha(0.35)
self.canvas[1] = {
type = "rectangle",
action = "fill",
fillColor = hs.drawing.color.osx_red,
frame = {x="0%", y="0%", w="0%", h="100%"}
}
self.canvas[2] = {
type = "rectangle",
action = "fill",
fillColor = hs.drawing.color.osx_green,
frame = {x="0%", y="0%", w="0%", h="100%"}
}
end
--- CountDown:startFor(minutes)
--- Method
--- Start a countdown for `minutes` minutes immediately. Calling this method again will kill the existing countdown instance.
---
--- Parameters:
--- * minutes - How many minutes
local function canvasCleanup()
if obj.timer then
obj.timer:stop()
obj.timer = nil
end
obj.canvas[1].frame.w = "0%"
obj.canvas[2].frame.x = "0%"
obj.canvas[2].frame.w = "0%"
obj.canvas:frame({x=0, y=0, w=0, h=0})
end
function obj:startFor(minutes)
if obj.timer then
canvasCleanup()
else
local mainScreen = hs.screen.mainScreen()
local mainRes = mainScreen:fullFrame()
obj.canvas:frame({x=mainRes.x, y=mainRes.y+mainRes.h-5, w=mainRes.w, h=5})
-- Set minimum visual step to 2px (i.e. Make sure every trigger updates 2px on screen at least.)
local minimumStep = 2
local secCount = math.ceil(60*minutes)
obj.loopCount = 0
if mainRes.w/secCount >= 2 then
obj.timer = hs.timer.doEvery(1, function()
obj.loopCount = obj.loopCount+1/secCount
obj:setProgress(obj.loopCount, minutes)
end)
else
local interval = 2/(mainRes.w/secCount)
obj.timer = hs.timer.doEvery(interval, function()
obj.loopCount = obj.loopCount+1/mainRes.w*2
obj:setProgress(obj.loopCount, minutes)
end)
end
end
return self
end
--- CountDown:pauseOrResume()
--- Method
--- Pause or resume the existing countdown.
---
function obj:pauseOrResume()
if obj.timer then
if obj.timer:running() then
obj.timer:stop()
else
obj.timer:start()
end
end
end
--- CountDown:setProgress(progress)
--- Method
--- Set the progress of visual indicator to `progress`.
---
--- Parameters:
--- * progress - an number specifying the value of progress (0.0 - 1.0)
function obj:setProgress(progress, notifystr)
if obj.canvas:frame().h == 0 then
-- Make the canvas actully visible
local mainScreen = hs.screen.mainScreen()
local mainRes = mainScreen:fullFrame()
obj.canvas:frame({x=mainRes.x, y=mainRes.y+mainRes.h-5, w=mainRes.w, h=5})
end
if progress >= 1 then
canvasCleanup()
if notifystr then
hs.notify.new({
title = "Time(" .. notifystr .. " mins) is up!",
informativeText = "Now is " .. os.date("%X")
}):send()
end
else
obj.canvas[1].frame.w = tostring(progress)
obj.canvas[2].frame.x = tostring(progress)
obj.canvas[2].frame.w = tostring(1-progress)
end
end
return obj