mirror of https://github.com/einverne/dotfiles.git
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.
130 lines
3.7 KiB
130 lines
3.7 KiB
4 years ago
|
--- === 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
|