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.
179 lines
5.4 KiB
179 lines
5.4 KiB
--- === HCalendar === |
|
--- |
|
--- A horizonal calendar inset into the desktop |
|
--- |
|
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/HCalendar.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/HCalendar.spoon.zip) |
|
|
|
local obj={} |
|
obj.__index = obj |
|
|
|
-- Metadata |
|
obj.name = "HCalendar" |
|
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.hcalw = 31*24+20 |
|
obj.hcalh = 100 |
|
|
|
local function updateHcalCanvas() |
|
local titlestr = os.date("%B %Y") |
|
obj.canvas[3].text = titlestr |
|
local currentyear = os.date("%Y") |
|
local currentmonth = os.date("%m") |
|
local currentday = os.date("%d") |
|
local weeknames = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} |
|
local firstdayofnextmonth = os.time{year=currentyear, month=currentmonth+1, day=1} |
|
local lastdayofcurrentmonth = os.date("*t", firstdayofnextmonth-24*60*60).day |
|
for i=1,lastdayofcurrentmonth do |
|
local weekdayofqueriedday = os.date("*t", os.time{year=currentyear, month=currentmonth, day=i}).wday |
|
local mappedweekdaystr = weeknames[weekdayofqueriedday] |
|
obj.canvas[3+i].text = mappedweekdaystr |
|
obj.canvas[65+i].text = i |
|
if mappedweekdaystr == "Sa" or mappedweekdaystr == "Su" then |
|
obj.canvas[3+i].textColor = {hex="#FF7878"} |
|
obj.canvas[34+i].fillColor = {hex="#FF7878"} |
|
obj.canvas[65+i].textColor = {hex="#FF7878"} |
|
else |
|
-- Restore the default colors |
|
obj.canvas[3+i].textColor = {hex="#FFFFFF"} |
|
obj.canvas[34+i].fillColor = {hex="#FFFFFF", alpha=0.5} |
|
obj.canvas[65+i].textColor = {hex="#FFFFFF"} |
|
end |
|
if i == math.tointeger(currentday) then |
|
obj.canvas[34+i].fillColor = {hex="#00BAFF", alpha=0.8} |
|
obj.canvas[97].frame.x = tostring((10+24*(i-1))/obj.hcalw) |
|
end |
|
end |
|
-- hide extra day |
|
for i=lastdayofcurrentmonth+1, 31 do |
|
obj.canvas[3+i].text = "" |
|
obj.canvas[34+i].fillColor.alpha = 0 |
|
obj.canvas[65+i].text = "" |
|
end |
|
-- Adjust the size of clipmask to clip the canvas |
|
obj.canvas[2].frame.w = tostring((lastdayofcurrentmonth*24+20)/obj.hcalw) |
|
end |
|
|
|
function obj:init() |
|
local hcalbgcolor = {hex="#000000", alpha=0.3} |
|
local hcaltitlecolor = {hex="#FFFFFF", alpha=0.3} |
|
local todaycolor = {hex="#FFFFFF", alpha=0.2} |
|
local midlinecolor = {hex="#FFFFFF", alpha=0.5} |
|
local cscreen = hs.screen.mainScreen() |
|
local cres = cscreen:fullFrame() |
|
obj.canvas = hs.canvas.new({ |
|
x = 40, |
|
y = cres.h-obj.hcalh-40, |
|
w = obj.hcalw, |
|
h = obj.hcalh, |
|
}):show() |
|
|
|
obj.canvas:behavior(hs.canvas.windowBehaviors.canJoinAllSpaces) |
|
obj.canvas:level(hs.canvas.windowLevels.desktopIcon) |
|
|
|
-- Use one pseudo element to clip the canvas |
|
obj.canvas[1] = { |
|
type = "rectangle", |
|
action = "clip", |
|
roundedRectRadii = {xRadius = 10, yRadius = 10}, |
|
} |
|
|
|
-- *NOW* we can draw our actual "visible" parts |
|
obj.canvas[2] = { |
|
id = "hcal_bg", |
|
type = "rectangle", |
|
action = "fill", |
|
fillColor = hcalbgcolor, |
|
roundedRectRadii = {xRadius = 10, yRadius = 10}, |
|
} |
|
|
|
obj.canvas[3] = { |
|
id = "hcal_title", |
|
type = "text", |
|
text = "", |
|
textSize = 18, |
|
textColor = hcaltitlecolor, |
|
textAlignment = "left", |
|
frame = { |
|
x = tostring(10/obj.hcalw), |
|
y = tostring(10/obj.hcalh), |
|
w = tostring(1-20/obj.hcalw), |
|
h = "30%" |
|
} |
|
} |
|
|
|
-- upside weekday string |
|
for i=4, 4+30 do |
|
obj.canvas[i] = { |
|
type = "text", |
|
text = "", |
|
textFont = "Courier-Bold", |
|
textSize = 13, |
|
textAlignment = "center", |
|
frame = { |
|
x = tostring((10+24*(i-4))/obj.hcalw), |
|
y = "45%", |
|
w = tostring(24/(obj.hcalw-20)), |
|
h = "23%" |
|
} |
|
} |
|
end |
|
|
|
-- midline rectangle |
|
for i=35, 35+30 do |
|
obj.canvas[i] = { |
|
type = "rectangle", |
|
action = "fill", |
|
fillColor = midlinecolor, |
|
frame = { |
|
x = tostring((10+24*(i-35))/obj.hcalw), |
|
y = "65%", |
|
w = tostring(24/(obj.hcalw-20)), |
|
h = "4%" |
|
} |
|
} |
|
end |
|
|
|
-- downside day string |
|
for i=66, 66+30 do |
|
obj.canvas[i] = { |
|
type = "text", |
|
text = "", |
|
textFont = "Courier-Bold", |
|
textSize = 13, |
|
textAlignment = "center", |
|
frame = { |
|
x = tostring((10+24*(i-66))/obj.hcalw), |
|
y = "70%", |
|
w = tostring(24/(obj.hcalw-20)), |
|
h = "23%" |
|
} |
|
} |
|
end |
|
|
|
-- today cover rectangle |
|
obj.canvas[97] = { |
|
type = "rectangle", |
|
action = "fill", |
|
fillColor = todaycolor, |
|
roundedRectRadii = {xRadius = 3, yRadius = 3}, |
|
frame = { |
|
x = tostring(10/obj.hcalw), |
|
y = "44%", |
|
w = tostring(24/(obj.hcalw-20)), |
|
h = "46%" |
|
} |
|
} |
|
|
|
if obj.timer == nil then |
|
obj.timer = hs.timer.doEvery(1800, function() updateHcalCanvas() end) |
|
obj.timer:setNextTrigger(0) |
|
else |
|
obj.timer:start() |
|
end |
|
|
|
end |
|
|
|
return obj
|
|
|