Calendar widget

From awesome
Jump to: navigation, search

Contents

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('<span font_desc="%s">%s</span>', "monospace", displayMonth(calendar[1], calendar[2], 2))
end

timetextbox.mouse_enter = function ()
    local month, year = os.date('%m'), os.date('%Y')
    calendar = { month, year, 
                naughty.notify({
                    text = string.format('<span font_desc="%s">%s</span>', "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),
    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 = "<u>" .. d .. "</u>"
		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('<span font_desc="%s">%s</span>', "monospace", displayMonth(calendar[1], calendar[2], 2))
end

mytextbox:add_signal('mouse::enter', function ()
	local month, year = os.date('%m'), os.date('%Y')
	calendar = { month, year, 
	naughty.notify({
		text = string.format('<span font_desc="%s">%s</span>', "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({ }, 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) <Duck@DuckCorp.org> (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 = "<u>%s</u>"

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('<span font_desc="%s">%s</span>', "monospace", displayMonth(calendar[1], calendar[2], 2))
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('<span font_desc="%s">%s</span>', "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({ }, 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, "<span color='green'>%s</span>")

Duck 21:16, 29 December 2009 (UTC)

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)

Personal tools