Calendar widget

Original Version
I've created a simple calendar extention to the normal time widget (mytextbox), using naughty. See my blog entry for details.

--Bzed 01:31, 23 February 2009 (UTC)

Horizontal view with week (for 3.3)
Base on the original work, the following code propose a horizontal view

function displayMonth(month,year,weekStart) local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1 local d=os.date("*t",t) local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7

print(mthDays .."\n" .. stDay) local lines = "   "

for x=0,6 do       lines = lines .. os.date("%a ",os.time{year=2006,month=1,day=x+wkSt}) end

lines = lines .. "\n" .. os.date(" %V",os.time{year=year,month=month,day=1})

local writeLine = 1 while writeLine < (stDay + 1) do       lines = lines .. "   "        writeLine = writeLine + 1 end

for x=1,mthDays do       if writeLine == 8 then writeLine = 1 lines = lines .. "\n" .. os.date(" %V",os.time{year=year,month=month,day=x}) end if (#(tostring(x)) == 1) then x = " " .. x       end lines = lines .. " " .. x        writeLine = writeLine + 1 end local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1}) --header = string.rep(" ", math.floor(((#(lines)) - #header) / 2 )) .. header

return header .. "\n" .. lines end

local calendar = {} function switchNaughtyMonth(switchMonths) if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = calendar[1] + swMonths calendar[3].box.widgets[2].text = string.format('%s ', "monospace", displayMonth(calendar[1], calendar[2], 2)) end

function switchNaughtyGoToToday if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = os.date("*t").month calendar[2] = os.date("*t").year switchNaughtyMonth(0) end

timetextbox.mouse_enter = function local month, year = os.date('%m'), os.date('%Y') calendar = { month, year, naughty.notify({                   text = string.format('%s ', "monospace", displayMonth(month, year, 2)),                    timeout = 0, hover_timeout = 0.5,                    width = 270, screen = mouse.screen                }) } end mytextbox.mouse_leave = function naughty.destroy(calendar[3]) end

mytextbox:buttons({   button({ }, 1, function switchNaughtyMonth(-1) end),   awful.button({ }, 2, switchNaughtyGoToToday),    button({ }, 3, function switchNaughtyMonth(1) end),   button({ }, 4, function switchNaughtyMonth(-1) end),   button({ }, 5, function switchNaughtyMonth(1) end),   button({ 'Shift' }, 1, function switchNaughtyMonth(-12) end),   button({ 'Shift' }, 3, function switchNaughtyMonth(12) end),   button({ 'Shift' }, 4, function switchNaughtyMonth(-12) end),   button({ 'Shift' }, 5, function switchNaughtyMonth(12) end) })

Widget for 3.4
Based on previous code, this one works in 3.4. And as a minor improvement, underlines current day.

function displayMonth(month,year,weekStart) local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1 local d=os.date("*t",t) local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7

print(mthDays .."\n" .. stDay) local lines = "   "

for x=0,6 do lines = lines .. os.date("%a ",os.time{year=2006,month=1,day=x+wkSt}) end

lines = lines .. "\n" .. os.date(" %V",os.time{year=year,month=month,day=1})

local writeLine = 1 while writeLine < (stDay + 1) do lines = lines .. "   "		writeLine = writeLine + 1 end

for d=1,mthDays do		local x = d		local t = os.time{year=year,month=month,day=d} if writeLine == 8 then writeLine = 1 lines = lines .. "\n" .. os.date(" %V",t) end if os.date("%Y-%m-%d") == os.date("%Y-%m-%d", t) then x = " " .. d .. " "		end if (#(tostring(d)) == 1) then x = " " .. x		end lines = lines .. " " .. x		writeLine = writeLine + 1 end local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1})

return header .. "\n" .. lines end

local calendar = {} function switchNaughtyMonth(switchMonths) if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = calendar[1] + swMonths calendar[3].box.widgets[2].text = string.format('%s ', "monospace", displayMonth(calendar[1], calendar[2], 2)) end

function switchNaughtyGoToToday if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = os.date("*t").month calendar[2] = os.date("*t").year switchNaughtyMonth(0) end

mytextbox:add_signal('mouse::enter', function 	local month, year = os.date('%m'), os.date('%Y')	calendar = { month, year, 	naughty.notify({ text = string.format('%s ', "monospace", displayMonth(month, year, 2)), timeout = 0, hover_timeout = 0.5, screen = mouse.screen }) } end) mytextbox:add_signal('mouse::leave', function naughty.destroy(calendar[3]) end)

mytextbox:buttons(awful.util.table.join( awful.button({ }, 1, function	switchNaughtyMonth(-1) end), awful.button({ }, 2, switchNaughtyGoToToday), awful.button({ }, 3, function	switchNaughtyMonth(1) end), awful.button({ }, 4, function	switchNaughtyMonth(-1) end), awful.button({ }, 5, function	switchNaughtyMonth(1) end), awful.button({ 'Shift' }, 1, function	switchNaughtyMonth(-12) end), awful.button({ 'Shift' }, 3, function	switchNaughtyMonth(12) end), awful.button({ 'Shift' }, 4, function	switchNaughtyMonth(-12) end), awful.button({ 'Shift' }, 5, function	switchNaughtyMonth(12) end) ))

Module for 3.4
Here is a modified version of the latest code above from Bzed. It is a simple module which can attach a calendar to any widget.

Copy the following code into 'calendar2.lua' in your config directory: -- original code made by Bzed and published on http://awesome.naquadah.org/wiki/Calendar_widget -- modified by Marc Dequènes (Duck)  (2009-12-29), under the same licence, -- and with the following changes: --  + transformed to module --  + the current day formating is customizable

local string = string --local print = print local tostring = tostring local os = os local capi = { mouse = mouse, screen = screen } local awful = require("awful") local naughty = require("naughty") module("calendar2")

local calendar = {} local current_day_format = " %s "

function displayMonth(month,year,weekStart) local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1 local d=os.date("*t",t) local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7

--print(mthDays .."\n" .. stDay) local lines = "   "

for x=0,6 do               lines = lines .. os.date("%a ",os.time{year=2006,month=1,day=x+wkSt}) end

lines = lines .. "\n" .. os.date(" %V",os.time{year=year,month=month,day=1})

local writeLine = 1 while writeLine < (stDay + 1) do               lines = lines .. "   "                writeLine = writeLine + 1 end

for d=1,mthDays do               local x = d                local t = os.time{year=year,month=month,day=d} if writeLine == 8 then writeLine = 1 lines = lines .. "\n" .. os.date(" %V",t) end if os.date("%Y-%m-%d") == os.date("%Y-%m-%d", t) then x = string.format(current_day_format, d)               end if (#(tostring(d)) == 1) then x = " " .. x               end lines = lines .. " " .. x                writeLine = writeLine + 1 end local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1})

return header .. "\n" .. lines end

function switchNaughtyMonth(switchMonths) if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = calendar[1] + swMonths calendar[3].box.widgets[2].text = string.format('%s ', "monospace", displayMonth(calendar[1], calendar[2], 2)) end

function switchNaughtyGoToToday if (#calendar < 3) then return end local swMonths = switchMonths or 1 calendar[1] = os.date("*t").month calendar[2] = os.date("*t").year switchNaughtyMonth(0) end

function addCalendarToWidget(mywidget, custom_current_day_format) if custom_current_day_format then current_day_format = custom_current_day_format end

mywidget:add_signal('mouse::enter', function        local month, year = os.date('%m'), os.date('%Y')        calendar = { month, year,        naughty.notify({ text = string.format('%s ', "monospace", displayMonth(month, year, 2)), timeout = 0, hover_timeout = 0.5, screen = capi.mouse.screen }) }  end) mywidget:add_signal('mouse::leave', function naughty.destroy(calendar[3]) end)

mywidget:buttons(awful.util.table.join( awful.button({ }, 1, function       switchNaughtyMonth(-1)    end), awful.button({ }, 2, switchNaughtyGoToToday), awful.button({ }, 3, function       switchNaughtyMonth(1)    end), awful.button({ }, 4, function       switchNaughtyMonth(-1)    end), awful.button({ }, 5, function       switchNaughtyMonth(1)    end), awful.button({ 'Shift' }, 1, function       switchNaughtyMonth(-12)    end), awful.button({ 'Shift' }, 3, function       switchNaughtyMonth(12)    end), awful.button({ 'Shift' }, 4, function       switchNaughtyMonth(-12)    end), awful.button({ 'Shift' }, 5, function       switchNaughtyMonth(12)    end) )) end

And you can use it like this: require('calendar2')

calendar2.addCalendarToWidget(datewidget)

If you want the current day to be in green color instead of underlined: calendar2.addCalendarToWidget(datewidget, " %s ")

Duck 21:16, 29 December 2009 (UTC)

Use the middle button to switch back to the current month.

Steelman 21:26, 18 May 2012 (CEST)

Module for 3.4 using tooltip
I modify the calendar2 module to using awful.tooltip instead of naughty.

So it don't get in conflict with regular desktop notifications.

Also it is possible to add this tooltip to several widgets.

You can get the code from github. (install instruction included)