Merge pull request #1689 from getzze/wibox_calendar
Add calendar widgets (wibox and popup)
This commit is contained in:
commit
e993d7a117
|
@ -0,0 +1,390 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- A calendar popup wibox
|
||||||
|
--
|
||||||
|
-- Display a month or year calendar popup using `calendar_popup.month` or `calendar_popup.year`.
|
||||||
|
-- The calendar style can be tweaked by providing tables of style properties at creation:
|
||||||
|
-- `style_year`, `style_month`, `style_yearheader`, `style_header`,
|
||||||
|
-- `style_weekday`, `style_weeknumber`, `style_normal`, `style_focus` (see `cell_properties`).
|
||||||
|
--
|
||||||
|
-- The wibox accepts arguments for the calendar widget: `font`, `spacing`, `week_numbers`,
|
||||||
|
-- `start_sunday`, `long_weekdays`.
|
||||||
|
-- It also accepts the extra arguments `opacity`, `bg`, `screen` and `position`.
|
||||||
|
-- `opacity` and `bg` apply to the wibox itself, they are mainly useful to manage opacity
|
||||||
|
-- by setting `opacity` for the false opacity or setting `bg="#00000000"` for compositor opacity.
|
||||||
|
-- The `screen` argument forces the display of the wibox to this screen (instead of the focused screen by default).
|
||||||
|
-- The `position` argument is a two-characters string describing the screen alignment "[vertical][horizontal]",
|
||||||
|
-- e.g. "cc", "tr", "bl", ...
|
||||||
|
--
|
||||||
|
-- The wibox visibility can be changed calling the `toggle` method.
|
||||||
|
-- The `attach` method adds mouse bindings to an existing widget in order to toggle the display of the wibox.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_awidget_defaults_calendar_popup_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @author getzze
|
||||||
|
-- @copyright 2017 getzze
|
||||||
|
-- @classmod awful.widget.calendar_popup
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local setmetatable = setmetatable
|
||||||
|
local string = string
|
||||||
|
local gears = require("gears")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local base = require("wibox.widget.base")
|
||||||
|
local ascreen = require("awful.screen")
|
||||||
|
local abutton = require("awful.button")
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
|
||||||
|
local calendar_popup = { offset = 0, mt = {} }
|
||||||
|
|
||||||
|
local properties = { "markup", "fg_color", "bg_color", "shape", "padding", "border_width", "border_color", "opacity" }
|
||||||
|
local styles = { "year", "month", "yearheader", "monthheader", "header", "weekday", "weeknumber", "normal", "focus" }
|
||||||
|
|
||||||
|
|
||||||
|
--- The generic calendar style table.
|
||||||
|
--
|
||||||
|
-- Each table property can also be defined by `beautiful.calendar_[flag]_[property]=val`.
|
||||||
|
-- @beautiful beautiful.calendar_style
|
||||||
|
-- @tparam cell_properties table Table of cell style properties
|
||||||
|
|
||||||
|
|
||||||
|
--- Cell properties.
|
||||||
|
-- @field markup Markup function or format string
|
||||||
|
-- @field fg_color Text foreground color
|
||||||
|
-- @field bg_color Text background color
|
||||||
|
-- @field shape Cell shape
|
||||||
|
-- @field padding Cell padding
|
||||||
|
-- @field border_width Calendar border width
|
||||||
|
-- @field border_color Calendar border color
|
||||||
|
-- @field opacity Cell opacity
|
||||||
|
-- @table cell_properties
|
||||||
|
|
||||||
|
--- Cell types (flags).
|
||||||
|
-- @field year Year calendar grid properties table
|
||||||
|
-- @field month Month calendar grid properties table
|
||||||
|
-- @field yearheader Year header cell properties table
|
||||||
|
-- @field header Month header cell properties table (called `monthheader` for a year calendar)
|
||||||
|
-- @field weekday Weekday cell properties table
|
||||||
|
-- @field weeknumber Weeknumber cell properties table
|
||||||
|
-- @field normal Normal day cell properties table
|
||||||
|
-- @field focus Current day cell properties table
|
||||||
|
-- @table cell_flags
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a container for the grid layout
|
||||||
|
-- @tparam table tprops Table of calendar container properties.
|
||||||
|
-- @treturn function Embedding function widget,flag,date -> widget
|
||||||
|
local function embed(tprops)
|
||||||
|
local function fn (widget, flag, _)
|
||||||
|
if flag == "monthheader" and not tprops.monthheader then
|
||||||
|
flag = "header"
|
||||||
|
end
|
||||||
|
local props = tprops[flag]
|
||||||
|
-- Markup
|
||||||
|
if flag ~= "year" and flag ~= "month" then
|
||||||
|
local markup = widget:get_text()
|
||||||
|
local m = props.markup
|
||||||
|
if type(m) == "function" then
|
||||||
|
markup = m(markup)
|
||||||
|
elseif type(m) == "string" and string.find(m, "%s", 1, true) then
|
||||||
|
markup = string.format(m, markup)
|
||||||
|
end
|
||||||
|
widget:set_markup(markup)
|
||||||
|
end
|
||||||
|
|
||||||
|
local out = base.make_widget_declarative {
|
||||||
|
{
|
||||||
|
widget,
|
||||||
|
margins = props.padding + props.border_width,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
},
|
||||||
|
shape = props.shape or gears.shape.rectangle,
|
||||||
|
shape_border_color = props.border_color,
|
||||||
|
shape_border_width = props.border_width,
|
||||||
|
fg = props.fg_color,
|
||||||
|
bg = props.bg_color,
|
||||||
|
opacity = props.opacity,
|
||||||
|
widget = wibox.container.background
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
return fn
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Parse the properties of the cell type and set default values
|
||||||
|
-- @tparam string cell The cell type
|
||||||
|
-- @tparam table args Table of properties to enforce
|
||||||
|
-- @treturn table The properties table
|
||||||
|
local function parse_cell_options(cell, args)
|
||||||
|
args = args or {}
|
||||||
|
local props = {}
|
||||||
|
local bl_style = beautiful.calendar_style or {}
|
||||||
|
|
||||||
|
for _, prop in ipairs(properties) do
|
||||||
|
local default
|
||||||
|
if prop == 'markup' then
|
||||||
|
default = cell == "focus" and string.format('<span foreground="%s" background="%s"><b>%s</b></span>',
|
||||||
|
beautiful.fg_focus, beautiful.bg_focus, "%s")
|
||||||
|
elseif prop == 'fg_color' then
|
||||||
|
default = cell == "focus" and beautiful.fg_focus or beautiful.fg_normal
|
||||||
|
elseif prop == 'bg_color' then
|
||||||
|
default = cell == "focus" and beautiful.bg_focus or beautiful.bg_normal
|
||||||
|
elseif prop == 'padding' then
|
||||||
|
default = 2
|
||||||
|
elseif prop == 'opacity' then
|
||||||
|
default = 1
|
||||||
|
elseif prop == 'shape' then
|
||||||
|
default = nil
|
||||||
|
elseif prop == 'border_width' then
|
||||||
|
default = beautiful.border_width or 0
|
||||||
|
elseif prop == 'border_color' then
|
||||||
|
default = beautiful.border_normal or beautiful.fg_normal
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get default
|
||||||
|
props[prop] = args[prop] or beautiful["calendar_" .. cell .. "_" .. prop] or bl_style[prop] or default
|
||||||
|
end
|
||||||
|
return props
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Parse the properties
|
||||||
|
-- @tparam table args Table of properties
|
||||||
|
-- @treturn table The properties table
|
||||||
|
local function parse_all_options(args)
|
||||||
|
args = args or {}
|
||||||
|
local props = {}
|
||||||
|
|
||||||
|
for _, cell in pairs(styles) do
|
||||||
|
if cell~="monthheader" or args.style_monthheader then
|
||||||
|
props[cell] = parse_cell_options(cell, args["style_" .. cell])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return props
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Make the geometry of a wibox
|
||||||
|
-- @tparam widget widget Calendar widget
|
||||||
|
-- @tparam object screen Screen where to display the calendar (default to focused)
|
||||||
|
-- @tparam string position Two characters position of the calendar (default "cc")
|
||||||
|
-- @treturn number,number,number,number Geometry of the calendar, list of x, y, width, height
|
||||||
|
local function get_geometry(widget, screen, position)
|
||||||
|
local pos, s = position or "cc", screen or ascreen.focused()
|
||||||
|
local wa = s.workarea
|
||||||
|
local width, height = widget:fit({screen=s, dpi=beautiful.xresources.get_dpi(s)}, wa.width, wa.height)
|
||||||
|
|
||||||
|
width = width < wa.width and width or wa.width
|
||||||
|
height = height < wa.height and height or wa.height
|
||||||
|
|
||||||
|
|
||||||
|
-- Set to position: pos = tl, tc, tr
|
||||||
|
-- cl, cc, cr
|
||||||
|
-- bl, bc, br
|
||||||
|
local x,y
|
||||||
|
if pos:sub(1,1) == "t" then
|
||||||
|
y = wa.y
|
||||||
|
elseif pos:sub(1,1) == "b" then
|
||||||
|
y = wa.y + wa.height - height
|
||||||
|
else --if pos:sub(1,1) == "c" then
|
||||||
|
y = wa.y + math.floor((wa.height - height) / 2)
|
||||||
|
end
|
||||||
|
if pos:sub(2,2) == "l" then
|
||||||
|
x = wa.x
|
||||||
|
elseif pos:sub(2,2) == "r" then
|
||||||
|
x = wa.x + wa.width - width
|
||||||
|
else --if pos:sub(2,2) == "c" then
|
||||||
|
x = wa.x + math.floor((wa.width - width) / 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return {x=x, y=y, width=width, height=height}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Call the calendar with offset
|
||||||
|
-- @tparam number offset Offset with respect to current month or year
|
||||||
|
-- @tparam string position Two-character position of the calendar in the screen
|
||||||
|
-- @tparam screen screen Screen where to display the calendar
|
||||||
|
-- @treturn wibox The wibox calendar
|
||||||
|
function calendar_popup:call_calendar(offset, position, screen)
|
||||||
|
local inc_offset, pos, s = offset or 0, position or self.position, screen or self.screen or ascreen.focused()
|
||||||
|
self.position = pos -- remember last position when changing offset
|
||||||
|
|
||||||
|
self.offset = inc_offset ~= 0 and self.offset + inc_offset or 0
|
||||||
|
|
||||||
|
local widget = self:get_widget()
|
||||||
|
local raw_date = os.date("*t")
|
||||||
|
local date = {day=raw_date.day, month=raw_date.month, year=raw_date.year}
|
||||||
|
if widget._private.type == "month" and self.offset ~= 0 then
|
||||||
|
raw_date.month = raw_date.month + self.offset
|
||||||
|
raw_date = os.date("*t", os.time(raw_date))
|
||||||
|
date = {month=raw_date.month, year=raw_date.year}
|
||||||
|
elseif widget._private.type == "year" then
|
||||||
|
date = {year=raw_date.year + self.offset}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set date and screen before updating geometry
|
||||||
|
widget:set_date(date)
|
||||||
|
self:set_screen(s)
|
||||||
|
-- update geometry (depends on date and screen)
|
||||||
|
self:geometry(get_geometry(widget, s, pos))
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Toggle calendar visibility
|
||||||
|
function calendar_popup:toggle()
|
||||||
|
self:call_calendar(0)
|
||||||
|
self.visible = not self.visible
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Attach the calendar to a widget to display at a specific position.
|
||||||
|
--
|
||||||
|
-- local mytextclock = wibox.widget.textclock()
|
||||||
|
-- local month_calendar = calendar.month()
|
||||||
|
-- month_calendar:attach(mytextclock, 'tr')
|
||||||
|
--
|
||||||
|
-- @param widget Widget to attach the calendar
|
||||||
|
-- @tparam[opt="tr"] string position Two characters string defining the position on the screen
|
||||||
|
-- @treturn wibox The wibox calendar
|
||||||
|
function calendar_popup:attach(widget, position)
|
||||||
|
position = position or "tr"
|
||||||
|
widget:buttons(gears.table.join(
|
||||||
|
abutton({ }, 1, function ()
|
||||||
|
self:call_calendar(0, position)
|
||||||
|
self.visible = not self.visible
|
||||||
|
end),
|
||||||
|
abutton({ }, 4, function () self:call_calendar(-1) end),
|
||||||
|
abutton({ }, 5, function () self:call_calendar( 1) end)
|
||||||
|
))
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return a new calendar wibox by type.
|
||||||
|
--
|
||||||
|
-- A calendar widget displaying a `month` or a `year`
|
||||||
|
-- @tparam string caltype Type of calendar `month` or `year`
|
||||||
|
-- @tparam table args Properties of the widget
|
||||||
|
-- @tparam string args.position Two-character position of the calendar in the screen
|
||||||
|
-- @tparam screen args.screen Screen where to display the calendar
|
||||||
|
-- @tparam number args.opacity Wibox opacity
|
||||||
|
-- @tparam string args.bg Wibox background color
|
||||||
|
-- @tparam string args.font Calendar font
|
||||||
|
-- @tparam number args.spacing Calendar spacing
|
||||||
|
-- @tparam boolean args.week_numbers Show weeknumbers
|
||||||
|
-- @tparam boolean args.start_sunday Start week on Sunday
|
||||||
|
-- @tparam boolean args.long_weekdays Format the weekdays with three characters instead of two
|
||||||
|
-- @tparam table args.year_style Container style for the year calendar (see `cell_properties`)
|
||||||
|
-- @tparam table args.month_style Container style for the month calendar (see `cell_properties`)
|
||||||
|
-- @tparam table args.yearheader_style Cell style for the year calendar header (see `cell_properties`)
|
||||||
|
-- @tparam table args.header_style Cell style for the month calendar header (see `cell_properties`)
|
||||||
|
-- @tparam table args.weekday_style Cell style for the weekday cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.weeknumber_style Cell style for the weeknumber cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.normal_style Cell style for the normal day cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.focus_style Cell style for the current day cell (see `cell_properties`)
|
||||||
|
-- @treturn wibox A wibox containing the calendar
|
||||||
|
local function get_cal_wibox(caltype, args)
|
||||||
|
args = args or {}
|
||||||
|
|
||||||
|
local ret = wibox{ ontop = true,
|
||||||
|
opacity = args.opacity or 1,
|
||||||
|
bg = args.bg
|
||||||
|
}
|
||||||
|
gears.table.crush(ret, calendar_popup, false)
|
||||||
|
|
||||||
|
ret.offset = 0
|
||||||
|
ret.position = args.position or "cc"
|
||||||
|
ret.screen = args.screen
|
||||||
|
|
||||||
|
local widget = wibox.widget {
|
||||||
|
font = args.font,
|
||||||
|
spacing = args.spacing,
|
||||||
|
week_numbers = args.week_numbers,
|
||||||
|
start_sunday = args.start_sunday,
|
||||||
|
long_weekdays = args.long_weekdays,
|
||||||
|
fn_embed = embed(parse_all_options(args)),
|
||||||
|
widget = caltype == "year" and wibox.widget.calendar.year or wibox.widget.calendar.month
|
||||||
|
}
|
||||||
|
ret:set_widget(widget)
|
||||||
|
|
||||||
|
ret:buttons(gears.table.join(
|
||||||
|
abutton({ }, 1, function () ret.visible=false end),
|
||||||
|
abutton({ }, 3, function () ret.visible=false end),
|
||||||
|
abutton({ }, 4, function () ret:call_calendar(-1) end),
|
||||||
|
abutton({ }, 5, function () ret:call_calendar( 1) end)
|
||||||
|
))
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
--- A month calendar wibox.
|
||||||
|
--
|
||||||
|
-- It is highly customizable using the same options as for the widgets.
|
||||||
|
-- The options are set once and for all at creation, though.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_awidget_calendar_month_wibox_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- local mytextclock = wibox.widget.textclock()
|
||||||
|
-- month_calendar:attach( mytextclock, "tr" )
|
||||||
|
--
|
||||||
|
-- @tparam table args Properties of the widget
|
||||||
|
-- @tparam string args.position Two-character position of the calendar in the screen
|
||||||
|
-- @tparam screen args.screen Screen where to display the calendar
|
||||||
|
-- @tparam number args.opacity Wibox opacity
|
||||||
|
-- @tparam string args.bg Wibox background color
|
||||||
|
-- @tparam string args.font Calendar font
|
||||||
|
-- @tparam number args.spacing Calendar spacing
|
||||||
|
-- @tparam boolean args.week_numbers Show weeknumbers
|
||||||
|
-- @tparam boolean args.start_sunday Start week on Sunday
|
||||||
|
-- @tparam boolean args.long_weekdays Format the weekdays with three characters instead of two
|
||||||
|
-- @tparam table args.month_style Container style for the month calendar (see `cell_properties`)
|
||||||
|
-- @tparam table args.header_style Cell style for the month calendar header (see `cell_properties`)
|
||||||
|
-- @tparam table args.weekday_style Cell style for the weekday cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.weeknumber_style Cell style for the weeknumber cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.normal_style Cell style for the normal day cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.focus_style Cell style for the current day cell (see `cell_properties`)
|
||||||
|
-- @treturn wibox A wibox containing the calendar
|
||||||
|
-- @function awful.calendar.month
|
||||||
|
function calendar_popup.month(args)
|
||||||
|
return get_cal_wibox("month", args)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- A year calendar wibox.
|
||||||
|
--
|
||||||
|
-- It is highly customizable using the same options as for the widgets.
|
||||||
|
-- The options are set once and for all at creation, though.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_awidget_calendar_year_wibox_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- globalkeys = gears.table.join(globalkeys, awful.key(
|
||||||
|
-- { modkey, "Control" }, "c", function () year_calendar:toggle() end))
|
||||||
|
--
|
||||||
|
-- @tparam table args Properties of the widget
|
||||||
|
-- @tparam string args.position Two-character position of the calendar in the screen
|
||||||
|
-- @tparam screen args.screen Screen where to display the calendar
|
||||||
|
-- @tparam number args.opacity Wibox opacity
|
||||||
|
-- @tparam string args.bg Wibox background color
|
||||||
|
-- @tparam string args.font Calendar font
|
||||||
|
-- @tparam number args.spacing Calendar spacing
|
||||||
|
-- @tparam boolean args.week_numbers Show weeknumbers
|
||||||
|
-- @tparam boolean args.start_sunday Start week on Sunday
|
||||||
|
-- @tparam boolean args.long_weekdays Format the weekdays with three characters instead of two
|
||||||
|
-- @tparam table args.year_style Container style for the year calendar (see `cell_properties`)
|
||||||
|
-- @tparam table args.month_style Container style for the month calendar (see `cell_properties`).
|
||||||
|
-- This field can also be called `monthheader_style`.
|
||||||
|
-- @tparam table args.yearheader_style Cell style for the year calendar header (see `cell_properties`)
|
||||||
|
-- @tparam table args.header_style Cell style for the month calendar header (see `cell_properties`)
|
||||||
|
-- @tparam table args.weekday_style Cell style for the weekday cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.weeknumber_style Cell style for the weeknumber cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.normal_style Cell style for the normal day cells (see `cell_properties`)
|
||||||
|
-- @tparam table args.focus_style Cell style for the current day cell (see `cell_properties`)
|
||||||
|
-- @treturn wibox A wibox containing the calendar
|
||||||
|
-- @function awful.calendar.year
|
||||||
|
function calendar_popup.year(args)
|
||||||
|
return get_cal_wibox("year", args)
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(calendar_popup, calendar_popup.mt)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -21,6 +21,7 @@ return
|
||||||
watch = require("awful.widget.watch");
|
watch = require("awful.widget.watch");
|
||||||
only_on_screen = require("awful.widget.only_on_screen");
|
only_on_screen = require("awful.widget.only_on_screen");
|
||||||
clienticon = require("awful.widget.clienticon");
|
clienticon = require("awful.widget.clienticon");
|
||||||
|
calendar_popup = require("awful.widget.calendar_popup");
|
||||||
}
|
}
|
||||||
|
|
||||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
|
@ -0,0 +1,385 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- A calendar widget
|
||||||
|
--
|
||||||
|
-- This module defines two widgets: a month calendar and a year calendar
|
||||||
|
--
|
||||||
|
-- The two widgets have a `date` property, in the form of
|
||||||
|
-- a table {day=[number|nil], month=[number|nil], year=[number]}.
|
||||||
|
--
|
||||||
|
-- The `year` widget displays the whole specified year, e.g. {year=2006}.
|
||||||
|
--
|
||||||
|
-- The `month` widget displays the calendar for the specified month, e.g. {month=12, year=2006},
|
||||||
|
-- highlighting the specified day if the day is provided in the date, e.g. {day=22, month=12, year=2006}.
|
||||||
|
--
|
||||||
|
-- Cell and container styles can be overridden using the `fn_embed` callback function
|
||||||
|
-- which is called before adding the widgets to the layouts. The `fn_embed` function
|
||||||
|
-- takes three arguments, the original widget, the flag (`string` used to identified the widget)
|
||||||
|
-- and the date (`table`).
|
||||||
|
-- It returns another widget, embedding (and modifying) the original widget.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_defaults_calendar_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @author getzze
|
||||||
|
-- @copyright 2017 getzze
|
||||||
|
-- @classmod wibox.widget.calendar
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
local setmetatable = setmetatable
|
||||||
|
local string = string
|
||||||
|
local gtable = require("gears.table")
|
||||||
|
local vertical = require("wibox.layout.fixed").vertical
|
||||||
|
local grid = require("wibox.layout.grid")
|
||||||
|
local textbox = require("wibox.widget.textbox")
|
||||||
|
local bgcontainer = require("wibox.container.background")
|
||||||
|
local base = require("wibox.widget.base")
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
|
||||||
|
local calendar = { mt = {} }
|
||||||
|
|
||||||
|
local properties = { "date", "font", "spacing", "week_numbers", "start_sunday", "long_weekdays", "fn_embed" }
|
||||||
|
|
||||||
|
|
||||||
|
--- The calendar font.
|
||||||
|
-- @beautiful beautiful.calendar_font
|
||||||
|
-- @tparam string font Font of the calendar
|
||||||
|
|
||||||
|
--- The calendar spacing.
|
||||||
|
-- @beautiful beautiful.calendar_spacing
|
||||||
|
-- @tparam number spacing Spacing of the grid (twice this value for inter-month spacing)
|
||||||
|
|
||||||
|
--- Display the calendar week numbers.
|
||||||
|
-- @beautiful beautiful.calendar_week_numbers
|
||||||
|
-- @param boolean Display week numbers
|
||||||
|
|
||||||
|
--- Start the week on Sunday.
|
||||||
|
-- @beautiful beautiful.calendar_start_sunday
|
||||||
|
-- @param boolean Start the week on Sunday
|
||||||
|
|
||||||
|
--- Format the weekdays with three characters instead of two
|
||||||
|
-- @beautiful beautiful.calendar_long_weekdays
|
||||||
|
-- @param boolean Use three characters for the weekdays instead of two
|
||||||
|
|
||||||
|
--- The calendar date.
|
||||||
|
--
|
||||||
|
-- A table representing the date {day=[number|nil], month=[number|nil], year=[number]}.
|
||||||
|
--
|
||||||
|
-- E.g.. {day=21, month=2, year=2005}, {month=2, year=2005}, {year=2005}
|
||||||
|
-- @tparam date table Date table.
|
||||||
|
-- @tparam number date.year Date year
|
||||||
|
-- @tparam number|nil date.month Date month
|
||||||
|
-- @tparam number|nil date.day Date day
|
||||||
|
-- @property date
|
||||||
|
|
||||||
|
--- The calendar font.
|
||||||
|
--
|
||||||
|
-- Choose a monospace font for a better rendering.
|
||||||
|
--@DOC_wibox_widget_calendar_font_EXAMPLE@
|
||||||
|
-- @param[opt="Monospace 10"] string Font of the calendar
|
||||||
|
-- @property font
|
||||||
|
|
||||||
|
--- The calendar spacing.
|
||||||
|
--
|
||||||
|
-- The spacing between cells in the month.
|
||||||
|
-- The spacing between months in a year calendar is twice this value.
|
||||||
|
-- @param[opt=5] number Spacing of the grid
|
||||||
|
-- @property spacing
|
||||||
|
|
||||||
|
--- Display the calendar week numbers.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_week_numbers_EXAMPLE@
|
||||||
|
-- @param[opt=false] boolean Display week numbers
|
||||||
|
-- @property week_numbers
|
||||||
|
|
||||||
|
--- Start the week on Sunday.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_start_sunday_EXAMPLE@
|
||||||
|
-- @param[opt=false] boolean Start the week on Sunday
|
||||||
|
-- @property start_sunday
|
||||||
|
|
||||||
|
--- Format the weekdays with three characters instead of two
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_long_weekdays_EXAMPLE@
|
||||||
|
-- @param[opt=false] boolean Use three characters for the weekdays instead of two
|
||||||
|
-- @property long_weekdays
|
||||||
|
|
||||||
|
--- The widget encapsulating function.
|
||||||
|
--
|
||||||
|
-- Function that takes a widget, flag (`string`) and date (`table`) as argument
|
||||||
|
-- and returns a widget encapsulating the input widget.
|
||||||
|
--
|
||||||
|
-- Default value: function (widget, flag, date) return widget end
|
||||||
|
--
|
||||||
|
-- It is used to add a container to the grid layout and to the cells:
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_fn_embed_cell_EXAMPLE@
|
||||||
|
-- @param function Function to embed the widget depending on its flag
|
||||||
|
-- @property fn_embed
|
||||||
|
|
||||||
|
|
||||||
|
--- Make a textbox
|
||||||
|
-- @tparam string text Text of the textbox
|
||||||
|
-- @tparam string font Font of the text
|
||||||
|
-- @tparam boolean center Center the text horizontally
|
||||||
|
-- @treturn wibox.widget.textbox
|
||||||
|
local function make_cell(text, font, center)
|
||||||
|
return base.make_widget_declarative {
|
||||||
|
markup = text,
|
||||||
|
align = center and "center" or "right",
|
||||||
|
valign = 'center',
|
||||||
|
font = font,
|
||||||
|
widget = textbox
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a grid layout with the month calendar
|
||||||
|
-- @tparam table props Table of calendar properties
|
||||||
|
-- @tparam table date Date table
|
||||||
|
-- @tparam number date.year Date year
|
||||||
|
-- @tparam number date.month Date month
|
||||||
|
-- @tparam number|nil date.day Date day
|
||||||
|
-- @treturn widget Grid layout
|
||||||
|
local function create_month(props, date)
|
||||||
|
local num_rows = 8
|
||||||
|
local num_columns = props.week_numbers and 8 or 7
|
||||||
|
|
||||||
|
-- Create grid layout
|
||||||
|
local layout = base.make_widget_declarative{
|
||||||
|
layout = grid,
|
||||||
|
expand = true,
|
||||||
|
homogeneous = true,
|
||||||
|
spacing = props.spacing,
|
||||||
|
forced_num_rows = num_rows,
|
||||||
|
forced_num_cols = num_columns,
|
||||||
|
}
|
||||||
|
|
||||||
|
local start_row = 3
|
||||||
|
local start_column = num_columns - 6
|
||||||
|
local week_start = props.start_sunday and 1 or 2
|
||||||
|
local last_day = os.date("*t", os.time{year=date.year, month=date.month+1, day=0})
|
||||||
|
local month_days = last_day.day
|
||||||
|
local column_fday = (last_day.wday - month_days + 1 - week_start ) % 7
|
||||||
|
|
||||||
|
--local flags = {"header", "weekdays", "weeknumber", "normal", "focus"}
|
||||||
|
local cell_date, t, i, j, w, flag, text
|
||||||
|
|
||||||
|
-- Header
|
||||||
|
flag = "header"
|
||||||
|
t = os.time{year=date.year, month=date.month, day=1}
|
||||||
|
if props.subtype=="monthheader" then
|
||||||
|
flag = "monthheader"
|
||||||
|
text = os.date("%B", t)
|
||||||
|
else
|
||||||
|
text = os.date("%B %Y", t)
|
||||||
|
end
|
||||||
|
w = props.fn_embed(make_cell(text, props.font, true), flag, date)
|
||||||
|
layout:add_widget_at(w, 1, 1, 1, num_columns)
|
||||||
|
|
||||||
|
-- Days
|
||||||
|
i = start_row
|
||||||
|
j = column_fday + start_column
|
||||||
|
local current_week = nil
|
||||||
|
local drawn_weekdays = 0
|
||||||
|
for d=1, month_days do
|
||||||
|
cell_date = {year=date.year, month=date.month, day=d}
|
||||||
|
t = os.time(cell_date)
|
||||||
|
-- Week number
|
||||||
|
if props.week_numbers then
|
||||||
|
text = os.date("%V", t)
|
||||||
|
if tonumber(text) ~= current_week then
|
||||||
|
flag = "weeknumber"
|
||||||
|
w = props.fn_embed(make_cell(text, props.font), flag, cell_date)
|
||||||
|
layout:add_widget_at(w, i, 1, 1, 1)
|
||||||
|
current_week = tonumber(text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Week days
|
||||||
|
if drawn_weekdays < 7 then
|
||||||
|
flag = "weekday"
|
||||||
|
text = os.date("%a", t)
|
||||||
|
if not props.long_weekdays then
|
||||||
|
text = string.sub(text, 1, 2)
|
||||||
|
end
|
||||||
|
w = props.fn_embed(make_cell(text, props.font), flag, cell_date)
|
||||||
|
layout:add_widget_at(w, 2, j, 1, 1)
|
||||||
|
drawn_weekdays = drawn_weekdays +1
|
||||||
|
end
|
||||||
|
-- Normal day
|
||||||
|
flag = "normal"
|
||||||
|
text = string.format("%2d", d)
|
||||||
|
-- Focus day
|
||||||
|
if date.day == d then
|
||||||
|
flag = "focus"
|
||||||
|
text = "<b>"..text.."</b>"
|
||||||
|
end
|
||||||
|
w = props.fn_embed(make_cell(text, props.font), flag, cell_date)
|
||||||
|
layout:add_widget_at(w, i, j, 1, 1)
|
||||||
|
|
||||||
|
-- find next cell
|
||||||
|
i,j = layout:get_next_empty(i,j)
|
||||||
|
if j < start_column then j = start_column end
|
||||||
|
end
|
||||||
|
return props.fn_embed(layout, "month", date)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a grid layout for the year calendar
|
||||||
|
-- @tparam table props Table of year calendar properties
|
||||||
|
-- @param date Year to display (number or string)
|
||||||
|
-- @treturn widget Grid layout
|
||||||
|
local function create_year(props, date)
|
||||||
|
-- Create a grid widget with the 12 months
|
||||||
|
local in_layout = base.make_widget_declarative{
|
||||||
|
layout = grid,
|
||||||
|
expand = true,
|
||||||
|
homogeneous = true,
|
||||||
|
spacing = 2*props.spacing,
|
||||||
|
forced_num_cols = 4,
|
||||||
|
forced_num_rows = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
local month_date
|
||||||
|
local current_date = os.date("*t")
|
||||||
|
|
||||||
|
for month=1,12 do
|
||||||
|
if date.year == current_date.year and month == current_date.month then
|
||||||
|
month_date = {day=current_date.day, month=current_date.month, year=current_date.year}
|
||||||
|
else
|
||||||
|
month_date = {month=month, year=date.year}
|
||||||
|
end
|
||||||
|
in_layout:add(create_month(props, month_date))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create a vertical layout
|
||||||
|
local flag, text = "yearheader", string.format("%s", date.year)
|
||||||
|
local year_header = props.fn_embed(make_cell(text, props.font, true), flag, date)
|
||||||
|
local out_layout = base.make_widget_declarative{
|
||||||
|
year_header,
|
||||||
|
in_layout,
|
||||||
|
spacing = 2*props.spacing, -- separate header from calendar grid
|
||||||
|
layout = vertical
|
||||||
|
}
|
||||||
|
return props.fn_embed(out_layout, "year", date)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the container to the current date
|
||||||
|
-- @param self Widget to update
|
||||||
|
local function fill_container(self)
|
||||||
|
local date = self._private.date
|
||||||
|
if date then
|
||||||
|
-- Create calendar grid
|
||||||
|
if self._private.type == "month" then
|
||||||
|
self._private.container:set_widget(create_month(self._private, date))
|
||||||
|
elseif self._private.type == "year" then
|
||||||
|
self._private.container:set_widget(create_year(self._private, date))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self._private.container:set_widget(nil)
|
||||||
|
end
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Set the calendar date
|
||||||
|
function calendar:set_date(date)
|
||||||
|
if date ~= self._private.date then
|
||||||
|
self._private.date = date
|
||||||
|
-- (Re)create calendar grid
|
||||||
|
fill_container(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Build properties function
|
||||||
|
for _, prop in ipairs(properties) do
|
||||||
|
-- setter
|
||||||
|
if not calendar["set_" .. prop] then
|
||||||
|
calendar["set_" .. prop] = function(self, value)
|
||||||
|
if (string.sub(prop,1,3)=="fn_" and type(value) == "function") or self._private[prop] ~= value then
|
||||||
|
self._private[prop] = value
|
||||||
|
-- (Re)create calendar grid
|
||||||
|
fill_container(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- getter
|
||||||
|
if not calendar["get_" .. prop] then
|
||||||
|
calendar["get_" .. prop] = function(self)
|
||||||
|
return self._private[prop]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return a new calendar widget by type.
|
||||||
|
--
|
||||||
|
-- @tparam string type Type of the calendar, `year` or `month`
|
||||||
|
-- @tparam table date Date of the calendar
|
||||||
|
-- @tparam number date.year Date year
|
||||||
|
-- @tparam number|nil date.month Date month
|
||||||
|
-- @tparam number|nil date.day Date day
|
||||||
|
-- @tparam[opt="Monospace 10"] string font Font of the calendar
|
||||||
|
-- @treturn widget The calendar widget
|
||||||
|
local function get_calendar(type, date, font)
|
||||||
|
local ct = bgcontainer()
|
||||||
|
local ret = base.make_widget(ct, "calendar", {enable_properties = true})
|
||||||
|
gtable.crush(ret, calendar, true)
|
||||||
|
|
||||||
|
ret._private.type = type
|
||||||
|
ret._private.container = ct
|
||||||
|
|
||||||
|
-- default values
|
||||||
|
ret._private.date = date
|
||||||
|
ret._private.font = font or beautiful.calendar_font or "Monospace 10"
|
||||||
|
|
||||||
|
ret._private.spacing = beautiful.calendar_spacing or 5
|
||||||
|
ret._private.week_numbers = beautiful.calendar_week_numbers or false
|
||||||
|
ret._private.start_sunday = beautiful.calendar_start_sunday or false
|
||||||
|
ret._private.long_weekdays = beautiful.calendar_long_weekdays or false
|
||||||
|
ret._private.fn_embed = function (w, _) return w end
|
||||||
|
|
||||||
|
-- header specific
|
||||||
|
ret._private.subtype = type=="year" and "monthheader" or "fullheader"
|
||||||
|
|
||||||
|
fill_container(ret)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
--- A month calendar widget.
|
||||||
|
--
|
||||||
|
-- A calendar widget is a grid containing the calendar for one month.
|
||||||
|
-- If the day is specified in the date, its cell is highlighted.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_month_EXAMPLE@
|
||||||
|
-- @tparam table date Date of the calendar
|
||||||
|
-- @tparam number date.year Date year
|
||||||
|
-- @tparam number date.month Date month
|
||||||
|
-- @tparam number|nil date.day Date day
|
||||||
|
-- @tparam[opt="Monospace 10"] string font Font of the calendar
|
||||||
|
-- @treturn widget The month calendar widget
|
||||||
|
-- @function wibox.widget.calendar.month
|
||||||
|
function calendar.month(date, font)
|
||||||
|
return get_calendar("month", date, font)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- A year calendar widget.
|
||||||
|
--
|
||||||
|
-- A calendar widget is a grid containing the calendar for one year.
|
||||||
|
--
|
||||||
|
--@DOC_wibox_widget_calendar_year_EXAMPLE@
|
||||||
|
-- @tparam table date Date of the calendar
|
||||||
|
-- @tparam number date.year Date year
|
||||||
|
-- @tparam number|nil date.month Date month
|
||||||
|
-- @tparam number|nil date.day Date day
|
||||||
|
-- @tparam[opt="Monospace 10"] string font Font of the calendar
|
||||||
|
-- @treturn widget The year calendar widget
|
||||||
|
-- @function wibox.widget.calendar.year
|
||||||
|
function calendar.year(date, font)
|
||||||
|
return get_calendar("year", date, font)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return setmetatable(calendar, calendar.mt)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -19,6 +19,7 @@ local widget = {
|
||||||
checkbox = require("wibox.widget.checkbox");
|
checkbox = require("wibox.widget.checkbox");
|
||||||
piechart = require("wibox.widget.piechart");
|
piechart = require("wibox.widget.piechart");
|
||||||
slider = require("wibox.widget.slider");
|
slider = require("wibox.widget.slider");
|
||||||
|
calendar = require("wibox.widget.calendar");
|
||||||
}
|
}
|
||||||
|
|
||||||
setmetatable(widget, {
|
setmetatable(widget, {
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local gears = require("gears") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local styles = {}
|
||||||
|
local function rounded_shape(size, partial)
|
||||||
|
if partial then
|
||||||
|
return function(cr, width, height)
|
||||||
|
gears.shape.partially_rounded_rect(cr, width, height,
|
||||||
|
false, true, false, true, 5)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return function(cr, width, height)
|
||||||
|
gears.shape.rounded_rect(cr, width, height, size)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
styles.month = { padding = 5,
|
||||||
|
bg_color = "#555555",
|
||||||
|
border_width = 2,
|
||||||
|
shape = rounded_shape(10)
|
||||||
|
}
|
||||||
|
styles.normal = { shape = rounded_shape(5) }
|
||||||
|
styles.focus = { fg_color = "#000000",
|
||||||
|
bg_color = "#ff9800",
|
||||||
|
markup = function(t) return '<b>' .. t .. '</b>' end,
|
||||||
|
shape = rounded_shape(5, true)
|
||||||
|
}
|
||||||
|
styles.header = { fg_color = "#de5e1e",
|
||||||
|
markup = function(t) return '<b>' .. t .. '</b>' end,
|
||||||
|
shape = rounded_shape(10)
|
||||||
|
}
|
||||||
|
styles.weekday = { fg_color = "#7788af",
|
||||||
|
markup = function(t) return '<b>' .. t .. '</b>' end,
|
||||||
|
shape = rounded_shape(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
local function decorate_cell(widget, flag, date)
|
||||||
|
if flag=="monthheader" and not styles.monthheader then
|
||||||
|
flag = "header"
|
||||||
|
end
|
||||||
|
local props = styles[flag] or {}
|
||||||
|
if props.markup and widget.get_text and widget.set_markup then
|
||||||
|
widget:set_markup(props.markup(widget:get_text()))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Change bg color for weekends
|
||||||
|
local d = {year=date.year, month=(date.month or 1), day=(date.day or 1)}
|
||||||
|
local weekday = tonumber(os.date("%w", os.time(d)))
|
||||||
|
local default_bg = (weekday==0 or weekday==6) and "#232323" or "#383838"
|
||||||
|
|
||||||
|
local ret = wibox.widget {
|
||||||
|
{
|
||||||
|
widget,
|
||||||
|
margins = (props.padding or 2) + (props.border_width or 0),
|
||||||
|
widget = wibox.container.margin
|
||||||
|
},
|
||||||
|
shape = props.shape,
|
||||||
|
shape_border_color = props.border_color or "#b9214f",
|
||||||
|
shape_border_width = props.border_width or 0,
|
||||||
|
fg = props.fg_color or "#999999",
|
||||||
|
bg = props.bg_color or default_bg,
|
||||||
|
widget = wibox.container.background
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local cal = wibox.widget {
|
||||||
|
date = os.date("*t"),
|
||||||
|
fn_embed = decorate_cell,
|
||||||
|
widget = wibox.widget.calendar.month
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,17 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("sans 12") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget.calendar.month(
|
||||||
|
os.date("*t"), "sans 12")
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,21 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget {
|
||||||
|
date = os.date("*t"),
|
||||||
|
font = "Monospace 10",
|
||||||
|
long_weekdays = true,
|
||||||
|
widget = wibox.widget.calendar.month
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,51 @@
|
||||||
|
local parent = ... --DOC_HIDE_ALL
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local date = os.date("*t") --DOC_HIDE
|
||||||
|
|
||||||
|
local w = wibox.widget {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = '{day='..date.day..', month='..date.month..',\n year='..date.year..'}',
|
||||||
|
align = 'center',
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_width = 2,
|
||||||
|
bg = beautiful.bg_normal,
|
||||||
|
widget = wibox.container.background
|
||||||
|
},
|
||||||
|
wibox.widget.calendar.month({day=date.day, month=date.month, year=date.year}),
|
||||||
|
spacing = 10,
|
||||||
|
widget = wibox.layout.fixed.vertical
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = '{month='..date.month..',\n year='..date.year..'}',
|
||||||
|
align = 'center',
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_width = 2,
|
||||||
|
bg = beautiful.bg_normal,
|
||||||
|
widget = wibox.container.background
|
||||||
|
},
|
||||||
|
wibox.widget.calendar.month({month=date.month, year=date.year}),
|
||||||
|
spacing = 10,
|
||||||
|
widget = wibox.layout.fixed.vertical
|
||||||
|
},
|
||||||
|
spacing = 20,
|
||||||
|
widget = wibox.layout.flex.horizontal
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(w) --DOC_HIDE
|
|
@ -0,0 +1,21 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget {
|
||||||
|
date = os.date("*t"),
|
||||||
|
font = "Monospace 10",
|
||||||
|
start_sunday = true,
|
||||||
|
widget = wibox.widget.calendar.month
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,21 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget {
|
||||||
|
date = os.date("*t"),
|
||||||
|
font = "Monospace 10",
|
||||||
|
week_numbers = true,
|
||||||
|
widget = wibox.widget.calendar.month
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,25 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget {
|
||||||
|
date = os.date("*t"),
|
||||||
|
font = "Monospace 8",
|
||||||
|
spacing = 2,
|
||||||
|
week_numbers = false,
|
||||||
|
start_sunday = false,
|
||||||
|
widget = wibox.widget.calendar.year
|
||||||
|
}
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
||||||
|
local w,h = parent:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
||||||
|
return w+30, h --DOC_HIDE
|
|
@ -0,0 +1,16 @@
|
||||||
|
local parent = ... --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require( "beautiful" ) --DOC_HIDE
|
||||||
|
local Pango = require("lgi").Pango --DOC_HIDE
|
||||||
|
|
||||||
|
-- Beautiful fake get_font --DOC_HIDE
|
||||||
|
local f = Pango.FontDescription.from_string("monospace 10") --DOC_HIDE
|
||||||
|
beautiful.get_font = function() return f end --DOC_HIDE
|
||||||
|
|
||||||
|
-- Fake beautiful theme --DOC_HIDE
|
||||||
|
beautiful.fg_focus = "#ff9800" --DOC_HIDE
|
||||||
|
beautiful.bg_focus = "#b9214f" --DOC_HIDE
|
||||||
|
|
||||||
|
local cal = wibox.widget.calendar.month(os.date("*t"))
|
||||||
|
|
||||||
|
parent:add(cal) --DOC_HIDE
|
|
@ -0,0 +1,71 @@
|
||||||
|
--- Test for awful.widget.calendar
|
||||||
|
|
||||||
|
local runner = require("_runner")
|
||||||
|
local awful = require("awful")
|
||||||
|
local calendar = require("awful.widget.calendar_popup")
|
||||||
|
|
||||||
|
local wa = awful.screen.focused().workarea
|
||||||
|
|
||||||
|
local cmonth = calendar.month()
|
||||||
|
local cyear = calendar.year()
|
||||||
|
local current_date = os.date("*t")
|
||||||
|
local day, month, year = current_date.day, current_date.month, current_date.year
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
-- Check center geometry
|
||||||
|
function(count)
|
||||||
|
if count == 1 then
|
||||||
|
cmonth:call_calendar(0, 'cc')
|
||||||
|
else
|
||||||
|
local geo = cmonth:geometry()
|
||||||
|
assert( math.abs((wa.x + wa.width/2.0) - (geo.x + geo.width/2.0)) < 2 )
|
||||||
|
assert( math.abs((wa.y + wa.height/2.0) - (geo.y + geo.height/2.0)) < 2 )
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
-- Check top-right geometry
|
||||||
|
function(count)
|
||||||
|
if count == 1 then
|
||||||
|
cmonth:call_calendar(0, 'tr')
|
||||||
|
else
|
||||||
|
local geo = cmonth:geometry()
|
||||||
|
assert(wa.x + wa.width == geo.x + geo.width)
|
||||||
|
assert(wa.y == geo.y)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
-- Check visibility
|
||||||
|
function()
|
||||||
|
local v = cyear.visible
|
||||||
|
cyear:toggle()
|
||||||
|
assert(v == not cyear.visible)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
-- Check current date
|
||||||
|
function()
|
||||||
|
local mdate = cmonth:get_widget():get_date()
|
||||||
|
assert(mdate.day==day and mdate.month==month and mdate.year==year)
|
||||||
|
local ydate = cyear:get_widget():get_date()
|
||||||
|
assert(ydate.year==year)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
-- Check new date
|
||||||
|
function(count)
|
||||||
|
if count == 1 then
|
||||||
|
-- Increment
|
||||||
|
cmonth:call_calendar(1)
|
||||||
|
cyear:call_calendar(-1)
|
||||||
|
else
|
||||||
|
local mdate = cmonth:get_widget():get_date()
|
||||||
|
assert( mdate.day==nil and
|
||||||
|
((mdate.month==month+1 and mdate.year==year) or (mdate.month==1 and mdate.year==year+1)) )
|
||||||
|
local ydate = cyear:get_widget():get_date()
|
||||||
|
assert(ydate.year==year-1)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
}
|
||||||
|
runner.run_steps(steps)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
Loading…
Reference in New Issue