calendar_old.lua 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. -- @author cedlemo
  2. local awful = require('awful')
  3. local capi = { screen = screen, mouse = mouse }
  4. local helpers = require('blingbling.helpers')
  5. local text_box = require('blingbling.text_box')
  6. local superproperties = require('blingbling.superproperties')
  7. local math = math
  8. local util = require('awful.util')
  9. local wibox = require('wibox')
  10. local pairs = pairs
  11. local layout = require('wibox.layout')
  12. local calendar = { mt = {} }
  13. local data = setmetatable({}, { __mode = "k" })
  14. ---Calendar widget.
  15. --Show current month user can navigate through previous or next month with two button. The top centered button with current mont string allow user to reload the current month.
  16. --User can get events from remind and taskwarrior and can add their own events handler.
  17. --@module blingbling.calendar
  18. ---Set the style of the previous and next month button.
  19. --@usage mycalendar:set_prev_next_widget_style(style)
  20. --@name set_prev_next_widget_style
  21. --@class function
  22. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  23. ---Set the style of the current date text_box widget.
  24. --@usage mycalendar:set_current_date_widget_style(style)
  25. --@name set_current_date_widget_style
  26. --@class function
  27. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  28. ---Define the style of the cells that contains the week days names.
  29. --@usage mycalendar:set_days_of_week_widget_style(style)
  30. --@name set_days_of_week_widget_style
  31. --@class function
  32. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  33. ---Set the style of the days of the month widget.
  34. --@usage mycalendar:set_days_of_month_widget_style(style)
  35. --@name set_days_of_month_widget_style
  36. --@class function
  37. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  38. ---Define the style of the cells that displays the week number (left column).
  39. --@usage mycalendar:set_weeks_number_widget_style(style)
  40. --@name set_weeks_number_widget_style
  41. --@class function
  42. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  43. ---Set the style of the cell used as a corner between the week days line and the week number column.
  44. --@usage mycalendar:set_corner_widget_style(style)
  45. --@name set_corner_widget_style
  46. --@class function
  47. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  48. ---Define the style used in order to show the current day.
  49. --@usage mycalendar:set_current_day_widget_style(style)
  50. --@name set_current_day_widget_style
  51. --@class function
  52. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  53. ---Define the style used when the mouse pass on a cell (only active is set_link_to_external_calendar(true)).
  54. --@usage mycalendar:set_focus_widget_style(style)
  55. --@name set_focus_widget_style
  56. --@class function
  57. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  58. ---Define the style of the big widget on the right that displays information (current day or external calendar events).
  59. --@usage mycalendar:set_info_cell_style
  60. --@name set_info_cell_style
  61. --@class function
  62. --@param style a table of parameters (see text_box widget in order to find which ones are available)
  63. ---Allow to get information from external calendar.
  64. --@usage mycalendar:set_link_to_external_calendar(boolean)
  65. --@name set_link_to_external_calendar
  66. --@class function
  67. --@param boolean true or false
  68. ---Use a specific locale for the week days.
  69. --@usage mycalendar:set_locale(locale)
  70. --@name set_locale
  71. --@class function
  72. --@param locale a string
  73. ---Add new function in order to get events from external application.
  74. --This method let the taskwarrior and remind links intact and add your founction.
  75. --@name append_function_get_events_from
  76. --@usage mycalendar:append_function_get_events_from(function(day, month, year)
  77. --s="third function ".. " " .. day .. " " .. month .." " ..year
  78. --return s
  79. --end)
  80. --This function display in the menu the string "third function 26 11 2011" for example.
  81. --@class function
  82. --@param my_function a function that you write
  83. ---Add new function in order to get events from external application and remove the existing function.
  84. --@name clear_and_add_function_get_events_from
  85. --@usage mycalendar:clear_and_add_function_get_events_from(my_function)
  86. --@class function
  87. --@param my_function a function that you write
  88. local function apply_style(widget, style)
  89. for k,v in pairs(style) do
  90. if widget['set_'..k] ~= nil and type(widget['set_'..k]) == "function" then
  91. widget['set_' ..k](widget, v)
  92. end
  93. end
  94. end
  95. function show_events(calendarbutton,day_label, month, year, function_index)
  96. local day = tonumber(day_label)
  97. local month = month
  98. local year = year
  99. if function_index == nil then
  100. data[calendarbutton].get_events_function_index = 1
  101. elseif function_index == 1 and data[calendarbutton].get_events_function_index == #data[calendarbutton].get_events_from then
  102. data[calendarbutton].get_events_function_index = 1
  103. elseif function_index == -1 and data[calendarbutton].get_events_function_index == 1 then
  104. data[calendarbutton].get_events_function_index = #data[calendarbutton].get_events_from
  105. else
  106. data[calendarbutton].get_events_function_index = data[calendarbutton].get_events_function_index + function_index
  107. end
  108. local day_events=data[calendarbutton].get_events_from[data[calendarbutton].get_events_function_index](day,month,year)
  109. data[calendarbutton].info:set_text(day_events)
  110. end
  111. local function add_focus(calendarbutton)
  112. data[calendarbutton].next_month.widget:connect_signal("mouse::enter", function() apply_style(data[calendarbutton].next_month.widget,data[calendarbutton].focus_widget_style) end)
  113. data[calendarbutton].next_month.widget:connect_signal("mouse::leave", function() apply_style(data[calendarbutton].next_month.widget,data[calendarbutton].prev_next_widget_style) end)
  114. data[calendarbutton].prev_month.widget:connect_signal("mouse::enter", function() apply_style(data[calendarbutton].prev_month.widget,data[calendarbutton].focus_widget_style) end)
  115. data[calendarbutton].prev_month.widget:connect_signal("mouse::leave", function() apply_style(data[calendarbutton].prev_month.widget,data[calendarbutton].prev_next_widget_style) end)
  116. data[calendarbutton].date.widget:connect_signal("mouse::enter", function() apply_style(data[calendarbutton].date.widget,data[calendarbutton].focus_widget_style) end)
  117. data[calendarbutton].date.widget:connect_signal("mouse::leave", function() apply_style(data[calendarbutton].date.widget,data[calendarbutton].current_date_widget_style) end)
  118. if data[calendarbutton].link_to_external_calendar == true then
  119. --remove all previous handlers :
  120. for i=1,42 do
  121. if data[calendarbutton].month_days_cells[i].focus_handler ~= nil then
  122. data[calendarbutton].month_days_cells[i].widget:disconnect_signal("mouse::enter", data[calendarbutton].month_days_cells[i].focus_handler )
  123. data[calendarbutton].month_days_cells[i].widget:buttons({})
  124. end
  125. end
  126. --get current day cell if we are in current month view
  127. local current_day_cell = tonumber(os.date("%d")) + data[calendarbutton].first_day_widget -1
  128. for i=data[calendarbutton].first_day_widget,data[calendarbutton].last_day_widget -1 do
  129. data[calendarbutton].month_days_cells[i].focus_handler =function()
  130. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].focus_widget_style)
  131. show_events(calendarbutton,i -data[calendarbutton].first_day_widget +1 , data[calendarbutton].month, data[calendarbutton].year)
  132. end
  133. data[calendarbutton].month_days_cells[i].widget:connect_signal("mouse::enter",
  134. data[calendarbutton].month_days_cells[i].focus_handler
  135. )
  136. data[calendarbutton].month_days_cells[i].widget:buttons(util.table.join(
  137. awful.button({ }, 4, function()
  138. show_events(calendarbutton,i -data[calendarbutton].first_day_widget +1 , data[calendarbutton].month, data[calendarbutton].year, 1)
  139. end),
  140. awful.button({ }, 5, function()
  141. show_events(calendarbutton,i -data[calendarbutton].first_day_widget +1 , data[calendarbutton].month, data[calendarbutton].year, -1)
  142. end)
  143. ))
  144. if current_day_cell ~= nil and i == current_day_cell then
  145. data[calendarbutton].month_days_cells[i].widget:connect_signal("mouse::leave",
  146. function()
  147. if tonumber(os.date("%m")) == data[calendarbutton].month and data[calendarbutton].year == tonumber(os.date("%Y")) then
  148. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].current_day_widget_style)
  149. else
  150. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].days_of_month_widget_style)
  151. end
  152. local text_info = nil
  153. if data[calendarbutton].default_info == nil then
  154. text_info = os.date("%A %B %d %Y")
  155. end
  156. if type(data[calendarbutton].default_info) == "string" then
  157. text_info = data[calendarbutton].default_info
  158. end
  159. if type(data[calendarbutton].default_info) == "function" then
  160. text_info = data[calendarbutton].default_info()
  161. end
  162. data[calendarbutton].info:set_text(text_info)
  163. end
  164. )
  165. else
  166. data[calendarbutton].month_days_cells[i].widget:connect_signal("mouse::leave",
  167. function()
  168. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].days_of_month_widget_style)
  169. local text_info = nil
  170. if data[calendarbutton].default_info == nil then
  171. text_info = os.date("%A %B %d %Y")
  172. end
  173. if type(data[calendarbutton].default_info) == "string" then
  174. text_info = data[calendarbutton].default_info
  175. end
  176. if type(data[calendarbutton].default_info) == "function" then
  177. text_info = data[calendarbutton].default_info()
  178. end
  179. data[calendarbutton].info:set_text(text_info)
  180. --data[calendarbutton].info:set_text(data[calendarbutton].default_info or os.date("%A %B %d %Y"))
  181. end
  182. )
  183. end
  184. end
  185. end
  186. end
  187. local function fill_calendar(calendarbutton)
  188. local month_label = os.date("%B", os.time{year=data[calendarbutton].year, month=data[calendarbutton].month, day=01})
  189. data[calendarbutton].date.widget:set_text(month_label .. " " .. data[calendarbutton].year)
  190. local weeks_numbers = helpers.get_ISO8601_weeks_number_of_month(data[calendarbutton].month,data[calendarbutton].year)
  191. for i=1,6 do
  192. data[calendarbutton].weeks_number[i].widget:set_text(weeks_numbers[i])
  193. end
  194. local first_day_of_current_month = 0
  195. --find the first week day of the month it is the number used as start for displaying day in the table data[calendar].days_of_month
  196. local d=os.date('*t',os.time{year=data[calendarbutton].year,month=data[calendarbutton].month,day=01})
  197. --We use Monday as first day of week
  198. first_day_of_current_month = d['wday'] - 1
  199. if first_day_of_current_month == 0 then first_day_of_current_month = 7 end
  200. data[calendarbutton].first_day_widget = first_day_of_current_month
  201. local last_day_of_current_month = tonumber(helpers.get_days_in_month(data[calendarbutton].month, data[calendarbutton].year))
  202. data[calendarbutton].last_day_widget = last_day_of_current_month +first_day_of_current_month
  203. local y=1
  204. for i=1,42 do
  205. if i< first_day_of_current_month then
  206. data[calendarbutton].month_days_cells[i].widget:set_text(util.escape("--"))
  207. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].days_of_month_widget_style)
  208. elseif i>= first_day_of_current_month and i < last_day_of_current_month +first_day_of_current_month then
  209. data[calendarbutton].month_days_cells[i].widget:set_text(y)
  210. --TODO After seeing current month, next or prev month let the current date cell with the style of current date event for different month
  211. --Better if we check that if we are not in current month and set the current day cell to normal color rather than applying normal color to all cell each time
  212. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].days_of_month_widget_style)
  213. y=y+1
  214. else
  215. data[calendarbutton].month_days_cells[i].widget:set_text(util.escape("--"))
  216. apply_style(data[calendarbutton].month_days_cells[i].widget, data[calendarbutton].days_of_month_widget_style)
  217. end
  218. end
  219. --mark current day if it's current month
  220. if tonumber(os.date("%m")) == data[calendarbutton].month and data[calendarbutton].year == tonumber(os.date("%Y")) then
  221. local current_day = tonumber(os.date("%d"))
  222. apply_style(data[calendarbutton].month_days_cells[current_day + first_day_of_current_month -1].widget, data[calendarbutton].current_day_widget_style)
  223. end
  224. --mark events from specific function
  225. if data[calendarbutton].link_to_external_calendar == true then
  226. --TODO get the days events and mark them with a style modification
  227. end
  228. --set current date in the info panel
  229. local text_info = nil
  230. if data[calendarbutton].default_info == nil then
  231. text_info = os.date("%A %B %d %Y")
  232. end
  233. if type(data[calendarbutton].default_info) == "string" then
  234. text_info = data[calendarbutton].default_info
  235. end
  236. if type(data[calendarbutton].default_info) == "function" then
  237. text_info = data[calendarbutton].default_info()
  238. end
  239. data[calendarbutton].info:set_text(text_info)
  240. --data[calendarbutton].info:set_text(data[calendarbutton].default_info or os.date("%A %B %d %Y"))
  241. end
  242. local function reload_and_fill(calendarbutton)
  243. fill_calendar(calendarbutton)
  244. add_focus(calendarbutton)
  245. end
  246. local function see_current_month(calendarbutton)
  247. data[calendarbutton].month = tonumber(os.date("%m"))
  248. data[calendarbutton].year = tonumber(os.date("%Y"))
  249. fill_calendar(calendarbutton)
  250. add_focus(calendarbutton)
  251. end
  252. local function see_prev_month(calendarbutton)
  253. if data[calendarbutton].month == 1 then
  254. data[calendarbutton].month = 12
  255. data[calendarbutton].year = data[calendarbutton].year -1
  256. else
  257. data[calendarbutton].month = data[calendarbutton].month - 1
  258. end
  259. fill_calendar(calendarbutton)
  260. add_focus(calendarbutton)
  261. end
  262. local function see_next_month(calendarbutton)
  263. if data[calendarbutton].month == 12 then
  264. data[calendarbutton].month = 1
  265. data[calendarbutton].year = data[calendarbutton].year +1
  266. else
  267. data[calendarbutton].month = data[calendarbutton].month + 1
  268. end
  269. fill_calendar(calendarbutton)
  270. add_focus(calendarbutton)
  271. end
  272. local function generate_calendar_box(calendarbutton)
  273. data[calendarbutton].title = layout.fixed.horizontal()
  274. --data[calendarbutton].title:fill_space(false)
  275. data[calendarbutton].column = layout.fixed.vertical()
  276. --data[calendarbutton].column:fill_space(true)
  277. data[calendarbutton].week_days_line = layout.flex.horizontal()
  278. --data[calendarbutton].week_days_line:fill_space(true)
  279. data[calendarbutton].week_days_cells = {}
  280. local line_height = 0
  281. local line_width = 0
  282. local max_line_width = 0
  283. local all_lines_height = 0
  284. local w,h =0
  285. local title_line_length = 0
  286. --margins left, right, top, bottom
  287. local ml = 2
  288. local mr = 2
  289. local mt = 2
  290. local mb = 2
  291. --create first line with prev, current date and next widget
  292. data[calendarbutton].date = {}
  293. data[calendarbutton].next_month = {}
  294. data[calendarbutton].prev_month = {}
  295. data[calendarbutton].prev_month.widget = text_box(data[calendarbutton].prev_next_widget_style)
  296. data[calendarbutton].prev_month.widget:set_text(util.escape("<<"))
  297. data[calendarbutton].prev_month.widget:buttons(util.table.join(
  298. awful.button({ }, 1, function()
  299. see_prev_month(calendarbutton)
  300. end)
  301. ))
  302. data[calendarbutton].prev_month.margin = layout.margin(data[calendarbutton].prev_month.widget, ml,mr,mt,mb)
  303. data[calendarbutton].date.widget = text_box(data[calendarbutton].current_date_widget_style)
  304. data[calendarbutton].date.widget:set_text(os.date('%a %b %d, %H:%M'))
  305. data[calendarbutton].date.widget:buttons(util.table.join(
  306. awful.button({ }, 1, function()
  307. see_current_month(calendarbutton)
  308. end)
  309. ))
  310. data[calendarbutton].date.margin = layout.margin(data[calendarbutton].date.widget, ml,mr,mt,mb)
  311. data[calendarbutton].next_month.widget = text_box(data[calendarbutton].prev_next_widget_style)
  312. data[calendarbutton].next_month.widget:set_text(util.escape(">>"))
  313. data[calendarbutton].next_month.widget:buttons(util.table.join(
  314. awful.button({ }, 1, function()
  315. see_next_month(calendarbutton)
  316. end)
  317. ))
  318. data[calendarbutton].next_month.margin = layout.margin(data[calendarbutton].next_month.widget, ml,mr,mt,mb)
  319. --add those 3 widgets and margins in the title line
  320. data[calendarbutton].title:add(data[calendarbutton].prev_month.margin)
  321. data[calendarbutton].title:add(data[calendarbutton].date.margin)
  322. data[calendarbutton].title:add(data[calendarbutton].next_month.margin)
  323. --create the days of week line
  324. line_width = 0
  325. line_height = 0
  326. max_height = 0
  327. max_width =0 --used as reference in order to calculate the width of the wibox
  328. data[calendarbutton].corner = {}
  329. data[calendarbutton].corner.widget = text_box(data[calendarbutton].corner_widget_style)
  330. data[calendarbutton].corner.widget:set_text(util.escape('/'))
  331. data[calendarbutton].corner.margin = layout.margin(data[calendarbutton].corner.widget, ml,mr,mt,mb)
  332. data[calendarbutton].week_days_line:add(data[calendarbutton].corner.margin)
  333. for i=1,7 do
  334. data[calendarbutton].week_days_cells[i] = {}
  335. data[calendarbutton].week_days_cells[i].widget = text_box(data[calendarbutton].days_of_week_widget_style)
  336. data[calendarbutton].week_days_cells[i].widget:set_text(data[calendarbutton].week_days[i])
  337. data[calendarbutton].week_days_cells[i].margin = layout.margin(data[calendarbutton].week_days_cells[i].widget, ml,mr,mt,mb)
  338. w,h = data[calendarbutton].week_days_cells[i].margin:fit(0,0)
  339. max_width = max_width > w and max_width or w
  340. max_height = max_height > h and max_height or h
  341. data[calendarbutton].week_days_line:add(data[calendarbutton].week_days_cells[i].margin)
  342. end
  343. --Now that we have the longer width, we apply it to all the days of week widgets:
  344. data[calendarbutton].corner.widget:set_width(max_width)
  345. data[calendarbutton].corner.widget:set_height(max_height)
  346. for i=1,7 do
  347. data[calendarbutton].week_days_cells[i].widget:set_width(max_width)
  348. data[calendarbutton].week_days_cells[i].widget:set_height(max_height)
  349. end
  350. -- And we can calculate and set the width for the next, prev and current date widget:
  351. data[calendarbutton].date.widget:set_width(max_width *4)
  352. data[calendarbutton].date.widget:set_height(max_height)
  353. w,h = data[calendarbutton].date.margin:fit(0,0)
  354. local remains = math.floor((math.ceil((max_width + ml + mr )* 8 ) - (w + (ml+mr)*2))/2)
  355. data[calendarbutton].prev_month.widget:set_width(remains )
  356. data[calendarbutton].prev_month.widget:set_height(max_height )
  357. data[calendarbutton].next_month.widget:set_width(remains )
  358. data[calendarbutton].next_month.widget:set_height(max_height )
  359. --We create the month day cells
  360. data[calendarbutton].month_days_cells={}
  361. for i=01,42 do
  362. data[calendarbutton].month_days_cells[i]={}
  363. data[calendarbutton].month_days_cells[i].widget = text_box(data[calendarbutton].days_of_month_widget_style)
  364. data[calendarbutton].month_days_cells[i].widget:set_text(i)
  365. data[calendarbutton].month_days_cells[i].widget:set_width(max_width)
  366. data[calendarbutton].month_days_cells[i].widget:set_height(max_height)
  367. data[calendarbutton].month_days_cells[i].margin = layout.margin(data[calendarbutton].month_days_cells[i].widget, ml,mr,mt,mb)
  368. end
  369. --Week numbers
  370. data[calendarbutton].weeks_number={}
  371. for i=1,6 do
  372. data[calendarbutton].weeks_number[i]={}
  373. data[calendarbutton].weeks_number[i].widget = text_box(data[calendarbutton].weeks_number_widget_style)
  374. data[calendarbutton].weeks_number[i].widget:set_text(i)
  375. data[calendarbutton].weeks_number[i].widget:set_width(max_width)
  376. data[calendarbutton].weeks_number[i].widget:set_height(max_height)
  377. data[calendarbutton].weeks_number[i].margin = layout.margin(data[calendarbutton].weeks_number[i].widget,ml,mr,mt,mb)
  378. end
  379. --day cells are displayed in lines
  380. data[calendarbutton].month_days_lines = {}
  381. for i=1,6 do
  382. data[calendarbutton].month_days_lines[i] = layout.flex.horizontal()
  383. data[calendarbutton].month_days_lines[i]:add(data[calendarbutton].weeks_number[i].margin)
  384. for y=1,7 do
  385. data[calendarbutton].month_days_lines[i]:add(data[calendarbutton].month_days_cells[y +((i-1) *7)].margin)
  386. end
  387. end
  388. --All the previous stuff are displayed in a column
  389. data[calendarbutton].column:add(data[calendarbutton].title)
  390. data[calendarbutton].column:add(data[calendarbutton].week_days_line)
  391. for i=1,6 do
  392. data[calendarbutton].column:add(data[calendarbutton].month_days_lines[i])
  393. end
  394. data[calendarbutton].fullview = layout.flex.horizontal()
  395. data[calendarbutton].info = text_box( data[calendarbutton].info_cell_style)
  396. local text_info = nil
  397. if data[calendarbutton].default_info == nil then
  398. text_info = os.date("%A %B %d %Y")
  399. end
  400. if type(data[calendarbutton].default_info) == "string" then
  401. text_info = data[calendarbutton].default_info
  402. end
  403. if type(data[calendarbutton].default_info) == "function" then
  404. text_info = data[calendarbutton].default_info()
  405. end
  406. --data[calendarbutton].info:set_text(os.date("%A %B %d %Y"))
  407. data[calendarbutton].info:set_text(text_info)
  408. data[calendarbutton].info:set_height((max_height + mt +mr) * 8 )
  409. data[calendarbutton].info:set_width(math.ceil((max_width + ml + mr )* 8 ))
  410. data[calendarbutton].fullview:add(data[calendarbutton].column)
  411. data[calendarbutton].fullview:add(data[calendarbutton].info)
  412. --dirty hack in order to get the good layout size
  413. data[calendarbutton].info:fit(math.ceil((max_width + ml + mr )* 8 ), (max_height + mt +mr) * 8 )
  414. data[calendarbutton].calendarbox = wibox( {ontop = true, width = math.ceil((max_width + ml + mr )* 8 ) *2,
  415. height = (max_height + mt +mr) * 8})
  416. data[calendarbutton].calendarbox.visible =false
  417. data[calendarbutton].calendarbox:set_widget(data[calendarbutton].fullview)
  418. see_current_month(calendarbutton)
  419. end
  420. local function show_wibox(wibox)
  421. local current_screen = capi.mouse.screen
  422. local screen_geometry = capi.screen[current_screen].workarea
  423. local screen_w = screen_geometry.x + screen_geometry.width
  424. local screen_h = screen_geometry.y + screen_geometry.height
  425. local mouse_coords = capi.mouse.coords()
  426. local x,y =0
  427. y = mouse_coords.y < screen_geometry.y and screen_geometry.y or mouse_coords.y
  428. x = mouse_coords.x < screen_geometry.x and screen_geometry.x or mouse_coords.x
  429. y = y + wibox.height > ( screen_h - 10)and screen_h - (wibox.height + 10) or y + 10
  430. x = x + wibox.width > ( screen_w - 10) and screen_w - ( wibox.width + 10) or x + 10
  431. wibox:geometry({ --width = wibox.width,
  432. --height = wibox.height,
  433. x = x ,
  434. y = y })
  435. wibox.visible = true
  436. end
  437. local function toggle_visibility(calendarbutton)
  438. calendarbutton:buttons( awful.util.table.join(
  439. awful.button({}, 1, function()
  440. if data[calendarbutton].calendarbox then
  441. if data[calendarbutton].calendarbox.visible ~= true then
  442. reload_and_fill(calendarbutton)
  443. --w,h = data[calendarbutton].info:fit(0,0)
  444. --helpers.dbg({w,h})
  445. show_wibox(data[calendarbutton].calendarbox)
  446. else
  447. data[calendarbutton].calendarbox.visible = false
  448. end
  449. else
  450. generate_calendar_box(calendarbutton)
  451. --w,h = data[calendarbutton].info:fit(0,0)
  452. --helpers.dbg({w,h})
  453. reload_and_fill(calendarbutton)
  454. show_wibox(data[calendarbutton].calendarbox)
  455. end
  456. end)
  457. )
  458. )
  459. end
  460. local properties = { "prev_next_widget_style", "current_date_widget_style", "days_of_week_widget_style", "days_of_month_widget_style", "weeks_number_widget_style", "corner_widget_style", "current_day_widget_style", "focus_widget_style", "info_cell_style", "link_to_external_calendar" }
  461. -- Build properties function
  462. for _, prop in ipairs(properties) do
  463. if not calendar["set_" .. prop] then
  464. calendar["set_" .. prop] = function(calendarbutton, value)
  465. data[calendarbutton][prop] = value
  466. calendarbutton:emit_signal("widget::updated")
  467. return calendarbutton
  468. end
  469. end
  470. end
  471. function append_function_get_events_from(calendarbutton, my_function)
  472. table.insert(data[calendarbutton].get_events_from, my_function)
  473. return self
  474. end
  475. function clear_and_add_function_get_events_from(calendarbutton, my_function)
  476. data[calendarbutton].get_events_from={}
  477. table.insert(data[calendarbutton].get_events_from, my_function)
  478. return calendar
  479. end
  480. function set_locale(calendarbutton, locale)
  481. os.setlocale(locale)
  482. data[calendarbutton].week_days = {}
  483. for i=6,12 do
  484. table.insert(data[calendarbutton].week_days,(os.date("%a",os.time({month=2,day=i,year=2012}))))
  485. end
  486. data[calendarbutton].months = {}
  487. for i=1,12 do
  488. table.insert(data[calendarbutton].months,os.date("%B",os.time({month=i,day=1,year=2012})))
  489. end
  490. end
  491. function set_default_info(calendarbutton, text)
  492. data[calendarbutton].default_info = text
  493. end
  494. function calendar.new(args)
  495. local args = args or {}
  496. local calendarbutton = args.widget or awful.widget.textclock(" %a %b %d, %H:%M")
  497. data[calendarbutton] = {}
  498. --get days and month labels
  499. if args.locale then
  500. os.setlocale(locale)
  501. end
  502. data[calendarbutton].week_days = {}
  503. for i=6,12 do
  504. table.insert(data[calendarbutton].week_days,(os.date("%a",os.time({month=2,day=i,year=2012}))))
  505. end
  506. data[calendarbutton].months = {}
  507. for i=1,12 do
  508. table.insert(data[calendarbutton].months,os.date("%B",os.time({month=i,day=1,year=2012})))
  509. end
  510. data[calendarbutton].prev_next_widget_style = superproperties.calendar.prev_next_widget_style
  511. data[calendarbutton].current_date_widget_style = superproperties.calendar.current_date_widget_style
  512. data[calendarbutton].days_of_week_widget_style = superproperties.calendar.days_of_week_widget_style
  513. data[calendarbutton].days_of_month_widget_style = superproperties.calendar.days_of_month_widget_style
  514. data[calendarbutton].weeks_number_widget_style = superproperties.calendar.weeks_number_widget_style
  515. data[calendarbutton].corner_widget_style = superproperties.calendar.corner_widget_style
  516. data[calendarbutton].current_day_widget_style = superproperties.calendar.current_day_widget_style
  517. data[calendarbutton].focus_widget_style = superproperties.calendar.focus_widget_style
  518. data[calendarbutton].info_cell_style = superproperties.calendar.info_cell_style
  519. toggle_visibility(calendarbutton)
  520. data[calendarbutton].link_to_external_calendar = false
  521. --This table contains the functions to access event from different agenda, can be extended.
  522. data[calendarbutton].get_events_from={
  523. --reminds
  524. function(day,month,year)
  525. local day_events=util.pread('remind -k\'echo %s\' ~/.reminders ' .. day .. " " .. os.date("%B",os.time{year=year,month=month,day=day}) .." " .. year)
  526. day_events = string.gsub(day_events,"\n\n+","\n")
  527. day_events =string.gsub(day_events,"\n*$","")
  528. day_events="Remind:\n" .. day_events
  529. return day_events
  530. end,
  531. --task_warrior
  532. function(day,month,year)
  533. local day_events=util.pread('task overdue due:' .. os.date("%m",os.time{year=year,month=month,day=day}) .."/"..day.."/" .. year)
  534. local day_events = "Task warrior:\n" .. day_events
  535. return day_events
  536. end,
  537. }
  538. for _, prop in ipairs(properties) do
  539. calendarbutton["set_" .. prop] = calendar["set_" .. prop]
  540. end
  541. calendarbutton.clear_and_add_function_get_events_from = clear_and_add_function_get_events_from
  542. calendarbutton.append_function_get_events_from =append_function_get_events_from
  543. calendarbutton.set_locale = set_locale
  544. calendarbutton.set_default_info = set_default_info
  545. return calendarbutton
  546. end
  547. function calendar.mt:__call(...)
  548. return calendar.new(...)
  549. end
  550. return setmetatable(calendar, calendar.mt)