]> git.madduck.net Git - etc/awesome.git/blob - widget/cal.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

47e91a979889739046d314d4251da11a2f056458
[etc/awesome.git] / widget / cal.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2018, Luca CPZ
5
6 --]]
7
8 local helpers  = require("lain.helpers")
9 local markup   = require("lain.util.markup")
10 local awful    = require("awful")
11 local naughty  = require("naughty")
12 local floor    = math.floor
13 local os       = os
14 local pairs    = pairs
15 local string   = string
16 local tconcat  = table.concat
17 local tonumber = tonumber
18 local tostring = tostring
19
20 -- Calendar notification
21 -- lain.widget.cal
22 local function factory(args)
23     args = args or {}
24     local cal = {
25         attach_to           = args.attach_to or {},
26         week_start          = args.week_start or 2,
27         three               = args.three or false,
28         followtag           = args.followtag or false,
29         icons               = args.icons or helpers.icons_dir .. "cal/white/",
30         notification_preset = args.notification_preset or {
31             font = "Monospace 10", fg = "#FFFFFF", bg = "#000000"
32         }
33     }
34
35     function cal.build(month, year)
36         local current_month, current_year = tonumber(os.date("%m")), tonumber(os.date("%Y"))
37         local is_current_month = (not month or not year) or (month == current_month and year == current_year)
38         local today = is_current_month and tonumber(os.date("%d")) -- otherwise nil and not highlighted
39         local t = os.time { year = year or current_year, month = month and month+1 or current_month+1, day = 0 }
40         local d = os.date("*t", t)
41         local mth_days, st_day, this_month = d.day, (d.wday-d.day-cal.week_start+1)%7, os.date("%B %Y", t)
42         local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - this_month:len())/2)), markup.bold(this_month)) }
43         for x = 0,6 do notifytable[#notifytable+1] = os.date("%a ", os.time { year=2006, month=1, day=x+cal.week_start }) end
44         notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", st_day*4))
45         for x = 1,mth_days do
46             local strx = x ~= today and x or markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. " ")
47             strx = string.format("%s%s", string.rep(" ", 3 - tostring(x):len()), strx)
48             notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+st_day)%7==0 and x ~= mth_days and "\n" or "")
49         end
50         if string.len(cal.icons or "") > 0 and today then cal.icon = cal.icons .. today .. ".png" end
51         cal.month, cal.year = d.month, d.year
52         return notifytable
53     end
54
55     function cal.getdate(month, year, offset)
56         if not month or not year then
57             month = tonumber(os.date("%m"))
58             year  = tonumber(os.date("%Y"))
59         end
60
61         month = month + offset
62
63         while month > 12 do
64             month = month - 12
65             year = year + 1
66         end
67
68         while month < 1 do
69             month = month + 12
70             year = year - 1
71         end
72
73         return month, year
74     end
75
76     function cal.hide()
77         if not cal.notification then return end
78         naughty.destroy(cal.notification)
79         cal.notification = nil
80     end
81
82     function cal.show(timeout, month, year, scr)
83         cal.notification_preset.text = tconcat(cal.build(month, year))
84
85         if cal.three then
86             local current_month, current_year = cal.month, cal.year
87             local prev_month, prev_year = cal.getdate(cal.month, cal.year, -1)
88             local next_month, next_year = cal.getdate(cal.month, cal.year,  1)
89             cal.notification_preset.text = string.format("%s\n\n%s\n\n%s",
90             tconcat(cal.build(prev_month, prev_year)), cal.notification_preset.text,
91             tconcat(cal.build(next_month, next_year)))
92             cal.month, cal.year = current_month, current_year
93         end
94
95         cal.hide()
96         cal.notification = naughty.notify {
97             preset  = cal.notification_preset,
98             screen  = cal.followtag and awful.screen.focused() or scr or 1,
99             icon    = cal.icon,
100             timeout = timeout or cal.notification_preset.timeout or 5
101         }
102     end
103
104     function cal.hover_on() cal.show(0) end
105     function cal.move(offset)
106         local offset = offset or 0
107         cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
108         cal.show(0, cal.month, cal.year)
109     end
110     function cal.prev() cal.move(-1) end
111     function cal.next() cal.move( 1) end
112
113     function cal.attach(widget)
114         widget:connect_signal("mouse::enter", cal.hover_on)
115         widget:connect_signal("mouse::leave", cal.hide)
116         widget:buttons(awful.util.table.join(
117                     awful.button({}, 1, cal.prev),
118                     awful.button({}, 3, cal.next),
119                     awful.button({}, 2, cal.hover_on),
120                     awful.button({}, 5, cal.prev),
121                     awful.button({}, 4, cal.next)))
122     end
123
124     for _, widget in pairs(cal.attach_to) do cal.attach(widget) end
125
126     return cal
127 end
128
129 return factory