common: Refactor awful.widget.common to support external extensions
This commit allow user defined delegates to be used as list elements. This put an end to the endless attempt to cram more features into this code. A widget template (non-instantiated) is passed to the arguments and is created by the common code. It also supports "roles" where some user defined widgets can replace the old textbox or imagebox.
This commit is contained in:
parent
2e7cd2b2ef
commit
f147f0d28a
|
@ -9,7 +9,9 @@ local type = type
|
||||||
local ipairs = ipairs
|
local ipairs = ipairs
|
||||||
local capi = { button = button }
|
local capi = { button = button }
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
|
local gdebug = require("gears.debug")
|
||||||
local dpi = require("beautiful").xresources.apply_dpi
|
local dpi = require("beautiful").xresources.apply_dpi
|
||||||
|
local base = require("wibox.widget.base")
|
||||||
|
|
||||||
--- Common utilities for awful widgets
|
--- Common utilities for awful widgets
|
||||||
local common = {}
|
local common = {}
|
||||||
|
@ -36,6 +38,52 @@ function common.create_buttons(buttons, object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function default_template()
|
||||||
|
local ib = wibox.widget.imagebox()
|
||||||
|
local tb = wibox.widget.textbox()
|
||||||
|
local bgb = wibox.container.background()
|
||||||
|
local tbm = wibox.container.margin(tb, dpi(4), dpi(4))
|
||||||
|
local ibm = wibox.container.margin(ib, dpi(4))
|
||||||
|
local l = wibox.layout.fixed.horizontal()
|
||||||
|
|
||||||
|
-- All of this is added in a fixed widget
|
||||||
|
l:fill_space(true)
|
||||||
|
l:add(ibm)
|
||||||
|
l:add(tbm)
|
||||||
|
|
||||||
|
-- And all of this gets a background
|
||||||
|
bgb:set_widget(l)
|
||||||
|
|
||||||
|
return {
|
||||||
|
ib = ib,
|
||||||
|
tb = tb,
|
||||||
|
bgb = bgb,
|
||||||
|
tbm = tbm,
|
||||||
|
ibm = ibm,
|
||||||
|
primary = l,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function custom_template(args)
|
||||||
|
local l = base.make_widget_from_value(args.widget_template)
|
||||||
|
|
||||||
|
-- The template system requires being able to get children elements by ids.
|
||||||
|
-- This is not optimal, but for now there is no way around it.
|
||||||
|
assert(l.get_children_by_id,"The given widget template did not result in a"..
|
||||||
|
"layout with a 'get_children_by_id' method")
|
||||||
|
|
||||||
|
return {
|
||||||
|
ib = l:get_children_by_id( "icon_role" )[1],
|
||||||
|
tb = l:get_children_by_id( "text_role" )[1],
|
||||||
|
bgb = l:get_children_by_id( "background_role" )[1],
|
||||||
|
tbm = l:get_children_by_id( "text_margin_role" )[1],
|
||||||
|
ibm = l:get_children_by_id( "icon_margin_role" )[1],
|
||||||
|
primary = l,
|
||||||
|
update_callback = l.update_callback,
|
||||||
|
create_callback = l.create_callback,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
--- Common update method.
|
--- Common update method.
|
||||||
-- @param w The widget.
|
-- @param w The widget.
|
||||||
-- @tab buttons
|
-- @tab buttons
|
||||||
|
@ -44,73 +92,69 @@ end
|
||||||
-- has to return `text`, `bg`, `bg_image`, `icon`.
|
-- has to return `text`, `bg`, `bg_image`, `icon`.
|
||||||
-- @tab data Current data/cache, indexed by objects.
|
-- @tab data Current data/cache, indexed by objects.
|
||||||
-- @tab objects Objects to be displayed / updated.
|
-- @tab objects Objects to be displayed / updated.
|
||||||
function common.list_update(w, buttons, label, data, objects)
|
-- @tparam[opt={}] table args
|
||||||
|
function common.list_update(w, buttons, label, data, objects, args)
|
||||||
-- update the widgets, creating them if needed
|
-- update the widgets, creating them if needed
|
||||||
w:reset()
|
w:reset()
|
||||||
for i, o in ipairs(objects) do
|
for i, o in ipairs(objects) do
|
||||||
local cache = data[o]
|
local cache = data[o]
|
||||||
local ib, tb, bgb, tbm, ibm, l
|
|
||||||
if cache then
|
|
||||||
ib = cache.ib
|
|
||||||
tb = cache.tb
|
|
||||||
bgb = cache.bgb
|
|
||||||
tbm = cache.tbm
|
|
||||||
ibm = cache.ibm
|
|
||||||
else
|
|
||||||
ib = wibox.widget.imagebox()
|
|
||||||
tb = wibox.widget.textbox()
|
|
||||||
bgb = wibox.container.background()
|
|
||||||
tbm = wibox.container.margin(tb, dpi(4), dpi(4))
|
|
||||||
ibm = wibox.container.margin(ib, dpi(4))
|
|
||||||
l = wibox.layout.fixed.horizontal()
|
|
||||||
|
|
||||||
-- All of this is added in a fixed widget
|
if not cache then
|
||||||
l:fill_space(true)
|
cache = (args and args.widget_template) and
|
||||||
l:add(ibm)
|
custom_template(args) or default_template()
|
||||||
l:add(tbm)
|
|
||||||
|
|
||||||
-- And all of this gets a background
|
cache.primary:buttons(common.create_buttons(buttons, o))
|
||||||
bgb:set_widget(l)
|
|
||||||
|
|
||||||
bgb:buttons(common.create_buttons(buttons, o))
|
if cache.create_callback then
|
||||||
|
cache.create_callback(cache.primary, o, i, objects)
|
||||||
|
end
|
||||||
|
|
||||||
data[o] = {
|
data[o] = cache
|
||||||
ib = ib,
|
elseif cache.update_callback then
|
||||||
tb = tb,
|
cache.update_callback(cache.primary, o, i, objects)
|
||||||
bgb = bgb,
|
|
||||||
tbm = tbm,
|
|
||||||
ibm = ibm,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local text, bg, bg_image, icon, args = label(o, tb)
|
local text, bg, bg_image, icon, item_args = label(o, cache.tb)
|
||||||
args = args or {}
|
item_args = item_args or {}
|
||||||
|
|
||||||
-- The text might be invalid, so use pcall.
|
-- The text might be invalid, so use pcall.
|
||||||
if text == nil or text == "" then
|
if cache.tbm and (text == nil or text == "") then
|
||||||
tbm:set_margins(0)
|
cache.tbm:set_margins(0)
|
||||||
else
|
elseif cache.tb then
|
||||||
if not tb:set_markup_silently(text) then
|
if not cache.tb:set_markup_silently(text) then
|
||||||
tb:set_markup("<i><Invalid text></i>")
|
cache.tb:set_markup("<i><Invalid text></i>")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
bgb:set_bg(bg)
|
|
||||||
if type(bg_image) == "function" then
|
if cache.bgb then
|
||||||
-- TODO: Why does this pass nil as an argument?
|
cache.bgb:set_bg(bg)
|
||||||
bg_image = bg_image(tb,o,nil,objects,i)
|
|
||||||
end
|
--TODO v5 remove this if, it existed only for a removed and
|
||||||
bgb:set_bgimage(bg_image)
|
-- undocumented API
|
||||||
if icon then
|
if type(bg_image) ~= "function" then
|
||||||
ib:set_image(icon)
|
cache.bgb:set_bgimage(bg_image)
|
||||||
else
|
else
|
||||||
ibm:set_margins(0)
|
gdebug.deprecate("If you read this, you used an undocumented API"..
|
||||||
|
" which has been replaced by the new awful.widget.common "..
|
||||||
|
"templating system, please migrate now. This feature is "..
|
||||||
|
"already staged for removal", {
|
||||||
|
deprecated_in = 4
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
cache.bgb.shape = item_args.shape
|
||||||
|
cache.bgb.shape_border_width = item_args.shape_border_width
|
||||||
|
cache.bgb.shape_border_color = item_args.shape_border_color
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
bgb.shape = args.shape
|
if cache.ib and icon then
|
||||||
bgb.shape_border_width = args.shape_border_width
|
cache.ib:set_image(icon)
|
||||||
bgb.shape_border_color = args.shape_border_color
|
elseif cache.ibm then
|
||||||
|
cache.ibm:set_margins(0)
|
||||||
|
end
|
||||||
|
|
||||||
w:add(bgb)
|
w:add(cache.primary)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue