-
Notifications
You must be signed in to change notification settings - Fork 599
/
Copy pathcommon.lua
213 lines (184 loc) · 7.36 KB
/
common.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
---------------------------------------------------------------------------
-- This module contains helper functions to manage a layout widgets.
--
-- This is the boilerplate code to manage a "list" of objects and display
-- them in a `wibox.layout`. It uses signals to detect when an object change
-- and its widget be updated.
--
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008-2009 Julien Danjou
-- @classmod awful.widget.common
---------------------------------------------------------------------------
-- Grab environment we need
local type = type
local ipairs = ipairs
local capi = { button = button }
local wibox = require("wibox")
local gdebug = require("gears.debug")
local dpi = require("beautiful").xresources.apply_dpi
local base = require("wibox.widget.base")
--- Common utilities for awful widgets
local common = {}
--- Common method to create buttons.
-- @tparam table buttons
-- @param object
-- @treturn table
function common.create_buttons(buttons, object)
local is_formatted = buttons and buttons[1] and (
type(buttons[1]) == "button" or buttons[1]._is_capi_button) or false
if buttons then
local btns = {}
for _, src in ipairs(buttons) do
--TODO v6 Remove this legacy overhead
for _, b in ipairs(is_formatted and {src} or src) do
-- Create a proxy button object: it will receive the real
-- press and release events, and will propagate them to the
-- button object the user provided, but with the object as
-- argument.
local btn = capi.button { modifiers = b.modifiers, button = b.button }
btn:connect_signal("press", function () b:emit_signal("press", object) end)
btn:connect_signal("release", function () b:emit_signal("release", object) end)
btns[#btns + 1] = btn
end
end
return btns
end
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
local function default_template()
return custom_template {
widget_template = {
id = 'background_role',
border_strategy = 'inner',
widget = wibox.container.background,
{
widget = wibox.layout.fixed.horizontal,
fill_space = true,
{
id = 'icon_margin_role',
widget = wibox.container.margin,
{
id = 'icon_role',
widget = wibox.widget.imagebox,
left = dpi(4),
},
},
{
id = 'text_margin_role',
widget = wibox.container.margin,
left = dpi(4),
right = dpi(4),
{
id = 'text_role',
widget = wibox.widget.textbox,
},
}
}
}
}
end
-- Find all the childrens (without the hierarchy) and set a property.
function common._set_common_property(widget, property, value)
if widget["set_"..property] then
widget["set_"..property](widget, value)
end
if widget.get_children then
for _, w in ipairs(widget:get_children()) do
common._set_common_property(w, property, value)
end
end
end
--- Common update method.
-- @param w The widget.
-- @tparam table buttons
-- @func label Function to generate label parameters from an object.
-- The function gets passed an object from `objects`, and
-- has to return `text`, `bg`, `bg_image`, `icon`.
-- @tparam table data Current data/cache, indexed by objects.
-- @tparam table objects Objects to be displayed / updated.
-- @tparam[opt={}] table args
function common.list_update(w, buttons, label, data, objects, args)
-- update the widgets, creating them if needed
w:reset()
for i, o in ipairs(objects) do
local cache = data[o]
-- Allow the buttons to be replaced.
if cache and cache._buttons ~= buttons then
cache = nil
end
if not cache then
cache = (args and args.widget_template) and
custom_template(args) or default_template()
cache.primary.buttons = {common.create_buttons(buttons, o)}
if cache.create_callback then
cache.create_callback(cache.primary, o, i, objects)
end
if args and args.create_callback then
args.create_callback(cache.primary, o, i, objects)
end
cache._buttons = buttons
data[o] = cache
elseif cache.update_callback then
cache.update_callback(cache.primary, o, i, objects)
end
local text, bg, bg_image, icon, item_args = label(o, cache.tb)
item_args = item_args or {}
-- The text might be invalid, so use pcall.
if cache.tbm and (text == nil or text == "") then
cache.tbm:set_margins(0)
elseif cache.tb then
if not cache.tb:set_markup_silently(text) then
cache.tb:set_markup("<i><Invalid text></i>")
end
end
if cache.bgb then
cache.bgb:set_bg(bg)
--TODO v5 remove this if, it existed only for a removed and
-- undocumented API
if type(bg_image) ~= "function" then
cache.bgb:set_bgimage(bg_image)
else
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.border_width = item_args.shape_border_width
cache.bgb.border_color = item_args.shape_border_color
end
if cache.ib and icon then
cache.ib:set_image(icon)
elseif cache.ibm then
cache.ibm:set_margins(0)
end
if item_args.icon_size and cache.ib then
cache.ib.forced_height = item_args.icon_size
cache.ib.forced_width = item_args.icon_size
elseif cache.ib then
cache.ib.forced_height = nil
cache.ib.forced_width = nil
end
w:add(cache.primary)
end
end
return common
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80