awesome-wm-widgets/calendar-widget/calendar.lua

286 lines
9.3 KiB
Lua
Raw Normal View History

2019-12-12 04:05:01 +01:00
-------------------------------------------------
-- Calendar Widget for Awesome Window Manager
-- Shows the current month and supports scroll up/down to switch month
2019-12-12 04:05:01 +01:00
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/calendar-widget
2019-12-12 04:05:01 +01:00
-- @author Pavel Makhov
-- @copyright 2019 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
2019-12-13 04:27:12 +01:00
local beautiful = require("beautiful")
2019-12-12 04:05:01 +01:00
local wibox = require("wibox")
local gears = require("gears")
local naughty = require("naughty")
2019-12-12 04:05:01 +01:00
local calendar_widget = {}
2020-12-06 20:47:40 +01:00
local function worker(user_args)
2019-12-16 04:10:22 +01:00
local calendar_themes = {
nord = {
bg = '#2E3440',
fg = '#D8DEE9',
focus_date_bg = '#88C0D0',
focus_date_fg = '#000000',
weekend_day_bg = '#3B4252',
weekday_fg = '#88C0D0',
header_fg = '#E5E9F0',
border = '#4C566A'
},
outrun = {
bg = '#0d0221',
fg = '#D8DEE9',
focus_date_bg = '#650d89',
focus_date_fg = '#2de6e2',
weekend_day_bg = '#261447',
weekday_fg = '#2de6e2',
header_fg = '#f6019d',
border = '#261447'
2019-12-17 22:43:36 +01:00
},
dark = {
bg = '#000000',
fg = '#ffffff',
focus_date_bg = '#ffffff',
focus_date_fg = '#000000',
weekend_day_bg = '#444444',
weekday_fg = '#ffffff',
header_fg = '#ffffff',
border = '#333333'
},
light = {
bg = '#ffffff',
fg = '#000000',
focus_date_bg = '#000000',
focus_date_fg = '#ffffff',
weekend_day_bg = '#AAAAAA',
weekday_fg = '#000000',
header_fg = '#000000',
border = '#CCCCCC'
2019-12-18 03:46:02 +01:00
},
monokai = {
bg = '#272822',
fg = '#F8F8F2',
focus_date_bg = '#AE81FF',
focus_date_fg = '#ffffff',
weekend_day_bg = '#75715E',
weekday_fg = '#FD971F',
header_fg = '#F92672',
border = '#75715E'
},
naughty = {
bg = beautiful.notification_bg or beautiful.bg or beautiful.bg_normal,
fg = beautiful.notification_fg or beautiful.fg or beautiful.fg_normal,
focus_date_bg = beautiful.notification_fg or beautiful.fg or beautiful.fg_normal,
focus_date_fg = beautiful.notification_bg or beautiful.bg or beautiful.bg_normal,
weekend_day_bg = beautiful.bg_focus,
weekday_fg = beautiful.fg,
header_fg = beautiful.fg,
border = beautiful.border_normal
2019-12-16 04:10:22 +01:00
}
2019-12-16 04:10:22 +01:00
}
2019-12-13 04:27:12 +01:00
2020-12-06 20:47:40 +01:00
local args = user_args or {}
2019-12-16 04:10:22 +01:00
if args.theme ~= nil and calendar_themes[args.theme] == nil then
naughty.notify({
2019-12-25 02:38:27 +01:00
preset = naughty.config.presets.critical,
title = 'Calendar Widget',
text = 'Theme "' .. args.theme .. '" not found, fallback to default'})
args.theme = 'naughty'
end
local theme = args.theme or 'naughty'
2019-12-16 04:10:22 +01:00
local placement = args.placement or 'top'
local radius = args.radius or 8
local next_month_button = args.next_month_button or 4
local previous_month_button = args.previous_month_button or 5
local start_sunday = args.start_sunday or false
local week_numbers = args.week_numbers or false
2019-12-16 04:10:22 +01:00
local styles = {}
local function rounded_shape(size)
return function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, size)
2019-12-12 04:05:01 +01:00
end
end
2019-12-16 04:10:22 +01:00
styles.month = {
padding = 4,
bg_color = calendar_themes[theme].bg,
border_width = 0,
}
styles.normal = {
markup = function(t) return t end,
shape = rounded_shape(4)
}
styles.focus = {
fg_color = calendar_themes[theme].focus_date_fg,
bg_color = calendar_themes[theme].focus_date_bg,
markup = function(t) return '<b>' .. t .. '</b>' end,
shape = rounded_shape(4)
}
styles.header = {
fg_color = calendar_themes[theme].header_fg,
bg_color = calendar_themes[theme].bg,
markup = function(t) return '<b>' .. t .. '</b>' end
}
styles.weekday = {
fg_color = calendar_themes[theme].weekday_fg,
bg_color = calendar_themes[theme].bg,
markup = function(t) return '<b>' .. t .. '</b>' end,
}
local function decorate_cell(widget, flag, date)
if flag == 'monthheader' and not styles.monthheader then
flag = 'header'
end
-- highlight only today's day
if flag == 'focus' then
local today = os.date('*t')
2021-06-26 14:32:20 +02:00
if not (today.month == date.month and today.year == date.year) then
2019-12-16 04:10:22 +01:00
flag = 'normal'
end
end
local props = styles[flag] or {}
if props.markup and widget.get_text and widget.set_markup then
widget:set_markup(props.markup(widget:get_text()))
end
-- Change bg color for weekends
local default_bg
if (flag == "normal") then
local d = { year = date.year, month = (date.month or 1), day = (date.day or 1) }
local weekday = tonumber(os.date('%w', os.time(d)))
default_bg = (weekday == 0 or weekday == 6)
and calendar_themes[theme].weekend_day_bg
or calendar_themes[theme].bg
end
2019-12-16 04:10:22 +01:00
local ret = wibox.widget {
{
2019-12-16 04:10:22 +01:00
{
widget,
halign = 'center',
widget = wibox.container.place
},
margins = (props.padding or 2) + (props.border_width or 0),
widget = wibox.container.margin
},
2019-12-16 04:10:22 +01:00
shape = props.shape,
shape_border_color = props.border_color or '#000000',
shape_border_width = props.border_width or 0,
fg = props.fg_color or calendar_themes[theme].fg,
bg = props.bg_color or default_bg,
2019-12-16 04:10:22 +01:00
widget = wibox.container.background
}
return ret
end
local cal = wibox.widget {
date = os.date('*t'),
font = beautiful.get_font(),
fn_embed = decorate_cell,
long_weekdays = true,
start_sunday = start_sunday,
week_numbers = week_numbers,
2019-12-16 04:10:22 +01:00
widget = wibox.widget.calendar.month
2019-12-12 04:05:01 +01:00
}
2019-12-16 04:10:22 +01:00
local popup = awful.popup {
ontop = true,
visible = false,
shape = rounded_shape(radius),
2019-12-16 04:10:22 +01:00
offset = { y = 5 },
border_width = 1,
border_color = calendar_themes[theme].border,
widget = cal
}
2024-11-09 19:57:48 +01:00
local auto_hide_timer = gears.timer({
timeout = user_args.timeout or 2,
single_shot = true,
callback = function()
calendar_widget.toggle()
end,
})
popup:connect_signal("mouse::leave", function()
2024-11-09 19:57:48 +01:00
if user_args.auto_hide then
auto_hide_timer:again()
end
end)
popup:connect_signal("mouse::enter", function()
auto_hide_timer:stop()
end)
2019-12-16 04:10:22 +01:00
popup:buttons(
awful.util.table.join(
awful.button({}, next_month_button, function()
2019-12-16 04:10:22 +01:00
local a = cal:get_date()
a.month = a.month + 1
cal:set_date(nil)
cal:set_date(a)
popup:set_widget(cal)
end),
awful.button({}, previous_month_button, function()
2019-12-16 04:10:22 +01:00
local a = cal:get_date()
a.month = a.month - 1
cal:set_date(nil)
cal:set_date(a)
popup:set_widget(cal)
end)
)
)
function calendar_widget.toggle()
if popup.visible then
2024-08-03 23:53:50 +02:00
auto_hide_timer:stop()
2019-12-16 04:10:22 +01:00
-- to faster render the calendar refresh it and just hide
cal:set_date(nil) -- the new date is not set without removing the old one
cal:set_date(os.date('*t'))
popup:set_widget(nil) -- just in case
popup:set_widget(cal)
popup.visible = not popup.visible
2019-12-13 04:27:12 +01:00
else
2019-12-16 04:10:22 +01:00
if placement == 'top' then
awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() })
elseif placement == 'top_right' then
awful.placement.top_right(popup, { margins = { top = 30, right = 10}, parent = awful.screen.focused() })
2022-05-24 16:49:32 +02:00
elseif placement == 'top_left' then
awful.placement.top_left(popup, { margins = { top = 30, left = 10}, parent = awful.screen.focused() })
2019-12-16 04:10:22 +01:00
elseif placement == 'bottom_right' then
2020-12-06 20:47:40 +01:00
awful.placement.bottom_right(popup, { margins = { bottom = 30, right = 10},
parent = awful.screen.focused() })
2022-05-24 16:49:32 +02:00
elseif placement == 'bottom_left' then
awful.placement.bottom_left(popup, { margins = { bottom = 30, left = 10},
parent = awful.screen.focused() })
2019-12-16 04:10:22 +01:00
else
awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() })
end
popup.visible = true
if user_args.auto_hide then
auto_hide_timer:start()
end
2019-12-16 04:10:22 +01:00
2019-12-13 04:27:12 +01:00
end
2019-12-16 04:10:22 +01:00
end
2019-12-12 04:05:01 +01:00
2019-12-16 04:10:22 +01:00
return calendar_widget
2019-12-12 04:05:01 +01:00
2019-12-13 04:27:12 +01:00
end
2019-12-16 04:10:22 +01:00
return setmetatable(calendar_widget, { __call = function(_, ...)
return worker(...)
end })