]> 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:

lain.imap: various improvements
[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)
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             icon    = cal.icon,
99             timeout = timeout or cal.notification_preset.timeout or 5
100         }
101     end
102
103     function cal.hover_on() cal.show(0) end
104     function cal.move(offset)
105         local offset = offset or 0
106         cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
107         cal.show(0, cal.month, cal.year)
108     end
109     function cal.prev() cal.move(-1) end
110     function cal.next() cal.move( 1) end
111
112     function cal.attach(widget)
113         widget:connect_signal("mouse::enter", cal.hover_on)
114         widget:connect_signal("mouse::leave", cal.hide)
115         widget:buttons(awful.util.table.join(
116                     awful.button({}, 1, cal.prev),
117                     awful.button({}, 3, cal.next),
118                     awful.button({}, 2, cal.hover_on),
119                     awful.button({}, 5, cal.prev),
120                     awful.button({}, 4, cal.next)))
121     end
122
123     for _, widget in pairs(cal.attach_to) do cal.attach(widget) end
124
125     return cal
126 end
127
128 return factory