diff --git a/lib/gears/shape.lua b/lib/gears/shape.lua
index f247b5b7..3307d429 100644
--- a/lib/gears/shape.lua
+++ b/lib/gears/shape.lua
@@ -22,6 +22,8 @@
-- @module gears.shape
---------------------------------------------------------------------------
local g_matrix = require( "gears.matrix" )
+local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
+local atan2 = math.atan2 or math.atan -- lua 5.3 compat
local module = {}
@@ -326,9 +328,11 @@ end
-- @param cr A cairo context
-- @tparam number width The shape width
-- @tparam number height The shape height
-function module.circle(cr, width, height)
- local size = math.min(width, height) / 2
- cr:arc(width / 2, height / 2, size, 0, 2*math.pi)
+-- @tparam[opt=math.min(width height) / 2)] number radius The radius
+function module.circle(cr, width, height, radius)
+ radius = radius or math.min(width, height) / 2
+ cr:move_to(width/2+radius, height/2)
+ cr:arc(width / 2, height / 2, radius, 0, 2*math.pi)
cr:close_path()
end
@@ -376,6 +380,153 @@ function module.losange(cr, width, height)
cr:close_path()
end
+--- A pie.
+--
+-- The pie center is the center of the area.
+--
+-- @DOC_gears_shape_pie_EXAMPLE@
+--
+-- @param cr A cairo context
+-- @tparam number width The shape width
+-- @tparam number height The shape height
+-- @tparam[opt=0] number start_angle The start angle (in radian)
+-- @tparam[opt=math.pi/2] number end_angle The end angle (in radian)
+-- @tparam[opt=math.min(width height)/2] number radius The shape height
+function module.pie(cr, width, height, start_angle, end_angle, radius)
+ radius = radius or math.floor(math.min(width, height)/2)
+ start_angle, end_angle = start_angle or 0, end_angle or math.pi/2
+
+ -- If the shape is a circle, then avoid the lines
+ if math.abs(start_angle + end_angle - 2*math.pi) <= 0.01 then
+ cr:arc(width/2, height/2, radius, 0, 2*math.pi)
+ else
+ cr:move_to(width/2, height/2)
+ cr:line_to(
+ width/2 + math.cos(start_angle)*radius,
+ height/2 + math.sin(start_angle)*radius
+ )
+ cr:arc(width/2, height/2, radius, start_angle, end_angle)
+ end
+
+ cr:close_path()
+end
+
+--- A rounded arc.
+--
+-- The pie center is the center of the area.
+--
+-- @DOC_gears_shape_arc_EXAMPLE@
+--
+-- @param cr A cairo context
+-- @tparam number width The shape width
+-- @tparam number height The shape height
+-- @tparam[opt=math.min(width height)/2] number thickness The arc thickness
+-- @tparam[opt=0] number start_angle The start angle (in radian)
+-- @tparam[opt=math.pi/2] number end_angle The end angle (in radian)
+-- @tparam[opt=false] boolean start_rounded if the arc start rounded
+-- @tparam[opt=false] boolean end_rounded if the arc end rounded
+function module.arc(cr, width, height, thickness, start_angle, end_angle, start_rounded, end_rounded)
+ start_angle = start_angle or 0
+ end_angle = end_angle or math.pi/2
+
+ -- This shape is a partial circle
+ local radius = math.min(width, height)/2
+
+ thickness = thickness or radius/2
+
+ local inner_radius = radius - thickness
+
+ -- As the edge of the small arc need to touch the [start_p1, start_p2]
+ -- line, a small subset of the arc circumference has to be substracted
+ -- that's (less or more) equal to the thickness/2 (a little longer given
+ -- it is an arc and not a line, but it wont show)
+ local arc_percent = math.abs(end_angle-start_angle)/(2*math.pi)
+ local arc_length = ((radius-thickness/2)*2*math.pi)*arc_percent
+
+ if start_rounded then
+ arc_length = arc_length - thickness/2
+
+ -- And back to angles
+ start_angle = end_angle - (arc_length/(radius - thickness/2))
+ end
+
+ if end_rounded then
+ arc_length = arc_length - thickness/2
+
+ -- And back to angles
+ end_angle = start_angle + (arc_length/(radius - thickness/2))
+ end
+
+ -- The path is a curcular arc joining 4 points
+
+ -- Outer first corner
+ local start_p1 = {
+ width /2 + math.cos(start_angle)*radius,
+ height/2 + math.sin(start_angle)*radius
+ }
+
+ if start_rounded then
+
+ -- Inner first corner
+ local start_p2 = {
+ width /2 + math.cos(start_angle)*inner_radius,
+ height/2 + math.sin(start_angle)*inner_radius
+ }
+
+ local median_angle = atan2(
+ start_p2[1] - start_p1[1],
+ -(start_p2[2] - start_p1[2])
+ )
+
+ local arc_center = {
+ (start_p1[1] + start_p2[1])/2,
+ (start_p1[2] + start_p2[2])/2,
+ }
+
+ cr:arc(arc_center[1], arc_center[2], thickness/2,
+ median_angle-math.pi/2, median_angle+math.pi/2
+ )
+
+ else
+ cr:move_to(unpack(start_p1))
+ end
+
+ cr:arc(width/2, height/2, radius, start_angle, end_angle)
+
+ if end_rounded then
+
+ -- Outer second corner
+ local end_p1 = {
+ width /2 + math.cos(end_angle)*radius,
+ height/2 + math.sin(end_angle)*radius
+ }
+
+ -- Inner first corner
+ local end_p2 = {
+ width /2 + math.cos(end_angle)*inner_radius,
+ height/2 + math.sin(end_angle)*inner_radius
+ }
+ local median_angle = atan2(
+ end_p2[1] - end_p1[1],
+ -(end_p2[2] - end_p1[2])
+ ) - math.pi
+
+ local arc_center = {
+ (end_p1[1] + end_p2[1])/2,
+ (end_p1[2] + end_p2[2])/2,
+ }
+
+ cr:arc(arc_center[1], arc_center[2], thickness/2,
+ median_angle-math.pi/2, median_angle+math.pi/2
+ )
+
+ end
+
+ cr:arc_negative(width/2, height/2, inner_radius, end_angle, start_angle)
+
+ cr:close_path()
+end
+
--- A partial rounded bar. How much of the rounded bar is visible depends on
-- the given percentage value.
--
diff --git a/lib/wibox/container/arcchart.lua b/lib/wibox/container/arcchart.lua
new file mode 100644
index 00000000..381d3ead
--- /dev/null
+++ b/lib/wibox/container/arcchart.lua
@@ -0,0 +1,345 @@
+---------------------------------------------------------------------------
+--
+-- A circular chart (arc chart).
+--
+-- It can contain a central widget (or not) and display multiple values.
+--
+--@DOC_wibox_container_defaults_arcchart_EXAMPLE@
+-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
+-- @copyright 2013 Emmanuel Lepage Vallee
+-- @release @AWESOME_VERSION@
+-- @classmod wibox.container.arcchart
+---------------------------------------------------------------------------
+
+local setmetatable = setmetatable
+local base = require("wibox.widget.base")
+local shape = require("gears.shape" )
+local util = require( "awful.util" )
+local color = require( "gears.color" )
+local beautiful = require("beautiful" )
+
+
+local arcchart = { mt = {} }
+
+--- The progressbar border background color.
+-- @beautiful beautiful.arcchart_border_color
+
+--- The progressbar foreground color.
+-- @beautiful beautiful.arcchart_color
+
+--- The progressbar border width.
+-- @beautiful beautiful.arcchart_border_width
+
+--- The padding between the outline and the progressbar.
+-- @beautiful beautiful.arcchart_paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+--- The arc thickness.
+-- @beautiful beautiful.thickness
+-- @param number
+
+local function outline_workarea(width, height)
+ local x, y = 0, 0
+ local size = math.min(width, height)
+
+ return {x=x+(width-size)/2, y=y+(height-size)/2, width=size, height=size}
+end
+
+-- The child widget area
+local function content_workarea(self, width, height)
+ local padding = self._private.paddings or {}
+ local border_width = self:get_border_width() or 0
+ local wa = outline_workarea(width, height)
+ local thickness = math.max(border_width, self:get_thickness() or 5)
+
+ wa.x = wa.x + (padding.left or 0) + thickness + 2*border_width
+ wa.y = wa.y + (padding.top or 0) + thickness + 2*border_width
+ wa.width = wa.width - (padding.left or 0) - (padding.right or 0)
+ - 2*thickness - 4*border_width
+ wa.height = wa.height - (padding.top or 0) - (padding.bottom or 0)
+ - 2*thickness - 4*border_width
+
+ return wa
+end
+
+-- Draw the radial outline and progress
+function arcchart:after_draw_children(_, cr, width, height)
+ cr:restore()
+
+ local values = self:get_values() or {}
+ local border_width = self:get_border_width() or 0
+ local thickness = math.max(border_width, self:get_thickness() or 5)
+
+ local offset = thickness + 2*border_width
+
+ -- Draw a circular background
+ local bg = self:get_bg()
+ if bg then
+ cr:save()
+ cr:translate(offset/2, offset/2)
+ shape.circle(
+ cr,
+ width-offset,
+ height-offset
+ )
+ cr:set_line_width(thickness+2*border_width)
+ cr:set_source(color(bg))
+ cr:stroke()
+ cr:restore()
+ end
+
+ if #values == 0 then
+ return
+ end
+
+ local wa = outline_workarea(width, height)
+ cr:translate(wa.x+border_width/2, wa.y+border_width/2)
+
+
+ -- Get the min and max value
+ --local min_val = self:get_min_value() or 0 --TODO support min_values
+ local max_val = self:get_max_value()
+ local sum = 0
+
+ if not max_val then
+ for _, v in ipairs(values) do
+ sum = sum + v
+ end
+ max_val = sum
+ end
+
+ max_val = math.max(max_val, sum)
+
+ local use_rounded_edges = sum ~= max_val and self:get_rounded_edge()
+
+ -- Fallback to the current foreground color
+ local colors = self:get_colors() or {}
+
+ -- Draw the outline
+ local offset_angle = self:get_start_angle() or math.pi
+ local start_angle, end_angle = offset_angle, offset_angle
+
+ for k, v in ipairs(values) do
+ end_angle = start_angle + (v*2*math.pi) / max_val
+
+ if colors[k] then
+ cr:set_source(color(colors[k]))
+ end
+
+ shape.arc(cr, wa.width-border_width, wa.height-border_width,
+ thickness+border_width, math.pi-end_angle, math.pi-start_angle,
+ (use_rounded_edges and k == 1), (use_rounded_edges and k == #values)
+ )
+
+ cr:fill()
+ start_angle = end_angle
+ end
+
+ if border_width > 0 then
+ local border_color = self:get_border_color()
+
+ cr:set_source(color(border_color))
+ cr:set_line_width(border_width)
+
+ shape.arc(cr, wa.width-border_width, wa.height-border_width,
+ thickness+border_width, math.pi-end_angle, math.pi-offset_angle,
+ use_rounded_edges, use_rounded_edges
+ )
+ cr:stroke()
+ end
+
+end
+
+-- Set the clip
+function arcchart:before_draw_children(_, cr, width, height)
+ cr:save()
+ local wa = content_workarea(self, width, height)
+ cr:translate(wa.x, wa.y)
+ shape.circle(
+ cr,
+ wa.width,
+ wa.height
+ )
+ cr:clip()
+ cr:translate(-wa.x, -wa.y)
+end
+
+-- Layout this layout
+function arcchart:layout(_, width, height)
+ if self._private.widget then
+ local wa = content_workarea(self, width, height)
+
+ return { base.place_widget_at(
+ self._private.widget, wa.x, wa.y, wa.width, wa.height
+ ) }
+ end
+end
+
+-- Fit this layout into the given area
+function arcchart:fit(_, width, height)
+ local size = math.min(width, height)
+ return size, size
+end
+
+--- The widget to wrap in a radial proggressbar.
+-- @property widget
+-- @tparam widget widget The widget
+
+function arcchart:set_widget(widget)
+ if widget then
+ base.check_widget(widget)
+ end
+ self._private.widget = widget
+ self:emit_signal("widget::layout_changed")
+end
+
+--- Get the children elements.
+-- @treturn table The children
+function arcchart:get_children()
+ return {self._private.widget}
+end
+
+--- Replace the layout children
+-- This layout only accept one children, all others will be ignored
+-- @tparam table children A table composed of valid widgets
+function arcchart:set_children(children)
+ self._private.widget = children and children[1]
+ self:emit_signal("widget::layout_changed")
+end
+
+--- Reset this layout. The widget will be removed and the rotation reset.
+function arcchart:reset()
+ self:set_widget(nil)
+end
+
+for _,v in ipairs {"left", "right", "top", "bottom"} do
+ arcchart["set_"..v.."_padding"] = function(self, val)
+ self._private.paddings = self._private.paddings or {}
+ self._private.paddings[v] = val
+ self:emit_signal("widget::redraw_needed")
+ self:emit_signal("widget::layout_changed")
+ end
+end
+
+--- The padding between the outline and the progressbar.
+--@DOC_wibox_container_arcchart_paddings_EXAMPLE@
+-- @property paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+--- The border background color.
+--@DOC_wibox_container_arcchart_border_color_EXAMPLE@
+-- @property border_color
+
+--- The border foreground color.
+--@DOC_wibox_container_arcchart_color_EXAMPLE@
+-- @property color
+
+--- The border width.
+--@DOC_wibox_container_arcchart_border_width_EXAMPLE@
+-- @property border_width
+-- @tparam[opt=3] number border_width
+
+--- The minimum value.
+-- @property min_value
+
+--- The maximum value.
+-- @property max_value
+
+--- The radial background.
+--@DOC_wibox_container_arcchart_bg_EXAMPLE@
+-- @property bg
+-- @param color
+-- @see gears.color
+
+--- The value.
+--@DOC_wibox_container_arcchart_value_EXAMPLE@
+-- @property value
+-- @tparam number value Between min_value and max_value
+-- @see values
+
+--- The values.
+-- The arcchart is designed to display multiple values at once. Each will be
+-- shown in table order.
+--@DOC_wibox_container_arcchart_values_EXAMPLE@
+-- @property values
+-- @tparam table values An ordered set if values.
+-- @see value
+
+--- If the chart has rounded edges.
+--@DOC_wibox_container_arcchart_rounded_edge_EXAMPLE@
+-- @property rounded_edge
+-- @param[opt=false] boolean
+
+--- The arc thickness.
+--@DOC_wibox_container_arcchart_thickness_EXAMPLE@
+-- @property thickness
+-- @param number
+
+--- The (radiant) angle where the first value start.
+--@DOC_wibox_container_arcchart_start_angle_EXAMPLE@
+-- @property start_angle
+-- @param[opt=math.pi] number A number between 0 and 2*math.pi
+
+for _, prop in ipairs {"border_width", "border_color", "paddings", "colors",
+ "rounded_edge", "bg", "thickness", "values", "min_value", "max_value",
+ "start_angle" } do
+ arcchart["set_"..prop] = function(self, value)
+ self._private[prop] = value
+ self:emit_signal("property::"..prop)
+ self:emit_signal("widget::redraw_needed")
+ end
+ arcchart["get_"..prop] = function(self)
+ return self._private[prop] or beautiful["arcchart_"..prop]
+ end
+end
+
+function arcchart:set_paddings(val)
+ self._private.paddings = type(val) == "number" and {
+ left = val,
+ right = val,
+ top = val,
+ bottom = val,
+ } or val or {}
+ self:emit_signal("property::paddings")
+ self:emit_signal("widget::redraw_needed")
+ self:emit_signal("widget::layout_changed")
+end
+
+function arcchart:set_value(value)
+ self:set_values {value}
+end
+
+--- Returns a new arcchart layout.
+-- @param[opt] widget The widget to display.
+-- @function wibox.container.arcchart
+local function new(widget)
+ local ret = base.make_widget(nil, nil, {
+ enable_properties = true,
+ })
+
+ util.table.crush(ret, arcchart)
+
+ ret:set_widget(widget)
+
+ return ret
+end
+
+function arcchart.mt:__call(...)
+ return new(...)
+end
+
+--@DOC_widget_COMMON@
+
+--@DOC_object_COMMON@
+
+return setmetatable(arcchart, arcchart.mt)
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/wibox/container/init.lua b/lib/wibox/container/init.lua
index b5cd7b37..833712c8 100644
--- a/lib/wibox/container/init.lua
+++ b/lib/wibox/container/init.lua
@@ -15,6 +15,8 @@ return setmetatable({
constraint = require("wibox.container.constraint");
scroll = require("wibox.container.scroll");
background = require("wibox.container.background");
+ radialprogressbar = require("wibox.container.radialprogressbar");
+ arcchart = require("wibox.container.arcchart");
}, {__call = function(_, args) return base.make_widget_declarative(args) end})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/wibox/container/radialprogressbar.lua b/lib/wibox/container/radialprogressbar.lua
new file mode 100644
index 00000000..4630c101
--- /dev/null
+++ b/lib/wibox/container/radialprogressbar.lua
@@ -0,0 +1,266 @@
+---------------------------------------------------------------------------
+--
+-- A circular progressbar wrapper.
+--
+-- If no child `widget` is set, then the radialprogressbar will take all the
+-- available size. Use a `wibox.container.constraint` to prevent this.
+--
+--@DOC_wibox_container_defaults_radialprogressbar_EXAMPLE@
+-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
+-- @copyright 2013 Emmanuel Lepage Vallee
+-- @release @AWESOME_VERSION@
+-- @classmod wibox.container.radialprogressbar
+---------------------------------------------------------------------------
+
+local setmetatable = setmetatable
+local base = require("wibox.widget.base")
+local shape = require("gears.shape" )
+local util = require( "awful.util" )
+local color = require( "gears.color" )
+local beautiful = require("beautiful" )
+
+local default_outline_width = 2
+
+local radialprogressbar = { mt = {} }
+
+--- The progressbar border background color.
+-- @beautiful beautiful.radialprogressbar_border_color
+
+--- The progressbar foreground color.
+-- @beautiful beautiful.radialprogressbar_color
+
+--- The progressbar border width.
+-- @beautiful beautiful.radialprogressbar_border_width
+
+--- The padding between the outline and the progressbar.
+-- @beautiful beautiful.radialprogressbar_paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+local function outline_workarea(self, width, height)
+ local border_width = self._private.border_width or
+ beautiful.radialprogressbar_border_width or default_outline_width
+
+ local x, y = 0, 0
+
+ -- Make sure the border fit in the clip area
+ local offset = border_width/2
+ x, y = x + offset, y+offset
+ width, height = width-2*offset, height-2*offset
+
+ return {x=x, y=y, width=width, height=height}, offset
+end
+
+-- The child widget area
+local function content_workarea(self, width, height)
+ local padding = self._private.paddings or {}
+ local wa = outline_workarea(self, width, height)
+
+ wa.x = wa.x + (padding.left or 0)
+ wa.y = wa.y + (padding.top or 0)
+ wa.width = wa.width - (padding.left or 0) - (padding.right or 0)
+ wa.height = wa.height - (padding.top or 0) - (padding.bottom or 0)
+
+ return wa
+end
+
+-- Draw the radial outline and progress
+function radialprogressbar:after_draw_children(_, cr, width, height)
+ cr:restore()
+
+ local border_width = self._private.border_width or
+ beautiful.radialprogressbar_border_width or default_outline_width
+
+ local wa = outline_workarea(self, width, height)
+ cr:translate(wa.x, wa.y)
+
+ -- Draw the outline
+ shape.rounded_bar(cr, wa.width, wa.height)
+ cr:set_source(color(self:get_border_color() or "#0000ff"))
+ cr:set_line_width(border_width)
+ cr:stroke()
+
+ -- Draw the progress
+ cr:set_source(color(self:get_color() or "#ff00ff"))
+ shape.radial_progress(cr, wa.width, wa.height, self._percent or 0)
+ cr:set_line_width(border_width)
+ cr:stroke()
+
+end
+
+-- Set the clip
+function radialprogressbar:before_draw_children(_, cr, width, height)
+ cr:save()
+ local wa = content_workarea(self, width, height)
+ cr:translate(wa.x, wa.y)
+ shape.rounded_bar(cr, wa.width, wa.height)
+ cr:clip()
+ cr:translate(-wa.x, -wa.y)
+end
+
+-- Layout this layout
+function radialprogressbar:layout(_, width, height)
+ if self._private.widget then
+ local wa = content_workarea(self, width, height)
+
+ return { base.place_widget_at(
+ self._private.widget, wa.x, wa.y, wa.width, wa.height
+ ) }
+ end
+end
+
+-- Fit this layout into the given area
+function radialprogressbar:fit(context, width, height)
+ if self._private.widget then
+ local wa = content_workarea(self, width, height)
+ local w, h = base.fit_widget(self, context, self._private.widget, wa.width, wa.height)
+ return wa.x + w, wa.y + h
+ end
+
+ return width, height
+end
+
+--- The widget to wrap in a radial proggressbar.
+-- @property widget
+-- @tparam widget widget The widget
+
+function radialprogressbar:set_widget(widget)
+ if widget then
+ base.check_widget(widget)
+ end
+ self._private.widget = widget
+ self:emit_signal("widget::layout_changed")
+end
+
+--- Get the children elements
+-- @treturn table The children
+function radialprogressbar:get_children()
+ return {self._private.widget}
+end
+
+--- Replace the layout children
+-- This layout only accept one children, all others will be ignored
+-- @tparam table children A table composed of valid widgets
+function radialprogressbar:set_children(children)
+ self._private.widget = children and children[1]
+ self:emit_signal("widget::layout_changed")
+end
+
+--- Reset this container.
+function radialprogressbar:reset()
+ self:set_widget(nil)
+end
+
+for _,v in ipairs {"left", "right", "top", "bottom"} do
+ radialprogressbar["set_"..v.."_padding"] = function(self, val)
+ self._private.paddings = self._private.paddings or {}
+ self._private.paddings[v] = val
+ self:emit_signal("widget::redraw_needed")
+ self:emit_signal("widget::layout_changed")
+ end
+end
+
+--- The padding between the outline and the progressbar.
+--@DOC_wibox_container_radialprogressbar_padding_EXAMPLE@
+-- @property paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+--- The progressbar value.
+--@DOC_wibox_container_radialprogressbar_value_EXAMPLE@
+-- @property value
+-- @tparam number value Between min_value and max_value
+
+function radialprogressbar:set_value(val)
+ if not val then self._percent = 0; return end
+
+ if val > self._private.max_value then
+ self:set_max_value(val)
+ elseif val < self._private.min_value then
+ self:set_min_value(val)
+ end
+
+ local delta = self._private.max_value - self._private.min_value
+
+ self._percent = val/delta
+ self:emit_signal("widget::redraw_needed")
+end
+
+--- The border background color.
+--@DOC_wibox_container_radialprogressbar_border_color_EXAMPLE@
+-- @property border_color
+
+--- The border foreground color.
+--@DOC_wibox_container_radialprogressbar_color_EXAMPLE@
+-- @property color
+
+--- The border width.
+--@DOC_wibox_container_radialprogressbar_border_width_EXAMPLE@
+-- @property border_width
+-- @tparam[opt=3] number border_width
+
+--- The minimum value.
+-- @property min_value
+
+--- The maximum value.
+-- @property max_value
+
+for _, prop in ipairs {"max_value", "min_value", "border_color", "color",
+ "border_width", "paddings"} do
+ radialprogressbar["set_"..prop] = function(self, value)
+ self._private[prop] = value
+ self:emit_signal("property::"..prop)
+ self:emit_signal("widget::redraw_needed")
+ end
+ radialprogressbar["get_"..prop] = function(self)
+ return self._private[prop] or beautiful["radialprogressbar_"..prop]
+ end
+end
+
+function radialprogressbar:set_paddings(val)
+ self._private.paddings = type(val) == "number" and {
+ left = val,
+ right = val,
+ top = val,
+ bottom = val,
+ } or val or {}
+ self:emit_signal("property::paddings")
+ self:emit_signal("widget::redraw_needed")
+ self:emit_signal("widget::layout_changed")
+end
+
+--- Returns a new radialprogressbar layout. A radialprogressbar layout
+-- radialprogressbars a given widget. Use `.widget` to set the widget.
+-- @param[opt] widget The widget to display.
+-- @function wibox.container.radialprogressbar
+local function new(widget)
+ local ret = base.make_widget(nil, nil, {
+ enable_properties = true,
+ })
+
+ util.table.crush(ret, radialprogressbar)
+ ret._private.max_value = 1
+ ret._private.min_value = 0
+
+ ret:set_widget(widget)
+
+ return ret
+end
+
+function radialprogressbar.mt:__call(_, ...)
+ return new(...)
+end
+
+--@DOC_widget_COMMON@
+
+--@DOC_object_COMMON@
+
+return setmetatable(radialprogressbar, radialprogressbar.mt)
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/wibox/widget/checkbox.lua b/lib/wibox/widget/checkbox.lua
new file mode 100644
index 00000000..0634adc9
--- /dev/null
+++ b/lib/wibox/widget/checkbox.lua
@@ -0,0 +1,252 @@
+---------------------------------------------------------------------------
+-- A boolean display widget.
+--
+-- If necessary, themes can implement custom shape:
+--
+--@DOC_wibox_widget_checkbox_custom_EXAMPLE@
+--
+--@DOC_wibox_widget_defaults_checkbox_EXAMPLE@
+-- @author Emmanuel Lepage Valle
+-- @copyright 2010 Emmanuel Lepage Vallee
+-- @release @AWESOME_VERSION@
+-- @classmod wibox.widget.checkbox
+---------------------------------------------------------------------------
+
+local color = require( "gears.color" )
+local base = require( "wibox.widget.base" )
+local beautiful = require( "beautiful" )
+local shape = require( "gears.shape" )
+local util = require( "awful.util" )
+
+local checkbox = {}
+
+--- The outer (unchecked area) border width.
+-- @beautiful beautiful.checkbox_border_width
+
+--- The outer (unchecked area) background color, pattern or gradient.
+-- @beautiful beautiful.checkbox_bg
+
+--- The outer (unchecked area) border color.
+-- @beautiful beautiful.checkbox_border_color
+
+--- The checked part border color.
+-- @beautiful beautiful.checkbox_check_border_color
+
+--- The checked part border width.
+-- @beautiful beautiful.checkbox_check_border_width
+
+--- The checked part filling color.
+-- @beautiful beautiful.checkbox_check_color
+
+--- The outer (unchecked area) shape.
+-- @beautiful beautiful.checkbox_shape
+-- @see gears.shape
+
+--- The checked part shape.
+-- If none is set, then the `shape` property will be used.
+-- @beautiful beautiful.checkbox_check_shape
+-- @see gears.shape
+
+--- The padding between the outline and the progressbar.
+-- @beautiful beautiful.checkbox_paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+--- The checkbox color.
+-- This will be used for the unchecked part border color and the checked part
+-- filling color. Note that `check_color` and `border_color` have priority
+-- over this property.
+-- @beautiful beautiful.checkbox_color
+
+--- The outer (unchecked area) border width.
+-- @property border_width
+
+--- The outer (unchecked area) background color, pattern or gradient.
+--@DOC_wibox_widget_checkbox_bg_EXAMPLE@
+-- @property bg
+
+--- The outer (unchecked area) border color.
+-- @property border_color
+
+--- The checked part border color.
+-- @property check_border_color
+
+--- The checked part border width.
+-- @property check_border_width
+
+--- The checked part filling color.
+-- @property check_color
+
+--- The outer (unchecked area) shape.
+--@DOC_wibox_widget_checkbox_shape_EXAMPLE@
+-- @property shape
+-- @see gears.shape
+
+--- The checked part shape.
+-- If none is set, then the `shape` property will be used.
+--@DOC_wibox_widget_checkbox_check_shape_EXAMPLE@
+-- @property check_shape
+-- @see gears.shape
+
+--- The padding between the outline and the progressbar.
+-- @property paddings
+-- @tparam[opt=0] table|number paddings A number or a table
+-- @tparam[opt=0] number paddings.top
+-- @tparam[opt=0] number paddings.bottom
+-- @tparam[opt=0] number paddings.left
+-- @tparam[opt=0] number paddings.right
+
+--- The checkbox color.
+-- This will be used for the unchecked part border color and the checked part
+-- filling color. Note that `check_color` and `border_color` have priority
+-- over this property.
+-- @property color
+
+local function outline_workarea(self, width, height)
+ local offset = (self._private.border_width or
+ beautiful.checkbox_border_width or 1)/2
+
+ return {
+ x = offset,
+ y = offset,
+ width = width-2*offset,
+ height = height-2*offset
+ }
+end
+
+-- The child widget area
+local function content_workarea(self, width, height)
+ local padding = self._private.paddings or {}
+ local offset = self:get_check_border_width() or 0
+ local wa = outline_workarea(self, width, height)
+
+ wa.x = offset + wa.x + (padding.left or 1)
+ wa.y = offset + wa.y + (padding.top or 1)
+ wa.width = wa.width - (padding.left or 1) - (padding.right or 1) - 2*offset
+ wa.height = wa.height - (padding.top or 1) - (padding.bottom or 1) - 2*offset
+
+ return wa
+end
+
+local function draw(self, _, cr, width, height)
+ local size = math.min(width, height)
+
+ local background_shape = self:get_shape() or shape.rectangle
+ local border_width = self:get_border_width() or 1
+
+ local main_color = self:get_color()
+ local bg = self:get_bg()
+ local border_color = self:get_border_color()
+
+ -- If no color is set, it will fallback to the default one
+ if border_color or main_color then
+ cr:set_source(color(border_color or main_color))
+ end
+
+ local wa = outline_workarea(self, size, size)
+ cr:translate(wa.x, wa.y)
+ background_shape(cr, wa.width, wa.height)
+ cr:set_line_width(border_width)
+
+ if bg then
+ cr:save()
+ cr:set_source(color(bg))
+ cr:fill_preserve()
+ cr:restore()
+ end
+
+ cr:stroke()
+
+ cr:translate(-wa.x, -wa.y)
+
+ -- Draw the checked part
+ if self._private.checked then
+ local col = self:get_check_color() or main_color
+ border_color = self:get_check_border_color()
+ border_width = self:get_check_border_width() or 0
+ local check_shape = self:get_check_shape() or background_shape
+
+ wa = content_workarea(self, size, size)
+ cr:translate(wa.x, wa.y)
+
+ check_shape(cr, wa.width, wa.height)
+
+ if col then
+ cr:set_source(color(col))
+ end
+
+ if border_width > 0 then
+ cr:fill_preserve()
+ cr:set_line_width(border_width)
+ cr:set_source(color(border_color))
+ cr:stroke()
+ else
+ cr:fill()
+ end
+ end
+end
+
+local function fit(_, _, w, h)
+ local size = math.min(w, h)
+ return size, size
+end
+
+--- If the checkbox is checked.
+-- @property checked
+-- @param boolean
+
+for _, prop in ipairs {"border_width", "bg", "border_color", "check_border_color",
+ "check_border_width", "check_color", "shape", "check_shape", "paddings",
+ "checked", "color" } do
+ checkbox["set_"..prop] = function(self, value)
+ self._private[prop] = value
+ self:emit_signal("property::"..prop)
+ self:emit_signal("widget::redraw_needed")
+ end
+ checkbox["get_"..prop] = function(self)
+ return self._private[prop] or beautiful["checkbox_"..prop]
+ end
+end
+
+--- The checkbox color.
+-- @property color
+
+function checkbox:set_paddings(val)
+ self._private.paddings = type(val) == "number" and {
+ left = val,
+ right = val,
+ top = val,
+ bottom = val,
+ } or val or {}
+ self:emit_signal("property::paddings")
+ self:emit_signal("widget::redraw_needed")
+end
+
+local function new(checked, args)
+ checked, args = checked or false, args or {}
+
+ local ret = base.make_widget(nil, nil, {
+ enable_properties = true,
+ })
+
+ util.table.crush(ret, checkbox)
+
+ ret._private.checked = checked
+ ret._private.color = args.color and color(args.color) or nil
+
+ rawset(ret, "fit" , fit )
+ rawset(ret, "draw", draw)
+
+ return ret
+end
+
+--@DOC_widget_COMMON@
+
+--@DOC_object_COMMON@
+
+return setmetatable({}, { __call = function(_, ...) return new(...) end})
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/wibox/widget/init.lua b/lib/wibox/widget/init.lua
index 4fc533cc..16c3fe9b 100644
--- a/lib/wibox/widget/init.lua
+++ b/lib/wibox/widget/init.lua
@@ -15,6 +15,8 @@ return setmetatable({
textclock = require("wibox.widget.textclock");
progressbar = require("wibox.widget.progressbar");
graph = require("wibox.widget.graph");
+ checkbox = require("wibox.widget.checkbox");
+ piechart = require("wibox.widget.piechart");
}, {__call = function(_, args) return base.make_widget_declarative(args) end})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/wibox/widget/piechart.lua b/lib/wibox/widget/piechart.lua
new file mode 100644
index 00000000..c2959ae7
--- /dev/null
+++ b/lib/wibox/widget/piechart.lua
@@ -0,0 +1,218 @@
+---------------------------------------------------------------------------
+-- Display percentage in a circle.
+--
+-- Note that this widget makes no attempts to prevent overlapping labels or
+-- labels drawn outside of the widget boundaries.
+--
+--@DOC_wibox_widget_defaults_piechart_EXAMPLE@
+-- @author Emmanuel Lepage Valle
+-- @copyright 2012 Emmanuel Lepage Vallee
+-- @release @AWESOME_VERSION@
+-- @classmod wibox.widget.piechart
+---------------------------------------------------------------------------
+
+local color = require( "gears.color" )
+local base = require( "wibox.widget.base" )
+local beautiful = require( "beautiful" )
+local util = require( "awful.util" )
+local pie = require( "gears.shape" ).pie
+local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
+
+local module = {}
+
+local piechart = {}
+
+local function draw_label(cr,angle,radius,center_x,center_y,text)
+ local edge_x = center_x+(radius/2)*math.cos(angle)
+ local edge_y = center_y+(radius/2)*math.sin(angle)
+
+ cr:move_to(edge_x, edge_y)
+
+ cr:rel_line_to(radius*math.cos(angle), radius*math.sin(angle))
+
+ local x,y = cr:get_current_point()
+
+ cr:rel_line_to(x > center_x and radius/2 or -radius/2, 0)
+
+ local ext = cr:text_extents(text)
+
+ cr:rel_move_to(
+ (x>center_x and radius/2.5 or (-radius/2.5 - ext.width)),
+ ext.height/2
+ )
+
+ cr:show_text(text) --TODO eventually port away from the toy API
+ cr:stroke()
+
+ cr:arc(edge_x, edge_y,2,0,2*math.pi)
+ cr:arc(x+(x>center_x and radius/2 or -radius/2),y,2,0,2*math.pi)
+
+ cr:fill()
+end
+
+local function compute_sum(data)
+ local ret = 0
+ for _,v in pairs(data) do
+ ret = ret + v
+ end
+
+ return ret
+end
+
+local function draw(self, _, cr, width, height)
+ if not self._private.data then return end
+
+ local radius = (height > width and width or height) / 4
+ local sum, start, count = compute_sum(self._private.data),0,0
+ local has_label = self._private.display_labels ~= false
+
+ -- Labels need to be drawn later so the original source is kept
+ -- use get_source() wont work are the reference cannot be set from Lua(?)
+ local labels = {}
+
+ local border_width = self:get_border_width() or 1
+ local border_color = self:get_border_color()
+ border_color = border_color and color(border_color)
+
+ -- Draw the pies
+ cr:save()
+ cr:set_line_width(border_width)
+
+ -- Alternate from a given sets or colors
+ local colors = self:get_colors()
+ local col_count = colors and #colors or 0
+
+ for k,v in pairs(self._private.data) do
+ local end_angle = start + 2*math.pi*(v/sum)
+
+ local col = colors and color(colors[math.fmod(count,col_count)+1]) or nil
+
+ pie(cr, width, height, start, end_angle, radius)
+
+ if col then
+ cr:save()
+ cr:set_source(color(col))
+ end
+
+ if border_width > 0 then
+ if col then
+ cr:fill_preserve()
+ cr:restore()
+ end
+
+ -- By default, it uses the fg color
+ if border_color then
+ cr:set_source(border_color)
+ end
+ cr:stroke()
+ elseif col then
+ cr:fill()
+ cr:restore()
+ end
+
+ -- Store the label position for later
+ if has_label then
+ table.insert(labels, {
+ --[[angle ]] start+(end_angle-start)/2,
+ --[[radius ]] radius,
+ --[[center_x]] width/2,
+ --[[center_y]] height/2,
+ --[[text ]] k,
+ })
+ end
+ start,count = end_angle,count+1
+ end
+ cr:restore()
+
+ -- Draw the labels
+ if has_label then
+ for _, v in ipairs(labels) do
+ draw_label(cr, unpack(v))
+ end
+ end
+end
+
+local function fit(_, _, width, height)
+ return width, height
+end
+
+--- The pie chart data.
+-- @property data
+-- @tparam table data Labels as keys and number as value.
+
+--- The border color.
+-- If none is set, it will use current foreground (text) color.
+--@DOC_wibox_widget_piechart_border_color_EXAMPLE@
+-- @property border_color
+-- @param color
+-- @see gears.color
+
+--- The pie elements border width.
+--@DOC_wibox_widget_piechart_border_width_EXAMPLE@
+-- @property border_width
+-- @tparam[opt=1] number border_width
+
+--- The pie chart colors.
+-- If no color is set, only the border will be drawn. If less colors than
+-- required are set, colors will be re-used in order.
+-- @property colors
+-- @tparam table colors A table of colors, one for each elements
+-- @see gears.color
+
+--- The border color.
+-- If none is set, it will use current foreground (text) color.
+-- @beautiful beautiful.piechart_border_color
+-- @param color
+-- @see gears.color
+
+--- If the pie chart has labels.
+--@DOC_wibox_widget_piechart_label_EXAMPLE@
+-- @property display_labels
+-- @param[opt=true] boolean
+
+--- The pie elements border width.
+-- @beautiful beautiful.piechart_border_width
+-- @tparam[opt=1] number border_width
+
+--- The pie chart colors.
+-- If no color is set, only the border will be drawn. If less colors than
+-- required are set, colors will be re-used in order.
+-- @beautiful beautiful.piechart_colors
+-- @tparam table colors A table of colors, one for each elements
+-- @see gears.color
+
+for _, prop in ipairs {"data", "border_color", "border_width", "colors",
+ "display_labels"
+ } do
+ piechart["set_"..prop] = function(self, value)
+ self._private[prop] = value
+ self:emit_signal("property::"..prop)
+ self:emit_signal("widget::redraw_needed")
+ end
+ piechart["get_"..prop] = function(self)
+ return self._private[prop] or beautiful["piechart_"..prop]
+ end
+end
+
+local function new(data)
+
+ local ret = base.make_widget(nil, nil, {
+ enable_properties = true,
+ })
+
+ util.table.crush(ret, piechart)
+
+ rawset(ret, "fit" , fit )
+ rawset(ret, "draw", draw)
+
+ ret:set_data(data)
+
+ return ret
+end
+
+--@DOC_widget_COMMON@
+
+--@DOC_object_COMMON@
+
+return setmetatable(module, { __call = function(_, ...) return new(...) end })
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/tests/examples/gears/shape/arc.lua b/tests/examples/gears/shape/arc.lua
new file mode 100644
index 00000000..6fc696d4
--- /dev/null
+++ b/tests/examples/gears/shape/arc.lua
@@ -0,0 +1,10 @@
+local shape,cr,show = ... --DOC_HIDE
+
+shape.arc(cr,70,70, 10)
+show(cr) --DOC_HIDE
+
+shape.arc(cr,70,70, 10, nil, nil, true, true)
+show(cr) --DOC_HIDE
+
+shape.arc(cr,70,70, nil, 0, 2*math.pi)
+show(cr) --DOC_HIDE
diff --git a/tests/examples/gears/shape/pie.lua b/tests/examples/gears/shape/pie.lua
new file mode 100644
index 00000000..60fafdd4
--- /dev/null
+++ b/tests/examples/gears/shape/pie.lua
@@ -0,0 +1,10 @@
+local shape,cr,show = ... --DOC_HIDE
+
+shape.pie(cr, 70, 70)
+show(cr) --DOC_HIDE
+
+shape.pie(cr,70,70, 1.0471975511966, 4.1887902047864)
+show(cr) --DOC_HIDE
+
+shape.pie(cr,70,70, 0, 2*math.pi, 10)
+show(cr) --DOC_HIDE
diff --git a/tests/examples/wibox/container/arcchart/bg.lua b/tests/examples/wibox/container/arcchart/bg.lua
new file mode 100644
index 00000000..3288a5dd
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/bg.lua
@@ -0,0 +1,38 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {"", "#00ff00", "#0000ff"} do
+ l:add(wibox.widget {
+ {
+ text = v~="" and v or "nil",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = v~="" and v or nil,
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ })
+end
+
+return nil, 60
diff --git a/tests/examples/wibox/container/arcchart/border_width.lua b/tests/examples/wibox/container/arcchart/border_width.lua
new file mode 100644
index 00000000..e553b487
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/border_width.lua
@@ -0,0 +1,48 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local cols = {"#ff000022","#00ff0022","#0000ff22","#ff00ff22"}
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {0,1,3,6.5} do
+ l:add(wibox.widget {
+ {
+ {
+ {
+ text = v,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ bg= "#ff000044",
+ widget = wibox.container.background,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#00ff0033",
+ border_width = v,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ },
+ bg = cols[_],
+ widget = wibox.container.background
+ })
+end
+
+return nil, 60
diff --git a/tests/examples/wibox/container/arcchart/paddings.lua b/tests/examples/wibox/container/arcchart/paddings.lua
new file mode 100644
index 00000000..7b989d00
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/paddings.lua
@@ -0,0 +1,79 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {0, 2, 4} do
+ l:add(wibox.widget {
+ {
+ {
+ text = v,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ bg= beautiful.bg_normal,
+ widget = wibox.container.background,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ paddings = v,
+ widget = wibox.container.arcchart
+ })
+end
+
+l:add(wibox.widget {
+ {
+ {
+ text = 6,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ bg= beautiful.bg_normal,
+ widget = wibox.container.background,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ paddings = {
+ left = 6,
+ right = 6,
+ top = 6,
+ bottom = 6,
+ },
+ widget = wibox.container.arcchart
+ })
+
+return nil, 60
diff --git a/tests/examples/wibox/container/arcchart/rounded_edge.lua b/tests/examples/wibox/container/arcchart/rounded_edge.lua
new file mode 100644
index 00000000..36eb68a9
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/rounded_edge.lua
@@ -0,0 +1,81 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+parent:add(wibox.widget {
+ {
+ {
+ markup = "rounded_edge = false",
+ widget = wibox.widget.textbox
+ },
+ {
+ {
+ {
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ },
+ margins = 2,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ layout = wibox.container.margin
+ },
+ margins = 1,
+ color = beautiful.border_color,
+ layout = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ {
+ {
+ markup = "rounded_edge = true",
+ widget = wibox.widget.textbox
+ },
+ {
+ {
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = true,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ },
+ margins = 1,
+ color = beautiful.border_color,
+ layout = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ layout = wibox.layout.flex.horizontal
+})
+
+return 500, 60
diff --git a/tests/examples/wibox/container/arcchart/start_angle.lua b/tests/examples/wibox/container/arcchart/start_angle.lua
new file mode 100644
index 00000000..244ec527
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/start_angle.lua
@@ -0,0 +1,35 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {0, math.pi/2, math.pi} do
+ l:add(wibox.widget {
+ {
+ text = v,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ value = 1,
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#ff000033",
+ start_angle = v,
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ })
+end
+
+return nil, 60
diff --git a/tests/examples/wibox/container/arcchart/thickness.lua b/tests/examples/wibox/container/arcchart/thickness.lua
new file mode 100644
index 00000000..432e642f
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/thickness.lua
@@ -0,0 +1,39 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {1,3,7,10} do
+ l:add(wibox.widget {
+ {
+ text = v,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ thickness = v,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ })
+end
+
+return nil, 60
diff --git a/tests/examples/wibox/container/arcchart/value.lua b/tests/examples/wibox/container/arcchart/value.lua
new file mode 100644
index 00000000..256224fc
--- /dev/null
+++ b/tests/examples/wibox/container/arcchart/value.lua
@@ -0,0 +1,28 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+l.spacing = 10
+parent:add(l)
+
+for _, v in ipairs {0,1,7,99} do
+ l:add(wibox.widget {
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ value = v,
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = false,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ widget = wibox.container.arcchart
+ })
+end
+
+return nil, 60
diff --git a/tests/examples/wibox/container/defaults/arcchart.lua b/tests/examples/wibox/container/defaults/arcchart.lua
new file mode 100644
index 00000000..284900a6
--- /dev/null
+++ b/tests/examples/wibox/container/defaults/arcchart.lua
@@ -0,0 +1,45 @@
+--DOC_HIDE_ALL
+local wibox = require("wibox")
+local beautiful = require("beautiful")
+
+return {
+ text = "Before",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+},
+{
+ {
+ {
+ text = "After",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ values = {
+ 1,
+ 2,
+ 3,
+ },
+ max_value = 10,
+ min_value = 0,
+ rounded_edge = true,
+ bg = "#ff000033",
+ border_width = 0.5,
+ border_color = "#000000",
+ start_angle = 0,
+ widget = wibox.container.arcchart
+ },
+ margins = 2,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ layout = wibox.container.margin
+}
diff --git a/tests/examples/wibox/container/defaults/radialprogressbar.lua b/tests/examples/wibox/container/defaults/radialprogressbar.lua
new file mode 100644
index 00000000..5ae4190e
--- /dev/null
+++ b/tests/examples/wibox/container/defaults/radialprogressbar.lua
@@ -0,0 +1,25 @@
+--DOC_HIDE_ALL
+local wibox = require("wibox")
+
+return {
+ text = "Before",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+},
+{
+ {
+ {
+ text = "After",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ value = 0.5,
+ max_value = 1,
+ min_value = 0,
+ widget = wibox.container.radialprogressbar
+ },
+ margins = 5,
+ layout = wibox.container.margin
+}
diff --git a/tests/examples/wibox/container/radialprogressbar/border_color.lua b/tests/examples/wibox/container/radialprogressbar/border_color.lua
new file mode 100644
index 00000000..6885a706
--- /dev/null
+++ b/tests/examples/wibox/container/radialprogressbar/border_color.lua
@@ -0,0 +1,26 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require("wibox")
+
+local function gen(val)
+ return wibox.widget {
+ {
+ text = "Value: "..val,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ border_color = val,
+ value = 0.75,
+ widget = wibox.container.radialprogressbar
+ }
+end
+
+local l = wibox.layout {
+ gen("#ff0000"),gen("#00ff00"),gen("#0000ff"),
+ forced_height = 30,
+ forced_width = 400,
+ layout = wibox.layout.flex.horizontal
+}
+
+parent:add(l)
diff --git a/tests/examples/wibox/container/radialprogressbar/border_width.lua b/tests/examples/wibox/container/radialprogressbar/border_width.lua
new file mode 100644
index 00000000..b13bddf7
--- /dev/null
+++ b/tests/examples/wibox/container/radialprogressbar/border_width.lua
@@ -0,0 +1,29 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require("wibox")
+
+local function gen(val)
+ return wibox.widget {
+ {
+ text = "Value: "..val,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ paddings = 0,
+ border_width = val,
+ value = 0.75,
+ max_value = 1,
+ min_value = 0,
+ widget = wibox.container.radialprogressbar
+ }
+end
+
+local l = wibox.layout {
+ gen(1),gen(3),gen(5),
+ forced_height = 30,
+ forced_width = 400,
+ layout = wibox.layout.flex.horizontal
+}
+
+parent:add(l)
diff --git a/tests/examples/wibox/container/radialprogressbar/color.lua b/tests/examples/wibox/container/radialprogressbar/color.lua
new file mode 100644
index 00000000..7c097af5
--- /dev/null
+++ b/tests/examples/wibox/container/radialprogressbar/color.lua
@@ -0,0 +1,26 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require("wibox")
+
+local function gen(val)
+ return wibox.widget {
+ {
+ text = "Value: "..val,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ color = val,
+ value = 0.75,
+ widget = wibox.container.radialprogressbar
+ }
+end
+
+local l = wibox.layout {
+ gen("#ff0000"),gen("#00ff00"),gen("#0000ff"),
+ forced_height = 30,
+ forced_width = 400,
+ layout = wibox.layout.flex.horizontal
+}
+
+parent:add(l)
diff --git a/tests/examples/wibox/container/radialprogressbar/padding.lua b/tests/examples/wibox/container/radialprogressbar/padding.lua
new file mode 100644
index 00000000..9e46370f
--- /dev/null
+++ b/tests/examples/wibox/container/radialprogressbar/padding.lua
@@ -0,0 +1,33 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require("wibox")
+local beautiful = require("beautiful")
+
+local function gen(val)
+ return wibox.widget {
+ {
+ {
+ text = "Value: "..val,
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.widget.background,
+ },
+ paddings = val,
+ value = 0.75,
+ max_value = 1,
+ min_value = 0,
+ widget = wibox.container.radialprogressbar
+ }
+end
+
+local l = wibox.layout {
+ gen(0),gen(5),gen(10),
+ forced_height = 30,
+ forced_width = 400,
+ layout = wibox.layout.flex.horizontal
+}
+
+parent:add(l)
diff --git a/tests/examples/wibox/container/radialprogressbar/value.lua b/tests/examples/wibox/container/radialprogressbar/value.lua
new file mode 100644
index 00000000..a3e7c944
--- /dev/null
+++ b/tests/examples/wibox/container/radialprogressbar/value.lua
@@ -0,0 +1,28 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require("wibox")
+
+local function gen(val)
+ return wibox.widget {
+ {
+ text = "Value: "..(val*100).."%",
+ align = "center",
+ valign = "center",
+ widget = wibox.widget.textbox,
+ },
+ padding = 5,
+ value = val,
+ max_value = 1,
+ min_value = 0,
+ widget = wibox.container.radialprogressbar
+ }
+end
+
+local l = wibox.layout {
+ gen(0.0),gen(0.3),gen(1.0),
+ forced_height = 30,
+ forced_width = 400,
+ layout = wibox.layout.flex.horizontal
+}
+
+parent:add(l)
diff --git a/tests/examples/wibox/widget/checkbox/bg.lua b/tests/examples/wibox/widget/checkbox/bg.lua
new file mode 100644
index 00000000..059c376d
--- /dev/null
+++ b/tests/examples/wibox/widget/checkbox/bg.lua
@@ -0,0 +1,20 @@
+local parent = ... --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+
+parent:add( --DOC_HIDE
+wibox.widget {
+ checked = true,
+ color = beautiful.bg_normal,
+ bg = "#ff00ff",
+ border_width = 3,
+ paddings = 4,
+ border_color = "#0000ff",
+ check_color = "#ff0000",
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ check_border_color = "#ffff00",
+ check_border_width = 1,
+ widget = wibox.widget.checkbox
+}
+) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/checkbox/check_shape.lua b/tests/examples/wibox/widget/checkbox/check_shape.lua
new file mode 100644
index 00000000..8c953e89
--- /dev/null
+++ b/tests/examples/wibox/widget/checkbox/check_shape.lua
@@ -0,0 +1,27 @@
+local parent = ... --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+local gears = {shape = require("gears.shape")} --DOC_HIDE
+
+local l = wibox.widget { --DOC_HIDE
+ spacing = 4, --DOC_HIDE
+ layout = wibox.layout.fixed.horizontal --DOC_HIDE
+} --DOC_HIDE
+
+for _, s in ipairs {"rectangle", "circle", "losange", "octogon"} do
+
+l:add( --DOC_HIDE
+ wibox.widget {
+ checked = true,
+ color = beautiful.bg_normal,
+ paddings = 2,
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ check_shape = gears.shape[s],
+ widget = wibox.widget.checkbox
+ }
+) --DOC_HIDE
+
+end
+
+parent:add(l) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/checkbox/custom.lua b/tests/examples/wibox/widget/checkbox/custom.lua
new file mode 100644
index 00000000..2309a444
--- /dev/null
+++ b/tests/examples/wibox/widget/checkbox/custom.lua
@@ -0,0 +1,33 @@
+local parent = ... --DOC_NO_USAGE --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+
+parent:add( --DOC_HIDE
+ wibox.widget {
+ checked = true,
+ color = beautiful.bg_normal,
+ paddings = 2,
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ check_shape = function(cr, width, height)
+ local rs = math.min(width, height)
+
+ cr:move_to( 0 , 0 )
+ cr:line_to( rs , 0 )
+ cr:move_to( 0 , 0 )
+ cr:line_to( 0 , rs )
+ cr:move_to( 0 , rs )
+ cr:line_to( rs , rs )
+ cr:move_to( rs , 0 )
+ cr:line_to( rs , rs )
+ cr:move_to( 0 , 0 )
+ cr:line_to( rs , rs )
+ cr:move_to( 0 , rs )
+ cr:line_to( rs , 0 )
+ end,
+ check_border_color = "#ff0000",
+ check_color = "#00000000",
+ check_border_width = 1,
+ widget = wibox.widget.checkbox
+ }
+) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/checkbox/shape.lua b/tests/examples/wibox/widget/checkbox/shape.lua
new file mode 100644
index 00000000..680f474b
--- /dev/null
+++ b/tests/examples/wibox/widget/checkbox/shape.lua
@@ -0,0 +1,27 @@
+local parent = ... --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+local gears = {shape = require("gears.shape")} --DOC_HIDE
+
+local l = wibox.widget { --DOC_HIDE
+ spacing = 4, --DOC_HIDE
+ layout = wibox.layout.fixed.horizontal --DOC_HIDE
+} --DOC_HIDE
+
+for _, s in ipairs {"rectangle", "circle", "losange", "octogon"} do
+
+l:add( --DOC_HIDE
+ wibox.widget {
+ checked = true,
+ color = beautiful.bg_normal,
+ paddings = 2,
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ shape = gears.shape[s],
+ widget = wibox.widget.checkbox
+ }
+) --DOC_HIDE
+
+end
+
+parent:add(l) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/defaults/checkbox.lua b/tests/examples/wibox/widget/defaults/checkbox.lua
new file mode 100644
index 00000000..981aa4e0
--- /dev/null
+++ b/tests/examples/wibox/widget/defaults/checkbox.lua
@@ -0,0 +1,31 @@
+local parent = ... --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+local gears = {shape = require("gears.shape")} --DOC_HIDE
+
+parent:add( --DOC_HIDE
+wibox.widget { --DOC_HIDE
+wibox.widget {
+ checked = true,
+ color = beautiful.bg_normal,
+ paddings = 2,
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ shape = gears.shape.circle,
+ widget = wibox.widget.checkbox
+}
+, --DOC_HIDE
+wibox.widget { --DOC_HIDE
+ checked = false, --DOC_HIDE
+ color = beautiful.bg_normal, --DOC_HIDE
+ paddings = 2, --DOC_HIDE
+ forced_width = 20, --DOC_HIDE
+ forced_height = 20, --DOC_HIDE
+ shape = gears.shape.circle, --DOC_HIDE
+ widget = wibox.widget.checkbox --DOC_HIDE
+}, --DOC_HIDE
+spacing = 4, --DOC_HIDE
+layout = wibox.layout.fixed.horizontal --DOC_HIDE
+} --DOC_HIDE
+
+) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/defaults/piechart.lua b/tests/examples/wibox/widget/defaults/piechart.lua
new file mode 100644
index 00000000..a5d61369
--- /dev/null
+++ b/tests/examples/wibox/widget/defaults/piechart.lua
@@ -0,0 +1,24 @@
+local parent = ... --DOC_HIDE
+local wibox = require( "wibox" ) --DOC_HIDE
+local beautiful = require( "beautiful" ) --DOC_HIDE
+
+parent:add( --DOC_HIDE
+
+wibox.widget {
+ data = {
+ ['L1'] = 100,
+ ['L2'] = 200,
+ ['L3'] = 300,
+ },
+ border_width = 1,
+ forced_height = 50, --DOC_HIDE
+ forced_width = 100, --DOC_HIDE
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ widget = wibox.widget.piechart
+}
+
+) --DOC_HIDE
diff --git a/tests/examples/wibox/widget/piechart/border_color.lua b/tests/examples/wibox/widget/piechart/border_color.lua
new file mode 100644
index 00000000..d69375d1
--- /dev/null
+++ b/tests/examples/wibox/widget/piechart/border_color.lua
@@ -0,0 +1,27 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+parent:add(l)
+
+for _, v in ipairs {"#ff0000", "#00ff00", "#0000ff"} do
+ l:add(wibox.widget {
+ data = {
+ ['L1'] = 100,
+ ['L2'] = 200,
+ ['L3'] = 300,
+ },
+ border_width = 1,
+ border_color = v,
+ forced_height = 50,
+ forced_width = 100,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ widget = wibox.widget.piechart
+ })
+end
diff --git a/tests/examples/wibox/widget/piechart/border_width.lua b/tests/examples/wibox/widget/piechart/border_width.lua
new file mode 100644
index 00000000..88a86b62
--- /dev/null
+++ b/tests/examples/wibox/widget/piechart/border_width.lua
@@ -0,0 +1,26 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+local l = wibox.layout.fixed.horizontal()
+parent:add(l)
+
+for _, v in ipairs {0,1,3,5} do
+ l:add(wibox.widget {
+ data = {
+ ['L1'] = 100,
+ ['L2'] = 200,
+ ['L3'] = 300,
+ },
+ border_width = v,
+ forced_height = 50,
+ forced_width = 100,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ widget = wibox.widget.piechart
+ })
+end
diff --git a/tests/examples/wibox/widget/piechart/label.lua b/tests/examples/wibox/widget/piechart/label.lua
new file mode 100644
index 00000000..1315eb22
--- /dev/null
+++ b/tests/examples/wibox/widget/piechart/label.lua
@@ -0,0 +1,68 @@
+--DOC_HIDE_ALL
+local parent = ...
+local wibox = require( "wibox" )
+local beautiful = require( "beautiful" )
+
+parent:add(wibox.widget {
+ {
+ {
+ markup = "display_labels = false",
+ widget = wibox.widget.textbox
+ },
+ {
+ {
+ data = {
+ ['L1'] = 100,
+ ['L2'] = 200,
+ ['L3'] = 300,
+ },
+ border_width = 1,
+ forced_height = 50,
+ forced_width = 100,
+ display_labels = false,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ widget = wibox.widget.piechart
+ },
+ margins = 1,
+ color = beautiful.border_color,
+ layout = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ {
+ {
+ markup = "display_labels = true",
+ widget = wibox.widget.textbox
+ },
+ {
+ {
+ data = {
+ ['L1'] = 100,
+ ['L2'] = 200,
+ ['L3'] = 300,
+ },
+ border_width = 1,
+ forced_height = 50,
+ forced_width = 100,
+ display_labels = true,
+ colors = {
+ beautiful.bg_normal,
+ beautiful.bg_highlight,
+ beautiful.border_color,
+ },
+ widget = wibox.widget.piechart
+ },
+ margins = 1,
+ color = beautiful.border_color,
+ layout = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ layout = wibox.layout.flex.horizontal
+})
+
+return 500, 60