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

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