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

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