2016-05-23 05:56:45 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
-- A container capable of changing the background color, foreground color
|
|
|
|
-- widget shape.
|
2016-05-24 19:38:37 +02:00
|
|
|
--
|
|
|
|
--@DOC_wibox_container_defaults_background_EXAMPLE@
|
2016-05-23 05:56:45 +02:00
|
|
|
-- @author Uli Schlachter
|
|
|
|
-- @copyright 2010 Uli Schlachter
|
|
|
|
-- @classmod wibox.container.background
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
local base = require("wibox.widget.base")
|
|
|
|
local color = require("gears.color")
|
|
|
|
local surface = require("gears.surface")
|
|
|
|
local beautiful = require("beautiful")
|
|
|
|
local cairo = require("lgi").cairo
|
2017-03-08 21:18:33 +01:00
|
|
|
local gtable = require("gears.table")
|
2016-05-23 05:56:45 +02:00
|
|
|
local setmetatable = setmetatable
|
|
|
|
local type = type
|
|
|
|
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
|
|
|
|
|
|
|
local background = { mt = {} }
|
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
-- Make sure a surface pattern is freed *now*
|
|
|
|
local function dispose_pattern(pattern)
|
|
|
|
local status, s = pattern:get_surface()
|
|
|
|
if status == "SUCCESS" then
|
|
|
|
s:finish()
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
end
|
2016-05-23 05:56:45 +02:00
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
-- Prepare drawing the children of this widget
|
|
|
|
function background:before_draw_children(context, cr, width, height)
|
|
|
|
-- Redirect drawing to a temporary surface if there is a shape
|
2016-05-26 07:18:20 +02:00
|
|
|
if self._private.shape then
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
cr:push_group_with_content(cairo.Content.COLOR_ALPHA)
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
-- Draw the background
|
2016-05-26 07:18:20 +02:00
|
|
|
if self._private.background then
|
2019-01-27 11:30:08 +01:00
|
|
|
cr:save()
|
2016-05-26 07:18:20 +02:00
|
|
|
cr:set_source(self._private.background)
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
cr:rectangle(0, 0, width, height)
|
|
|
|
cr:fill()
|
2019-01-27 11:30:08 +01:00
|
|
|
cr:restore()
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
2016-05-26 07:18:20 +02:00
|
|
|
if self._private.bgimage then
|
2019-01-27 11:30:08 +01:00
|
|
|
cr:save()
|
2016-05-26 07:18:20 +02:00
|
|
|
if type(self._private.bgimage) == "function" then
|
|
|
|
self._private.bgimage(context, cr, width, height,unpack(self._private.bgimage_args))
|
2016-05-23 05:56:45 +02:00
|
|
|
else
|
2016-05-26 07:18:20 +02:00
|
|
|
local pattern = cairo.Pattern.create_for_surface(self._private.bgimage)
|
2016-05-23 05:56:45 +02:00
|
|
|
cr:set_source(pattern)
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
cr:rectangle(0, 0, width, height)
|
|
|
|
cr:fill()
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
2019-01-27 11:30:08 +01:00
|
|
|
cr:restore()
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
2019-02-01 15:28:29 +01:00
|
|
|
|
|
|
|
if self._private.foreground then
|
|
|
|
cr:set_source(self._private.foreground)
|
|
|
|
end
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Draw the border
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
function background:after_draw_children(_, cr, width, height)
|
|
|
|
if not self._private.shape then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Okay, there is a shape. Get it as a path.
|
|
|
|
local bw = self._private.shape_border_width or 0
|
|
|
|
|
|
|
|
cr:translate(bw, bw)
|
|
|
|
self._private.shape(cr, width - 2*bw, height - 2*bw, unpack(self._private.shape_args or {}))
|
|
|
|
cr:translate(-bw, -bw)
|
|
|
|
|
|
|
|
if bw > 0 then
|
|
|
|
-- Now we need to do a border, somehow. We begin with another
|
|
|
|
-- temporary surface.
|
|
|
|
cr:push_group_with_content(cairo.Content.ALPHA)
|
|
|
|
|
|
|
|
-- Mark everything as "this is border"
|
|
|
|
cr:set_source_rgba(0, 0, 0, 1)
|
|
|
|
cr:paint()
|
|
|
|
|
|
|
|
-- Now remove the inside of the shape to get just the border
|
|
|
|
cr:set_operator(cairo.Operator.SOURCE)
|
|
|
|
cr:set_source_rgba(0, 0, 0, 0)
|
|
|
|
cr:fill_preserve()
|
|
|
|
|
|
|
|
local mask = cr:pop_group()
|
|
|
|
-- Now actually draw the border via the mask we just created.
|
2016-05-26 07:18:20 +02:00
|
|
|
cr:set_source(color(self._private.shape_border_color or self._private.foreground or beautiful.fg_normal))
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
cr:set_operator(cairo.Operator.SOURCE)
|
|
|
|
cr:mask(mask)
|
2016-05-23 05:56:45 +02:00
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
dispose_pattern(mask)
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
-- We now have the right content in a temporary surface. Copy it to the
|
|
|
|
-- target surface. For this, we need another mask
|
|
|
|
cr:push_group_with_content(cairo.Content.ALPHA)
|
2016-05-23 05:56:45 +02:00
|
|
|
|
Change the way the shape is done in the background container
Previously, the background container "just" used the shape and drew a
line around it. This means that half the line will be inside of the
shape and half of it will be outside. Thus, this hides the actual shape
that is used.
This commit changes that so that the line is added outside of the shape.
It does this via some tricks:
- In :before_draw_children(), :push_group() is used to redirect drawing
of the child widget to a temporary surface.
- In :after_draw_children(), the border is added to this group.
+ For this, another temporary surface is created. It will be used as a
mask.
+ The inside of the shape on this mask is cleared, everything else is
filled. Thus, the mask now contains everything "not content".
+ Everything inside the mask is filled with the background color.
- Also in :after_draw_children(), the group is drawn to the actual
target surface.
+ Again, this needs a mask.
+ This time, we draw the shape to the mask with twice the border width.
Thus, half of this line will be outside of the shape.
+ Then, the shape itself is also filled so that the mask contains the
shape and the border.
+ This mask is then used to copy the right parts of the temporary
surface were the child widget and border was drawn to the actual
target surface that will be visible on screen.
This approach has some upsides. Because we no longer have "half the
border" above content, colors with some transparency work fine for the
border. Also, this should avoid issues with anti-aliasing, because e.g.
the border is not just drawn with the border width, but also further out
to everything else so that the background cannot "bleed through".
Fixes: https://github.com/awesomeWM/awesome/issues/2516
Signed-off-by: Uli Schlachter <psychon@znc.in>
2019-01-25 15:16:17 +01:00
|
|
|
-- Draw the border with 2 * border width (this draws both
|
|
|
|
-- inside and outside, only half of it is outside)
|
|
|
|
cr.line_width = 2 * bw
|
|
|
|
cr:set_source_rgba(0, 0, 0, 1)
|
|
|
|
cr:stroke_preserve()
|
|
|
|
|
|
|
|
-- Now fill the whole inside so that it is also include in the mask
|
|
|
|
cr:fill()
|
|
|
|
|
|
|
|
local mask = cr:pop_group()
|
|
|
|
local source = cr:pop_group() -- This pops what was pushed in before_draw_children
|
|
|
|
|
|
|
|
-- This now draws the content of the background widget to the actual
|
|
|
|
-- target, but only the part that is inside the mask
|
|
|
|
cr:set_operator(cairo.Operator.OVER)
|
|
|
|
cr:set_source(source)
|
|
|
|
cr:mask(mask)
|
|
|
|
|
|
|
|
dispose_pattern(mask)
|
|
|
|
dispose_pattern(source)
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Layout this widget
|
|
|
|
function background:layout(_, width, height)
|
2016-05-26 07:18:20 +02:00
|
|
|
if self._private.widget then
|
|
|
|
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Fit this widget into the given area
|
|
|
|
function background:fit(context, width, height)
|
2016-05-26 07:18:20 +02:00
|
|
|
if not self._private.widget then
|
2016-05-23 05:56:45 +02:00
|
|
|
return 0, 0
|
|
|
|
end
|
|
|
|
|
2016-05-26 07:18:20 +02:00
|
|
|
return base.fit_widget(self, context, self._private.widget, width, height)
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
--- The widget displayed in the background widget.
|
|
|
|
-- @property widget
|
2016-05-23 05:56:45 +02:00
|
|
|
-- @tparam widget widget The widget to be disaplayed inside of the background
|
|
|
|
-- area
|
2016-05-26 08:09:18 +02:00
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_widget(widget)
|
|
|
|
if widget then
|
|
|
|
base.check_widget(widget)
|
|
|
|
end
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.widget = widget
|
2016-05-23 05:56:45 +02:00
|
|
|
self:emit_signal("widget::layout_changed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_widget()
|
|
|
|
return self._private.widget
|
|
|
|
end
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
-- Get children element
|
|
|
|
-- @treturn table The children
|
|
|
|
function background:get_children()
|
2016-05-26 07:18:20 +02:00
|
|
|
return {self._private.widget}
|
2016-05-23 05:56:45 +02:00
|
|
|
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 background:set_children(children)
|
|
|
|
self:set_widget(children[1])
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
--- The background color/pattern/gradient to use.
|
2016-05-23 06:09:57 +02:00
|
|
|
--@DOC_wibox_container_background_bg_EXAMPLE@
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @property bg
|
|
|
|
-- @param bg A color string, pattern or gradient
|
|
|
|
-- @see gears.color
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_bg(bg)
|
|
|
|
if bg then
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.background = color(bg)
|
2016-05-23 05:56:45 +02:00
|
|
|
else
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.background = nil
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_bg()
|
|
|
|
return self._private.background
|
|
|
|
end
|
|
|
|
|
|
|
|
--- The foreground (text) color/pattern/gradient to use.
|
2016-05-23 06:09:57 +02:00
|
|
|
--@DOC_wibox_container_background_fg_EXAMPLE@
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @property fg
|
|
|
|
-- @param fg A color string, pattern or gradient
|
|
|
|
-- @see gears.color
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_fg(fg)
|
|
|
|
if fg then
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.foreground = color(fg)
|
2016-05-23 05:56:45 +02:00
|
|
|
else
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.foreground = nil
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_fg()
|
|
|
|
return self._private.foreground
|
|
|
|
end
|
|
|
|
|
2016-05-26 20:25:07 +02:00
|
|
|
--- The background shap e.
|
2016-05-26 08:09:18 +02:00
|
|
|
--
|
|
|
|
-- Use `set_shape` to set additional shape paramaters.
|
|
|
|
--
|
|
|
|
--@DOC_wibox_container_background_shape_EXAMPLE@
|
|
|
|
-- @property shape
|
|
|
|
-- @param shape A function taking a context, width and height as arguments
|
|
|
|
-- @see gears.shape
|
|
|
|
-- @see set_shape
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
--- Set the background shape.
|
|
|
|
--
|
|
|
|
-- Any other arguments will be passed to the shape function
|
|
|
|
-- @param shape A function taking a context, width and height as arguments
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @see gears.shape
|
|
|
|
-- @see shape
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_shape(shape, ...)
|
2016-08-05 07:13:20 +02:00
|
|
|
local args = {...}
|
|
|
|
|
|
|
|
if shape == self._private.shape and #args == 0 then return end
|
|
|
|
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.shape = shape
|
|
|
|
self._private.shape_args = {...}
|
2016-05-23 05:56:45 +02:00
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_shape()
|
|
|
|
return self._private.shape
|
|
|
|
end
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
--- When a `shape` is set, also draw a border.
|
|
|
|
--
|
2016-05-26 08:09:18 +02:00
|
|
|
-- See `wibox.container.background.shape` for an usage example.
|
|
|
|
-- @property shape_border_width
|
2016-05-23 05:56:45 +02:00
|
|
|
-- @tparam number width The border width
|
2016-05-26 08:09:18 +02:00
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_shape_border_width(width)
|
2016-08-05 07:13:20 +02:00
|
|
|
if self._private.shape_border_width == width then return end
|
|
|
|
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.shape_border_width = width
|
2016-05-23 05:56:45 +02:00
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_shape_border_width()
|
|
|
|
return self._private.shape_border_width
|
|
|
|
end
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
--- When a `shape` is set, also draw a border.
|
|
|
|
--
|
2016-05-26 08:09:18 +02:00
|
|
|
-- See `wibox.container.background.shape` for an usage example.
|
|
|
|
-- @property shape_border_color
|
2016-05-26 07:18:20 +02:00
|
|
|
-- @param[opt=self._private.foreground] fg The border color, pattern or gradient
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @see gears.color
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_shape_border_color(fg)
|
2016-08-05 07:13:20 +02:00
|
|
|
if self._private.shape_border_color == fg then return end
|
|
|
|
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.shape_border_color = fg
|
2016-05-23 05:56:45 +02:00
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_shape_border_color()
|
|
|
|
return self._private.shape_border_color
|
|
|
|
end
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_shape_clip(value)
|
2019-01-28 14:55:53 +01:00
|
|
|
if value then return end
|
|
|
|
require("gears.debug").print_warning("shape_clip property of background container was removed."
|
|
|
|
.. " Use wibox.layout.stack instead if you want shape_clip=false.")
|
2016-05-23 05:56:45 +02:00
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_shape_clip()
|
2019-01-28 14:55:53 +01:00
|
|
|
require("gears.debug").print_warning("shape_clip property of background container was removed."
|
|
|
|
.. " Use wibox.layout.stack instead if you want shape_clip=false.")
|
|
|
|
return true
|
2016-05-26 08:09:18 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- The background image to use
|
2016-05-23 05:56:45 +02:00
|
|
|
-- If `image` is a function, it will be called with `(context, cr, width, height)`
|
|
|
|
-- as arguments. Any other arguments passed to this method will be appended.
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @property bgimage
|
2016-05-23 05:56:45 +02:00
|
|
|
-- @param image A background image or a function
|
2016-05-26 08:09:18 +02:00
|
|
|
-- @see gears.surface
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
function background:set_bgimage(image, ...)
|
2016-05-26 07:18:20 +02:00
|
|
|
self._private.bgimage = type(image) == "function" and image or surface.load(image)
|
|
|
|
self._private.bgimage_args = {...}
|
2016-05-23 05:56:45 +02:00
|
|
|
self:emit_signal("widget::redraw_needed")
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
function background:get_bgimage()
|
|
|
|
return self._private.bgimage
|
|
|
|
end
|
|
|
|
|
2016-05-23 08:46:28 +02:00
|
|
|
--- Returns a new background container.
|
|
|
|
--
|
|
|
|
-- A background container applies a background and foreground color
|
|
|
|
-- to another widget.
|
2016-05-23 05:56:45 +02:00
|
|
|
-- @param[opt] widget The widget to display.
|
|
|
|
-- @param[opt] bg The background to use for that widget.
|
|
|
|
-- @param[opt] shape A `gears.shape` compatible shape function
|
2016-05-23 08:46:28 +02:00
|
|
|
-- @function wibox.container.background
|
2016-05-23 05:56:45 +02:00
|
|
|
local function new(widget, bg, shape)
|
2016-05-26 08:09:18 +02:00
|
|
|
local ret = base.make_widget(nil, nil, {
|
|
|
|
enable_properties = true,
|
|
|
|
})
|
2016-05-23 05:56:45 +02:00
|
|
|
|
2017-03-08 21:18:33 +01:00
|
|
|
gtable.crush(ret, background, true)
|
2016-05-23 05:56:45 +02:00
|
|
|
|
2016-05-26 07:18:20 +02:00
|
|
|
ret._private.shape = shape
|
2016-05-23 05:56:45 +02:00
|
|
|
|
|
|
|
ret:set_widget(widget)
|
|
|
|
ret:set_bg(bg)
|
|
|
|
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
|
|
|
function background.mt:__call(...)
|
|
|
|
return new(...)
|
|
|
|
end
|
|
|
|
|
2016-05-26 08:09:18 +02:00
|
|
|
--@DOC_widget_COMMON@
|
|
|
|
|
2016-05-26 21:12:56 +02:00
|
|
|
--@DOC_object_COMMON@
|
|
|
|
|
2016-05-23 05:56:45 +02:00
|
|
|
return setmetatable(background, background.mt)
|
|
|
|
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|