X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/91882180214426b521217649e40adbb0055ed71e..448d0b1be999e40f7e84697bd25de8d1f6ac9884:/widget/cal.lua?ds=inline

diff --git a/widget/cal.lua b/widget/cal.lua
index 7a81c68..326dc00 100644
--- a/widget/cal.lua
+++ b/widget/cal.lua
@@ -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