From b74b8ea0cdf753e05b131b705691863c04425b3f Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 18 Jan 2016 03:38:46 -0500 Subject: [PATCH 1/4] margin: Add an option to :fit() -> 0,0 when the content is empty Make it easier to write "optional" widgets, like empty textbox that can be filled only in certain scenarios. --- lib/wibox/layout/margin.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/wibox/layout/margin.lua b/lib/wibox/layout/margin.lua index c84fb3900..9994ec665 100644 --- a/lib/wibox/layout/margin.lua +++ b/lib/wibox/layout/margin.lua @@ -55,6 +55,11 @@ function margin:fit(context, width, height) if self.widget then w, h = base.fit_widget(self, context, self.widget, width - extra_w, height - extra_h) end + + if self._draw_empty == false and (w == 0 or h == 0) then + return 0, 0 + end + return w + extra_w, h + extra_h end @@ -82,6 +87,13 @@ function margin:set_color(color) self:emit_signal("widget::redraw_needed") end +--- Draw the margin even if the content size is 0x0 (default: true) +-- @tparam boolean draw_empty Draw nothing is content is 0x0 or draw the margin anyway +function margin:set_draw_empty(draw_empty) + self._draw_empty = draw_empty + self:emit_signal("widget::layout_changed") +end + --- Reset this layout. The widget will be unreferenced, the margins set to 0 -- and the color erased function margin:reset() @@ -129,7 +141,8 @@ end -- @param[opt] top A margin to use on the top side of the widget. -- @param[opt] bottom A margin to use on the bottom side of the widget. -- @param[opt] color A color for the margins. -local function new(widget, left, right, top, bottom, color) +-- @param[opt] draw_empty whether or not to draw the margin when the content is empty +local function new(widget, left, right, top, bottom, color, draw_empty) local ret = base.make_widget() for k, v in pairs(margin) do @@ -142,6 +155,7 @@ local function new(widget, left, right, top, bottom, color) ret:set_right(right or 0) ret:set_top(top or 0) ret:set_bottom(bottom or 0) + ret:set_draw_empty(draw_empty) ret:set_color(color) From fb0c82a79891aaa7dc577194325d46334e286653 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 18 Jan 2016 17:20:32 -0500 Subject: [PATCH 2/4] gears.shape: Add a new module to make it easier to use shapes This code is imported from Elv13 config and make it very easy to create shaped objects. If accepted upstream, other shapes, such as arrow and powerline will also be added. This commit introsuce the 2 most common shapes, rounded rectangle and rounded bar. --- lib/gears/init.lua | 1 + lib/gears/shape.lua | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 lib/gears/shape.lua diff --git a/lib/gears/init.lua b/lib/gears/init.lua index 3289483ac..fab5d1f52 100644 --- a/lib/gears/init.lua +++ b/lib/gears/init.lua @@ -17,6 +17,7 @@ return timer = require("gears.timer"); cache = require("gears.cache"); matrix = require("gears.matrix"); + shape = require("gears.shape"); } -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/gears/shape.lua b/lib/gears/shape.lua new file mode 100644 index 000000000..dd7594250 --- /dev/null +++ b/lib/gears/shape.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------- +--- Module dedicated to gather common shape painters. +-- +-- It add the concept of "shape" to Awesome. A shape can be applied to a +-- background, a margin, a mask or a drawable shape bounding. +-- +-- The functions exposed by this module always take a context as first +-- parameter followed by the widget and height and additional parameters. +-- +-- The functions provided by this module only create a path in the content. +-- to actually draw the content, use cr:fill(), cr:mask(), cr:slip() or +-- cr:stroke() +-- +-- In many case, it is necessary to apply the shape using a transformation +-- such as a rotation. The preferred way to do this is to wrap the function +-- in another function calling `cr:rotate()` (or any other transformation +-- matrix) +-- +-- @author Emmanuel Lepage Vallee +-- @copyright 2011-2016 Emmanuel Lepage Vallee +-- @release @AWESOME_VERSION@ +-- @module gears.shape +--------------------------------------------------------------------------- + +local module = {} + +--- Add a rounded rectangle to the current path +-- @note If the radius is bigger than either half side, it will be reduced +-- @param cr A cairo content +-- @param width The rectangle width +-- @param height The rectangle height +-- @param radius the corner radius +function module.rounded_rect(cr, width, height, radius) + if width / 2 < radius then + radius = width / 2 + end + + if height / 2 < radius then + radius = height / 2 + end + + cr:arc( radius , radius , radius, math.pi , 3*(math.pi/2) ) + cr:arc( width-radius, radius , radius, 3*(math.pi/2), math.pi*2 ) + cr:arc( width-radius, height-radius, radius, math.pi*2 , math.pi/2 ) + cr:arc( radius , height-radius, radius, math.pi/2 , math.pi ) + + cr:close_path() +end + +--- Add a rectangle delimited by 2 180 degree arcs to the path +-- @param cr A cairo content +-- @param width The rectangle width +-- @param height The rectangle height +function module.rounded_bar(cr, width, height) + module.rounded_rect(cr, width, height, height / 2) +end + +return module From dd93418afb5297211c7078bd6567e4895b14b595 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 18 Jan 2016 17:22:44 -0500 Subject: [PATCH 3/4] gears.surface: Add an helper to set a shape to drawable --- lib/gears/surface.lua | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/gears/surface.lua b/lib/gears/surface.lua index 427c51b19..404f38cfa 100644 --- a/lib/gears/surface.lua +++ b/lib/gears/surface.lua @@ -152,6 +152,32 @@ function surface.duplicate_surface(s) return result end +--- Apply a shape to a client or a wibox. +-- +-- If the wibox or client size change, this function need to be called +-- again. +-- @param draw A wibox or a client +-- @param shape or gears.shape function or a custom function with a context, +-- width and height as parameter. +-- @param[opt] Any additional parameters will be passed to the shape function +function surface.apply_shape_bounding(draw, shape, ...) + local geo = draw:geometry() + + local img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height) + local cr = cairo.Context(img) + + cr:set_operator(cairo.Operator.CLEAR) + cr:set_source_rgba(0,0,0,1) + cr:paint() + cr:set_operator(cairo.Operator.SOURCE) + cr:set_source_rgba(1,1,1,1) + + shape(cr, geo.width, geo.height, ...) + + cr:fill() + + draw.shape_bounding = img._native +end return setmetatable(surface, surface.mt) From d01c1d2d6d2a993dff7a6790684f4d08b0b66245 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 18 Jan 2016 17:08:21 -0500 Subject: [PATCH 4/4] widget.background: Allow background to have a shape --- lib/wibox/widget/background.lua | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/wibox/widget/background.lua b/lib/wibox/widget/background.lua index e8f2c3f82..101311618 100644 --- a/lib/wibox/widget/background.lua +++ b/lib/wibox/widget/background.lua @@ -21,6 +21,11 @@ function background:draw(context, cr, width, height) return end + if self._shape then + self._shape(cr, width, height, unpack(self._shape_args or {})) + cr:clip() + end + if self.background then cr:set_source(self.background) cr:paint() @@ -84,6 +89,15 @@ function background:set_fg(fg) self:emit_signal("widget::redraw_needed") end +--- Set the background shape +-- @param shape A function taking a context, width and height as arguments +-- Any other arguments will be passed to the shape function +function background:set_shape(shape, ...) + ret._shape = shape + ret._shape_args = {...} + self:emit_signal("widget::redraw_needed") +end + --- Set the background image to use function background:set_bgimage(image) self.bgimage = surface.load(image) @@ -94,7 +108,8 @@ end -- and foreground color to another widget. -- @param[opt] widget The widget to display. -- @param[opt] bg The background to use for that widget. -local function new(widget, bg) +-- @param[opt] shape A `gears.shape` compatible shape function +local function new(widget, bg, shape) local ret = base.make_widget() for k, v in pairs(background) do @@ -103,6 +118,8 @@ local function new(widget, bg) end end + ret._shape = shape + ret:set_widget(widget) ret:set_bg(bg)