-
Notifications
You must be signed in to change notification settings - Fork 2
/
init.lua
195 lines (164 loc) · 6.7 KB
/
init.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
local awful = require("awful")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local beautiful = require("beautiful")
local gears = require("gears")
local json = require("json")
local gfs = require("gears.filesystem")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local row_builder = require("noobie.row_builder")
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/noobie'
local ICONS_DIR = WIDGET_DIR .. '/feather_icons/'
local CACHE_DIR = os.getenv("HOME") .. '/.cache/noobie/icons'
local cur_stdout
local noobie_widget = {}
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Noobie',
text = message}
end
local function worker(user_args)
local args = user_args or {}
local refresh_rate = args.refresh_rate or 600
local path = args.path
local background = args.background or '#00000000'
if path == nil then
show_warning("Cannot create a widget, required parameter 'path' is not provided")
return
end
if not gfs.dir_readable(CACHE_DIR) then
gfs.make_directories(CACHE_DIR)
end
local noobie_popup = awful.popup{
ontop = true,
visible = false,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 4)
end,
border_width = 1,
border_color = beautiful.bg_focus,
width = 200,
minimum_width = 100,
maximum_width = 400,
offset = { y = 5 },
widget = {}
}
local has_menu = false
local has_mouse_actions = false
local menu_buttons = {}
local mouse_actions_buttons = {}
noobie_widget = wibox.widget {
{
{
{
{
id = 'icn',
--forced_height = 20,
--forced_width = 20,
resize = true,
widget = wibox.widget.imagebox
},
valign = 'center',
layout = wibox.container.place
},
{
id = 'txt',
widget = wibox.widget.textbox
},
id = 'spc',
spacing = 4,
layout = wibox.layout.fixed.horizontal
},
margins = 4,
widget = wibox.container.margin
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 4)
end,
bg = background,
widget = wibox.container.background,
set_text = function(self, new_text)
if new_text == nil or new_text == '' then
self:get_children_by_id('txt')[1]:set_text('')
self:get_children_by_id('spc')[1]:set_spacing(0)
else
self:get_children_by_id('txt')[1]:set_text(new_text)
end
end,
set_icon = function(self, new_icon)
-- new_icon is a path to a file
if new_icon:sub(1, 1) == '/' then
self:get_children_by_id('icn')[1]:set_image(new_icon)
-- new_icon is a relative path to the file
elseif new_icon:sub(1, 1) == '~' then
self:get_children_by_id('icn')[1]:set_image(HOME_DIR .. '/' .. new_icon:sub(3))
-- new_icon is a url to the icon
elseif new_icon:sub(1, 4) == 'http' then
local icon_path = CACHE_DIR .. '/' .. new_icon:sub(-16)
if not gfs.file_readable(icon_path) then
local download_cmd = string.format([[sh -c "curl -n --create-dirs -o %s %s"]], icon_path, new_icon)
spawn.easy_async(download_cmd,
function() self:get_children_by_id('icn')[1]:set_image(icon_path) end)
else
self:get_children_by_id('icn')[1]:set_image(icon_path)
end
-- new_icon is a feather icon
else
self:get_children_by_id('icn')[1]:set_image(ICONS_DIR .. new_icon .. '.svg')
end
end
}
local update_widget = function(widget, stdout, stderr)
if stderr ~= '' then
show_warning(stderr)
return
end
--- do nothing if the output hasn't changed
if (cur_stdout == stdout) then return
else cur_stdout = stdout
end
local result = json.decode(stdout)
widget:set_text(result.widget.text)
widget:set_icon(result.widget.icon)
has_menu = result.menu ~= nil and result.menu.items ~= nil and #result.menu.items > 0
if has_menu then
local rows = { layout = wibox.layout.fixed.vertical }
for i = 0, #rows do rows[i]=nil end
for _, item in ipairs(result.menu.items) do
local row = row_builder:build_row(item, widget, noobie_popup)
table.insert(rows, row)
end
noobie_popup:setup(rows)
menu_buttons = gears.table.join(
awful.button({}, 1, function()
if noobie_popup.visible then
widget:set_bg(background)
noobie_popup.visible = not noobie_popup.visible
else
widget:set_bg(beautiful.bg_focus)
noobie_popup:move_next_to(mouse.current_widget_geometry)
end
end)
)
end
local actions = result.widget.mouse_actions
has_mouse_actions = actions ~= nil
if has_mouse_actions then
mouse_actions_buttons = gears.table.join(
awful.button({}, 1, function() if actions.on_left_click ~= nil then awful.spawn.with_shell(actions.on_left_click) end end),
awful.button({}, 2, function() if actions.on_right_click ~= nil then awful.spawn.with_shell(actions.on_right_click) end end),
awful.button({}, 4, function() if actions.on_scroll_up ~= nil then awful.spawn.with_shell(actions.on_scroll_up) end end),
awful.button({}, 5, function() if actions.on_scroll_down ~= nil then awful.spawn.with_shell(actions.on_scroll_down) end end)
)
end
widget:buttons(gears.table.join(mouse_actions_buttons, menu_buttons))
end
watch(string.format([[sh -c "%s"]], path), refresh_rate, update_widget, noobie_widget)
return noobie_widget
end
return setmetatable(noobie_widget, { __call = function(_, ...)
return worker(...)
end })