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.
129 lines
3.7 KiB
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
|
|
|