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:

widget.cal: add options for displaying 3 months spanning the date
authorLuca CPZ <luca.cpz@gmail.com>
Fri, 14 Sep 2018 18:21:42 +0000 (20:21 +0200)
committerLuca CPZ <luca.cpz@gmail.com>
Fri, 14 Sep 2018 18:21:42 +0000 (20:21 +0200)
widget/cal.lua

index 7a81c68924fcc76f77e1d1924f03766b91cc38cb..326dc00e203c67fd307f6b7acce41c8a3595c82d 100644 (file)
@@ -11,8 +11,8 @@ local awful    = require("awful")
 local naughty  = require("naughty")
 local floor    = math.floor
 local os       = os
+local pairs    = pairs
 local string   = string
-local ipairs   = ipairs
 local tconcat  = table.concat
 local tonumber = tonumber
 local tostring = tostring
@@ -22,8 +22,9 @@ local tostring = tostring
 local function factory(args)
     args = args or {}
     local cal = {
-        weekStart           = args.weekStart or 2,
         attach_to           = args.attach_to or {},
+        week_start          = args.week_start or 2,
+        three               = args.three or false,
         followtag           = args.followtag or false,
         icons               = args.icons or helpers.icons_dir .. "cal/white/",
         notification_preset = args.notification_preset or {
@@ -31,60 +32,85 @@ local function factory(args)
         }
     }
 
-    function cal.hide()
-        if not cal.notification then return end
-        naughty.destroy(cal.notification)
-        cal.notification = nil
-    end
-
-    function cal.show(timeout, month, year)
+    function cal.build(month, year)
         local current_month, current_year = tonumber(os.date("%m")), tonumber(os.date("%Y"))
         local is_current_month = (not month or not year) or (month == current_month and year == current_year)
         local today = is_current_month and tonumber(os.date("%d")) -- otherwise nil and not highlighted
         local t = os.time { year = year or current_year, month = month and month+1 or current_month+1, day = 0 }
         local d = os.date("*t", t)
-        local mthDays, stDay, cmonth = d.day, (d.wday-d.day-cal.weekStart+1)%7, os.date("%B %Y", t)
-        local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - cmonth:len())/2)), markup.bold(cmonth)) }
-        for x = 0,6 do notifytable[#notifytable+1] = os.date("%a ", os.time { year=2006, month=1, day=x+cal.weekStart }) end
-        notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", stDay*4))
-        for x = 1,mthDays do
+        local mth_days, st_day, this_month = d.day, (d.wday-d.day-cal.week_start+1)%7, os.date("%B %Y", t)
+        local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - this_month:len())/2)), markup.bold(this_month)) }
+        for x = 0,6 do notifytable[#notifytable+1] = os.date("%a ", os.time { year=2006, month=1, day=x+cal.week_start }) end
+        notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", st_day*4))
+        for x = 1,mth_days do
             local strx = x ~= today and x or markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. " ")
             strx = string.format("%s%s", string.rep(" ", 3 - tostring(x):len()), strx)
-            notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+stDay)%7==0 and x ~= mthDays and "\n" or "")
+            notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+st_day)%7==0 and x ~= mth_days and "\n" or "")
+        end
+        cal.month, cal.year = d.month, d.year
+        return notifytable
+    end
+
+    function cal.getdate(month, year, offset)
+        if not month or not year then
+            month = tonumber(os.date("%m"))
+            year  = tonumber(os.date("%Y"))
+        end
+
+        month = month + offset
+
+        while month > 12 do
+            month = month - 12
+            year = year + 1
+        end
+
+        while month < 1 do
+            month = month + 12
+            year = year - 1
+        end
+
+        return month, year
+    end
+
+    function cal.hide()
+        if not cal.notification then return end
+        naughty.destroy(cal.notification)
+        cal.notification = nil
+    end
+
+    function cal.show(timeout, month, year)
+        cal.notification_preset.text = tconcat(cal.build(month, year))
+
+        if cal.three then
+            local current_month, current_year = cal.month, cal.year
+            local prev_month, prev_year = cal.getdate(cal.month, cal.year, -1)
+            local next_month, next_year = cal.getdate(cal.month, cal.year,  1)
+            cal.notification_preset.text = string.format("%s\n\n%s\n\n%s",
+            tconcat(cal.build(prev_month, prev_year)), cal.notification_preset.text,
+            tconcat(cal.build(next_month, next_year)))
+            cal.month, cal.year = current_month, current_year
         end
 
-        cal.notification_preset.text = tconcat(notifytable)
         cal.hide()
         cal.notification = naughty.notify {
             preset  = cal.notification_preset,
             icon    = cal.icon,
             timeout = timeout or cal.notification_preset.timeout or 5
         }
-        cal.month, cal.year = d.month, d.year
     end
 
     function cal.hover_on() cal.show(0) end
-    function cal.hover_off() cal.hide() end
-    function cal.prev()
-        cal.month = cal.month - 1
-        if cal.month == 0 then
-            cal.month = 12
-            cal.year = cal.year - 1
-        end
-        cal.show(0, cal.month, cal.year)
-    end
-    function cal.next()
-        cal.month = cal.month + 1
-        if cal.month == 13 then
-            cal.month = 1
-            cal.year = cal.year + 1
-        end
+    function cal.move(offset)
+        local offset = offset or 0
+        cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
         cal.show(0, cal.month, cal.year)
     end
+    function cal.prev() cal.move(-1) end
+    function cal.next() cal.move( 1) end
 
     function cal.attach(widget)
         widget:connect_signal("mouse::enter", cal.hover_on)
-        widget:connect_signal("mouse::leave", cal.hover_off)
+        widget:connect_signal("mouse::leave", cal.hide)
         widget:buttons(awful.util.table.join(
                     awful.button({}, 1, cal.prev),
                     awful.button({}, 3, cal.next),
@@ -93,7 +119,7 @@ local function factory(args)
                     awful.button({}, 4, cal.next)))
     end
 
-    for _, widget in ipairs(cal.attach_to) do cal.attach(widget) end
+    for _, widget in pairs(cal.attach_to) do cal.attach(widget) end
 
     return cal
 end