diff --git a/calendar-widget/README.md b/calendar-widget/README.md index fa1b761..be1dd84 100644 --- a/calendar-widget/README.md +++ b/calendar-widget/README.md @@ -1,28 +1,54 @@ # Calendar Widget -Calendar widget for Awesome WM - slightly improved version of the `wibox.widget.calendar`. Also supports mouse scroll up/down in order ot switch month - scroll up - shows next month, scroll down - previous. +Calendar widget for Awesome WM - slightly improved version of the `wibox.widget.calendar`. -Top center placement: +## Features -![calendar_top](./calendar_top.png) + - mouse support: scroll up - shows next month, scroll down - previous + - themes: + + nord (default): -Top right placement: + ![nord_theme](./nord.png) -![calendar_top_right](./calendar_top_right.png) + outrun: -The placement is setup in theme.lua by `calendar_placement` variable, currently supported `top` (default), `top_right`, `bottom_right`. + ![outrun_theme](./outrun.png) -# How to use + - setup widget placement + + top center - in case you clock is centered: + + ![calendar_top](./calendar_top.png) + + top right - for default awesome config: + + ![calendar_top_right](./calendar_top_right.png) + + bottom right - in case your wibar at the bottom: + + ![calendar_bottom_right](./calendar_bottom_right.png) + + +## How to use This widget needs an 'anchor' - another widget which triggers visibility of the calendar. Default `mytextclock` is the perfect candidate! ```lua local calendar_widget = require("awesome-wm-widgets.calendar-widget.calendar") -- ... +-- {{{ Wibar -- Create a textclock widget mytextclock = wibox.widget.textclock() -mytextclock:connect_signal("button::press", +-- default +cw = calendar_widget() +-- or customized +cw = calendar_widget({ + theme = 'outrun', + placement = 'bottom_right' +}) +mytextclock:connect_signal("button::press", function(_, _, _, button) - if button == 1 then calendar_widget.toggle() end + if button == 1 then cw.toggle() end end) -``` \ No newline at end of file +``` diff --git a/calendar-widget/calendar.lua b/calendar-widget/calendar.lua index f612e09..b98b3a4 100644 --- a/calendar-widget/calendar.lua +++ b/calendar-widget/calendar.lua @@ -15,148 +15,183 @@ local gears = require("gears") local calendar_widget = {} -local styles = {} -local function rounded_shape(size) - return function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, size) - end -end +local function worker(args) -styles.month = { - padding = 4, - bg_color = '#2E3440', - border_width = 0, -} + 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' + } + } + -styles.normal = { - markup = function(t) return t end, - shape = rounded_shape(4) -} + local args = args or {} -styles.focus = { - fg_color = '#000000', - bg_color = '#88C0D0', - markup = function(t) return '' .. t .. '' end, - shape = rounded_shape(4) -} + local theme = args.theme or 'nord' + local placement = args.placement or 'top' -styles.header = { - fg_color = '#E5E9F0', - markup = function(t) return '' .. t .. '' end, - bg_color = '#2E3440' -} - -styles.weekday = { - fg_color = '#88C0D0', - markup = function(t) return '' .. t .. '' end, - bg_color = '#2E3440', -} - -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') - if today.month ~= date.month then - flag = 'normal' + local styles = {} + local function rounded_shape(size) + return function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, size) 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 d = { year = date.year, month = (date.month or 1), day = (date.day or 1) } - local weekday = tonumber(os.date('%w', os.time(d))) - local default_bg = (weekday == 0 or weekday == 6) and '#3B4252' or '#2E3440' - local ret = wibox.widget { - { - { - widget, - halign = 'center', - widget = wibox.container.place - }, - margins = (props.padding or 2) + (props.border_width or 0), - widget = wibox.container.margin - }, - shape = props.shape, - shape_border_color = props.border_color or '#b9214f', - shape_border_width = props.border_width or 0, - fg = props.fg_color or '#D8DEE9', - bg = props.bg_color or default_bg, - widget = wibox.container.background + styles.month = { + padding = 4, + bg_color = calendar_themes[theme].bg, + border_width = 0, } - return ret -end + styles.normal = { + markup = function(t) return t end, + shape = rounded_shape(4) + } -local cal = wibox.widget { - date = os.date('*t'), - font = beautiful.get_font(), - fn_embed = decorate_cell, - long_weekdays = true, - widget = wibox.widget.calendar.month -} + styles.focus = { + fg_color = calendar_themes[theme].focus_date_fg, + bg_color = calendar_themes[theme].focus_date_bg, + markup = function(t) return '' .. t .. '' end, + shape = rounded_shape(4) + } -local popup = awful.popup { - ontop = true, - visible = false, - shape = gears.shape.rounded_rect, - preferred_positions = top, - offset = { y = 5 }, - border_width = 1, - border_color = '#4C566A', - widget = cal -} + styles.header = { + fg_color = calendar_themes[theme].header_fg, + bg_color = calendar_themes[theme].bg, + markup = function(t) return '' .. t .. '' end + } -popup:buttons( - awful.util.table.join( - awful.button({}, 4, function() - 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({}, 5, function() - local a = cal:get_date() - a.month = a.month - 1 - cal:set_date(nil) - cal:set_date(a) - popup:set_widget(cal) - end) - ) -) + styles.weekday = { + fg_color = calendar_themes[theme].weekday_fg, + bg_color = calendar_themes[theme].bg, + markup = function(t) return '' .. t .. '' end, + } -function calendar_widget.toggle() - - if popup.visible then - -- 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 - else - if not beautiful.calendar_placement then - awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() }) - elseif beautiful.calendar_placement == 'top' then - awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() }) - elseif beautiful.calendar_placement == 'top_right' then - awful.placement.top_right(popup, { margins = { top = 30, right = 10}, parent = awful.screen.focused() }) - elseif beautiful.calendar_placement == 'bottom_right' then - awful.placement.bottom_right(popup, { margins = { bottom = 20, right = 10}, parent = awful.screen.focused() }) - else - awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() }) + local function decorate_cell(widget, flag, date) + if flag == 'monthheader' and not styles.monthheader then + flag = 'header' end - popup.visible = true + -- highlight only today's day + if flag == 'focus' then + local today = os.date('*t') + if today.month ~= date.month then + 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 d = { year = date.year, month = (date.month or 1), day = (date.day or 1) } + local weekday = tonumber(os.date('%w', os.time(d))) + local default_bg = (weekday == 0 or weekday == 6) and calendar_themes[theme].weekend_day_bg or calendar_themes[theme].bg + local ret = wibox.widget { + { + { + widget, + halign = 'center', + widget = wibox.container.place + }, + margins = (props.padding or 2) + (props.border_width or 0), + widget = wibox.container.margin + }, + 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, + 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, + widget = wibox.widget.calendar.month + } + + local popup = awful.popup { + ontop = true, + visible = false, + shape = gears.shape.rounded_rect, + preferred_positions = top, + offset = { y = 5 }, + border_width = 1, + border_color = calendar_themes[theme].border, + widget = cal + } + + popup:buttons( + awful.util.table.join( + awful.button({}, 4, function() + 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({}, 5, function() + 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 + -- 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 + else + 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() }) + elseif placement == 'bottom_right' then + awful.placement.bottom_right(popup, { margins = { bottom = 30, right = 10}, parent = awful.screen.focused() }) + else + awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() }) + end + + popup.visible = true + + end + end + + return calendar_widget + end -return calendar_widget +return setmetatable(calendar_widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/calendar-widget/calendar_bottom_right.png b/calendar-widget/calendar_bottom_right.png new file mode 100644 index 0000000..2bc2e82 Binary files /dev/null and b/calendar-widget/calendar_bottom_right.png differ diff --git a/calendar-widget/nord.png b/calendar-widget/nord.png new file mode 100644 index 0000000..94f9f7e Binary files /dev/null and b/calendar-widget/nord.png differ diff --git a/calendar-widget/outrun.png b/calendar-widget/outrun.png new file mode 100644 index 0000000..d59c123 Binary files /dev/null and b/calendar-widget/outrun.png differ